chore(client/print): load nota into forca

This commit is contained in:
Elian Doran 2025-10-18 21:01:31 +03:00
parent e83eacb18b
commit 54724b8c58
No known key found for this signature in database
9 changed files with 88 additions and 70 deletions

View File

@ -1 +1,19 @@
console.log("Print script is here."); import FNote from "./entities/fnote";
async function main() {
const noteId = window.location.pathname.split("/")[2];
const froca = (await import("./services/froca")).default;
const note = await froca.getNote(noteId);
if (!note) return;
if (note.type === "book") {
handleCollection(note);
}
}
function handleCollection(note: FNote) {
console.log("Rendering collection.");
}
main();

View File

@ -40,20 +40,23 @@ class FrocaImpl implements Froca {
constructor() { constructor() {
this.initializedPromise = this.loadInitialTree(); this.initializedPromise = this.loadInitialTree();
this.#clear();
} }
async loadInitialTree() { async loadInitialTree() {
const resp = await server.get<SubtreeResponse>("tree"); const resp = await server.get<SubtreeResponse>("tree");
// clear the cache only directly before adding new content which is important for e.g., switching to protected session // clear the cache only directly before adding new content which is important for e.g., switching to protected session
this.#clear();
this.addResp(resp);
}
#clear() {
this.notes = {}; this.notes = {};
this.branches = {}; this.branches = {};
this.attributes = {}; this.attributes = {};
this.attachments = {}; this.attachments = {};
this.blobPromises = {}; this.blobPromises = {};
this.addResp(resp);
} }
async loadSubTree(subTreeNoteId: string) { async loadSubTree(subTreeNoteId: string) {

View File

@ -70,26 +70,26 @@ async function setupProtectedSession(password: string) {
protectedSessionHolder.enableProtectedSession(); protectedSessionHolder.enableProtectedSession();
} }
ws.subscribeToMessages(async (message) => { // ws.subscribeToMessages(async (message) => {
if (message.type === "protectedSessionLogin") { // if (message.type === "protectedSessionLogin") {
await reloadData(); // await reloadData();
await appContext.triggerEvent("frocaReloaded", {}); // await appContext.triggerEvent("frocaReloaded", {});
appContext.triggerEvent("protectedSessionStarted", {}); // appContext.triggerEvent("protectedSessionStarted", {});
appContext.triggerCommand("closeProtectedSessionPasswordDialog"); // appContext.triggerCommand("closeProtectedSessionPasswordDialog");
if (protectedSessionDeferred !== null) { // if (protectedSessionDeferred !== null) {
protectedSessionDeferred.resolve(true); // protectedSessionDeferred.resolve(true);
protectedSessionDeferred = null; // protectedSessionDeferred = null;
} // }
toastService.showMessage(t("protected_session.started")); // toastService.showMessage(t("protected_session.started"));
} else if (message.type === "protectedSessionLogout") { // } else if (message.type === "protectedSessionLogout") {
utils.reloadFrontendApp(`Protected session logout`); // utils.reloadFrontendApp(`Protected session logout`);
} // }
}); // });
async function protectNote(noteId: string, protect: boolean, includingSubtree: boolean) { async function protectNote(noteId: string, protect: boolean, includingSubtree: boolean) {
await enterProtectedSession(); await enterProtectedSession();
@ -106,29 +106,29 @@ function makeToast(message: Message, title: string, text: string): ToastOptions
}; };
} }
ws.subscribeToMessages(async (message) => { // ws.subscribeToMessages(async (message) => {
if (!("taskType" in message) || message.taskType !== "protectNotes") { // if (!("taskType" in message) || message.taskType !== "protectNotes") {
return; // return;
} // }
const isProtecting = message.data?.protect; // const isProtecting = message.data?.protect;
const title = isProtecting ? t("protected_session.protecting-title") : t("protected_session.unprotecting-title"); // const title = isProtecting ? t("protected_session.protecting-title") : t("protected_session.unprotecting-title");
if (message.type === "taskError") { // if (message.type === "taskError") {
toastService.closePersistent(message.taskId); // toastService.closePersistent(message.taskId);
toastService.showError(message.message); // toastService.showError(message.message);
} else if (message.type === "taskProgressCount") { // } else if (message.type === "taskProgressCount") {
const count = message.progressCount; // const count = message.progressCount;
const text = isProtecting ? t("protected_session.protecting-in-progress", { count }) : t("protected_session.unprotecting-in-progress-count", { count }); // const text = isProtecting ? t("protected_session.protecting-in-progress", { count }) : t("protected_session.unprotecting-in-progress-count", { count });
toastService.showPersistent(makeToast(message, title, text)); // toastService.showPersistent(makeToast(message, title, text));
} else if (message.type === "taskSucceeded") { // } else if (message.type === "taskSucceeded") {
const text = isProtecting ? t("protected_session.protecting-finished-successfully") : t("protected_session.unprotecting-finished-successfully"); // const text = isProtecting ? t("protected_session.protecting-finished-successfully") : t("protected_session.unprotecting-finished-successfully");
const toast = makeToast(message, title, text); // const toast = makeToast(message, title, text);
toast.closeAfter = 3000; // toast.closeAfter = 3000;
toastService.showPersistent(toast); // toastService.showPersistent(toast);
} // }
}); // });
export default { export default {
protectNote, protectNote,

View File

@ -122,17 +122,17 @@ async function resolveNotePathToSegments(notePath: string, hoistedNoteId = "root
} }
} }
ws.subscribeToMessages((message) => { // ws.subscribeToMessages((message) => {
if (message.type === "openNote") { // if (message.type === "openNote") {
appContext.tabManager.activateOrOpenNote(message.noteId); // appContext.tabManager.activateOrOpenNote(message.noteId);
if (utils.isElectron()) { // if (utils.isElectron()) {
const currentWindow = utils.dynamicRequire("@electron/remote").getCurrentWindow(); // const currentWindow = utils.dynamicRequire("@electron/remote").getCurrentWindow();
currentWindow.show(); // currentWindow.show();
} // }
} // }
}); // });
function getParentProtectedStatus(node: Fancytree.FancytreeNode) { function getParentProtectedStatus(node: Fancytree.FancytreeNode) {
return hoistedNoteService.isHoistedNode(node) ? false : node.getParent().data.isProtected; return hoistedNoteService.isHoistedNode(node) ? false : node.getParent().data.isProtected;

View File

@ -3,7 +3,7 @@
window.glob = { window.glob = {
device: "<%= device %>", device: "<%= device %>",
baseApiUrl: 'api/', baseApiUrl: "<%= baseApiUrl %>",
activeDialog: null, activeDialog: null,
maxEntityChangeIdAtLoad: <%= maxEntityChangeIdAtLoad %>, maxEntityChangeIdAtLoad: <%= maxEntityChangeIdAtLoad %>,
maxEntityChangeSyncIdAtLoad: <%= maxEntityChangeSyncIdAtLoad %>, maxEntityChangeSyncIdAtLoad: <%= maxEntityChangeSyncIdAtLoad %>,

View File

@ -21,6 +21,8 @@
document.getElementsByTagName("body")[0].style.display = "none"; document.getElementsByTagName("body")[0].style.display = "none";
</script> </script>
<%- include("./partials/windowGlobal.ejs", locals) %>
<!-- Required for correct loading of scripts in Electron --> <!-- Required for correct loading of scripts in Electron -->
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script> <script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>

View File

@ -1,14 +0,0 @@
import { Request, Response } from "express";
import assetPath from "../../services/asset_path";
import app_path from "../../services/app_path";
import { getCurrentLocale } from "../../services/i18n";
export function getPrintablePage(req: Request, res: Response) {
const { noteId } = req.params;
res.render("print", {
assetPath: assetPath,
appPath: app_path,
currentLocale: getCurrentLocale()
});
}

View File

@ -16,9 +16,19 @@ import type { Request, Response } from "express";
import type BNote from "../becca/entities/bnote.js"; import type BNote from "../becca/entities/bnote.js";
import { getCurrentLocale } from "../services/i18n.js"; import { getCurrentLocale } from "../services/i18n.js";
type View = "desktop" | "mobile" | "print";
function index(req: Request, res: Response) { function index(req: Request, res: Response) {
const options = optionService.getOptionMap();
const view = getView(req); const view = getView(req);
renderView(req, res, view);
}
export function printIndex(req: Request, res: Response) {
renderView(req, res, "print");
}
function renderView(req: Request, res: Response, view: View) {
const options = optionService.getOptionMap();
//'overwrite' set to false (default) => the existing token will be re-used and validated //'overwrite' set to false (default) => the existing token will be re-used and validated
//'validateOnReuse' set to false => if validation fails, generate a new token instead of throwing an error //'validateOnReuse' set to false => if validation fails, generate a new token instead of throwing an error
@ -57,8 +67,9 @@ function index(req: Request, res: Response) {
isProtectedSessionAvailable: protectedSessionService.isProtectedSessionAvailable(), isProtectedSessionAvailable: protectedSessionService.isProtectedSessionAvailable(),
maxContentWidth: Math.max(640, parseInt(options.maxContentWidth)), maxContentWidth: Math.max(640, parseInt(options.maxContentWidth)),
triliumVersion: packageJson.version, triliumVersion: packageJson.version,
assetPath: assetPath, assetPath: view !== "print" ? assetPath : "../" + assetPath,
appPath: appPath, appPath: view !== "print" ? appPath : "../" + appPath,
baseApiUrl: view !== "print" ? 'api/' : "../api/",
currentLocale: getCurrentLocale() currentLocale: getCurrentLocale()
}); });
} }
@ -122,5 +133,6 @@ function getAppCssNoteIds() {
} }
export default { export default {
index index,
printIndex
}; };

View File

@ -72,7 +72,6 @@ import etapiBackupRoute from "../etapi/backup.js";
import etapiMetricsRoute from "../etapi/metrics.js"; import etapiMetricsRoute from "../etapi/metrics.js";
import apiDocsRoute from "./api_docs.js"; import apiDocsRoute from "./api_docs.js";
import { apiResultHandler, apiRoute, asyncApiRoute, asyncRoute, route, router, uploadMiddlewareWithErrorHandling } from "./route_api.js"; import { apiResultHandler, apiRoute, asyncApiRoute, asyncRoute, route, router, uploadMiddlewareWithErrorHandling } from "./route_api.js";
import { getPrintablePage } from "./api/print.js";
const GET = "get", const GET = "get",
PST = "post", PST = "post",
@ -82,6 +81,7 @@ const GET = "get",
function register(app: express.Application) { function register(app: express.Application) {
route(GET, "/", [auth.checkAuth, csrfMiddleware], indexRoute.index); route(GET, "/", [auth.checkAuth, csrfMiddleware], indexRoute.index);
route(GET, "/print/:noteId", [ auth.checkAuth ], indexRoute.printIndex);
route(GET, "/login", [auth.checkAppInitialized, auth.checkPasswordSet], loginRoute.loginPage); route(GET, "/login", [auth.checkAppInitialized, auth.checkPasswordSet], loginRoute.loginPage);
route(GET, "/set-password", [auth.checkAppInitialized, auth.checkPasswordNotSet], loginRoute.setPasswordPage); route(GET, "/set-password", [auth.checkAppInitialized, auth.checkPasswordNotSet], loginRoute.setPasswordPage);
@ -387,9 +387,6 @@ function register(app: express.Application) {
// API Documentation // API Documentation
apiDocsRoute(app); apiDocsRoute(app);
// Printing route
route(GET, "/print/:noteId", [ auth.checkAuth ], getPrintablePage);
app.use("", router); app.use("", router);
} }