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:
parent
7f7789792b
commit
740b3e4616
@ -31,7 +31,7 @@ android {
|
|||||||
applicationId = "eu.kanade.tachiyomi.sy"
|
applicationId = "eu.kanade.tachiyomi.sy"
|
||||||
minSdk = AndroidConfig.minSdk
|
minSdk = AndroidConfig.minSdk
|
||||||
targetSdk = AndroidConfig.targetSdk
|
targetSdk = AndroidConfig.targetSdk
|
||||||
versionCode = 46
|
versionCode = 47
|
||||||
versionName = "1.9.0"
|
versionName = "1.9.0"
|
||||||
|
|
||||||
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
||||||
|
@ -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,
|
||||||
// SY -->
|
// SY -->
|
||||||
@ -15,6 +15,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(
|
||||||
|
@ -17,11 +17,12 @@ private val mapper = { cursor: SqlCursor ->
|
|||||||
cursor.getLong(5)!! == 1L,
|
cursor.getLong(5)!! == 1L,
|
||||||
cursor.getLong(6)!! == 1L,
|
cursor.getLong(6)!! == 1L,
|
||||||
cursor.getLong(7)!!,
|
cursor.getLong(7)!!,
|
||||||
cursor.getLong(8)!! == 1L,
|
cursor.getLong(8)!!,
|
||||||
cursor.getString(9),
|
cursor.getLong(9)!! == 1L,
|
||||||
cursor.getLong(10)!!,
|
cursor.getString(10),
|
||||||
cursor.getLong(11)!!,
|
cursor.getLong(11)!!,
|
||||||
cursor.getLong(12)!!,
|
cursor.getLong(12)!!,
|
||||||
|
cursor.getLong(13)!!,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,6 +39,7 @@ class UpdatesQuery(val driver: SqlDriver, val after: Long) : Query<UpdatesWithRe
|
|||||||
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,
|
||||||
@ -58,6 +60,7 @@ class UpdatesQuery(val driver: SqlDriver, val after: Long) : Query<UpdatesWithRe
|
|||||||
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,
|
||||||
|
@ -14,6 +14,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,
|
||||||
|
@ -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
|
||||||
@ -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.ChapterItem
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreenState
|
import eu.kanade.tachiyomi.ui.manga.MangaScreenState
|
||||||
import eu.kanade.tachiyomi.ui.manga.PagePreviewState
|
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.MERGED_SOURCE_ID
|
||||||
import exh.source.getMainSource
|
import exh.source.getMainSource
|
||||||
|
import exh.source.isEhBasedManga
|
||||||
import exh.ui.metadata.adapters.EHentaiDescription
|
import exh.ui.metadata.adapters.EHentaiDescription
|
||||||
import exh.ui.metadata.adapters.EightMusesDescription
|
import exh.ui.metadata.adapters.EightMusesDescription
|
||||||
import exh.ui.metadata.adapters.HBrowseDescription
|
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.NHentaiDescription
|
||||||
import exh.ui.metadata.adapters.PururinDescription
|
import exh.ui.metadata.adapters.PururinDescription
|
||||||
import exh.ui.metadata.adapters.TsuminoDescription
|
import exh.ui.metadata.adapters.TsuminoDescription
|
||||||
|
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,
|
||||||
@ -144,6 +154,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,
|
||||||
@ -183,6 +195,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,
|
||||||
@ -225,6 +239,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)?,
|
||||||
@ -488,7 +504,13 @@ private fun MangaScreenSmallImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
sharedChapterItems(
|
sharedChapterItems(
|
||||||
|
manga = state.manga,
|
||||||
chapters = chapters,
|
chapters = chapters,
|
||||||
|
dateRelativeTime = dateRelativeTime,
|
||||||
|
dateFormat = dateFormat,
|
||||||
|
// SY -->
|
||||||
|
alwaysShowReadingProgress = state.alwaysShowReadingProgress,
|
||||||
|
// SY <--
|
||||||
onChapterClicked = onChapterClicked,
|
onChapterClicked = onChapterClicked,
|
||||||
onDownloadChapter = onDownloadChapter,
|
onDownloadChapter = onDownloadChapter,
|
||||||
onChapterSelected = onChapterSelected,
|
onChapterSelected = onChapterSelected,
|
||||||
@ -503,6 +525,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)?,
|
||||||
@ -741,7 +765,13 @@ fun MangaScreenLargeImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
sharedChapterItems(
|
sharedChapterItems(
|
||||||
|
manga = state.manga,
|
||||||
chapters = chapters,
|
chapters = chapters,
|
||||||
|
dateRelativeTime = dateRelativeTime,
|
||||||
|
dateFormat = dateFormat,
|
||||||
|
// SY -->
|
||||||
|
alwaysShowReadingProgress = state.alwaysShowReadingProgress,
|
||||||
|
// SY <--
|
||||||
onChapterClicked = onChapterClicked,
|
onChapterClicked = onChapterClicked,
|
||||||
onDownloadChapter = onDownloadChapter,
|
onDownloadChapter = onDownloadChapter,
|
||||||
onChapterSelected = onChapterSelected,
|
onChapterSelected = onChapterSelected,
|
||||||
@ -797,7 +827,13 @@ private fun SharedMangaBottomActionMenu(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun LazyListScope.sharedChapterItems(
|
private fun LazyListScope.sharedChapterItems(
|
||||||
|
manga: Manga,
|
||||||
chapters: List<ChapterItem>,
|
chapters: List<ChapterItem>,
|
||||||
|
dateRelativeTime: Int,
|
||||||
|
dateFormat: DateFormat,
|
||||||
|
// SY -->
|
||||||
|
alwaysShowReadingProgress: Boolean,
|
||||||
|
// SY <--
|
||||||
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,
|
||||||
@ -808,10 +844,40 @@ 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 {
|
||||||
|
// 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 <-- */ },
|
scanlator = chapterItem.chapter.scanlator.takeIf { !it.isNullOrBlank() /* SY --> */ && chapterItem.showScanlator /* SY <-- */ },
|
||||||
// SY -->
|
// SY -->
|
||||||
sourceName = chapterItem.sourceName,
|
sourceName = chapterItem.sourceName,
|
||||||
|
@ -45,6 +45,9 @@ fun UpdateScreen(
|
|||||||
snackbarHostState: SnackbarHostState,
|
snackbarHostState: SnackbarHostState,
|
||||||
lastUpdated: Long,
|
lastUpdated: Long,
|
||||||
relativeTime: Int,
|
relativeTime: Int,
|
||||||
|
// SY -->
|
||||||
|
preserveReadingPosition: Boolean,
|
||||||
|
// SY <--
|
||||||
onClickCover: (UpdatesItem) -> Unit,
|
onClickCover: (UpdatesItem) -> Unit,
|
||||||
onSelectAll: (Boolean) -> Unit,
|
onSelectAll: (Boolean) -> Unit,
|
||||||
onInvertSelection: () -> Unit,
|
onInvertSelection: () -> Unit,
|
||||||
@ -117,6 +120,9 @@ fun UpdateScreen(
|
|||||||
updatesUiItems(
|
updatesUiItems(
|
||||||
uiModels = state.getUiModel(context, relativeTime),
|
uiModels = state.getUiModel(context, relativeTime),
|
||||||
selectionMode = state.selectionMode,
|
selectionMode = state.selectionMode,
|
||||||
|
// SY -->
|
||||||
|
preserveReadingPosition = preserveReadingPosition,
|
||||||
|
// SY <--
|
||||||
onUpdateSelected = onUpdateSelected,
|
onUpdateSelected = onUpdateSelected,
|
||||||
onClickCover = onClickCover,
|
onClickCover = onClickCover,
|
||||||
onClickUpdate = onOpenChapter,
|
onClickUpdate = onOpenChapter,
|
||||||
@ -193,7 +199,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 {
|
||||||
|
@ -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
|
||||||
@ -80,6 +81,9 @@ fun LazyListScope.updatesLastUpdatedItem(
|
|||||||
fun LazyListScope.updatesUiItems(
|
fun LazyListScope.updatesUiItems(
|
||||||
uiModels: List<UpdatesUiModel>,
|
uiModels: List<UpdatesUiModel>,
|
||||||
selectionMode: Boolean,
|
selectionMode: Boolean,
|
||||||
|
// SY -->
|
||||||
|
preserveReadingPosition: Boolean,
|
||||||
|
// SY <--
|
||||||
onUpdateSelected: (UpdatesItem, Boolean, Boolean, Boolean) -> Unit,
|
onUpdateSelected: (UpdatesItem, Boolean, Boolean, Boolean) -> Unit,
|
||||||
onClickCover: (UpdatesItem) -> Unit,
|
onClickCover: (UpdatesItem) -> Unit,
|
||||||
onClickUpdate: (UpdatesItem) -> Unit,
|
onClickUpdate: (UpdatesItem) -> Unit,
|
||||||
@ -113,6 +117,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 { /* SY --> */(!updatesItem.update.read || (preserveReadingPosition && updatesItem.isEhBasedUpdate()))/* SY <-- */ && 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 +151,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 +216,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(
|
||||||
|
@ -140,6 +140,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) },
|
||||||
|
@ -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
|
||||||
@ -75,7 +78,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.withNonCancellableContext
|
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
|
||||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||||
@ -88,7 +90,6 @@ import exh.log.xLogD
|
|||||||
import exh.md.utils.FollowStatus
|
import exh.md.utils.FollowStatus
|
||||||
import exh.md.utils.MdUtil
|
import exh.md.utils.MdUtil
|
||||||
import exh.merged.sql.models.MergedMangaReference
|
import exh.merged.sql.models.MergedMangaReference
|
||||||
import exh.metadata.MetadataUtil
|
|
||||||
import exh.metadata.metadata.base.FlatMetadata
|
import exh.metadata.metadata.base.FlatMetadata
|
||||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||||
import exh.source.MERGED_SOURCE_ID
|
import exh.source.MERGED_SOURCE_ID
|
||||||
@ -114,10 +115,8 @@ 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 uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
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,
|
||||||
@ -179,6 +178,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()
|
||||||
|
|
||||||
@ -213,23 +215,6 @@ class MangaInfoScreenModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
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 {
|
coroutineScope.launchIO {
|
||||||
getMangaAndChapters.subscribe(mangaId)
|
getMangaAndChapters.subscribe(mangaId)
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
@ -295,7 +280,7 @@ class MangaInfoScreenModel(
|
|||||||
.combine(downloadCache.changes) { state, _ -> state }
|
.combine(downloadCache.changes) { state, _ -> state }
|
||||||
// SY <--
|
// SY <--
|
||||||
.collectLatest { (manga, chapters /* SY --> */, flatMetadata, mergedData /* 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 {
|
updateSuccessState {
|
||||||
it.copy(
|
it.copy(
|
||||||
manga = manga,
|
manga = manga,
|
||||||
@ -316,7 +301,7 @@ class MangaInfoScreenModel(
|
|||||||
val manga = getMangaAndChapters.awaitManga(mangaId)
|
val manga = getMangaAndChapters.awaitManga(mangaId)
|
||||||
// SY -->
|
// SY -->
|
||||||
val chapters = (if (manga.source == MERGED_SOURCE_ID) getMergedChapterByMangaId.await(mangaId) else getMangaAndChapters.awaitChapters(mangaId))
|
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 ->
|
val mergedData = getMergedReferencesById.await(mangaId).takeIf { it.isNotEmpty() }?.let { references ->
|
||||||
MergedMangaData(
|
MergedMangaData(
|
||||||
references,
|
references,
|
||||||
@ -358,6 +343,7 @@ class MangaInfoScreenModel(
|
|||||||
PagePreviewState.Unused
|
PagePreviewState.Unused
|
||||||
},
|
},
|
||||||
scanlators = getChapterScanlators(manga, chapters.map { it.chapter }),
|
scanlators = getChapterScanlators(manga, chapters.map { it.chapter }),
|
||||||
|
alwaysShowReadingProgress = readerPreferences.preserveReadingPosition().get() && manga.isEhBasedManga(),
|
||||||
// SY <--
|
// SY <--
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -906,12 +892,8 @@ class MangaInfoScreenModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun List<Chapter>.toChapterItems(
|
private fun List<Chapter>.toChapterItems(
|
||||||
context: Context,
|
|
||||||
manga: Manga,
|
manga: Manga,
|
||||||
dateRelativeTime: Int,
|
|
||||||
dateFormat: DateFormat,
|
|
||||||
mergedData: MergedMangaData?,
|
mergedData: MergedMangaData?,
|
||||||
alwaysShowReadingProgress: Boolean,
|
|
||||||
): List<ChapterItem> {
|
): List<ChapterItem> {
|
||||||
val isLocal = manga.isLocal()
|
val isLocal = manga.isLocal()
|
||||||
// SY -->
|
// SY -->
|
||||||
@ -951,29 +933,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 { /* SY --> */(!chapter.read || alwaysShowReadingProgress)/* SY <-- */ && it > 0 }?.let {
|
|
||||||
context.getString(
|
|
||||||
R.string.chapter_progress,
|
|
||||||
it + 1,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
selected = chapter.id in selectedChapterIds,
|
selected = chapter.id in selectedChapterIds,
|
||||||
// SY -->
|
// SY -->
|
||||||
sourceName = source?.getNameForMangaInfo(null, enabledLanguages = enabledLanguages),
|
sourceName = source?.getNameForMangaInfo(null, enabledLanguages = enabledLanguages),
|
||||||
@ -1601,6 +1560,7 @@ sealed class MangaScreenState {
|
|||||||
val showMergeWithAnother: Boolean,
|
val showMergeWithAnother: Boolean,
|
||||||
val pagePreviewsState: PagePreviewState,
|
val pagePreviewsState: PagePreviewState,
|
||||||
val scanlators: List<String>,
|
val scanlators: List<String>,
|
||||||
|
val alwaysShowReadingProgress: Boolean,
|
||||||
// SY <--
|
// SY <--
|
||||||
) : MangaScreenState() {
|
) : MangaScreenState() {
|
||||||
|
|
||||||
@ -1659,11 +1619,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,
|
||||||
|
|
||||||
// SY -->
|
// SY -->
|
||||||
|
@ -28,11 +28,14 @@ import eu.kanade.tachiyomi.data.download.DownloadService
|
|||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
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.launchIO
|
||||||
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
|
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
|
||||||
import eu.kanade.tachiyomi.util.lang.toDateKey
|
import eu.kanade.tachiyomi.util.lang.toDateKey
|
||||||
import eu.kanade.tachiyomi.util.lang.toRelativeString
|
import eu.kanade.tachiyomi.util.lang.toRelativeString
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
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.channels.Channel
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
@ -46,7 +49,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
|
||||||
|
|
||||||
@ -62,15 +64,20 @@ class UpdatesScreenModel(
|
|||||||
private val libraryPreferences: LibraryPreferences = Injekt.get(),
|
private val libraryPreferences: LibraryPreferences = Injekt.get(),
|
||||||
val snackbarHostState: SnackbarHostState = SnackbarHostState(),
|
val snackbarHostState: SnackbarHostState = SnackbarHostState(),
|
||||||
uiPreferences: UiPreferences = Injekt.get(),
|
uiPreferences: UiPreferences = Injekt.get(),
|
||||||
|
// SY -->
|
||||||
|
readerPreferences: ReaderPreferences = Injekt.get(),
|
||||||
|
// SY <--
|
||||||
) : StateScreenModel<UpdatesState>(UpdatesState()) {
|
) : StateScreenModel<UpdatesState>(UpdatesState()) {
|
||||||
|
|
||||||
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()
|
||||||
|
|
||||||
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)
|
// SY -->
|
||||||
val dateFormat: DateFormat by mutableStateOf(UiPreferences.dateFormat(uiPreferences.dateFormat().get()))
|
val preserveReadingPosition by readerPreferences.preserveReadingPosition().asState(coroutineScope)
|
||||||
|
// SY <--
|
||||||
|
|
||||||
// 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,15 +117,15 @@ 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,
|
||||||
// SY -->
|
// SY -->
|
||||||
it.ogMangaTitle,
|
update.ogMangaTitle,
|
||||||
// SY <--
|
// SY <--
|
||||||
it.sourceId,
|
update.sourceId,
|
||||||
)
|
)
|
||||||
val downloadState = when {
|
val downloadState = when {
|
||||||
activeDownload != null -> activeDownload.status
|
activeDownload != null -> activeDownload.status
|
||||||
@ -126,10 +133,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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -392,7 +399,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 ->
|
||||||
@ -420,4 +428,10 @@ data class UpdatesItem(
|
|||||||
val downloadStateProvider: () -> Download.State,
|
val downloadStateProvider: () -> Download.State,
|
||||||
val downloadProgressProvider: () -> Int,
|
val downloadProgressProvider: () -> Int,
|
||||||
val selected: Boolean = false,
|
val selected: Boolean = false,
|
||||||
)
|
) {
|
||||||
|
// SY -->
|
||||||
|
fun isEhBasedUpdate(): Boolean {
|
||||||
|
return update.sourceId == EH_SOURCE_ID || update.sourceId == EXH_SOURCE_ID
|
||||||
|
}
|
||||||
|
// SY <--
|
||||||
|
}
|
||||||
|
@ -74,6 +74,9 @@ object UpdatesTab : Tab {
|
|||||||
snackbarHostState = screenModel.snackbarHostState,
|
snackbarHostState = screenModel.snackbarHostState,
|
||||||
lastUpdated = screenModel.lastUpdated,
|
lastUpdated = screenModel.lastUpdated,
|
||||||
relativeTime = screenModel.relativeTime,
|
relativeTime = screenModel.relativeTime,
|
||||||
|
// SY -->
|
||||||
|
preserveReadingPosition = screenModel.preserveReadingPosition,
|
||||||
|
// SY <--
|
||||||
onClickCover = { item -> navigator.push(MangaScreen(item.update.mangaId)) },
|
onClickCover = { item -> navigator.push(MangaScreen(item.update.mangaId)) },
|
||||||
onSelectAll = screenModel::toggleAllSelection,
|
onSelectAll = screenModel::toggleAllSelection,
|
||||||
onInvertSelection = screenModel::invertSelection,
|
onInvertSelection = screenModel::invertSelection,
|
||||||
|
23
app/src/main/sqldelight/migrations/24.sqm
Normal file
23
app/src/main/sqldelight/migrations/24.sqm
Normal 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;
|
@ -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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user