fix: S1 安全冲刺——切库清空标签页+冲刷(FR-V6)、重命名/移动同步标签页路径(FR-T7)、默认库路径设置页(FR-V5);vaultBrowse IPC+pickDirectory;tab-store closeAll/renamePath;store resetEditor/syncCurrentPath;safety E2E 2 项
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useSettings } from './settings-store';
|
||||
import { useKeymap } from '../keymap/keymap-service';
|
||||
import { useStore } from '../../store';
|
||||
import { useTabs } from '../tabs/tab-store';
|
||||
import { invoke } from '../../ipc-client';
|
||||
import { IPC } from '@hunter/shared';
|
||||
|
||||
const pageBtn: React.CSSProperties = { padding: '8px 14px', border: 'none', background: 'transparent', color: '#888', cursor: 'pointer', borderBottom: '2px solid transparent', fontSize: 13 };
|
||||
const row: React.CSSProperties = { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '10px 0', borderBottom: '1px solid #2a2a3a' };
|
||||
@@ -54,7 +58,7 @@ export function SettingsPanel({ onClose }: { onClose: () => void }) {
|
||||
<div style={row}><span style={lbl}>自动换行</span><button onClick={() => s.set('wordWrap', !s.wordWrap)} style={toggle(s.wordWrap)}><span style={dot(s.wordWrap)} /></button></div>
|
||||
</>}
|
||||
{page === 'other' && <div style={row}><span style={lbl}>删除前确认</span><button onClick={() => s.set('confirmDelete', !s.confirmDelete)} style={toggle(s.confirmDelete)}><span style={dot(s.confirmDelete)} /></button></div>}
|
||||
{page === 'path' && <div style={{ ...lbl, opacity: 0.6, padding: '12px 0' }}>文件路径设置将在 M9 完善(默认库路径配置)</div>}
|
||||
{page === 'path' && <PathPage />}
|
||||
{page === 'keymap' && <>
|
||||
<div style={{ ...lbl, opacity: 0.6, marginBottom: 8 }}>点击「录入」后按下新组合键(需含 Ctrl/Meta/Alt);Esc 取消</div>
|
||||
{bindings.map(b => {
|
||||
@@ -81,3 +85,46 @@ export function SettingsPanel({ onClose }: { onClose: () => void }) {
|
||||
|
||||
const sel: React.CSSProperties = { background: '#15151f', border: '1px solid #3a3a4a', color: '#ddd', borderRadius: 4, padding: '4px 8px', fontSize: 13 };
|
||||
function dot(on: boolean): React.CSSProperties { return { position: 'absolute', top: 2, left: on ? 18 : 2, width: 16, height: 16, borderRadius: '50%', background: '#fff', transition: 'left 0.2s' }; }
|
||||
|
||||
// FR-V5: 默认库路径设置页——查看当前库、浏览选择、立即切换
|
||||
function PathPage() {
|
||||
const { vault, loadVault, loadTree } = useStore();
|
||||
const [val, setVal] = useState(vault?.currentRoot ?? '');
|
||||
const [msg, setMsg] = useState('');
|
||||
const browse = async () => { const p = await invoke(IPC.vaultBrowse, undefined as never); if (p) setVal(p); };
|
||||
const apply = async () => {
|
||||
if (!val.trim()) { setMsg('请填写或浏览选择库路径'); return; }
|
||||
try {
|
||||
setMsg('切换中…');
|
||||
await useStore.getState().saveNow(); // 先冲刷未保存到旧库
|
||||
await invoke(IPC.vaultSwitch, { root: val.trim() });
|
||||
useTabs.getState().closeAll(); // 清空标签页(FR-V6)
|
||||
useStore.getState().resetEditor(); // 重置编辑区
|
||||
await loadVault();
|
||||
await loadTree();
|
||||
setMsg('已切换到:' + val.trim());
|
||||
} catch (e: any) { setMsg('切换失败:' + (e?.message ?? String(e))); }
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div style={{ ...row, alignItems: 'flex-start' }}>
|
||||
<span style={{ ...lbl, paddingTop: 6 }}>当前库路径</span>
|
||||
<span style={{ fontSize: 12, color: '#9cf', maxWidth: 320, wordBreak: 'break-all', textAlign: 'right' }}>{vault?.currentRoot ?? '—'}</span>
|
||||
</div>
|
||||
<div style={{ ...row, alignItems: 'flex-start' }}>
|
||||
<span style={{ ...lbl, paddingTop: 6 }}>新库路径</span>
|
||||
<span style={{ display: 'flex', gap: 6, flex: 1, justifyContent: 'flex-end' }}>
|
||||
<input value={val} onChange={e => setVal(e.target.value)} placeholder="填写或浏览选择目录…" style={{ ...sel, flex: 1, maxWidth: 220 }} />
|
||||
<button onClick={browse} style={{ ...sel, cursor: 'pointer' }}>浏览…</button>
|
||||
</span>
|
||||
</div>
|
||||
<div style={{ ...row }}>
|
||||
<span style={lbl} />
|
||||
<span style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
|
||||
{msg && <span style={{ fontSize: 12, color: msg.startsWith('切换失败') ? '#f88' : (msg.startsWith('已切换') ? '#8c8' : '#9cf') }}>{msg}</span>}
|
||||
<button onClick={apply} style={{ ...sel, cursor: 'pointer', background: '#2a4a6a', color: '#9cf' }}>立即切换</button>
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user