Allow partially read chapters to be marked as unread in updates screen (#8884)

* Allow partially read chapters to be marked as unread in updates screen

* Review changes

* Review changes 2

(cherry picked from commit f301dc64f00c2d8a19cb89610cf6fba7eb78917d)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt
#	app/src/main/sqldelight/migrations/23.sqm
This commit is contained in:
zbue 2023-01-15 07:26:40 +08:00 committed by Jobobby04
parent 7f7789792b
commit 740b3e4616
13 changed files with 178 additions and 79 deletions

View File

@ -31,7 +31,7 @@ android {
applicationId = "eu.kanade.tachiyomi.sy"
minSdk = AndroidConfig.minSdk
targetSdk = AndroidConfig.targetSdk
versionCode = 46
versionCode = 47
versionName = "1.9.0"
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")

View File

@ -3,8 +3,8 @@ package eu.kanade.data.updates
import eu.kanade.domain.manga.model.MangaCover
import eu.kanade.domain.updates.model.UpdatesWithRelations
val updateWithRelationMapper: (Long, String, Long, String, String?, Boolean, Boolean, Long, Boolean, String?, Long, Long, Long) -> UpdatesWithRelations = {
mangaId, mangaTitle, chapterId, chapterName, scanlator, read, bookmark, sourceId, favorite, thumbnailUrl, coverLastModified, _, dateFetch ->
val updateWithRelationMapper: (Long, String, Long, String, String?, Boolean, Boolean, Long, Long, Boolean, String?, Long, Long, Long) -> UpdatesWithRelations = {
mangaId, mangaTitle, chapterId, chapterName, scanlator, read, bookmark, lastPageRead, sourceId, favorite, thumbnailUrl, coverLastModified, _, dateFetch ->
UpdatesWithRelations(
mangaId = mangaId,
// SY -->
@ -15,6 +15,7 @@ val updateWithRelationMapper: (Long, String, Long, String, String?, Boolean, Boo
scanlator = scanlator,
read = read,
bookmark = bookmark,
lastPageRead = lastPageRead,
sourceId = sourceId,
dateFetch = dateFetch,
coverData = MangaCover(

View File

@ -17,11 +17,12 @@ private val mapper = { cursor: SqlCursor ->
cursor.getLong(5)!! == 1L,
cursor.getLong(6)!! == 1L,
cursor.getLong(7)!!,
cursor.getLong(8)!! == 1L,
cursor.getString(9),
cursor.getLong(10)!!,
cursor.getLong(8)!!,
cursor.getLong(9)!! == 1L,
cursor.getString(10),
cursor.getLong(11)!!,
cursor.getLong(12)!!,
cursor.getLong(13)!!,
)
}
@ -38,6 +39,7 @@ class UpdatesQuery(val driver: SqlDriver, val after: Long) : Query<UpdatesWithRe
chapters.scanlator,
chapters.read,
chapters.bookmark,
chapters.last_page_read,
mangas.source,
mangas.favorite,
mangas.thumbnail_url AS thumbnailUrl,
@ -58,6 +60,7 @@ class UpdatesQuery(val driver: SqlDriver, val after: Long) : Query<UpdatesWithRe
chapters.scanlator,
chapters.read,
chapters.bookmark,
chapters.last_page_read,
mangas.source,
mangas.favorite,
mangas.thumbnail_url AS thumbnailUrl,

View File

@ -14,6 +14,7 @@ data class UpdatesWithRelations(
val scanlator: String?,
val read: Boolean,
val bookmark: Boolean,
val lastPageRead: Long,
val sourceId: Long,
val dateFetch: Long,
val coverData: MangaCover,

View File

@ -39,6 +39,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.LocalLayoutDirection
@ -47,6 +48,7 @@ import androidx.compose.ui.util.fastAll
import androidx.compose.ui.util.fastAny
import androidx.compose.ui.util.fastMap
import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.manga.model.Manga
import eu.kanade.presentation.components.ChapterDownloadAction
import eu.kanade.presentation.components.ExtendedFloatingActionButton
import eu.kanade.presentation.components.LazyColumn
@ -82,8 +84,12 @@ import eu.kanade.tachiyomi.source.online.english.Tsumino
import eu.kanade.tachiyomi.ui.manga.ChapterItem
import eu.kanade.tachiyomi.ui.manga.MangaScreenState
import eu.kanade.tachiyomi.ui.manga.PagePreviewState
import eu.kanade.tachiyomi.ui.manga.chapterDecimalFormat
import eu.kanade.tachiyomi.util.lang.toRelativeString
import exh.metadata.MetadataUtil
import exh.source.MERGED_SOURCE_ID
import exh.source.getMainSource
import exh.source.isEhBasedManga
import exh.ui.metadata.adapters.EHentaiDescription
import exh.ui.metadata.adapters.EightMusesDescription
import exh.ui.metadata.adapters.HBrowseDescription
@ -91,11 +97,15 @@ import exh.ui.metadata.adapters.MangaDexDescription
import exh.ui.metadata.adapters.NHentaiDescription
import exh.ui.metadata.adapters.PururinDescription
import exh.ui.metadata.adapters.TsuminoDescription
import java.text.DateFormat
import java.util.Date
@Composable
fun MangaScreen(
state: MangaScreenState.Success,
snackbarHostState: SnackbarHostState,
dateRelativeTime: Int,
dateFormat: DateFormat,
isTabletUi: Boolean,
onBackClicked: () -> Unit,
onChapterClicked: (Chapter) -> Unit,
@ -144,6 +154,8 @@ fun MangaScreen(
MangaScreenSmallImpl(
state = state,
snackbarHostState = snackbarHostState,
dateRelativeTime = dateRelativeTime,
dateFormat = dateFormat,
onBackClicked = onBackClicked,
onChapterClicked = onChapterClicked,
onDownloadChapter = onDownloadChapter,
@ -183,6 +195,8 @@ fun MangaScreen(
MangaScreenLargeImpl(
state = state,
snackbarHostState = snackbarHostState,
dateRelativeTime = dateRelativeTime,
dateFormat = dateFormat,
onBackClicked = onBackClicked,
onChapterClicked = onChapterClicked,
onDownloadChapter = onDownloadChapter,
@ -225,6 +239,8 @@ fun MangaScreen(
private fun MangaScreenSmallImpl(
state: MangaScreenState.Success,
snackbarHostState: SnackbarHostState,
dateRelativeTime: Int,
dateFormat: DateFormat,
onBackClicked: () -> Unit,
onChapterClicked: (Chapter) -> Unit,
onDownloadChapter: ((List<ChapterItem>, ChapterDownloadAction) -> Unit)?,
@ -488,7 +504,13 @@ private fun MangaScreenSmallImpl(
}
sharedChapterItems(
manga = state.manga,
chapters = chapters,
dateRelativeTime = dateRelativeTime,
dateFormat = dateFormat,
// SY -->
alwaysShowReadingProgress = state.alwaysShowReadingProgress,
// SY <--
onChapterClicked = onChapterClicked,
onDownloadChapter = onDownloadChapter,
onChapterSelected = onChapterSelected,
@ -503,6 +525,8 @@ private fun MangaScreenSmallImpl(
fun MangaScreenLargeImpl(
state: MangaScreenState.Success,
snackbarHostState: SnackbarHostState,
dateRelativeTime: Int,
dateFormat: DateFormat,
onBackClicked: () -> Unit,
onChapterClicked: (Chapter) -> Unit,
onDownloadChapter: ((List<ChapterItem>, ChapterDownloadAction) -> Unit)?,
@ -741,7 +765,13 @@ fun MangaScreenLargeImpl(
}
sharedChapterItems(
manga = state.manga,
chapters = chapters,
dateRelativeTime = dateRelativeTime,
dateFormat = dateFormat,
// SY -->
alwaysShowReadingProgress = state.alwaysShowReadingProgress,
// SY <--
onChapterClicked = onChapterClicked,
onDownloadChapter = onDownloadChapter,
onChapterSelected = onChapterSelected,
@ -797,7 +827,13 @@ private fun SharedMangaBottomActionMenu(
}
private fun LazyListScope.sharedChapterItems(
manga: Manga,
chapters: List<ChapterItem>,
dateRelativeTime: Int,
dateFormat: DateFormat,
// SY -->
alwaysShowReadingProgress: Boolean,
// SY <--
onChapterClicked: (Chapter) -> Unit,
onDownloadChapter: ((List<ChapterItem>, ChapterDownloadAction) -> Unit)?,
onChapterSelected: (ChapterItem, Boolean, Boolean, Boolean) -> Unit,
@ -808,10 +844,40 @@ private fun LazyListScope.sharedChapterItems(
contentType = { MangaScreenItem.CHAPTER },
) { chapterItem ->
val haptic = LocalHapticFeedback.current
val context = LocalContext.current
MangaChapterListItem(
title = chapterItem.chapterTitleString,
date = chapterItem.dateUploadString,
readProgress = chapterItem.readProgressString,
title = if (manga.displayMode == Manga.CHAPTER_DISPLAY_NUMBER) {
stringResource(
R.string.display_mode_chapter,
chapterDecimalFormat.format(chapterItem.chapter.chapterNumber.toDouble()),
)
} else {
chapterItem.chapter.name
},
date = chapterItem.chapter.dateUpload
.takeIf { it > 0L }
?.let {
// SY -->
if (manga.isEhBasedManga()) {
MetadataUtil.EX_DATE_FORMAT.format(Date(it))
} else {
Date(it).toRelativeString(
context,
dateRelativeTime,
dateFormat,
)
}
// SY <--
},
readProgress = chapterItem.chapter.lastPageRead
.takeIf { /* SY --> */(!chapterItem.chapter.read || alwaysShowReadingProgress)/* SY <-- */ && it > 0L }
?.let {
stringResource(
R.string.chapter_progress,
it + 1,
)
},
scanlator = chapterItem.chapter.scanlator.takeIf { !it.isNullOrBlank() /* SY --> */ && chapterItem.showScanlator /* SY <-- */ },
// SY -->
sourceName = chapterItem.sourceName,

View File

@ -45,6 +45,9 @@ fun UpdateScreen(
snackbarHostState: SnackbarHostState,
lastUpdated: Long,
relativeTime: Int,
// SY -->
preserveReadingPosition: Boolean,
// SY <--
onClickCover: (UpdatesItem) -> Unit,
onSelectAll: (Boolean) -> Unit,
onInvertSelection: () -> Unit,
@ -117,6 +120,9 @@ fun UpdateScreen(
updatesUiItems(
uiModels = state.getUiModel(context, relativeTime),
selectionMode = state.selectionMode,
// SY -->
preserveReadingPosition = preserveReadingPosition,
// SY <--
onUpdateSelected = onUpdateSelected,
onClickCover = onClickCover,
onClickUpdate = onOpenChapter,
@ -193,7 +199,7 @@ private fun UpdatesBottomBar(
}.takeIf { selected.fastAny { !it.update.read } },
onMarkAsUnreadClicked = {
onMultiMarkAsReadClicked(selected, false)
}.takeIf { selected.fastAny { it.update.read } },
}.takeIf { selected.fastAny { it.update.read || it.update.lastPageRead > 0L } },
onDownloadClicked = {
onDownloadChapter(selected, ChapterDownloadAction.START)
}.takeIf {

View File

@ -38,6 +38,7 @@ import eu.kanade.presentation.components.ChapterDownloadAction
import eu.kanade.presentation.components.ChapterDownloadIndicator
import eu.kanade.presentation.components.ListGroupHeader
import eu.kanade.presentation.components.MangaCover
import eu.kanade.presentation.manga.components.DotSeparatorText
import eu.kanade.presentation.util.ReadItemAlpha
import eu.kanade.presentation.util.padding
import eu.kanade.presentation.util.selectedBackground
@ -80,6 +81,9 @@ fun LazyListScope.updatesLastUpdatedItem(
fun LazyListScope.updatesUiItems(
uiModels: List<UpdatesUiModel>,
selectionMode: Boolean,
// SY -->
preserveReadingPosition: Boolean,
// SY <--
onUpdateSelected: (UpdatesItem, Boolean, Boolean, Boolean) -> Unit,
onClickCover: (UpdatesItem) -> Unit,
onClickUpdate: (UpdatesItem) -> Unit,
@ -113,6 +117,14 @@ fun LazyListScope.updatesUiItems(
modifier = Modifier.animateItemPlacement(),
update = updatesItem.update,
selected = updatesItem.selected,
readProgress = updatesItem.update.lastPageRead
.takeIf { /* SY --> */(!updatesItem.update.read || (preserveReadingPosition && updatesItem.isEhBasedUpdate()))/* SY <-- */ && it > 0L }
?.let {
stringResource(
R.string.chapter_progress,
it + 1,
)
},
onLongClick = {
onUpdateSelected(updatesItem, !updatesItem.selected, true, true)
},
@ -139,6 +151,7 @@ fun UpdatesUiItem(
modifier: Modifier,
update: UpdatesWithRelations,
selected: Boolean,
readProgress: String?,
onClick: () -> Unit,
onLongClick: () -> Unit,
onClickCover: (() -> Unit)?,
@ -203,8 +216,19 @@ fun UpdatesUiItem(
style = MaterialTheme.typography.bodySmall,
overflow = TextOverflow.Ellipsis,
onTextLayout = { textHeight = it.size.height },
modifier = Modifier.alpha(textAlpha),
modifier = Modifier
.weight(weight = 1f, fill = false)
.alpha(textAlpha),
)
if (readProgress != null) {
DotSeparatorText()
Text(
text = readProgress,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.alpha(ReadItemAlpha),
)
}
}
}
ChapterDownloadIndicator(

View File

@ -140,6 +140,8 @@ class MangaScreen(
MangaScreen(
state = successState,
snackbarHostState = screenModel.snackbarHostState,
dateRelativeTime = screenModel.relativeTime,
dateFormat = screenModel.dateFormat,
isTabletUi = isTabletUi(),
onBackClicked = navigator::pop,
onChapterClicked = { openChapter(context, it) },

View File

@ -4,9 +4,12 @@ import android.content.Context
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.SnackbarResult
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import cafe.adriel.voyager.core.model.StateScreenModel
import cafe.adriel.voyager.core.model.coroutineScope
import eu.kanade.core.prefs.CheckboxState
import eu.kanade.core.prefs.asState
import eu.kanade.core.prefs.mapAsCheckboxState
import eu.kanade.core.util.addOrRemove
import eu.kanade.data.chapter.NoChaptersException
@ -75,7 +78,6 @@ import eu.kanade.tachiyomi.util.chapter.getChapterSort
import eu.kanade.tachiyomi.util.chapter.getNextUnread
import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
import eu.kanade.tachiyomi.util.lang.toRelativeString
import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
import eu.kanade.tachiyomi.util.lang.withUIContext
@ -88,7 +90,6 @@ import exh.log.xLogD
import exh.md.utils.FollowStatus
import exh.md.utils.MdUtil
import exh.merged.sql.models.MergedMangaReference
import exh.metadata.MetadataUtil
import exh.metadata.metadata.base.FlatMetadata
import exh.metadata.metadata.base.RaisedSearchMetadata
import exh.source.MERGED_SOURCE_ID
@ -114,10 +115,8 @@ import logcat.LogPriority
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.text.DateFormat
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
import java.util.Date
class MangaInfoScreenModel(
val context: Context,
@ -179,6 +178,9 @@ class MangaInfoScreenModel(
private val processedChapters: Sequence<ChapterItem>?
get() = successState?.processedChapters
val relativeTime by uiPreferences.relativeTime().asState(coroutineScope)
val dateFormat by mutableStateOf(UiPreferences.dateFormat(uiPreferences.dateFormat().get()))
private val selectedPositions: Array<Int> = arrayOf(-1, -1) // first and last selected index in list
private val selectedChapterIds: HashSet<Long> = HashSet()
@ -213,23 +215,6 @@ class MangaInfoScreenModel(
}
init {
val toChapterItemsParams: List<Chapter>.(manga: Manga /* SY --> */, mergedData: MergedMangaData? /* SY <-- */) -> List<ChapterItem> = { manga, mergedData ->
toChapterItems(
context = context,
manga = manga,
// SY -->
dateRelativeTime = if (manga.isEhBasedManga()) 0 else uiPreferences.relativeTime().get(),
dateFormat = if (manga.isEhBasedManga()) {
MetadataUtil.EX_DATE_FORMAT
} else {
UiPreferences.dateFormat(uiPreferences.dateFormat().get())
},
mergedData = mergedData,
alwaysShowReadingProgress = readerPreferences.preserveReadingPosition().get() && manga.isEhBasedManga(),
// SY <--
)
}
coroutineScope.launchIO {
getMangaAndChapters.subscribe(mangaId)
.distinctUntilChanged()
@ -295,7 +280,7 @@ class MangaInfoScreenModel(
.combine(downloadCache.changes) { state, _ -> state }
// SY <--
.collectLatest { (manga, chapters /* SY --> */, flatMetadata, mergedData /* SY <-- */) ->
val chapterItems = chapters.toChapterItemsParams(manga /* SY --> */, mergedData /* SY <-- */)
val chapterItems = chapters.toChapterItems(manga /* SY --> */, mergedData /* SY <-- */)
updateSuccessState {
it.copy(
manga = manga,
@ -316,7 +301,7 @@ class MangaInfoScreenModel(
val manga = getMangaAndChapters.awaitManga(mangaId)
// SY -->
val chapters = (if (manga.source == MERGED_SOURCE_ID) getMergedChapterByMangaId.await(mangaId) else getMangaAndChapters.awaitChapters(mangaId))
.toChapterItemsParams(manga, null)
.toChapterItems(manga, null)
val mergedData = getMergedReferencesById.await(mangaId).takeIf { it.isNotEmpty() }?.let { references ->
MergedMangaData(
references,
@ -358,6 +343,7 @@ class MangaInfoScreenModel(
PagePreviewState.Unused
},
scanlators = getChapterScanlators(manga, chapters.map { it.chapter }),
alwaysShowReadingProgress = readerPreferences.preserveReadingPosition().get() && manga.isEhBasedManga(),
// SY <--
)
}
@ -906,12 +892,8 @@ class MangaInfoScreenModel(
}
private fun List<Chapter>.toChapterItems(
context: Context,
manga: Manga,
dateRelativeTime: Int,
dateFormat: DateFormat,
mergedData: MergedMangaData?,
alwaysShowReadingProgress: Boolean,
): List<ChapterItem> {
val isLocal = manga.isLocal()
// SY -->
@ -951,29 +933,6 @@ class MangaInfoScreenModel(
chapter = chapter,
downloadState = downloadState,
downloadProgress = activeDownload?.progress ?: 0,
chapterTitleString = if (manga.displayMode == Manga.CHAPTER_DISPLAY_NUMBER) {
context.getString(
R.string.display_mode_chapter,
chapterDecimalFormat.format(chapter.chapterNumber.toDouble()),
)
} else {
chapter.name
},
dateUploadString = chapter.dateUpload
.takeIf { it > 0 }
?.let {
Date(it).toRelativeString(
context,
dateRelativeTime,
dateFormat,
)
},
readProgressString = chapter.lastPageRead.takeIf { /* SY --> */(!chapter.read || alwaysShowReadingProgress)/* SY <-- */ && it > 0 }?.let {
context.getString(
R.string.chapter_progress,
it + 1,
)
},
selected = chapter.id in selectedChapterIds,
// SY -->
sourceName = source?.getNameForMangaInfo(null, enabledLanguages = enabledLanguages),
@ -1601,6 +1560,7 @@ sealed class MangaScreenState {
val showMergeWithAnother: Boolean,
val pagePreviewsState: PagePreviewState,
val scanlators: List<String>,
val alwaysShowReadingProgress: Boolean,
// SY <--
) : MangaScreenState() {
@ -1659,11 +1619,6 @@ data class ChapterItem(
val chapter: Chapter,
val downloadState: Download.State,
val downloadProgress: Int,
val chapterTitleString: String,
val dateUploadString: String?,
val readProgressString: String?,
val selected: Boolean = false,
// SY -->

View File

@ -28,11 +28,14 @@ import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
import eu.kanade.tachiyomi.util.lang.toDateKey
import eu.kanade.tachiyomi.util.lang.toRelativeString
import eu.kanade.tachiyomi.util.system.logcat
import exh.source.EH_SOURCE_ID
import exh.source.EXH_SOURCE_ID
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
@ -46,7 +49,6 @@ import kotlinx.coroutines.launch
import logcat.LogPriority
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.text.DateFormat
import java.util.Calendar
import java.util.Date
@ -62,15 +64,20 @@ class UpdatesScreenModel(
private val libraryPreferences: LibraryPreferences = Injekt.get(),
val snackbarHostState: SnackbarHostState = SnackbarHostState(),
uiPreferences: UiPreferences = Injekt.get(),
// SY -->
readerPreferences: ReaderPreferences = Injekt.get(),
// SY <--
) : StateScreenModel<UpdatesState>(UpdatesState()) {
private val _events: Channel<Event> = Channel(Int.MAX_VALUE)
val events: Flow<Event> = _events.receiveAsFlow()
val lastUpdated by libraryPreferences.libraryUpdateLastTimestamp().asState(coroutineScope)
val relativeTime by uiPreferences.relativeTime().asState(coroutineScope)
val relativeTime: Int by uiPreferences.relativeTime().asState(coroutineScope)
val dateFormat: DateFormat by mutableStateOf(UiPreferences.dateFormat(uiPreferences.dateFormat().get()))
// SY -->
val preserveReadingPosition by readerPreferences.preserveReadingPosition().asState(coroutineScope)
// SY <--
// First and last selected index in list
private val selectedPositions: Array<Int> = arrayOf(-1, -1)
@ -110,15 +117,15 @@ class UpdatesScreenModel(
}
private fun List<UpdatesWithRelations>.toUpdateItems(): List<UpdatesItem> {
return this.map {
val activeDownload = downloadManager.getQueuedDownloadOrNull(it.chapterId)
return this.map { update ->
val activeDownload = downloadManager.getQueuedDownloadOrNull(update.chapterId)
val downloaded = downloadManager.isChapterDownloaded(
it.chapterName,
it.scanlator,
update.chapterName,
update.scanlator,
// SY -->
it.ogMangaTitle,
update.ogMangaTitle,
// SY <--
it.sourceId,
update.sourceId,
)
val downloadState = when {
activeDownload != null -> activeDownload.status
@ -126,10 +133,10 @@ class UpdatesScreenModel(
else -> Download.State.NOT_DOWNLOADED
}
UpdatesItem(
update = it,
update = update,
downloadStateProvider = { downloadState },
downloadProgressProvider = { activeDownload?.progress ?: 0 },
selected = it.chapterId in selectedChapterIds,
selected = update.chapterId in selectedChapterIds,
)
}
}
@ -392,7 +399,8 @@ data class UpdatesState(
val selectionMode = selected.isNotEmpty()
fun getUiModel(context: Context, relativeTime: Int): List<UpdatesUiModel> {
val dateFormat = UiPreferences.dateFormat(Injekt.get<UiPreferences>().dateFormat().get())
val dateFormat by mutableStateOf(UiPreferences.dateFormat(Injekt.get<UiPreferences>().dateFormat().get()))
return items
.map { UpdatesUiModel.Item(it) }
.insertSeparators { before, after ->
@ -420,4 +428,10 @@ data class UpdatesItem(
val downloadStateProvider: () -> Download.State,
val downloadProgressProvider: () -> Int,
val selected: Boolean = false,
)
) {
// SY -->
fun isEhBasedUpdate(): Boolean {
return update.sourceId == EH_SOURCE_ID || update.sourceId == EXH_SOURCE_ID
}
// SY <--
}

View File

@ -74,6 +74,9 @@ object UpdatesTab : Tab {
snackbarHostState = screenModel.snackbarHostState,
lastUpdated = screenModel.lastUpdated,
relativeTime = screenModel.relativeTime,
// SY -->
preserveReadingPosition = screenModel.preserveReadingPosition,
// SY <--
onClickCover = { item -> navigator.push(MangaScreen(item.update.mangaId)) },
onSelectAll = screenModel::toggleAllSelection,
onInvertSelection = screenModel::invertSelection,

View File

@ -0,0 +1,23 @@
DROP VIEW IF EXISTS updatesView;
CREATE VIEW updatesView AS
SELECT
mangas._id AS mangaId,
mangas.title AS mangaTitle,
chapters._id AS chapterId,
chapters.name AS chapterName,
chapters.scanlator,
chapters.read,
chapters.bookmark,
chapters.last_page_read,
mangas.source,
mangas.favorite,
mangas.thumbnail_url AS thumbnailUrl,
mangas.cover_last_modified AS coverLastModified,
chapters.date_upload AS dateUpload,
chapters.date_fetch AS datefetch
FROM mangas JOIN chapters
ON mangas._id = chapters.manga_id
WHERE favorite = 1
AND date_fetch > date_added
ORDER BY date_fetch DESC;

View File

@ -7,6 +7,7 @@ SELECT
chapters.scanlator,
chapters.read,
chapters.bookmark,
chapters.last_page_read,
mangas.source,
mangas.favorite,
mangas.thumbnail_url AS thumbnailUrl,