import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; import {faCloud, faCloudArrowDown, faCloudArrowUp, faSpinner} from "@fortawesome/free-solid-svg-icons"; import {useTranslations} from "next-intl"; import {useState, useContext} from "react"; import OfflineContext, {OfflineContextType} from "@/context/OfflineContext"; import System from "@/lib/models/System"; import {SessionContext, SessionContextProps} from "@/context/SessionContext"; import {LangContext} from "@/context/LangContext"; import {CompleteBook} from "@/lib/models/Book"; import {BooksSyncContext, BooksSyncContextProps, SyncType} from "@/context/BooksSyncContext"; import {AlertContext, AlertContextProps} from "@/context/AlertContext"; import {BookSyncCompare, SyncedBook} from "@/lib/models/SyncedBook"; interface SyncBookProps { bookId: string; status: SyncType; } export default function SyncBook({bookId, status}: SyncBookProps) { const t = useTranslations(); const {session} = useContext(SessionContext); const {lang} = useContext(LangContext); const {errorMessage} = useContext(AlertContext); const {isCurrentlyOffline} = useContext(OfflineContext); const [isLoading, setIsLoading] = useState(false); const [currentStatus, setCurrentStatus] = useState(status); const {booksToSyncToServer, booksToSyncFromServer,serverSyncedBooks,localSyncedBooks,setLocalOnlyBooks, setServerOnlyBooks} = useContext(BooksSyncContext) const isOffline: boolean = isCurrentlyOffline(); async function upload(): Promise { if (isOffline) { return; } setIsLoading(true); try { const bookToSync: CompleteBook = await window.electron.invoke('db:book:uploadToServer', bookId); if (!bookToSync) { errorMessage(t("bookCard.uploadError")); return; } const response: boolean = await System.authPostToServer('book/sync/upload', { book: bookToSync }, session.accessToken, lang); if (!response) { errorMessage(t("bookCard.uploadError")); return; } setCurrentStatus('synced'); setLocalOnlyBooks((prevBooks: SyncedBook[]): SyncedBook[] => { return prevBooks.filter((book: SyncedBook): boolean => book.id !== bookId) }); } catch (e:unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("bookCard.uploadError")); } } finally { setIsLoading(false); } } async function download(): Promise { if (isOffline) { return; } setIsLoading(true); try { const response: CompleteBook = await System.authGetQueryToServer('book/sync/download', session.accessToken, lang, {bookId}); if (!response) { errorMessage(t("bookCard.downloadError")); return; } const syncStatus:boolean = await window.electron.invoke('db:book:syncSave', response); if (!syncStatus) { errorMessage(t("bookCard.downloadError")); return; } setCurrentStatus('synced'); setServerOnlyBooks((prevBooks: SyncedBook[]): SyncedBook[] => { return prevBooks.filter((book: SyncedBook): boolean => book.id !== bookId) }); } catch (e:unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("bookCard.downloadError")); } } finally { setIsLoading(false); } } async function syncFromServer(): Promise { if (isOffline) { return; } setIsLoading(true); try { const bookToFetch:BookSyncCompare|undefined = booksToSyncFromServer.find((book:BookSyncCompare):boolean => book.id === bookId); if (!bookToFetch) { errorMessage(t("bookCard.syncFromServerError")); return; } const response: CompleteBook = await System.authPostToServer('book/sync/server-to-client', { bookToSync: bookToFetch }, session.accessToken, lang); if (!response) { errorMessage(t("bookCard.syncFromServerError")); return; } const syncStatus:boolean = await window.electron.invoke('db:book:sync:toClient', response); if (!syncStatus) { errorMessage(t("bookCard.syncFromServerError")); return; } setCurrentStatus('synced'); } catch (e:unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("bookCard.syncFromServerError")); } } finally { setIsLoading(false); } } async function syncToServer(): Promise { if (isOffline) { return; } setIsLoading(true); try { const bookToFetch:BookSyncCompare|undefined = booksToSyncToServer.find((book:BookSyncCompare):boolean => book.id === bookId); if (!bookToFetch) { errorMessage(t("bookCard.syncToServerError")); return; } const bookToSync: CompleteBook = await window.electron.invoke('db:book:sync:toServer', bookToFetch); if (!bookToSync) { errorMessage(t("bookCard.syncToServerError")); return; } const response: boolean = await System.authPatchToServer('book/sync/client-to-server', { book: bookToSync }, session.accessToken, lang); if (!response) { errorMessage(t("bookCard.syncToServerError")); return; } setCurrentStatus('synced'); } catch (e:unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("bookCard.syncToServerError")); } } finally { setIsLoading(false); } } if (isLoading) { return (
); } return (
{currentStatus === 'synced' && ( )} {currentStatus === 'local-only' && ( )} {currentStatus === 'server-only' && ( )} {currentStatus === 'to-sync-from-server' && ( )} {currentStatus === 'to-sync-to-server' && ( )}
); }