fix(update-errors): Fix range selection & ordering latest error first (#914)

* Fix range selection

* Sort error list by latest error first

* Correct non-nullable lastUpdate & fix comment
This commit is contained in:
Cuong-Tran 2025-05-16 15:07:37 +07:00 committed by GitHub
parent c52de8c472
commit bc33a75b6b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 50 additions and 26 deletions

View file

@ -25,8 +25,8 @@ android {
defaultConfig { defaultConfig {
applicationId = "app.komikku" applicationId = "app.komikku"
versionCode = 73 versionCode = 74
versionName = "1.13.1" versionName = "1.13.2"
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"") buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"") buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"")

View file

@ -32,7 +32,7 @@ class LibraryUpdateErrorScreenModel(
mutableState.update { mutableState.update {
it.copy( it.copy(
isLoading = false, isLoading = false,
items = toLibraryUpdateErrorItems(errors), items = errors.toLibraryUpdateErrorItems(),
messages = errorMessages, messages = errorMessages,
) )
} }
@ -40,13 +40,15 @@ class LibraryUpdateErrorScreenModel(
} }
} }
private fun toLibraryUpdateErrorItems(errors: List<LibraryUpdateErrorWithRelations>): List<LibraryUpdateErrorItem> { private fun List<LibraryUpdateErrorWithRelations>.toLibraryUpdateErrorItems(): List<LibraryUpdateErrorItem> {
return errors.map { error -> return map { error ->
LibraryUpdateErrorItem( LibraryUpdateErrorItem(
error = error, error = error,
selected = error.errorId in selectedErrorIds, selected = error.errorId in selectedErrorIds,
) )
} }
// Sort by messageId to group errors by type, preserving last_update order within groups (from DB)
.sortedBy { it.error.messageId }
} }
fun toggleSelection( fun toggleSelection(

View file

@ -2,10 +2,11 @@ package tachiyomi.data.libraryUpdateError
import tachiyomi.domain.libraryUpdateError.model.LibraryUpdateError import tachiyomi.domain.libraryUpdateError.model.LibraryUpdateError
val libraryUpdateErrorMapper: (Long, Long, Long) -> LibraryUpdateError = { id, mangaId, messageId -> val libraryUpdateErrorMapper: (Long, Long, Long, Long) -> LibraryUpdateError = { id, mangaId, messageId, lastUpdate ->
LibraryUpdateError( LibraryUpdateError(
id = id, id = id,
mangaId = mangaId, mangaId = mangaId,
messageId = messageId, messageId = messageId,
lastUpdate = lastUpdate,
) )
} }

View file

@ -11,17 +11,13 @@ class LibraryUpdateErrorRepositoryImpl(
override suspend fun getAll(): List<LibraryUpdateError> { override suspend fun getAll(): List<LibraryUpdateError> {
return handler.awaitList { return handler.awaitList {
libraryUpdateErrorQueries.getAllErrors( libraryUpdateErrorQueries.getAllErrors(libraryUpdateErrorMapper)
libraryUpdateErrorMapper,
)
} }
} }
override fun getAllAsFlow(): Flow<List<LibraryUpdateError>> { override fun getAllAsFlow(): Flow<List<LibraryUpdateError>> {
return handler.subscribeToList { return handler.subscribeToList {
libraryUpdateErrorQueries.getAllErrors( libraryUpdateErrorQueries.getAllErrors(libraryUpdateErrorMapper)
libraryUpdateErrorMapper,
)
} }
} }
@ -39,9 +35,7 @@ class LibraryUpdateErrorRepositoryImpl(
override suspend fun deleteMangaError(mangaId: Long) { override suspend fun deleteMangaError(mangaId: Long) {
return handler.await { return handler.await {
libraryUpdateErrorQueries.deleteMangaError( libraryUpdateErrorQueries.deleteMangaError(mangaId = mangaId)
mangaId = mangaId,
)
} }
} }

View file

@ -4,8 +4,8 @@ import tachiyomi.domain.libraryUpdateError.model.LibraryUpdateErrorWithRelations
import tachiyomi.domain.manga.model.MangaCover import tachiyomi.domain.manga.model.MangaCover
val libraryUpdateErrorWithRelationsMapper: val libraryUpdateErrorWithRelationsMapper:
(Long, String, Long, Boolean, String?, Long, Long, Long) -> LibraryUpdateErrorWithRelations = (Long, String, Long, Boolean, String?, Long, Long, Long, Long) -> LibraryUpdateErrorWithRelations =
{ mangaId, mangaTitle, mangaSource, favorite, mangaThumbnail, coverLastModified, errorId, messageId -> { mangaId, mangaTitle, mangaSource, favorite, mangaThumbnail, coverLastModified, errorId, messageId, lastUpdate ->
LibraryUpdateErrorWithRelations( LibraryUpdateErrorWithRelations(
mangaId = mangaId, mangaId = mangaId,
mangaTitle = mangaTitle, mangaTitle = mangaTitle,
@ -19,5 +19,6 @@ val libraryUpdateErrorWithRelationsMapper:
), ),
errorId = errorId, errorId = errorId,
messageId = messageId, messageId = messageId,
lastUpdate = lastUpdate,
) )
} }

View file

@ -1,7 +1,8 @@
CREATE TABLE libraryUpdateError ( CREATE TABLE libraryUpdateError (
_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, _id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
manga_id INTEGER NOT NULL UNIQUE, manga_id INTEGER NOT NULL UNIQUE,
message_id INTEGER NOT NULL message_id INTEGER NOT NULL,
last_update INTEGER NOT NULL DEFAULT 0
); );
getAllErrors: getAllErrors:
@ -9,15 +10,16 @@ SELECT *
FROM libraryUpdateError; FROM libraryUpdateError;
insert: insert:
INSERT INTO libraryUpdateError(manga_id, message_id) VALUES (:mangaId, :messageId); INSERT INTO libraryUpdateError(manga_id, message_id, last_update) VALUES (:mangaId, :messageId, strftime('%s', 'now'));
upsert: upsert:
INSERT INTO libraryUpdateError(manga_id, message_id) INSERT INTO libraryUpdateError(manga_id, message_id, last_update)
VALUES (:mangaId, :messageId) VALUES (:mangaId, :messageId, strftime('%s', 'now'))
ON CONFLICT(manga_id) ON CONFLICT(manga_id)
DO UPDATE DO UPDATE
SET SET
message_id = :messageId message_id = :messageId,
last_update = strftime('%s', 'now')
WHERE manga_id = :mangaId; WHERE manga_id = :mangaId;
deleteAllErrors: deleteAllErrors:

View file

@ -0,0 +1,20 @@
ALTER TABLE libraryUpdateError
ADD COLUMN last_update INTEGER NOT NULL DEFAULT 0;
DROP VIEW IF EXISTS libraryUpdateErrorView;
CREATE VIEW libraryUpdateErrorView AS
SELECT
mangas._id AS mangaId,
mangas.title AS mangaTitle,
mangas.source,
mangas.favorite,
mangas.thumbnail_url AS thumbnailUrl,
mangas.cover_last_modified AS coverLastModified,
libraryUpdateError._id AS errorId,
libraryUpdateError.message_id AS messageId,
libraryUpdateError.last_update AS lastUpdate
FROM mangas JOIN libraryUpdateError
ON mangas._id = libraryUpdateError.manga_id
WHERE favorite = 1
ORDER BY lastUpdate DESC;

View file

@ -7,10 +7,12 @@ SELECT
mangas.thumbnail_url AS thumbnailUrl, mangas.thumbnail_url AS thumbnailUrl,
mangas.cover_last_modified AS coverLastModified, mangas.cover_last_modified AS coverLastModified,
libraryUpdateError._id AS errorId, libraryUpdateError._id AS errorId,
libraryUpdateError.message_id AS messageId libraryUpdateError.message_id AS messageId,
libraryUpdateError.last_update AS lastUpdate
FROM mangas JOIN libraryUpdateError FROM mangas JOIN libraryUpdateError
ON mangas._id = libraryUpdateError.manga_id ON mangas._id = libraryUpdateError.manga_id
WHERE favorite = 1; WHERE favorite = 1
ORDER BY lastUpdate DESC;
errors: errors:
SELECT * SELECT *

View file

@ -6,4 +6,5 @@ data class LibraryUpdateError(
val id: Long, val id: Long,
val mangaId: Long, val mangaId: Long,
val messageId: Long, val messageId: Long,
val lastUpdate: Long = 0L,
) : Serializable ) : Serializable

View file

@ -9,4 +9,5 @@ data class LibraryUpdateErrorWithRelations(
val mangaCover: MangaCover, val mangaCover: MangaCover,
val errorId: Long, val errorId: Long,
val messageId: Long, val messageId: Long,
val lastUpdate: Long,
) )