diff --git a/app/page.tsx b/app/page.tsx index 5dec6ce..88dc5f7 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -205,13 +205,11 @@ function ScribeContent() { let serverBooksResponse: SyncedBook[] = []; if (!isCurrentlyOffline()){ - // Mode online: récupérer les livres du serveur ET de la DB locale if (offlineMode.isDatabaseInitialized) { localBooksResponse = await window.electron.invoke('db:books:synced'); } serverBooksResponse = await System.authGetQueryToServer('books/synced', session.accessToken, locale); } else { - // Mode offline: récupérer uniquement depuis la DB locale if (offlineMode.isDatabaseInitialized) { localBooksResponse = await window.electron.invoke('db:books:synced'); } @@ -364,13 +362,6 @@ function ScribeContent() { console.error('[Page] Error initializing user:', error); } } - setSession({ - isConnected: true, - user: user, - accessToken: token, - }); - setCurrentCredits(user.creditsBalance) - setAmountSpent(user.aiUsage) if (window.electron && user.id) { try { const dbInitialized:boolean = await initializeDatabase(user.id); @@ -392,6 +383,13 @@ function ScribeContent() { console.error('Failed to initialize database:', error); } } + setSession({ + isConnected: true, + user: user, + accessToken: token, + }); + setCurrentCredits(user.creditsBalance) + setAmountSpent(user.aiUsage) } catch (e: unknown) { if (window.electron) { try { diff --git a/components/book/BookList.tsx b/components/book/BookList.tsx index 8eb9a9a..90bd1f3 100644 --- a/components/book/BookList.tsx +++ b/components/book/BookList.tsx @@ -86,10 +86,9 @@ export default function BookList() { setBookGuide(true); } }, [groupedBooks]); - - // Charger les livres quand les conditions sont remplies + useEffect((): void => { - const shouldFetchBooks = + const shouldFetchBooks:boolean|"" = (session.isConnected || accessToken) && (!isCurrentlyOffline() || offlineMode.isDatabaseInitialized); @@ -119,7 +118,6 @@ export default function BookList() { setBookGuide(false); } } else { - // Mode offline: stocker dans localStorage const completedGuides = JSON.parse(localStorage.getItem('completedGuides') || '[]'); if (!completedGuides.includes('new-first-book')) { completedGuides.push('new-first-book'); @@ -229,6 +227,7 @@ export default function BookList() { async function getBook(bookId: string): Promise { try { + let localBookOnly: boolean = false; let bookResponse: BookListProps|null = null; if (isCurrentlyOffline()){ if (!offlineMode.isDatabaseInitialized) { @@ -236,10 +235,18 @@ export default function BookList() { return; } bookResponse = await window.electron.invoke('db:book:bookBasicInformation', bookId) + if (bookResponse) { + localBookOnly = true; + } } else { - bookResponse = await System.authGetQueryToServer(`book/basic-information`, accessToken, lang, { - id: bookId - }); + const isOfflineBook: SyncedBook | undefined = localOnlyBooks.find((book: SyncedBook):boolean => book.id === bookId); + if (isOfflineBook) { + bookResponse = await window.electron.invoke('db:book:bookBasicInformation', bookId) + localBookOnly = true; + } + if (!bookResponse) { + bookResponse = await System.authGetQueryToServer(`book/basic-information`, accessToken, lang, {id: bookId}); + } } if (!bookResponse) { errorMessage(t("bookList.errorBookDetails")); @@ -256,6 +263,7 @@ export default function BookList() { publicationDate: bookResponse?.desiredReleaseDate || '', desiredWordCount: bookResponse?.desiredWordCount || 0, totalWordCount: 0, + localBook: localBookOnly, coverImage: bookResponse?.coverImage ? 'data:image/jpeg;base64,' + bookResponse.coverImage : '', }); } diff --git a/components/leftbar/ScribeChapterComponent.tsx b/components/leftbar/ScribeChapterComponent.tsx index b893788..0315786 100644 --- a/components/leftbar/ScribeChapterComponent.tsx +++ b/components/leftbar/ScribeChapterComponent.tsx @@ -1,5 +1,5 @@ import {ChapterListProps, ChapterProps} from "@/lib/models/Chapter"; -import {useContext, useEffect, useRef, useState} from "react"; +import {RefObject, useContext, useEffect, useRef, useState} from "react"; import System from "@/lib/models/System"; import {BookContext} from "@/context/BookContext"; import {AlertContext} from "@/context/AlertContext"; @@ -32,8 +32,8 @@ export default function ScribeChapterComponent() { const [deleteConfirmationMessage, setDeleteConfirmationMessage] = useState(false); const [removeChapterId, setRemoveChapterId] = useState(''); - const chapterRefs = useRef>(new Map()); - const scrollContainerRef = useRef(null); + const chapterRefs: RefObject> = useRef>(new Map()); + const scrollContainerRef: RefObject = useRef(null); useEffect((): void => { if (book) @@ -46,9 +46,9 @@ export default function ScribeChapterComponent() { useEffect((): void => { if (chapter?.chapterId && scrollContainerRef.current) { - setTimeout(() => { - const element = chapterRefs.current.get(chapter.chapterId); - const container = scrollContainerRef.current; + setTimeout(():void => { + const element: HTMLDivElement | undefined = chapterRefs.current.get(chapter.chapterId); + const container: HTMLUListElement | null = scrollContainerRef.current; if (element && container) { const containerRect:DOMRect = container.getBoundingClientRect(); @@ -77,7 +77,11 @@ export default function ScribeChapterComponent() { if (isCurrentlyOffline()){ response = await window.electron.invoke('db:book:chapters', book?.bookId) } else { - response = await System.authGetQueryToServer(`book/chapters?id=${book?.bookId}`, userToken, lang); + if (book?.localBook){ + response = await window.electron.invoke('db:book:chapters', book?.bookId) + } else { + response = await System.authGetQueryToServer(`book/chapters?id=${book?.bookId}`, userToken, lang); + } } if (response) { setChapters(response); @@ -94,7 +98,7 @@ export default function ScribeChapterComponent() { async function getChapter(chapterId: string): Promise { const version: number = chapter?.chapterContent.version ? chapter?.chapterContent.version : 2; try { - let response: ChapterProps | null = null + let response: ChapterProps | null if (isCurrentlyOffline()) { response = await window.electron.invoke('db:chapter:whole', { bookid: book?.bookId, @@ -102,11 +106,19 @@ export default function ScribeChapterComponent() { version: version, }) } else { - response = await System.authGetQueryToServer(`chapter/whole`, userToken, lang, { - bookid: book?.bookId, - id: chapterId, - version: version, - }); + if (book?.localBook){ + response = await window.electron.invoke('db:chapter:whole', { + bookid: book?.bookId, + id: chapterId, + version: version, + }) + } else { + response = await System.authGetQueryToServer(`chapter/whole`, userToken, lang, { + bookid: book?.bookId, + id: chapterId, + version: version, + }); + } } if (!response) { errorMessage(t("scribeChapterComponent.errorFetchChapter")); @@ -132,11 +144,19 @@ export default function ScribeChapterComponent() { title: title, }) } else { - response = await System.authPostToServer('chapter/update', { - chapterId: chapterId, - chapterOrder: chapterOrder, - title: title, - }, userToken, lang); + if (book?.localBook){ + response = await window.electron.invoke('db:chapter:update',{ + chapterId: chapterId, + chapterOrder: chapterOrder, + title: title, + }) + } else { + response = await System.authPostToServer('chapter/update', { + chapterId: chapterId, + chapterOrder: chapterOrder, + title: title, + }, userToken, lang); + } } if (!response) { errorMessage(t("scribeChapterComponent.errorChapterUpdate")); @@ -173,9 +193,13 @@ export default function ScribeChapterComponent() { if (isCurrentlyOffline()) { response = await window.electron.invoke('db:chapter:remove', removeChapterId) } else { - response = await System.authDeleteToServer('chapter/remove', { - chapterId: removeChapterId, - }, userToken, lang); + if (book?.localBook){ + response = await window.electron.invoke('db:chapter:remove', removeChapterId) + } else { + response = await System.authDeleteToServer('chapter/remove', { + chapterId: removeChapterId, + }, userToken, lang); + } } if (!response) { errorMessage(t("scribeChapterComponent.errorChapterDelete")); @@ -209,11 +233,19 @@ export default function ScribeChapterComponent() { title: chapterTitle }) } else { - chapterId = await System.authPostToServer('chapter/add', { - bookId: book?.bookId, - chapterOrder: chapterOrder, - title: chapterTitle - }, userToken, lang); + if (book?.localBook){ + chapterId = await window.electron.invoke('db:chapter:add', { + bookId: book?.bookId, + chapterOrder: chapterOrder, + title: chapterTitle + }) + } else { + chapterId = await System.authPostToServer('chapter/add', { + bookId: book?.bookId, + chapterOrder: chapterOrder, + title: chapterTitle + }, userToken, lang); + } } if (!chapterId) { errorMessage(t("scribeChapterComponent.errorChapterSubmit", {chapterName: newChapterName})); diff --git a/lib/models/Book.ts b/lib/models/Book.ts index 59fd4b7..fd49ef4 100644 --- a/lib/models/Book.ts +++ b/lib/models/Book.ts @@ -69,6 +69,7 @@ export interface BookProps { desiredWordCount?: number; totalWordCount?: number; coverImage?: string; + localBook?: boolean; chapters?: ChapterProps[]; }