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:
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user