Merge pull request #1196 from TriliumNext/feature/zen_mode

Zen Mode
This commit is contained in:
Elian Doran 2025-02-16 15:39:54 +02:00 committed by GitHub
commit a532ae6426
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 137 additions and 14 deletions

View File

@ -223,6 +223,8 @@ export type CommandMappings = {
// Geomap // Geomap
deleteFromMap: { noteId: string }, deleteFromMap: { noteId: string },
openGeoLocation: { noteId: string, event: JQuery.MouseDownEvent } openGeoLocation: { noteId: string, event: JQuery.MouseDownEvent }
toggleZenMode: CommandData;
}; };
type EventMappings = { type EventMappings = {
@ -325,6 +327,7 @@ type EventMappings = {
}; };
scrollToEnd: { ntxId: string }; scrollToEnd: { ntxId: string };
noteTypeMimeChanged: { noteId: string }; noteTypeMimeChanged: { noteId: string };
zenModeChanged: { isEnabled: boolean };
}; };
export type EventListener<T extends EventNames> = { export type EventListener<T extends EventNames> = {

View File

@ -178,6 +178,13 @@ export default class RootCommandExecutor extends Component {
for (const window of windows) window[action](); for (const window of windows) window[action]();
} }
toggleZenModeCommand() {
const $body = $("body");
$body.toggleClass("zen");
const isEnabled = $body.hasClass("zen");
appContext.triggerEvent("zenModeChanged", { isEnabled });
}
firstTabCommand() { firstTabCommand() {
this.#goToTab(1); this.#goToTab(1);
} }

View File

@ -87,6 +87,7 @@ import options from "../services/options.js";
import utils from "../services/utils.js"; import utils from "../services/utils.js";
import GeoMapButtons from "../widgets/floating_buttons/geo_map_button.js"; import GeoMapButtons from "../widgets/floating_buttons/geo_map_button.js";
import ContextualHelpButton from "../widgets/floating_buttons/help_button.js"; import ContextualHelpButton from "../widgets/floating_buttons/help_button.js";
import CloseZenButton from "../widgets/close_zen_button.js";
export default class DesktopLayout { export default class DesktopLayout {
constructor(customWidgets) { constructor(customWidgets) {
@ -262,7 +263,8 @@ export default class DesktopLayout {
.child(new DeleteNotesDialog()) .child(new DeleteNotesDialog())
.child(new InfoDialog()) .child(new InfoDialog())
.child(new ConfirmDialog()) .child(new ConfirmDialog())
.child(new PromptDialog()); .child(new PromptDialog())
.child(new CloseZenButton())
} }
#buildLauncherPane(isHorizontal) { #buildLauncherPane(isHorizontal) {

View File

@ -133,7 +133,12 @@ const TPL = `
${t("title_bar_buttons.window-on-top")} ${t("title_bar_buttons.window-on-top")}
</li> </li>
<div class="dropdown-divider zoom-container-separator"></div> <li class="dropdown-item" data-trigger-command="toggleZenMode">
<span class="bx bxs-yin-yang"></span>
${t("global_menu.toggle-zen-mode")}
</li>
<div class="dropdown-divider"></div>
<li class="dropdown-item switch-to-mobile-version-button" data-trigger-command="switchToMobileVersion"> <li class="dropdown-item switch-to-mobile-version-button" data-trigger-command="switchToMobileVersion">
<span class="bx bx-mobile"></span> <span class="bx bx-mobile"></span>
@ -251,6 +256,7 @@ export default class GlobalMenuWidget extends BasicWidget {
private $updateToLatestVersionButton!: JQuery<HTMLElement>; private $updateToLatestVersionButton!: JQuery<HTMLElement>;
private $zoomState!: JQuery<HTMLElement>; private $zoomState!: JQuery<HTMLElement>;
private $toggleZenMode!: JQuery<HTMLElement>;
constructor(isHorizontalLayout: boolean) { constructor(isHorizontalLayout: boolean) {
super(); super();
@ -355,17 +361,11 @@ export default class GlobalMenuWidget extends BasicWidget {
if (!utils.isElectron()) { if (!utils.isElectron()) {
this.$widget.find(".zoom-container").hide(); this.$widget.find(".zoom-container").hide();
this.$widget.find(".zoom-container-separator").hide();
} }
this.$zoomState = this.$widget.find(".zoom-state"); this.$zoomState = this.$widget.find(".zoom-state");
this.$widget.on("show.bs.dropdown", () => { this.$toggleZenMode = this.$widget.find('[data-trigger-command="toggleZenMode"');
this.updateZoomState(); this.$widget.on("show.bs.dropdown", () => this.#onShown());
if (this.tooltip) {
this.tooltip.hide();
this.tooltip.disable();
}
});
if (this.tooltip) { if (this.tooltip) {
this.$widget.on("hide.bs.dropdown", () => this.tooltip.enable()); this.$widget.on("hide.bs.dropdown", () => this.tooltip.enable());
} }
@ -381,6 +381,15 @@ export default class GlobalMenuWidget extends BasicWidget {
setInterval(() => this.updateVersionStatus(), 8 * 60 * 60 * 1000); setInterval(() => this.updateVersionStatus(), 8 * 60 * 60 * 1000);
} }
#onShown() {
this.$toggleZenMode.toggleClass("active", $("body").hasClass("zen"));
this.updateZoomState();
if (this.tooltip) {
this.tooltip.hide();
this.tooltip.disable();
}
}
updateZoomState() { updateZoomState() {
if (!utils.isElectron()) { if (!utils.isElectron()) {
return; return;

View File

@ -0,0 +1,46 @@
import BasicWidget from "./basic_widget.js";
const TPL = `\
<div class="close-zen-container">
<button class="button-widget bx icon-action bxs-yin-yang"
data-trigger-command="toggleZenMode" />
<style>
:root {
--zen-button-size: 32px;
}
.close-zen-container {
display: none;
width: var(--zen-button-size);
height: var(--zen-button-size);
}
body.zen .close-zen-container {
display: block;
position: fixed;
top: 2px;
right: 2px;
z-index: 9999;
-webkit-app-region: no-drag;
}
body.zen.electron:not(.platform-darwin):not(.native-titlebar) .close-zen-container {
left: calc(env(titlebar-area-width) - var(--zen-button-size) - 2px);
right: unset;
}
</style>
</div>
`;
export default class CloseZenButton extends BasicWidget {
doRender(): void {
this.$widget = $(TPL);
}
zenChangedEvent() {
this.toggleInt(true);
}
}

View File

@ -1644,3 +1644,44 @@ body.electron.platform-darwin:not(.native-titlebar) .tab-row-container {
box-shadow: 0px 10px 20px rgba(0, 0, 0, var(--dropdown-shadow-opacity)); box-shadow: 0px 10px 20px rgba(0, 0, 0, var(--dropdown-shadow-opacity));
border-radius: 4px; border-radius: 4px;
} }
body.zen {
--tab-bar-height: 0;
}
body.zen .gutter,
body.zen #launcher-container,
body.zen #launcher-pane,
body.zen #left-pane,
body.zen #right-pane,
body.zen .tab-row-container,
body.zen .tab-row-widget,
body.zen .ribbon-container,
body.zen .note-icon-widget,
body.zen .title-row .button-widget,
body.zen .floating-buttons {
display: none !important;
}
body.zen #launcher-pane {
position: absolute !important;
top: 0 !important;
right: 0 !important;
width: 64px !important;
height: 64px !important;
background: transparent !important;
border: 0 !important;
}
body.zen .title-row {
display: block !important;
height: unset !important;
-webkit-app-region: drag;
padding-left: env(titlebar-area-x);
}
body.zen .note-title-widget,
body.zen .note-title-widget input {
font-size: 1rem !important;
background: transparent !important;
}

View File

@ -1807,3 +1807,8 @@ div.bookmark-folder-widget .note-link .bx {
background: var(--hover-item-background-color); background: var(--hover-item-background-color);
color: var(--hover-item-text-color); color: var(--hover-item-text-color);
} }
body.background-effects.zen #root-widget {
--main-background-color: transparent;
--root-background: transparent;
}

View File

@ -642,7 +642,8 @@
"show_help": "Show Help", "show_help": "Show Help",
"about": "About TriliumNext Notes", "about": "About TriliumNext Notes",
"logout": "Logout", "logout": "Logout",
"show-cheatsheet": "Show Cheatsheet" "show-cheatsheet": "Show Cheatsheet",
"toggle-zen-mode": "Zen Mode"
}, },
"sync_status": { "sync_status": {
"unknown": "<p>Sync status will be known once the next sync attempt starts.</p><p>Click to trigger sync now.</p>", "unknown": "<p>Sync status will be known once the next sync attempt starts.</p><p>Click to trigger sync now.</p>",

View File

@ -592,7 +592,8 @@
"zoom": "Zoom", "zoom": "Zoom",
"zoom_in": "Mărește", "zoom_in": "Mărește",
"zoom_out": "Micșorează", "zoom_out": "Micșorează",
"show-cheatsheet": "Afișează ghidul rapid" "show-cheatsheet": "Afișează ghidul rapid",
"toggle-zen-mode": "Mod zen"
}, },
"heading_style": { "heading_style": {
"markdown": "Stil Markdown", "markdown": "Stil Markdown",

View File

@ -238,6 +238,12 @@ function getDefaultKeyboardActions() {
description: t("keyboard_actions.toggle-tray"), description: t("keyboard_actions.toggle-tray"),
scope: "window" scope: "window"
}, },
{
actionName: "toggleZenMode",
defaultShortcuts: ["Alt+Z"],
description: t("keyboard_actions.toggle-zen-mode"),
scope: "window"
},
{ {
actionName: "firstTab", actionName: "firstTab",
defaultShortcuts: ["CommandOrControl+1"], defaultShortcuts: ["CommandOrControl+1"],

View File

@ -35,6 +35,7 @@ const enum KeyboardActionNamesEnum {
activatePreviousTab, activatePreviousTab,
openNewWindow, openNewWindow,
toggleTray, toggleTray,
toggleZenMode,
firstTab, firstTab,
secondTab, secondTab,
thirdTab, thirdTab,

View File

@ -92,7 +92,8 @@
"toggle-book-properties": "Toggle Book Properties", "toggle-book-properties": "Toggle Book Properties",
"toggle-classic-editor-toolbar": "Toggle the Formatting tab for the editor with fixed toolbar", "toggle-classic-editor-toolbar": "Toggle the Formatting tab for the editor with fixed toolbar",
"export-as-pdf": "Exports the current note as a PDF", "export-as-pdf": "Exports the current note as a PDF",
"show-cheatsheet": "Shows a modal with common keyboard operations" "show-cheatsheet": "Shows a modal with common keyboard operations",
"toggle-zen-mode": "Enables/disables the zen mode (minimal UI for more focused editing)"
}, },
"login": { "login": {
"title": "Login", "title": "Login",