Дезайн ыыыы
This commit is contained in:
parent
403d7086d4
commit
e7c02c7feb
174 changed files with 15802 additions and 9725 deletions
107
frontend/js/store.js
Normal file
107
frontend/js/store.js
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
// Single mutable state object + a plain pub/sub. No framework: components
|
||||
// mutate `state` directly (or via the small helpers below) and then call
|
||||
// notify() — every subscriber re-renders its own slice of the DOM from
|
||||
// scratch. That's cheap at file-manager list sizes and keeps the mental
|
||||
// model identical to the old egui immediate-mode AppState.
|
||||
export const state = {
|
||||
// Local pane
|
||||
local: {
|
||||
path: "",
|
||||
entries: [],
|
||||
selected: [], // names of selected entries, in no particular order
|
||||
selectAnchor: null, // name shift-click range selection extends from
|
||||
sort: { col: "name", dir: "asc" },
|
||||
},
|
||||
|
||||
// One entry per open remote connection tab.
|
||||
// { id, label, params, status, remotePath, remoteEntries, remoteSelected,
|
||||
// remoteSelectAnchor, loading, sort: { col, dir } }
|
||||
tabs: [],
|
||||
activeTabId: null, // null = Local pane currently displayed, otherwise the displayed remote tab's id
|
||||
// The remote connection toolbar actions (Upload, refresh, New Folder, ...)
|
||||
// target. Unlike activeTabId this is NOT cleared when the Local pane is
|
||||
// displayed -- switching to Local to pick a file to upload shouldn't lose
|
||||
// track of which server it's going to, mirroring the old egui AppState
|
||||
// where `active_tab` persisted across the Local dock tab gaining focus.
|
||||
lastRemoteTabId: null,
|
||||
activePane: "local", // 'local' | 'remote' — who last received a click (toolbar targets this)
|
||||
|
||||
// Split-pane layout. Each pane slot holds a tabId (null = Local, otherwise
|
||||
// a remote connection id). The user can rearrange panes by dragging tabs.
|
||||
layout: {
|
||||
dir: "row", // 'row' | 'column' — direction of the split
|
||||
panes: [
|
||||
{ id: "pane-0", tabId: null }, // null = Local
|
||||
],
|
||||
},
|
||||
|
||||
sidebar: {
|
||||
quickAccess: [
|
||||
{ name: "Home", path: "" },
|
||||
{ name: "Desktop", path: "" },
|
||||
{ name: "Documents", path: "" },
|
||||
{ name: "Downloads", path: "" },
|
||||
{ name: "Pictures", path: "" },
|
||||
{ name: "Music", path: "" },
|
||||
{ name: "Videos", path: "" },
|
||||
],
|
||||
bookmarks: [],
|
||||
},
|
||||
|
||||
history: [],
|
||||
sites: [],
|
||||
|
||||
queueTasks: [],
|
||||
showQueue: false,
|
||||
|
||||
statusMessage: "",
|
||||
|
||||
showConnectDialog: false,
|
||||
connectLoading: false,
|
||||
connectError: "",
|
||||
|
||||
showHistoryPopup: false,
|
||||
|
||||
opTarget: "local", // which side New Folder / Rename / Delete apply to
|
||||
dialog: null, // { kind: 'mkdir'|'rename'|'delete', ... }
|
||||
|
||||
showSettingsDialog: false,
|
||||
// Persisted (via get_pref/set_pref) + session-only (panel visibility)
|
||||
// preferences -- see js/components/settingsDialog.js.
|
||||
settings: {
|
||||
language: "en",
|
||||
theme: "ember",
|
||||
confirmBeforeDelete: true,
|
||||
defaultLocalFolder: "",
|
||||
autoClearCompletedSecs: 0,
|
||||
maxConcurrent: 2,
|
||||
showToolbar: true,
|
||||
showSidebar: true,
|
||||
showStatusBar: true,
|
||||
showQueuePanel: true,
|
||||
},
|
||||
};
|
||||
|
||||
const listeners = new Set();
|
||||
|
||||
export function notify() {
|
||||
listeners.forEach((fn) => fn(state));
|
||||
}
|
||||
|
||||
export function subscribe(fn) {
|
||||
listeners.add(fn);
|
||||
return () => listeners.delete(fn);
|
||||
}
|
||||
|
||||
export function activeTab() {
|
||||
return state.tabs.find((t) => t.id === state.lastRemoteTabId) ?? null;
|
||||
}
|
||||
|
||||
export function isWelcome() {
|
||||
return state.tabs.length === 0;
|
||||
}
|
||||
|
||||
export function setStatus(message) {
|
||||
state.statusMessage = message;
|
||||
notify();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue