feat(web): add i18n, light/dark theme switching, and version constant

- Add i18n (English + 简体中文) with a locale store, $t() magic, and a language toggle (persisted)
- Add light/dark/system theme switching via a theme store and [data-theme] token overrides
- Set the theme before paint to avoid a flash of the wrong theme
- Add frontend version constant web/version.js (window.YDROPBX_VERSION) shown in the app footer
- Update AGENTS.md version-control convention to mention web/version.js
- Bump version to 0.1.1 across frontend, webui changelog, and backend constant
This commit is contained in:
2026-08-27 15:21:21 +08:00
parent d84e4dfdba
commit 5bb42a8b8a
14 changed files with 379 additions and 36 deletions
+7 -7
View File
@@ -24,12 +24,12 @@
this.files.inbox = inbox.files || [];
this.files.outbox = outbox.files || [];
} catch (e) {
this.showToast('Failed to load files');
this.showToast('toast.loadFailed');
}
},
showToast(message) {
this.toast.message = message;
this.toast.message = Alpine.store('locale').t(message);
this.toast.show = true;
if (this.toast._timer) clearTimeout(this.toast._timer);
this.toast._timer = setTimeout(() => {
@@ -45,7 +45,7 @@
form.append('dir', dir);
await fetch('/api/upload', { method: 'POST', body: form });
}
this.showToast('File uploaded');
this.showToast('toast.uploaded');
await this.loadFiles();
},
@@ -55,13 +55,13 @@
async deleteFile(id) {
const confirmed = await Alpine.store('confirm').show({
title: 'Delete file',
message: 'This file will be permanently removed. Continue?',
title: 'confirm.deleteTitle',
message: 'confirm.deleteMessage',
danger: true,
});
if (!confirmed) return;
await fetch('/api/files/' + id, { method: 'DELETE' });
this.showToast('File deleted');
this.showToast('toast.deleted');
await this.loadFiles();
},
@@ -70,7 +70,7 @@
const data = await res.json();
try {
await navigator.clipboard.writeText(data.url);
this.showToast('Share link copied to clipboard');
this.showToast('toast.shareCopied');
} catch (_) {
window.prompt('Share URL:', data.url);
}