From d247edd87055b21305c9c96ef11e9be82fd21ec8 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 29 Nov 2025 21:02:53 +0200 Subject: [PATCH 001/118] feat(mobile/split): add split container to layout --- apps/client/src/layouts/mobile_layout.tsx | 57 ++++++++++++----------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/apps/client/src/layouts/mobile_layout.tsx b/apps/client/src/layouts/mobile_layout.tsx index 7a177d23b..0c2b3e7ea 100644 --- a/apps/client/src/layouts/mobile_layout.tsx +++ b/apps/client/src/layouts/mobile_layout.tsx @@ -29,6 +29,7 @@ import type AppContext from "../components/app_context.js"; import NoteDetail from "../widgets/NoteDetail.jsx"; import MobileEditorToolbar from "../widgets/type_widgets/text/mobile_editor_toolbar.jsx"; import PromotedAttributes from "../widgets/PromotedAttributes.jsx"; +import SplitNoteContainer from "../widgets/containers/split_note_container.js"; const MOBILE_CSS = ` `); registeredClasses.add(className); - if (hue) { + if (hue !== undefined) { colorsWithHue.add(className); } } From 66f2d0c7dcd40454fd95163279eb8067d56b8dc1 Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Sun, 30 Nov 2025 19:46:15 +0200 Subject: [PATCH 028/118] style/note colors: use a more elegant way to retrieve the theme-aware note color --- apps/client/src/services/css_class_manager.ts | 2 +- apps/client/src/stylesheets/theme-dark.css | 3 +++ apps/client/src/stylesheets/theme-light.css | 4 ++++ apps/client/src/stylesheets/theme-next-dark.css | 4 ++++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/client/src/services/css_class_manager.ts b/apps/client/src/services/css_class_manager.ts index 510a044d6..f22dbf437 100644 --- a/apps/client/src/services/css_class_manager.ts +++ b/apps/client/src/services/css_class_manager.ts @@ -44,7 +44,7 @@ function createClassForColor(colorString: string | null) { } } - return clsx(className, colorsWithHue.has(className) && "with-hue"); + return clsx("use-note-color", className, colorsWithHue.has(className) && "with-hue"); } function parseColor(color: string) { diff --git a/apps/client/src/stylesheets/theme-dark.css b/apps/client/src/stylesheets/theme-dark.css index a356d32fd..0354e3346 100644 --- a/apps/client/src/stylesheets/theme-dark.css +++ b/apps/client/src/stylesheets/theme-dark.css @@ -109,3 +109,6 @@ body .todo-list input[type="checkbox"]:not(:checked):before { box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.6) !important; } +.use-note-color { + --custom-color: var(--dark-theme-custom-color); +} \ No newline at end of file diff --git a/apps/client/src/stylesheets/theme-light.css b/apps/client/src/stylesheets/theme-light.css index 872e7431f..0208ed97c 100644 --- a/apps/client/src/stylesheets/theme-light.css +++ b/apps/client/src/stylesheets/theme-light.css @@ -91,4 +91,8 @@ html { .ck-content a.reference-link > span, .board-note { color: var(--light-theme-custom-color, inherit); +} + +.use-note-color { + --custom-color: var(--light-theme-custom-color); } \ No newline at end of file diff --git a/apps/client/src/stylesheets/theme-next-dark.css b/apps/client/src/stylesheets/theme-next-dark.css index 72271ad2e..a02bedc2c 100644 --- a/apps/client/src/stylesheets/theme-next-dark.css +++ b/apps/client/src/stylesheets/theme-next-dark.css @@ -308,4 +308,8 @@ body .todo-list input[type="checkbox"]:not(:checked):before { --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%); +} + +.use-note-color { + --custom-color: var(--dark-theme-custom-color); } \ No newline at end of file From aacd92eee38b68128fa82c44d96258096bf3412a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 30 Nov 2025 19:47:17 +0200 Subject: [PATCH 029/118] chore(popup-editor): implement switch to full editor button --- apps/client/src/translations/en/translation.json | 3 +++ apps/client/src/widgets/dialogs/PopupEditor.tsx | 11 +++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/client/src/translations/en/translation.json b/apps/client/src/translations/en/translation.json index 514301594..c1a509944 100644 --- a/apps/client/src/translations/en/translation.json +++ b/apps/client/src/translations/en/translation.json @@ -2107,5 +2107,8 @@ "clear-color": "Clear note color", "set-color": "Set note color", "set-custom-color": "Set custom note color" + }, + "popup-editor": { + "maximize": "Switch to full editor" } } diff --git a/apps/client/src/widgets/dialogs/PopupEditor.tsx b/apps/client/src/widgets/dialogs/PopupEditor.tsx index 0d158f828..c85dcd3b3 100644 --- a/apps/client/src/widgets/dialogs/PopupEditor.tsx +++ b/apps/client/src/widgets/dialogs/PopupEditor.tsx @@ -19,6 +19,8 @@ import tree from "../../services/tree"; import froca from "../../services/froca"; import ReadOnlyNoteInfoBar from "../ReadOnlyNoteInfoBar"; import MobileEditorToolbar from "../type_widgets/text/mobile_editor_toolbar"; +import { t } from "../../services/i18n"; +import appContext from "../../components/app_context"; export default function PopupEditor() { const [ shown, setShown ] = useState(false); @@ -62,8 +64,13 @@ export default function PopupEditor() { title={} customTitleBarButtons={[{ iconClassName: "bx-expand-alt", - title: "Switch to full editor", - onClick: () => {/* TO DO */} + title: t("popup-editor.maximize"), + onClick: async () => { + if (!noteContext.noteId) return; + const { noteId, hoistedNoteId } = noteContext; + await appContext.tabManager.openInNewTab(noteId, hoistedNoteId, true); + setShown(false); + } }]} className="popup-editor-dialog" size="lg" From 7779acc7bcde4aebade6db670d306a1bc1c77711 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 30 Nov 2025 19:55:40 +0200 Subject: [PATCH 030/118] refactor(client): split revisions CSS into file --- apps/client/src/stylesheets/style.css | 40 ------------------ apps/client/src/widgets/dialogs/revisions.css | 41 +++++++++++++++++++ apps/client/src/widgets/dialogs/revisions.tsx | 1 + 3 files changed, 42 insertions(+), 40 deletions(-) create mode 100644 apps/client/src/widgets/dialogs/revisions.css diff --git a/apps/client/src/stylesheets/style.css b/apps/client/src/stylesheets/style.css index ea55db041..5db4b1582 100644 --- a/apps/client/src/stylesheets/style.css +++ b/apps/client/src/stylesheets/style.css @@ -1686,46 +1686,6 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu { body.mobile .modal-dialog.modal-dialog-scrollable { height: unset; } - - body.mobile .revisions-dialog .modal-dialog { - height: 95vh; - } - - body.mobile .revisions-dialog .modal-body { - height: 100% !important; - flex-direction: column; - padding: 0; - } - - body.mobile .revisions-dialog .revision-list { - height: unset; - max-height: 20vh; - border-bottom: 1px solid var(--main-border-color) !important; - padding: 0 1em; - } - - body.mobile .revisions-dialog .modal-body > .revision-content-wrapper { - flex-grow: 1; - height: 100%; - overflow: auto; - margin: 0; - } - - body.mobile .revisions-dialog .modal-body > .revision-content-wrapper > div:first-of-type { - flex-direction: column; - } - - body.mobile .revisions-dialog .revision-title { - font-size: 1rem; - } - - body.mobile .revisions-dialog .revision-title-buttons { - text-align: center; - } - - body.mobile .revisions-dialog .revision-content { - padding: 0.5em; - } } /* Mobile, tablet mode */ diff --git a/apps/client/src/widgets/dialogs/revisions.css b/apps/client/src/widgets/dialogs/revisions.css new file mode 100644 index 000000000..91c3af11c --- /dev/null +++ b/apps/client/src/widgets/dialogs/revisions.css @@ -0,0 +1,41 @@ +body.mobile .revisions-dialog { + .modal-dialog { + height: 95vh; + } + + .modal-body { + height: 100% !important; + flex-direction: column; + padding: 0; + } + + .revision-list { + height: unset; + max-height: 20vh; + border-bottom: 1px solid var(--main-border-color) !important; + padding: 0 1em; + } + + .modal-body > .revision-content-wrapper { + flex-grow: 1; + height: 100%; + overflow: auto; + margin: 0; + } + + .modal-body > .revision-content-wrapper > div:first-of-type { + flex-direction: column; + } + + .revision-title { + font-size: 1rem; + } + + .revision-title-buttons { + text-align: center; + } + + .revision-content { + padding: 0.5em; + } +} \ No newline at end of file diff --git a/apps/client/src/widgets/dialogs/revisions.tsx b/apps/client/src/widgets/dialogs/revisions.tsx index e20c4c978..fd2dd9a16 100644 --- a/apps/client/src/widgets/dialogs/revisions.tsx +++ b/apps/client/src/widgets/dialogs/revisions.tsx @@ -20,6 +20,7 @@ import ActionButton from "../react/ActionButton"; import options from "../../services/options"; import { useTriliumEvent } from "../react/hooks"; import { diffWords } from "diff"; +import "./revisions.css"; export default function RevisionsDialog() { const [ note, setNote ] = useState(); From 63f9006d177f1c9a642eb156cf05ad870f9f65c6 Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Sun, 30 Nov 2025 20:08:24 +0200 Subject: [PATCH 031/118] style/calendar collection: improve the support for colored notes --- .../src/stylesheets/theme-next-dark.css | 5 ++++ .../src/stylesheets/theme-next-light.css | 5 ++++ .../collections/calendar/event_builder.ts | 4 ++- .../widgets/collections/calendar/index.css | 28 ++++++++++++++++++- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/apps/client/src/stylesheets/theme-next-dark.css b/apps/client/src/stylesheets/theme-next-dark.css index a02bedc2c..28f42c218 100644 --- a/apps/client/src/stylesheets/theme-next-dark.css +++ b/apps/client/src/stylesheets/theme-next-dark.css @@ -270,6 +270,11 @@ --ck-editor-toolbar-button-on-color: white; --ck-editor-toolbar-button-on-shadow: 1px 1px 2px rgba(0, 0, 0, .75); --ck-editor-toolbar-dropdown-button-open-background: #ffffff14; + + --calendar-coll-event-background-saturation: 12%; + --calendar-coll-event-background-lightness: 21%; + --calendar-coll-event-text-color: white; + --calendar-cell-event-hover-filter: brightness(1.25); } /* diff --git a/apps/client/src/stylesheets/theme-next-light.css b/apps/client/src/stylesheets/theme-next-light.css index 780d519f7..9fe9b53fe 100644 --- a/apps/client/src/stylesheets/theme-next-light.css +++ b/apps/client/src/stylesheets/theme-next-light.css @@ -268,6 +268,11 @@ --ck-editor-toolbar-button-on-color: black; --ck-editor-toolbar-button-on-shadow: none; --ck-editor-toolbar-dropdown-button-open-background: #0000000f; + + --calendar-coll-event-background-lightness: 95%; + --calendar-coll-event-background-saturation: 80%; + --calendar-coll-event-text-color: black; + --calendar-cell-event-hover-filter: brightness(.95) saturate(1.25); } #left-pane .fancytree-node.tinted { diff --git a/apps/client/src/widgets/collections/calendar/event_builder.ts b/apps/client/src/widgets/collections/calendar/event_builder.ts index 8687dc6d9..2d884f8fe 100644 --- a/apps/client/src/widgets/collections/calendar/event_builder.ts +++ b/apps/client/src/widgets/collections/calendar/event_builder.ts @@ -3,6 +3,7 @@ import froca from "../../../services/froca"; import { formatDateToLocalISO, getCustomisableLabel, getMonthsInDateRange, offsetDate } from "./utils"; import FNote from "../../../entities/fnote"; import server from "../../../services/server"; +import clsx from "clsx"; interface Event { startDate: string, @@ -81,6 +82,7 @@ export async function buildEvent(note: FNote, { startDate, endDate, startTime, e const customTitleAttributeName = note.getLabelValue("calendar:title"); const titles = await parseCustomTitle(customTitleAttributeName, note); const color = note.getLabelValue("calendar:color") ?? note.getLabelValue("color"); + const colorClass = note.getColorClass(); const events: EventInput[] = []; const calendarDisplayedAttributes = note.getLabelValue("calendar:displayedAttributes")?.split(","); @@ -111,7 +113,7 @@ export async function buildEvent(note: FNote, { startDate, endDate, startTime, e color: color ?? undefined, iconClass: note.getLabelValue("iconClass"), promotedAttributes: displayedAttributesData, - className: isArchived ? "archived" : "" + className: clsx({archived: isArchived}, colorClass) }; if (endDate) { eventData.end = endDate; diff --git a/apps/client/src/widgets/collections/calendar/index.css b/apps/client/src/widgets/collections/calendar/index.css index 5dd836fe6..b950cd8d4 100644 --- a/apps/client/src/widgets/collections/calendar/index.css +++ b/apps/client/src/widgets/collections/calendar/index.css @@ -75,4 +75,30 @@ body.desktop:not(.zen) .calendar-view .calendar-header { .search-result-widget-content .calendar-view .calendar-header { padding-inline-end: unset !important; } -/* #endregion */ \ No newline at end of file +/* #endregion */ + +.calendar-view { + --fc-event-text-color: var(--calendar-coll-event-text-color); +} + +.calendar-view a.fc-timegrid-event, +.calendar-view a.fc-daygrid-event { + font-weight: 500; +} + +.calendar-view a.fc-timegrid-event:hover, +.calendar-view a.fc-daygrid-event:hover { + text-decoration: none; + filter: var(--calendar-cell-event-hover-filter); +} + +.fc-timegrid-event.with-hue, .fc-daygrid-event:not(.fc-daygrid-dot-event).with-hue { + --fc-event-text-color: var(--custom-color); + + border: unset; + border-left: 4px solid; + padding-left: 8px; + background: hsl(var(--custom-color-hue), + var(--calendar-coll-event-background-saturation), + var(--calendar-coll-event-background-lightness)) !important; +} \ No newline at end of file From 11618260cf6ab0201dd3ff0a4a3b0c63a9719410 Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Sun, 30 Nov 2025 20:18:16 +0200 Subject: [PATCH 032/118] style/calendar collection: tweak the appearance of events without a color --- apps/client/src/stylesheets/theme-next-dark.css | 1 + apps/client/src/stylesheets/theme-next-light.css | 1 + apps/client/src/widgets/collections/calendar/index.css | 10 ++++++---- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/client/src/stylesheets/theme-next-dark.css b/apps/client/src/stylesheets/theme-next-dark.css index 28f42c218..1565fe1e8 100644 --- a/apps/client/src/stylesheets/theme-next-dark.css +++ b/apps/client/src/stylesheets/theme-next-dark.css @@ -273,6 +273,7 @@ --calendar-coll-event-background-saturation: 12%; --calendar-coll-event-background-lightness: 21%; + --calendar-coll-event-background-color: #3c3c3c; --calendar-coll-event-text-color: white; --calendar-cell-event-hover-filter: brightness(1.25); } diff --git a/apps/client/src/stylesheets/theme-next-light.css b/apps/client/src/stylesheets/theme-next-light.css index 9fe9b53fe..423ef8d52 100644 --- a/apps/client/src/stylesheets/theme-next-light.css +++ b/apps/client/src/stylesheets/theme-next-light.css @@ -271,6 +271,7 @@ --calendar-coll-event-background-lightness: 95%; --calendar-coll-event-background-saturation: 80%; + --calendar-coll-event-background-color: #eaeaea; --calendar-coll-event-text-color: black; --calendar-cell-event-hover-filter: brightness(.95) saturate(1.25); } diff --git a/apps/client/src/widgets/collections/calendar/index.css b/apps/client/src/widgets/collections/calendar/index.css index b950cd8d4..60886f716 100644 --- a/apps/client/src/widgets/collections/calendar/index.css +++ b/apps/client/src/widgets/collections/calendar/index.css @@ -79,25 +79,27 @@ body.desktop:not(.zen) .calendar-view .calendar-header { .calendar-view { --fc-event-text-color: var(--calendar-coll-event-text-color); + --fc-event-bg-color: var(--calendar-coll-event-background-color); } .calendar-view a.fc-timegrid-event, .calendar-view a.fc-daygrid-event { + border: unset; + border-left: 4px solid; + padding-left: 8px; font-weight: 500; } .calendar-view a.fc-timegrid-event:hover, .calendar-view a.fc-daygrid-event:hover { - text-decoration: none; + text-decoration: none; + border-color: var(--fc-event-text-color); filter: var(--calendar-cell-event-hover-filter); } .fc-timegrid-event.with-hue, .fc-daygrid-event:not(.fc-daygrid-dot-event).with-hue { --fc-event-text-color: var(--custom-color); - border: unset; - border-left: 4px solid; - padding-left: 8px; background: hsl(var(--custom-color-hue), var(--calendar-coll-event-background-saturation), var(--calendar-coll-event-background-lightness)) !important; From 5ff77c16abca59a5a65fd8d38ba366c8240ac4a4 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 30 Nov 2025 21:13:07 +0200 Subject: [PATCH 033/118] feat(revisions): improve layout on mobile --- apps/client/src/widgets/dialogs/revisions.css | 22 ++++++++++++++++++- apps/client/src/widgets/dialogs/revisions.tsx | 2 +- apps/client/src/widgets/react/FormList.tsx | 6 +++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/apps/client/src/widgets/dialogs/revisions.css b/apps/client/src/widgets/dialogs/revisions.css index 91c3af11c..5528ac368 100644 --- a/apps/client/src/widgets/dialogs/revisions.css +++ b/apps/client/src/widgets/dialogs/revisions.css @@ -2,15 +2,31 @@ body.mobile .revisions-dialog { .modal-dialog { height: 95vh; } + + .modal-header { + display: flex; + flex-wrap: wrap; + gap: 0.25em; + font-size: 0.9em; + } + + .modal-title { + flex-grow: 1; + width: 100%; + } .modal-body { height: 100% !important; flex-direction: column; padding: 0; } + + .modal-footer { + font-size: 0.9em; + } .revision-list { - height: unset; + height: fit-content !important; max-height: 20vh; border-bottom: 1px solid var(--main-border-color) !important; padding: 0 1em; @@ -18,6 +34,7 @@ body.mobile .revisions-dialog { .modal-body > .revision-content-wrapper { flex-grow: 1; + max-width: unset !important; height: 100%; overflow: auto; margin: 0; @@ -33,6 +50,9 @@ body.mobile .revisions-dialog { .revision-title-buttons { text-align: center; + display: flex; + gap: 0.25em; + flex-wrap: wrap; } .revision-content { diff --git a/apps/client/src/widgets/dialogs/revisions.tsx b/apps/client/src/widgets/dialogs/revisions.tsx index fd2dd9a16..322abdd3b 100644 --- a/apps/client/src/widgets/dialogs/revisions.tsx +++ b/apps/client/src/widgets/dialogs/revisions.tsx @@ -138,7 +138,7 @@ export default function RevisionsDialog() { function RevisionsList({ revisions, onSelect, currentRevision }: { revisions: RevisionItem[], onSelect: (val: string) => void, currentRevision?: RevisionItem }) { return ( - + {revisions.map((item) => void; style?: CSSProperties; + wrapperClassName?: string; fullHeight?: boolean; } -export default function FormList({ children, onSelect, style, fullHeight }: FormListOpts) { +export default function FormList({ children, onSelect, style, fullHeight, wrapperClassName }: FormListOpts) { const wrapperRef = useRef(null); const triggerRef = useRef(null); @@ -43,7 +45,7 @@ export default function FormList({ children, onSelect, style, fullHeight }: Form }, [ fullHeight ]); return ( -
+