Minor cleanup
This commit is contained in:
parent
2556e9f08c
commit
abae9bf37d
46 changed files with 341 additions and 331 deletions
|
@ -72,9 +72,9 @@ class SetReadStatus(
|
||||||
suspend fun await(manga: Manga, read: Boolean) =
|
suspend fun await(manga: Manga, read: Boolean) =
|
||||||
await(manga.id, read)
|
await(manga.id, read)
|
||||||
|
|
||||||
sealed class Result {
|
sealed interface Result {
|
||||||
data object Success : Result()
|
data object Success : Result
|
||||||
data object NoChapters : Result()
|
data object NoChapters : Result
|
||||||
data class InternalError(val error: Throwable) : Result()
|
data class InternalError(val error: Throwable) : Result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ import eu.kanade.presentation.more.settings.widget.TrailingWidgetBuffer
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
import eu.kanade.tachiyomi.ui.browse.extension.details.ExtensionDetailsState
|
import eu.kanade.tachiyomi.ui.browse.extension.details.ExtensionDetailsScreenModel
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
|
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
|
||||||
import tachiyomi.presentation.core.components.material.DIVIDER_ALPHA
|
import tachiyomi.presentation.core.components.material.DIVIDER_ALPHA
|
||||||
|
@ -65,7 +65,7 @@ import tachiyomi.presentation.core.screens.EmptyScreen
|
||||||
@Composable
|
@Composable
|
||||||
fun ExtensionDetailsScreen(
|
fun ExtensionDetailsScreen(
|
||||||
navigateUp: () -> Unit,
|
navigateUp: () -> Unit,
|
||||||
state: ExtensionDetailsState,
|
state: ExtensionDetailsScreenModel.State,
|
||||||
onClickSourcePreferences: (sourceId: Long) -> Unit,
|
onClickSourcePreferences: (sourceId: Long) -> Unit,
|
||||||
onClickWhatsNew: () -> Unit,
|
onClickWhatsNew: () -> Unit,
|
||||||
onClickReadme: () -> Unit,
|
onClickReadme: () -> Unit,
|
||||||
|
|
|
@ -43,7 +43,7 @@ import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
import eu.kanade.tachiyomi.extension.model.InstallStep
|
import eu.kanade.tachiyomi.extension.model.InstallStep
|
||||||
import eu.kanade.tachiyomi.ui.browse.extension.ExtensionUiModel
|
import eu.kanade.tachiyomi.ui.browse.extension.ExtensionUiModel
|
||||||
import eu.kanade.tachiyomi.ui.browse.extension.ExtensionsState
|
import eu.kanade.tachiyomi.ui.browse.extension.ExtensionsScreenModel
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
||||||
import tachiyomi.presentation.core.components.material.PullRefresh
|
import tachiyomi.presentation.core.components.material.PullRefresh
|
||||||
|
@ -57,7 +57,7 @@ import tachiyomi.presentation.core.util.secondaryItemAlpha
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ExtensionScreen(
|
fun ExtensionScreen(
|
||||||
state: ExtensionsState,
|
state: ExtensionsScreenModel.State,
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
searchQuery: String?,
|
searchQuery: String?,
|
||||||
onLongClickItem: (Extension) -> Unit,
|
onLongClickItem: (Extension) -> Unit,
|
||||||
|
@ -108,7 +108,7 @@ fun ExtensionScreen(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ExtensionContent(
|
private fun ExtensionContent(
|
||||||
state: ExtensionsState,
|
state: ExtensionsScreenModel.State,
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
onLongClickItem: (Extension) -> Unit,
|
onLongClickItem: (Extension) -> Unit,
|
||||||
onClickItemCancel: (Extension) -> Unit,
|
onClickItemCancel: (Extension) -> Unit,
|
||||||
|
|
|
@ -8,7 +8,7 @@ import androidx.compose.ui.Modifier
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.manga.components.BaseMangaListItem
|
import eu.kanade.presentation.manga.components.BaseMangaListItem
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrateMangaState
|
import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrateMangaScreenModel
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
|
@ -18,7 +18,7 @@ import tachiyomi.presentation.core.screens.EmptyScreen
|
||||||
fun MigrateMangaScreen(
|
fun MigrateMangaScreen(
|
||||||
navigateUp: () -> Unit,
|
navigateUp: () -> Unit,
|
||||||
title: String?,
|
title: String?,
|
||||||
state: MigrateMangaState,
|
state: MigrateMangaScreenModel.State,
|
||||||
onClickItem: (Manga) -> Unit,
|
onClickItem: (Manga) -> Unit,
|
||||||
onClickCover: (Manga) -> Unit,
|
onClickCover: (Manga) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
@ -51,7 +51,7 @@ fun MigrateMangaScreen(
|
||||||
@Composable
|
@Composable
|
||||||
private fun MigrateMangaContent(
|
private fun MigrateMangaContent(
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
state: MigrateMangaState,
|
state: MigrateMangaScreenModel.State,
|
||||||
onClickItem: (Manga) -> Unit,
|
onClickItem: (Manga) -> Unit,
|
||||||
onClickCover: (Manga) -> Unit,
|
onClickCover: (Manga) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ import eu.kanade.domain.source.interactor.SetMigrateSorting
|
||||||
import eu.kanade.presentation.browse.components.BaseSourceItem
|
import eu.kanade.presentation.browse.components.BaseSourceItem
|
||||||
import eu.kanade.presentation.browse.components.SourceIcon
|
import eu.kanade.presentation.browse.components.SourceIcon
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.sources.MigrateSourceState
|
import eu.kanade.tachiyomi.ui.browse.migration.sources.MigrateSourceScreenModel
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import tachiyomi.domain.source.model.Source
|
import tachiyomi.domain.source.model.Source
|
||||||
import tachiyomi.presentation.core.components.Badge
|
import tachiyomi.presentation.core.components.Badge
|
||||||
|
@ -43,7 +43,7 @@ import tachiyomi.presentation.core.util.secondaryItemAlpha
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MigrateSourceScreen(
|
fun MigrateSourceScreen(
|
||||||
state: MigrateSourceState,
|
state: MigrateSourceScreenModel.State,
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
onClickItem: (Source) -> Unit,
|
onClickItem: (Source) -> Unit,
|
||||||
onToggleSortingDirection: () -> Unit,
|
onToggleSortingDirection: () -> Unit,
|
||||||
|
|
|
@ -12,7 +12,7 @@ import eu.kanade.presentation.browse.components.BaseSourceItem
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
|
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.SourcesFilterState
|
import eu.kanade.tachiyomi.ui.browse.source.SourcesFilterScreenModel
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
import tachiyomi.domain.source.model.Source
|
import tachiyomi.domain.source.model.Source
|
||||||
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
||||||
|
@ -22,7 +22,7 @@ import tachiyomi.presentation.core.screens.EmptyScreen
|
||||||
@Composable
|
@Composable
|
||||||
fun SourcesFilterScreen(
|
fun SourcesFilterScreen(
|
||||||
navigateUp: () -> Unit,
|
navigateUp: () -> Unit,
|
||||||
state: SourcesFilterState.Success,
|
state: SourcesFilterScreenModel.State.Success,
|
||||||
onClickLanguage: (String) -> Unit,
|
onClickLanguage: (String) -> Unit,
|
||||||
onClickSource: (Source) -> Unit,
|
onClickSource: (Source) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
@ -54,7 +54,7 @@ fun SourcesFilterScreen(
|
||||||
@Composable
|
@Composable
|
||||||
private fun SourcesFilterContent(
|
private fun SourcesFilterContent(
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
state: SourcesFilterState.Success,
|
state: SourcesFilterScreenModel.State.Success,
|
||||||
onClickLanguage: (String) -> Unit,
|
onClickLanguage: (String) -> Unit,
|
||||||
onClickSource: (Source) -> Unit,
|
onClickSource: (Source) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -192,7 +192,7 @@ fun SourceOptionsDialog(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class SourceUiModel {
|
sealed interface SourceUiModel {
|
||||||
data class Item(val source: Source) : SourceUiModel()
|
data class Item(val source: Source) : SourceUiModel
|
||||||
data class Header(val language: String) : SourceUiModel()
|
data class Header(val language: String) : SourceUiModel
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ import eu.kanade.presentation.components.SearchToolbar
|
||||||
import eu.kanade.presentation.history.components.HistoryItem
|
import eu.kanade.presentation.history.components.HistoryItem
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.history.HistoryScreenModel
|
import eu.kanade.tachiyomi.ui.history.HistoryScreenModel
|
||||||
import eu.kanade.tachiyomi.ui.history.HistoryState
|
|
||||||
import tachiyomi.domain.history.model.HistoryWithRelations
|
import tachiyomi.domain.history.model.HistoryWithRelations
|
||||||
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
|
@ -33,7 +32,7 @@ import java.util.Date
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HistoryScreen(
|
fun HistoryScreen(
|
||||||
state: HistoryState,
|
state: HistoryScreenModel.State,
|
||||||
snackbarHostState: SnackbarHostState,
|
snackbarHostState: SnackbarHostState,
|
||||||
onSearchQueryChange: (String?) -> Unit,
|
onSearchQueryChange: (String?) -> Unit,
|
||||||
onClickCover: (mangaId: Long) -> Unit,
|
onClickCover: (mangaId: Long) -> Unit,
|
||||||
|
@ -139,7 +138,7 @@ private fun HistoryScreenContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class HistoryUiModel {
|
sealed interface HistoryUiModel {
|
||||||
data class Header(val date: Date) : HistoryUiModel()
|
data class Header(val date: Date) : HistoryUiModel
|
||||||
data class Item(val item: HistoryWithRelations) : HistoryUiModel()
|
data class Item(val item: HistoryWithRelations) : HistoryUiModel
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.source.getNameForMangaInfo
|
import eu.kanade.tachiyomi.source.getNameForMangaInfo
|
||||||
import eu.kanade.tachiyomi.ui.manga.ChapterItem
|
import eu.kanade.tachiyomi.ui.manga.ChapterItem
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreenState
|
import eu.kanade.tachiyomi.ui.manga.MangaScreenModel
|
||||||
import eu.kanade.tachiyomi.util.lang.toRelativeString
|
import eu.kanade.tachiyomi.util.lang.toRelativeString
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import tachiyomi.domain.chapter.model.Chapter
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
|
@ -82,7 +82,7 @@ import java.util.Date
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MangaScreen(
|
fun MangaScreen(
|
||||||
state: MangaScreenState.Success,
|
state: MangaScreenModel.State.Success,
|
||||||
snackbarHostState: SnackbarHostState,
|
snackbarHostState: SnackbarHostState,
|
||||||
dateRelativeTime: Int,
|
dateRelativeTime: Int,
|
||||||
dateFormat: DateFormat,
|
dateFormat: DateFormat,
|
||||||
|
@ -210,7 +210,7 @@ fun MangaScreen(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun MangaScreenSmallImpl(
|
private fun MangaScreenSmallImpl(
|
||||||
state: MangaScreenState.Success,
|
state: MangaScreenModel.State.Success,
|
||||||
snackbarHostState: SnackbarHostState,
|
snackbarHostState: SnackbarHostState,
|
||||||
dateRelativeTime: Int,
|
dateRelativeTime: Int,
|
||||||
dateFormat: DateFormat,
|
dateFormat: DateFormat,
|
||||||
|
@ -436,7 +436,7 @@ private fun MangaScreenSmallImpl(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MangaScreenLargeImpl(
|
fun MangaScreenLargeImpl(
|
||||||
state: MangaScreenState.Success,
|
state: MangaScreenModel.State.Success,
|
||||||
snackbarHostState: SnackbarHostState,
|
snackbarHostState: SnackbarHostState,
|
||||||
dateRelativeTime: Int,
|
dateRelativeTime: Int,
|
||||||
dateFormat: DateFormat,
|
dateFormat: DateFormat,
|
||||||
|
|
|
@ -19,6 +19,7 @@ import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
@ -269,12 +270,15 @@ private class ClearDatabaseScreenModel : StateScreenModel<ClearDatabaseScreenMod
|
||||||
state.copy(showConfirmation = false)
|
state.copy(showConfirmation = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class State {
|
sealed interface State {
|
||||||
data object Loading : State()
|
@Immutable
|
||||||
|
data object Loading : State
|
||||||
|
|
||||||
|
@Immutable
|
||||||
data class Ready(
|
data class Ready(
|
||||||
val items: List<SourceWithCount>,
|
val items: List<SourceWithCount>,
|
||||||
val selection: List<Long> = emptyList(),
|
val selection: List<Long> = emptyList(),
|
||||||
val showConfirmation: Boolean = false,
|
val showConfirmation: Boolean = false,
|
||||||
) : State()
|
) : State
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@ package eu.kanade.presentation.more.stats
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import eu.kanade.presentation.more.stats.data.StatsData
|
import eu.kanade.presentation.more.stats.data.StatsData
|
||||||
|
|
||||||
sealed class StatsScreenState {
|
sealed interface StatsScreenState {
|
||||||
@Immutable
|
@Immutable
|
||||||
data object Loading : StatsScreenState()
|
data object Loading : StatsScreenState
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class Success(
|
data class Success(
|
||||||
|
@ -13,5 +13,5 @@ sealed class StatsScreenState {
|
||||||
val titles: StatsData.Titles,
|
val titles: StatsData.Titles,
|
||||||
val chapters: StatsData.Chapters,
|
val chapters: StatsData.Chapters,
|
||||||
val trackers: StatsData.Trackers,
|
val trackers: StatsData.Trackers,
|
||||||
) : StatsScreenState()
|
) : StatsScreenState
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
package eu.kanade.presentation.more.stats.data
|
package eu.kanade.presentation.more.stats.data
|
||||||
|
|
||||||
sealed class StatsData {
|
sealed interface StatsData {
|
||||||
|
|
||||||
data class Overview(
|
data class Overview(
|
||||||
val libraryMangaCount: Int,
|
val libraryMangaCount: Int,
|
||||||
val completedMangaCount: Int,
|
val completedMangaCount: Int,
|
||||||
val totalReadDuration: Long,
|
val totalReadDuration: Long,
|
||||||
) : StatsData()
|
) : StatsData
|
||||||
|
|
||||||
data class Titles(
|
data class Titles(
|
||||||
val globalUpdateItemCount: Int,
|
val globalUpdateItemCount: Int,
|
||||||
val startedMangaCount: Int,
|
val startedMangaCount: Int,
|
||||||
val localMangaCount: Int,
|
val localMangaCount: Int,
|
||||||
) : StatsData()
|
) : StatsData
|
||||||
|
|
||||||
data class Chapters(
|
data class Chapters(
|
||||||
val totalChapterCount: Int,
|
val totalChapterCount: Int,
|
||||||
val readChapterCount: Int,
|
val readChapterCount: Int,
|
||||||
val downloadCount: Int,
|
val downloadCount: Int,
|
||||||
) : StatsData()
|
) : StatsData
|
||||||
|
|
||||||
data class Trackers(
|
data class Trackers(
|
||||||
val trackedTitleCount: Int,
|
val trackedTitleCount: Int,
|
||||||
val meanScore: Double,
|
val meanScore: Double,
|
||||||
val trackerCount: Int,
|
val trackerCount: Int,
|
||||||
) : StatsData()
|
) : StatsData
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ import eu.kanade.presentation.manga.components.MangaBottomActionMenu
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.ui.updates.UpdatesItem
|
import eu.kanade.tachiyomi.ui.updates.UpdatesItem
|
||||||
import eu.kanade.tachiyomi.ui.updates.UpdatesState
|
import eu.kanade.tachiyomi.ui.updates.UpdatesScreenModel
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
||||||
|
@ -40,7 +40,7 @@ import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UpdateScreen(
|
fun UpdateScreen(
|
||||||
state: UpdatesState,
|
state: UpdatesScreenModel.State,
|
||||||
snackbarHostState: SnackbarHostState,
|
snackbarHostState: SnackbarHostState,
|
||||||
lastUpdated: Long,
|
lastUpdated: Long,
|
||||||
relativeTime: Int,
|
relativeTime: Int,
|
||||||
|
@ -209,7 +209,7 @@ private fun UpdatesBottomBar(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class UpdatesUiModel {
|
sealed interface UpdatesUiModel {
|
||||||
data class Header(val date: String) : UpdatesUiModel()
|
data class Header(val date: String) : UpdatesUiModel
|
||||||
data class Item(val item: UpdatesItem) : UpdatesUiModel()
|
data class Item(val item: UpdatesItem) : UpdatesUiModel
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,8 +152,8 @@ sealed class Image(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Location {
|
sealed interface Location {
|
||||||
data class Pictures private constructor(val relativePath: String) : Location() {
|
data class Pictures private constructor(val relativePath: String) : Location {
|
||||||
companion object {
|
companion object {
|
||||||
fun create(relativePath: String = ""): Pictures {
|
fun create(relativePath: String = ""): Pictures {
|
||||||
return Pictures(relativePath)
|
return Pictures(relativePath)
|
||||||
|
@ -161,7 +161,7 @@ sealed class Location {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data object Cache : Location()
|
data object Cache : Location
|
||||||
|
|
||||||
fun directory(context: Context): File {
|
fun directory(context: Context): File {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package eu.kanade.tachiyomi.extension.model
|
package eu.kanade.tachiyomi.extension.model
|
||||||
|
|
||||||
sealed class LoadResult {
|
sealed interface LoadResult {
|
||||||
data class Success(val extension: Extension.Installed) : LoadResult()
|
data class Success(val extension: Extension.Installed) : LoadResult
|
||||||
data class Untrusted(val extension: Extension.Untrusted) : LoadResult()
|
data class Untrusted(val extension: Extension.Untrusted) : LoadResult
|
||||||
data object Error : LoadResult()
|
data object Error : LoadResult
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,20 +54,20 @@ class ExtensionFilterScreenModel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class ExtensionFilterEvent {
|
sealed interface ExtensionFilterEvent {
|
||||||
data object FailedFetchingLanguages : ExtensionFilterEvent()
|
data object FailedFetchingLanguages : ExtensionFilterEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class ExtensionFilterState {
|
sealed interface ExtensionFilterState {
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data object Loading : ExtensionFilterState()
|
data object Loading : ExtensionFilterState
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class Success(
|
data class Success(
|
||||||
val languages: List<String>,
|
val languages: List<String>,
|
||||||
val enabledLanguages: Set<String> = emptySet(),
|
val enabledLanguages: Set<String> = emptySet(),
|
||||||
) : ExtensionFilterState() {
|
) : ExtensionFilterState {
|
||||||
|
|
||||||
val isEmpty: Boolean
|
val isEmpty: Boolean
|
||||||
get() = languages.isEmpty()
|
get() = languages.isEmpty()
|
||||||
|
|
|
@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.extension
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||||
import cafe.adriel.voyager.core.model.coroutineScope
|
import cafe.adriel.voyager.core.model.coroutineScope
|
||||||
import eu.kanade.domain.extension.interactor.GetExtensionsByType
|
import eu.kanade.domain.extension.interactor.GetExtensionsByType
|
||||||
|
@ -35,7 +36,7 @@ class ExtensionsScreenModel(
|
||||||
preferences: SourcePreferences = Injekt.get(),
|
preferences: SourcePreferences = Injekt.get(),
|
||||||
private val extensionManager: ExtensionManager = Injekt.get(),
|
private val extensionManager: ExtensionManager = Injekt.get(),
|
||||||
private val getExtensions: GetExtensionsByType = Injekt.get(),
|
private val getExtensions: GetExtensionsByType = Injekt.get(),
|
||||||
) : StateScreenModel<ExtensionsState>(ExtensionsState()) {
|
) : StateScreenModel<ExtensionsScreenModel.State>(State()) {
|
||||||
|
|
||||||
private var _currentDownloads = MutableStateFlow<Map<String, InstallStep>>(hashMapOf())
|
private var _currentDownloads = MutableStateFlow<Map<String, InstallStep>>(hashMapOf())
|
||||||
|
|
||||||
|
@ -190,9 +191,9 @@ class ExtensionsScreenModel(
|
||||||
fun trustSignature(signatureHash: String) {
|
fun trustSignature(signatureHash: String) {
|
||||||
extensionManager.trustSignature(signatureHash)
|
extensionManager.trustSignature(signatureHash)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
data class ExtensionsState(
|
@Immutable
|
||||||
|
data class State(
|
||||||
val isLoading: Boolean = true,
|
val isLoading: Boolean = true,
|
||||||
val isRefreshing: Boolean = false,
|
val isRefreshing: Boolean = false,
|
||||||
val items: ItemGroups = mutableMapOf(),
|
val items: ItemGroups = mutableMapOf(),
|
||||||
|
@ -201,6 +202,7 @@ data class ExtensionsState(
|
||||||
) {
|
) {
|
||||||
val isEmpty = items.isEmpty()
|
val isEmpty = items.isEmpty()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typealias ItemGroups = MutableMap<ExtensionUiModel.Header, List<ExtensionUiModel.Item>>
|
typealias ItemGroups = MutableMap<ExtensionUiModel.Header, List<ExtensionUiModel.Item>>
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ class ExtensionDetailsScreenModel(
|
||||||
private val extensionManager: ExtensionManager = Injekt.get(),
|
private val extensionManager: ExtensionManager = Injekt.get(),
|
||||||
private val getExtensionSources: GetExtensionSources = Injekt.get(),
|
private val getExtensionSources: GetExtensionSources = Injekt.get(),
|
||||||
private val toggleSource: ToggleSource = Injekt.get(),
|
private val toggleSource: ToggleSource = Injekt.get(),
|
||||||
) : StateScreenModel<ExtensionDetailsState>(ExtensionDetailsState()) {
|
) : StateScreenModel<ExtensionDetailsScreenModel.State>(State()) {
|
||||||
|
|
||||||
private val _events: Channel<ExtensionDetailsEvent> = Channel()
|
private val _events: Channel<ExtensionDetailsEvent> = Channel()
|
||||||
val events: Flow<ExtensionDetailsEvent> = _events.receiveAsFlow()
|
val events: Flow<ExtensionDetailsEvent> = _events.receiveAsFlow()
|
||||||
|
@ -160,14 +160,9 @@ class ExtensionDetailsScreenModel(
|
||||||
url + "/src/" + pkgName.replace(".", "/") + path
|
url + "/src/" + pkgName.replace(".", "/") + path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sealed class ExtensionDetailsEvent {
|
|
||||||
data object Uninstalled : ExtensionDetailsEvent()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class ExtensionDetailsState(
|
data class State(
|
||||||
val extension: Extension.Installed? = null,
|
val extension: Extension.Installed? = null,
|
||||||
private val _sources: List<ExtensionSourceItem>? = null,
|
private val _sources: List<ExtensionSourceItem>? = null,
|
||||||
) {
|
) {
|
||||||
|
@ -178,3 +173,8 @@ data class ExtensionDetailsState(
|
||||||
val isLoading: Boolean
|
val isLoading: Boolean
|
||||||
get() = extension == null || _sources == null
|
get() = extension == null || _sources == null
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface ExtensionDetailsEvent {
|
||||||
|
data object Uninstalled : ExtensionDetailsEvent
|
||||||
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ import eu.kanade.tachiyomi.util.system.toast
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import tachiyomi.presentation.core.screens.LoadingScreen
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
|
|
||||||
data class MigrationMangaScreen(
|
data class MigrateMangaScreen(
|
||||||
private val sourceId: Long,
|
private val sourceId: Long,
|
||||||
) : Screen() {
|
) : Screen() {
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ data class MigrationMangaScreen(
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
val screenModel = rememberScreenModel { MigrationMangaScreenModel(sourceId) }
|
val screenModel = rememberScreenModel { MigrateMangaScreenModel(sourceId) }
|
||||||
|
|
||||||
val state by screenModel.state.collectAsState()
|
val state by screenModel.state.collectAsState()
|
||||||
|
|
|
@ -20,11 +20,11 @@ import tachiyomi.domain.source.service.SourceManager
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
class MigrationMangaScreenModel(
|
class MigrateMangaScreenModel(
|
||||||
private val sourceId: Long,
|
private val sourceId: Long,
|
||||||
private val sourceManager: SourceManager = Injekt.get(),
|
private val sourceManager: SourceManager = Injekt.get(),
|
||||||
private val getFavorites: GetFavorites = Injekt.get(),
|
private val getFavorites: GetFavorites = Injekt.get(),
|
||||||
) : StateScreenModel<MigrateMangaState>(MigrateMangaState()) {
|
) : StateScreenModel<MigrateMangaScreenModel.State>(State()) {
|
||||||
|
|
||||||
private val _events: Channel<MigrationMangaEvent> = Channel()
|
private val _events: Channel<MigrationMangaEvent> = Channel()
|
||||||
val events: Flow<MigrationMangaEvent> = _events.receiveAsFlow()
|
val events: Flow<MigrationMangaEvent> = _events.receiveAsFlow()
|
||||||
|
@ -51,14 +51,9 @@ class MigrationMangaScreenModel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sealed class MigrationMangaEvent {
|
|
||||||
data object FailedFetchingFavorites : MigrationMangaEvent()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class MigrateMangaState(
|
data class State(
|
||||||
val source: Source? = null,
|
val source: Source? = null,
|
||||||
private val titleList: List<Manga>? = null,
|
private val titleList: List<Manga>? = null,
|
||||||
) {
|
) {
|
||||||
|
@ -72,3 +67,8 @@ data class MigrateMangaState(
|
||||||
val isEmpty: Boolean
|
val isEmpty: Boolean
|
||||||
get() = titles.isEmpty()
|
get() = titles.isEmpty()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface MigrationMangaEvent {
|
||||||
|
data object FailedFetchingFavorites : MigrationMangaEvent
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ class MigrateSearchScreenDialogScreenModel(
|
||||||
val dialog: Dialog? = null,
|
val dialog: Dialog? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
sealed class Dialog {
|
sealed interface Dialog {
|
||||||
data class Migrate(val manga: Manga) : Dialog()
|
data class Migrate(val manga: Manga) : Dialog
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.ui.browse.migration.sources
|
package eu.kanade.tachiyomi.ui.browse.migration.sources
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||||
import cafe.adriel.voyager.core.model.coroutineScope
|
import cafe.adriel.voyager.core.model.coroutineScope
|
||||||
import eu.kanade.domain.source.interactor.GetSourcesWithFavoriteCount
|
import eu.kanade.domain.source.interactor.GetSourcesWithFavoriteCount
|
||||||
|
@ -23,7 +24,7 @@ class MigrateSourceScreenModel(
|
||||||
preferences: SourcePreferences = Injekt.get(),
|
preferences: SourcePreferences = Injekt.get(),
|
||||||
private val getSourcesWithFavoriteCount: GetSourcesWithFavoriteCount = Injekt.get(),
|
private val getSourcesWithFavoriteCount: GetSourcesWithFavoriteCount = Injekt.get(),
|
||||||
private val setMigrateSorting: SetMigrateSorting = Injekt.get(),
|
private val setMigrateSorting: SetMigrateSorting = Injekt.get(),
|
||||||
) : StateScreenModel<MigrateSourceState>(MigrateSourceState()) {
|
) : StateScreenModel<MigrateSourceScreenModel.State>(State()) {
|
||||||
|
|
||||||
private val _channel = Channel<Event>(Int.MAX_VALUE)
|
private val _channel = Channel<Event>(Int.MAX_VALUE)
|
||||||
val channel = _channel.receiveAsFlow()
|
val channel = _channel.receiveAsFlow()
|
||||||
|
@ -76,12 +77,8 @@ class MigrateSourceScreenModel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Event {
|
@Immutable
|
||||||
data object FailedFetchingSourcesWithCount : Event()
|
data class State(
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class MigrateSourceState(
|
|
||||||
val isLoading: Boolean = true,
|
val isLoading: Boolean = true,
|
||||||
val items: List<Pair<Source, Long>> = emptyList(),
|
val items: List<Pair<Source, Long>> = emptyList(),
|
||||||
val sortingMode: SetMigrateSorting.Mode = SetMigrateSorting.Mode.ALPHABETICAL,
|
val sortingMode: SetMigrateSorting.Mode = SetMigrateSorting.Mode.ALPHABETICAL,
|
||||||
|
@ -89,3 +86,8 @@ data class MigrateSourceState(
|
||||||
) {
|
) {
|
||||||
val isEmpty = items.isEmpty()
|
val isEmpty = items.isEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed interface Event {
|
||||||
|
data object FailedFetchingSourcesWithCount : Event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import eu.kanade.presentation.browse.MigrateSourceScreen
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.components.TabContent
|
import eu.kanade.presentation.components.TabContent
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrationMangaScreen
|
import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrateMangaScreen
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Screen.migrateSourceTab(): TabContent {
|
fun Screen.migrateSourceTab(): TabContent {
|
||||||
|
@ -40,7 +40,7 @@ fun Screen.migrateSourceTab(): TabContent {
|
||||||
state = state,
|
state = state,
|
||||||
contentPadding = contentPadding,
|
contentPadding = contentPadding,
|
||||||
onClickItem = { source ->
|
onClickItem = { source ->
|
||||||
navigator.push(MigrationMangaScreen(source.id))
|
navigator.push(MigrateMangaScreen(source.id))
|
||||||
},
|
},
|
||||||
onToggleSortingDirection = screenModel::toggleSortingDirection,
|
onToggleSortingDirection = screenModel::toggleSortingDirection,
|
||||||
onToggleSortingMode = screenModel::toggleSortingMode,
|
onToggleSortingMode = screenModel::toggleSortingMode,
|
||||||
|
|
|
@ -22,12 +22,12 @@ class SourcesFilterScreen : Screen() {
|
||||||
val screenModel = rememberScreenModel { SourcesFilterScreenModel() }
|
val screenModel = rememberScreenModel { SourcesFilterScreenModel() }
|
||||||
val state by screenModel.state.collectAsState()
|
val state by screenModel.state.collectAsState()
|
||||||
|
|
||||||
if (state is SourcesFilterState.Loading) {
|
if (state is SourcesFilterScreenModel.State.Loading) {
|
||||||
LoadingScreen()
|
LoadingScreen()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state is SourcesFilterState.Error) {
|
if (state is SourcesFilterScreenModel.State.Error) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
context.toast(R.string.internal_error)
|
context.toast(R.string.internal_error)
|
||||||
|
@ -36,7 +36,7 @@ class SourcesFilterScreen : Screen() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val successState = state as SourcesFilterState.Success
|
val successState = state as SourcesFilterScreenModel.State.Success
|
||||||
|
|
||||||
SourcesFilterScreen(
|
SourcesFilterScreen(
|
||||||
navigateUp = navigator::pop,
|
navigateUp = navigator::pop,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.ui.browse.source
|
package eu.kanade.tachiyomi.ui.browse.source
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||||
import cafe.adriel.voyager.core.model.coroutineScope
|
import cafe.adriel.voyager.core.model.coroutineScope
|
||||||
import eu.kanade.domain.source.interactor.GetLanguagesWithSources
|
import eu.kanade.domain.source.interactor.GetLanguagesWithSources
|
||||||
|
@ -21,7 +22,7 @@ class SourcesFilterScreenModel(
|
||||||
private val getLanguagesWithSources: GetLanguagesWithSources = Injekt.get(),
|
private val getLanguagesWithSources: GetLanguagesWithSources = Injekt.get(),
|
||||||
private val toggleSource: ToggleSource = Injekt.get(),
|
private val toggleSource: ToggleSource = Injekt.get(),
|
||||||
private val toggleLanguage: ToggleLanguage = Injekt.get(),
|
private val toggleLanguage: ToggleLanguage = Injekt.get(),
|
||||||
) : StateScreenModel<SourcesFilterState>(SourcesFilterState.Loading) {
|
) : StateScreenModel<SourcesFilterScreenModel.State>(State.Loading) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
|
@ -32,14 +33,14 @@ class SourcesFilterScreenModel(
|
||||||
) { a, b, c -> Triple(a, b, c) }
|
) { a, b, c -> Triple(a, b, c) }
|
||||||
.catch { throwable ->
|
.catch { throwable ->
|
||||||
mutableState.update {
|
mutableState.update {
|
||||||
SourcesFilterState.Error(
|
State.Error(
|
||||||
throwable = throwable,
|
throwable = throwable,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.collectLatest { (languagesWithSources, enabledLanguages, disabledSources) ->
|
.collectLatest { (languagesWithSources, enabledLanguages, disabledSources) ->
|
||||||
mutableState.update {
|
mutableState.update {
|
||||||
SourcesFilterState.Success(
|
State.Success(
|
||||||
items = languagesWithSources,
|
items = languagesWithSources,
|
||||||
enabledLanguages = enabledLanguages,
|
enabledLanguages = enabledLanguages,
|
||||||
disabledSources = disabledSources,
|
disabledSources = disabledSources,
|
||||||
|
@ -56,23 +57,26 @@ class SourcesFilterScreenModel(
|
||||||
fun toggleLanguage(language: String) {
|
fun toggleLanguage(language: String) {
|
||||||
toggleLanguage.await(language)
|
toggleLanguage.await(language)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sealed class SourcesFilterState {
|
sealed interface State {
|
||||||
|
|
||||||
data object Loading : SourcesFilterState()
|
@Immutable
|
||||||
|
data object Loading : State
|
||||||
|
|
||||||
|
@Immutable
|
||||||
data class Error(
|
data class Error(
|
||||||
val throwable: Throwable,
|
val throwable: Throwable,
|
||||||
) : SourcesFilterState()
|
) : State
|
||||||
|
|
||||||
|
@Immutable
|
||||||
data class Success(
|
data class Success(
|
||||||
val items: SortedMap<String, List<Source>>,
|
val items: SortedMap<String, List<Source>>,
|
||||||
val enabledLanguages: Set<String>,
|
val enabledLanguages: Set<String>,
|
||||||
val disabledSources: Set<String>,
|
val disabledSources: Set<String>,
|
||||||
) : SourcesFilterState() {
|
) : State {
|
||||||
|
|
||||||
val isEmpty: Boolean
|
val isEmpty: Boolean
|
||||||
get() = items.isEmpty()
|
get() = items.isEmpty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -93,8 +93,8 @@ class SourcesScreenModel(
|
||||||
mutableState.update { it.copy(dialog = null) }
|
mutableState.update { it.copy(dialog = null) }
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Event {
|
sealed interface Event {
|
||||||
data object FailedFetchingSources : Event()
|
data object FailedFetchingSources : Event
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Dialog(val source: Source)
|
data class Dialog(val source: Source)
|
||||||
|
|
|
@ -365,15 +365,15 @@ class BrowseSourceScreenModel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Dialog {
|
sealed interface Dialog {
|
||||||
data object Filter : Dialog()
|
data object Filter : Dialog
|
||||||
data class RemoveManga(val manga: Manga) : Dialog()
|
data class RemoveManga(val manga: Manga) : Dialog
|
||||||
data class AddDuplicateManga(val manga: Manga, val duplicate: Manga) : Dialog()
|
data class AddDuplicateManga(val manga: Manga, val duplicate: Manga) : Dialog
|
||||||
data class ChangeMangaCategory(
|
data class ChangeMangaCategory(
|
||||||
val manga: Manga,
|
val manga: Manga,
|
||||||
val initialSelection: List<CheckboxState.State<Category>>,
|
val initialSelection: List<CheckboxState.State<Category>>,
|
||||||
) : Dialog()
|
) : Dialog
|
||||||
data class Migrate(val newManga: Manga) : Dialog()
|
data class Migrate(val newManga: Manga) : Dialog
|
||||||
}
|
}
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
|
|
|
@ -190,16 +190,16 @@ enum class SourceFilter {
|
||||||
PinnedOnly,
|
PinnedOnly,
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class SearchItemResult {
|
sealed interface SearchItemResult {
|
||||||
data object Loading : SearchItemResult()
|
data object Loading : SearchItemResult
|
||||||
|
|
||||||
data class Error(
|
data class Error(
|
||||||
val throwable: Throwable,
|
val throwable: Throwable,
|
||||||
) : SearchItemResult()
|
) : SearchItemResult
|
||||||
|
|
||||||
data class Success(
|
data class Success(
|
||||||
val result: List<Manga>,
|
val result: List<Manga>,
|
||||||
) : SearchItemResult() {
|
) : SearchItemResult {
|
||||||
val isEmpty: Boolean
|
val isEmpty: Boolean
|
||||||
get() = result.isEmpty()
|
get() = result.isEmpty()
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,27 +107,27 @@ class CategoryScreenModel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class CategoryDialog {
|
sealed interface CategoryDialog {
|
||||||
data object Create : CategoryDialog()
|
data object Create : CategoryDialog
|
||||||
data class Rename(val category: Category) : CategoryDialog()
|
data class Rename(val category: Category) : CategoryDialog
|
||||||
data class Delete(val category: Category) : CategoryDialog()
|
data class Delete(val category: Category) : CategoryDialog
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class CategoryEvent {
|
sealed interface CategoryEvent {
|
||||||
sealed class LocalizedMessage(@StringRes val stringRes: Int) : CategoryEvent()
|
sealed class LocalizedMessage(@StringRes val stringRes: Int) : CategoryEvent
|
||||||
data object InternalError : LocalizedMessage(R.string.internal_error)
|
data object InternalError : LocalizedMessage(R.string.internal_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class CategoryScreenState {
|
sealed interface CategoryScreenState {
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data object Loading : CategoryScreenState()
|
data object Loading : CategoryScreenState
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class Success(
|
data class Success(
|
||||||
val categories: List<Category>,
|
val categories: List<Category>,
|
||||||
val dialog: CategoryDialog? = null,
|
val dialog: CategoryDialog? = null,
|
||||||
) : CategoryScreenState() {
|
) : CategoryScreenState {
|
||||||
|
|
||||||
val isEmpty: Boolean
|
val isEmpty: Boolean
|
||||||
get() = categories.isEmpty()
|
get() = categories.isEmpty()
|
||||||
|
|
|
@ -34,7 +34,7 @@ class HistoryScreenModel(
|
||||||
private val getHistory: GetHistory = Injekt.get(),
|
private val getHistory: GetHistory = Injekt.get(),
|
||||||
private val getNextChapters: GetNextChapters = Injekt.get(),
|
private val getNextChapters: GetNextChapters = Injekt.get(),
|
||||||
private val removeHistory: RemoveHistory = Injekt.get(),
|
private val removeHistory: RemoveHistory = Injekt.get(),
|
||||||
) : StateScreenModel<HistoryState>(HistoryState()) {
|
) : StateScreenModel<HistoryScreenModel.State>(State()) {
|
||||||
|
|
||||||
private val _events: Channel<Event> = Channel(Channel.UNLIMITED)
|
private val _events: Channel<Event> = Channel(Channel.UNLIMITED)
|
||||||
val events: Flow<Event> = _events.receiveAsFlow()
|
val events: Flow<Event> = _events.receiveAsFlow()
|
||||||
|
@ -113,21 +113,21 @@ class HistoryScreenModel(
|
||||||
mutableState.update { it.copy(dialog = dialog) }
|
mutableState.update { it.copy(dialog = dialog) }
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Dialog {
|
|
||||||
data object DeleteAll : Dialog()
|
|
||||||
data class Delete(val history: HistoryWithRelations) : Dialog()
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class Event {
|
|
||||||
data class OpenChapter(val chapter: Chapter?) : Event()
|
|
||||||
data object InternalError : Event()
|
|
||||||
data object HistoryCleared : Event()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class HistoryState(
|
data class State(
|
||||||
val searchQuery: String? = null,
|
val searchQuery: String? = null,
|
||||||
val list: List<HistoryUiModel>? = null,
|
val list: List<HistoryUiModel>? = null,
|
||||||
val dialog: HistoryScreenModel.Dialog? = null,
|
val dialog: Dialog? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
sealed interface Dialog {
|
||||||
|
data object DeleteAll : Dialog
|
||||||
|
data class Delete(val history: HistoryWithRelations) : Dialog
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface Event {
|
||||||
|
data class OpenChapter(val chapter: Chapter?) : Event
|
||||||
|
data object InternalError : Event
|
||||||
|
data object HistoryCleared : Event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -291,11 +291,11 @@ object HomeScreen : Screen() {
|
||||||
showBottomNavEvent.send(show)
|
showBottomNavEvent.send(show)
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Tab {
|
sealed interface Tab {
|
||||||
data class Library(val mangaIdToOpen: Long? = null) : Tab()
|
data class Library(val mangaIdToOpen: Long? = null) : Tab
|
||||||
data object Updates : Tab()
|
data object Updates : Tab
|
||||||
data object History : Tab()
|
data object History : Tab
|
||||||
data class Browse(val toExtensions: Boolean = false) : Tab()
|
data class Browse(val toExtensions: Boolean = false) : Tab
|
||||||
data class More(val toDownloads: Boolean) : Tab()
|
data class More(val toDownloads: Boolean) : Tab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -657,10 +657,10 @@ class LibraryScreenModel(
|
||||||
mutableState.update { it.copy(dialog = null) }
|
mutableState.update { it.copy(dialog = null) }
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Dialog {
|
sealed interface Dialog {
|
||||||
data object SettingsSheet : Dialog()
|
data object SettingsSheet : Dialog
|
||||||
data class ChangeCategory(val manga: List<Manga>, val initialSelection: List<CheckboxState<Category>>) : Dialog()
|
data class ChangeCategory(val manga: List<Manga>, val initialSelection: List<CheckboxState<Category>>) : Dialog
|
||||||
data class DeleteManga(val manga: List<Manga>) : Dialog()
|
data class DeleteManga(val manga: List<Manga>) : Dialog
|
||||||
}
|
}
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
|
|
|
@ -75,12 +75,12 @@ class MangaScreen(
|
||||||
|
|
||||||
val state by screenModel.state.collectAsState()
|
val state by screenModel.state.collectAsState()
|
||||||
|
|
||||||
if (state is MangaScreenState.Loading) {
|
if (state is MangaScreenModel.State.Loading) {
|
||||||
LoadingScreen()
|
LoadingScreen()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val successState = state as MangaScreenState.Success
|
val successState = state as MangaScreenModel.State.Success
|
||||||
val isHttpSource = remember { successState.source is HttpSource }
|
val isHttpSource = remember { successState.source is HttpSource }
|
||||||
|
|
||||||
LaunchedEffect(successState.manga, screenModel.source) {
|
LaunchedEffect(successState.manga, screenModel.source) {
|
||||||
|
|
|
@ -98,10 +98,10 @@ class MangaScreenModel(
|
||||||
private val getTracks: GetTracks = Injekt.get(),
|
private val getTracks: GetTracks = Injekt.get(),
|
||||||
private val setMangaCategories: SetMangaCategories = Injekt.get(),
|
private val setMangaCategories: SetMangaCategories = Injekt.get(),
|
||||||
val snackbarHostState: SnackbarHostState = SnackbarHostState(),
|
val snackbarHostState: SnackbarHostState = SnackbarHostState(),
|
||||||
) : StateScreenModel<MangaScreenState>(MangaScreenState.Loading) {
|
) : StateScreenModel<MangaScreenModel.State>(State.Loading) {
|
||||||
|
|
||||||
private val successState: MangaScreenState.Success?
|
private val successState: State.Success?
|
||||||
get() = state.value as? MangaScreenState.Success
|
get() = state.value as? State.Success
|
||||||
|
|
||||||
private val loggedServices by lazy { trackManager.services.filter { it.isLogged } }
|
private val loggedServices by lazy { trackManager.services.filter { it.isLogged } }
|
||||||
|
|
||||||
|
@ -133,11 +133,11 @@ class MangaScreenModel(
|
||||||
/**
|
/**
|
||||||
* Helper function to update the UI state only if it's currently in success state
|
* Helper function to update the UI state only if it's currently in success state
|
||||||
*/
|
*/
|
||||||
private inline fun updateSuccessState(func: (MangaScreenState.Success) -> MangaScreenState.Success) {
|
private inline fun updateSuccessState(func: (State.Success) -> State.Success) {
|
||||||
mutableState.update {
|
mutableState.update {
|
||||||
when (it) {
|
when (it) {
|
||||||
MangaScreenState.Loading -> it
|
State.Loading -> it
|
||||||
is MangaScreenState.Success -> func(it)
|
is State.Success -> func(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ class MangaScreenModel(
|
||||||
|
|
||||||
// Show what we have earlier
|
// Show what we have earlier
|
||||||
mutableState.update {
|
mutableState.update {
|
||||||
MangaScreenState.Success(
|
State.Success(
|
||||||
manga = manga,
|
manga = manga,
|
||||||
source = Injekt.get<SourceManager>().getOrStub(manga.source),
|
source = Injekt.get<SourceManager>().getOrStub(manga.source),
|
||||||
isFromSource = isFromSource,
|
isFromSource = isFromSource,
|
||||||
|
@ -334,8 +334,7 @@ class MangaScreenModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun promptChangeCategories() {
|
fun promptChangeCategories() {
|
||||||
val state = successState ?: return
|
val manga = successState?.manga ?: return
|
||||||
val manga = state.manga
|
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
val categories = getCategories()
|
val categories = getCategories()
|
||||||
val selection = getMangaCategoryIds(manga)
|
val selection = getMangaCategoryIds(manga)
|
||||||
|
@ -662,9 +661,9 @@ class MangaScreenModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun markPreviousChapterRead(pointer: Chapter) {
|
fun markPreviousChapterRead(pointer: Chapter) {
|
||||||
val successState = successState ?: return
|
val manga = successState?.manga ?: return
|
||||||
val chapters = filteredChapters.orEmpty().map { it.chapter }
|
val chapters = filteredChapters.orEmpty().map { it.chapter }
|
||||||
val prevChapters = if (successState.manga.sortDescending()) chapters.asReversed() else chapters
|
val prevChapters = if (manga.sortDescending()) chapters.asReversed() else chapters
|
||||||
val pointerPos = prevChapters.indexOf(pointer)
|
val pointerPos = prevChapters.indexOf(pointer)
|
||||||
if (pointerPos != -1) markChaptersRead(prevChapters.take(pointerPos), true)
|
if (pointerPos != -1) markChaptersRead(prevChapters.take(pointerPos), true)
|
||||||
}
|
}
|
||||||
|
@ -940,13 +939,13 @@ class MangaScreenModel(
|
||||||
|
|
||||||
// Track sheet - end
|
// Track sheet - end
|
||||||
|
|
||||||
sealed class Dialog {
|
sealed interface Dialog {
|
||||||
data class ChangeCategory(val manga: Manga, val initialSelection: List<CheckboxState<Category>>) : Dialog()
|
data class ChangeCategory(val manga: Manga, val initialSelection: List<CheckboxState<Category>>) : Dialog
|
||||||
data class DeleteChapters(val chapters: List<Chapter>) : Dialog()
|
data class DeleteChapters(val chapters: List<Chapter>) : Dialog
|
||||||
data class DuplicateManga(val manga: Manga, val duplicate: Manga) : Dialog()
|
data class DuplicateManga(val manga: Manga, val duplicate: Manga) : Dialog
|
||||||
data object SettingsSheet : Dialog()
|
data object SettingsSheet : Dialog
|
||||||
data object TrackSheet : Dialog()
|
data object TrackSheet : Dialog
|
||||||
data object FullCover : Dialog()
|
data object FullCover : Dialog
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dismissDialog() {
|
fun dismissDialog() {
|
||||||
|
@ -968,11 +967,10 @@ class MangaScreenModel(
|
||||||
fun showCoverDialog() {
|
fun showCoverDialog() {
|
||||||
updateSuccessState { it.copy(dialog = Dialog.FullCover) }
|
updateSuccessState { it.copy(dialog = Dialog.FullCover) }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sealed class MangaScreenState {
|
sealed interface State {
|
||||||
@Immutable
|
@Immutable
|
||||||
object Loading : MangaScreenState()
|
object Loading : State
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class Success(
|
data class Success(
|
||||||
|
@ -982,9 +980,9 @@ sealed class MangaScreenState {
|
||||||
val chapters: List<ChapterItem>,
|
val chapters: List<ChapterItem>,
|
||||||
val trackItems: List<TrackItem> = emptyList(),
|
val trackItems: List<TrackItem> = emptyList(),
|
||||||
val isRefreshingData: Boolean = false,
|
val isRefreshingData: Boolean = false,
|
||||||
val dialog: MangaScreenModel.Dialog? = null,
|
val dialog: Dialog? = null,
|
||||||
val hasPromptedToAddBefore: Boolean = false,
|
val hasPromptedToAddBefore: Boolean = false,
|
||||||
) : MangaScreenState() {
|
) : State {
|
||||||
|
|
||||||
val processedChapters by lazy {
|
val processedChapters by lazy {
|
||||||
chapters.applyFilters(manga).toList()
|
chapters.applyFilters(manga).toList()
|
||||||
|
@ -1013,6 +1011,7 @@ sealed class MangaScreenState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class ChapterItem(
|
data class ChapterItem(
|
||||||
|
|
|
@ -108,8 +108,8 @@ private class MoreScreenModel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class DownloadQueueState {
|
sealed interface DownloadQueueState {
|
||||||
data object Stopped : DownloadQueueState()
|
data object Stopped : DownloadQueueState
|
||||||
data class Paused(val pending: Int) : DownloadQueueState()
|
data class Paused(val pending: Int) : DownloadQueueState
|
||||||
data class Downloading(val pending: Int) : DownloadQueueState()
|
data class Downloading(val pending: Int) : DownloadQueueState
|
||||||
}
|
}
|
||||||
|
|
|
@ -798,9 +798,9 @@ class ReaderViewModel(
|
||||||
Error,
|
Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class SaveImageResult {
|
sealed interface SaveImageResult {
|
||||||
class Success(val uri: Uri) : SaveImageResult()
|
class Success(val uri: Uri) : SaveImageResult
|
||||||
class Error(val error: Throwable) : SaveImageResult()
|
class Error(val error: Throwable) : SaveImageResult
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -860,18 +860,18 @@ class ReaderViewModel(
|
||||||
get() = viewerChapters?.currChapter?.pages?.size ?: -1
|
get() = viewerChapters?.currChapter?.pages?.size ?: -1
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Dialog {
|
sealed interface Dialog {
|
||||||
data object Loading : Dialog()
|
data object Loading : Dialog
|
||||||
data object Settings : Dialog()
|
data object Settings : Dialog
|
||||||
data class PageActions(val page: ReaderPage) : Dialog()
|
data class PageActions(val page: ReaderPage) : Dialog
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Event {
|
sealed interface Event {
|
||||||
data object ReloadViewerChapters : Event()
|
data object ReloadViewerChapters : Event
|
||||||
data class SetOrientation(val orientation: Int) : Event()
|
data class SetOrientation(val orientation: Int) : Event
|
||||||
data class SetCoverResult(val result: SetAsCoverResult) : Event()
|
data class SetCoverResult(val result: SetAsCoverResult) : Event
|
||||||
|
|
||||||
data class SavedImage(val result: SaveImageResult) : Event()
|
data class SavedImage(val result: SaveImageResult) : Event
|
||||||
data class ShareImage(val uri: Uri, val page: ReaderPage) : Event()
|
data class ShareImage(val uri: Uri, val page: ReaderPage) : Event
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,10 +39,10 @@ data class ReaderChapter(val chapter: Chapter) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class State {
|
sealed interface State {
|
||||||
data object Wait : State()
|
data object Wait : State
|
||||||
data object Loading : State()
|
data object Loading : State
|
||||||
data class Error(val error: Throwable) : State()
|
data class Error(val error: Throwable) : State
|
||||||
data class Loaded(val pages: List<ReaderPage>) : State()
|
data class Loaded(val pages: List<ReaderPage>) : State
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ class UpdatesScreenModel(
|
||||||
private val libraryPreferences: LibraryPreferences = Injekt.get(),
|
private val libraryPreferences: LibraryPreferences = Injekt.get(),
|
||||||
val snackbarHostState: SnackbarHostState = SnackbarHostState(),
|
val snackbarHostState: SnackbarHostState = SnackbarHostState(),
|
||||||
uiPreferences: UiPreferences = Injekt.get(),
|
uiPreferences: UiPreferences = Injekt.get(),
|
||||||
) : StateScreenModel<UpdatesState>(UpdatesState()) {
|
) : StateScreenModel<UpdatesScreenModel.State>(State()) {
|
||||||
|
|
||||||
private val _events: Channel<Event> = Channel(Int.MAX_VALUE)
|
private val _events: Channel<Event> = Channel(Int.MAX_VALUE)
|
||||||
val events: Flow<Event> = _events.receiveAsFlow()
|
val events: Flow<Event> = _events.receiveAsFlow()
|
||||||
|
@ -366,18 +366,8 @@ class UpdatesScreenModel(
|
||||||
libraryPreferences.newUpdatesCount().set(0)
|
libraryPreferences.newUpdatesCount().set(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Dialog {
|
|
||||||
data class DeleteConfirmation(val toDelete: List<UpdatesItem>) : Dialog()
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class Event {
|
|
||||||
data object InternalError : Event()
|
|
||||||
data class LibraryUpdateTriggered(val started: Boolean) : Event()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class UpdatesState(
|
data class State(
|
||||||
val isLoading: Boolean = true,
|
val isLoading: Boolean = true,
|
||||||
val items: List<UpdatesItem> = emptyList(),
|
val items: List<UpdatesItem> = emptyList(),
|
||||||
val dialog: UpdatesScreenModel.Dialog? = null,
|
val dialog: UpdatesScreenModel.Dialog? = null,
|
||||||
|
@ -409,6 +399,16 @@ data class UpdatesState(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed interface Dialog {
|
||||||
|
data class DeleteConfirmation(val toDelete: List<UpdatesItem>) : Dialog
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface Event {
|
||||||
|
data object InternalError : Event
|
||||||
|
data class LibraryUpdateTriggered(val started: Boolean) : Event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class UpdatesItem(
|
data class UpdatesItem(
|
||||||
val update: UpdatesWithRelations,
|
val update: UpdatesWithRelations,
|
||||||
|
|
|
@ -37,8 +37,8 @@ class CreateCategoryWithName(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Result {
|
sealed interface Result {
|
||||||
data object Success : Result()
|
data object Success : Result
|
||||||
data class InternalError(val error: Throwable) : Result()
|
data class InternalError(val error: Throwable) : Result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,8 @@ class DeleteCategory(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Result {
|
sealed interface Result {
|
||||||
data object Success : Result()
|
data object Success : Result
|
||||||
data class InternalError(val error: Throwable) : Result()
|
data class InternalError(val error: Throwable) : Result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,8 @@ class RenameCategory(
|
||||||
|
|
||||||
suspend fun await(category: Category, name: String) = await(category.id, name)
|
suspend fun await(category: Category, name: String) = await(category.id, name)
|
||||||
|
|
||||||
sealed class Result {
|
sealed interface Result {
|
||||||
data object Success : Result()
|
data object Success : Result
|
||||||
data class InternalError(val error: Throwable) : Result()
|
data class InternalError(val error: Throwable) : Result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,10 +57,10 @@ class ReorderCategory(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Result {
|
sealed interface Result {
|
||||||
data object Success : Result()
|
data object Success : Result
|
||||||
data object Unchanged : Result()
|
data object Unchanged : Result
|
||||||
data class InternalError(val error: Throwable) : Result()
|
data class InternalError(val error: Throwable) : Result
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum class MoveTo {
|
private enum class MoveTo {
|
||||||
|
|
|
@ -17,8 +17,8 @@ class UpdateCategory(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class Result {
|
sealed interface Result {
|
||||||
data object Success : Result()
|
data object Success : Result
|
||||||
data class Error(val error: Exception) : Result()
|
data class Error(val error: Exception) : Result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package tachiyomi.domain.library.model
|
package tachiyomi.domain.library.model
|
||||||
|
|
||||||
sealed class LibraryDisplayMode {
|
sealed interface LibraryDisplayMode {
|
||||||
|
|
||||||
data object CompactGrid : LibraryDisplayMode()
|
data object CompactGrid : LibraryDisplayMode
|
||||||
data object ComfortableGrid : LibraryDisplayMode()
|
data object ComfortableGrid : LibraryDisplayMode
|
||||||
data object List : LibraryDisplayMode()
|
data object List : LibraryDisplayMode
|
||||||
data object CoverOnlyGrid : LibraryDisplayMode()
|
data object CoverOnlyGrid : LibraryDisplayMode
|
||||||
|
|
||||||
object Serializer {
|
object Serializer {
|
||||||
fun deserialize(serialized: String): LibraryDisplayMode {
|
fun deserialize(serialized: String): LibraryDisplayMode {
|
||||||
|
|
|
@ -71,9 +71,9 @@ class GetApplicationRelease(
|
||||||
val forceCheck: Boolean = false,
|
val forceCheck: Boolean = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
sealed class Result {
|
sealed interface Result {
|
||||||
data class NewUpdate(val release: Release) : Result()
|
data class NewUpdate(val release: Release) : Result
|
||||||
data object NoNewUpdate : Result()
|
data object NoNewUpdate : Result
|
||||||
data object ThirdPartyInstallation : Result()
|
data object ThirdPartyInstallation : Result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,11 @@ package tachiyomi.source.local.io
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
sealed class Format {
|
sealed interface Format {
|
||||||
data class Directory(val file: File) : Format()
|
data class Directory(val file: File) : Format
|
||||||
data class Zip(val file: File) : Format()
|
data class Zip(val file: File) : Format
|
||||||
data class Rar(val file: File) : Format()
|
data class Rar(val file: File) : Format
|
||||||
data class Epub(val file: File) : Format()
|
data class Epub(val file: File) : Format
|
||||||
|
|
||||||
class UnknownFormatException : Exception()
|
class UnknownFormatException : Exception()
|
||||||
|
|
||||||
|
|
Reference in a new issue