feat: ship v1.1.0 writer toolkit with templates, import, export, and inspiration capture

Implement chapter templates, txt/md/docx import, submission export presets, and global inspiration shortcut. Split import handlers into a separate main bundle and fix EditorLayout setTarget loop that broke E2E.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-08 13:53:22 +08:00
parent ea4819847f
commit adf877861d
49 changed files with 2450 additions and 87 deletions
@@ -4,6 +4,8 @@ import type { ThemeId, Language, PomodoroDuration } from '@shared/types'
import { useSettingsStore } from '@renderer/stores/useSettingsStore'
import { ShortcutEditor } from '@renderer/components/settings/ShortcutEditor'
import { AiSettingsPage } from '@renderer/components/settings/AiSettingsPage'
import { TemplateSettingsTab } from '@renderer/components/settings/TemplateSettingsTab'
import { SubmissionPresetTab } from '@renderer/components/settings/SubmissionPresetTab'
const THEMES: { id: ThemeId; key: string }[] = [
{ id: 'default', key: 'theme.default' },
@@ -18,7 +20,9 @@ const THEMES: { id: ThemeId; key: string }[] = [
export function SettingsPage(): React.JSX.Element {
const { t } = useTranslation()
const settings = useSettingsStore()
const [section, setSection] = useState<'general' | 'ai' | 'shortcuts' | 'about'>('general')
const [section, setSection] = useState<
'general' | 'ai' | 'templates' | 'submission' | 'shortcuts' | 'about'
>('general')
return (
<div id="settings-page">
@@ -40,6 +44,24 @@ export function SettingsPage(): React.JSX.Element {
>
{t('settings.ai')}
</div>
<div
className={`settings-nav-item ${section === 'templates' ? 'active' : ''}`}
onClick={() => setSection('templates')}
role="button"
tabIndex={0}
data-testid="settings-nav-templates"
>
{t('settings.templates')}
</div>
<div
className={`settings-nav-item ${section === 'submission' ? 'active' : ''}`}
onClick={() => setSection('submission')}
role="button"
tabIndex={0}
data-testid="settings-nav-submission"
>
{t('settings.submission')}
</div>
<div
className={`settings-nav-item ${section === 'shortcuts' ? 'active' : ''}`}
onClick={() => setSection('shortcuts')}
@@ -225,10 +247,12 @@ export function SettingsPage(): React.JSX.Element {
</>
)}
{section === 'ai' && <AiSettingsPage />}
{section === 'templates' && <TemplateSettingsTab />}
{section === 'submission' && <SubmissionPresetTab />}
{section === 'shortcuts' && <ShortcutEditor />}
{section === 'about' && (
<p style={{ color: 'var(--text-secondary)', lineHeight: 1.8 }}>
{t('app.name')} v1.0.0
{t('app.name')} v1.1.0
<br />
{t('app.tagline')}
</p>