'use client' import React, {ReactNode, useContext, useState} from 'react'; import {ArrowDown, ArrowUp} from 'lucide-react'; import {useTranslations} from '@/lib/i18n'; import {SessionContext, SessionContextProps} from '@/context/SessionContext'; import {AlertContext, AlertContextProps} from '@/context/AlertContext'; import {LangContext, LangContextProps} from '@/context/LangContext'; import {apiPost} from '@/lib/api/client'; import {isDesktop} from '@/lib/configs'; import * as tauri from '@/lib/tauri'; import OfflineContext, {OfflineContextType} from '@/context/OfflineContext'; import {BookContext, BookContextProps} from '@/context/BookContext'; import {BooksSyncContext, BooksSyncContextProps} from '@/context/BooksSyncContext'; import {SyncedBook} from '@/lib/types/synced-book'; import {LocalSyncQueueContext, LocalSyncQueueContextProps} from '@/context/SyncQueueContext'; import IconButton from '@/components/ui/IconButton'; export type SyncElementType = 'character' | 'world' | 'location' | 'spell'; interface SyncFieldWrapperProps { children: ReactNode; seriesElementId: string | null | undefined; seriesValue: string; currentValue: string; bookElementId: string; field: string; elementType: SyncElementType; onDownload: () => void; onSyncComplete?: () => void; } interface SeriesSyncUploadResponse { success: boolean; updatedCount: number; } export default function SyncFieldWrapper({ children, seriesElementId, seriesValue, currentValue, bookElementId, field, elementType, onDownload, onSyncComplete }: SyncFieldWrapperProps) { const t = useTranslations(); const {session}: SessionContextProps = useContext(SessionContext); const {errorMessage, successMessage}: AlertContextProps = useContext(AlertContext); const {lang}: LangContextProps = useContext(LangContext); const {isCurrentlyOffline}: OfflineContextType = useContext(OfflineContext); const {addToQueue}: LocalSyncQueueContextProps = useContext(LocalSyncQueueContext); const {localSyncedBooks}: BooksSyncContextProps = useContext(BooksSyncContext); const {book}: BookContextProps = useContext(BookContext); const [isUploading, setIsUploading] = useState(false); const isLinkedToSeries: boolean = !!seriesElementId; const hasSeriesDiff: boolean = isLinkedToSeries && seriesValue !== currentValue; async function handleUpload(): Promise { if (!seriesElementId || isUploading) return; setIsUploading(true); try { const requestData = {type: elementType, bookElementId, field, value: currentValue}; let response: SeriesSyncUploadResponse; if (isDesktop && (isCurrentlyOffline() || book?.localBook)) { response = await tauri.invoke('series_sync_upload', {data: requestData}); } else { response = await apiPost('series/propagate', requestData, session.accessToken, lang); if (isDesktop && book?.bookId && localSyncedBooks.find((sb: SyncedBook): boolean => sb.id === book.bookId)) { addToQueue('series_sync_upload', requestData); } } if (response.success) { successMessage(t('syncField.uploadSuccess', {count: response.updatedCount})); if (onSyncComplete) { onSyncComplete(); } } } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } } finally { setIsUploading(false); } } function handleDownload(): void { onDownload(); } if (!isLinkedToSeries) { return <>{children}; } return (
{children}
); }