Refactor and extend offline synchronization logic across components and services
- Integrated sync queue mechanisms with `LocalSyncQueueContext` for offline data handling. - Updated key sync-related services (e.g., book, chapter, series) to support offline-first functionality. - Removed redundant database fetch methods to optimize repository logic and improve maintainability. - Enhanced Tauri IPC usage for sync operations and removed legacy methods in Rust services.
This commit is contained in:
@@ -26,6 +26,9 @@ import {apiPost} from '@/lib/api/client';
|
||||
import {isDesktop} from '@/lib/configs';
|
||||
import * as tauri from '@/lib/tauri';
|
||||
import OfflineContext, {OfflineContextType} from '@/context/OfflineContext';
|
||||
import {BooksSyncContext, BooksSyncContextProps} from '@/context/BooksSyncContext';
|
||||
import {SyncedBook} from '@/lib/types/synced-book';
|
||||
import {LocalSyncQueueContext, LocalSyncQueueContextProps} from '@/context/SyncQueueContext';
|
||||
import {AlertContext, AlertContextProps} from '@/context/AlertContext';
|
||||
import {SessionContext, SessionContextProps} from "@/context/SessionContext";
|
||||
import DraftCompanion from "@/components/editor/DraftCompanion";
|
||||
@@ -144,7 +147,9 @@ export default function TextEditor() {
|
||||
const {errorMessage, successMessage}: AlertContextProps = useContext<AlertContextProps>(AlertContext);
|
||||
const {session}: SessionContextProps = useContext<SessionContextProps>(SessionContext);
|
||||
const {isCurrentlyOffline}: OfflineContextType = useContext<OfflineContextType>(OfflineContext);
|
||||
|
||||
const {addToQueue}: LocalSyncQueueContextProps = useContext<LocalSyncQueueContextProps>(LocalSyncQueueContext);
|
||||
const {localSyncedBooks}: BooksSyncContextProps = useContext<BooksSyncContextProps>(BooksSyncContext);
|
||||
|
||||
const [mainTimer, setMainTimer] = useState<number>(0);
|
||||
const [showDraftCompanion, setShowDraftCompanion] = useState<boolean>(false);
|
||||
const [showGhostWriter, setShowGhostWriter] = useState<boolean>(false);
|
||||
@@ -291,13 +296,18 @@ export default function TextEditor() {
|
||||
contentId: '',
|
||||
});
|
||||
} else {
|
||||
response = await apiPost<boolean>(`chapter/content`, {
|
||||
const saveData = {
|
||||
chapterId,
|
||||
version,
|
||||
content,
|
||||
totalWordCount: editor.getText().length,
|
||||
currentTime: mainTimer
|
||||
}, session?.accessToken ?? '');
|
||||
};
|
||||
response = await apiPost<boolean>(`chapter/content`, saveData, session?.accessToken ?? '');
|
||||
|
||||
if (isDesktop && localSyncedBooks.find((sb: SyncedBook): boolean => sb.id === book?.bookId)) {
|
||||
addToQueue('save_chapter_content', saveData);
|
||||
}
|
||||
}
|
||||
if (!response) {
|
||||
errorMessage(t('editor.error.savedFailed'));
|
||||
@@ -315,7 +325,7 @@ export default function TextEditor() {
|
||||
}
|
||||
setIsSaving(false);
|
||||
}
|
||||
}, [editor, chapter, mainTimer, session?.accessToken, successMessage, errorMessage]);
|
||||
}, [editor, chapter, mainTimer, session?.accessToken, successMessage, errorMessage, addToQueue, book?.localBook, isCurrentlyOffline]);
|
||||
|
||||
const handleShowDraftCompanion: () => void = useCallback((): void => {
|
||||
setShowDraftCompanion((prev: boolean): boolean => !prev);
|
||||
@@ -454,7 +464,7 @@ export default function TextEditor() {
|
||||
onClick={handleShowUserSettings}
|
||||
tooltip={t("textEditor.preferences")}
|
||||
/>
|
||||
{chapter?.chapterContent.version === 2 && book?.quillsenseEnabled !== false && (
|
||||
{chapter?.chapterContent.version === 2 && !isCurrentlyOffline() && !book?.localBook && book?.quillsenseEnabled !== false && (
|
||||
<IconButton
|
||||
icon={Ghost}
|
||||
variant="ghost"
|
||||
|
||||
Reference in New Issue
Block a user