Refactor character, chapter, and story components to support offline mode
- Add `OfflineContext` and `BookContext` to components for offline state management. - Introduce conditional logic to toggle between server API requests and offline IPC handlers for CRUD operations. - Refine `TextEditor`, `DraftCompanion`, and other components to disable actions or features unavailable in offline mode. - Improve error handling and user feedback in both online and offline scenarios.
This commit is contained in:
@@ -32,6 +32,7 @@ import {LangContext, LangContextProps} from "@/context/LangContext";
|
||||
import {BookTags} from "@/lib/models/Book";
|
||||
import {AIUsageContext, AIUsageContextProps} from "@/context/AIUsageContext";
|
||||
import {configs} from "@/lib/configs";
|
||||
import OfflineContext, {OfflineContextType} from "@/context/OfflineContext";
|
||||
|
||||
interface CompanionContent {
|
||||
version: number;
|
||||
@@ -43,6 +44,7 @@ export default function DraftCompanion() {
|
||||
const t = useTranslations();
|
||||
const {setTotalPrice, setTotalCredits} = useContext<AIUsageContextProps>(AIUsageContext)
|
||||
const {lang} = useContext<LangContextProps>(LangContext)
|
||||
const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
|
||||
|
||||
const mainEditor: Editor | null = useEditor({
|
||||
extensions: [
|
||||
@@ -95,7 +97,7 @@ export default function DraftCompanion() {
|
||||
|
||||
const isGPTEnabled: boolean = QuillSense.isOpenAIEnabled(session);
|
||||
const isSubTierTree: boolean = QuillSense.getSubLevel(session) === 3;
|
||||
const hasAccess: boolean = isGPTEnabled || isSubTierTree;
|
||||
const hasAccess: boolean = (isGPTEnabled || isSubTierTree) && !isCurrentlyOffline() && !book?.localBook;
|
||||
|
||||
useEffect((): void => {
|
||||
getDraftContent().then();
|
||||
@@ -106,11 +108,28 @@ export default function DraftCompanion() {
|
||||
|
||||
async function getDraftContent(): Promise<void> {
|
||||
try {
|
||||
const response: CompanionContent = await System.authGetQueryToServer<CompanionContent>(`chapter/content/companion`, session.accessToken, lang, {
|
||||
bookid: book?.bookId,
|
||||
chapterid: chapter?.chapterId,
|
||||
version: chapter?.chapterContent.version,
|
||||
});
|
||||
let response: CompanionContent | null;
|
||||
if (isCurrentlyOffline()) {
|
||||
response = await window.electron.invoke<CompanionContent>('db:chapter:content:companion', {
|
||||
bookid: book?.bookId,
|
||||
chapterid: chapter?.chapterId,
|
||||
version: chapter?.chapterContent.version,
|
||||
});
|
||||
} else {
|
||||
if (book?.localBook) {
|
||||
response = await window.electron.invoke<CompanionContent>('db:chapter:content:companion', {
|
||||
bookid: book?.bookId,
|
||||
chapterid: chapter?.chapterId,
|
||||
version: chapter?.chapterContent.version,
|
||||
});
|
||||
} else {
|
||||
response = await System.authGetQueryToServer<CompanionContent>(`chapter/content/companion`, session.accessToken, lang, {
|
||||
bookid: book?.bookId,
|
||||
chapterid: chapter?.chapterId,
|
||||
version: chapter?.chapterContent.version,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (response && mainEditor) {
|
||||
mainEditor.commands.setContent(JSON.parse(response.content));
|
||||
setDraftVersion(response.version);
|
||||
@@ -145,9 +164,18 @@ export default function DraftCompanion() {
|
||||
|
||||
async function fetchTags(): Promise<void> {
|
||||
try {
|
||||
const responseTags: BookTags = await System.authGetQueryToServer<BookTags>(`book/tags`, session.accessToken, lang, {
|
||||
bookId: book?.bookId
|
||||
});
|
||||
let responseTags: BookTags | null;
|
||||
if (isCurrentlyOffline()) {
|
||||
responseTags = await window.electron.invoke<BookTags>('db:book:tags', book?.bookId);
|
||||
} else {
|
||||
if (book?.localBook) {
|
||||
responseTags = await window.electron.invoke<BookTags>('db:book:tags', book?.bookId);
|
||||
} else {
|
||||
responseTags = await System.authGetQueryToServer<BookTags>(`book/tags`, session.accessToken, lang, {
|
||||
bookId: book?.bookId
|
||||
});
|
||||
}
|
||||
}
|
||||
if (responseTags) {
|
||||
setCharacters(responseTags.characters);
|
||||
setLocations(responseTags.locations);
|
||||
|
||||
@@ -22,6 +22,7 @@ import {ChapterContext} from '@/context/ChapterContext';
|
||||
import System from '@/lib/models/System';
|
||||
import {AlertContext} from '@/context/AlertContext';
|
||||
import {SessionContext} from "@/context/SessionContext";
|
||||
import {BookContext} from '@/context/BookContext';
|
||||
import DraftCompanion from "@/components/editor/DraftCompanion";
|
||||
import GhostWriter from "@/components/ghostwriter/GhostWriter";
|
||||
import SubmitButtonWLoading from "@/components/form/SubmitButtonWLoading";
|
||||
@@ -135,6 +136,7 @@ export default function TextEditor() {
|
||||
const {lang} = useContext<LangContextProps>(LangContext)
|
||||
const {editor} = useContext(EditorContext);
|
||||
const {chapter} = useContext(ChapterContext);
|
||||
const {book} = useContext(BookContext);
|
||||
const {errorMessage, successMessage} = useContext(AlertContext);
|
||||
const {session} = useContext(SessionContext);
|
||||
const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
|
||||
@@ -294,13 +296,23 @@ export default function TextEditor() {
|
||||
currentTime: mainTimer
|
||||
})
|
||||
} else {
|
||||
response = await System.authPostToServer<boolean>(`chapter/content`, {
|
||||
chapterId,
|
||||
version,
|
||||
content,
|
||||
totalWordCount: editor.getText().length,
|
||||
currentTime: mainTimer
|
||||
}, session?.accessToken, lang);
|
||||
if (book?.localBook) {
|
||||
response = await window.electron.invoke<boolean>('db:chapter:content:save',{
|
||||
chapterId,
|
||||
version,
|
||||
content,
|
||||
totalWordCount: editor.getText().length,
|
||||
currentTime: mainTimer
|
||||
})
|
||||
} else {
|
||||
response = await System.authPostToServer<boolean>(`chapter/content`, {
|
||||
chapterId,
|
||||
version,
|
||||
content,
|
||||
totalWordCount: editor.getText().length,
|
||||
currentTime: mainTimer
|
||||
}, session?.accessToken, lang);
|
||||
}
|
||||
}
|
||||
if (!response) {
|
||||
errorMessage(t('editor.error.savedFailed'));
|
||||
@@ -467,7 +479,7 @@ export default function TextEditor() {
|
||||
onClick={handleShowUserSettings}
|
||||
icon={faCog}
|
||||
/>
|
||||
{chapter?.chapterContent.version === 2 && !isCurrentlyOffline() && (
|
||||
{chapter?.chapterContent.version === 2 && !isCurrentlyOffline() && !book?.localBook && (
|
||||
<CollapsableButton
|
||||
showCollapsable={showGhostWriter}
|
||||
text={t("textEditor.ghostWriter")}
|
||||
|
||||
Reference in New Issue
Block a user