From c00193f8cad12d8b5bdfd035946c09c244a6ed51 Mon Sep 17 00:00:00 2001 From: Roshan Varughese <40583749+Animeboynz@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:17:35 +1200 Subject: [PATCH] Add Library List --- .../settings/screen/SettingsDataScreen.kt | 17 +++ .../settings/screen/data/LibraryListScreen.kt | 129 ++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 app/src/main/java/eu/kanade/presentation/more/settings/screen/data/LibraryListScreen.kt diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDataScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDataScreen.kt index ecfd2ec75..ca0cc1e5c 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDataScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDataScreen.kt @@ -39,6 +39,7 @@ import eu.kanade.presentation.more.settings.Preference import eu.kanade.presentation.more.settings.screen.data.CreateBackupScreen import eu.kanade.presentation.more.settings.screen.data.RestoreBackupScreen import eu.kanade.presentation.more.settings.screen.data.StorageInfo +import eu.kanade.presentation.more.settings.screen.data.LibraryDebugListScreen import eu.kanade.presentation.more.settings.widget.BasePreferenceWidget import eu.kanade.presentation.more.settings.widget.PrefsHorizontalPadding import eu.kanade.presentation.util.relativeTimeSpanString @@ -95,6 +96,7 @@ object SettingsDataScreen : SearchableSettings { getBackupAndRestoreGroup(backupPreferences = backupPreferences), getDataGroup(), + getExportGroup(), ) } @@ -312,4 +314,19 @@ object SettingsDataScreen : SearchableSettings { ), ) } + + @Composable + private fun getExportGroup(): Preference.PreferenceGroup { + val navigator = LocalNavigator.currentOrThrow + + return Preference.PreferenceGroup( + title = "Export", + preferenceItems = persistentListOf( + Preference.PreferenceItem.TextPreference( + title = LibraryDebugListScreen.TITLE, + onClick = { navigator.push(LibraryDebugListScreen()) }, + ), + ), + ) + } } diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/LibraryListScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/LibraryListScreen.kt new file mode 100644 index 000000000..77bc22ac9 --- /dev/null +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/LibraryListScreen.kt @@ -0,0 +1,129 @@ +package eu.kanade.presentation.more.settings.screen.data + +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ContentCopy +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import cafe.adriel.voyager.navigator.LocalNavigator +import cafe.adriel.voyager.navigator.currentOrThrow +import eu.kanade.presentation.components.AppBar +import eu.kanade.presentation.components.AppBarActions +import eu.kanade.presentation.manga.components.MangaCover +import eu.kanade.presentation.util.Screen +import eu.kanade.tachiyomi.util.system.copyToClipboard +import kotlinx.collections.immutable.persistentListOf +import tachiyomi.domain.manga.interactor.GetFavorites +import tachiyomi.domain.manga.model.Manga +import tachiyomi.i18n.MR +import tachiyomi.presentation.core.components.material.Scaffold +import tachiyomi.presentation.core.i18n.stringResource +import uy.kohesive.injekt.Injekt +import kotlinx.coroutines.flow.flow +import tachiyomi.presentation.core.components.material.padding +import tachiyomi.presentation.core.screens.EmptyScreen +import uy.kohesive.injekt.api.get + +@Composable +fun BaseMangaListItem( + manga: Manga, + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier + .height(56.dp) + .padding(horizontal = MaterialTheme.padding.medium), + verticalAlignment = Alignment.CenterVertically, + ) { + MangaCover.Square( + modifier = Modifier + .padding(vertical = MaterialTheme.padding.small) + .fillMaxHeight(), + data = manga, + ) + + Box(modifier = Modifier.weight(1f)) { + Text( + text = manga.title, + modifier = Modifier + .padding(start = MaterialTheme.padding.medium), + overflow = TextOverflow.Ellipsis, + maxLines = 1, + style = MaterialTheme.typography.bodyMedium, + ) + } + } +} + +class LibraryDebugListScreen : Screen() { + + companion object { + const val TITLE = "Library List" + } + + @Composable + override fun Content() { + val context = LocalContext.current + val navigator = LocalNavigator.currentOrThrow + val getFavorites: GetFavorites = Injekt.get() + + val favoritesFlow = remember { flow { emit(getFavorites.await()) } } + val favoritesState by favoritesFlow.collectAsState(emptyList()) + + Scaffold( + topBar = { + AppBar( + title = TITLE, + navigateUp = navigator::pop, + actions = { + AppBarActions( + persistentListOf( + AppBar.Action( + title = stringResource(MR.strings.action_copy_to_clipboard), + icon = Icons.Default.ContentCopy, + onClick = { + val csvData = favoritesState.joinToString("\n") { manga -> + val author = manga.author ?: "" + val artist = manga.artist ?: "" + "${manga.title}, $author, $artist" + } + context.copyToClipboard(TITLE, csvData) + }, + ), + ), + ) + }, + ) + }, + ) { contentPadding -> + + if (favoritesState.isEmpty()) { + EmptyScreen( + stringRes = MR.strings.empty_screen, + modifier = Modifier.padding(contentPadding), + ) + return@Scaffold + } + + LazyColumn( + modifier = Modifier + .padding(contentPadding) + .padding(8.dp) + ) { + items(favoritesState) { manga -> + BaseMangaListItem( + manga = manga, + ) + } + } + } + } +}