From f7f1a15e7ee386d92e02a27b1f04ec821ed14dfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartu=20=C3=96zen?= Date: Sat, 10 Jan 2026 18:44:01 +0300 Subject: [PATCH] Improve library manga sorting (#1051) * Improve library manga sorting * Update CHANGELOG.md * Revert unread count sort change --- CHANGELOG.md | 1 + .../hooks/useGetVisibleLibraryMangas.ts | 63 ++++++++++--------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba754fac..bb781a47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). - (**Theme**) Improve automatic theme background colors - (**Theme**) Adjust "primary color" of dynamic color theme on manga pages - (**Theme**) Increase max length of custom theme names to 32 (previously 16) +- (**Library**) Improve library manga sorting ### Fixed - (**Library**) Fix total library size chip color in light mode diff --git a/src/features/library/hooks/useGetVisibleLibraryMangas.ts b/src/features/library/hooks/useGetVisibleLibraryMangas.ts index 72af014c..62e899ad 100644 --- a/src/features/library/hooks/useGetVisibleLibraryMangas.ts +++ b/src/features/library/hooks/useGetVisibleLibraryMangas.ts @@ -161,7 +161,7 @@ const filterMangas = ( const sortByNumber = (a: number | string = 0, b: number | string = 0) => Number(a) - Number(b); -const sortByString = (a: string, b: string): number => a.localeCompare(b); +const sortByString = (a: string, b: string): number => a.localeCompare(b, undefined, { sensitivity: 'base' }); type TMangaSort = Pick & MangaChapterCountInfo & { @@ -176,37 +176,38 @@ const sortManga = ( ): Manga[] => { const result = [...manga]; - switch (sort) { - case 'alphabetically': - result.sort((a, b) => sortByString(a.title, b.title)); - break; - case 'dateAdded': - result.sort((a, b) => sortByNumber(a.inLibraryAt, b.inLibraryAt)); - break; - case 'unreadChapters': - result.sort((a, b) => sortByNumber(a.unreadCount, b.unreadCount)); - break; - case 'lastRead': - result.sort((a, b) => sortByNumber(a.lastReadChapter?.lastReadAt, b.lastReadChapter?.lastReadAt)); - break; - case 'latestUploadedChapter': - result.sort((a, b) => - sortByNumber(a.latestUploadedChapter?.uploadDate, b.latestUploadedChapter?.uploadDate), - ); - break; - case 'latestFetchedChapter': - result.sort((a, b) => sortByNumber(a.latestFetchedChapter?.fetchedAt, b.latestFetchedChapter?.fetchedAt)); - break; - case 'totalChapters': - result.sort((a, b) => sortByNumber(a.chapters.totalCount, b.chapters.totalCount)); - break; - default: - break; - } + const primaryComparator = ((): ((a: Manga, b: Manga) => number) => { + switch (sort) { + case 'alphabetically': + return (a, b) => sortByString(a.title, b.title); + case 'dateAdded': + return (a, b) => sortByNumber(a.inLibraryAt, b.inLibraryAt); + case 'unreadChapters': + return (a, b) => sortByNumber(a.unreadCount, b.unreadCount); + case 'lastRead': + return (a, b) => sortByNumber(a.lastReadChapter?.lastReadAt, b.lastReadChapter?.lastReadAt); + case 'latestUploadedChapter': + return (a, b) => sortByNumber(a.latestUploadedChapter?.uploadDate, b.latestUploadedChapter?.uploadDate); + case 'latestFetchedChapter': + return (a, b) => sortByNumber(a.latestFetchedChapter?.fetchedAt, b.latestFetchedChapter?.fetchedAt); + case 'totalChapters': + return (a, b) => sortByNumber(a.chapters.totalCount, b.chapters.totalCount); + default: + return () => 0; + } + })(); - if (desc) { - result.reverse(); - } + result.sort((a, b) => { + const cmp = primaryComparator(a, b); + if (cmp !== 0) { + if (desc) { + return -cmp; + } + return cmp; + } + + return sortByString(a.title, b.title); + }); return result; };