diff --git a/src/apps/webapp/.gitignore b/src/apps/webapp/.gitignore index 7ac8ea1..9fbfdf2 100644 --- a/src/apps/webapp/.gitignore +++ b/src/apps/webapp/.gitignore @@ -2,3 +2,4 @@ node_modules dist .DS_Store *.log +.nyc_output \ No newline at end of file diff --git a/src/apps/webapp/main.ts b/src/apps/webapp/main.ts index 3cd4adf..67db1bd 100644 --- a/src/apps/webapp/main.ts +++ b/src/apps/webapp/main.ts @@ -13,11 +13,11 @@ import type { InjectableSettingService } from "@lib/services/implements/injectab import { useOfflineScanner } from "@lib/serviceFeatures/offlineScanner"; import { useRedFlagFeatures } from "@/serviceFeatures/redFlag"; import { useCheckRemoteSize } from "@lib/serviceFeatures/checkRemoteSize"; -import { useSetupQRCodeFeature } from "@lib/serviceFeatures/setupObsidian/qrCode"; import { useSetupURIFeature } from "@lib/serviceFeatures/setupObsidian/setupUri"; import { SetupManager } from "@/modules/features/SetupManager"; -// import { ModuleObsidianSettingsAsMarkdown } from "@/modules/features/ModuleObsidianSettingAsMarkdown"; -// import { ModuleObsidianMenu } from "@/modules/essentialObsidian/ModuleObsidianMenu"; +import { useSetupManagerHandlersFeature } from "@/serviceFeatures/setupObsidian/setupManagerHandlers"; +import { useP2PReplicatorCommands } from "@/lib/src/replication/trystero/useP2PReplicatorCommands"; +import { useP2PReplicatorFeature } from "@/lib/src/replication/trystero/useP2PReplicatorFeature"; const SETTINGS_DIR = ".livesync"; const SETTINGS_FILE = "settings.json"; @@ -96,6 +96,16 @@ class LiveSyncWebApp { return DEFAULT_SETTINGS as ObsidianLiveSyncSettings; }); + // App lifecycle handlers + this.serviceHub.appLifecycle.scheduleRestart.setHandler(async () => { + console.log("[AppLifecycle] Restart requested"); + await this.shutdown(); + await this.initialize(); + setTimeout(() => { + window.location.reload(); + }, 1000); + }); + // Create LiveSync core this.core = new LiveSyncBaseCore( this.serviceHub, @@ -114,15 +124,18 @@ class LiveSyncWebApp { // new ModuleDev(this, core), // new ModuleReplicateTest(this, core), // new ModuleIntegratedTest(this, core), - // new SetupManager(core), - new SetupManager(core), // this should be moved to core? + // new ModuleReplicatorP2P(core), // Register P2P replicator for CLI (useP2PReplicator is not used here) + new SetupManager(core), ], () => [], // No add-ons (core) => { useOfflineScanner(core); useRedFlagFeatures(core); useCheckRemoteSize(core); - useSetupQRCodeFeature(core); + const replicator = useP2PReplicatorFeature(core); + useP2PReplicatorCommands(core, replicator); + const setupManager = core.getModule(SetupManager); + useSetupManagerHandlersFeature(core, setupManager); useSetupURIFeature(core); } ); diff --git a/src/apps/webapp/vite.config.ts b/src/apps/webapp/vite.config.ts index 48daae6..f58d3db 100644 --- a/src/apps/webapp/vite.config.ts +++ b/src/apps/webapp/vite.config.ts @@ -1,16 +1,45 @@ import { defineConfig } from "vite"; import { svelte } from "@sveltejs/vite-plugin-svelte"; +import istanbul from "vite-plugin-istanbul"; import path from "node:path"; import { readFileSync } from "node:fs"; const packageJson = JSON.parse(readFileSync("../../../package.json", "utf-8")); const manifestJson = JSON.parse(readFileSync("../../../manifest.json", "utf-8")); +const enableCoverage = process.env.PW_COVERAGE === "1"; +const repoRoot = path.resolve(__dirname, "../../.."); // https://vite.dev/config/ export default defineConfig({ - plugins: [svelte()], + plugins: [ + svelte(), + ...(enableCoverage + ? [ + istanbul({ + cwd: repoRoot, + include: ["src/**/*.ts", "src/**/*.svelte"], + exclude: [ + "node_modules", + "dist", + "test", + "coverage", + "src/apps/webapp/test/**", + "playwright.config.ts", + "vite.config.ts", + "**/*.spec.ts", + "**/*.test.ts", + ], + extension: [".js", ".ts", ".svelte"], + requireEnv: false, + cypress: false, + checkProd: false, + }), + ] + : []), + ], resolve: { alias: { "@": path.resolve(__dirname, "../../"), "@lib": path.resolve(__dirname, "../../lib/src"), + obsidian: path.resolve(__dirname, "../../../test/harness/obsidian-mock.ts"), }, }, base: "./", @@ -18,9 +47,12 @@ export default defineConfig({ outDir: "dist", emptyOutDir: true, rollupOptions: { + // test.html is used by the Playwright dev-server; include it here + // so the production build doesn't emit warnings about unused inputs. input: { index: path.resolve(__dirname, "index.html"), webapp: path.resolve(__dirname, "webapp.html"), + test: path.resolve(__dirname, "test.html"), }, external: ["crypto"], }, @@ -28,6 +60,8 @@ export default defineConfig({ define: { MANIFEST_VERSION: JSON.stringify(process.env.MANIFEST_VERSION || manifestJson.version || "0.0.0"), PACKAGE_VERSION: JSON.stringify(process.env.PACKAGE_VERSION || packageJson.version || "0.0.0"), + global: "globalThis", + hostPlatform: JSON.stringify(process.platform || "linux"), }, server: { port: 3000, diff --git a/src/apps/webapp/webapp.css b/src/apps/webapp/webapp.css index 69bedda..1867363 100644 --- a/src/apps/webapp/webapp.css +++ b/src/apps/webapp/webapp.css @@ -4,6 +4,18 @@ box-sizing: border-box; } +:root { + --background-primary: #ffffff; + --background-primary-alt: #667eea; + --background-secondary: #f0f0f0; + --background-secondary-alt: #e0e0e0; + --background-modifier-border: #d0d0d0; + --text-normal: #333333; + --text-warning: #d9534f; + --text-accent: #5bc0de; + --text-on-accent: #ffffff; +} + body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); @@ -134,6 +146,7 @@ button { button:hover { background: #1e4ad6; + opacity: 0.7; } button:disabled { @@ -367,3 +380,23 @@ body.livesync-log-visible { bottom: 12px; } } + +popup { + position: fixed; + min-width: 80vw; + max-width: 90vw; + min-height: 40vh; + max-height: 80vh; + background: rgba(255, 255, 255, 0.8); + padding: 1em; + border-radius: 6px; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2); + z-index: 10000; + overflow-y: auto; + display: flex; + align-items: center; + justify-content: center; + backdrop-filter: blur(15px); + border-radius: 10px; + z-index: 10; +} \ No newline at end of file diff --git a/src/apps/webapp/webapp.html b/src/apps/webapp/webapp.html index 7512066..72ba158 100644 --- a/src/apps/webapp/webapp.html +++ b/src/apps/webapp/webapp.html @@ -8,7 +8,7 @@
-

Self-hosted LiveSync

+

Self-hosted LiveSync on Web

Browser-based Self-hosted LiveSync using FileSystem API

Initialising...
@@ -27,8 +27,8 @@