fix: Order EPUB Chapters Across Paginated Pages (Closes #1762)

This commit is contained in:
Rajarshee Chatterjee
2026-07-02 00:52:53 +05:30
parent 93bc5e5e4b
commit 52d5c99c46
2 changed files with 62 additions and 24 deletions
+18 -16
View File
@@ -677,24 +677,26 @@ export const getNovelDownloadedChapters = async (
startPosition?: number,
endPosition?: number,
): Promise<ChapterInfo[]> => {
const whereConditions = [
eq(chapterSchema.novelId, novelId),
eq(chapterSchema.isDownloaded, true),
];
if (startPosition !== undefined && endPosition !== undefined) {
whereConditions.push(
sql`${chapterSchema.position} >= ${startPosition - 1}`,
);
whereConditions.push(sql`${chapterSchema.position} <= ${endPosition - 1}`);
}
return dbManager
const query = dbManager
.select()
.from(chapterSchema)
.where(and(...whereConditions))
.orderBy(asc(chapterSchema.position))
.all();
.where(
and(
eq(chapterSchema.novelId, novelId),
eq(chapterSchema.isDownloaded, true),
),
)
.orderBy(
asc(castInt(chapterSchema.page)),
asc(chapterSchema.position),
)
.$dynamic();
if (startPosition !== undefined && endPosition !== undefined) {
query.limit(endPosition - startPosition + 1).offset(startPosition - 1);
}
return query.all();
};
export const getUpdatedOverviewFromDb = async () =>
@@ -1023,43 +1023,79 @@ describe('ChapterQueries', () => {
});
describe('getNovelDownloadedChapters', () => {
it('should return downloaded chapters for a novel', async () => {
it('should return downloaded chapters in page and position order', async () => {
const testDb = getTestDb();
const novelId = await insertTestNovel(testDb, { inLibrary: true });
await insertTestChapter(testDb, novelId, {
isDownloaded: true,
page: '10',
position: 1,
});
await insertTestChapter(testDb, novelId, {
isDownloaded: true,
page: '2',
position: 1,
});
await insertTestChapter(testDb, novelId, {
isDownloaded: true,
page: '1',
position: 1,
});
await insertTestChapter(testDb, novelId, {
isDownloaded: true,
page: '2',
position: 0,
});
await insertTestChapter(testDb, novelId, {
isDownloaded: false,
position: 1,
page: '1',
position: 0,
});
const result = await getNovelDownloadedChapters(novelId);
expect(result).toHaveLength(1);
expect(result[0].isDownloaded).toBe(true);
expect(result.map(chapter => [chapter.page, chapter.position])).toEqual([
['1', 1],
['2', 0],
['2', 1],
['10', 1],
]);
});
it('should filter by position range', async () => {
it('should apply a range to the ordered downloaded chapters', async () => {
const testDb = getTestDb();
const novelId = await insertTestNovel(testDb, { inLibrary: true });
await insertTestChapter(testDb, novelId, {
name: 'Chapter 1',
isDownloaded: true,
page: '1',
position: 0,
});
await insertTestChapter(testDb, novelId, {
name: 'Chapter 2',
isDownloaded: true,
page: '1',
position: 1,
});
await insertTestChapter(testDb, novelId, {
name: 'Chapter 3',
isDownloaded: true,
position: 2,
page: '2',
position: 0,
});
await insertTestChapter(testDb, novelId, {
name: 'Chapter 4',
isDownloaded: true,
page: '2',
position: 1,
});
const result = await getNovelDownloadedChapters(novelId, 0, 1);
const result = await getNovelDownloadedChapters(novelId, 2, 3);
expect(result.length).toBeLessThanOrEqual(2);
expect(result.map(chapter => chapter.name)).toEqual([
'Chapter 2',
'Chapter 3',
]);
});
});