增加了基础的块功能
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Lock, Save, Sparkles, Type, Upload, Download, Loader2 } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Lock, Save, Sparkles, Type, Upload, Download, Loader2, History, Trash2 } from "lucide-react";
|
||||
import { ResizableSidebar } from "@/components/sidebar";
|
||||
import { PromptManagement } from "@/components/settings/prompt-management";
|
||||
import { ImportProvider } from "@/components/import-context";
|
||||
import { useSettingsStore, fontOptions, timezoneOptions } from "@/lib/settings-store";
|
||||
import { useConfirm } from "@/components/confirm-provider";
|
||||
import { cleanupAllPageHistories, estimateAllPageHistoriesUsage, trimAllPageHistoriesToRecent } from "@/lib/page-history";
|
||||
|
||||
export default function SettingsPage() {
|
||||
const confirm = useConfirm();
|
||||
@@ -21,6 +22,8 @@ export default function SettingsPage() {
|
||||
setTableLineHeight,
|
||||
timezone,
|
||||
setTimezone,
|
||||
localHistory,
|
||||
setLocalHistory,
|
||||
aiConfig,
|
||||
setAIConfig,
|
||||
} = useSettingsStore();
|
||||
@@ -30,8 +33,15 @@ export default function SettingsPage() {
|
||||
const [confirmPassword, setConfirmPassword] = useState("");
|
||||
const [isExporting, setIsExporting] = useState(false);
|
||||
const [isRestoring, setIsRestoring] = useState(false);
|
||||
const [historyMsg, setHistoryMsg] = useState<string | null>(null);
|
||||
const [trimRecentCount, setTrimRecentCount] = useState(10);
|
||||
const [historyStats, setHistoryStats] = useState({ keys: 0, snapshots: 0, bytes: 0 });
|
||||
const [msg, setMsg] = useState<{ type: "success" | "error"; text: string } | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setHistoryStats(estimateAllPageHistoriesUsage());
|
||||
}, []);
|
||||
|
||||
const handlePasswordChange = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setMsg(null);
|
||||
@@ -151,6 +161,85 @@ export default function SettingsPage() {
|
||||
</label>
|
||||
</section>
|
||||
|
||||
<section className="ui-card ui-enter-delayed space-y-5 p-4 md:p-6">
|
||||
<div className="flex items-center gap-2 border-b pb-2">
|
||||
<History size={18} className="text-primary" />
|
||||
<h2 className="text-lg font-semibold md:text-xl">本地历史策略</h2>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
控制浏览器本地历史快照占用空间。保存后会在后续写入时自动清理,也可立即手动清理一次。
|
||||
</p>
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
<label className="space-y-2 text-sm">
|
||||
<span className="font-medium">每篇最多保留: {localHistory.maxSnapshotsPerPage} 条</span>
|
||||
<input
|
||||
type="range"
|
||||
min="5"
|
||||
max="200"
|
||||
step="1"
|
||||
value={localHistory.maxSnapshotsPerPage}
|
||||
onChange={(e) =>
|
||||
setLocalHistory({ maxSnapshotsPerPage: parseInt(e.target.value, 10) })
|
||||
}
|
||||
className="w-full accent-primary"
|
||||
/>
|
||||
</label>
|
||||
<label className="space-y-2 text-sm">
|
||||
<span className="font-medium">保留时长: {localHistory.retentionDays} 天</span>
|
||||
<input
|
||||
type="range"
|
||||
min="1"
|
||||
max="365"
|
||||
step="1"
|
||||
value={localHistory.retentionDays}
|
||||
onChange={(e) => setLocalHistory({ retentionDays: parseInt(e.target.value, 10) })}
|
||||
className="w-full accent-primary"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div className="rounded-md border border-border/60 bg-muted/20 px-3 py-2 text-xs text-muted-foreground">
|
||||
<div>本地历史键: {historyStats.keys}</div>
|
||||
<div>快照总数: {historyStats.snapshots}</div>
|
||||
<div>估算占用: {(historyStats.bytes / 1024).toFixed(1)} KB</div>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-3">
|
||||
<button
|
||||
onClick={() => {
|
||||
const result = cleanupAllPageHistories();
|
||||
setHistoryStats(estimateAllPageHistoriesUsage());
|
||||
setHistoryMsg(`已清理本地历史键 ${result.touched} 项`);
|
||||
}}
|
||||
className="ui-btn-secondary"
|
||||
>
|
||||
<Trash2 size={14} />
|
||||
立即清理一次
|
||||
</button>
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
max={200}
|
||||
value={trimRecentCount}
|
||||
onChange={(e) => setTrimRecentCount(Math.max(1, Math.min(200, parseInt(e.target.value || "1", 10))))}
|
||||
className="ui-input h-9 w-24"
|
||||
/>
|
||||
<button
|
||||
onClick={() => {
|
||||
const result = trimAllPageHistoriesToRecent(trimRecentCount);
|
||||
setHistoryStats(estimateAllPageHistoriesUsage());
|
||||
setHistoryMsg(
|
||||
`已处理 ${result.touched} 项,删除快照 ${result.removedSnapshots} 条(每篇保留最近 ${trimRecentCount} 条)`
|
||||
);
|
||||
}}
|
||||
className="ui-btn-secondary"
|
||||
>
|
||||
仅保留最近 N 条
|
||||
</button>
|
||||
</div>
|
||||
{historyMsg && <span className="text-xs text-muted-foreground">{historyMsg}</span>}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="ui-card ui-enter-delayed space-y-5 p-4 md:p-6">
|
||||
<div className="flex items-center gap-2 border-b pb-2">
|
||||
<Sparkles size={18} className="text-primary" />
|
||||
|
||||
Reference in New Issue
Block a user