CI / lint (push) Successful in 1m3s
CI / security (push) Successful in 46s
CI / test (push) Successful in 2m43s
CI / build (push) Successful in 38s
CI / e2e (push) Successful in 11m12s
Desktop Build / build-windows (push) Canceled after 0s
Desktop Build / build-linux (push) Canceled after 0s
Barre d'outils Markdown flottante (gras/italique/code/liste/lien) sur la selection CodeMirror, bouton Coller persistant (contournement iOS), zoom par pincement + hauteur ajustable persistes, raccourcis swipe (gauche -> liens entrants, droite -> table des matieres), mode lecture plein ecran avec navigation entre fichiers du dossier. 22 tests JSDOM + spec E2E mobile. Docs: fiche feature, CHANGELOG, ROADMAP, guide i18n FR/EN, README.
138 lines
4.7 KiB
JavaScript
138 lines
4.7 KiB
JavaScript
/* ObsiGate — Module orchestrator (ES modules).
|
|
Replaces the monolithic frontend/app.js IIFE.
|
|
All code lives in frontend/js/*.js modules. */
|
|
|
|
import * as UI from './ui.js';
|
|
import * as Utils from './utils.js';
|
|
import { initI18n, t } from './i18n.js';
|
|
import { initAIFab } from './ai-fab.js';
|
|
|
|
// Wire up AI toolbar toast (avoids circular import in utils.js)
|
|
window._obsigateShowToast = UI.showToast;
|
|
import * as Sidebar from './sidebar.js';
|
|
import * as Auth from './auth.js';
|
|
import * as Viewer from './viewer.js';
|
|
import * as Sync from './sync.js';
|
|
import { initGraphView } from './graph.js';
|
|
import * as Legacy from './legacy.js';
|
|
import { initCommandPalette } from './palette.js';
|
|
import { initMobileToolbar } from './mobile-toolbar.js';
|
|
import { initMobileEditor } from './mobile-editor.js';
|
|
import { initDragDrop } from './dragdrop.js';
|
|
import { initMermaid, setupFocusMode } from './mermaid-viewer.js';
|
|
import PaneManager from './pane-manager.js';
|
|
import { initDesktopIntegration, isTauriEnv } from './desktop.js';
|
|
import { initPush } from './push.js';
|
|
import { initPlugins } from './plugins.js';
|
|
import { populateVersions } from './config.js';
|
|
|
|
// =========================================================================
|
|
// Initialization — mirrors the original app.js init() ordering
|
|
// =========================================================================
|
|
async function init() {
|
|
// 1. Init i18n FIRST — loads fallback (FR) + selected locale
|
|
// Server language check may fail (no auth yet), falls to localStorage
|
|
// LocalStorage has correct language if user set it previously
|
|
await initI18n();
|
|
|
|
// 1b. Desktop bridge — crash banner + OS theme sync (before theme engine).
|
|
// No-op on web (Docker); on desktop it also readies the vault picker.
|
|
await initDesktopIntegration();
|
|
|
|
// 2. Init auth — now t() works inside showApp()/renderUserMenu()
|
|
const authOk = await Auth.AuthManager.initAuth();
|
|
|
|
UI.initTheme();
|
|
UI.initHeaderMenu();
|
|
UI.initCustomDropdowns();
|
|
|
|
document.getElementById("theme-toggle").addEventListener("click", UI.toggleTheme);
|
|
document.getElementById("header-logo").addEventListener("click", Legacy.goHome);
|
|
const refreshBtn = document.getElementById("header-refresh-btn");
|
|
if (refreshBtn) refreshBtn.addEventListener("click", Legacy.goHome);
|
|
|
|
Legacy.initSearch();
|
|
UI.initSidebarToggle();
|
|
UI.initMobile();
|
|
Sidebar.initVaultContext();
|
|
Legacy.initSidebarTabs();
|
|
Legacy.initHelpModal();
|
|
Legacy.initConfigModal();
|
|
Legacy.initAboutModal();
|
|
Sidebar.initSidebarFilter();
|
|
UI.initSidebarResize();
|
|
Utils.initEditor();
|
|
Auth.initLoginForm();
|
|
Legacy.initRecentTab();
|
|
|
|
UI.RightSidebarManager.init();
|
|
UI.FindInPageManager.init();
|
|
UI.ContextMenuManager.init();
|
|
UI.TabManager.init();
|
|
PaneManager.init();
|
|
initCommandPalette();
|
|
initMobileToolbar();
|
|
initMobileEditor();
|
|
initPush();
|
|
initPlugins();
|
|
|
|
if (authOk) {
|
|
Legacy.initSyncStatus();
|
|
|
|
try {
|
|
await Promise.all([Legacy.loadVaultSettings(), Sidebar.loadVaults(), Sidebar.loadTags()]);
|
|
|
|
initDragDrop();
|
|
|
|
Legacy.DashboardRecentWidget.init();
|
|
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
if (urlParams.get("popup") === "true") {
|
|
document.body.classList.add("popup-mode");
|
|
}
|
|
|
|
if (window.location.hash && window.location.hash.startsWith("#file=")) {
|
|
const hashVal = window.location.hash.substring(6);
|
|
const sepIndex = hashVal.indexOf(":");
|
|
if (sepIndex > -1) {
|
|
const vault = decodeURIComponent(hashVal.substring(0, sepIndex));
|
|
const path = decodeURIComponent(hashVal.substring(sepIndex + 1));
|
|
Viewer.openFile(vault, path);
|
|
}
|
|
} else if (urlParams.get("popup") !== "true") {
|
|
Legacy.showWelcome();
|
|
}
|
|
} catch (err) {
|
|
console.error("Failed to initialize ObsiGate:", err);
|
|
UI.showToast(t("error.initialization"), "error");
|
|
}
|
|
}
|
|
|
|
initGraphView();
|
|
initMermaid();
|
|
setupFocusMode();
|
|
Utils.safeCreateIcons();
|
|
initAIFab();
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", async () => {
|
|
try {
|
|
await init();
|
|
Sync.init();
|
|
} finally {
|
|
// Signale au splash de démarrage (index.html #boot-splash) que l'app est
|
|
// initialisée : le splash est retiré et le squelette stylé révélé.
|
|
// Set AFTER init() resolves so every handler (search, tabs, …) is bound.
|
|
window.__OBSIGATE_BOOTED = true;
|
|
if (typeof window.__obsigateBootReady === "function") window.__obsigateBootReady();
|
|
}
|
|
// Show version in header — always visible, fallback before the async fetch
|
|
populateVersions();
|
|
fetch('/api/health')
|
|
.then(r => r.json())
|
|
.then(d => {
|
|
if (d && d.version) populateVersions(d.version);
|
|
})
|
|
.catch(() => {});
|
|
});
|