diff --git a/components/book/AddNewBookForm.tsx b/components/book/AddNewBookForm.tsx index 2e4df44..b9ff37e 100644 --- a/components/book/AddNewBookForm.tsx +++ b/components/book/AddNewBookForm.tsx @@ -27,7 +27,7 @@ import GuideTour, {GuideStep} from "@/components/GuideTour"; import {UserProps} from "@/lib/models/User"; import {useTranslations} from "next-intl"; import {LangContext, LangContextProps} from "@/context/LangContext"; -// TODO: Refactor to use window.electron.invoke() instead of OfflineDataService +import OfflineContext, {OfflineContextType} from "@/context/OfflineContext"; interface MinMax { min: number; @@ -39,6 +39,7 @@ export default function AddNewBookForm({setCloseForm}: { setCloseForm: Dispatch< const {lang} = useContext(LangContext); const {session, setSession} = useContext(SessionContext); const {errorMessage} = useContext(AlertContext); + const {isCurrentlyOffline} = useContext(OfflineContext); const modalRef: React.RefObject = useRef(null); const [title, setTitle] = useState(''); @@ -123,7 +124,6 @@ export default function AddNewBookForm({setCloseForm}: { setCloseForm: Dispatch< } setIsAddingBook(true); try { - const offlineDataService = getOfflineDataService(); const bookData = { title, subTitle: subtitle, @@ -134,26 +134,25 @@ export default function AddNewBookForm({setCloseForm}: { setCloseForm: Dispatch< desiredWordCount: wordCount }; - const bookId: string = await offlineDataService.createBook( - bookData, - session.user?.id || '', - async () => { - // Only called if online - const id = await System.authPostToServer('book/add', { - title: title, - subTitle: subtitle, - type: selectedBookType, - summary: summary, - serie: 0, - publicationDate: publicationDate, - desiredWordCount: wordCount, - }, token, lang); - if (!id) { - throw new Error(t('addNewBookForm.error.addingBook')); - } - return id; + let bookId: string; + if (!isCurrentlyOffline()) { + // Online - call API server + bookId = await System.authPostToServer('book/add', { + title: title, + subTitle: subtitle, + type: selectedBookType, + summary: summary, + serie: 0, + publicationDate: publicationDate, + desiredWordCount: wordCount, + }, token, lang); + if (!bookId) { + throw new Error(t('addNewBookForm.error.addingBook')); } - ); + } else { + // Offline - call local database + bookId = await window.electron.invoke('db:book:create', bookData); + } const book: BookProps = { bookId: bookId, diff --git a/electron/database/models/Book.ts b/electron/database/models/Book.ts index 82a46bf..ebd07d0 100644 --- a/electron/database/models/Book.ts +++ b/electron/database/models/Book.ts @@ -18,8 +18,7 @@ import fs from "fs"; import BookRepo from "../repositories/book.repository.js"; import Chapter, {ActChapter, ChapterContentData, ChapterProps} from "./Chapter.js"; import UserRepo from "../repositories/user.repository.js"; -import ChapterRepo from "@/electron/database/repositories/chapter.repository"; -import {mainStyle} from "@/electron/database/models/EpubStyle"; +import ChapterRepo from "../repositories/chapter.repository.js"; export interface BookProps{ id:string; diff --git a/electron/database/models/Chapter.ts b/electron/database/models/Chapter.ts index 1e143a8..c1cd358 100644 --- a/electron/database/models/Chapter.ts +++ b/electron/database/models/Chapter.ts @@ -8,9 +8,9 @@ import ChapterRepo, { CompanionContentQueryResult, ChapterStoryQueryResult, ContentQueryResult -} from "@/electron/database/repositories/chapter.repository"; -import System from "../System"; -import {getUserEncryptionKey} from "../keyManager"; +} from "../repositories/chapter.repository.js"; +import System from "../System.js"; +import {getUserEncryptionKey} from "../keyManager.js"; import { generateHTML } from "@tiptap/react"; export interface ChapterContent { diff --git a/electron/database/models/Character.ts b/electron/database/models/Character.ts index a79fcaf..3c34620 100644 --- a/electron/database/models/Character.ts +++ b/electron/database/models/Character.ts @@ -2,9 +2,9 @@ import CharacterRepo, { AttributeResult, CharacterResult, CompleteCharacterResult -} from "@/electron/database/repositories/character.repository"; -import System from "@/electron/database/System"; -import {getUserEncryptionKey} from "../keyManager"; +} from "../repositories/character.repository.js"; +import System from "../System.js"; +import {getUserEncryptionKey} from "../keyManager.js"; export type CharacterCategory = 'Main' | 'Secondary' | 'Recurring'; diff --git a/electron/database/models/Location.ts b/electron/database/models/Location.ts index 1814f1c..248016a 100644 --- a/electron/database/models/Location.ts +++ b/electron/database/models/Location.ts @@ -2,9 +2,9 @@ import LocationRepo, { LocationByTagResult, LocationElementQueryResult, LocationQueryResult -} from "@/electron/database/repositories/location.repository"; -import System from "@/electron/database/System"; -import {getUserEncryptionKey} from "../keyManager"; +} from "../repositories/location.repository.js"; +import System from "../System.js"; +import {getUserEncryptionKey} from "../keyManager.js"; export interface SubElement { id: string; diff --git a/electron/database/models/User.ts b/electron/database/models/User.ts index f3e12c2..d606a54 100644 --- a/electron/database/models/User.ts +++ b/electron/database/models/User.ts @@ -1,7 +1,7 @@ -import UserRepo, {UserAccountQuery, UserInfosQueryResponse} from "@/electron/database/repositories/user.repository"; -import System from "@/electron/database/System"; -import Book, {BookProps} from "@/electron/database/models/Book"; -import {getUserEncryptionKey} from "@/electron/database/keyManager"; +import UserRepo, {UserAccountQuery, UserInfosQueryResponse} from "../repositories/user.repository.js"; +import System from "../System.js"; +import Book, {BookProps} from "./Book.js"; +import {getUserEncryptionKey} from "../keyManager.js"; interface UserAccount{ firstName:string; diff --git a/electron/database/repositories/book.repository.ts b/electron/database/repositories/book.repository.ts index 805e2e3..3e99ab1 100644 --- a/electron/database/repositories/book.repository.ts +++ b/electron/database/repositories/book.repository.ts @@ -1,5 +1,5 @@ import {Database, QueryResult, RunResult, SQLiteValue} from 'node-sqlite3-wasm'; -import System from "@/electron/database/System"; +import System from "../System.js"; export interface BookQuery extends Record { book_id: string; diff --git a/electron/database/repositories/chapter.repository.ts b/electron/database/repositories/chapter.repository.ts index 5b6597f..273fa58 100644 --- a/electron/database/repositories/chapter.repository.ts +++ b/electron/database/repositories/chapter.repository.ts @@ -1,5 +1,5 @@ import {Database, RunResult, SQLiteValue} from 'node-sqlite3-wasm'; -import System from "../System"; +import System from "../System.js"; export interface ChapterContentQueryResult extends Record{ chapter_id: string; diff --git a/electron/database/repositories/character.repository.ts b/electron/database/repositories/character.repository.ts index ab35f98..f1bf243 100644 --- a/electron/database/repositories/character.repository.ts +++ b/electron/database/repositories/character.repository.ts @@ -1,5 +1,5 @@ import {Database, RunResult, SQLiteValue} from 'node-sqlite3-wasm'; -import System from "../System"; +import System from "../System.js"; export interface CharacterResult extends Record { character_id: string; diff --git a/electron/database/repositories/location.repository.ts b/electron/database/repositories/location.repository.ts index 15ff35c..a3bd84e 100644 --- a/electron/database/repositories/location.repository.ts +++ b/electron/database/repositories/location.repository.ts @@ -1,5 +1,5 @@ import {Database, RunResult, SQLiteValue} from 'node-sqlite3-wasm'; -import System from "../System"; +import System from "../System.js"; export interface LocationQueryResult extends Record { loc_id: string; diff --git a/electron/database/repositories/user.repository.ts b/electron/database/repositories/user.repository.ts index fbdca85..c8c64ff 100644 --- a/electron/database/repositories/user.repository.ts +++ b/electron/database/repositories/user.repository.ts @@ -1,5 +1,5 @@ import {Database, RunResult, SQLiteValue} from 'node-sqlite3-wasm'; -import System from "../System"; +import System from "../System.js"; export interface UserInfosQueryResponse extends Record { first_name: string; diff --git a/electron/main.ts b/electron/main.ts index 39e9f1f..4b0fe43 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -222,192 +222,8 @@ ipcMain.handle('db-initialize', (_event, userId: string, encryptionKey: string) } }); -/** - * Get all books - */ -ipcMain.handle('db-get-books', () => { - try { - const db = getDatabaseService(); - const books = db.getBooks(); - return { success: true, data: books }; - } catch (error) { - console.error('Failed to get books:', error); - return { - success: false, - error: error instanceof Error ? error.message : 'Unknown error' - }; - } -}); - -/** - * Get single book with all data - */ -ipcMain.handle('db-get-book', (_event, bookId: string) => { - try { - const db = getDatabaseService(); - const book = db.getBook(bookId); - return { success: true, data: book }; - } catch (error) { - console.error('Failed to get book:', error); - return { - success: false, - error: error instanceof Error ? error.message : 'Unknown error' - }; - } -}); - -/** - * Save book - */ -ipcMain.handle('db-save-book', (_event, book: any, authorId?: string) => { - try { - const db = getDatabaseService(); - db.saveBook(book, authorId); - return { success: true }; - } catch (error) { - console.error('Failed to save book:', error); - return { - success: false, - error: error instanceof Error ? error.message : 'Unknown error' - }; - } -}); - -/** - * Delete book - */ -ipcMain.handle('db-delete-book', (_event, bookId: string) => { - try { - const db = getDatabaseService(); - db.deleteBook(bookId); - return { success: true }; - } catch (error) { - console.error('Failed to delete book:', error); - return { - success: false, - error: error instanceof Error ? error.message : 'Unknown error' - }; - } -}); - -/** - * Save chapter - */ -ipcMain.handle('db-save-chapter', (_event, chapter: any, bookId: string, contentId?: string) => { - try { - const db = getDatabaseService(); - db.saveChapter(chapter, bookId, contentId); - return { success: true }; - } catch (error) { - console.error('Failed to save chapter:', error); - return { - success: false, - error: error instanceof Error ? error.message : 'Unknown error' - }; - } -}); - -/** - * Get characters for a book - */ -ipcMain.handle('db-get-characters', (_event, bookId: string) => { - try { - const db = getDatabaseService(); - const characters = db.getCharacters(bookId); - return { success: true, data: characters }; - } catch (error) { - console.error('Failed to get characters:', error); - return { - success: false, - error: error instanceof Error ? error.message : 'Unknown error' - }; - } -}); - -/** - * Save character - */ -ipcMain.handle('db-save-character', (_event, character: any, bookId: string) => { - try { - const db = getDatabaseService(); - db.saveCharacter(character, bookId); - return { success: true }; - } catch (error) { - console.error('Failed to save character:', error); - return { - success: false, - error: error instanceof Error ? error.message : 'Unknown error' - }; - } -}); - -/** - * Get AI conversations for a book - */ -ipcMain.handle('db-get-conversations', (_event, bookId: string) => { - try { - const db = getDatabaseService(); - const conversations = db.getConversations(bookId); - return { success: true, data: conversations }; - } catch (error) { - console.error('Failed to get conversations:', error); - return { - success: false, - error: error instanceof Error ? error.message : 'Unknown error' - }; - } -}); - -/** - * Save AI conversation - */ -ipcMain.handle('db-save-conversation', (_event, conversation: any, bookId: string) => { - try { - const db = getDatabaseService(); - db.saveConversation(conversation, bookId); - return { success: true }; - } catch (error) { - console.error('Failed to save conversation:', error); - return { - success: false, - error: error instanceof Error ? error.message : 'Unknown error' - }; - } -}); - -/** - * Get sync status - */ -ipcMain.handle('db-get-sync-status', () => { - try { - const db = getDatabaseService(); - const status = db.getSyncStatus(); - return { success: true, data: status }; - } catch (error) { - console.error('Failed to get sync status:', error); - return { - success: false, - error: error instanceof Error ? error.message : 'Unknown error' - }; - } -}); - -/** - * Get pending changes - */ -ipcMain.handle('db-get-pending-changes', (_event, limit: number = 100) => { - try { - const db = getDatabaseService(); - const changes = db.getPendingChanges(limit); - return { success: true, data: changes }; - } catch (error) { - console.error('Failed to get pending changes:', error); - return { - success: false, - error: error instanceof Error ? error.message : 'Unknown error' - }; - } -}); +// NOTE: All database IPC handlers have been moved to ./ipc/book.ipc.ts +// and use the new createHandler() pattern with auto userId/lang injection app.whenReady().then(() => { console.log('App ready, isDev:', isDev); diff --git a/lib/db/sync.service.ts b/lib/db/sync.service.ts index 2e9012e..7cdc252 100644 --- a/lib/db/sync.service.ts +++ b/lib/db/sync.service.ts @@ -21,11 +21,8 @@ export async function getSyncStatus(): Promise { } try { - const result = await window.electron.dbGetSyncStatus(); - if (!result.success) { - throw new Error(result.error); - } - return result.data; + const result = await window.electron.invoke('db:sync:status'); + return result; } catch (error) { console.error('Failed to get sync status:', error); return { @@ -46,11 +43,8 @@ export async function getPendingChanges(limit: number = 100) { } try { - const result = await window.electron.dbGetPendingChanges(limit); - if (!result.success) { - throw new Error(result.error); - } - return result.data || []; + const result = await window.electron.invoke('db:sync:pending-changes', limit); + return result || []; } catch (error) { console.error('Failed to get pending changes:', error); return [];