Compare commits

2 Commits

Author SHA1 Message Date
acite
88392444a4 [feat] Task Statistics 2025-09-28 02:03:20 +08:00
acite
2166229923 [fix] Offline mode display exception 2025-09-28 01:54:02 +08:00
4 changed files with 80 additions and 42 deletions

View File

@@ -120,6 +120,10 @@ class FetchManager @Inject constructor(
} }
suspend fun startVideoDownload(video: Video) { suspend fun startVideoDownload(video: Video) {
if(getAllDownloadsAsync().any{
it.extras.getString("class", "") == video.klass && it.extras.getString("id", "") == video.id })
return
makeFolder(video) makeFolder(video)
File( File(
context.getExternalFilesDir(null), context.getExternalFilesDir(null),

View File

@@ -21,6 +21,8 @@ import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
import androidx.compose.material3.DividerDefaults
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@@ -38,6 +40,7 @@ import androidx.compose.ui.unit.sp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.room.util.TableInfo
import coil3.compose.AsyncImage import coil3.compose.AsyncImage
import coil3.request.ImageRequest import coil3.request.ImageRequest
import com.acitelight.aether.Global.updateRelate import com.acitelight.aether.Global.updateRelate
@@ -51,6 +54,7 @@ import kotlinx.coroutines.withContext
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import java.io.File import java.io.File
import kotlin.collections.sortedWith import kotlin.collections.sortedWith
import kotlin.math.abs
@Composable @Composable
fun TransmissionScreen( fun TransmissionScreen(
@@ -58,11 +62,37 @@ fun TransmissionScreen(
transmissionScreenViewModel: TransmissionScreenViewModel = hiltViewModel<TransmissionScreenViewModel>() transmissionScreenViewModel: TransmissionScreenViewModel = hiltViewModel<TransmissionScreenViewModel>()
) { ) {
val downloads = transmissionScreenViewModel.downloads val downloads = transmissionScreenViewModel.downloads
Column()
{
Text(
text = "Video Tasks",
style = MaterialTheme.typography.headlineMedium,
modifier = Modifier.padding(8.dp).align(Alignment.Start)
)
Text(
text = "All: ${downloads.count { it.type == "main" }}",
modifier = Modifier.padding(horizontal = 8.dp).align(Alignment.Start),
fontSize = 12.sp,
lineHeight = 13.sp,
maxLines = 1
)
Text(
text = "Completed: ${downloads.count { it.type == "main" && it.status == Status.COMPLETED }}",
modifier = Modifier.padding(horizontal = 8.dp).align(Alignment.Start),
fontSize = 12.sp,
lineHeight = 13.sp,
maxLines = 1
)
HorizontalDivider(Modifier.padding(8.dp), 2.dp, DividerDefaults.color)
LazyColumn( LazyColumn(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(8.dp) verticalArrangement = Arrangement.spacedBy(8.dp)
) { )
{
items(downloads.filter { it.type == "main" }, key = { it.id }) { item -> items(downloads.filter { it.type == "main" }, key = { it.id }) { item ->
VideoDownloadCard( VideoDownloadCard(
navigator = navigator, navigator = navigator,
@@ -95,6 +125,7 @@ fun TransmissionScreen(
) )
} }
} }
}
} }
@@ -254,7 +285,7 @@ private fun VideoDownloadCard(
// progress bar // progress bar
LinearProgressIndicator( LinearProgressIndicator(
progress = { model.progress.coerceIn(0, 100) / 100f }, progress = { abs(model.progress).coerceIn(0, 100) / 100f },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 8.dp, bottom = 8.dp), .padding(top = 8.dp, bottom = 8.dp),

View File

@@ -349,13 +349,14 @@ fun VideoCard(
{ {
videoScreenViewModel.download(i) videoScreenViewModel.download(i)
} }
}
Toast.makeText( Toast.makeText(
videoScreenViewModel.context, videoScreenViewModel.context,
"Start downloading ${video.video.group}", "Start downloading ${video.video.group}",
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} }
}
), ),
shape = RoundedCornerShape(6.dp), shape = RoundedCornerShape(6.dp),
) { ) {

View File

@@ -36,7 +36,7 @@ import javax.inject.Singleton
@HiltViewModel @HiltViewModel
class VideoScreenViewModel @Inject constructor( class VideoScreenViewModel @Inject constructor(
private val fetchManager: FetchManager, val fetchManager: FetchManager,
@ApplicationContext val context: Context, @ApplicationContext val context: Context,
val mediaManager: MediaManager, val mediaManager: MediaManager,
val recentManager: RecentManager, val recentManager: RecentManager,
@@ -82,7 +82,9 @@ class VideoScreenViewModel @Inject constructor(
videoLibrary.classesMap["Offline"] = mutableStateListOf<Video>() videoLibrary.classesMap["Offline"] = mutableStateListOf<Video>()
val downloaded = fetchManager.getAllDownloadsAsync().filter { val downloaded = fetchManager.getAllDownloadsAsync().filter {
it.status == Status.COMPLETED && it.extras.getString("class", "") != "comic" it.status == Status.COMPLETED &&
it.extras.getString("class", "") != "comic" &&
it.extras.getString("type", "") == "main"
} }
val jsonQuery = downloaded.map{ File( val jsonQuery = downloaded.map{ File(