Handle chapter updates sync in reader

To be able to properly prevent unnecessary chapter updates, the ongoing updates have to finish, so that the apollo cache is update to date.

Otherwise, the update guard will always be false since the apollo caches chapter data is still from before the previous updates were triggered.
This commit is contained in:
schroda
2024-12-16 14:45:11 +01:00
parent fcd44abccd
commit b4c1cdee77

View File

@@ -11,7 +11,7 @@ import { useNavigate } from 'react-router-dom';
import { Direction, useTheme } from '@mui/material/styles'; import { Direction, useTheme } from '@mui/material/styles';
import { t as translate } from 'i18next'; import { t as translate } from 'i18next';
import { TChapterReader } from '@/modules/chapter/Chapter.types.ts'; import { TChapterReader } from '@/modules/chapter/Chapter.types.ts';
import { Chapters } from '@/modules/chapter/services/Chapters.ts'; import { ChapterIdInfo, Chapters } from '@/modules/chapter/services/Chapters.ts';
import { import {
IReaderSettings, IReaderSettings,
IReaderSettingsWithDefaultFlag, IReaderSettingsWithDefaultFlag,
@@ -59,6 +59,16 @@ const DIRECTION_TO_READING_DIRECTION: Record<Direction, ReadingDirection> = {
export class ReaderService { export class ReaderService {
private static downloadAheadQueue: Queue = new Queue(1); private static downloadAheadQueue: Queue = new Queue(1);
private static chapterUpdateQueues: Map<ChapterIdInfo['id'], Queue> = new Map();
private static getOrCreateChapterUpdateQueue(id: ChapterIdInfo['id']): Queue {
if (!this.chapterUpdateQueues.has(id)) {
this.chapterUpdateQueues.set(id, new Queue(1));
}
return this.chapterUpdateQueues.get(id)!;
}
static useNavigateToChapter(chapter?: TChapterReader, resumeMode?: ReaderResumeMode): () => void { static useNavigateToChapter(chapter?: TChapterReader, resumeMode?: ReaderResumeMode): () => void {
const navigate = useNavigate(); const navigate = useNavigate();
return useCallback( return useCallback(
@@ -130,50 +140,58 @@ export class ReaderService {
return; return;
} }
const chapterIdsToUpdate = Chapters.getIds( const update = async () => {
shouldSkipDupChapters ? Chapters.addDuplicates([currentChapter], mangaChapters) : [currentChapter], const chapterIdsToUpdate = Chapters.getIds(
); shouldSkipDupChapters
? Chapters.addDuplicates([currentChapter], mangaChapters)
: [currentChapter],
);
const isUpdateRequired = chapterIdsToUpdate.some((id) => { const isUpdateRequired = chapterIdsToUpdate.some((id) => {
const chapterUpToDateData = getReaderChapterFromCache(id); const chapterUpToDateData = getReaderChapterFromCache(id);
if (!chapterUpToDateData) { if (!chapterUpToDateData) {
return false; return false;
}
return (
(patch.isRead !== undefined && patch.isRead !== chapterUpToDateData.isRead) ||
(patch.lastPageRead !== undefined &&
patch.lastPageRead !== chapterUpToDateData.lastPageRead) ||
(patch.isBookmarked !== undefined &&
patch.isBookmarked !== chapterUpToDateData.isBookmarked)
);
});
if (!isUpdateRequired) {
return;
} }
return ( const chapterIdsToDelete = getChapterIdsToDeleteForChapterUpdate(
(patch.isRead !== undefined && patch.isRead !== chapterUpToDateData.isRead) || currentChapter,
(patch.lastPageRead !== undefined && patch.lastPageRead !== chapterUpToDateData.lastPageRead) || mangaChapters,
(patch.isBookmarked !== undefined && patch.isBookmarked !== chapterUpToDateData.isBookmarked) previousChapters,
patch,
deleteChaptersWhileReading,
deleteChaptersWithBookmark,
shouldSkipDupChapters,
); );
});
if (!isUpdateRequired) {
return;
}
const chapterIdsToDelete = getChapterIdsToDeleteForChapterUpdate( await requestManager
currentChapter, .updateChapters(
mangaChapters, chapterIdsToUpdate,
previousChapters, {
patch, ...patch,
deleteChaptersWhileReading, chapterIdsToDelete,
deleteChaptersWithBookmark, trackProgressMangaId:
shouldSkipDupChapters, updateProgressAfterReading && patch.isRead && manga.trackRecords.totalCount
); ? manga.id
: undefined,
},
{ errorPolicy: 'all' },
)
.response.catch(defaultPromiseErrorHandler('ReaderService::useUpdateChapter'));
};
requestManager this.getOrCreateChapterUpdateQueue(currentChapter.id).enqueue(`${currentChapter.id}`, () => update());
.updateChapters(
chapterIdsToUpdate,
{
...patch,
chapterIdsToDelete,
trackProgressMangaId:
updateProgressAfterReading && patch.isRead && manga.trackRecords.totalCount
? manga.id
: undefined,
},
{ errorPolicy: 'all' },
)
.response.catch(defaultPromiseErrorHandler('ReaderService::useUpdateChapter'));
}, },
[ [
manga?.id, manga?.id,