mirror of
https://github.com/zadam/trilium.git
synced 2025-11-10 00:19:04 +01:00
UI improvements (#7655)
Some checks are pending
Checks / main (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Dev / Test development (push) Waiting to run
Dev / Build Docker image (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile) (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile.alpine) (push) Blocked by required conditions
/ Check Docker build (Dockerfile) (push) Waiting to run
/ Check Docker build (Dockerfile.alpine) (push) Waiting to run
/ Build Docker images (Dockerfile, ubuntu-24.04-arm, linux/arm64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.alpine, ubuntu-latest, linux/amd64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v7) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v8) (push) Blocked by required conditions
/ Merge manifest lists (push) Blocked by required conditions
playwright / main (push) Waiting to run
Some checks are pending
Checks / main (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Dev / Test development (push) Waiting to run
Dev / Build Docker image (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile) (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile.alpine) (push) Blocked by required conditions
/ Check Docker build (Dockerfile) (push) Waiting to run
/ Check Docker build (Dockerfile.alpine) (push) Waiting to run
/ Build Docker images (Dockerfile, ubuntu-24.04-arm, linux/arm64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.alpine, ubuntu-latest, linux/amd64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v7) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v8) (push) Blocked by required conditions
/ Merge manifest lists (push) Blocked by required conditions
playwright / main (push) Waiting to run
This commit is contained in:
commit
78e2814068
@ -499,6 +499,10 @@ type EventMappings = {
|
|||||||
noteIds: string[];
|
noteIds: string[];
|
||||||
};
|
};
|
||||||
refreshData: { ntxId: string | null | undefined };
|
refreshData: { ntxId: string | null | undefined };
|
||||||
|
contentSafeMarginChanged: {
|
||||||
|
top: number;
|
||||||
|
noteContext: NoteContext;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EventListener<T extends EventNames> = {
|
export type EventListener<T extends EventNames> = {
|
||||||
|
|||||||
@ -1,47 +1,49 @@
|
|||||||
import FlexContainer from "../widgets/containers/flex_container.js";
|
|
||||||
import TabRowWidget from "../widgets/tab_row.js";
|
|
||||||
import LeftPaneContainer from "../widgets/containers/left_pane_container.js";
|
|
||||||
import NoteTreeWidget from "../widgets/note_tree.js";
|
|
||||||
import NoteTitleWidget from "../widgets/note_title.jsx";
|
|
||||||
import NoteDetailWidget from "../widgets/note_detail.js";
|
|
||||||
import PromotedAttributesWidget from "../widgets/promoted_attributes.js";
|
|
||||||
import NoteIconWidget from "../widgets/note_icon.jsx";
|
|
||||||
import ScrollingContainer from "../widgets/containers/scrolling_container.js";
|
|
||||||
import RootContainer from "../widgets/containers/root_container.js";
|
|
||||||
import WatchedFileUpdateStatusWidget from "../widgets/watched_file_update_status.js";
|
|
||||||
import SpacerWidget from "../widgets/spacer.js";
|
|
||||||
import QuickSearchWidget from "../widgets/quick_search.js";
|
|
||||||
import SplitNoteContainer from "../widgets/containers/split_note_container.js";
|
|
||||||
import CreatePaneButton from "../widgets/buttons/create_pane_button.js";
|
|
||||||
import ClosePaneButton from "../widgets/buttons/close_pane_button.js";
|
|
||||||
import RightPaneContainer from "../widgets/containers/right_pane_container.js";
|
|
||||||
import NoteWrapperWidget from "../widgets/note_wrapper.js";
|
|
||||||
import FindWidget from "../widgets/find.js";
|
|
||||||
import TocWidget from "../widgets/toc.js";
|
|
||||||
import HighlightsListWidget from "../widgets/highlights_list.js";
|
|
||||||
import PasswordNoteSetDialog from "../widgets/dialogs/password_not_set.js";
|
|
||||||
import LauncherContainer from "../widgets/containers/launcher_container.js";
|
|
||||||
import MovePaneButton from "../widgets/buttons/move_pane_button.js";
|
|
||||||
import UploadAttachmentsDialog from "../widgets/dialogs/upload_attachments.js";
|
|
||||||
import ScrollPadding from "../widgets/scroll_padding.js";
|
|
||||||
import options from "../services/options.js";
|
|
||||||
import utils from "../services/utils.js";
|
|
||||||
import type { AppContext } from "../components/app_context.js";
|
|
||||||
import type { WidgetsByParent } from "../services/bundle.js";
|
|
||||||
import { applyModals } from "./layout_commons.js";
|
import { applyModals } from "./layout_commons.js";
|
||||||
import Ribbon from "../widgets/ribbon/Ribbon.jsx";
|
|
||||||
import FloatingButtons from "../widgets/FloatingButtons.jsx";
|
|
||||||
import { DESKTOP_FLOATING_BUTTONS } from "../widgets/FloatingButtonsDefinitions.jsx";
|
import { DESKTOP_FLOATING_BUTTONS } from "../widgets/FloatingButtonsDefinitions.jsx";
|
||||||
import SearchResult from "../widgets/search_result.jsx";
|
import ApiLog from "../widgets/api_log.jsx";
|
||||||
|
import ClosePaneButton from "../widgets/buttons/close_pane_button.js";
|
||||||
|
import CloseZenModeButton from "../widgets/close_zen_button.jsx";
|
||||||
|
import ContentHeader from "../widgets/containers/content-header.js";
|
||||||
|
import CreatePaneButton from "../widgets/buttons/create_pane_button.js";
|
||||||
|
import FindWidget from "../widgets/find.js";
|
||||||
|
import FlexContainer from "../widgets/containers/flex_container.js";
|
||||||
|
import FloatingButtons from "../widgets/FloatingButtons.jsx";
|
||||||
import GlobalMenu from "../widgets/buttons/global_menu.jsx";
|
import GlobalMenu from "../widgets/buttons/global_menu.jsx";
|
||||||
|
import HighlightsListWidget from "../widgets/highlights_list.js";
|
||||||
|
import LauncherContainer from "../widgets/containers/launcher_container.js";
|
||||||
|
import LeftPaneContainer from "../widgets/containers/left_pane_container.js";
|
||||||
|
import LeftPaneToggle from "../widgets/buttons/left_pane_toggle.js";
|
||||||
|
import MovePaneButton from "../widgets/buttons/move_pane_button.js";
|
||||||
|
import NoteDetailWidget from "../widgets/note_detail.js";
|
||||||
|
import NoteIconWidget from "../widgets/note_icon.jsx";
|
||||||
|
import NoteList from "../widgets/collections/NoteList.jsx";
|
||||||
|
import NoteTitleWidget from "../widgets/note_title.jsx";
|
||||||
|
import NoteTreeWidget from "../widgets/note_tree.js";
|
||||||
|
import NoteWrapperWidget from "../widgets/note_wrapper.js";
|
||||||
|
import options from "../services/options.js";
|
||||||
|
import PasswordNoteSetDialog from "../widgets/dialogs/password_not_set.js";
|
||||||
|
import PromotedAttributesWidget from "../widgets/promoted_attributes.js";
|
||||||
|
import QuickSearchWidget from "../widgets/quick_search.js";
|
||||||
|
import ReadOnlyNoteInfoBar from "../widgets/ReadOnlyNoteInfoBar.jsx";
|
||||||
|
import Ribbon from "../widgets/ribbon/Ribbon.jsx";
|
||||||
|
import RightPaneContainer from "../widgets/containers/right_pane_container.js";
|
||||||
|
import RootContainer from "../widgets/containers/root_container.js";
|
||||||
|
import ScrollingContainer from "../widgets/containers/scrolling_container.js";
|
||||||
|
import ScrollPadding from "../widgets/scroll_padding.js";
|
||||||
|
import SearchResult from "../widgets/search_result.jsx";
|
||||||
|
import SharedInfo from "../widgets/shared_info.jsx";
|
||||||
|
import SpacerWidget from "../widgets/spacer.js";
|
||||||
|
import SplitNoteContainer from "../widgets/containers/split_note_container.js";
|
||||||
import SqlResults from "../widgets/sql_result.js";
|
import SqlResults from "../widgets/sql_result.js";
|
||||||
import SqlTableSchemas from "../widgets/sql_table_schemas.js";
|
import SqlTableSchemas from "../widgets/sql_table_schemas.js";
|
||||||
|
import TabRowWidget from "../widgets/tab_row.js";
|
||||||
import TitleBarButtons from "../widgets/title_bar_buttons.jsx";
|
import TitleBarButtons from "../widgets/title_bar_buttons.jsx";
|
||||||
import LeftPaneToggle from "../widgets/buttons/left_pane_toggle.js";
|
import TocWidget from "../widgets/toc.js";
|
||||||
import ApiLog from "../widgets/api_log.jsx";
|
import type { AppContext } from "../components/app_context.js";
|
||||||
import CloseZenModeButton from "../widgets/close_zen_button.jsx";
|
import type { WidgetsByParent } from "../services/bundle.js";
|
||||||
import SharedInfo from "../widgets/shared_info.jsx";
|
import UploadAttachmentsDialog from "../widgets/dialogs/upload_attachments.js";
|
||||||
import NoteList from "../widgets/collections/NoteList.jsx";
|
import utils from "../services/utils.js";
|
||||||
|
import WatchedFileUpdateStatusWidget from "../widgets/watched_file_update_status.js";
|
||||||
|
|
||||||
export default class DesktopLayout {
|
export default class DesktopLayout {
|
||||||
|
|
||||||
@ -129,12 +131,15 @@ export default class DesktopLayout {
|
|||||||
.child(<CreatePaneButton />)
|
.child(<CreatePaneButton />)
|
||||||
)
|
)
|
||||||
.child(<Ribbon />)
|
.child(<Ribbon />)
|
||||||
.child(<SharedInfo />)
|
|
||||||
.child(new WatchedFileUpdateStatusWidget())
|
.child(new WatchedFileUpdateStatusWidget())
|
||||||
.child(<FloatingButtons items={DESKTOP_FLOATING_BUTTONS} />)
|
.child(<FloatingButtons items={DESKTOP_FLOATING_BUTTONS} />)
|
||||||
.child(
|
.child(
|
||||||
new ScrollingContainer()
|
new ScrollingContainer()
|
||||||
.filling()
|
.filling()
|
||||||
|
.child(new ContentHeader()
|
||||||
|
.child(<ReadOnlyNoteInfoBar />)
|
||||||
|
.child(<SharedInfo />)
|
||||||
|
)
|
||||||
.child(new PromotedAttributesWidget())
|
.child(new PromotedAttributesWidget())
|
||||||
.child(<SqlTableSchemas />)
|
.child(<SqlTableSchemas />)
|
||||||
.child(new NoteDetailWidget())
|
.child(new NoteDetailWidget())
|
||||||
|
|||||||
@ -1,32 +1,34 @@
|
|||||||
|
import { applyModals } from "./layout_commons.js";
|
||||||
|
import { MOBILE_FLOATING_BUTTONS } from "../widgets/FloatingButtonsDefinitions.jsx";
|
||||||
|
import { useNoteContext } from "../widgets/react/hooks.jsx";
|
||||||
|
import CloseZenModeButton from "../widgets/close_zen_button.js";
|
||||||
|
import FilePropertiesTab from "../widgets/ribbon/FilePropertiesTab.jsx";
|
||||||
import FlexContainer from "../widgets/containers/flex_container.js";
|
import FlexContainer from "../widgets/containers/flex_container.js";
|
||||||
import NoteTitleWidget from "../widgets/note_title.js";
|
import FloatingButtons from "../widgets/FloatingButtons.jsx";
|
||||||
import NoteDetailWidget from "../widgets/note_detail.js";
|
|
||||||
import QuickSearchWidget from "../widgets/quick_search.js";
|
|
||||||
import NoteTreeWidget from "../widgets/note_tree.js";
|
|
||||||
import ScreenContainer from "../widgets/mobile_widgets/screen_container.js";
|
|
||||||
import ScrollingContainer from "../widgets/containers/scrolling_container.js";
|
|
||||||
import GlobalMenuWidget from "../widgets/buttons/global_menu.js";
|
import GlobalMenuWidget from "../widgets/buttons/global_menu.js";
|
||||||
import LauncherContainer from "../widgets/containers/launcher_container.js";
|
import LauncherContainer from "../widgets/containers/launcher_container.js";
|
||||||
import RootContainer from "../widgets/containers/root_container.js";
|
|
||||||
import SharedInfoWidget from "../widgets/shared_info.js";
|
|
||||||
import PromotedAttributesWidget from "../widgets/promoted_attributes.js";
|
|
||||||
import SidebarContainer from "../widgets/mobile_widgets/sidebar_container.js";
|
|
||||||
import type AppContext from "../components/app_context.js";
|
|
||||||
import TabRowWidget from "../widgets/tab_row.js";
|
|
||||||
import MobileEditorToolbar from "../widgets/type_widgets/ckeditor/mobile_editor_toolbar.js";
|
|
||||||
import { applyModals } from "./layout_commons.js";
|
|
||||||
import FilePropertiesTab from "../widgets/ribbon/FilePropertiesTab.jsx";
|
|
||||||
import { useNoteContext } from "../widgets/react/hooks.jsx";
|
|
||||||
import FloatingButtons from "../widgets/FloatingButtons.jsx";
|
|
||||||
import { MOBILE_FLOATING_BUTTONS } from "../widgets/FloatingButtonsDefinitions.jsx";
|
|
||||||
import ToggleSidebarButton from "../widgets/mobile_widgets/toggle_sidebar_button.jsx";
|
|
||||||
import CloseZenModeButton from "../widgets/close_zen_button.js";
|
|
||||||
import NoteWrapperWidget from "../widgets/note_wrapper.js";
|
|
||||||
import MobileDetailMenu from "../widgets/mobile_widgets/mobile_detail_menu.js";
|
import MobileDetailMenu from "../widgets/mobile_widgets/mobile_detail_menu.js";
|
||||||
|
import MobileEditorToolbar from "../widgets/type_widgets/ckeditor/mobile_editor_toolbar.js";
|
||||||
|
import NoteDetailWidget from "../widgets/note_detail.js";
|
||||||
import NoteList from "../widgets/collections/NoteList.jsx";
|
import NoteList from "../widgets/collections/NoteList.jsx";
|
||||||
import StandaloneRibbonAdapter from "../widgets/ribbon/components/StandaloneRibbonAdapter.jsx";
|
import NoteTitleWidget from "../widgets/note_title.js";
|
||||||
|
import ContentHeader from "../widgets/containers/content-header.js";
|
||||||
|
import NoteTreeWidget from "../widgets/note_tree.js";
|
||||||
|
import NoteWrapperWidget from "../widgets/note_wrapper.js";
|
||||||
|
import PromotedAttributesWidget from "../widgets/promoted_attributes.js";
|
||||||
|
import QuickSearchWidget from "../widgets/quick_search.js";
|
||||||
|
import ReadOnlyNoteInfoBar from "../widgets/ReadOnlyNoteInfoBar.jsx";
|
||||||
|
import RootContainer from "../widgets/containers/root_container.js";
|
||||||
|
import ScreenContainer from "../widgets/mobile_widgets/screen_container.js";
|
||||||
|
import ScrollingContainer from "../widgets/containers/scrolling_container.js";
|
||||||
import SearchDefinitionTab from "../widgets/ribbon/SearchDefinitionTab.jsx";
|
import SearchDefinitionTab from "../widgets/ribbon/SearchDefinitionTab.jsx";
|
||||||
import SearchResult from "../widgets/search_result.jsx";
|
import SearchResult from "../widgets/search_result.jsx";
|
||||||
|
import SharedInfoWidget from "../widgets/shared_info.js";
|
||||||
|
import SidebarContainer from "../widgets/mobile_widgets/sidebar_container.js";
|
||||||
|
import StandaloneRibbonAdapter from "../widgets/ribbon/components/StandaloneRibbonAdapter.jsx";
|
||||||
|
import TabRowWidget from "../widgets/tab_row.js";
|
||||||
|
import ToggleSidebarButton from "../widgets/mobile_widgets/toggle_sidebar_button.jsx";
|
||||||
|
import type AppContext from "../components/app_context.js";
|
||||||
|
|
||||||
const MOBILE_CSS = `
|
const MOBILE_CSS = `
|
||||||
<style>
|
<style>
|
||||||
@ -149,13 +151,16 @@ export default class MobileLayout {
|
|||||||
.child(<NoteTitleWidget />)
|
.child(<NoteTitleWidget />)
|
||||||
.child(<MobileDetailMenu />)
|
.child(<MobileDetailMenu />)
|
||||||
)
|
)
|
||||||
.child(<SharedInfoWidget />)
|
|
||||||
.child(<FloatingButtons items={MOBILE_FLOATING_BUTTONS} />)
|
.child(<FloatingButtons items={MOBILE_FLOATING_BUTTONS} />)
|
||||||
.child(new PromotedAttributesWidget())
|
.child(new PromotedAttributesWidget())
|
||||||
.child(
|
.child(
|
||||||
new ScrollingContainer()
|
new ScrollingContainer()
|
||||||
.filling()
|
.filling()
|
||||||
.contentSized()
|
.contentSized()
|
||||||
|
.child(new ContentHeader()
|
||||||
|
.child(<ReadOnlyNoteInfoBar />)
|
||||||
|
.child(<SharedInfoWidget />)
|
||||||
|
)
|
||||||
.child(new NoteDetailWidget())
|
.child(new NoteDetailWidget())
|
||||||
.child(<NoteList media="screen" />)
|
.child(<NoteList media="screen" />)
|
||||||
.child(<StandaloneRibbonAdapter component={SearchDefinitionTab} />)
|
.child(<StandaloneRibbonAdapter component={SearchDefinitionTab} />)
|
||||||
|
|||||||
@ -1809,12 +1809,15 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.note-split {
|
.note-split {
|
||||||
|
/* Limits the maximum width of the note */
|
||||||
|
--max-content-width: var(--preferred-max-content-width);
|
||||||
|
|
||||||
margin-inline-start: auto;
|
margin-inline-start: auto;
|
||||||
margin-inline-end: auto;
|
margin-inline-end: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-split.full-content-width {
|
.note-split.full-content-width {
|
||||||
max-width: 999999px;
|
--max-content-width: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.close:hover {
|
button.close:hover {
|
||||||
@ -2034,13 +2037,16 @@ body.zen #right-pane,
|
|||||||
body.zen #mobile-sidebar-wrapper,
|
body.zen #mobile-sidebar-wrapper,
|
||||||
body.zen .tab-row-container,
|
body.zen .tab-row-container,
|
||||||
body.zen .tab-row-widget,
|
body.zen .tab-row-widget,
|
||||||
|
body.zen .shared-info-widget,
|
||||||
body.zen .ribbon-container:not(:has(.classic-toolbar-widget)),
|
body.zen .ribbon-container:not(:has(.classic-toolbar-widget)),
|
||||||
body.zen .ribbon-container:has(.classic-toolbar-widget) .ribbon-top-row,
|
body.zen .ribbon-container:has(.classic-toolbar-widget) .ribbon-top-row,
|
||||||
body.zen .ribbon-container .ribbon-body:not(:has(.classic-toolbar-widget)),
|
body.zen .ribbon-container .ribbon-body:not(:has(.classic-toolbar-widget)),
|
||||||
body.zen .note-icon-widget,
|
body.zen .note-icon-widget,
|
||||||
body.zen .title-row .icon-action,
|
body.zen .title-row .icon-action,
|
||||||
|
body.zen .promoted-attributes-widget,
|
||||||
body.zen .floating-buttons-children > *:not(.bx-edit-alt),
|
body.zen .floating-buttons-children > *:not(.bx-edit-alt),
|
||||||
body.zen .action-button {
|
body.zen .action-button,
|
||||||
|
body.zen .note-list-widget:not(.full-height) {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2084,12 +2090,116 @@ body.zen .note-title-widget,
|
|||||||
body.zen .note-title-widget input {
|
body.zen .note-title-widget input {
|
||||||
font-size: 1rem !important;
|
font-size: 1rem !important;
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.zen #detail-container {
|
body.zen #detail-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.zen .note-split:not(.full-content-width) .scrolling-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
scroll-behavior: unset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.zen .note-split:not(.full-content-width) .note-detail {
|
||||||
|
margin: auto;
|
||||||
|
padding-bottom: 25vh;
|
||||||
|
max-width: var(--max-content-width);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.zen .note-split:not(.full-content-width) .scroll-padding-widget {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.zen .note-split.type-text {
|
||||||
|
position: relative;
|
||||||
|
font-size: 1.15em;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.zen:not(.backdrop-effects-disabled) .note-split.type-text .title-row {
|
||||||
|
--start-color: var(--main-background-color);
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
background: linear-gradient(var(--start-color) 30%, transparent 100%);
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@supports (background: color-mix(in srgb, white, transparent)) {
|
||||||
|
body.zen .note-split.type-text .title-row {
|
||||||
|
--start-color: color-mix(in srgb, var(--main-background-color), transparent 10%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body.zen .note-split.type-text .scrolling-container {
|
||||||
|
--padding-bottom: 130px; /* Should be enough to avoid caret being hidden by the formatting toolbar */
|
||||||
|
|
||||||
|
/* (Usually) keeps the caret above the fixed toolbar */
|
||||||
|
scroll-padding-bottom: var(--padding-bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.zen:not(.backdrop-effects-disabled) .note-split.type-text .scrolling-container {
|
||||||
|
--padding-top: 50px; /* Should be enough to cover the title row */
|
||||||
|
|
||||||
|
padding-top: var(--padding-top);
|
||||||
|
scroll-padding-top: var(--padding-top);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fixed formatting toolbar */
|
||||||
|
|
||||||
|
body.zen .note-split .ribbon-container {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
bottom: 20px;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1000;
|
||||||
|
opacity: 0; /* Hidden unless the current note split is focused */
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity 100ms linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.zen .note-split:focus-within .ribbon-container {
|
||||||
|
opacity: 1; /* Show when the note split is focused */
|
||||||
|
}
|
||||||
|
|
||||||
|
body.zen .note-split .ribbon-container .ribbon-body {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.zen .note-split .ribbon-container .classic-toolbar-widget {
|
||||||
|
margin: auto;
|
||||||
|
width: fit-content;
|
||||||
|
box-shadow: 0px 10px 20px rgba(0, 0, 0, .1);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--main-border-color);
|
||||||
|
padding: 4px;
|
||||||
|
background: var(--menu-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.zen .note-split:focus-within .ribbon-container .classic-toolbar-widget {
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1300px) {
|
||||||
|
body.zen .note-split .ribbon-container .classic-toolbar-widget {
|
||||||
|
/* Set the toolbar to full with */
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_se,
|
||||||
|
body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sw,
|
||||||
|
body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_smw,
|
||||||
|
body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_sme,
|
||||||
|
body.zen .classic-toolbar-widget .ck.ck-dropdown .ck-dropdown__panel.ck-dropdown__panel_s {
|
||||||
|
/* Force toolbar items overflow dropdowns open upwards */
|
||||||
|
top: auto;
|
||||||
|
bottom: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Content renderer */
|
/* Content renderer */
|
||||||
|
|
||||||
footer.file-footer,
|
footer.file-footer,
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
--native-titlebar-background: #00000000;
|
--native-titlebar-background: #00000000;
|
||||||
--window-background-color-bgfx: transparent; /* When background effects enabled */
|
--window-background-color-bgfx: transparent; /* When background effects enabled */
|
||||||
|
|
||||||
--main-background-color: #272727;
|
--main-background-color: #242424;
|
||||||
--main-text-color: #ccc;
|
--main-text-color: #ccc;
|
||||||
--main-border-color: #454545;
|
--main-border-color: #454545;
|
||||||
--subtle-border-color: #313131;
|
--subtle-border-color: #313131;
|
||||||
@ -166,6 +166,9 @@
|
|||||||
--protected-session-active-icon-color: #8edd8e;
|
--protected-session-active-icon-color: #8edd8e;
|
||||||
--sync-status-error-pulse-color: #f47871;
|
--sync-status-error-pulse-color: #f47871;
|
||||||
|
|
||||||
|
--center-pane-vert-layout-background-color-bgfx: #0c0c0c69;
|
||||||
|
--center-pane-horiz-layout-background-color-bgfx: #1e1e1ec7;
|
||||||
|
|
||||||
--right-pane-heading-color: gray;
|
--right-pane-heading-color: gray;
|
||||||
|
|
||||||
--root-background: var(--left-pane-background-color);
|
--root-background: var(--left-pane-background-color);
|
||||||
@ -192,9 +195,9 @@
|
|||||||
--badge-background-color: #ffffff1a;
|
--badge-background-color: #ffffff1a;
|
||||||
--badge-text-color: var(--muted-text-color);
|
--badge-text-color: var(--muted-text-color);
|
||||||
|
|
||||||
--promoted-attribute-card-background-color: var(--card-background-color);
|
--promoted-attribute-card-background-color: #ffffff21;
|
||||||
--promoted-attribute-card-shadow-color: #000000b3;
|
--promoted-attribute-card-shadow: none;
|
||||||
|
|
||||||
--floating-button-shadow-color: #00000080;
|
--floating-button-shadow-color: #00000080;
|
||||||
--floating-button-background-color: #494949d2;
|
--floating-button-background-color: #494949d2;
|
||||||
--floating-button-color: var(--button-text-color);
|
--floating-button-color: var(--button-text-color);
|
||||||
@ -208,6 +211,8 @@
|
|||||||
--floating-button-hide-button-background: #00000029;
|
--floating-button-hide-button-background: #00000029;
|
||||||
--floating-button-hide-button-color: #ffffff63;
|
--floating-button-hide-button-color: #ffffff63;
|
||||||
|
|
||||||
|
--right-pane-background-color: var(--main-background-color);
|
||||||
|
--right-pane-background-color-bgfx: #0c0c0c24; /* Only for the vertical layout */
|
||||||
--right-pane-item-hover-background: #ffffff26;
|
--right-pane-item-hover-background: #ffffff26;
|
||||||
--right-pane-item-hover-color: white;
|
--right-pane-item-hover-color: white;
|
||||||
|
|
||||||
@ -227,8 +232,8 @@
|
|||||||
--card-background-color: #ffffff12;
|
--card-background-color: #ffffff12;
|
||||||
--card-background-hover-color: #3c3c3c;
|
--card-background-hover-color: #3c3c3c;
|
||||||
--card-background-press-color: #464646;
|
--card-background-press-color: #464646;
|
||||||
--card-border-color: #222222;
|
--card-border-color: transparent;
|
||||||
--card-box-shadow: 0 0 12px rgba(0, 0, 0, 0.15);
|
--card-box-shadow: none;
|
||||||
|
|
||||||
--calendar-color: var(--menu-text-color);
|
--calendar-color: var(--menu-text-color);
|
||||||
--calendar-weekday-labels-color: var(--muted-text-color);
|
--calendar-weekday-labels-color: var(--muted-text-color);
|
||||||
@ -294,4 +299,10 @@ body ::-webkit-calendar-picker-indicator {
|
|||||||
|
|
||||||
body .todo-list input[type="checkbox"]:not(:checked):before {
|
body .todo-list input[type="checkbox"]:not(:checked):before {
|
||||||
border-color: var(--muted-text-color) !important;
|
border-color: var(--muted-text-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tinted-quick-edit-dialog {
|
||||||
|
--modal-background-color: hsl(var(--custom-color-hue), 8.8%, 11.2%);
|
||||||
|
--modal-border-color: hsl(var(--custom-color-hue), 9.4%, 25.1%);
|
||||||
|
--promoted-attribute-card-background-color: hsl(var(--custom-color-hue), 13.2%, 20.8%);
|
||||||
}
|
}
|
||||||
@ -159,6 +159,9 @@
|
|||||||
--protected-session-active-icon-color: #16b516;
|
--protected-session-active-icon-color: #16b516;
|
||||||
--sync-status-error-pulse-color: #ff5528;
|
--sync-status-error-pulse-color: #ff5528;
|
||||||
|
|
||||||
|
--center-pane-vert-layout-background-color-bgfx: #ffffff75;
|
||||||
|
--center-pane-horiz-layout-background-color-bgfx: #ffffffd6;
|
||||||
|
|
||||||
--right-pane-heading-color: gray;
|
--right-pane-heading-color: gray;
|
||||||
|
|
||||||
--root-background: var(--left-pane-background-color);
|
--root-background: var(--left-pane-background-color);
|
||||||
@ -180,13 +183,13 @@
|
|||||||
--inactive-tab-hover-background-color: #00000016;
|
--inactive-tab-hover-background-color: #00000016;
|
||||||
--inactive-tab-text-color: #4e4e4e;
|
--inactive-tab-text-color: #4e4e4e;
|
||||||
|
|
||||||
--alert-bar-background: #32637b29;
|
--alert-bar-background: #f9cf2b29;
|
||||||
|
|
||||||
--badge-background-color: #00000011;
|
--badge-background-color: #00000011;
|
||||||
--badge-text-color: var(--muted-text-color);
|
--badge-text-color: var(--muted-text-color);
|
||||||
|
|
||||||
--promoted-attribute-card-background-color: var(--card-background-color);
|
--promoted-attribute-card-background-color: #00000014;
|
||||||
--promoted-attribute-card-shadow-color: #00000033;
|
--promoted-attribute-card-shadow: none;
|
||||||
|
|
||||||
--floating-button-shadow-color: #00000042;
|
--floating-button-shadow-color: #00000042;
|
||||||
--floating-button-background-color: #eaeaeacc;
|
--floating-button-background-color: #eaeaeacc;
|
||||||
@ -207,6 +210,8 @@
|
|||||||
--new-tab-button-hover-background: white;
|
--new-tab-button-hover-background: white;
|
||||||
--new-tab-button-hover-color: black;
|
--new-tab-button-hover-color: black;
|
||||||
|
|
||||||
|
--right-pane-background-color: var(--main-background-color);
|
||||||
|
--right-pane-background-color-bgfx: var(--center-pane-vert-layout-background-color-bgfx); /* Only for the vertical layout */
|
||||||
--right-pane-item-hover-background: #ececec;
|
--right-pane-item-hover-background: #ececec;
|
||||||
--right-pane-item-hover-color: inherit;
|
--right-pane-item-hover-color: inherit;
|
||||||
|
|
||||||
@ -223,12 +228,12 @@
|
|||||||
|
|
||||||
--code-block-box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.1), 0px 0px 2px rgba(0, 0, 0, 0.2);
|
--code-block-box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.1), 0px 0px 2px rgba(0, 0, 0, 0.2);
|
||||||
|
|
||||||
--card-background-color: var(--accented-background-color);
|
--card-background-color: #0000000d;
|
||||||
--card-background-hover-color: #f9f9f9;
|
--card-background-hover-color: #f9f9f9;
|
||||||
--card-background-press-color: #efefef;
|
--card-background-press-color: #efefef;
|
||||||
--card-border-color: #eaeaea;
|
--card-border-color: transparent;
|
||||||
--card-shadow-color: rgba(0, 0, 0, 0.1);
|
--card-shadow-color: rgba(0, 0, 0, 0.1);
|
||||||
--card-box-shadow: 0 0 12px var(--card-shadow-color);
|
--card-box-shadow: none;
|
||||||
|
|
||||||
--calendar-color: var(--menu-text-color);
|
--calendar-color: var(--menu-text-color);
|
||||||
--calendar-weekday-labels-color: var(--muted-text-color);
|
--calendar-weekday-labels-color: var(--muted-text-color);
|
||||||
@ -270,4 +275,10 @@
|
|||||||
* The --custom-color-hue variable contains the hue of the user-selected note color.
|
* The --custom-color-hue variable contains the hue of the user-selected note color.
|
||||||
* This value is unset for gray tones. */
|
* This value is unset for gray tones. */
|
||||||
--custom-bg-color: hsl(var(--custom-color-hue), 37%, 89%, 1);
|
--custom-bg-color: hsl(var(--custom-color-hue), 37%, 89%, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tinted-quick-edit-dialog {
|
||||||
|
--modal-background-color: hsl(var(--custom-color-hue), 56%, 96%);
|
||||||
|
--modal-border-color: hsl(var(--custom-color-hue), 33%, 41%);
|
||||||
|
--promoted-attribute-card-background-color: hsl(var(--custom-color-hue), 40%, 88%);
|
||||||
}
|
}
|
||||||
@ -82,6 +82,7 @@
|
|||||||
|
|
||||||
/* Theme capabilities */
|
/* Theme capabilities */
|
||||||
--tab-note-icons: true;
|
--tab-note-icons: true;
|
||||||
|
--allow-background-effects: true;
|
||||||
|
|
||||||
/* To ensure that a tree item's custom color remains sufficiently contrasted and readable,
|
/* To ensure that a tree item's custom color remains sufficiently contrasted and readable,
|
||||||
* the color is adjusted based on the current color scheme (light or dark). The lightness
|
* the color is adjusted based on the current color scheme (light or dark). The lightness
|
||||||
@ -131,7 +132,8 @@ body.mobile .dropdown-menu .dropdown-menu {
|
|||||||
|
|
||||||
body.desktop .dropdown-menu::before,
|
body.desktop .dropdown-menu::before,
|
||||||
:root .ck.ck-dropdown__panel::before,
|
:root .ck.ck-dropdown__panel::before,
|
||||||
:root .excalidraw .popover::before {
|
:root .excalidraw .popover::before,
|
||||||
|
body.zen .note-split .ribbon-container .classic-toolbar-widget::before {
|
||||||
content: "";
|
content: "";
|
||||||
backdrop-filter: var(--dropdown-backdrop-filter);
|
backdrop-filter: var(--dropdown-backdrop-filter);
|
||||||
border-radius: var(--dropdown-border-radius);
|
border-radius: var(--dropdown-border-radius);
|
||||||
|
|||||||
@ -148,7 +148,7 @@ div.note-detail-empty {
|
|||||||
--options-card-min-width: 500px;
|
--options-card-min-width: 500px;
|
||||||
--options-card-max-width: 900px;
|
--options-card-max-width: 900px;
|
||||||
--options-card-padding: 17px;
|
--options-card-padding: 17px;
|
||||||
--options-title-font-size: 1rem;
|
--options-title-font-size: .75rem;
|
||||||
--options-title-offset: 13px;
|
--options-title-offset: 13px;
|
||||||
}
|
}
|
||||||
/* Create a gap at the top of the option pages */
|
/* Create a gap at the top of the option pages */
|
||||||
@ -173,16 +173,19 @@ div.note-detail-empty {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.options-section:not(.tn-no-card) {
|
.options-section:not(.tn-no-card) {
|
||||||
margin: auto;
|
margin-bottom: calc(var(--options-title-offset) + 26px) !important;
|
||||||
border-radius: 12px;
|
|
||||||
border: 1px solid var(--card-border-color) !important;
|
|
||||||
box-shadow: var(--card-box-shadow);
|
box-shadow: var(--card-box-shadow);
|
||||||
|
border: 1px solid var(--card-border-color) !important;
|
||||||
|
border-radius: 8px;
|
||||||
background: var(--card-background-color);
|
background: var(--card-background-color);
|
||||||
padding: var(--options-card-padding);
|
padding: var(--options-card-padding);
|
||||||
margin-bottom: calc(var(--options-title-offset) + 26px) !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body.desktop .option-section:not(.tn-no-card) {
|
body.prefers-centered-content .options-section:not(.tn-no-card) {
|
||||||
|
margin-inline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.desktop .options-section:not(.tn-no-card) {
|
||||||
min-width: var(--options-card-min-width);
|
min-width: var(--options-card-min-width);
|
||||||
max-width: var(--options-card-max-width);
|
max-width: var(--options-card-max-width);
|
||||||
}
|
}
|
||||||
@ -193,9 +196,16 @@ body.desktop .option-section:not(.tn-no-card) {
|
|||||||
padding-bottom: var(--default-padding);
|
padding-bottom: var(--default-padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.options-section:not(.tn-no-card) h4,
|
||||||
|
.options-section:not(.tn-no-card) h5 {
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: .4pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.options-section:not(.tn-no-card) h4 {
|
.options-section:not(.tn-no-card) h4 {
|
||||||
font-size: var(--options-title-font-size);
|
font-size: var(--options-title-font-size);
|
||||||
font-weight: bold;
|
font-weight: 600;
|
||||||
color: var(--launcher-pane-text-color);
|
color: var(--launcher-pane-text-color);
|
||||||
margin-top: calc(-1 * var(--options-card-padding) - var(--options-title-font-size) - var(--options-title-offset)) !important;
|
margin-top: calc(-1 * var(--options-card-padding) - var(--options-title-font-size) - var(--options-title-offset)) !important;
|
||||||
margin-bottom: calc(var(--options-title-offset) + var(--options-card-padding)) !important;
|
margin-bottom: calc(var(--options-title-offset) + var(--options-card-padding)) !important;
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
div.promoted-attributes-container {
|
div.promoted-attributes-container {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
|
margin-inline-start: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--dropdown-backdrop-filter: blur(10px) saturate(6);
|
--dropdown-backdrop-filter: blur(20px) saturate(6);
|
||||||
--dropdown-border-radius: 10px;
|
--dropdown-border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,30 +35,52 @@ body.mobile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* #region Mica */
|
/* #region Mica */
|
||||||
|
|
||||||
body.background-effects.platform-win32 {
|
body.background-effects.platform-win32 {
|
||||||
|
/* Quirk: --background-material is read before "theme-supports-background-effects" class
|
||||||
|
* is applied. Apply the matterial even if the theme doesn't support it. */
|
||||||
--background-material: tabbed;
|
--background-material: tabbed;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.background-effects.theme-supports-background-effects.platform-win32 {
|
||||||
--launcher-pane-horiz-border-color: var(--launcher-pane-horiz-border-color-bgfx);
|
--launcher-pane-horiz-border-color: var(--launcher-pane-horiz-border-color-bgfx);
|
||||||
--launcher-pane-horiz-background-color: var(--launcher-pane-horiz-background-color-bgfx);
|
--launcher-pane-horiz-background-color: var(--launcher-pane-horiz-background-color-bgfx);
|
||||||
--launcher-pane-vert-background-color: var(--launcher-pane-vert-background-color-bgfx);
|
--launcher-pane-vert-background-color: var(--launcher-pane-vert-background-color-bgfx);
|
||||||
--tab-background-color: var(--window-background-color-bgfx);
|
--tab-background-color: var(--window-background-color-bgfx);
|
||||||
--new-tab-button-background: var(--window-background-color-bgfx);
|
--new-tab-button-background: var(--window-background-color-bgfx);
|
||||||
--active-tab-background-color: var(--launcher-pane-horiz-background-color);
|
--active-tab-background-color: var(--launcher-pane-horiz-background-color);
|
||||||
|
--root-background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.background-effects.platform-win32.layout-vertical {
|
body.background-effects.platform-win32.layout-vertical {
|
||||||
--left-pane-background-color: var(--window-background-color-bgfx);
|
|
||||||
--background-material: mica;
|
--background-material: mica;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.background-effects.platform-win32,
|
body.background-effects.theme-supports-background-effects.platform-win32.layout-vertical {
|
||||||
body.background-effects.platform-win32 #root-widget {
|
--left-pane-background-color: var(--window-background-color-bgfx);
|
||||||
|
--center-pane-background-color-bgfx: var(--center-pane-vert-layout-background-color-bgfx);
|
||||||
|
--right-pane-background-color: var(--right-pane-background-color-bgfx);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.background-effects.theme-supports-background-effects.platform-win32.layout-horizontal {
|
||||||
|
--center-pane-background-color-bgfx: var(--center-pane-horiz-layout-background-color-bgfx);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.background-effects.theme-supports-background-effects.platform-win32,
|
||||||
|
body.background-effects.theme-supports-background-effects.platform-win32 #root-widget {
|
||||||
background: var(--window-background-color-bgfx) !important;
|
background: var(--window-background-color-bgfx) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.background-effects.platform-win32.layout-horizontal #horizontal-main-container,
|
body.background-effects.theme-supports-background-effects.platform-win32.layout-horizontal #horizontal-main-container,
|
||||||
body.background-effects.platform-win32.layout-vertical #vertical-main-container {
|
body.background-effects.theme-supports-background-effects.platform-win32.layout-vertical #vertical-main-container {
|
||||||
background-color: var(--root-background);
|
background-color: var(--root-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Note split with background effects */
|
||||||
|
body.background-effects.theme-supports-background-effects.platform-win32 #center-pane .note-split.bgfx {
|
||||||
|
--note-split-background-color: var(--center-pane-background-color-bgfx);
|
||||||
|
}
|
||||||
|
|
||||||
/* #endregion */
|
/* #endregion */
|
||||||
|
|
||||||
/* Matches when the left pane is collapsed */
|
/* Matches when the left pane is collapsed */
|
||||||
@ -72,9 +94,21 @@ body.layout-vertical #horizontal-main-container.left-pane-hidden #launcher-pane.
|
|||||||
border-inline-end: 2px solid var(--left-pane-collapsed-border-color);
|
border-inline-end: 2px solid var(--left-pane-collapsed-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
body.background-effects.zen #root-widget {
|
/*
|
||||||
--main-background-color: transparent;
|
* Zen mode
|
||||||
--root-background: transparent;
|
*/
|
||||||
|
|
||||||
|
@keyframes zen-formatting-toolbar-entrance {
|
||||||
|
from {
|
||||||
|
transform: translateY(200%);
|
||||||
|
} to {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body.zen .note-split .ribbon-container .classic-toolbar-widget {
|
||||||
|
position: relative;
|
||||||
|
animation: zen-formatting-toolbar-entrance 300ms ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1171,23 +1205,18 @@ body.layout-vertical .tab-row-widget-is-sorting .note-tab.note-tab-is-dragging .
|
|||||||
* CENTER PANE
|
* CENTER PANE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#center-pane {
|
/* The first visible note split */
|
||||||
background: var(--main-background-color);
|
.vertical-layout #center-pane .note-split:not(.visible ~ .visible) {
|
||||||
}
|
|
||||||
|
|
||||||
.vertical-layout #center-pane {
|
|
||||||
border-radius: var(--center-pane-border-radius) 0 0 0;
|
border-radius: var(--center-pane-border-radius) 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-split {
|
#center-pane .note-split {
|
||||||
padding-top: 2px;
|
padding-top: 2px;
|
||||||
animation: note-entrance 100ms linear;
|
background-color: var(--note-split-background-color, var(--main-background-color));
|
||||||
/* will-change: opacity; -- causes some weird artifacts to the note menu in split view */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.split-note-container-widget > .gutter {
|
body:not(.background-effects) #center-pane .note-split {
|
||||||
background: var(--root-background) !important;
|
animation: note-entrance 100ms linear;
|
||||||
transition: background 150ms ease-out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1200,9 +1229,9 @@ body.layout-vertical .tab-row-widget-is-sorting .note-tab.note-tab-is-dragging .
|
|||||||
|
|
||||||
@keyframes note-entrance {
|
@keyframes note-entrance {
|
||||||
from {
|
from {
|
||||||
opacity: 0;
|
filter: opacity(0);
|
||||||
} to {
|
} to {
|
||||||
opacity: 1;
|
filter: opacity(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1328,8 +1357,7 @@ div.promoted-attribute-cell {
|
|||||||
--pa-card-padding-inline-end: 2px;
|
--pa-card-padding-inline-end: 2px;
|
||||||
--input-background-color: transparent;
|
--input-background-color: transparent;
|
||||||
|
|
||||||
box-shadow: 1px 1px 2px var(--promoted-attribute-card-shadow-color);
|
box-shadow: var(--promoted-attribute-card-shadow);
|
||||||
|
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@ -1716,7 +1744,7 @@ div.find-replace-widget div.find-widget-found-wrapper > span {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#right-pane {
|
#right-pane {
|
||||||
background: var(--main-background-color);
|
background: var(--right-pane-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
#right-pane div.card-header {
|
#right-pane div.card-header {
|
||||||
|
|||||||
@ -520,9 +520,7 @@
|
|||||||
"max_content_width": {
|
"max_content_width": {
|
||||||
"max_width_unit": "بكسل",
|
"max_width_unit": "بكسل",
|
||||||
"title": "عرض المحتوى",
|
"title": "عرض المحتوى",
|
||||||
"reload_button": "اعادة تحميل الواجهة",
|
"max_width_label": "اقصى عرض للمحتوى"
|
||||||
"max_width_label": "اقصى عرض للمحتوى",
|
|
||||||
"reload_description": "تغييرات من خيارات المظهر"
|
|
||||||
},
|
},
|
||||||
"native_title_bar": {
|
"native_title_bar": {
|
||||||
"enabled": "مفعل",
|
"enabled": "مفعل",
|
||||||
|
|||||||
@ -1107,9 +1107,6 @@
|
|||||||
"title": "内容宽度",
|
"title": "内容宽度",
|
||||||
"default_description": "Trilium默认会限制内容的最大宽度以提高在宽屏中全屏时的可读性。",
|
"default_description": "Trilium默认会限制内容的最大宽度以提高在宽屏中全屏时的可读性。",
|
||||||
"max_width_label": "内容最大宽度(像素)",
|
"max_width_label": "内容最大宽度(像素)",
|
||||||
"apply_changes_description": "要应用内容宽度更改,请点击",
|
|
||||||
"reload_button": "重载前端",
|
|
||||||
"reload_description": "来自外观选项的更改",
|
|
||||||
"max_width_unit": "像素"
|
"max_width_unit": "像素"
|
||||||
},
|
},
|
||||||
"native_title_bar": {
|
"native_title_bar": {
|
||||||
|
|||||||
@ -1104,9 +1104,6 @@
|
|||||||
"title": "Inhaltsbreite",
|
"title": "Inhaltsbreite",
|
||||||
"default_description": "Trilium begrenzt standardmäßig die maximale Inhaltsbreite, um die Lesbarkeit für maximierte Bildschirme auf Breitbildschirmen zu verbessern.",
|
"default_description": "Trilium begrenzt standardmäßig die maximale Inhaltsbreite, um die Lesbarkeit für maximierte Bildschirme auf Breitbildschirmen zu verbessern.",
|
||||||
"max_width_label": "Maximale Inhaltsbreite in Pixel",
|
"max_width_label": "Maximale Inhaltsbreite in Pixel",
|
||||||
"apply_changes_description": "Um Änderungen an der Inhaltsbreite anzuwenden, klicke auf",
|
|
||||||
"reload_button": "Frontend neu laden",
|
|
||||||
"reload_description": "Änderungen an den Darstellungsoptionen",
|
|
||||||
"max_width_unit": "Pixel"
|
"max_width_unit": "Pixel"
|
||||||
},
|
},
|
||||||
"native_title_bar": {
|
"native_title_bar": {
|
||||||
|
|||||||
@ -1111,9 +1111,7 @@
|
|||||||
"default_description": "Trilium by default limits max content width to improve readability for maximized screens on wide screens.",
|
"default_description": "Trilium by default limits max content width to improve readability for maximized screens on wide screens.",
|
||||||
"max_width_label": "Max content width",
|
"max_width_label": "Max content width",
|
||||||
"max_width_unit": "pixels",
|
"max_width_unit": "pixels",
|
||||||
"apply_changes_description": "To apply content width changes, click on",
|
"centerContent": "Keep content centered"
|
||||||
"reload_button": "reload frontend",
|
|
||||||
"reload_description": "changes from appearance options"
|
|
||||||
},
|
},
|
||||||
"native_title_bar": {
|
"native_title_bar": {
|
||||||
"title": "Native Title Bar (requires app restart)",
|
"title": "Native Title Bar (requires app restart)",
|
||||||
@ -1639,6 +1637,12 @@
|
|||||||
"shared_locally": "This note is shared locally on {{- link}}.",
|
"shared_locally": "This note is shared locally on {{- link}}.",
|
||||||
"help_link": "For help visit <a href=\"https://triliumnext.github.io/Docs/Wiki/sharing.html\">wiki</a>."
|
"help_link": "For help visit <a href=\"https://triliumnext.github.io/Docs/Wiki/sharing.html\">wiki</a>."
|
||||||
},
|
},
|
||||||
|
"read-only-info": {
|
||||||
|
"read-only-note": "Currently viewing a read-only note.",
|
||||||
|
"auto-read-only-note": "This note is shown in a read-only mode for faster loading.",
|
||||||
|
"auto-read-only-learn-more": "Learn more",
|
||||||
|
"edit-note": "Edit note"
|
||||||
|
},
|
||||||
"note_types": {
|
"note_types": {
|
||||||
"text": "Text",
|
"text": "Text",
|
||||||
"code": "Code",
|
"code": "Code",
|
||||||
|
|||||||
@ -1107,10 +1107,7 @@
|
|||||||
"title": "Ancho del contenido",
|
"title": "Ancho del contenido",
|
||||||
"default_description": "Trilium limita de forma predeterminada el ancho máximo del contenido para mejorar la legibilidad de ventanas maximizadas en pantallas anchas.",
|
"default_description": "Trilium limita de forma predeterminada el ancho máximo del contenido para mejorar la legibilidad de ventanas maximizadas en pantallas anchas.",
|
||||||
"max_width_label": "Ancho máximo del contenido en píxeles",
|
"max_width_label": "Ancho máximo del contenido en píxeles",
|
||||||
"max_width_unit": "píxeles",
|
"max_width_unit": "píxeles"
|
||||||
"apply_changes_description": "Para aplicar cambios en el ancho del contenido, haga clic en",
|
|
||||||
"reload_button": "recargar la interfaz",
|
|
||||||
"reload_description": "cambios desde las opciones de apariencia"
|
|
||||||
},
|
},
|
||||||
"native_title_bar": {
|
"native_title_bar": {
|
||||||
"title": "Barra de título nativa (requiere reiniciar la aplicación)",
|
"title": "Barra de título nativa (requiere reiniciar la aplicación)",
|
||||||
|
|||||||
@ -1106,9 +1106,6 @@
|
|||||||
"title": "Largeur du contenu",
|
"title": "Largeur du contenu",
|
||||||
"default_description": "Trilium limite par défaut la largeur maximale du contenu pour améliorer la lisibilité sur des écrans larges.",
|
"default_description": "Trilium limite par défaut la largeur maximale du contenu pour améliorer la lisibilité sur des écrans larges.",
|
||||||
"max_width_label": "Largeur maximale du contenu en pixels",
|
"max_width_label": "Largeur maximale du contenu en pixels",
|
||||||
"apply_changes_description": "Pour appliquer les modifications de largeur du contenu, cliquez sur",
|
|
||||||
"reload_button": "recharger l'interface",
|
|
||||||
"reload_description": "changements par rapport aux options d'apparence",
|
|
||||||
"max_width_unit": "Pixels"
|
"max_width_unit": "Pixels"
|
||||||
},
|
},
|
||||||
"native_title_bar": {
|
"native_title_bar": {
|
||||||
|
|||||||
@ -1570,10 +1570,7 @@
|
|||||||
"title": "Larghezza del contenuto",
|
"title": "Larghezza del contenuto",
|
||||||
"default_description": "Per impostazione predefinita, Trilium limita la larghezza massima del contenuto per migliorare la leggibilità sugli schermi più grandi.",
|
"default_description": "Per impostazione predefinita, Trilium limita la larghezza massima del contenuto per migliorare la leggibilità sugli schermi più grandi.",
|
||||||
"max_width_label": "Larghezza massima del contenuto",
|
"max_width_label": "Larghezza massima del contenuto",
|
||||||
"max_width_unit": "pixel",
|
"max_width_unit": "pixel"
|
||||||
"apply_changes_description": "Per applicare le modifiche alla larghezza del contenuto, fare clic su",
|
|
||||||
"reload_button": "ricarica frontend",
|
|
||||||
"reload_description": "modifiche dalle opzioni di aspetto"
|
|
||||||
},
|
},
|
||||||
"native_title_bar": {
|
"native_title_bar": {
|
||||||
"title": "Barra del titolo nativa (richiede il riavvio dell'app)",
|
"title": "Barra del titolo nativa (richiede il riavvio dell'app)",
|
||||||
|
|||||||
@ -833,13 +833,10 @@
|
|||||||
"theme_defined": "テーマが定義されました"
|
"theme_defined": "テーマが定義されました"
|
||||||
},
|
},
|
||||||
"max_content_width": {
|
"max_content_width": {
|
||||||
"reload_button": "フロントエンドをリロード",
|
|
||||||
"title": "コンテンツ幅",
|
"title": "コンテンツ幅",
|
||||||
"default_description": "Triliumは、ワイドスクリーンで最大化された画面での可読性を向上させるために、デフォルトでコンテンツの最大幅を制限しています。",
|
"default_description": "Triliumは、ワイドスクリーンで最大化された画面での可読性を向上させるために、デフォルトでコンテンツの最大幅を制限しています。",
|
||||||
"max_width_label": "最大コンテンツ幅",
|
"max_width_label": "最大コンテンツ幅",
|
||||||
"max_width_unit": "ピクセル",
|
"max_width_unit": "ピクセル"
|
||||||
"apply_changes_description": "コンテンツ幅の変更を適用するには、クリックしてください",
|
|
||||||
"reload_description": "外観設定から変更"
|
|
||||||
},
|
},
|
||||||
"theme": {
|
"theme": {
|
||||||
"title": "アプリのテーマ",
|
"title": "アプリのテーマ",
|
||||||
|
|||||||
@ -1464,10 +1464,7 @@
|
|||||||
"title": "Szerokość zawartości",
|
"title": "Szerokość zawartości",
|
||||||
"default_description": "Trilium domyślnie ogranicza maksymalną szerokość zawartości, aby poprawić czytelność na zmaksymalizowanych ekranach o dużej szerokości.",
|
"default_description": "Trilium domyślnie ogranicza maksymalną szerokość zawartości, aby poprawić czytelność na zmaksymalizowanych ekranach o dużej szerokości.",
|
||||||
"max_width_label": "Maksymalna szerokość zawartości",
|
"max_width_label": "Maksymalna szerokość zawartości",
|
||||||
"max_width_unit": "piksele",
|
"max_width_unit": "piksele"
|
||||||
"apply_changes_description": "Aby zastosować zmiany szerokości zawartości, kliknij na",
|
|
||||||
"reload_button": "przeładuj frontend",
|
|
||||||
"reload_description": "zmiany z opcji wyglądu"
|
|
||||||
},
|
},
|
||||||
"native_title_bar": {
|
"native_title_bar": {
|
||||||
"title": "Natywny pasek tytułu (wymaga ponownego uruchomienia aplikacji)",
|
"title": "Natywny pasek tytułu (wymaga ponownego uruchomienia aplikacji)",
|
||||||
|
|||||||
@ -1082,10 +1082,7 @@
|
|||||||
"title": "Largura do Conteúdo",
|
"title": "Largura do Conteúdo",
|
||||||
"default_description": "Por padrão, o Trilium limita a largura máxima do conteúdo para melhorar a legibilidade em janelas maximizadas em ecrãs largos.",
|
"default_description": "Por padrão, o Trilium limita a largura máxima do conteúdo para melhorar a legibilidade em janelas maximizadas em ecrãs largos.",
|
||||||
"max_width_label": "Largura máxima do conteúdo",
|
"max_width_label": "Largura máxima do conteúdo",
|
||||||
"max_width_unit": "pixels",
|
"max_width_unit": "pixels"
|
||||||
"apply_changes_description": "Para aplicar as alterações de largura do conteúdo, clique em",
|
|
||||||
"reload_button": "recarregar frontend",
|
|
||||||
"reload_description": "alterações de opções de aparência"
|
|
||||||
},
|
},
|
||||||
"native_title_bar": {
|
"native_title_bar": {
|
||||||
"title": "Barra de Título Nativa (requer recarregar a app)",
|
"title": "Barra de Título Nativa (requer recarregar a app)",
|
||||||
|
|||||||
@ -1304,9 +1304,6 @@
|
|||||||
"title": "Largura do Conteúdo",
|
"title": "Largura do Conteúdo",
|
||||||
"max_width_label": "Largura máxima do conteúdo",
|
"max_width_label": "Largura máxima do conteúdo",
|
||||||
"max_width_unit": "pixels",
|
"max_width_unit": "pixels",
|
||||||
"apply_changes_description": "Para aplicar as alterações de largura do conteúdo, clique em",
|
|
||||||
"reload_button": "recarregar frontend",
|
|
||||||
"reload_description": "alterações de opções de aparência",
|
|
||||||
"default_description": "Por padrão, o Trilium limita a largura máxima do conteúdo para melhorar a legibilidade em janelas maximizadas em telas wide."
|
"default_description": "Por padrão, o Trilium limita a largura máxima do conteúdo para melhorar a legibilidade em janelas maximizadas em telas wide."
|
||||||
},
|
},
|
||||||
"native_title_bar": {
|
"native_title_bar": {
|
||||||
|
|||||||
@ -796,12 +796,9 @@
|
|||||||
"modal_body_text": "Din cauza limitărilor la nivel de navigator, nu este posibilă citirea clipboard-ului din JavaScript. Inserați Markdown-ul pentru a-l importa în caseta de mai jos și dați clic pe butonul Import"
|
"modal_body_text": "Din cauza limitărilor la nivel de navigator, nu este posibilă citirea clipboard-ului din JavaScript. Inserați Markdown-ul pentru a-l importa în caseta de mai jos și dați clic pe butonul Import"
|
||||||
},
|
},
|
||||||
"max_content_width": {
|
"max_content_width": {
|
||||||
"apply_changes_description": "Pentru a aplica schimbările de lățime a conținutului, dați click pe",
|
|
||||||
"default_description": "În mod implicit Trilium limitează lățimea conținutului pentru a îmbunătăți lizibilitatea pentru ferestrele maximizate pe ecrane late.",
|
"default_description": "În mod implicit Trilium limitează lățimea conținutului pentru a îmbunătăți lizibilitatea pentru ferestrele maximizate pe ecrane late.",
|
||||||
"max_width_label": "Lungimea maximă a conținutului",
|
"max_width_label": "Lungimea maximă a conținutului",
|
||||||
"max_width_unit": "pixeli",
|
"max_width_unit": "pixeli",
|
||||||
"reload_button": "reîncarcă interfața",
|
|
||||||
"reload_description": "schimbări din opțiunile de afișare",
|
|
||||||
"title": "Lățime conținut"
|
"title": "Lățime conținut"
|
||||||
},
|
},
|
||||||
"mobile_detail_menu": {
|
"mobile_detail_menu": {
|
||||||
|
|||||||
@ -1203,11 +1203,8 @@
|
|||||||
"max_content_width": {
|
"max_content_width": {
|
||||||
"max_width_unit": "пикселей",
|
"max_width_unit": "пикселей",
|
||||||
"title": "Ширина контентной области",
|
"title": "Ширина контентной области",
|
||||||
"reload_button": "перезагрузить интерфейс",
|
|
||||||
"default_description": "Trilium по умолчанию ограничивает максимальную ширину контента, чтобы улучшить читаемость на широких экранах.",
|
"default_description": "Trilium по умолчанию ограничивает максимальную ширину контента, чтобы улучшить читаемость на широких экранах.",
|
||||||
"max_width_label": "Максимальная ширина контентной области",
|
"max_width_label": "Максимальная ширина контентной области"
|
||||||
"apply_changes_description": "Чтобы применить изменения, нажмите на",
|
|
||||||
"reload_description": "изменения в параметрах внешнего вида"
|
|
||||||
},
|
},
|
||||||
"native_title_bar": {
|
"native_title_bar": {
|
||||||
"enabled": "включено",
|
"enabled": "включено",
|
||||||
|
|||||||
@ -1104,9 +1104,6 @@
|
|||||||
"title": "內容寬度",
|
"title": "內容寬度",
|
||||||
"default_description": "Trilium 預設會限制內容的最大寬度以提高在寬螢幕中全螢幕時的可讀性。",
|
"default_description": "Trilium 預設會限制內容的最大寬度以提高在寬螢幕中全螢幕時的可讀性。",
|
||||||
"max_width_label": "內容最大寬度(像素)",
|
"max_width_label": "內容最大寬度(像素)",
|
||||||
"apply_changes_description": "要套用內容寬度更改,請點擊",
|
|
||||||
"reload_button": "重新載入前端",
|
|
||||||
"reload_description": "來自外觀選項的更改",
|
|
||||||
"max_width_unit": "像素"
|
"max_width_unit": "像素"
|
||||||
},
|
},
|
||||||
"native_title_bar": {
|
"native_title_bar": {
|
||||||
|
|||||||
@ -1204,10 +1204,7 @@
|
|||||||
"title": "Ширина вмісту",
|
"title": "Ширина вмісту",
|
||||||
"default_description": "Trilium за замовчуванням обмежує максимальну ширину вмісту, щоб поліпшити читабельність на широкоформатних екранах у режимі максимального розширення.",
|
"default_description": "Trilium за замовчуванням обмежує максимальну ширину вмісту, щоб поліпшити читабельність на широкоформатних екранах у режимі максимального розширення.",
|
||||||
"max_width_label": "Максимальна ширина вмісту",
|
"max_width_label": "Максимальна ширина вмісту",
|
||||||
"max_width_unit": "пікселів",
|
"max_width_unit": "пікселів"
|
||||||
"apply_changes_description": "Щоб застосувати зміни ширини вмісту, натисніть на",
|
|
||||||
"reload_button": "перезавантажити інтерфейс",
|
|
||||||
"reload_description": "зміни в параметрах зовнішнього вигляду"
|
|
||||||
},
|
},
|
||||||
"native_title_bar": {
|
"native_title_bar": {
|
||||||
"title": "Нативний рядок заголовка (потрібен перезапуск)",
|
"title": "Нативний рядок заголовка (потрібен перезапуск)",
|
||||||
|
|||||||
@ -23,6 +23,24 @@ export class CssVarReader {
|
|||||||
return (!isNaN(number.valueOf()) ? number.valueOf() : defaultValue)
|
return (!isNaN(number.valueOf()) ? number.valueOf() : defaultValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asBoolean(defaultValue?: boolean) {
|
||||||
|
let value = this.value.toLocaleLowerCase().trim();
|
||||||
|
let result: boolean | undefined;
|
||||||
|
|
||||||
|
switch (value) {
|
||||||
|
case "true":
|
||||||
|
case "1":
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
case "false":
|
||||||
|
case "0":
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result !== undefined) ? result : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
asEnum<T>(enumType: T, defaultValue?: T[keyof T]): T[keyof T] | undefined {
|
asEnum<T>(enumType: T, defaultValue?: T[keyof T]): T[keyof T] | undefined {
|
||||||
let result: T[keyof T] | undefined;
|
let result: T[keyof T] | undefined;
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
.floating-buttons-children,
|
.floating-buttons-children,
|
||||||
.show-floating-buttons {
|
.show-floating-buttons {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: var(--floating-buttons-vert-offset, 10px);
|
top: var(--floating-buttons-vert-offset, 14px);
|
||||||
inset-inline-end: var(--floating-buttons-horiz-offset, 10px);
|
inset-inline-end: var(--floating-buttons-horiz-offset, 10px);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
import "./FloatingButtons.css";
|
import "./FloatingButtons.css";
|
||||||
import { useNoteContext, useNoteLabel, useNoteLabelBoolean } from "./react/hooks";
|
import { useNoteContext, useNoteLabel, useNoteLabelBoolean, useTriliumEvent } from "./react/hooks";
|
||||||
import { useContext, useEffect, useMemo, useState } from "preact/hooks";
|
import { useContext, useEffect, useMemo, useState } from "preact/hooks";
|
||||||
import { ParentComponent } from "./react/react_utils";
|
import { ParentComponent } from "./react/react_utils";
|
||||||
import { EventData, EventNames } from "../components/app_context";
|
import { EventData, EventNames } from "../components/app_context";
|
||||||
@ -20,6 +20,7 @@ interface FloatingButtonsProps {
|
|||||||
* properly handle rounded corners, as defined by the --border-radius CSS variable.
|
* properly handle rounded corners, as defined by the --border-radius CSS variable.
|
||||||
*/
|
*/
|
||||||
export default function FloatingButtons({ items }: FloatingButtonsProps) {
|
export default function FloatingButtons({ items }: FloatingButtonsProps) {
|
||||||
|
const [ top, setTop ] = useState(0);
|
||||||
const { note, noteContext } = useNoteContext();
|
const { note, noteContext } = useNoteContext();
|
||||||
const parentComponent = useContext(ParentComponent);
|
const parentComponent = useContext(ParentComponent);
|
||||||
const [ viewType ] = useNoteLabel(note, "viewType");
|
const [ viewType ] = useNoteLabel(note, "viewType");
|
||||||
@ -47,8 +48,14 @@ export default function FloatingButtons({ items }: FloatingButtonsProps) {
|
|||||||
const [ visible, setVisible ] = useState(true);
|
const [ visible, setVisible ] = useState(true);
|
||||||
useEffect(() => setVisible(true), [ note ]);
|
useEffect(() => setVisible(true), [ note ]);
|
||||||
|
|
||||||
|
useTriliumEvent("contentSafeMarginChanged", (e) => {
|
||||||
|
if (e.noteContext === noteContext) {
|
||||||
|
setTop(e.top);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="floating-buttons no-print">
|
<div className="floating-buttons no-print" style={{top}}>
|
||||||
<div className={`floating-buttons-children ${!visible ? "temporarily-hidden" : ""}`}>
|
<div className={`floating-buttons-children ${!visible ? "temporarily-hidden" : ""}`}>
|
||||||
{context && items.map((Component) => (
|
{context && items.map((Component) => (
|
||||||
<Component {...context} />
|
<Component {...context} />
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import Component from "../components/component";
|
|||||||
import NoteContext from "../components/note_context";
|
import NoteContext from "../components/note_context";
|
||||||
import FNote from "../entities/fnote";
|
import FNote from "../entities/fnote";
|
||||||
import ActionButton, { ActionButtonProps } from "./react/ActionButton";
|
import ActionButton, { ActionButtonProps } from "./react/ActionButton";
|
||||||
import { useNoteLabelBoolean, useTriliumEvent, useTriliumOption, useWindowSize } from "./react/hooks";
|
import { useIsNoteReadOnly, useNoteLabelBoolean, useTriliumEvent, useTriliumOption, useWindowSize } from "./react/hooks";
|
||||||
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks";
|
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks";
|
||||||
import { createImageSrcUrl, openInAppHelpFromUrl } from "../services/utils";
|
import { createImageSrcUrl, openInAppHelpFromUrl } from "../services/utils";
|
||||||
import server from "../services/server";
|
import server from "../services/server";
|
||||||
@ -13,8 +13,6 @@ import toast from "../services/toast";
|
|||||||
import { t } from "../services/i18n";
|
import { t } from "../services/i18n";
|
||||||
import { copyImageReferenceToClipboard } from "../services/image";
|
import { copyImageReferenceToClipboard } from "../services/image";
|
||||||
import tree from "../services/tree";
|
import tree from "../services/tree";
|
||||||
import protected_session_holder from "../services/protected_session_holder";
|
|
||||||
import options from "../services/options";
|
|
||||||
import { getHelpUrlForNote } from "../services/in_app_help";
|
import { getHelpUrlForNote } from "../services/in_app_help";
|
||||||
import froca from "../services/froca";
|
import froca from "../services/froca";
|
||||||
import NoteLink from "./react/NoteLink";
|
import NoteLink from "./react/NoteLink";
|
||||||
@ -101,48 +99,26 @@ function ToggleReadOnlyButton({ note, viewType, isDefaultViewMode }: FloatingBut
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
function EditButton({ note, noteContext, isDefaultViewMode }: FloatingButtonContext) {
|
function EditButton({ note, noteContext }: FloatingButtonContext) {
|
||||||
const [ animationClass, setAnimationClass ] = useState("");
|
const [animationClass, setAnimationClass] = useState("");
|
||||||
const [ isEnabled, setIsEnabled ] = useState(false);
|
const {isReadOnly, enableEditing} = useIsNoteReadOnly(note, noteContext);
|
||||||
|
|
||||||
|
const isReadOnlyInfoBarDismissed = false; // TODO
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
noteContext.isReadOnly().then(isReadOnly => {
|
if (isReadOnly) {
|
||||||
setIsEnabled(
|
|
||||||
isDefaultViewMode
|
|
||||||
&& (!note.isProtected || protected_session_holder.isProtectedSessionAvailable())
|
|
||||||
&& !options.is("databaseReadonly")
|
|
||||||
&& isReadOnly
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}, [ note ]);
|
|
||||||
|
|
||||||
useTriliumEvent("readOnlyTemporarilyDisabled", ({ noteContext: eventNoteContext }) => {
|
|
||||||
if (noteContext?.ntxId === eventNoteContext.ntxId) {
|
|
||||||
setIsEnabled(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// make the edit button stand out on the first display, otherwise
|
|
||||||
// it's difficult to notice that the note is readonly
|
|
||||||
useEffect(() => {
|
|
||||||
if (isEnabled) {
|
|
||||||
setAnimationClass("bx-tada bx-lg");
|
setAnimationClass("bx-tada bx-lg");
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setAnimationClass("");
|
setAnimationClass("");
|
||||||
}, 1700);
|
}, 1700);
|
||||||
}
|
}
|
||||||
}, [ isEnabled ]);
|
}, [ isReadOnly ]);
|
||||||
|
|
||||||
return isEnabled && <FloatingButton
|
return !!isReadOnly && isReadOnlyInfoBarDismissed && <FloatingButton
|
||||||
text={t("edit_button.edit_this_note")}
|
text={t("edit_button.edit_this_note")}
|
||||||
icon="bx bx-pencil"
|
icon="bx bx-pencil"
|
||||||
className={animationClass}
|
className={animationClass}
|
||||||
onClick={() => {
|
onClick={() => enableEditing()}
|
||||||
if (noteContext.viewScope) {
|
|
||||||
noteContext.viewScope.readOnlyTemporarilyDisabled = true;
|
|
||||||
appContext.triggerEvent("readOnlyTemporarilyDisabled", { noteContext });
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
19
apps/client/src/widgets/ReadOnlyNoteInfoBar.css
Normal file
19
apps/client/src/widgets/ReadOnlyNoteInfoBar.css
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
body.zen div.read-only-note-info-bar-widget {
|
||||||
|
width: fit-content;
|
||||||
|
max-width: var(--max-content-width);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: unset;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.read-only-note-info-bar-widget-content {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root div.read-only-note-info-bar-widget button {
|
||||||
|
white-space: nowrap;
|
||||||
|
padding: 2px 8px;
|
||||||
|
}
|
||||||
36
apps/client/src/widgets/ReadOnlyNoteInfoBar.tsx
Normal file
36
apps/client/src/widgets/ReadOnlyNoteInfoBar.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import "./ReadOnlyNoteInfoBar.css";
|
||||||
|
import { t } from "../services/i18n";
|
||||||
|
import { useIsNoteReadOnly, useNoteContext, useTriliumEvent } from "./react/hooks"
|
||||||
|
import Button from "./react/Button";
|
||||||
|
import InfoBar from "./react/InfoBar";
|
||||||
|
|
||||||
|
export default function ReadOnlyNoteInfoBar(props: {}) {
|
||||||
|
const {note, noteContext} = useNoteContext();
|
||||||
|
const {isReadOnly, enableEditing} = useIsNoteReadOnly(note, noteContext);
|
||||||
|
const isExplicitReadOnly = note?.isLabelTruthy("readOnly");
|
||||||
|
|
||||||
|
return <InfoBar className="read-only-note-info-bar-widget"
|
||||||
|
type={(isExplicitReadOnly ? "subtle" : "prominent")}
|
||||||
|
style={{display: (!isReadOnly) ? "none" : undefined}}>
|
||||||
|
|
||||||
|
<div class="read-only-note-info-bar-widget-content">
|
||||||
|
{(isExplicitReadOnly) ? (
|
||||||
|
<div>{t("read-only-info.read-only-note")}</div>
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
{t("read-only-info.auto-read-only-note")}
|
||||||
|
|
||||||
|
<a class="tn-link"
|
||||||
|
href="https://docs.triliumnotes.org/user-guide/concepts/notes/read-only-notes#automatic-read-only-mode">
|
||||||
|
|
||||||
|
{t("read-only-info.auto-read-only-learn-more")}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Button text={t("read-only-info.edit-note")}
|
||||||
|
icon="bx-pencil" onClick={() => enableEditing()} />
|
||||||
|
</div>
|
||||||
|
</InfoBar>
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,9 +1,16 @@
|
|||||||
.note-list-widget {
|
.note-list-widget {
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
max-width: var(--max-content-width); /* Inherited from .note-split */
|
||||||
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
contain: none !important;
|
contain: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.prefers-centered-content .note-list-widget {
|
||||||
|
/* Horizontally center the widget in its parent when the "Keep content centered" option is on */
|
||||||
|
margin-inline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.note-list-widget .note-list {
|
.note-list-widget .note-list {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|||||||
63
apps/client/src/widgets/containers/content-header.ts
Normal file
63
apps/client/src/widgets/containers/content-header.ts
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import { EventData } from "../../components/app_context";
|
||||||
|
import BasicWidget from "../basic_widget";
|
||||||
|
import Container from "./container";
|
||||||
|
import NoteContext from "../../components/note_context";
|
||||||
|
|
||||||
|
export default class ContentHeader extends Container<BasicWidget> {
|
||||||
|
|
||||||
|
noteContext?: NoteContext;
|
||||||
|
thisElement?: HTMLElement;
|
||||||
|
parentElement?: HTMLElement;
|
||||||
|
resizeObserver: ResizeObserver;
|
||||||
|
currentHeight: number = 0;
|
||||||
|
currentSafeMargin: number = NaN;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.css("contain", "unset");
|
||||||
|
this.resizeObserver = new ResizeObserver(this.onResize.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
setNoteContextEvent({ noteContext }: EventData<"setNoteContext">) {
|
||||||
|
this.noteContext = noteContext;
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.parentElement = this.parent!.$widget.get(0);
|
||||||
|
|
||||||
|
if (!this.parentElement) {
|
||||||
|
console.warn("No parent set for <ContentHeader>.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.thisElement = this.$widget.get(0)!;
|
||||||
|
|
||||||
|
this.resizeObserver.observe(this.thisElement);
|
||||||
|
this.parentElement.addEventListener("scroll", this.updateSafeMargin.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSafeMargin() {
|
||||||
|
const newSafeMargin = Math.max(this.currentHeight - this.parentElement!.scrollTop, 0);
|
||||||
|
|
||||||
|
if (newSafeMargin !== this.currentSafeMargin) {
|
||||||
|
this.currentSafeMargin = newSafeMargin;
|
||||||
|
|
||||||
|
this.triggerEvent("contentSafeMarginChanged", {
|
||||||
|
top: newSafeMargin,
|
||||||
|
noteContext: this.noteContext!
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onResize(entries: ResizeObserverEntry[]) {
|
||||||
|
for (const entry of entries) {
|
||||||
|
if (entry.target === this.thisElement) {
|
||||||
|
this.currentHeight = entry.contentRect.height;
|
||||||
|
this.updateSafeMargin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,9 +1,10 @@
|
|||||||
import { EventData } from "../../components/app_context.js";
|
import { EventData } from "../../components/app_context.js";
|
||||||
|
import { LOCALES } from "@triliumnext/commons";
|
||||||
|
import { readCssVar } from "../../utils/css-var.js";
|
||||||
import FlexContainer from "./flex_container.js";
|
import FlexContainer from "./flex_container.js";
|
||||||
import options from "../../services/options.js";
|
import options from "../../services/options.js";
|
||||||
import type BasicWidget from "../basic_widget.js";
|
import type BasicWidget from "../basic_widget.js";
|
||||||
import utils from "../../services/utils.js";
|
import utils from "../../services/utils.js";
|
||||||
import { LOCALES } from "@triliumnext/commons";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The root container is the top-most widget/container, from which the entire layout derives.
|
* The root container is the top-most widget/container, from which the entire layout derives.
|
||||||
@ -30,9 +31,11 @@ export default class RootContainer extends FlexContainer<BasicWidget> {
|
|||||||
window.visualViewport?.addEventListener("resize", () => this.#onMobileResize());
|
window.visualViewport?.addEventListener("resize", () => this.#onMobileResize());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#setMotion(options.is("motionEnabled"));
|
this.#setMaxContentWidth();
|
||||||
this.#setShadows(options.is("shadowsEnabled"));
|
this.#setMotion();
|
||||||
this.#setBackdropEffects(options.is("backdropEffectsEnabled"));
|
this.#setShadows();
|
||||||
|
this.#setBackdropEffects();
|
||||||
|
this.#setThemeCapabilities();
|
||||||
this.#setLocaleAndDirection(options.get("locale"));
|
this.#setLocaleAndDirection(options.get("locale"));
|
||||||
|
|
||||||
return super.render();
|
return super.render();
|
||||||
@ -40,15 +43,21 @@ export default class RootContainer extends FlexContainer<BasicWidget> {
|
|||||||
|
|
||||||
entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
|
entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
|
||||||
if (loadResults.isOptionReloaded("motionEnabled")) {
|
if (loadResults.isOptionReloaded("motionEnabled")) {
|
||||||
this.#setMotion(options.is("motionEnabled"));
|
this.#setMotion();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadResults.isOptionReloaded("shadowsEnabled")) {
|
if (loadResults.isOptionReloaded("shadowsEnabled")) {
|
||||||
this.#setShadows(options.is("shadowsEnabled"));
|
this.#setShadows();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadResults.isOptionReloaded("backdropEffectsEnabled")) {
|
if (loadResults.isOptionReloaded("backdropEffectsEnabled")) {
|
||||||
this.#setBackdropEffects(options.is("backdropEffectsEnabled"));
|
this.#setBackdropEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loadResults.isOptionReloaded("maxContentWidth")
|
||||||
|
|| loadResults.isOptionReloaded("centerContent")) {
|
||||||
|
|
||||||
|
this.#setMaxContentWidth();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,19 +67,38 @@ export default class RootContainer extends FlexContainer<BasicWidget> {
|
|||||||
this.$widget.toggleClass("virtual-keyboard-opened", isKeyboardOpened);
|
this.$widget.toggleClass("virtual-keyboard-opened", isKeyboardOpened);
|
||||||
}
|
}
|
||||||
|
|
||||||
#setMotion(enabled: boolean) {
|
#setMaxContentWidth() {
|
||||||
|
const width = Math.max(options.getInt("maxContentWidth") || 0, 640);
|
||||||
|
document.body.style.setProperty("--preferred-max-content-width", `${width}px`);
|
||||||
|
|
||||||
|
document.body.classList.toggle("prefers-centered-content", options.is("centerContent"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#setMotion() {
|
||||||
|
const enabled = options.is("motionEnabled");
|
||||||
document.body.classList.toggle("motion-disabled", !enabled);
|
document.body.classList.toggle("motion-disabled", !enabled);
|
||||||
jQuery.fx.off = !enabled;
|
jQuery.fx.off = !enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
#setShadows(enabled: boolean) {
|
#setShadows() {
|
||||||
|
const enabled = options.is("shadowsEnabled");
|
||||||
document.body.classList.toggle("shadows-disabled", !enabled);
|
document.body.classList.toggle("shadows-disabled", !enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
#setBackdropEffects(enabled: boolean) {
|
#setBackdropEffects() {
|
||||||
|
const enabled = options.is("backdropEffectsEnabled");
|
||||||
document.body.classList.toggle("backdrop-effects-disabled", !enabled);
|
document.body.classList.toggle("backdrop-effects-disabled", !enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#setThemeCapabilities() {
|
||||||
|
// Supports background effects
|
||||||
|
|
||||||
|
const useBgfx = readCssVar(document.documentElement, "allow-background-effects")
|
||||||
|
.asBoolean(false);
|
||||||
|
|
||||||
|
document.body.classList.toggle("theme-supports-background-effects", useBgfx);
|
||||||
|
}
|
||||||
|
|
||||||
#setLocaleAndDirection(locale: string) {
|
#setLocaleAndDirection(locale: string) {
|
||||||
const correspondingLocale = LOCALES.find(l => l.id === locale);
|
const correspondingLocale = LOCALES.find(l => l.id === locale);
|
||||||
document.body.lang = locale;
|
document.body.lang = locale;
|
||||||
|
|||||||
@ -57,17 +57,19 @@ const TPL = /*html*/`\
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="modal-dialog modal-lg" role="document">
|
<div class="quick-edit-dialog-wrapper">
|
||||||
<div class="modal-content">
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
<div class="modal-header">
|
<div class="modal-content">
|
||||||
<div class="modal-title">
|
<div class="modal-header">
|
||||||
<!-- This is where the first child will be injected -->
|
<div class="modal-title">
|
||||||
|
<!-- This is where the first child will be injected -->
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<!-- This is where all but the first child will be injected. -->
|
<!-- This is where all but the first child will be injected. -->
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -79,6 +81,7 @@ export default class PopupEditorDialog extends Container<BasicWidget> {
|
|||||||
private noteContext: NoteContext;
|
private noteContext: NoteContext;
|
||||||
private $modalHeader!: JQuery<HTMLElement>;
|
private $modalHeader!: JQuery<HTMLElement>;
|
||||||
private $modalBody!: JQuery<HTMLElement>;
|
private $modalBody!: JQuery<HTMLElement>;
|
||||||
|
private $wrapper!: JQuery<HTMLDivElement>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -93,6 +96,7 @@ export default class PopupEditorDialog extends Container<BasicWidget> {
|
|||||||
const $newWidget = $(TPL);
|
const $newWidget = $(TPL);
|
||||||
this.$modalHeader = $newWidget.find(".modal-title");
|
this.$modalHeader = $newWidget.find(".modal-title");
|
||||||
this.$modalBody = $newWidget.find(".modal-body");
|
this.$modalBody = $newWidget.find(".modal-body");
|
||||||
|
this.$wrapper = $newWidget.find(".quick-edit-dialog-wrapper");
|
||||||
|
|
||||||
const children = this.$widget.children();
|
const children = this.$widget.children();
|
||||||
this.$modalHeader.append(children[0]);
|
this.$modalHeader.append(children[0]);
|
||||||
@ -112,6 +116,21 @@ export default class PopupEditorDialog extends Container<BasicWidget> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const colorClass = this.noteContext.note?.getColorClass();
|
||||||
|
const wrapperElement = this.$wrapper.get(0)!;
|
||||||
|
|
||||||
|
if (colorClass) {
|
||||||
|
wrapperElement.className = "quick-edit-dialog-wrapper " + colorClass;
|
||||||
|
} else {
|
||||||
|
wrapperElement.className = "quick-edit-dialog-wrapper";
|
||||||
|
}
|
||||||
|
|
||||||
|
const customHue = getComputedStyle(wrapperElement).getPropertyValue("--custom-color-hue");
|
||||||
|
if (customHue) {
|
||||||
|
/* Apply the tinted-dialog class only if the custom color CSS class specifies a hue */
|
||||||
|
wrapperElement.classList.add("tinted-quick-edit-dialog");
|
||||||
|
}
|
||||||
|
|
||||||
const activeEl = document.activeElement;
|
const activeEl = document.activeElement;
|
||||||
if (activeEl && "blur" in activeEl) {
|
if (activeEl && "blur" in activeEl) {
|
||||||
(activeEl as HTMLElement).blur();
|
(activeEl as HTMLElement).blur();
|
||||||
|
|||||||
@ -39,10 +39,16 @@ const TPL = /*html*/`
|
|||||||
<div class="note-detail">
|
<div class="note-detail">
|
||||||
<style>
|
<style>
|
||||||
.note-detail {
|
.note-detail {
|
||||||
|
max-width: var(--max-content-width); /* Inherited from .note-split */
|
||||||
font-family: var(--detail-font-family);
|
font-family: var(--detail-font-family);
|
||||||
font-size: var(--detail-font-size);
|
font-size: var(--detail-font-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.prefers-centered-content .note-detail {
|
||||||
|
/* Horizontally center the widget in its parent when the "Keep content centered" option is on */
|
||||||
|
margin-inline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.note-detail.full-height {
|
.note-detail.full-height {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,6 +52,7 @@ export default class NoteWrapperWidget extends FlexContainer<BasicWidget> {
|
|||||||
|
|
||||||
const note = this.noteContext?.note;
|
const note = this.noteContext?.note;
|
||||||
if (!note) {
|
if (!note) {
|
||||||
|
this.$widget.addClass("bgfx");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ export default class NoteWrapperWidget extends FlexContainer<BasicWidget> {
|
|||||||
|
|
||||||
this.$widget.addClass(utils.getNoteTypeClass(note.type));
|
this.$widget.addClass(utils.getNoteTypeClass(note.type));
|
||||||
this.$widget.addClass(utils.getMimeTypeClass(note.mime));
|
this.$widget.addClass(utils.getMimeTypeClass(note.mime));
|
||||||
|
this.$widget.toggleClass(["bgfx", "options"], note.isOptions());
|
||||||
this.$widget.toggleClass("protected", note.isProtected);
|
this.$widget.toggleClass("protected", note.isProtected);
|
||||||
|
|
||||||
const noteLanguage = note?.getLabelValue("language");
|
const noteLanguage = note?.getLabelValue("language");
|
||||||
@ -70,7 +71,7 @@ export default class NoteWrapperWidget extends FlexContainer<BasicWidget> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#isFullWidthNote(note: FNote) {
|
#isFullWidthNote(note: FNote) {
|
||||||
if (["image", "mermaid", "book", "render", "canvas", "webView", "mindMap"].includes(note.type)) {
|
if (["code", "image", "mermaid", "book", "render", "canvas", "webView", "mindMap"].includes(note.type)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
apps/client/src/widgets/react/InfoBar.css
Normal file
21
apps/client/src/widgets/react/InfoBar.css
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
.info-bar {
|
||||||
|
--link-color: var(--main-text-color);
|
||||||
|
|
||||||
|
margin-top: 4px;
|
||||||
|
contain: unset !important;
|
||||||
|
padding: 8px 20px;
|
||||||
|
color: var(--read-only-note-info-bar-color);
|
||||||
|
font-size: .9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-bar-prominent {
|
||||||
|
background: var(--alert-bar-background, var(--accented-background-color));
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-bar-subtle {
|
||||||
|
color: var(--muted-text-color);
|
||||||
|
border-bottom: 1px solid var(--main-border-color);
|
||||||
|
margin-block: 0;
|
||||||
|
margin-inline: 10px;
|
||||||
|
padding-inline: 12px;
|
||||||
|
}
|
||||||
19
apps/client/src/widgets/react/InfoBar.tsx
Normal file
19
apps/client/src/widgets/react/InfoBar.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import "./InfoBar.css";
|
||||||
|
import { ComponentChildren, CSSProperties } from "preact";
|
||||||
|
|
||||||
|
export type InfoBarParams = {
|
||||||
|
type: "prominent" | "subtle",
|
||||||
|
className: string;
|
||||||
|
style: CSSProperties
|
||||||
|
children: ComponentChildren;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function InfoBar(props: InfoBarParams) {
|
||||||
|
return <div className={`info-bar ${props.className} info-bar-${props.type}`} style={props.style}>
|
||||||
|
{props?.children}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoBar.defaultProps = {
|
||||||
|
type: "prominent"
|
||||||
|
} as InfoBarParams
|
||||||
@ -1,25 +1,26 @@
|
|||||||
import { Inputs, MutableRef, useCallback, useContext, useDebugValue, useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks";
|
import { CSSProperties } from "preact/compat";
|
||||||
import { CommandListenerData, EventData, EventNames } from "../../components/app_context";
|
import { DragData } from "../note_tree";
|
||||||
import { ParentComponent } from "./react_utils";
|
|
||||||
import SpacedUpdate from "../../services/spaced_update";
|
|
||||||
import { FilterLabelsByType, KeyboardActionNames, OptionNames, RelationNames } from "@triliumnext/commons";
|
import { FilterLabelsByType, KeyboardActionNames, OptionNames, RelationNames } from "@triliumnext/commons";
|
||||||
import options, { type OptionValue } from "../../services/options";
|
import { Inputs, MutableRef, useCallback, useContext, useDebugValue, useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks";
|
||||||
import utils, { escapeRegExp, reloadFrontendApp } from "../../services/utils";
|
import { ParentComponent } from "./react_utils";
|
||||||
import NoteContext from "../../components/note_context";
|
|
||||||
import BasicWidget, { ReactWrappedWidget } from "../basic_widget";
|
|
||||||
import FNote from "../../entities/fnote";
|
|
||||||
import attributes from "../../services/attributes";
|
|
||||||
import FBlob from "../../entities/fblob";
|
|
||||||
import NoteContextAwareWidget from "../note_context_aware_widget";
|
|
||||||
import { RefObject, VNode } from "preact";
|
import { RefObject, VNode } from "preact";
|
||||||
import { Tooltip } from "bootstrap";
|
import { Tooltip } from "bootstrap";
|
||||||
import { CSSProperties } from "preact/compat";
|
import { ViewMode } from "../../services/link";
|
||||||
|
import appContext, { CommandListenerData, EventData, EventNames } from "../../components/app_context";
|
||||||
|
import attributes from "../../services/attributes";
|
||||||
|
import BasicWidget, { ReactWrappedWidget } from "../basic_widget";
|
||||||
|
import Component from "../../components/component";
|
||||||
|
import FBlob from "../../entities/fblob";
|
||||||
|
import FNote from "../../entities/fnote";
|
||||||
import keyboard_actions from "../../services/keyboard_actions";
|
import keyboard_actions from "../../services/keyboard_actions";
|
||||||
import Mark from "mark.js";
|
import Mark from "mark.js";
|
||||||
import { DragData } from "../note_tree";
|
import NoteContext from "../../components/note_context";
|
||||||
import Component from "../../components/component";
|
import NoteContextAwareWidget from "../note_context_aware_widget";
|
||||||
|
import options, { type OptionValue } from "../../services/options";
|
||||||
|
import protected_session_holder from "../../services/protected_session_holder";
|
||||||
|
import SpacedUpdate from "../../services/spaced_update";
|
||||||
import toast, { ToastOptions } from "../../services/toast";
|
import toast, { ToastOptions } from "../../services/toast";
|
||||||
import { ViewMode } from "../../services/link";
|
import utils, { escapeRegExp, reloadFrontendApp } from "../../services/utils";
|
||||||
|
|
||||||
export function useTriliumEvent<T extends EventNames>(eventName: T, handler: (data: EventData<T>) => void) {
|
export function useTriliumEvent<T extends EventNames>(eventName: T, handler: (data: EventData<T>) => void) {
|
||||||
const parentComponent = useContext(ParentComponent);
|
const parentComponent = useContext(ParentComponent);
|
||||||
@ -701,3 +702,51 @@ export function useResizeObserver(ref: RefObject<HTMLElement>, callback: () => v
|
|||||||
return () => observer.disconnect();
|
return () => observer.disconnect();
|
||||||
}, [ callback, ref ]);
|
}, [ callback, ref ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the current note is in read-only mode, while an editing mode is available,
|
||||||
|
* and provides a way to switch to editing mode.
|
||||||
|
*/
|
||||||
|
export function useIsNoteReadOnly(note: FNote | null | undefined, noteContext: NoteContext | undefined) {
|
||||||
|
const [isReadOnly, setIsReadOnly] = useState<boolean | undefined>(undefined);
|
||||||
|
|
||||||
|
const enableEditing = useCallback(() => {
|
||||||
|
if (noteContext?.viewScope) {
|
||||||
|
noteContext.viewScope.readOnlyTemporarilyDisabled = true;
|
||||||
|
appContext.triggerEvent("readOnlyTemporarilyDisabled", {noteContext});
|
||||||
|
}
|
||||||
|
}, [noteContext]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (note && noteContext) {
|
||||||
|
isNoteReadOnly(note, noteContext).then((readOnly) => {
|
||||||
|
setIsReadOnly(readOnly);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [note, noteContext]);
|
||||||
|
|
||||||
|
useTriliumEvent("readOnlyTemporarilyDisabled", ({noteContext: eventNoteContext}) => {
|
||||||
|
if (noteContext?.ntxId === eventNoteContext.ntxId) {
|
||||||
|
setIsReadOnly(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {isReadOnly, enableEditing};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function isNoteReadOnly(note: FNote, noteContext: NoteContext) {
|
||||||
|
|
||||||
|
if (note.isProtected && !protected_session_holder.isProtectedSessionAvailable()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.is("databaseReadonly")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noteContext.viewScope?.viewMode !== "default" || !await noteContext.isReadOnly()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@ -1,19 +1,20 @@
|
|||||||
import { ConvertToAttachmentResponse } from "@triliumnext/commons";
|
import { ConvertToAttachmentResponse } from "@triliumnext/commons";
|
||||||
import appContext, { CommandNames } from "../../components/app_context";
|
|
||||||
import FNote from "../../entities/fnote"
|
|
||||||
import dialog from "../../services/dialog";
|
|
||||||
import { t } from "../../services/i18n"
|
|
||||||
import server from "../../services/server";
|
|
||||||
import toast from "../../services/toast";
|
|
||||||
import ws from "../../services/ws";
|
|
||||||
import ActionButton from "../react/ActionButton"
|
|
||||||
import Dropdown from "../react/Dropdown";
|
|
||||||
import { FormDropdownDivider, FormListItem } from "../react/FormList";
|
import { FormDropdownDivider, FormListItem } from "../react/FormList";
|
||||||
import { isElectron as getIsElectron, isMac as getIsMac } from "../../services/utils";
|
import { isElectron as getIsElectron, isMac as getIsMac } from "../../services/utils";
|
||||||
import { ParentComponent } from "../react/react_utils";
|
import { ParentComponent } from "../react/react_utils";
|
||||||
|
import { t } from "../../services/i18n"
|
||||||
import { useContext } from "preact/hooks";
|
import { useContext } from "preact/hooks";
|
||||||
import NoteContext from "../../components/note_context";
|
import { useIsNoteReadOnly } from "../react/hooks";
|
||||||
|
import ActionButton from "../react/ActionButton"
|
||||||
|
import appContext, { CommandNames } from "../../components/app_context";
|
||||||
import branches from "../../services/branches";
|
import branches from "../../services/branches";
|
||||||
|
import dialog from "../../services/dialog";
|
||||||
|
import Dropdown from "../react/Dropdown";
|
||||||
|
import FNote from "../../entities/fnote"
|
||||||
|
import NoteContext from "../../components/note_context";
|
||||||
|
import server from "../../services/server";
|
||||||
|
import toast from "../../services/toast";
|
||||||
|
import ws from "../../services/ws";
|
||||||
|
|
||||||
interface NoteActionsProps {
|
interface NoteActionsProps {
|
||||||
note?: FNote;
|
note?: FNote;
|
||||||
@ -52,6 +53,7 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
|
|||||||
const isMac = getIsMac();
|
const isMac = getIsMac();
|
||||||
const hasSource = ["text", "code", "relationMap", "mermaid", "canvas", "mindMap"].includes(note.type);
|
const hasSource = ["text", "code", "relationMap", "mermaid", "canvas", "mindMap"].includes(note.type);
|
||||||
const isSearchOrBook = ["search", "book"].includes(note.type);
|
const isSearchOrBook = ["search", "book"].includes(note.type);
|
||||||
|
const {isReadOnly, enableEditing} = useIsNoteReadOnly(note, noteContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
@ -59,8 +61,14 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
|
|||||||
className="note-actions"
|
className="note-actions"
|
||||||
hideToggleArrow
|
hideToggleArrow
|
||||||
noSelectButtonStyle
|
noSelectButtonStyle
|
||||||
iconAction
|
iconAction>
|
||||||
>
|
|
||||||
|
{isReadOnly && <>
|
||||||
|
<CommandItem icon="bx bx-pencil" text={t("read-only-info.edit-note")}
|
||||||
|
command={() => enableEditing()} />
|
||||||
|
<FormDropdownDivider />
|
||||||
|
</>}
|
||||||
|
|
||||||
{canBeConvertedToAttachment && <ConvertToAttachment note={note} /> }
|
{canBeConvertedToAttachment && <ConvertToAttachment note={note} /> }
|
||||||
{note.type === "render" && <CommandItem command="renderActiveNote" icon="bx bx-extension" text={t("note_actions.re_render_note")} />}
|
{note.type === "render" && <CommandItem command="renderActiveNote" icon="bx bx-extension" text={t("note_actions.re_render_note")} />}
|
||||||
<CommandItem command="findInText" icon="bx bx-search" disabled={!isSearchable} text={t("note_actions.search_in_note")} />
|
<CommandItem command="findInText" icon="bx bx-search" disabled={!isSearchable} text={t("note_actions.search_in_note")} />
|
||||||
|
|||||||
7
apps/client/src/widgets/shared_info.css
Normal file
7
apps/client/src/widgets/shared_info.css
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.shared-info-widget {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-info-widget button {
|
||||||
|
margin-inline-start: 8px;
|
||||||
|
}
|
||||||
@ -1,11 +1,12 @@
|
|||||||
import { useEffect, useState } from "preact/hooks";
|
import "./shared_info.css";
|
||||||
import { t } from "../services/i18n";
|
import { t } from "../services/i18n";
|
||||||
import Alert from "./react/Alert";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
import { useNoteContext, useTriliumEvent, useTriliumOption } from "./react/hooks";
|
import { useNoteContext, useTriliumEvent, useTriliumOption } from "./react/hooks";
|
||||||
import FNote from "../entities/fnote";
|
|
||||||
import attributes from "../services/attributes";
|
import attributes from "../services/attributes";
|
||||||
import RawHtml from "./react/RawHtml";
|
import FNote from "../entities/fnote";
|
||||||
import HelpButton from "./react/HelpButton";
|
import HelpButton from "./react/HelpButton";
|
||||||
|
import InfoBar from "./react/InfoBar";
|
||||||
|
import RawHtml from "./react/RawHtml";
|
||||||
|
|
||||||
export default function SharedInfo() {
|
export default function SharedInfo() {
|
||||||
const { note } = useNoteContext();
|
const { note } = useNoteContext();
|
||||||
@ -35,7 +36,7 @@ export default function SharedInfo() {
|
|||||||
link = `${location.protocol}//${host}${location.pathname}share/${shareId}`;
|
link = `${location.protocol}//${host}${location.pathname}share/${shareId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
setLink(`<a href="${link}" class="external">${link}</a>`);
|
setLink(`<a href="${link}" class="external tn-link">${link}</a>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(refresh, [ note ]);
|
useEffect(refresh, [ note ]);
|
||||||
@ -48,20 +49,14 @@ export default function SharedInfo() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Alert className="shared-info-widget" type="warning" style={{
|
<InfoBar className="shared-info-widget" type="subtle" style={{display: (!link) ? "none" : undefined}}>
|
||||||
contain: "none",
|
|
||||||
margin: "10px",
|
|
||||||
padding: "10px",
|
|
||||||
fontWeight: "bold",
|
|
||||||
display: !link ? "none" : undefined
|
|
||||||
}}>
|
|
||||||
{link && (
|
{link && (
|
||||||
<RawHtml html={syncServerHost
|
<RawHtml html={syncServerHost
|
||||||
? t("shared_info.shared_publicly", { link })
|
? t("shared_info.shared_publicly", { link })
|
||||||
: t("shared_info.shared_locally", { link })} />
|
: t("shared_info.shared_locally", { link })} />
|
||||||
)}
|
)}
|
||||||
<HelpButton helpPage="R9pX4DGra2Vt" style={{ width: "24px", height: "24px" }} />
|
<HelpButton helpPage="R9pX4DGra2Vt" style={{ width: "24px", height: "24px" }} />
|
||||||
</Alert>
|
</InfoBar>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -284,7 +284,8 @@ function SmoothScrollEnabledOption() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function MaxContentWidth() {
|
function MaxContentWidth() {
|
||||||
const [ maxContentWidth, setMaxContentWidth ] = useTriliumOption("maxContentWidth");
|
const [maxContentWidth, setMaxContentWidth] = useTriliumOption("maxContentWidth");
|
||||||
|
const [centerContent, setCenterContent] = useTriliumOptionBool("centerContent");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OptionsSection title={t("max_content_width.title")}>
|
<OptionsSection title={t("max_content_width.title")}>
|
||||||
@ -300,9 +301,9 @@ function MaxContentWidth() {
|
|||||||
</FormGroup>
|
</FormGroup>
|
||||||
</Column>
|
</Column>
|
||||||
|
|
||||||
<p>
|
<FormCheckbox label={t("max_content_width.centerContent")}
|
||||||
{t("max_content_width.apply_changes_description")} <Button text={t("max_content_width.reload_button")} size="micro" onClick={reloadFrontendApp} />
|
currentValue={centerContent}
|
||||||
</p>
|
onChange={setCenterContent} />
|
||||||
</OptionsSection>
|
</OptionsSection>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -97,7 +97,7 @@ function TokenList({ tokens }: { tokens: EtapiToken[] }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
tokens.length ? (
|
tokens.length ? (
|
||||||
<div style={{ overflow: "auto", height: "500px"}}>
|
<div style={{ overflow: "auto"}}>
|
||||||
<table className="table table-stripped">
|
<table className="table table-stripped">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@ -331,6 +331,8 @@
|
|||||||
"calendar-title": "Calendar",
|
"calendar-title": "Calendar",
|
||||||
"recent-changes-title": "Recent Changes",
|
"recent-changes-title": "Recent Changes",
|
||||||
"bookmarks-title": "Bookmarks",
|
"bookmarks-title": "Bookmarks",
|
||||||
|
"command-palette": "Open Command Palette",
|
||||||
|
"zen-mode": "Zen Mode",
|
||||||
"open-today-journal-note-title": "Open Today's Journal Note",
|
"open-today-journal-note-title": "Open Today's Journal Note",
|
||||||
"quick-search-title": "Quick Search",
|
"quick-search-title": "Quick Search",
|
||||||
"protected-session-title": "Protected Session",
|
"protected-session-title": "Protected Session",
|
||||||
|
|||||||
@ -28,12 +28,6 @@
|
|||||||
|
|
||||||
<%- include("./partials/windowGlobal.ejs", locals) %>
|
<%- include("./partials/windowGlobal.ejs", locals) %>
|
||||||
|
|
||||||
<style>
|
|
||||||
.note-split {
|
|
||||||
max-width: <%= maxContentWidth %>px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!-- Required for match the PWA's top bar color with the theme -->
|
<!-- Required for match the PWA's top bar color with the theme -->
|
||||||
<!-- This works even when the user directly changes --root-background in CSS -->
|
<!-- This works even when the user directly changes --root-background in CSS -->
|
||||||
<div id="background-color-tracker" style="position: absolute; visibility: hidden; color: var(--root-background); transition: color 1ms;"></div>
|
<div id="background-color-tracker" style="position: absolute; visibility: hidden; color: var(--root-background); transition: color 1ms;"></div>
|
||||||
|
|||||||
@ -68,6 +68,7 @@ const ALLOWED_OPTIONS = new Set<OptionNames>([
|
|||||||
"smoothScrollEnabled",
|
"smoothScrollEnabled",
|
||||||
"backdropEffectsEnabled",
|
"backdropEffectsEnabled",
|
||||||
"maxContentWidth",
|
"maxContentWidth",
|
||||||
|
"centerContent",
|
||||||
"compressImages",
|
"compressImages",
|
||||||
"downloadImagesAutomatically",
|
"downloadImagesAutomatically",
|
||||||
"minTocHeadings",
|
"minTocHeadings",
|
||||||
|
|||||||
@ -57,7 +57,6 @@ function index(req: Request, res: Response) {
|
|||||||
isDev,
|
isDev,
|
||||||
isMainWindow: view === "mobile" ? true : !req.query.extraWindow,
|
isMainWindow: view === "mobile" ? true : !req.query.extraWindow,
|
||||||
isProtectedSessionAvailable: protectedSessionService.isProtectedSessionAvailable(),
|
isProtectedSessionAvailable: protectedSessionService.isProtectedSessionAvailable(),
|
||||||
maxContentWidth: Math.max(640, parseInt(options.maxContentWidth)),
|
|
||||||
triliumVersion: packageJson.version,
|
triliumVersion: packageJson.version,
|
||||||
assetPath,
|
assetPath,
|
||||||
appPath,
|
appPath,
|
||||||
|
|||||||
@ -44,13 +44,42 @@ export default function buildLaunchBarConfig() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const desktopAvailableLaunchers: HiddenSubtreeItem[] = [
|
const desktopAvailableLaunchers: HiddenSubtreeItem[] = [
|
||||||
{ id: "_lbBackInHistory", ...sharedLaunchers.backInHistory },
|
{
|
||||||
{ id: "_lbForwardInHistory", ...sharedLaunchers.forwardInHistory },
|
id: "_lbBackInHistory",
|
||||||
{ id: "_lbBackendLog", title: t("hidden-subtree.backend-log-title"), type: "launcher", targetNoteId: "_backendLog", icon: "bx bx-terminal" },
|
...sharedLaunchers.backInHistory
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "_lbForwardInHistory",
|
||||||
|
...sharedLaunchers.forwardInHistory
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "_commandPalette",
|
||||||
|
title: t("hidden-subtree.command-palette"),
|
||||||
|
type: "launcher",
|
||||||
|
command: "commandPalette",
|
||||||
|
icon: "bx bx-chevron-right-square"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "_lbBackendLog",
|
||||||
|
title: t("hidden-subtree.backend-log-title"),
|
||||||
|
type: "launcher",
|
||||||
|
targetNoteId: "_backendLog",
|
||||||
|
icon: "bx bx-detail"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "_zenMode",
|
||||||
|
title: t("hidden-subtree.zen-mode"),
|
||||||
|
type: "launcher",
|
||||||
|
command: "toggleZenMode",
|
||||||
|
icon: "bx bxs-yin-yang"
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const desktopVisibleLaunchers: HiddenSubtreeItem[] = [
|
const desktopVisibleLaunchers: HiddenSubtreeItem[] = [
|
||||||
{ id: "_lbNewNote", ...sharedLaunchers.newNote },
|
{
|
||||||
|
id: "_lbNewNote",
|
||||||
|
...sharedLaunchers.newNote
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "_lbSearch",
|
id: "_lbSearch",
|
||||||
title: t("hidden-subtree.search-notes-title"),
|
title: t("hidden-subtree.search-notes-title"),
|
||||||
@ -67,7 +96,12 @@ export default function buildLaunchBarConfig() {
|
|||||||
icon: "bx bx-send",
|
icon: "bx bx-send",
|
||||||
attributes: [{ type: "label", name: "desktopOnly" }]
|
attributes: [{ type: "label", name: "desktopOnly" }]
|
||||||
},
|
},
|
||||||
{ id: "_lbNoteMap", title: t("hidden-subtree.note-map-title"), type: "launcher", targetNoteId: "_globalNoteMap", icon: "bx bxs-network-chart" },
|
{ id: "_lbNoteMap",
|
||||||
|
title: t("hidden-subtree.note-map-title"),
|
||||||
|
type: "launcher",
|
||||||
|
targetNoteId: "_globalNoteMap",
|
||||||
|
icon: "bx bxs-network-chart"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "_lbLlmChat",
|
id: "_lbLlmChat",
|
||||||
title: t("hidden-subtree.llm-chat-title"),
|
title: t("hidden-subtree.llm-chat-title"),
|
||||||
@ -78,12 +112,41 @@ export default function buildLaunchBarConfig() {
|
|||||||
{ type: "label", name: "desktopOnly" }
|
{ type: "label", name: "desktopOnly" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ id: "_lbCalendar", ...sharedLaunchers.calendar },
|
{
|
||||||
{ id: "_lbRecentChanges", ...sharedLaunchers.recentChanges },
|
id: "_lbCalendar",
|
||||||
{ id: "_lbSpacer1", title: t("hidden-subtree.spacer-title"), type: "launcher", builtinWidget: "spacer", baseSize: "50", growthFactor: "0" },
|
...sharedLaunchers.calendar
|
||||||
{ id: "_lbBookmarks", title: t("hidden-subtree.bookmarks-title"), type: "launcher", builtinWidget: "bookmarks", icon: "bx bx-bookmark" },
|
},
|
||||||
{ id: "_lbToday", ...sharedLaunchers.openToday },
|
{
|
||||||
{ id: "_lbSpacer2", title: t("hidden-subtree.spacer-title"), type: "launcher", builtinWidget: "spacer", baseSize: "0", growthFactor: "1" },
|
id: "_lbRecentChanges",
|
||||||
|
...sharedLaunchers.recentChanges
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "_lbSpacer1",
|
||||||
|
title: t("hidden-subtree.spacer-title"),
|
||||||
|
type: "launcher",
|
||||||
|
builtinWidget: "spacer",
|
||||||
|
baseSize: "50",
|
||||||
|
growthFactor: "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "_lbBookmarks",
|
||||||
|
title: t("hidden-subtree.bookmarks-title"),
|
||||||
|
type: "launcher",
|
||||||
|
builtinWidget: "bookmarks",
|
||||||
|
icon: "bx bx-bookmark"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "_lbToday",
|
||||||
|
...sharedLaunchers.openToday
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "_lbSpacer2",
|
||||||
|
title: t("hidden-subtree.spacer-title"),
|
||||||
|
type: "launcher",
|
||||||
|
builtinWidget: "spacer",
|
||||||
|
baseSize: "0",
|
||||||
|
growthFactor: "1"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "_lbQuickSearch",
|
id: "_lbQuickSearch",
|
||||||
title: t("hidden-subtree.quick-search-title"),
|
title: t("hidden-subtree.quick-search-title"),
|
||||||
@ -92,9 +155,26 @@ export default function buildLaunchBarConfig() {
|
|||||||
icon: "bx bx-rectangle",
|
icon: "bx bx-rectangle",
|
||||||
attributes: [{ type: "label", name: "docName", value: "launchbar_quick_search" }]
|
attributes: [{ type: "label", name: "docName", value: "launchbar_quick_search" }]
|
||||||
},
|
},
|
||||||
{ id: "_lbProtectedSession", title: t("hidden-subtree.protected-session-title"), type: "launcher", builtinWidget: "protectedSession", icon: "bx bx bx-shield-quarter" },
|
{
|
||||||
{ id: "_lbSyncStatus", title: t("hidden-subtree.sync-status-title"), type: "launcher", builtinWidget: "syncStatus", icon: "bx bx-wifi" },
|
id: "_lbProtectedSession",
|
||||||
{ id: "_lbSettings", title: t("hidden-subtree.settings-title"), type: "launcher", command: "showOptions", icon: "bx bx-cog" }
|
title: t("hidden-subtree.protected-session-title"),
|
||||||
|
type: "launcher", builtinWidget: "protectedSession",
|
||||||
|
icon: "bx bx bx-shield-quarter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "_lbSyncStatus",
|
||||||
|
title: t("hidden-subtree.sync-status-title"),
|
||||||
|
type: "launcher",
|
||||||
|
builtinWidget: "syncStatus",
|
||||||
|
icon: "bx bx-wifi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "_lbSettings",
|
||||||
|
title: t("hidden-subtree.settings-title"),
|
||||||
|
type: "launcher",
|
||||||
|
command: "showOptions",
|
||||||
|
icon: "bx bx-cog"
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const mobileAvailableLaunchers: HiddenSubtreeItem[] = [
|
const mobileAvailableLaunchers: HiddenSubtreeItem[] = [
|
||||||
@ -103,11 +183,29 @@ export default function buildLaunchBarConfig() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const mobileVisibleLaunchers: HiddenSubtreeItem[] = [
|
const mobileVisibleLaunchers: HiddenSubtreeItem[] = [
|
||||||
{ id: "_lbMobileBackInHistory", ...sharedLaunchers.backInHistory },
|
{
|
||||||
{ id: "_lbMobileForwardInHistory", ...sharedLaunchers.forwardInHistory },
|
id: "_lbMobileBackInHistory",
|
||||||
{ id: "_lbMobileJumpTo", title: t("hidden-subtree.jump-to-note-title"), type: "launcher", command: "jumpToNote", icon: "bx bx-plus-circle" },
|
...sharedLaunchers.backInHistory
|
||||||
{ id: "_lbMobileCalendar", ...sharedLaunchers.calendar },
|
},
|
||||||
{ id: "_lbMobileRecentChanges", ...sharedLaunchers.recentChanges }
|
{
|
||||||
|
id: "_lbMobileForwardInHistory",
|
||||||
|
...sharedLaunchers.forwardInHistory
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "_lbMobileJumpTo",
|
||||||
|
title: t("hidden-subtree.jump-to-note-title"),
|
||||||
|
type: "launcher",
|
||||||
|
command: "jumpToNote",
|
||||||
|
icon: "bx bx-plus-circle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "_lbMobileCalendar",
|
||||||
|
...sharedLaunchers.calendar
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "_lbMobileRecentChanges",
|
||||||
|
...sharedLaunchers.recentChanges
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -116,4 +214,4 @@ export default function buildLaunchBarConfig() {
|
|||||||
mobileAvailableLaunchers,
|
mobileAvailableLaunchers,
|
||||||
mobileVisibleLaunchers
|
mobileVisibleLaunchers
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -111,12 +111,13 @@ const defaultOptions: DefaultOption[] = [
|
|||||||
{ name: "debugModeEnabled", value: "false", isSynced: false },
|
{ name: "debugModeEnabled", value: "false", isSynced: false },
|
||||||
{ name: "headingStyle", value: "underline", isSynced: true },
|
{ name: "headingStyle", value: "underline", isSynced: true },
|
||||||
{ name: "autoCollapseNoteTree", value: "true", isSynced: true },
|
{ name: "autoCollapseNoteTree", value: "true", isSynced: true },
|
||||||
{ name: "autoReadonlySizeText", value: "10000", isSynced: false },
|
{ name: "autoReadonlySizeText", value: "32000", isSynced: false },
|
||||||
{ name: "autoReadonlySizeCode", value: "30000", isSynced: false },
|
{ name: "autoReadonlySizeCode", value: "64000", isSynced: false },
|
||||||
{ name: "dailyBackupEnabled", value: "true", isSynced: false },
|
{ name: "dailyBackupEnabled", value: "true", isSynced: false },
|
||||||
{ name: "weeklyBackupEnabled", value: "true", isSynced: false },
|
{ name: "weeklyBackupEnabled", value: "true", isSynced: false },
|
||||||
{ name: "monthlyBackupEnabled", value: "true", isSynced: false },
|
{ name: "monthlyBackupEnabled", value: "true", isSynced: false },
|
||||||
{ name: "maxContentWidth", value: "1200", isSynced: false },
|
{ name: "maxContentWidth", value: "1200", isSynced: false },
|
||||||
|
{ name: "centerContent", value: "false", isSynced: false },
|
||||||
{ name: "compressImages", value: "true", isSynced: true },
|
{ name: "compressImages", value: "true", isSynced: true },
|
||||||
{ name: "downloadImagesAutomatically", value: "true", isSynced: true },
|
{ name: "downloadImagesAutomatically", value: "true", isSynced: true },
|
||||||
{ name: "minTocHeadings", value: "5", isSynced: true },
|
{ name: "minTocHeadings", value: "5", isSynced: true },
|
||||||
|
|||||||
@ -6,7 +6,9 @@ enum Command {
|
|||||||
createNoteIntoInbox,
|
createNoteIntoInbox,
|
||||||
showRecentChanges,
|
showRecentChanges,
|
||||||
showOptions,
|
showOptions,
|
||||||
createAiChat
|
createAiChat,
|
||||||
|
commandPalette,
|
||||||
|
toggleZenMode
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HiddenSubtreeAttribute {
|
export interface HiddenSubtreeAttribute {
|
||||||
@ -41,7 +43,9 @@ export interface HiddenSubtreeItem {
|
|||||||
| "protectedSession"
|
| "protectedSession"
|
||||||
| "calendar"
|
| "calendar"
|
||||||
| "quickSearch"
|
| "quickSearch"
|
||||||
| "aiChatLauncher";
|
| "aiChatLauncher"
|
||||||
|
| "commandPalette"
|
||||||
|
| "toggleZenMode";
|
||||||
command?: keyof typeof Command;
|
command?: keyof typeof Command;
|
||||||
/**
|
/**
|
||||||
* If set to true, then branches will be enforced to be in the correct place.
|
* If set to true, then branches will be enforced to be in the correct place.
|
||||||
|
|||||||
@ -82,6 +82,7 @@ export interface OptionDefinitions extends KeyboardShortcutsOptions<KeyboardActi
|
|||||||
autoReadonlySizeText: number;
|
autoReadonlySizeText: number;
|
||||||
autoReadonlySizeCode: number;
|
autoReadonlySizeCode: number;
|
||||||
maxContentWidth: number;
|
maxContentWidth: number;
|
||||||
|
centerContent: boolean;
|
||||||
minTocHeadings: number;
|
minTocHeadings: number;
|
||||||
eraseUnusedAttachmentsAfterSeconds: number;
|
eraseUnusedAttachmentsAfterSeconds: number;
|
||||||
eraseUnusedAttachmentsAfterTimeScale: number;
|
eraseUnusedAttachmentsAfterTimeScale: number;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user