import { state, subscribe, notify, isWelcome } from "./store.js";
import * as ipc from "./ipc.js";
import { initLocal } from "./fsActions.js";
import { loadSettings } from "./settingsActions.js";
import { initPlatform } from "./platform.js";
import { initShortcuts } from "./shortcuts.js";
import { renderWelcome, updateWelcome } from "./components/welcome.js";
import { renderToolbar, updateToolbarIfNeeded } from "./components/toolbar.js";
import { renderSidebar, updateSidebarIfNeeded } from "./components/sidebar.js";
import { renderTabBar } from "./components/tabs.js";
import { renderPanes, updatePanes } from "./components/paneLayout.js";
import { renderQueuePanel, updateQueuePanelIfNeeded } from "./components/queuePanel.js";
import { renderStatusBar, updateStatusBarIfNeeded } from "./components/statusBar.js";
import { renderConnectDialog } from "./components/connectDialog.js";
import { renderHistoryPopup } from "./components/historyPopup.js";
import { renderOpDialogs, closeDialog } from "./components/opDialogs.js";
import { renderSettingsDialog } from "./components/settingsDialog.js";
import { renderSiteManager } from "./components/siteManager.js";
const root = document.getElementById("screen-root");
let currentScreen = null; // 'welcome' | 'main'
let currentLocale = "en";
let welcomeEl = null;
let mainShell = null; // { el, refs }
function buildWelcomeScreen() {
const el = document.createElement("div");
el.className = "screen";
root.appendChild(el);
renderWelcome(el);
return el;
}
function buildMainScreen() {
const el = document.createElement("div");
el.className = "screen app-shell";
el.innerHTML = `
`;
root.appendChild(el);
const refs = {
toolbar: el.querySelector('[data-role="toolbar"]'),
sidebar: el.querySelector('[data-role="sidebar"]'),
tabbar: el.querySelector('[data-role="tabbar"]'),
panes: el.querySelector('[data-role="panes"]'),
queue: el.querySelector('[data-role="queue"]'),
statusbar: el.querySelector('[data-role="statusbar"]'),
};
renderToolbar(refs.toolbar);
renderSidebar(refs.sidebar);
renderTabBar(refs.tabbar);
renderPanes(refs.panes);
renderQueuePanel(refs.queue);
renderStatusBar(refs.statusbar);
return { el, refs };
}
function render() {
const welcome = isWelcome();
const wantScreen = welcome ? "welcome" : "main";
const localeChanged = state.settings.language !== currentLocale;
if (wantScreen !== currentScreen || localeChanged) {
if (welcomeEl) {
welcomeEl.remove();
welcomeEl = null;
}
if (mainShell) {
mainShell.el.remove();
mainShell = null;
}
if (welcome) welcomeEl = buildWelcomeScreen();
else {
mainShell = buildMainScreen();
const { refs } = mainShell;
applyPanelVisibility(refs);
}
currentScreen = wantScreen;
currentLocale = state.settings.language;
} else if (welcome) {
updateWelcome(welcomeEl);
} else {
const { refs } = mainShell;
updateToolbarIfNeeded(refs.toolbar);
updateSidebarIfNeeded(refs.sidebar);
renderTabBar(refs.tabbar);
updatePanes(refs.panes);
updateQueuePanelIfNeeded(refs.queue);
updateStatusBarIfNeeded(refs.statusbar);
applyPanelVisibility(refs);
}
renderConnectDialog();
renderHistoryPopup();
renderOpDialogs();
renderSettingsDialog();
renderSiteManager();
}
// Settings → Appearance toggles — animated via CSS transitions.
function applyPanelVisibility(refs) {
refs.toolbar.classList.toggle("hidden", !state.settings.showToolbar);
refs.sidebar.classList.toggle("hidden", !state.settings.showSidebar);
refs.statusbar.classList.toggle("hidden", !state.settings.showStatusBar);
refs.queue.classList.toggle("hidden", !state.settings.showQueuePanel);
// Round main-content corners when adjacent panels are hidden
const mc = refs.panes.closest(".main-content");
if (mc) {
mc.classList.toggle("no-sidebar", !state.settings.showSidebar);
mc.classList.toggle("no-toolbar", !state.settings.showToolbar);
mc.classList.toggle("no-status", !state.settings.showStatusBar && !state.settings.showQueuePanel);
}
}
subscribe(render);
// Esc closes the topmost open overlay: op dialog > connect dialog > settings > history popover.
window.addEventListener("keydown", (e) => {
if (e.key !== "Escape") return;
if (state.dialog) {
closeDialog();
} else if (state.showSiteManager) {
state.showSiteManager = false;
notify();
} else if (state.showConnectDialog && !state.connectLoading) {
state.showConnectDialog = false;
notify();
} else if (state.showSettingsDialog) {
state.showSettingsDialog = false;
notify();
} else if (state.showHistoryPopup) {
state.showHistoryPopup = false;
notify();
}
});
async function boot() {
initPlatform(); // stamps data-platform/-desktop on ; async part fills in later
initShortcuts();
render(); // paint the welcome screen immediately, don't wait on any IPC
const [history, tasks, sites] = await Promise.allSettled([
ipc.listHistory(),
ipc.listTasks(),
ipc.listSites(),
]);
if (history.status === "fulfilled") state.history = history.value;
if (tasks.status === "fulfilled") state.queueTasks = tasks.value;
if (sites.status === "fulfilled") state.sites = sites.value;
notify();
await loadSettings();
notify();
await initLocal();
ipc.onTransferProgress(({ id, transferredBytes, speed, etaSecs }) => {
const task = state.queueTasks.find((tk) => tk.id === id);
if (task) {
task.transferredBytes = transferredBytes;
task.speed = speed;
task.etaSecs = etaSecs;
notify();
}
});
ipc.onTransferStateChanged(({ id, state: newState }) => {
const task = state.queueTasks.find((tk) => tk.id === id);
if (task) {
task.state = newState;
notify();
}
});
}
boot();