diff --git a/apps/client/src/components/entrypoints.ts b/apps/client/src/components/entrypoints.ts
index d1cc78515..2e55a9b9d 100644
--- a/apps/client/src/components/entrypoints.ts
+++ b/apps/client/src/components/entrypoints.ts
@@ -106,7 +106,9 @@ export default class Entrypoints extends Component {
if (win.isFullScreenable()) {
win.setFullScreen(!win.isFullScreen());
}
- } // outside of electron this is handled by the browser
+ } else {
+ document.documentElement.requestFullscreen();
+ }
}
reloadFrontendAppCommand() {
diff --git a/apps/client/src/services/attribute_renderer.ts b/apps/client/src/services/attribute_renderer.ts
index bbe278056..9432eebc6 100644
--- a/apps/client/src/services/attribute_renderer.ts
+++ b/apps/client/src/services/attribute_renderer.ts
@@ -79,7 +79,19 @@ async function renderAttributes(attributes: FAttribute[], renderIsInheritable: b
return $container;
}
-const HIDDEN_ATTRIBUTES = ["originalFileName", "fileSize", "template", "inherit", "cssClass", "iconClass", "pageSize", "viewType", "geolocation", "docName"];
+const HIDDEN_ATTRIBUTES = [
+ "originalFileName",
+ "fileSize",
+ "template",
+ "inherit",
+ "cssClass",
+ "iconClass",
+ "pageSize",
+ "viewType",
+ "geolocation",
+ "docName",
+ "webViewSrc"
+];
async function renderNormalAttributes(note: FNote) {
const promotedDefinitionAttributes = note.getPromotedDefinitionAttributes();
diff --git a/apps/client/src/services/command_registry.ts b/apps/client/src/services/command_registry.ts
index a6c1000b7..f0bb2eef5 100644
--- a/apps/client/src/services/command_registry.ts
+++ b/apps/client/src/services/command_registry.ts
@@ -1,7 +1,8 @@
+import { ActionKeyboardShortcut } from "@triliumnext/commons";
import appContext, { type CommandNames } from "../components/app_context.js";
import type NoteTreeWidget from "../widgets/note_tree.js";
import { t, translationsInitializedPromise } from "./i18n.js";
-import keyboardActions, { Action } from "./keyboard_actions.js";
+import keyboardActions from "./keyboard_actions.js";
import utils from "./utils.js";
export interface CommandDefinition {
@@ -15,7 +16,7 @@ export interface CommandDefinition {
aliases?: string[];
source?: "manual" | "keyboard-action";
/** Reference to the original keyboard action for scope checking. */
- keyboardAction?: Action;
+ keyboardAction?: ActionKeyboardShortcut;
}
class CommandRegistry {
@@ -105,7 +106,7 @@ class CommandRegistry {
}
}
- private registerKeyboardActions(actions: Action[]) {
+ private registerKeyboardActions(actions: ActionKeyboardShortcut[]) {
for (const action of actions) {
// Skip actions that we've already manually registered
if (this.commands.has(action.actionName)) {
@@ -122,6 +123,11 @@ class CommandRegistry {
continue;
}
+ // Skip actions that should not appear in the command palette
+ if (action.ignoreFromCommandPalette) {
+ continue;
+ }
+
// Get the primary shortcut (first one in the list)
const primaryShortcut = action.effectiveShortcuts?.[0];
@@ -238,15 +244,21 @@ class CommandRegistry {
if (command.keyboardAction && command.commandName) {
if (command.keyboardAction.scope === "note-tree") {
this.executeWithNoteTreeFocus(command.commandName);
+ } else if (command.keyboardAction.scope === "text-detail") {
+ this.executeWithTextDetail(command.commandName);
} else {
- appContext.triggerCommand(command.commandName);
+ appContext.triggerCommand(command.commandName, {
+ ntxId: appContext.tabManager.activeNtxId
+ });
}
return;
}
// Fallback for commands without keyboard action reference
if (command.commandName) {
- appContext.triggerCommand(command.commandName);
+ appContext.triggerCommand(command.commandName, {
+ ntxId: appContext.tabManager.activeNtxId
+ });
return;
}
@@ -260,7 +272,22 @@ class CommandRegistry {
}
const treeComponent = appContext.getComponentByEl(tree) as NoteTreeWidget;
- treeComponent.triggerCommand(actionName, { ntxId: appContext.tabManager.activeNtxId });
+ const activeNode = treeComponent.getActiveNode();
+ treeComponent.triggerCommand(actionName, {
+ ntxId: appContext.tabManager.activeNtxId,
+ node: activeNode
+ });
+ }
+
+ private async executeWithTextDetail(actionName: CommandNames) {
+ const typeWidget = await appContext.tabManager.getActiveContext()?.getTypeWidget();
+ if (!typeWidget) {
+ return;
+ }
+
+ typeWidget.triggerCommand(actionName, {
+ ntxId: appContext.tabManager.activeNtxId
+ });
}
}
diff --git a/apps/client/src/services/content_renderer.ts b/apps/client/src/services/content_renderer.ts
index 40480e073..4f6d12c34 100644
--- a/apps/client/src/services/content_renderer.ts
+++ b/apps/client/src/services/content_renderer.ts
@@ -65,6 +65,9 @@ async function getRenderedContent(this: {} | { ctx: string }, entity: FNote | FA
$renderedContent.append($("
").append("
This note is protected and to access it you need to enter password.
").append("
").append($button));
} else if (entity instanceof FNote) {
+ $renderedContent
+ .css("display", "flex")
+ .css("flex-direction", "column");
$renderedContent.append(
$("
")
.css("display", "flex")
@@ -72,8 +75,33 @@ async function getRenderedContent(this: {} | { ctx: string }, entity: FNote | FA
.css("align-items", "center")
.css("height", "100%")
.css("font-size", "500%")
+ .css("flex-grow", "1")
.append($("
").addClass(entity.getIcon()))
);
+
+ if (entity.type === "webView" && entity.hasLabel("webViewSrc")) {
+ const $footer = $("