import "@logseq/libs"; import { createExportPayload, downloadJson } from "./export"; import { TimerService } from "./timer-service"; import type { PageRef } from "./types"; import { TimetrackerUi } from "./ui"; declare const logseq: any; const service = new TimerService(); let isUiVisible = false; async function currentPage(): Promise { const page = await logseq.Editor.getCurrentPage(); if (!page) { return null; } return { uuid: page.uuid ?? null, name: page.name ?? page.originalName ?? "Untitled" }; } async function listPages(): Promise { try { const rows = await logseq.DB.datascriptQuery( `[:find ?name ?uuid :where [?p :block/name ?name] [?p :block/uuid ?uuid]]` ); if (!Array.isArray(rows)) { return []; } return rows .map((row: unknown) => { if (!Array.isArray(row) || row.length < 2) { return null; } const [name, uuid] = row; return { name: String(name), uuid: uuid ? String(uuid) : null }; }) .filter((page: PageRef | null): page is PageRef => Boolean(page)) .sort((a, b) => a.name.localeCompare(b.name)); } catch { return []; } } function openUi(): void { logseq.showMainUI({ autoFocus: false }); } function closeUi(): void { logseq.hideMainUI(); } function toggleUi(): void { if (isUiVisible) { closeUi(); return; } openUi(); } async function startCurrentPage(): Promise { const page = await currentPage(); if (!page) { logseq.App.showMsg("No current page found.", "warning"); return; } service.startForPage(page); logseq.App.showMsg(`Tracking started for ${page.name}.`, "success"); } async function switchCurrentPage(): Promise { const page = await currentPage(); if (!page) { logseq.App.showMsg("No current page found.", "warning"); return; } service.switchToPage(page); logseq.App.showMsg(`Tracking switched to ${page.name}.`, "success"); } function stopActive(): void { service.stopActive(); logseq.App.showMsg("Active tracking stopped.", "success"); } function exportJson(): void { const payload = createExportPayload(service.getState()); const content = JSON.stringify(payload, null, 2); downloadJson(`timetracker-export-${new Date().toISOString().slice(0, 10)}.json`, content); logseq.App.showMsg("JSON export downloaded.", "success"); } async function main(): Promise { const ui = new TimetrackerUi(service, currentPage, listPages); logseq.setMainUIInlineStyle({ zIndex: 11, width: "100vw", height: "100vh", left: "0", top: "0", backgroundColor: "transparent", overflow: "hidden" }); ui.init(); logseq.App.registerCommandPalette( { key: "page-timetracker-start-current-page", label: "Page Timetracker: Start tracking current page" }, startCurrentPage ); logseq.App.registerCommandPalette( { key: "page-timetracker-stop-active", label: "Page Timetracker: Stop active tracking" }, stopActive ); logseq.App.registerCommandPalette( { key: "page-timetracker-switch-current-page", label: "Page Timetracker: Switch tracking to current page" }, switchCurrentPage ); logseq.App.registerCommandPalette( { key: "page-timetracker-open-ui", label: "Page Timetracker: Open timetracker UI" }, openUi ); logseq.App.registerCommandPalette( { key: "page-timetracker-close-ui", label: "Page Timetracker: Close timetracker UI" }, closeUi ); logseq.App.registerCommandPalette( { key: "page-timetracker-export-json", label: "Page Timetracker: Export entries JSON" }, exportJson ); logseq.Editor.registerSlashCommand("Timetracker: Start current page", startCurrentPage); logseq.Editor.registerSlashCommand("Timetracker: Stop active", stopActive); logseq.Editor.registerSlashCommand("Timetracker: Switch to current page", switchCurrentPage); logseq.App.registerPageMenuItem("Track this page", startCurrentPage); logseq.App.registerUIItem("toolbar", { key: "page-timetracker-toolbar", template: `TT` }); logseq.provideModel({ pageTimetrackerOpen: openUi, pageTimetrackerClose: closeUi, pageTimetrackerToggle: toggleUi }); logseq.on("ui:visible:changed", ({ visible }: { visible: boolean }) => { isUiVisible = visible; if (visible) { ui.render(); } }); logseq.beforeunload(() => { service.persist(); ui.destroy(); }); logseq.App.showMsg("Page Timetracker loaded.", "success"); } logseq.ready(main).catch((error: unknown) => { console.error("Page Timetracker failed to load", error); });