'use client'; import { useState, useCallback } from 'react'; import { useAppStore } from '../store/useAppStore'; import { useI18n } from '../lib/useI18n'; import { createChapter, deleteChapter, updateChapter, exportToMarkdown, exportAllToMarkdown } from '../lib/storage'; import { exportProject, importProject } from '../lib/project-io'; import { WRITING_MODES } from '../lib/settings'; export default function Sidebar() { const { chapters, addChapter, setChapters, updateChapter: updateChapterStore, activeChapterId, setActiveChapterId, sidebarOpen, setSidebarOpen, theme, setTheme, writingMode, setShowSettings, setShowSnapshots, showToast } = useAppStore(); const [renameId, setRenameId] = useState(null); const [renameTitle, setRenameTitle] = useState(''); const [contextMenu, setContextMenu] = useState(null); const { t } = useI18n(); // 切换主题 const toggleTheme = useCallback(() => { const next = theme === 'light' ? 'dark' : 'light'; setTheme(next); document.documentElement.setAttribute('data-theme', next); localStorage.setItem('author-theme', next); }, [theme, setTheme]); // 从上一章节名推算下一章节名:提取末尾数字 +1 const getNextChapterTitle = useCallback(() => { if (chapters.length === 0) return t('sidebar.defaultChapterTitle').replace('{num}', 1); const lastTitle = chapters[chapters.length - 1].title; const match = lastTitle.match(/(\d+)\s*$/); if (match) { const nextNum = parseInt(match[1], 10) + 1; return lastTitle.replace(/(\d+)\s*$/, String(nextNum)); } return t('sidebar.defaultChapterTitle').replace('{num}', chapters.length + 1); }, [chapters, t]); // 创建新章节 — 一键创建并进入重命名模式 const handleCreateChapter = useCallback(async () => { const title = getNextChapterTitle(); const ch = await createChapter(title); addChapter(ch); setActiveChapterId(ch.id); // 立即进入重命名模式,方便用户修改标题 setRenameId(ch.id); setRenameTitle(title); showToast(t('sidebar.chapterCreated').replace('{title}', title), 'success'); }, [getNextChapterTitle, showToast, addChapter, setActiveChapterId, t]); // 删除章节 const handleDeleteChapter = useCallback((id) => { if (chapters.length <= 1) { showToast(t('sidebar.alertRetainOne'), 'error'); return; } const ch = chapters.find(c => c.id === id); const remaining = deleteChapter(id); setChapters(remaining); if (activeChapterId === id) { setActiveChapterId(remaining[0]?.id || null); } showToast(t('sidebar.chapterDeleted').replace('{title}', ch?.title), 'info'); setContextMenu(null); }, [chapters, activeChapterId, showToast, setChapters, setActiveChapterId, t]); // 重命名章节 const handleRename = useCallback((id) => { const title = renameTitle.trim(); if (!title) return; const updated = updateChapter(id, { title }); updateChapterStore(id, { title }); setRenameId(null); setRenameTitle(''); }, [renameTitle, updateChapterStore]); // 导出 const handleExport = useCallback((type) => { if (type === 'current' && activeChapterId) { const activeChapter = chapters.find(ch => ch.id === activeChapterId); if (activeChapter) { exportToMarkdown(activeChapter); showToast(t('sidebar.exportedChapter'), 'success'); } } else if (type === 'all') { exportAllToMarkdown(chapters); showToast(t('sidebar.exportedAll'), 'success'); } }, [activeChapterId, chapters, showToast, t]); const totalWords = chapters.reduce((sum, ch) => sum + (ch.wordCount || 0), 0); return ( <> {/* ===== 右键菜单 ===== */} {contextMenu && (
setContextMenu(null)} >
)} ); }