'use client' import * as tauri from '@/lib/tauri'; import React, {useCallback, useContext, useEffect, useState} from 'react'; import {useTranslations} from 'next-intl'; import {BookContext} from '@/context/BookContext'; import {AlertContext} from '@/context/AlertContext'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {faDownload, faSpinner} from '@fortawesome/free-solid-svg-icons'; import { ChapterExportInfo, ChapterExportSelection, chapterVersions, ExportFormat } from '@/lib/models/Chapter'; const exportFormats: {value: ExportFormat; label: string}[] = [ {value: 'epub', label: 'EPUB'}, {value: 'pdf', label: 'PDF'}, {value: 'docx', label: 'DOCX'}, ]; export default function ExportSetting(): React.JSX.Element { const t = useTranslations(); const {book} = useContext(BookContext); const {errorMessage, successMessage} = useContext(AlertContext); const [format, setFormat] = useState('epub'); const [chapters, setChapters] = useState([]); const [selections, setSelections] = useState([]); const [isLoading, setIsLoading] = useState(true); const [isExporting, setIsExporting] = useState(false); const loadChapters = useCallback(async (): Promise => { if (!book) return; setIsLoading(true); try { const chaptersInfo: ChapterExportInfo[] = await tauri.getBookExportInfo(book.bookId) as ChapterExportInfo[]; setChapters(chaptersInfo); const initialSelections: ChapterExportSelection[] = chaptersInfo.map( (ch: ChapterExportInfo): ChapterExportSelection => ({ chapterId: ch.chapterId, version: ch.availableVersions[ch.availableVersions.length - 1], selected: true }) ); setSelections(initialSelections); } catch { errorMessage(t('exportOption.error')); } finally { setIsLoading(false); } }, [book]); useEffect((): void => { loadChapters(); }, [loadChapters]); function toggleChapter(chapterId: string): void { setSelections((prev: ChapterExportSelection[]): ChapterExportSelection[] => prev.map((s: ChapterExportSelection): ChapterExportSelection => s.chapterId === chapterId ? {...s, selected: !s.selected} : s ) ); } function toggleAll(selectAll: boolean): void { setSelections((prev: ChapterExportSelection[]): ChapterExportSelection[] => prev.map((s: ChapterExportSelection): ChapterExportSelection => ({...s, selected: selectAll})) ); } function updateVersion(chapterId: string, version: number): void { setSelections((prev: ChapterExportSelection[]): ChapterExportSelection[] => prev.map((s: ChapterExportSelection): ChapterExportSelection => s.chapterId === chapterId ? {...s, version} : s ) ); } function getVersionLabel(version: number): string { const found = chapterVersions.find((v) => v.value === String(version)); return found ? t(found.label) : `v${version}`; } async function handleExport(): Promise { if (!book) return; setIsExporting(true); try { const selectedChapters = selections .filter((s: ChapterExportSelection): boolean => s.selected) .map((s: ChapterExportSelection) => ({chapterId: s.chapterId, version: s.version})); const result: boolean = await tauri.exportBook({ bookId: book.bookId, format, selections: selectedChapters.length === chapters.length ? null : selectedChapters }); if (result) { successMessage(t('exportOption.success')); } } catch { errorMessage(t('exportOption.error')); } finally { setIsExporting(false); } } const allSelected: boolean = selections.every((s: ChapterExportSelection): boolean => s.selected); const hasSelection: boolean = selections.some((s: ChapterExportSelection): boolean => s.selected); return (

{t('exportOption.format')}

{exportFormats.map(({value, label}) => ( ))}

{t('exportOption.chapters')}

{chapters.length > 0 && ( )}
{isLoading ? (
{t('exportOption.loadingChapters')}
) : chapters.length === 0 ? (

{t('exportOption.noChapters')}

) : (
{chapters.map((chapter: ChapterExportInfo) => { const selection: ChapterExportSelection | undefined = selections.find( (s: ChapterExportSelection): boolean => s.chapterId === chapter.chapterId ); if (!selection) return null; return (
{chapter.availableVersions.length > 1 && selection.selected && ( )}
); })}
)}
); }