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
This commit is contained in:
zbue 2023-01-15 07:26:40 +08:00 committed by GitHub
parent 33a2219716
commit f301dc64f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 125 additions and 69 deletions

View File

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

View File

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

View File

@ -39,6 +39,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.LocalLayoutDirection 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.fastAny
import androidx.compose.ui.util.fastMap import androidx.compose.ui.util.fastMap
import eu.kanade.domain.chapter.model.Chapter 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.ChapterDownloadAction
import eu.kanade.presentation.components.ExtendedFloatingActionButton import eu.kanade.presentation.components.ExtendedFloatingActionButton
import eu.kanade.presentation.components.LazyColumn import eu.kanade.presentation.components.LazyColumn
@ -69,11 +71,17 @@ import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.getNameForMangaInfo import eu.kanade.tachiyomi.source.getNameForMangaInfo
import eu.kanade.tachiyomi.ui.manga.ChapterItem import eu.kanade.tachiyomi.ui.manga.ChapterItem
import eu.kanade.tachiyomi.ui.manga.MangaScreenState import eu.kanade.tachiyomi.ui.manga.MangaScreenState
import eu.kanade.tachiyomi.ui.manga.chapterDecimalFormat
import eu.kanade.tachiyomi.util.lang.toRelativeString
import java.text.DateFormat
import java.util.Date
@Composable @Composable
fun MangaScreen( fun MangaScreen(
state: MangaScreenState.Success, state: MangaScreenState.Success,
snackbarHostState: SnackbarHostState, snackbarHostState: SnackbarHostState,
dateRelativeTime: Int,
dateFormat: DateFormat,
isTabletUi: Boolean, isTabletUi: Boolean,
onBackClicked: () -> Unit, onBackClicked: () -> Unit,
onChapterClicked: (Chapter) -> Unit, onChapterClicked: (Chapter) -> Unit,
@ -112,6 +120,8 @@ fun MangaScreen(
MangaScreenSmallImpl( MangaScreenSmallImpl(
state = state, state = state,
snackbarHostState = snackbarHostState, snackbarHostState = snackbarHostState,
dateRelativeTime = dateRelativeTime,
dateFormat = dateFormat,
onBackClicked = onBackClicked, onBackClicked = onBackClicked,
onChapterClicked = onChapterClicked, onChapterClicked = onChapterClicked,
onDownloadChapter = onDownloadChapter, onDownloadChapter = onDownloadChapter,
@ -141,6 +151,8 @@ fun MangaScreen(
MangaScreenLargeImpl( MangaScreenLargeImpl(
state = state, state = state,
snackbarHostState = snackbarHostState, snackbarHostState = snackbarHostState,
dateRelativeTime = dateRelativeTime,
dateFormat = dateFormat,
onBackClicked = onBackClicked, onBackClicked = onBackClicked,
onChapterClicked = onChapterClicked, onChapterClicked = onChapterClicked,
onDownloadChapter = onDownloadChapter, onDownloadChapter = onDownloadChapter,
@ -173,6 +185,8 @@ fun MangaScreen(
private fun MangaScreenSmallImpl( private fun MangaScreenSmallImpl(
state: MangaScreenState.Success, state: MangaScreenState.Success,
snackbarHostState: SnackbarHostState, snackbarHostState: SnackbarHostState,
dateRelativeTime: Int,
dateFormat: DateFormat,
onBackClicked: () -> Unit, onBackClicked: () -> Unit,
onChapterClicked: (Chapter) -> Unit, onChapterClicked: (Chapter) -> Unit,
onDownloadChapter: ((List<ChapterItem>, ChapterDownloadAction) -> Unit)?, onDownloadChapter: ((List<ChapterItem>, ChapterDownloadAction) -> Unit)?,
@ -364,7 +378,10 @@ private fun MangaScreenSmallImpl(
} }
sharedChapterItems( sharedChapterItems(
manga = state.manga,
chapters = chapters, chapters = chapters,
dateRelativeTime = dateRelativeTime,
dateFormat = dateFormat,
onChapterClicked = onChapterClicked, onChapterClicked = onChapterClicked,
onDownloadChapter = onDownloadChapter, onDownloadChapter = onDownloadChapter,
onChapterSelected = onChapterSelected, onChapterSelected = onChapterSelected,
@ -379,6 +396,8 @@ private fun MangaScreenSmallImpl(
fun MangaScreenLargeImpl( fun MangaScreenLargeImpl(
state: MangaScreenState.Success, state: MangaScreenState.Success,
snackbarHostState: SnackbarHostState, snackbarHostState: SnackbarHostState,
dateRelativeTime: Int,
dateFormat: DateFormat,
onBackClicked: () -> Unit, onBackClicked: () -> Unit,
onChapterClicked: (Chapter) -> Unit, onChapterClicked: (Chapter) -> Unit,
onDownloadChapter: ((List<ChapterItem>, ChapterDownloadAction) -> Unit)?, onDownloadChapter: ((List<ChapterItem>, ChapterDownloadAction) -> Unit)?,
@ -564,7 +583,10 @@ fun MangaScreenLargeImpl(
} }
sharedChapterItems( sharedChapterItems(
manga = state.manga,
chapters = chapters, chapters = chapters,
dateRelativeTime = dateRelativeTime,
dateFormat = dateFormat,
onChapterClicked = onChapterClicked, onChapterClicked = onChapterClicked,
onDownloadChapter = onDownloadChapter, onDownloadChapter = onDownloadChapter,
onChapterSelected = onChapterSelected, onChapterSelected = onChapterSelected,
@ -620,7 +642,10 @@ private fun SharedMangaBottomActionMenu(
} }
private fun LazyListScope.sharedChapterItems( private fun LazyListScope.sharedChapterItems(
manga: Manga,
chapters: List<ChapterItem>, chapters: List<ChapterItem>,
dateRelativeTime: Int,
dateFormat: DateFormat,
onChapterClicked: (Chapter) -> Unit, onChapterClicked: (Chapter) -> Unit,
onDownloadChapter: ((List<ChapterItem>, ChapterDownloadAction) -> Unit)?, onDownloadChapter: ((List<ChapterItem>, ChapterDownloadAction) -> Unit)?,
onChapterSelected: (ChapterItem, Boolean, Boolean, Boolean) -> Unit, onChapterSelected: (ChapterItem, Boolean, Boolean, Boolean) -> Unit,
@ -631,10 +656,34 @@ private fun LazyListScope.sharedChapterItems(
contentType = { MangaScreenItem.CHAPTER }, contentType = { MangaScreenItem.CHAPTER },
) { chapterItem -> ) { chapterItem ->
val haptic = LocalHapticFeedback.current val haptic = LocalHapticFeedback.current
val context = LocalContext.current
MangaChapterListItem( MangaChapterListItem(
title = chapterItem.chapterTitleString, title = if (manga.displayMode == Manga.CHAPTER_DISPLAY_NUMBER) {
date = chapterItem.dateUploadString, stringResource(
readProgress = chapterItem.readProgressString, R.string.display_mode_chapter,
chapterDecimalFormat.format(chapterItem.chapter.chapterNumber.toDouble()),
)
} else {
chapterItem.chapter.name
},
date = chapterItem.chapter.dateUpload
.takeIf { it > 0L }
?.let {
Date(it).toRelativeString(
context,
dateRelativeTime,
dateFormat,
)
},
readProgress = chapterItem.chapter.lastPageRead
.takeIf { !chapterItem.chapter.read && it > 0L }
?.let {
stringResource(
R.string.chapter_progress,
it + 1,
)
},
scanlator = chapterItem.chapter.scanlator.takeIf { !it.isNullOrBlank() }, scanlator = chapterItem.chapter.scanlator.takeIf { !it.isNullOrBlank() },
read = chapterItem.chapter.read, read = chapterItem.chapter.read,
bookmark = chapterItem.chapter.bookmark, bookmark = chapterItem.chapter.bookmark,

View File

@ -193,7 +193,7 @@ private fun UpdatesBottomBar(
}.takeIf { selected.fastAny { !it.update.read } }, }.takeIf { selected.fastAny { !it.update.read } },
onMarkAsUnreadClicked = { onMarkAsUnreadClicked = {
onMultiMarkAsReadClicked(selected, false) onMultiMarkAsReadClicked(selected, false)
}.takeIf { selected.fastAny { it.update.read } }, }.takeIf { selected.fastAny { it.update.read || it.update.lastPageRead > 0L } },
onDownloadClicked = { onDownloadClicked = {
onDownloadChapter(selected, ChapterDownloadAction.START) onDownloadChapter(selected, ChapterDownloadAction.START)
}.takeIf { }.takeIf {

View File

@ -38,6 +38,7 @@ import eu.kanade.presentation.components.ChapterDownloadAction
import eu.kanade.presentation.components.ChapterDownloadIndicator import eu.kanade.presentation.components.ChapterDownloadIndicator
import eu.kanade.presentation.components.ListGroupHeader import eu.kanade.presentation.components.ListGroupHeader
import eu.kanade.presentation.components.MangaCover import eu.kanade.presentation.components.MangaCover
import eu.kanade.presentation.manga.components.DotSeparatorText
import eu.kanade.presentation.util.ReadItemAlpha import eu.kanade.presentation.util.ReadItemAlpha
import eu.kanade.presentation.util.padding import eu.kanade.presentation.util.padding
import eu.kanade.presentation.util.selectedBackground import eu.kanade.presentation.util.selectedBackground
@ -113,6 +114,14 @@ fun LazyListScope.updatesUiItems(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItemPlacement(),
update = updatesItem.update, update = updatesItem.update,
selected = updatesItem.selected, selected = updatesItem.selected,
readProgress = updatesItem.update.lastPageRead
.takeIf { !updatesItem.update.read && it > 0L }
?.let {
stringResource(
R.string.chapter_progress,
it + 1,
)
},
onLongClick = { onLongClick = {
onUpdateSelected(updatesItem, !updatesItem.selected, true, true) onUpdateSelected(updatesItem, !updatesItem.selected, true, true)
}, },
@ -139,6 +148,7 @@ fun UpdatesUiItem(
modifier: Modifier, modifier: Modifier,
update: UpdatesWithRelations, update: UpdatesWithRelations,
selected: Boolean, selected: Boolean,
readProgress: String?,
onClick: () -> Unit, onClick: () -> Unit,
onLongClick: () -> Unit, onLongClick: () -> Unit,
onClickCover: (() -> Unit)?, onClickCover: (() -> Unit)?,
@ -203,8 +213,19 @@ fun UpdatesUiItem(
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
onTextLayout = { textHeight = it.size.height }, 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( ChapterDownloadIndicator(

View File

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

View File

@ -4,9 +4,12 @@ import android.content.Context
import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.SnackbarResult import androidx.compose.material3.SnackbarResult
import androidx.compose.runtime.Immutable 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.StateScreenModel
import cafe.adriel.voyager.core.model.coroutineScope import cafe.adriel.voyager.core.model.coroutineScope
import eu.kanade.core.prefs.CheckboxState import eu.kanade.core.prefs.CheckboxState
import eu.kanade.core.prefs.asState
import eu.kanade.core.prefs.mapAsCheckboxState import eu.kanade.core.prefs.mapAsCheckboxState
import eu.kanade.core.util.addOrRemove import eu.kanade.core.util.addOrRemove
import eu.kanade.data.chapter.NoChaptersException import eu.kanade.data.chapter.NoChaptersException
@ -49,7 +52,6 @@ import eu.kanade.tachiyomi.util.chapter.getChapterSort
import eu.kanade.tachiyomi.util.chapter.getNextUnread import eu.kanade.tachiyomi.util.chapter.getNextUnread
import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.launchNonCancellable 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.withIOContext
import eu.kanade.tachiyomi.util.lang.withUIContext import eu.kanade.tachiyomi.util.lang.withUIContext
import eu.kanade.tachiyomi.util.removeCovers import eu.kanade.tachiyomi.util.removeCovers
@ -69,10 +71,8 @@ import kotlinx.coroutines.launch
import logcat.LogPriority import logcat.LogPriority
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.text.DateFormat
import java.text.DecimalFormat import java.text.DecimalFormat
import java.text.DecimalFormatSymbols import java.text.DecimalFormatSymbols
import java.util.Date
class MangaInfoScreenModel( class MangaInfoScreenModel(
val context: Context, val context: Context,
@ -115,6 +115,9 @@ class MangaInfoScreenModel(
private val processedChapters: Sequence<ChapterItem>? private val processedChapters: Sequence<ChapterItem>?
get() = successState?.processedChapters 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 selectedPositions: Array<Int> = arrayOf(-1, -1) // first and last selected index in list
private val selectedChapterIds: HashSet<Long> = HashSet() private val selectedChapterIds: HashSet<Long> = HashSet()
@ -126,26 +129,16 @@ class MangaInfoScreenModel(
} }
init { init {
val toChapterItemsParams: List<Chapter>.(manga: Manga) -> List<ChapterItem> = { manga ->
toChapterItems(
context = context,
manga = manga,
dateRelativeTime = uiPreferences.relativeTime().get(),
dateFormat = UiPreferences.dateFormat(uiPreferences.dateFormat().get()),
)
}
coroutineScope.launchIO { coroutineScope.launchIO {
combine( combine(
getMangaAndChapters.subscribe(mangaId).distinctUntilChanged(), getMangaAndChapters.subscribe(mangaId).distinctUntilChanged(),
downloadCache.changes, downloadCache.changes,
) { mangaAndChapters, _ -> mangaAndChapters } ) { mangaAndChapters, _ -> mangaAndChapters }
.collectLatest { (manga, chapters) -> .collectLatest { (manga, chapters) ->
val chapterItems = chapters.toChapterItemsParams(manga)
updateSuccessState { updateSuccessState {
it.copy( it.copy(
manga = manga, manga = manga,
chapters = chapterItems, chapters = chapters.toChapterItems(manga),
) )
} }
} }
@ -156,7 +149,7 @@ class MangaInfoScreenModel(
coroutineScope.launchIO { coroutineScope.launchIO {
val manga = getMangaAndChapters.awaitManga(mangaId) val manga = getMangaAndChapters.awaitManga(mangaId)
val chapters = getMangaAndChapters.awaitChapters(mangaId) val chapters = getMangaAndChapters.awaitChapters(mangaId)
.toChapterItemsParams(manga) .toChapterItems(manga)
if (!manga.favorite) { if (!manga.favorite) {
setMangaDefaultChapterFlags.await(manga) setMangaDefaultChapterFlags.await(manga)
@ -463,12 +456,7 @@ class MangaInfoScreenModel(
} }
} }
private fun List<Chapter>.toChapterItems( private fun List<Chapter>.toChapterItems(manga: Manga): List<ChapterItem> {
context: Context,
manga: Manga,
dateRelativeTime: Int,
dateFormat: DateFormat,
): List<ChapterItem> {
val isLocal = manga.isLocal() val isLocal = manga.isLocal()
return map { chapter -> return map { chapter ->
val activeDownload = if (isLocal) { val activeDownload = if (isLocal) {
@ -491,29 +479,6 @@ class MangaInfoScreenModel(
chapter = chapter, chapter = chapter,
downloadState = downloadState, downloadState = downloadState,
downloadProgress = activeDownload?.progress ?: 0, 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 { !chapter.read && it > 0 }?.let {
context.getString(
R.string.chapter_progress,
it + 1,
)
},
selected = chapter.id in selectedChapterIds, selected = chapter.id in selectedChapterIds,
) )
} }
@ -1068,11 +1033,6 @@ data class ChapterItem(
val chapter: Chapter, val chapter: Chapter,
val downloadState: Download.State, val downloadState: Download.State,
val downloadProgress: Int, val downloadProgress: Int,
val chapterTitleString: String,
val dateUploadString: String?,
val readProgressString: String?,
val selected: Boolean = false, val selected: Boolean = false,
) { ) {
val isDownloaded = downloadState == Download.State.DOWNLOADED val isDownloaded = downloadState == Download.State.DOWNLOADED

View File

@ -46,7 +46,6 @@ import kotlinx.coroutines.launch
import logcat.LogPriority import logcat.LogPriority
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.text.DateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
@ -68,9 +67,7 @@ class UpdatesScreenModel(
val events: Flow<Event> = _events.receiveAsFlow() val events: Flow<Event> = _events.receiveAsFlow()
val lastUpdated by libraryPreferences.libraryUpdateLastTimestamp().asState(coroutineScope) 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()))
// First and last selected index in list // First and last selected index in list
private val selectedPositions: Array<Int> = arrayOf(-1, -1) private val selectedPositions: Array<Int> = arrayOf(-1, -1)
@ -110,13 +107,13 @@ class UpdatesScreenModel(
} }
private fun List<UpdatesWithRelations>.toUpdateItems(): List<UpdatesItem> { private fun List<UpdatesWithRelations>.toUpdateItems(): List<UpdatesItem> {
return this.map { return this.map { update ->
val activeDownload = downloadManager.getQueuedDownloadOrNull(it.chapterId) val activeDownload = downloadManager.getQueuedDownloadOrNull(update.chapterId)
val downloaded = downloadManager.isChapterDownloaded( val downloaded = downloadManager.isChapterDownloaded(
it.chapterName, update.chapterName,
it.scanlator, update.scanlator,
it.mangaTitle, update.mangaTitle,
it.sourceId, update.sourceId,
) )
val downloadState = when { val downloadState = when {
activeDownload != null -> activeDownload.status activeDownload != null -> activeDownload.status
@ -124,10 +121,10 @@ class UpdatesScreenModel(
else -> Download.State.NOT_DOWNLOADED else -> Download.State.NOT_DOWNLOADED
} }
UpdatesItem( UpdatesItem(
update = it, update = update,
downloadStateProvider = { downloadState }, downloadStateProvider = { downloadState },
downloadProgressProvider = { activeDownload?.progress ?: 0 }, downloadProgressProvider = { activeDownload?.progress ?: 0 },
selected = it.chapterId in selectedChapterIds, selected = update.chapterId in selectedChapterIds,
) )
} }
} }
@ -390,7 +387,8 @@ data class UpdatesState(
val selectionMode = selected.isNotEmpty() val selectionMode = selected.isNotEmpty()
fun getUiModel(context: Context, relativeTime: Int): List<UpdatesUiModel> { 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 return items
.map { UpdatesUiModel.Item(it) } .map { UpdatesUiModel.Item(it) }
.insertSeparators { before, after -> .insertSeparators { before, after ->

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.scanlator,
chapters.read, chapters.read,
chapters.bookmark, chapters.bookmark,
chapters.last_page_read,
mangas.source, mangas.source,
mangas.favorite, mangas.favorite,
mangas.thumbnail_url AS thumbnailUrl, mangas.thumbnail_url AS thumbnailUrl,