- 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
45 lines
1.2 KiB
JavaScript
45 lines
1.2 KiB
JavaScript
/**
|
|
* fileSection component.
|
|
*
|
|
* A single reusable component parametrized by `dir` and `canShare`. Both the
|
|
* Inbox and Outbox on the page are the same component instance with different
|
|
* props, replacing the previously copy-pasted <section> blocks.
|
|
*
|
|
* Usage:
|
|
* <section x-data="fileSection('inbox', { canShare: true })"> ... </section>
|
|
*/
|
|
(function () {
|
|
function register() {
|
|
Alpine.data('fileSection', (dir, opts = {}) => ({
|
|
dir,
|
|
canShare: opts.canShare ?? false,
|
|
dragover: false,
|
|
|
|
get files() {
|
|
return Alpine.store('files').files[dir];
|
|
},
|
|
get count() {
|
|
return this.files.length;
|
|
},
|
|
get title() {
|
|
return Alpine.store('locale').t(dir === 'inbox' ? 'inbox' : 'outbox');
|
|
},
|
|
get icon() {
|
|
return dir === 'inbox' ? window.Icons.inbox : window.Icons.outbox;
|
|
},
|
|
|
|
async onSelect(e) {
|
|
await Alpine.store('files').upload(this.dir, e.target.files);
|
|
e.target.value = '';
|
|
},
|
|
|
|
async onDrop(e) {
|
|
await Alpine.store('files').upload(this.dir, e.dataTransfer.files);
|
|
},
|
|
}));
|
|
}
|
|
|
|
if (window.Alpine) register();
|
|
else document.addEventListener('alpine:init', register);
|
|
})();
|