Add worker info screen (#8774)
Mainly for debug purpose, might help with support.
This commit is contained in:
parent
01ec26842d
commit
ab61a65b4a
@ -118,6 +118,7 @@ object SettingsAdvancedScreen : SearchableSettings {
|
||||
private fun getBackgroundActivityGroup(): Preference.PreferenceGroup {
|
||||
val context = LocalContext.current
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
|
||||
return Preference.PreferenceGroup(
|
||||
title = stringResource(R.string.label_background_activity),
|
||||
@ -149,6 +150,10 @@ object SettingsAdvancedScreen : SearchableSettings {
|
||||
subtitle = stringResource(R.string.about_dont_kill_my_app),
|
||||
onClick = { uriHandler.openUri("https://dontkillmyapp.com/") },
|
||||
),
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(R.string.pref_worker_info),
|
||||
onClick = { navigator.push(WorkerInfoScreen) },
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -0,0 +1,161 @@
|
||||
package eu.kanade.presentation.more.settings.screen
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.horizontalScroll
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.ContentCopy
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.asFlow
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.WorkQuery
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||
import eu.kanade.presentation.components.LazyColumn
|
||||
import eu.kanade.presentation.components.Scaffold
|
||||
import eu.kanade.presentation.util.plus
|
||||
import eu.kanade.tachiyomi.R
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object WorkerInfoScreen : Screen {
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val context = LocalContext.current
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
val clipboardManager = LocalClipboardManager.current
|
||||
|
||||
val screenModel = rememberScreenModel { Model(context) }
|
||||
val enqueued by screenModel.enqueued.collectAsState()
|
||||
val finished by screenModel.finished.collectAsState()
|
||||
val running by screenModel.running.collectAsState()
|
||||
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(text = stringResource(R.string.pref_worker_info)) },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = navigator::pop) {
|
||||
Icon(imageVector = Icons.Default.ArrowBack, contentDescription = null)
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
val copiedString = stringResource(R.string.copied_to_clipboard_plain)
|
||||
IconButton(
|
||||
onClick = {
|
||||
clipboardManager.setText(AnnotatedString(enqueued + finished + running))
|
||||
scope.launch { snackbarHostState.showSnackbar(copiedString) }
|
||||
},
|
||||
) {
|
||||
Icon(imageVector = Icons.Default.ContentCopy, contentDescription = null)
|
||||
}
|
||||
},
|
||||
scrollBehavior = it,
|
||||
)
|
||||
},
|
||||
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
||||
) { contentPadding ->
|
||||
LazyColumn(
|
||||
contentPadding = contentPadding + PaddingValues(horizontal = 16.dp),
|
||||
modifier = Modifier.horizontalScroll(rememberScrollState()),
|
||||
) {
|
||||
item { SectionTitle(title = "Enqueued") }
|
||||
item { SectionText(text = enqueued) }
|
||||
|
||||
item { SectionTitle(title = "Finished") }
|
||||
item { SectionText(text = finished) }
|
||||
|
||||
item { SectionTitle(title = "Running") }
|
||||
item { SectionText(text = running) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SectionTitle(title: String) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
modifier = Modifier.padding(vertical = 8.dp),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SectionText(text: String) {
|
||||
Text(
|
||||
text = text,
|
||||
softWrap = false,
|
||||
fontFamily = FontFamily.Monospace,
|
||||
)
|
||||
}
|
||||
|
||||
private class Model(context: Context) : ScreenModel {
|
||||
private val workManager = WorkManager.getInstance(context)
|
||||
|
||||
val finished = workManager
|
||||
.getWorkInfosLiveData(WorkQuery.fromStates(WorkInfo.State.SUCCEEDED, WorkInfo.State.FAILED, WorkInfo.State.CANCELLED))
|
||||
.asFlow()
|
||||
.map(::constructString)
|
||||
.stateIn(coroutineScope, SharingStarted.WhileSubscribed(), "")
|
||||
|
||||
val running = workManager
|
||||
.getWorkInfosLiveData(WorkQuery.fromStates(WorkInfo.State.RUNNING))
|
||||
.asFlow()
|
||||
.map(::constructString)
|
||||
.stateIn(coroutineScope, SharingStarted.WhileSubscribed(), "")
|
||||
|
||||
val enqueued = workManager
|
||||
.getWorkInfosLiveData(WorkQuery.fromStates(WorkInfo.State.ENQUEUED))
|
||||
.asFlow()
|
||||
.map(::constructString)
|
||||
.stateIn(coroutineScope, SharingStarted.WhileSubscribed(), "")
|
||||
|
||||
private fun constructString(list: List<WorkInfo>) = buildString {
|
||||
if (list.isEmpty()) {
|
||||
appendLine("-")
|
||||
} else {
|
||||
list.forEach { workInfo ->
|
||||
appendLine("Id: ${workInfo.id}")
|
||||
appendLine("Tags:")
|
||||
workInfo.tags.forEach {
|
||||
appendLine(" - $it")
|
||||
}
|
||||
appendLine("State: ${workInfo.state}")
|
||||
appendLine()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -538,6 +538,7 @@
|
||||
<string name="pref_tablet_ui_mode">Tablet UI</string>
|
||||
<string name="pref_verbose_logging">Verbose logging</string>
|
||||
<string name="pref_verbose_logging_summary">Print verbose logs to system log (reduces app performance)</string>
|
||||
<string name="pref_worker_info">Worker info</string>
|
||||
|
||||
<!-- About section -->
|
||||
<string name="website">Website</string>
|
||||
@ -634,6 +635,7 @@
|
||||
<item quantity="other">%1$s chapters</item>
|
||||
</plurals>
|
||||
<string name="delete_downloads_for_manga">Delete downloaded chapters?</string>
|
||||
<string name="copied_to_clipboard_plain">Copied to clipboard</string>
|
||||
<string name="copied_to_clipboard">Copied to clipboard:\n%1$s</string>
|
||||
<string name="clipboard_copy_error">Failed to copy to clipboard</string>
|
||||
<string name="source_not_installed">Source not installed: %1$s</string>
|
||||
|
Loading…
Reference in New Issue
Block a user