mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	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:
		@@ -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,
 | 
			
		||||
        mangaTitle = mangaTitle,
 | 
			
		||||
@@ -13,6 +13,7 @@ val updateWithRelationMapper: (Long, String, Long, String, String?, Boolean, Boo
 | 
			
		||||
        scanlator = scanlator,
 | 
			
		||||
        read = read,
 | 
			
		||||
        bookmark = bookmark,
 | 
			
		||||
        lastPageRead = lastPageRead,
 | 
			
		||||
        sourceId = sourceId,
 | 
			
		||||
        dateFetch = dateFetch,
 | 
			
		||||
        coverData = MangaCover(
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -69,11 +71,17 @@ import eu.kanade.tachiyomi.source.SourceManager
 | 
			
		||||
import eu.kanade.tachiyomi.source.getNameForMangaInfo
 | 
			
		||||
import eu.kanade.tachiyomi.ui.manga.ChapterItem
 | 
			
		||||
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
 | 
			
		||||
fun MangaScreen(
 | 
			
		||||
    state: MangaScreenState.Success,
 | 
			
		||||
    snackbarHostState: SnackbarHostState,
 | 
			
		||||
    dateRelativeTime: Int,
 | 
			
		||||
    dateFormat: DateFormat,
 | 
			
		||||
    isTabletUi: Boolean,
 | 
			
		||||
    onBackClicked: () -> Unit,
 | 
			
		||||
    onChapterClicked: (Chapter) -> Unit,
 | 
			
		||||
@@ -112,6 +120,8 @@ fun MangaScreen(
 | 
			
		||||
        MangaScreenSmallImpl(
 | 
			
		||||
            state = state,
 | 
			
		||||
            snackbarHostState = snackbarHostState,
 | 
			
		||||
            dateRelativeTime = dateRelativeTime,
 | 
			
		||||
            dateFormat = dateFormat,
 | 
			
		||||
            onBackClicked = onBackClicked,
 | 
			
		||||
            onChapterClicked = onChapterClicked,
 | 
			
		||||
            onDownloadChapter = onDownloadChapter,
 | 
			
		||||
@@ -141,6 +151,8 @@ fun MangaScreen(
 | 
			
		||||
        MangaScreenLargeImpl(
 | 
			
		||||
            state = state,
 | 
			
		||||
            snackbarHostState = snackbarHostState,
 | 
			
		||||
            dateRelativeTime = dateRelativeTime,
 | 
			
		||||
            dateFormat = dateFormat,
 | 
			
		||||
            onBackClicked = onBackClicked,
 | 
			
		||||
            onChapterClicked = onChapterClicked,
 | 
			
		||||
            onDownloadChapter = onDownloadChapter,
 | 
			
		||||
@@ -173,6 +185,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)?,
 | 
			
		||||
@@ -364,7 +378,10 @@ private fun MangaScreenSmallImpl(
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    sharedChapterItems(
 | 
			
		||||
                        manga = state.manga,
 | 
			
		||||
                        chapters = chapters,
 | 
			
		||||
                        dateRelativeTime = dateRelativeTime,
 | 
			
		||||
                        dateFormat = dateFormat,
 | 
			
		||||
                        onChapterClicked = onChapterClicked,
 | 
			
		||||
                        onDownloadChapter = onDownloadChapter,
 | 
			
		||||
                        onChapterSelected = onChapterSelected,
 | 
			
		||||
@@ -379,6 +396,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)?,
 | 
			
		||||
@@ -564,7 +583,10 @@ fun MangaScreenLargeImpl(
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            sharedChapterItems(
 | 
			
		||||
                                manga = state.manga,
 | 
			
		||||
                                chapters = chapters,
 | 
			
		||||
                                dateRelativeTime = dateRelativeTime,
 | 
			
		||||
                                dateFormat = dateFormat,
 | 
			
		||||
                                onChapterClicked = onChapterClicked,
 | 
			
		||||
                                onDownloadChapter = onDownloadChapter,
 | 
			
		||||
                                onChapterSelected = onChapterSelected,
 | 
			
		||||
@@ -620,7 +642,10 @@ private fun SharedMangaBottomActionMenu(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
private fun LazyListScope.sharedChapterItems(
 | 
			
		||||
    manga: Manga,
 | 
			
		||||
    chapters: List<ChapterItem>,
 | 
			
		||||
    dateRelativeTime: Int,
 | 
			
		||||
    dateFormat: DateFormat,
 | 
			
		||||
    onChapterClicked: (Chapter) -> Unit,
 | 
			
		||||
    onDownloadChapter: ((List<ChapterItem>, ChapterDownloadAction) -> Unit)?,
 | 
			
		||||
    onChapterSelected: (ChapterItem, Boolean, Boolean, Boolean) -> Unit,
 | 
			
		||||
@@ -631,10 +656,34 @@ 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 {
 | 
			
		||||
                    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() },
 | 
			
		||||
            read = chapterItem.chapter.read,
 | 
			
		||||
            bookmark = chapterItem.chapter.bookmark,
 | 
			
		||||
 
 | 
			
		||||
@@ -193,7 +193,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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -113,6 +114,14 @@ fun LazyListScope.updatesUiItems(
 | 
			
		||||
                    modifier = Modifier.animateItemPlacement(),
 | 
			
		||||
                    update = updatesItem.update,
 | 
			
		||||
                    selected = updatesItem.selected,
 | 
			
		||||
                    readProgress = updatesItem.update.lastPageRead
 | 
			
		||||
                        .takeIf { !updatesItem.update.read && it > 0L }
 | 
			
		||||
                        ?.let {
 | 
			
		||||
                            stringResource(
 | 
			
		||||
                                R.string.chapter_progress,
 | 
			
		||||
                                it + 1,
 | 
			
		||||
                            )
 | 
			
		||||
                        },
 | 
			
		||||
                    onLongClick = {
 | 
			
		||||
                        onUpdateSelected(updatesItem, !updatesItem.selected, true, true)
 | 
			
		||||
                    },
 | 
			
		||||
@@ -139,6 +148,7 @@ fun UpdatesUiItem(
 | 
			
		||||
    modifier: Modifier,
 | 
			
		||||
    update: UpdatesWithRelations,
 | 
			
		||||
    selected: Boolean,
 | 
			
		||||
    readProgress: String?,
 | 
			
		||||
    onClick: () -> Unit,
 | 
			
		||||
    onLongClick: () -> Unit,
 | 
			
		||||
    onClickCover: (() -> Unit)?,
 | 
			
		||||
@@ -203,8 +213,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(
 | 
			
		||||
 
 | 
			
		||||
@@ -101,6 +101,8 @@ class MangaScreen(
 | 
			
		||||
        MangaScreen(
 | 
			
		||||
            state = successState,
 | 
			
		||||
            snackbarHostState = screenModel.snackbarHostState,
 | 
			
		||||
            dateRelativeTime = screenModel.relativeTime,
 | 
			
		||||
            dateFormat = screenModel.dateFormat,
 | 
			
		||||
            isTabletUi = isTabletUi(),
 | 
			
		||||
            onBackClicked = navigator::pop,
 | 
			
		||||
            onChapterClicked = { openChapter(context, it) },
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -49,7 +52,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.withUIContext
 | 
			
		||||
import eu.kanade.tachiyomi.util.removeCovers
 | 
			
		||||
@@ -69,10 +71,8 @@ import kotlinx.coroutines.launch
 | 
			
		||||
import logcat.LogPriority
 | 
			
		||||
import uy.kohesive.injekt.Injekt
 | 
			
		||||
import uy.kohesive.injekt.api.get
 | 
			
		||||
import java.text.DateFormat
 | 
			
		||||
import java.text.DecimalFormat
 | 
			
		||||
import java.text.DecimalFormatSymbols
 | 
			
		||||
import java.util.Date
 | 
			
		||||
 | 
			
		||||
class MangaInfoScreenModel(
 | 
			
		||||
    val context: Context,
 | 
			
		||||
@@ -115,6 +115,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()
 | 
			
		||||
 | 
			
		||||
@@ -126,26 +129,16 @@ class MangaInfoScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 {
 | 
			
		||||
            combine(
 | 
			
		||||
                getMangaAndChapters.subscribe(mangaId).distinctUntilChanged(),
 | 
			
		||||
                downloadCache.changes,
 | 
			
		||||
            ) { mangaAndChapters, _ -> mangaAndChapters }
 | 
			
		||||
                .collectLatest { (manga, chapters) ->
 | 
			
		||||
                    val chapterItems = chapters.toChapterItemsParams(manga)
 | 
			
		||||
                    updateSuccessState {
 | 
			
		||||
                        it.copy(
 | 
			
		||||
                            manga = manga,
 | 
			
		||||
                            chapters = chapterItems,
 | 
			
		||||
                            chapters = chapters.toChapterItems(manga),
 | 
			
		||||
                        )
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -156,7 +149,7 @@ class MangaInfoScreenModel(
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
            val manga = getMangaAndChapters.awaitManga(mangaId)
 | 
			
		||||
            val chapters = getMangaAndChapters.awaitChapters(mangaId)
 | 
			
		||||
                .toChapterItemsParams(manga)
 | 
			
		||||
                .toChapterItems(manga)
 | 
			
		||||
 | 
			
		||||
            if (!manga.favorite) {
 | 
			
		||||
                setMangaDefaultChapterFlags.await(manga)
 | 
			
		||||
@@ -463,12 +456,7 @@ class MangaInfoScreenModel(
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun List<Chapter>.toChapterItems(
 | 
			
		||||
        context: Context,
 | 
			
		||||
        manga: Manga,
 | 
			
		||||
        dateRelativeTime: Int,
 | 
			
		||||
        dateFormat: DateFormat,
 | 
			
		||||
    ): List<ChapterItem> {
 | 
			
		||||
    private fun List<Chapter>.toChapterItems(manga: Manga): List<ChapterItem> {
 | 
			
		||||
        val isLocal = manga.isLocal()
 | 
			
		||||
        return map { chapter ->
 | 
			
		||||
            val activeDownload = if (isLocal) {
 | 
			
		||||
@@ -491,29 +479,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 { !chapter.read && it > 0 }?.let {
 | 
			
		||||
                    context.getString(
 | 
			
		||||
                        R.string.chapter_progress,
 | 
			
		||||
                        it + 1,
 | 
			
		||||
                    )
 | 
			
		||||
                },
 | 
			
		||||
                selected = chapter.id in selectedChapterIds,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
@@ -1068,11 +1033,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,
 | 
			
		||||
) {
 | 
			
		||||
    val isDownloaded = downloadState == Download.State.DOWNLOADED
 | 
			
		||||
 
 | 
			
		||||
@@ -46,7 +46,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
 | 
			
		||||
 | 
			
		||||
@@ -68,9 +67,7 @@ class UpdatesScreenModel(
 | 
			
		||||
    val events: Flow<Event> = _events.receiveAsFlow()
 | 
			
		||||
 | 
			
		||||
    val lastUpdated by libraryPreferences.libraryUpdateLastTimestamp().asState(coroutineScope)
 | 
			
		||||
 | 
			
		||||
    val relativeTime: Int by uiPreferences.relativeTime().asState(coroutineScope)
 | 
			
		||||
    val dateFormat: DateFormat by mutableStateOf(UiPreferences.dateFormat(uiPreferences.dateFormat().get()))
 | 
			
		||||
    val relativeTime by uiPreferences.relativeTime().asState(coroutineScope)
 | 
			
		||||
 | 
			
		||||
    // First and last selected index in list
 | 
			
		||||
    private val selectedPositions: Array<Int> = arrayOf(-1, -1)
 | 
			
		||||
@@ -110,13 +107,13 @@ 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,
 | 
			
		||||
                it.mangaTitle,
 | 
			
		||||
                it.sourceId,
 | 
			
		||||
                update.chapterName,
 | 
			
		||||
                update.scanlator,
 | 
			
		||||
                update.mangaTitle,
 | 
			
		||||
                update.sourceId,
 | 
			
		||||
            )
 | 
			
		||||
            val downloadState = when {
 | 
			
		||||
                activeDownload != null -> activeDownload.status
 | 
			
		||||
@@ -124,10 +121,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,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -390,7 +387,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 ->
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								app/src/main/sqldelight/migrations/23.sqm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								app/src/main/sqldelight/migrations/23.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.read,
 | 
			
		||||
    chapters.bookmark,
 | 
			
		||||
    chapters.last_page_read,
 | 
			
		||||
    mangas.source,
 | 
			
		||||
    mangas.favorite,
 | 
			
		||||
    mangas.thumbnail_url AS thumbnailUrl,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user