mirror of
https://github.com/zadam/trilium.git
synced 2025-11-26 10:34:25 +01:00
fix(text): classic toolbar broken on mobile due to prior change
This commit is contained in:
parent
c76f368fa0
commit
9b3ca65492
@ -10,16 +10,21 @@ import { TabContext } from "./ribbon-interface";
|
||||
* The ribbon item is active by default for text notes, as long as they are not in read-only mode.
|
||||
*
|
||||
* ! The toolbar is not only used in the ribbon, but also in the quick edit feature.
|
||||
* * The mobile toolbar is handled separately (see `MobileEditorToolbar`).
|
||||
*/
|
||||
export default function FormattingToolbar({ hidden, ntxId }: TabContext) {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [ textNoteEditorType ] = useTriliumOption("textNoteEditorType");
|
||||
|
||||
// Attach the toolbar from the CKEditor.
|
||||
useTriliumEvent("textEditorRefreshed", ({ ntxId: eventNtxId, editor }) => {
|
||||
if (eventNtxId !== ntxId) return;
|
||||
if (eventNtxId !== ntxId || !containerRef.current) return;
|
||||
const toolbar = editor.ui.view.toolbar?.element;
|
||||
if (toolbar && containerRef.current) {
|
||||
|
||||
if (toolbar) {
|
||||
containerRef.current.replaceChildren(toolbar);
|
||||
} else {
|
||||
containerRef.current.replaceChildren();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -233,12 +233,6 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext
|
||||
onWatchdogStateChange={onWatchdogStateChange}
|
||||
onChange={() => spacedUpdate.scheduleUpdate()}
|
||||
onEditorInitialized={(editor) => {
|
||||
console.log("Editor has been initialized!", parentComponent, editor);
|
||||
|
||||
if (isClassicEditor) {
|
||||
setupClassicEditor(editor, parentComponent);
|
||||
}
|
||||
|
||||
if (hasTouchBar) {
|
||||
const handler = () => refreshTouchBarRef.current?.();
|
||||
for (const event of [ "bold", "italic", "underline", "paragraph", "heading" ]) {
|
||||
@ -303,26 +297,6 @@ function onNotificationWarning(data, evt) {
|
||||
evt.stop();
|
||||
}
|
||||
|
||||
function setupClassicEditor(editor: CKTextEditor, parentComponent: Component | undefined) {
|
||||
if (!parentComponent) return;
|
||||
|
||||
if (utils.isMobile()) {
|
||||
// Reposition all dropdowns to point upwards instead of downwards.
|
||||
// See https://ckeditor.com/docs/ckeditor5/latest/examples/framework/bottom-toolbar-editor.html for more info.
|
||||
const toolbarView = (editor as ClassicEditor).ui.view.toolbar;
|
||||
for (const item of toolbarView.items) {
|
||||
if (!("panelView" in item)) continue;
|
||||
|
||||
item.on("change:isOpen", () => {
|
||||
if (!("isOpen" in item) || !item.isOpen) return;
|
||||
|
||||
// @ts-ignore
|
||||
item.panelView.position = item.panelView.position.replace("s", "n");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function EditableTextTouchBar({ watchdogRef, refreshTouchBarRef }: { watchdogRef: RefObject<EditorWatchdog | null>, refreshTouchBarRef: RefObject<() => void> }) {
|
||||
const [ headingSelectedIndex, setHeadingSelectedIndex ] = useState<number>();
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { MutableRef, useCallback, useEffect, useRef, useState } from "preact/hooks";
|
||||
import { useNoteContext } from "../../react/hooks";
|
||||
import { useNoteContext, useTriliumEvent } from "../../react/hooks";
|
||||
import "./mobile_editor_toolbar.css";
|
||||
import { isIOS } from "../../../services/utils";
|
||||
import { CKTextEditor, ClassicEditor } from "@triliumnext/ckeditor5";
|
||||
|
||||
/**
|
||||
* Handles the editing toolbar for CKEditor in mobile mode. The toolbar acts as a floating bar, with two different mechanism:
|
||||
@ -10,12 +11,12 @@ import { isIOS } from "../../../services/utils";
|
||||
* - On Android, the viewport change makes the keyboard resize the content area, all we have to do is to hide the tab bar and global menu (handled in the global style).
|
||||
*/
|
||||
export default function MobileEditorToolbar() {
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
const { note, noteContext } = useNoteContext();
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const { note, noteContext, ntxId } = useNoteContext();
|
||||
const [ shouldDisplay, setShouldDisplay ] = useState(false);
|
||||
const [ dropdownActive, setDropdownActive ] = useState(false);
|
||||
|
||||
usePositioningOniOS(wrapperRef);
|
||||
usePositioningOniOS(containerRef);
|
||||
|
||||
useEffect(() => {
|
||||
noteContext?.isReadOnly().then(isReadOnly => {
|
||||
@ -23,15 +24,28 @@ export default function MobileEditorToolbar() {
|
||||
});
|
||||
}, [ note ]);
|
||||
|
||||
// Attach the toolbar from the CKEditor.
|
||||
useTriliumEvent("textEditorRefreshed", ({ ntxId: eventNtxId, editor }) => {
|
||||
if (eventNtxId !== ntxId || !containerRef.current) return;
|
||||
const toolbar = editor.ui.view.toolbar?.element;
|
||||
|
||||
repositionDropdowns(editor);
|
||||
if (toolbar) {
|
||||
containerRef.current.replaceChildren(toolbar);
|
||||
} else {
|
||||
containerRef.current.replaceChildren();
|
||||
}
|
||||
});
|
||||
|
||||
// Observe when a dropdown is expanded to apply a style that allows the dropdown to be visible, since we can't have the element both visible and the toolbar scrollable.
|
||||
useEffect(() => {
|
||||
if (!wrapperRef.current) return;
|
||||
if (!containerRef.current) return;
|
||||
|
||||
const observer = new MutationObserver(e => {
|
||||
setDropdownActive(e.map((e) => (e.target as any).ariaExpanded === "true").reduce((acc, e) => acc && e));
|
||||
});
|
||||
|
||||
observer.observe(wrapperRef.current, {
|
||||
observer.observe(containerRef.current, {
|
||||
attributeFilter: ["aria-expanded"],
|
||||
subtree: true
|
||||
});
|
||||
@ -41,7 +55,7 @@ export default function MobileEditorToolbar() {
|
||||
|
||||
return (
|
||||
<div className={`classic-toolbar-outer-container ${!shouldDisplay ? "hidden-ext" : "visible"} ${isIOS() ? "ios" : ""}`}>
|
||||
<div ref={wrapperRef} className={`classic-toolbar-widget ${dropdownActive ? "dropdown-active" : ""}`}></div>
|
||||
<div ref={containerRef} className={`classic-toolbar-widget ${dropdownActive ? "dropdown-active" : ""}`}></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -50,7 +64,7 @@ function usePositioningOniOS(wrapperRef: MutableRef<HTMLDivElement | null>) {
|
||||
const adjustPosition = useCallback(() => {
|
||||
if (!wrapperRef.current) return;
|
||||
let bottom = window.innerHeight - (window.visualViewport?.height || 0);
|
||||
wrapperRef.current.style.bottom = `${bottom}px`;
|
||||
wrapperRef.current.style.bottom = `${bottom}px`;
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
@ -65,3 +79,22 @@ function usePositioningOniOS(wrapperRef: MutableRef<HTMLDivElement | null>) {
|
||||
};
|
||||
}, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reposition all dropdowns to point upwards instead of downwards.
|
||||
* See https://ckeditor.com/docs/ckeditor5/latest/examples/framework/bottom-toolbar-editor.html for more info.
|
||||
* @param editor
|
||||
*/
|
||||
function repositionDropdowns(editor: CKTextEditor) {
|
||||
const toolbarView = (editor as ClassicEditor).ui.view.toolbar;
|
||||
for (const item of toolbarView.items) {
|
||||
if (!("panelView" in item)) continue;
|
||||
|
||||
item.on("change:isOpen", () => {
|
||||
if (!("isOpen" in item) || !item.isOpen) return;
|
||||
|
||||
// @ts-ignore
|
||||
item.panelView.position = item.panelView.position.replace("s", "n");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user