diff --git a/composeApp/src/androidMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.android.kt b/composeApp/src/androidMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.android.kt index cf1e4b4..770f060 100644 --- a/composeApp/src/androidMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.android.kt +++ b/composeApp/src/androidMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.android.kt @@ -54,57 +54,41 @@ actual class BurningSeriesResolver( actual val isAvailable: Boolean get() = packageInfo != null - actual fun resolveWatchedEpisodes(): ImmutableSet { + actual fun resolveWatchedEpisode(seriesHref: String): Int? = scopeCatching { if (episodeClient == null) { - return persistentSetOf() + return@scopeCatching null } val episodeCursor = episodeClient.query( episodesContentUri, + arrayOf("MAX(number) as number"), + "finished = 1 AND seriesHref = '$seriesHref'", null, - "progress > 0 AND length > 0", - null, - null - ) ?: return persistentSetOf() - - val episodes = mutableSetOf() + "number DESC" + ) ?: return@scopeCatching null + var max: Int? = null if (episodeCursor.moveToFirst()) { while (!episodeCursor.isAfterLast) { - val progressIndex = episodeCursor.getColumnIndex("progress") - val lengthIndex = episodeCursor.getColumnIndex("length") val numberIndex = episodeCursor.getColumnIndex("number") - val seriesHrefIndex = episodeCursor.getColumnIndex("seriesHref") - if (progressIndex == -1 || lengthIndex == -1 || numberIndex == -1 || seriesHrefIndex == -1) { + if (numberIndex == -1) { episodeCursor.moveToNext() continue } - val progress = episodeCursor.getLong(progressIndex) - val length = episodeCursor.getLong(lengthIndex) - val number = episodeCursor.getString(numberIndex) - val seriesHref = episodeCursor.getString(seriesHrefIndex) - - episodes.add( - Episode( - progress = progress, - length = length, - number = number, - series = Series( - title = seriesHref, - href = seriesHref - ) - ) - ) + val number = episodeCursor.getInt(numberIndex) + if (max == null || number > max) { + max = number + } episodeCursor.moveToNext() } } episodeCursor.close() - return episodes.toImmutableSet() - } + return@scopeCatching max + }.getOrNull() actual fun resolveByName(english: String?, romaji: String?): ImmutableSet { val englishTrimmed = english?.trim()?.ifBlank { null }?.replace("'", "")?.trim() @@ -115,29 +99,29 @@ actual class BurningSeriesResolver( } val selection = if (englishTrimmed != null && romajiTrimmed != null) { - "fullTitle LIKE '%$englishTrimmed%' OR fullTitle LIKE '%$romajiTrimmed%'" + "isAnime = 1 AND fullTitle LIKE '%$englishTrimmed%' OR fullTitle LIKE '%$romajiTrimmed%'" } else if (englishTrimmed != null) { - "fullTitle LIKE '%$englishTrimmed%'" + "isAnime = 1 AND fullTitle LIKE '%$englishTrimmed%'" } else { - "fullTitle LIKE '%$romajiTrimmed%'" + "isAnime = 1 AND fullTitle LIKE '%$romajiTrimmed%'" } return seriesBySelection(selection).ifEmpty { val mainTitleSelection = if (englishTrimmed != null && romajiTrimmed != null) { - "mainTitle LIKE '%$englishTrimmed%' OR mainTitle LIKE '%$romajiTrimmed%'" + "isAnime = 1 AND mainTitle LIKE '%$englishTrimmed%' OR mainTitle LIKE '%$romajiTrimmed%'" } else if (englishTrimmed != null) { - "mainTitle LIKE '%$englishTrimmed%'" + "isAnime = 1 AND mainTitle LIKE '%$englishTrimmed%'" } else { - "mainTitle LIKE '%$romajiTrimmed%'" + "isAnime = 1 AND mainTitle LIKE '%$romajiTrimmed%'" } seriesBySelection(mainTitleSelection).ifEmpty { val subTitleSelection = if (englishTrimmed != null && romajiTrimmed != null) { - "subTitle LIKE '%$englishTrimmed%' OR subTitle LIKE '%$romajiTrimmed%'" + "isAnime = 1 AND subTitle LIKE '%$englishTrimmed%' OR subTitle LIKE '%$romajiTrimmed%'" } else if (englishTrimmed != null) { - "subTitle LIKE '%$englishTrimmed%'" + "isAnime = 1 AND subTitle LIKE '%$englishTrimmed%'" } else { - "subTitle LIKE '%$romajiTrimmed%'" + "isAnime = 1 AND subTitle LIKE '%$romajiTrimmed%'" } seriesBySelection(subTitleSelection) @@ -149,7 +133,7 @@ actual class BurningSeriesResolver( val trimmed = value.trim().replace("'", "").trim() return if (trimmed.length >= 3) { - seriesBySelection("fullTitle LIKE '%$trimmed%'") + seriesBySelection("isAnime = 1 AND fullTitle LIKE '%$trimmed%'") } else { persistentSetOf() } diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.kt index 479ad20..b56fc8e 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/other/BurningSeriesResolver.kt @@ -7,20 +7,13 @@ expect class BurningSeriesResolver { val versionCode: Int val versionName: String? - fun resolveWatchedEpisodes(): ImmutableSet + fun resolveWatchedEpisode(seriesHref: String): Int? fun resolveByName(english: String?, romaji: String?): ImmutableSet fun resolveByName(value: String): ImmutableSet fun close() } -data class Episode( - val progress: Long, - val length: Long, - val number: String, - val series: Series -) - data class Series( val title: String, val href: String diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/DialogConfig.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/DialogConfig.kt index 1cb21b7..fde89b0 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/DialogConfig.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/DialogConfig.kt @@ -12,5 +12,7 @@ sealed class DialogConfig { ) : DialogConfig() @Serializable - data object Edit : DialogConfig() + data class Edit( + val watched: Int? = null + ) : DialogConfig() } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumComponent.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumComponent.kt index bb0e268..c3c098d 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumComponent.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumComponent.kt @@ -76,4 +76,5 @@ interface MediumComponent : ContentHolderComponent { fun edit() suspend fun searchBS(value: String) + fun selectBS(series: Series) } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumScreenComponent.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumScreenComponent.kt index db6d3be..d512008 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumScreenComponent.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/MediumScreenComponent.kt @@ -262,7 +262,7 @@ class MediumScreenComponent( componentContext = context, di = di, episodesOrChapters = episodesOrChapters, - progress = watchProgress, + progress = config.watched?.let(::flowOf) ?: watchProgress, listStatus = listStatus, repeatCount = watchRepeat, episodeStartDate = mediumSuccessState.mapLatest { @@ -374,10 +374,16 @@ class MediumScreenComponent( } override fun edit() { - dialogNavigation.activate(DialogConfig.Edit) + dialogNavigation.activate(DialogConfig.Edit()) } override suspend fun searchBS(value: String) { bsSearch.update { value } } + + override fun selectBS(series: Series) { + val max = burningSeriesResolver.resolveWatchedEpisode(series.href) + + dialogNavigation.activate(DialogConfig.Edit(max)) + } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/component/BSDialog.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/component/BSDialog.kt index 4e0d8d4..67679d6 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/component/BSDialog.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/component/BSDialog.kt @@ -31,7 +31,8 @@ fun BSDialog( bsVersionCode: Int, bsVersionName: String?, bsOptions: ImmutableCollection, - onSearch: suspend (String) -> Unit + onSearch: suspend (String) -> Unit, + onSelect: (Series) -> Unit ) { OptionDialog( state = state, @@ -45,7 +46,7 @@ fun BSDialog( ) }, onSelectOption = { option, _ -> - + onSelect(bsOptions.toList()[option]) } ), header = Header.Default( diff --git a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/component/FABContent.kt b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/component/FABContent.kt index 62c1c29..fba0aa7 100644 --- a/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/component/FABContent.kt +++ b/composeApp/src/commonMain/kotlin/dev/datlag/aniflow/ui/navigation/screen/medium/component/FABContent.kt @@ -84,7 +84,8 @@ fun FABContent( bsVersionCode = component.bsVersionCode, bsVersionName = component.bsVersionName, bsOptions = bsOptions, - onSearch = component::searchBS + onSearch = component::searchBS, + onSelect = component::selectBS ) RatingDialog(