Minor cleanup

(cherry picked from commit abae9bf37dea6bfb351c8b93fe00998c053dba34)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/browse/SourcesScreen.kt
#	app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateSearchScreenDialogScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/MigrateSourceTab.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesFilterScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt
#	domain/src/main/java/tachiyomi/domain/category/interactor/CreateCategoryWithName.kt
This commit is contained in:
arkon 2023-07-23 20:03:37 -04:00 committed by Jobobby04
parent 984bc0b94c
commit ae8b478f51
52 changed files with 395 additions and 384 deletions

View File

@ -91,9 +91,9 @@ class SetReadStatus(
} }
// SY <-- // SY <--
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
} }
} }

View File

@ -54,7 +54,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
@ -66,7 +66,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,

View File

@ -45,7 +45,7 @@ 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.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
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 exh.source.anyIs import exh.source.anyIs
import tachiyomi.presentation.core.components.FastScrollLazyColumn import tachiyomi.presentation.core.components.FastScrollLazyColumn
@ -60,7 +60,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,
@ -111,7 +111,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,

View File

@ -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,
) { ) {

View File

@ -28,7 +28,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
@ -45,7 +45,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,

View File

@ -13,7 +13,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
@ -23,7 +23,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,
// SY --> // SY -->
@ -61,7 +61,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,
// SY --> // SY -->

View File

@ -251,9 +251,9 @@ 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, val isCategory: Boolean) : SourceUiModel() data class Header(val language: String, val isCategory: Boolean) : SourceUiModel
} }
// SY --> // SY -->

View File

@ -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
} }

View File

@ -74,7 +74,7 @@ import eu.kanade.tachiyomi.source.online.english.HBrowse
import eu.kanade.tachiyomi.source.online.english.Pururin import eu.kanade.tachiyomi.source.online.english.Pururin
import eu.kanade.tachiyomi.source.online.english.Tsumino import eu.kanade.tachiyomi.source.online.english.Tsumino
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.ui.manga.PagePreviewState import eu.kanade.tachiyomi.ui.manga.PagePreviewState
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
@ -106,7 +106,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,
@ -264,7 +264,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,
@ -566,7 +566,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,
@ -990,7 +990,7 @@ private fun onChapterItemClick(
} }
// SY --> // SY -->
typealias MetadataDescriptionComposable = @Composable (state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) -> Unit typealias MetadataDescriptionComposable = @Composable (state: MangaScreenModel.State.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) -> Unit
@Composable @Composable
fun metadataDescription(source: Source): MetadataDescriptionComposable? { fun metadataDescription(source: Source): MetadataDescriptionComposable? {

View File

@ -20,6 +20,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.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -304,12 +305,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
} }
} }

View File

@ -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
} }

View File

@ -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
} }

View File

@ -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,
@ -215,7 +215,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
} }

View File

@ -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) {

View File

@ -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
} }

View File

@ -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()

View File

@ -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>>

View File

@ -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
}

View File

@ -19,7 +19,8 @@ import tachiyomi.domain.UnsortedPreferences
import tachiyomi.presentation.core.screens.LoadingScreen import tachiyomi.presentation.core.screens.LoadingScreen
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
data class MigrationMangaScreen(
data class MigrateMangaScreen(
private val sourceId: Long, private val sourceId: Long,
) : Screen() { ) : Screen() {
@ -27,7 +28,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()

View File

@ -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
}

View File

@ -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
}
}

View File

@ -16,7 +16,7 @@ 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.advanced.design.PreMigrationScreen import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationScreen
import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrationMangaScreen import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrateMangaScreen
import tachiyomi.core.util.lang.launchIO import tachiyomi.core.util.lang.launchIO
import tachiyomi.core.util.lang.withUIContext import tachiyomi.core.util.lang.withUIContext
import tachiyomi.domain.UnsortedPreferences import tachiyomi.domain.UnsortedPreferences
@ -47,7 +47,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,

View File

@ -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,

View File

@ -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,
@ -62,23 +63,26 @@ class SourcesFilterScreenModel(
toggleSource.await(sources.map { it.id }, enable) toggleSource.await(sources.map { it.id }, enable)
} }
// SY <-- // SY <--
}
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()
} }
} }
}

View File

@ -160,8 +160,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
} }
sealed class Dialog { sealed class Dialog {

View File

@ -474,19 +474,19 @@ open 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
// SY --> // SY -->
data class DeleteSavedSearch(val idToDelete: Long, val name: String) : Dialog() data class DeleteSavedSearch(val idToDelete: Long, val name: String) : Dialog
data class CreateSavedSearch(val currentSavedSearches: List<String>) : Dialog() data class CreateSavedSearch(val currentSavedSearches: List<String>) : Dialog
// SY <-- // SY <--
} }

View File

@ -193,16 +193,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()
} }

View File

@ -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()

View File

@ -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
}
}

View File

@ -309,11 +309,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
} }
} }

View File

@ -1114,12 +1114,12 @@ 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
object SyncFavoritesWarning : Dialog() object SyncFavoritesWarning : Dialog
object SyncFavoritesConfirm : Dialog() object SyncFavoritesConfirm : Dialog
} }
// SY --> // SY -->

View File

@ -101,12 +101,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) {
@ -272,14 +272,14 @@ class MangaScreen(
} }
} }
// SY --> // SY -->
is MangaInfoScreenModel.Dialog.EditMangaInfo -> { is MangaScreenModel.Dialog.EditMangaInfo -> {
EditMangaDialog( EditMangaDialog(
manga = dialog.manga, manga = dialog.manga,
onDismissRequest = screenModel::dismissDialog, onDismissRequest = screenModel::dismissDialog,
onPositiveClick = screenModel::updateMangaInfo, onPositiveClick = screenModel::updateMangaInfo,
) )
} }
is MangaInfoScreenModel.Dialog.EditMergedSettings -> { is MangaScreenModel.Dialog.EditMergedSettings -> {
EditMergedSettingsDialog( EditMergedSettingsDialog(
mergedData = dialog.mergedData, mergedData = dialog.mergedData,
onDismissRequest = screenModel::dismissDialog, onDismissRequest = screenModel::dismissDialog,

View File

@ -162,10 +162,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 } }
@ -218,11 +218,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)
} }
} }
} }
@ -337,7 +337,7 @@ class MangaScreenModel(
// Show what we have earlier // Show what we have earlier
mutableState.update { mutableState.update {
val source = sourceManager.getOrStub(manga.source) val source = sourceManager.getOrStub(manga.source)
MangaScreenState.Success( State.Success(
manga = manga, manga = manga,
source = source, source = source,
isFromSource = isFromSource, isFromSource = isFromSource,
@ -755,8 +755,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)
@ -1145,9 +1144,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)
} }
@ -1472,19 +1471,19 @@ 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
// SY --> // SY -->
data class EditMangaInfo(val manga: Manga) : Dialog() data class EditMangaInfo(val manga: Manga) : Dialog
data class EditMergedSettings(val mergedData: MergedMangaData) : Dialog() data class EditMergedSettings(val mergedData: MergedMangaData) : Dialog
// SY <-- // SY <--
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() {
@ -1511,8 +1510,8 @@ class MangaScreenModel(
fun showEditMangaInfoDialog() { fun showEditMangaInfoDialog() {
mutableState.update { state -> mutableState.update { state ->
when (state) { when (state) {
MangaScreenState.Loading -> state State.Loading -> state
is MangaScreenState.Success -> { is State.Success -> {
state.copy(dialog = Dialog.EditMangaInfo(state.manga)) state.copy(dialog = Dialog.EditMangaInfo(state.manga))
} }
} }
@ -1523,25 +1522,18 @@ class MangaScreenModel(
val mergedData = successState?.mergedData ?: return val mergedData = successState?.mergedData ?: return
mutableState.update { state -> mutableState.update { state ->
when (state) { when (state) {
MangaScreenState.Loading -> state State.Loading -> state
is MangaScreenState.Success -> { is State.Success -> {
state.copy(dialog = Dialog.EditMergedSettings(mergedData)) state.copy(dialog = Dialog.EditMergedSettings(mergedData))
} }
} }
} }
} }
// SY <-- // SY <--
}
data class MergedMangaData( sealed interface State {
val references: List<MergedMangaReference>,
val manga: Map<Long, Manga>,
val sources: List<Source>,
)
sealed class MangaScreenState {
@Immutable @Immutable
object Loading : MangaScreenState() data object Loading : State
@Immutable @Immutable
data class Success( data class Success(
@ -1563,7 +1555,7 @@ sealed class MangaScreenState {
val scanlators: List<String>, val scanlators: List<String>,
val alwaysShowReadingProgress: Boolean, val alwaysShowReadingProgress: Boolean,
// SY <-- // SY <--
) : MangaScreenState() { ) : State {
val processedChapters by lazy { val processedChapters by lazy {
chapters.applyFilters(manga).toList() chapters.applyFilters(manga).toList()
@ -1597,6 +1589,13 @@ sealed class MangaScreenState {
} }
} }
} }
}
data class MergedMangaData(
val references: List<MergedMangaReference>,
val manga: Map<Long, Manga>,
val sources: List<Source>,
)
@Immutable @Immutable
data class ChapterItem( data class ChapterItem(
@ -1614,10 +1613,10 @@ data class ChapterItem(
} }
// SY --> // SY -->
sealed class PagePreviewState { sealed interface PagePreviewState {
object Unused : PagePreviewState() object Unused : PagePreviewState
object Loading : PagePreviewState() object Loading : PagePreviewState
data class Success(val pagePreviews: List<PagePreview>) : PagePreviewState() data class Success(val pagePreviews: List<PagePreview>) : PagePreviewState
data class Error(val error: Throwable) : PagePreviewState() data class Error(val error: Throwable) : PagePreviewState
} }
// SY <-- // SY <--

View File

@ -129,8 +129,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
} }

View File

@ -1077,9 +1077,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
} }
/** /**
@ -1156,18 +1156,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/* SY --> */, val extraPage: ReaderPage? = null /* SY <-- */) : Dialog() data class PageActions(val page: ReaderPage/* SY --> */, val extraPage: ReaderPage? = null /* SY <-- */) : 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, val secondPage: ReaderPage? = null) : Event() data class ShareImage(val uri: Uri, val page: ReaderPage/* SY --> */, val secondPage: ReaderPage? = null /* SY <-- */) : Event
} }
} }

View File

@ -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
} }
} }

View File

@ -66,7 +66,7 @@ class UpdatesScreenModel(
// SY --> // SY -->
readerPreferences: ReaderPreferences = Injekt.get(), readerPreferences: ReaderPreferences = Injekt.get(),
// SY <-- // SY <--
) : 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()
@ -378,18 +378,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,
@ -421,6 +411,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,

View File

@ -9,14 +9,14 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.DescriptionAdapterEhBinding import eu.kanade.tachiyomi.databinding.DescriptionAdapterEhBinding
import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.ui.manga.MangaScreenModel.State
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import exh.metadata.MetadataUtil import exh.metadata.MetadataUtil
import exh.metadata.metadata.EHentaiSearchMetadata import exh.metadata.metadata.EHentaiSearchMetadata
import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable
@Composable @Composable
fun EHentaiDescription(state: MangaScreenState.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) { fun EHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit, search: (String) -> Unit) {
val context = LocalContext.current val context = LocalContext.current
AndroidView( AndroidView(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),

View File

@ -8,13 +8,13 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.DescriptionAdapter8mBinding import eu.kanade.tachiyomi.databinding.DescriptionAdapter8mBinding
import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.ui.manga.MangaScreenModel.State
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import exh.metadata.metadata.EightMusesSearchMetadata import exh.metadata.metadata.EightMusesSearchMetadata
import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable
@Composable @Composable
fun EightMusesDescription(state: MangaScreenState.Success, openMetadataViewer: () -> Unit) { fun EightMusesDescription(state: State.Success, openMetadataViewer: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
AndroidView( AndroidView(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),

View File

@ -8,13 +8,13 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.DescriptionAdapterHbBinding import eu.kanade.tachiyomi.databinding.DescriptionAdapterHbBinding
import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.ui.manga.MangaScreenModel.State
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import exh.metadata.metadata.HBrowseSearchMetadata import exh.metadata.metadata.HBrowseSearchMetadata
import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable
@Composable @Composable
fun HBrowseDescription(state: MangaScreenState.Success, openMetadataViewer: () -> Unit) { fun HBrowseDescription(state: State.Success, openMetadataViewer: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
AndroidView( AndroidView(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),

View File

@ -10,7 +10,7 @@ import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.isVisible import androidx.core.view.isVisible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.DescriptionAdapterMdBinding import eu.kanade.tachiyomi.databinding.DescriptionAdapterMdBinding
import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.ui.manga.MangaScreenModel.State
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import exh.metadata.metadata.MangaDexSearchMetadata import exh.metadata.metadata.MangaDexSearchMetadata
import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable
@ -18,7 +18,7 @@ import exh.ui.metadata.adapters.MetadataUIUtil.getRatingString
import kotlin.math.round import kotlin.math.round
@Composable @Composable
fun MangaDexDescription(state: MangaScreenState.Success, openMetadataViewer: () -> Unit) { fun MangaDexDescription(state: State.Success, openMetadataViewer: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
AndroidView( AndroidView(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),

View File

@ -9,7 +9,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.DescriptionAdapterNhBinding import eu.kanade.tachiyomi.databinding.DescriptionAdapterNhBinding
import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.ui.manga.MangaScreenModel.State
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import exh.metadata.MetadataUtil import exh.metadata.MetadataUtil
import exh.metadata.metadata.NHentaiSearchMetadata import exh.metadata.metadata.NHentaiSearchMetadata
@ -17,7 +17,7 @@ import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable
import java.util.Date import java.util.Date
@Composable @Composable
fun NHentaiDescription(state: MangaScreenState.Success, openMetadataViewer: () -> Unit) { fun NHentaiDescription(state: State.Success, openMetadataViewer: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
AndroidView( AndroidView(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),

View File

@ -9,14 +9,14 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.DescriptionAdapterPuBinding import eu.kanade.tachiyomi.databinding.DescriptionAdapterPuBinding
import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.ui.manga.MangaScreenModel.State
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import exh.metadata.metadata.PururinSearchMetadata import exh.metadata.metadata.PururinSearchMetadata
import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable
import kotlin.math.round import kotlin.math.round
@Composable @Composable
fun PururinDescription(state: MangaScreenState.Success, openMetadataViewer: () -> Unit) { fun PururinDescription(state: State.Success, openMetadataViewer: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
AndroidView( AndroidView(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),

View File

@ -9,7 +9,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.DescriptionAdapterTsBinding import eu.kanade.tachiyomi.databinding.DescriptionAdapterTsBinding
import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.ui.manga.MangaScreenModel.State
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import exh.metadata.metadata.TsuminoSearchMetadata import exh.metadata.metadata.TsuminoSearchMetadata
import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable
@ -17,7 +17,7 @@ import java.util.Date
import kotlin.math.round import kotlin.math.round
@Composable @Composable
fun TsuminoDescription(state: MangaScreenState.Success, openMetadataViewer: () -> Unit) { fun TsuminoDescription(state: State.Success, openMetadataViewer: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
AndroidView( AndroidView(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),

View File

@ -37,11 +37,11 @@ class CreateCategoryWithName(
} }
} }
sealed class Result { sealed interface Result {
// SY --> // SY -->
data class Success(val category: Category) : Result() data class Success(val category: Category) : Result
// SY <-- // SY <--
data class InternalError(val error: Throwable) : Result() data class InternalError(val error: Throwable) : Result
} }
} }

View File

@ -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
} }
} }

View File

@ -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
} }
} }

View File

@ -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 {

View File

@ -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
} }
} }

View File

@ -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 {

View File

@ -79,9 +79,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
} }
} }

View File

@ -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()