Compare commits

...
1 Commits
Author SHA1 Message Date
Xianren Studio bd3f648ccd feat: configurable upload size limit (default 10MB) 2026-08-13 23:55:25 +08:00
3 changed files with 20 additions and 8 deletions
+1
View File
@@ -65,6 +65,7 @@ impl CoreApp {
("api_port", "1234".to_string()),
("api_key", String::new()),
("api_enabled", "false".to_string()),
("upload_max_mb", "10".to_string()),
];
for (key, value) in defaults {
let _ = settings::set(&db, key, &value);
+14 -8
View File
@@ -50,9 +50,6 @@ const TEXT_EXTENSIONS = new Set([
"yml", "toml", "ini", "sh", "ps1", "bat", "sql", "env", "gitignore",
]);
const MAX_IMAGE_SIZE = 3 * 1024 * 1024;
const MAX_TEXT_SIZE = 100 * 1024;
export default function ChatPage() {
const models = useStore((s) => s.models);
const conversations = useStore((s) => s.conversations);
@@ -75,6 +72,7 @@ export default function ChatPage() {
const [editingDraft, setEditingDraft] = useState("");
const [versionsFor, setVersionsFor] = useState<Record<string, MessageVersion[]>>({});
const [attachments, setAttachments] = useState<Attachment[]>([]);
const [uploadLimitMb, setUploadLimitMb] = useState(10);
const bottomRef = useRef<HTMLDivElement>(null);
const fileInputRef = useRef<HTMLInputElement>(null);
@@ -104,6 +102,13 @@ export default function ChatPage() {
}
}, [models, selectedModelId]);
useEffect(() => {
api.settingsGet().then((s) => {
const v = Number(s.upload_max_mb);
if (v > 0) setUploadLimitMb(v);
});
}, []);
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
}, [messages]);
@@ -302,11 +307,12 @@ export default function ChatPage() {
}
async function handleFiles(files: FileList | File[]) {
const maxBytes = uploadLimitMb * 1024 * 1024;
for (const file of Array.from(files)) {
const ext = file.name.split(".").pop()?.toLowerCase() ?? "";
if (file.type.startsWith("image/") || ["png", "jpg", "jpeg", "webp", "gif", "bmp"].includes(ext)) {
if (file.size > MAX_IMAGE_SIZE) {
setError(`图片 ${file.name} 超过 3MB,已跳过`);
if (file.size > maxBytes) {
setError(`图片 ${file.name} 超过上限 ${uploadLimitMb}MB,已跳过`);
continue;
}
const dataUrl = await readAsDataUrl(file);
@@ -315,8 +321,8 @@ export default function ChatPage() {
{ id: crypto.randomUUID(), kind: "image", name: file.name, size: file.size, dataUrl },
]);
} else if (file.type.startsWith("text/") || TEXT_EXTENSIONS.has(ext)) {
if (file.size > MAX_TEXT_SIZE) {
setError(`文件 ${file.name} 超过 100KB,已跳过`);
if (file.size > maxBytes) {
setError(`文件 ${file.name} 超过上限 ${uploadLimitMb}MB,已跳过`);
continue;
}
const text = await file.text();
@@ -468,7 +474,7 @@ export default function ChatPage() {
<button
className="mb-1 flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border border-border bg-panel-2 text-slate-400 hover:bg-panel-2/60 hover:text-slate-200"
onClick={() => fileInputRef.current?.click()}
title="上传图片或文本文件"
title={`上传图片或文本文件(上限 ${uploadLimitMb}MB`}
>
<Icon name="paperclip" className="h-4 w-4" />
</button>
+5
View File
@@ -77,6 +77,11 @@ export default function SettingsPage() {
value={settings.backend ?? ""}
onSave={(v) => handleSave("backend", v)}
/>
<SettingInput
label="上传图片/文件大小上限(MB"
value={settings.upload_max_mb ?? "10"}
onSave={(v) => handleSave("upload_max_mb", v)}
/>
</div>
</div>