diff --git a/app/src/main/java/eu/kanade/presentation/libraryUpdateError/LibraryUpdateErrorScreen.kt b/app/src/main/java/eu/kanade/presentation/libraryUpdateError/LibraryUpdateErrorScreen.kt index f4c02f1ef..752c4d71e 100644 --- a/app/src/main/java/eu/kanade/presentation/libraryUpdateError/LibraryUpdateErrorScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/libraryUpdateError/LibraryUpdateErrorScreen.kt @@ -14,6 +14,7 @@ import androidx.compose.foundation.shape.ZeroCornerSize import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.ArrowDownward import androidx.compose.material.icons.outlined.ArrowUpward +import androidx.compose.material.icons.outlined.DeleteOutline import androidx.compose.material.icons.outlined.FindReplace import androidx.compose.material.icons.outlined.FlipToBack import androidx.compose.material.icons.outlined.SelectAll @@ -63,6 +64,8 @@ fun LibraryUpdateErrorScreen( onMultiMigrateClicked: (() -> Unit), onSelectAll: (Boolean) -> Unit, onInvertSelection: () -> Unit, + onErrorsDelete: () -> Unit, + onErrorDelete: (Long) -> Unit, onErrorSelected: (LibraryUpdateErrorItem, Boolean, Boolean, Boolean) -> Unit, navigateUp: () -> Unit, ) { @@ -112,6 +115,7 @@ fun LibraryUpdateErrorScreen( onClickUnselectAll = { onSelectAll(false) }, onClickSelectAll = { onSelectAll(true) }, onClickInvertSelection = onInvertSelection, + onClickDeleteErrors = onErrorsDelete, scrollBehavior = scrollBehavior, ) }, @@ -173,6 +177,7 @@ fun LibraryUpdateErrorScreen( onErrorSelected = onErrorSelected, onClick = onClick, onClickCover = onClickCover, + onDelete = onErrorDelete, ) } } @@ -303,6 +308,7 @@ private fun LibraryUpdateErrorAppBar( onClickUnselectAll: () -> Unit, onClickSelectAll: () -> Unit, onClickInvertSelection: () -> Unit, + onClickDeleteErrors: () -> Unit, scrollBehavior: TopAppBarScrollBehavior, ) { AppBar( @@ -326,6 +332,11 @@ private fun LibraryUpdateErrorAppBar( actionModeActions = { AppBarActions( persistentListOf( + AppBar.Action( + title = stringResource(MR.strings.action_delete), + icon = Icons.Outlined.DeleteOutline, + onClick = onClickDeleteErrors, + ), AppBar.Action( title = stringResource(MR.strings.action_select_all), icon = Icons.Outlined.SelectAll, diff --git a/app/src/main/java/eu/kanade/presentation/libraryUpdateError/components/LibraryUpdateErrorUiItem.kt b/app/src/main/java/eu/kanade/presentation/libraryUpdateError/components/LibraryUpdateErrorUiItem.kt index 2a1fa6cda..1d1f2d13e 100644 --- a/app/src/main/java/eu/kanade/presentation/libraryUpdateError/components/LibraryUpdateErrorUiItem.kt +++ b/app/src/main/java/eu/kanade/presentation/libraryUpdateError/components/LibraryUpdateErrorUiItem.kt @@ -1,14 +1,28 @@ package eu.kanade.presentation.libraryUpdateError.components +import androidx.compose.animation.animateColorAsState +import androidx.compose.foundation.background import androidx.compose.foundation.combinedClickable +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.Delete +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.SwipeToDismissBox +import androidx.compose.material3.SwipeToDismissBoxState +import androidx.compose.material3.SwipeToDismissBoxValue.EndToStart +import androidx.compose.material3.SwipeToDismissBoxValue.Settled +import androidx.compose.material3.SwipeToDismissBoxValue.StartToEnd import androidx.compose.material3.Text +import androidx.compose.material3.rememberSwipeToDismissBoxState import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.hapticfeedback.HapticFeedbackType @@ -19,14 +33,13 @@ import eu.kanade.presentation.manga.components.MangaCover import eu.kanade.presentation.util.animateItemFastScroll import eu.kanade.tachiyomi.ui.libraryUpdateError.LibraryUpdateErrorItem import tachiyomi.domain.libraryUpdateError.model.LibraryUpdateErrorWithRelations -import tachiyomi.domain.source.service.SourceManager +import tachiyomi.i18n.MR import tachiyomi.presentation.core.components.ListGroupHeader import tachiyomi.presentation.core.components.Scroller.STICKY_HEADER_KEY_PREFIX import tachiyomi.presentation.core.components.material.padding +import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.util.secondaryItemAlpha import tachiyomi.presentation.core.util.selectedBackground -import uy.kohesive.injekt.Injekt -import uy.kohesive.injekt.api.get internal fun LazyListScope.libraryUpdateErrorUiItems( uiModels: List, @@ -34,6 +47,7 @@ internal fun LazyListScope.libraryUpdateErrorUiItems( onErrorSelected: (LibraryUpdateErrorItem, Boolean, Boolean, Boolean) -> Unit, onClick: (LibraryUpdateErrorItem) -> Unit, onClickCover: (LibraryUpdateErrorItem) -> Unit, + onDelete: (Long) -> Unit, ) { uiModels.forEach { uiModel -> when (uiModel) { @@ -46,6 +60,7 @@ internal fun LazyListScope.libraryUpdateErrorUiItems( modifier = Modifier.animateItemFastScroll(), text = uiModel.errorMessage, tonalElevation = 1.dp, + count = uiModel.count, ) } } @@ -58,6 +73,8 @@ internal fun LazyListScope.libraryUpdateErrorUiItems( LibraryUpdateErrorUiItem( modifier = Modifier.animateItemFastScroll(), error = libraryUpdateErrorItem.error, + mangaCover = libraryUpdateErrorItem.mangaCover, + sourceName = libraryUpdateErrorItem.sourceName, selected = libraryUpdateErrorItem.selected, onClick = { when { @@ -80,6 +97,7 @@ internal fun LazyListScope.libraryUpdateErrorUiItems( ) }, onClickCover = { onClickCover(libraryUpdateErrorItem) }.takeIf { !selectionMode }, + onSwipe = { onDelete(libraryUpdateErrorItem.error.errorId) }, ) } } @@ -91,63 +109,124 @@ internal fun LazyListScope.libraryUpdateErrorUiItems( private fun LibraryUpdateErrorUiItem( modifier: Modifier, error: LibraryUpdateErrorWithRelations, + mangaCover: tachiyomi.domain.manga.model.MangaCover, + sourceName: String, selected: Boolean, onClick: () -> Unit, onLongClick: () -> Unit, onClickCover: (() -> Unit)?, + onSwipe: () -> Unit, ) { val haptic = LocalHapticFeedback.current - Row( - modifier = modifier - .selectedBackground(selected) - .combinedClickable( - onClick = onClick, - onLongClick = { - onLongClick() - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - }, - ) - .padding(horizontal = MaterialTheme.padding.medium), - verticalAlignment = Alignment.Top, + val dismissState = rememberSwipeToDismissBoxState( + confirmValueChange = { + when (it) { + StartToEnd -> onSwipe() + EndToStart -> onSwipe() + else -> {} + } + return@rememberSwipeToDismissBoxState true + }, + // Set threshold to 25% of the width + positionalThreshold = { totalDistance -> totalDistance * 0.25f }, + ) + + SwipeToDismissBox( + state = dismissState, + modifier = modifier, + backgroundContent = { DismissBackground(dismissState) }, ) { - MangaCover.Square( + Row( modifier = Modifier - .padding(vertical = 6.dp) - .height(48.dp), - data = error.mangaCover, - onClick = onClickCover, - ) - - Column( - modifier = Modifier - .padding(horizontal = MaterialTheme.padding.medium, vertical = 5.dp) - .weight(1f), + .background(MaterialTheme.colorScheme.surface) + .selectedBackground(selected) + .combinedClickable( + onClick = onClick, + onLongClick = { + onLongClick() + haptic.performHapticFeedback(HapticFeedbackType.LongPress) + }, + ) + .padding(horizontal = MaterialTheme.padding.medium), + verticalAlignment = Alignment.Top, ) { - Text( - text = error.mangaTitle, - style = MaterialTheme.typography.bodyMedium, - overflow = TextOverflow.Visible, + MangaCover.Square( + modifier = Modifier + .padding(vertical = 6.dp) + .height(48.dp), + data = mangaCover, + onClick = onClickCover, ) - Row(modifier = Modifier.padding(vertical = 4.dp), verticalAlignment = Alignment.CenterVertically) { + Column( + modifier = Modifier + .padding(horizontal = MaterialTheme.padding.medium, vertical = 5.dp) + .weight(1f), + ) { Text( - text = Injekt.get().getOrStub(error.mangaSource).name, - style = MaterialTheme.typography.bodySmall, + text = error.mangaTitle, + style = MaterialTheme.typography.bodyMedium, overflow = TextOverflow.Visible, - maxLines = 1, - modifier = Modifier - .secondaryItemAlpha() - .weight(weight = 1f, fill = false), ) + + Row(modifier = Modifier.padding(vertical = 4.dp), verticalAlignment = Alignment.CenterVertically) { + Text( + text = sourceName, + style = MaterialTheme.typography.bodySmall, + overflow = TextOverflow.Visible, + maxLines = 1, + modifier = Modifier + .secondaryItemAlpha() + .weight(weight = 1f, fill = false), + ) + } } } } } +@Composable +fun DismissBackground(dismissState: SwipeToDismissBoxState) { + val direction = dismissState.dismissDirection + val targetState = dismissState.targetValue + + val backgroundColor by animateColorAsState( + when (direction) { + Settled -> + MaterialTheme.colorScheme.surface + StartToEnd -> + MaterialTheme.colorScheme.errorContainer + .copy(alpha = if (targetState == Settled) 0.45f else 1f) + EndToStart -> + MaterialTheme.colorScheme.errorContainer + .copy(alpha = if (targetState == Settled) 0.45f else 1f) + }, + ) + val alignment = when (direction) { + StartToEnd -> Alignment.CenterStart + EndToStart -> Alignment.CenterEnd + else -> Alignment.Center + } + + Box( + modifier = Modifier + .fillMaxSize() + .background(backgroundColor) + .padding(horizontal = 20.dp), + contentAlignment = alignment, + ) { + Icon( + imageVector = Icons.Outlined.Delete, + contentDescription = stringResource(MR.strings.action_delete), + tint = MaterialTheme.colorScheme.onErrorContainer, + ) + } +} + sealed class LibraryUpdateErrorUiModel { - data class Header(val errorMessage: String) : LibraryUpdateErrorUiModel() + data class Header(val errorMessage: String, val count: Int) : LibraryUpdateErrorUiModel() data class Item(val item: LibraryUpdateErrorItem) : LibraryUpdateErrorUiModel() } diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/MangaChapterListItem.kt b/app/src/main/java/eu/kanade/presentation/manga/components/MangaChapterListItem.kt index f89594d8b..fa53c9099 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/components/MangaChapterListItem.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/components/MangaChapterListItem.kt @@ -96,14 +96,14 @@ fun MangaChapterListItem( } SwipeableActionsBox( - modifier = Modifier.clipToBounds(), + modifier = modifier.clipToBounds(), startActions = listOfNotNull(swipeStart), endActions = listOfNotNull(swipeEnd), swipeThreshold = swipeActionThreshold, backgroundUntilSwipeThreshold = MaterialTheme.colorScheme.surfaceContainerLowest, ) { Row( - modifier = modifier + modifier = Modifier .selectedBackground(selected) .combinedClickable( onClick = onClick, @@ -244,7 +244,7 @@ internal fun getSwipeAction( } } -private fun swipeAction( +internal fun swipeAction( onSwipe: () -> Unit, icon: ImageVector, background: Color, diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt index 10c56c093..95201afa0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt @@ -655,7 +655,7 @@ class LibraryUpdateJob(private val context: Context, private val workerParams: W // KMK --> private suspend fun clearErrorFromDB(mangaId: Long) { - deleteLibraryUpdateErrors.deleteMangaError(mangaId = mangaId) + deleteLibraryUpdateErrors.deleteMangaError(mangaIds = listOf(mangaId)) } private suspend fun writeErrorToDB(error: Pair) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/libraryUpdateError/LibraryUpdateErrorScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/libraryUpdateError/LibraryUpdateErrorScreen.kt index f49bcf21c..b785fedd5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/libraryUpdateError/LibraryUpdateErrorScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/libraryUpdateError/LibraryUpdateErrorScreen.kt @@ -41,6 +41,8 @@ class LibraryUpdateErrorScreen : Screen() { }, onSelectAll = screenModel::toggleAllSelection, onInvertSelection = screenModel::invertSelection, + onErrorsDelete = screenModel::deleteSelected, + onErrorDelete = screenModel::delete, onErrorSelected = screenModel::toggleSelection, navigateUp = navigator::pop, ) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/libraryUpdateError/LibraryUpdateErrorScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/libraryUpdateError/LibraryUpdateErrorScreenModel.kt index 71d3dff4d..44ef6bae0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/libraryUpdateError/LibraryUpdateErrorScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/libraryUpdateError/LibraryUpdateErrorScreenModel.kt @@ -5,19 +5,26 @@ import cafe.adriel.voyager.core.model.StateScreenModel import cafe.adriel.voyager.core.model.screenModelScope import eu.kanade.core.util.addOrRemove import eu.kanade.presentation.libraryUpdateError.components.LibraryUpdateErrorUiModel +import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.update import tachiyomi.core.common.util.lang.launchIO +import tachiyomi.core.common.util.lang.withUIContext +import tachiyomi.domain.libraryUpdateError.interactor.DeleteLibraryUpdateErrors import tachiyomi.domain.libraryUpdateError.interactor.GetLibraryUpdateErrorWithRelations import tachiyomi.domain.libraryUpdateError.model.LibraryUpdateErrorWithRelations import tachiyomi.domain.libraryUpdateErrorMessage.interactor.GetLibraryUpdateErrorMessages import tachiyomi.domain.libraryUpdateErrorMessage.model.LibraryUpdateErrorMessage +import tachiyomi.domain.manga.model.MangaCover +import tachiyomi.domain.source.service.SourceManager import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get class LibraryUpdateErrorScreenModel( private val getLibraryUpdateErrorWithRelations: GetLibraryUpdateErrorWithRelations = Injekt.get(), private val getLibraryUpdateErrorMessages: GetLibraryUpdateErrorMessages = Injekt.get(), + private val deleteLibraryUpdateErrors: DeleteLibraryUpdateErrors = Injekt.get(), + private val sourceManager: SourceManager = Injekt.get(), ) : StateScreenModel(LibraryUpdateErrorScreenState()) { // First and last selected index in list @@ -44,6 +51,7 @@ class LibraryUpdateErrorScreenModel( return map { error -> LibraryUpdateErrorItem( error = error, + sourceName = sourceManager.getOrStub(error.mangaSource).name, selected = error.errorId in selectedErrorIds, ) } @@ -139,6 +147,26 @@ class LibraryUpdateErrorScreenModel( selectedPositions[0] = -1 selectedPositions[1] = -1 } + + @OptIn(DelicateCoroutinesApi::class) + fun deleteSelected() { + launchIO { + deleteLibraryUpdateErrors.delete(selectedErrorIds.toList()) + withUIContext { + selectedErrorIds.clear() + } + } + } + + @OptIn(DelicateCoroutinesApi::class) + fun delete(errorId: Long) { + launchIO { + deleteLibraryUpdateErrors.delete(listOf(errorId)) + withUIContext { + selectedErrorIds.remove(errorId) + } + } + } } @Immutable @@ -156,7 +184,7 @@ data class LibraryUpdateErrorScreenState( val errorMap = items.groupBy { it.error.messageId } errorMap.forEach { (messageId, errors) -> val message = messages.find { it.id == messageId } - uiModels.add(LibraryUpdateErrorUiModel.Header(message!!.message)) + uiModels.add(LibraryUpdateErrorUiModel.Header(message!!.message, errors.size)) uiModels.addAll(errors.map { LibraryUpdateErrorUiModel.Item(it) }) } return uiModels @@ -171,5 +199,14 @@ data class LibraryUpdateErrorScreenState( @Immutable data class LibraryUpdateErrorItem( val error: LibraryUpdateErrorWithRelations, + val sourceName: String, val selected: Boolean, -) +) { + val mangaCover = MangaCover( + mangaId = error.mangaId, + sourceId = error.mangaSource, + isMangaFavorite = error.favorite, + ogUrl = error.mangaThumbnail, + lastModified = error.coverLastModified, + ) +} diff --git a/data/src/main/java/tachiyomi/data/libraryUpdateError/LibraryUpdateErrorRepositoryImpl.kt b/data/src/main/java/tachiyomi/data/libraryUpdateError/LibraryUpdateErrorRepositoryImpl.kt index 7b1089eeb..49b7b692b 100644 --- a/data/src/main/java/tachiyomi/data/libraryUpdateError/LibraryUpdateErrorRepositoryImpl.kt +++ b/data/src/main/java/tachiyomi/data/libraryUpdateError/LibraryUpdateErrorRepositoryImpl.kt @@ -25,17 +25,15 @@ class LibraryUpdateErrorRepositoryImpl( return handler.await { libraryUpdateErrorQueries.deleteAllErrors() } } - override suspend fun delete(errorId: Long) { + override suspend fun delete(errorIds: List) { return handler.await { - libraryUpdateErrorQueries.deleteError( - _id = errorId, - ) + libraryUpdateErrorQueries.deleteErrors(_ids = errorIds) } } - override suspend fun deleteMangaError(mangaId: Long) { + override suspend fun deleteMangaError(mangaIds: List) { return handler.await { - libraryUpdateErrorQueries.deleteMangaError(mangaId = mangaId) + libraryUpdateErrorQueries.deleteMangaErrors(mangaIds = mangaIds) } } diff --git a/data/src/main/java/tachiyomi/data/libraryUpdateError/LibraryUpdateErrorWithRelationsMapper.kt b/data/src/main/java/tachiyomi/data/libraryUpdateError/LibraryUpdateErrorWithRelationsMapper.kt index b8b0d3b71..528b5e68e 100644 --- a/data/src/main/java/tachiyomi/data/libraryUpdateError/LibraryUpdateErrorWithRelationsMapper.kt +++ b/data/src/main/java/tachiyomi/data/libraryUpdateError/LibraryUpdateErrorWithRelationsMapper.kt @@ -1,7 +1,6 @@ package tachiyomi.data.libraryUpdateError import tachiyomi.domain.libraryUpdateError.model.LibraryUpdateErrorWithRelations -import tachiyomi.domain.manga.model.MangaCover val libraryUpdateErrorWithRelationsMapper: (Long, String, Long, Boolean, String?, Long, Long, Long, Long) -> LibraryUpdateErrorWithRelations = @@ -10,13 +9,9 @@ val libraryUpdateErrorWithRelationsMapper: mangaId = mangaId, mangaTitle = mangaTitle, mangaSource = mangaSource, - mangaCover = MangaCover( - mangaId = mangaId, - sourceId = mangaSource, - isMangaFavorite = favorite, - ogUrl = mangaThumbnail, - lastModified = coverLastModified, - ), + favorite = favorite, + mangaThumbnail = mangaThumbnail, + coverLastModified = coverLastModified, errorId = errorId, messageId = messageId, lastUpdate = lastUpdate, diff --git a/data/src/main/sqldelight/tachiyomi/data/libraryUpdateError.sq b/data/src/main/sqldelight/tachiyomi/data/libraryUpdateError.sq index 0cd6ffb62..0e988c140 100644 --- a/data/src/main/sqldelight/tachiyomi/data/libraryUpdateError.sq +++ b/data/src/main/sqldelight/tachiyomi/data/libraryUpdateError.sq @@ -25,13 +25,13 @@ WHERE manga_id = :mangaId; deleteAllErrors: DELETE FROM libraryUpdateError; -deleteError: +deleteErrors: DELETE FROM libraryUpdateError -WHERE _id = :_id; +WHERE _id IN :_ids; -deleteMangaError: +deleteMangaErrors: DELETE FROM libraryUpdateError -WHERE manga_id = :mangaId; +WHERE manga_id IN :mangaIds; cleanUnrelevantMangaErrors: DELETE FROM libraryUpdateError diff --git a/domain/src/main/java/tachiyomi/domain/libraryUpdateError/interactor/DeleteLibraryUpdateErrors.kt b/domain/src/main/java/tachiyomi/domain/libraryUpdateError/interactor/DeleteLibraryUpdateErrors.kt index f53158344..78ee10cb7 100644 --- a/domain/src/main/java/tachiyomi/domain/libraryUpdateError/interactor/DeleteLibraryUpdateErrors.kt +++ b/domain/src/main/java/tachiyomi/domain/libraryUpdateError/interactor/DeleteLibraryUpdateErrors.kt @@ -9,7 +9,7 @@ class DeleteLibraryUpdateErrors( private val libraryUpdateErrorRepository: LibraryUpdateErrorRepository, ) { - suspend fun await() = withNonCancellableContext { + suspend fun deleteAll() = withNonCancellableContext { try { libraryUpdateErrorRepository.deleteAll() Result.Success @@ -19,9 +19,9 @@ class DeleteLibraryUpdateErrors( } } - suspend fun await(errorId: Long) = withNonCancellableContext { + suspend fun delete(errorIds: List) = withNonCancellableContext { try { - libraryUpdateErrorRepository.delete(errorId) + libraryUpdateErrorRepository.delete(errorIds) Result.Success } catch (e: Exception) { logcat(LogPriority.ERROR, e) @@ -29,9 +29,9 @@ class DeleteLibraryUpdateErrors( } } - suspend fun deleteMangaError(mangaId: Long) = withNonCancellableContext { + suspend fun deleteMangaError(mangaIds: List) = withNonCancellableContext { try { - libraryUpdateErrorRepository.deleteMangaError(mangaId) + libraryUpdateErrorRepository.deleteMangaError(mangaIds) Result.Success } catch (e: Exception) { logcat(LogPriority.ERROR, e) diff --git a/domain/src/main/java/tachiyomi/domain/libraryUpdateError/model/LibraryUpdateErrorWithRelations.kt b/domain/src/main/java/tachiyomi/domain/libraryUpdateError/model/LibraryUpdateErrorWithRelations.kt index f2bca4da5..ebab489ad 100644 --- a/domain/src/main/java/tachiyomi/domain/libraryUpdateError/model/LibraryUpdateErrorWithRelations.kt +++ b/domain/src/main/java/tachiyomi/domain/libraryUpdateError/model/LibraryUpdateErrorWithRelations.kt @@ -1,12 +1,12 @@ package tachiyomi.domain.libraryUpdateError.model -import tachiyomi.domain.manga.model.MangaCover - data class LibraryUpdateErrorWithRelations( val mangaId: Long, val mangaTitle: String, val mangaSource: Long, - val mangaCover: MangaCover, + val favorite: Boolean, + val mangaThumbnail: String?, + val coverLastModified: Long, val errorId: Long, val messageId: Long, val lastUpdate: Long, diff --git a/domain/src/main/java/tachiyomi/domain/libraryUpdateError/repository/LibraryUpdateErrorRepository.kt b/domain/src/main/java/tachiyomi/domain/libraryUpdateError/repository/LibraryUpdateErrorRepository.kt index b5a5889ce..39e41adab 100644 --- a/domain/src/main/java/tachiyomi/domain/libraryUpdateError/repository/LibraryUpdateErrorRepository.kt +++ b/domain/src/main/java/tachiyomi/domain/libraryUpdateError/repository/LibraryUpdateErrorRepository.kt @@ -11,9 +11,9 @@ interface LibraryUpdateErrorRepository { suspend fun deleteAll() - suspend fun delete(errorId: Long) + suspend fun delete(errorIds: List) - suspend fun deleteMangaError(mangaId: Long) + suspend fun deleteMangaError(mangaIds: List) suspend fun cleanUnrelevantMangaErrors() diff --git a/presentation-core/src/main/java/tachiyomi/presentation/core/components/ListGroupHeader.kt b/presentation-core/src/main/java/tachiyomi/presentation/core/components/ListGroupHeader.kt index d7ae5d4f2..149625f54 100644 --- a/presentation-core/src/main/java/tachiyomi/presentation/core/components/ListGroupHeader.kt +++ b/presentation-core/src/main/java/tachiyomi/presentation/core/components/ListGroupHeader.kt @@ -1,11 +1,14 @@ package tachiyomi.presentation.core.components +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Badge import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp @@ -18,6 +21,7 @@ fun ListGroupHeader( modifier: Modifier = Modifier, // KMK --> tonalElevation: Dp = 0.dp, + count: Int? = null, // KMK <-- ) { // KMK --> @@ -26,17 +30,32 @@ fun ListGroupHeader( .fillMaxWidth(), tonalElevation = tonalElevation, ) { - // KMK <-- - Text( - text = text, - modifier = Modifier - .padding( - horizontal = MaterialTheme.padding.medium, - vertical = MaterialTheme.padding.small, - ), - color = MaterialTheme.colorScheme.onSurfaceVariant, - fontWeight = FontWeight.SemiBold, - style = MaterialTheme.typography.bodyMedium, - ) + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth(), + ) { + // KMK <-- + Text( + text = text, + modifier = Modifier + .padding( + horizontal = MaterialTheme.padding.medium, + vertical = MaterialTheme.padding.small, + ), + color = MaterialTheme.colorScheme.onSurfaceVariant, + fontWeight = FontWeight.SemiBold, + style = MaterialTheme.typography.bodyMedium, + ) + // KMK --> + if (count != null) { + Badge( + containerColor = MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary, + ) { + Text("$count") + } + } + // KMK <-- + } } }