Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Progress Tracking #1157

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
8 changes: 4 additions & 4 deletions src/database/queries/ChapterQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,16 +384,16 @@ export const bookmarkChapter = async (chapterId: number) => {
});
};

const markPreviuschaptersReadQuery =
const markPreviousChaptersReadQuery =
'UPDATE Chapter SET `unread` = 0 WHERE id <= ? AND novelId = ?';

export const markPreviuschaptersRead = async (
export const markPreviousChaptersRead = async (
chapterId: number,
novelId: number,
) => {
db.transaction(tx => {
tx.executeSql(
markPreviuschaptersReadQuery,
markPreviousChaptersReadQuery,
[chapterId, novelId],
(_txObj, _res) => {},
(_txObj, _error) => {
Expand All @@ -405,7 +405,7 @@ export const markPreviuschaptersRead = async (
};

const markPreviousChaptersUnreadQuery =
'UPDATE Chapter SET `unread` = 1 WHERE id <= ? AND novelId = ?';
'UPDATE Chapter SET `unread` = 1 WHERE id >= ? AND novelId = ?';

export const markPreviousChaptersUnread = async (
chapterId: number,
Expand Down
107 changes: 97 additions & 10 deletions src/hooks/persisted/useNovel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
bookmarkChapter as _bookmarkChapter,
markChapterRead as _markChapterRead,
markChaptersRead as _markChaptersRead,
markPreviuschaptersRead as _markPreviuschaptersRead,
markPreviousChaptersRead as _markPreviousChaptersRead,
markPreviousChaptersUnread as _markPreviousChaptersUnread,
markChaptersUnread as _markChaptersUnread,
deleteChapter as _deleteChapter,
Expand All @@ -32,6 +32,7 @@ import { parseChapterNumber } from '@utils/parseChapterNumber';
import { NOVEL_STORAGE } from '@utils/Storages';
import FileManager from '@native/FileManager';
import { useAppSettings } from './useSettings';
import { getPlugin } from '@plugins/pluginManager';

// store key: '<PREFIX>_<novel.pluginId>_<novel.path>',
// store key: '<PREFIX>_<novel.id>',
Expand Down Expand Up @@ -195,6 +196,7 @@ export const useNovel = (novelPath: string, pluginId: string) => {
_chapters.map(_chapter => {
_bookmarkChapter(_chapter.id);
});

setChapters(
chapters.map(chapter => {
if (_chapters.some(_c => _c.id === chapter.id)) {
Expand All @@ -208,19 +210,51 @@ export const useNovel = (novelPath: string, pluginId: string) => {
);
};

const markPreviouschaptersRead = (chapterId: number) => {
const markPreviousChaptersRead = (chapterId: number) => {
if (novel) {
_markPreviuschaptersRead(chapterId, novel.id);
// Track progress if the plugin supports it
const plugin = getPlugin(novel.pluginId);
if (plugin?.trackProgress) {
const chapterPosition = chapters.find(
chapter => chapter.id === chapterId,
)?.position;
const trackedChapter = chapters.find(
chapter => chapter.position === chapterPosition,
);

if (trackedChapter) {
plugin.trackProgress(novel.path, trackedChapter.path);
}
}
_markPreviousChaptersRead(chapterId, novel.id);

setChapters(
chapters.map(chapter =>
chapter.id <= chapterId ? { ...chapter, unread: false } : chapter,
),
chapters.map(chapter => {
if (chapter.id <= chapterId) {
return { ...chapter, unread: false };
}
return chapter;
}),
);
}
};

const markChapterRead = (chapterId: number) => {
if (novel) {
// Track progress if the plugin supports it
const plugin = getPlugin(novel.pluginId);
if (plugin?.trackProgress) {
const selectedChapter = chapters.find(
chapter => chapter.id === chapterId,
);

if (selectedChapter) {
plugin.trackProgress(novel.path, selectedChapter.path);
}
}
}
_markChapterRead(chapterId);

setChapters(
chapters.map(c => {
if (c.id !== chapterId) {
Expand All @@ -235,6 +269,19 @@ export const useNovel = (novelPath: string, pluginId: string) => {
};

const markChaptersRead = (_chapters: ChapterInfo[]) => {
if (novel) {
// Track progress if the plugin supports it
const plugin = getPlugin(novel.pluginId);
if (plugin?.trackProgress) {
// Sort the selected chapters based on the position
const sortedChapters = [..._chapters].sort((a, b) => {
return b.position! - a.position!;
});
const trackedChapter = sortedChapters[0];

plugin.trackProgress?.(novel.path, trackedChapter.path);
}
}
const chapterIds = _chapters.map(chapter => chapter.id);
_markChaptersRead(chapterIds);

Expand All @@ -253,16 +300,56 @@ export const useNovel = (novelPath: string, pluginId: string) => {

const markPreviousChaptersUnread = (chapterId: number) => {
if (novel) {
// Track progress if the plugin supports it
const plugin = getPlugin(novel.pluginId);
if (plugin?.trackProgress) {
const chapterPosition = chapters.find(
chapter => chapter.id === chapterId,
)?.position;
const trackedChapter =
chapters.find(chapter => chapter.position === chapterPosition! - 1) ||
chapters.find(chapter => chapter.position === chapterPosition);

if (trackedChapter) {
plugin.trackProgress(novel.path, trackedChapter.path);
}
}
_markPreviousChaptersUnread(chapterId, novel.id);

setChapters(
chapters.map(chapter =>
chapter.id <= chapterId ? { ...chapter, unread: true } : chapter,
),
chapters.map(chapter => {
if (chapter.id >= chapterId) {
return { ...chapter, unread: true };
}
return chapter;
}),
);
}
};

const markChaptersUnread = (_chapters: ChapterInfo[]) => {
if (novel) {
// Track progress if the plugin supports it
const plugin = getPlugin(novel.pluginId);
if (plugin?.trackProgress) {
// Sort the selected chapters based on the position
const sortedChapters = [..._chapters].sort((a, b) => {
return a.position! - b.position!;
});
const firstChapterPosition = chapters.find(
chapter => chapter.id === sortedChapters[0].id,
)?.position;
const trackedChapter =
chapters.find(
chapter => chapter.position === firstChapterPosition! - 1,
) ||
chapters.find(chapter => chapter.position === firstChapterPosition);

if (trackedChapter) {
plugin.trackProgress(novel.path, trackedChapter.path);
}
}
}
const chapterIds = _chapters.map(chapter => chapter.id);
_markChaptersUnread(chapterIds);

Expand Down Expand Up @@ -406,7 +493,7 @@ export const useNovel = (novelPath: string, pluginId: string) => {
sortAndFilterChapters,
followNovel,
bookmarkChapters,
markPreviouschaptersRead,
markPreviousChaptersRead,
markChaptersRead,
markPreviousChaptersUnread,
markChaptersUnread,
Expand Down
1 change: 1 addition & 0 deletions src/plugins/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export interface Plugin extends PluginItem {
parseNovel: (novelPath: string) => Promise<SourceNovel>;
parsePage?: (novelPath: string, page: string) => Promise<SourcePage>;
parseChapter: (chapterPath: string) => Promise<string>;
trackProgress?: (novelPath: string, chapterPath: string) => Promise<void>;
searchNovels: (searchTerm: string, pageNo: number) => Promise<NovelItem[]>;
resolveUrl?: (path: string, isNovel?: boolean) => string;
webStorageUtilized?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions src/screens/novel/NovelScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const Novel = ({ route, navigation }: NovelScreenProps) => {
bookmarkChapters,
markChaptersRead,
markChaptersUnread,
markPreviouschaptersRead,
markPreviousChaptersRead,
markPreviousChaptersUnread,
followNovel,
deleteChapter,
Expand Down Expand Up @@ -261,7 +261,7 @@ const Novel = ({ route, navigation }: NovelScreenProps) => {
list.push({
icon: 'playlist-check',
onPress: () => {
markPreviouschaptersRead(selected[0].id);
markPreviousChaptersRead(selected[0].id);
setSelected([]);
},
});
Expand Down
8 changes: 8 additions & 0 deletions src/screens/reader/hooks/useChapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { defaultTo } from 'lodash-es';
import { useChapterContext } from '../ChapterContext';
import { showToast } from '@utils/showToast';
import { getString } from '@strings/translations';
import { getPlugin } from '@plugins/pluginManager';

const emmiter = new NativeEventEmitter(VolumeButtonListener);

Expand Down Expand Up @@ -145,6 +146,13 @@ export default function useChapter(webViewRef: RefObject<WebView>) {

if (!incognitoMode && percentage >= 97) {
// a relative number

// Track progress if the plugin supports it
const plugin = getPlugin(novel.pluginId);
if (plugin?.trackProgress && chapter.unread) {
plugin.trackProgress(novel.path, chapter.path);
}

markChapterRead(chapter.id);
updateTracker();
}
Expand Down