chore(react/collections): bring back touch bar

This commit is contained in:
Elian Doran 2025-09-05 11:54:58 +03:00
parent cb53ff880d
commit c79dd43105
No known key found for this signature in database
6 changed files with 67 additions and 88 deletions

View File

@ -650,7 +650,7 @@ export class AppContext extends Component {
}
getComponentByEl(el: HTMLElement) {
return $(el).closest(".component").prop("component");
return $(el).closest("[data-component-id]").prop("component");
}
addBeforeUnloadListener(obj: BeforeUploadListener | (() => boolean)) {

View File

@ -23,11 +23,11 @@ export default class TouchBarComponent extends Component {
this.$widget = $("<div>");
$(window).on("focusin", async (e) => {
const $target = $(e.target);
const focusedEl = e.target as unknown as HTMLElement;
const $target = $(focusedEl);
this.$activeModal = $target.closest(".modal-dialog");
const parentComponentEl = $target.closest(".component");
this.lastFocusedComponent = appContext.getComponentByEl(parentComponentEl[0]);
this.lastFocusedComponent = appContext.getComponentByEl(focusedEl);
this.#refreshTouchBar();
});
}

View File

@ -1,7 +1,7 @@
import Map, { MapApi } from "./map";
import "./index.css";
import { ViewModeProps } from "../interface";
import { useNoteBlob, useNoteLabel, useNoteLabelBoolean, useNoteProperty, useNoteTreeDrag, useSpacedUpdate, useTriliumEvent } from "../../react/hooks";
import { useNoteBlob, useNoteLabel, useNoteLabelBoolean, useNoteProperty, useNoteTreeDrag, useSpacedUpdate, useTouchBar, useTriliumEvent } from "../../react/hooks";
import { DEFAULT_MAP_LAYER_NAME } from "./map_layer";
import { divIcon, GPXOptions, LatLng, LeafletMouseEvent } from "leaflet";
import { useCallback, useEffect, useMemo, useRef, useState } from "preact/hooks";
@ -17,6 +17,7 @@ import toast from "../../../services/toast";
import { t } from "../../../services/i18n";
import server from "../../../services/server";
import branches from "../../../services/branches";
import { hasTouchBar } from "../../../services/utils";
const DEFAULT_COORDINATES: [number, number] = [3.878638227135724, 446.6630455551659];
const DEFAULT_ZOOM = 2;
@ -90,7 +91,7 @@ export default function GeoView({ note, noteIds, viewConfig, saveConfig }: ViewM
// Dragging
const containerRef = useRef<HTMLDivElement>(null);
const apiRef = useRef<MapApi>(null);
const apiRef = useRef<L.Map>(null);
useNoteTreeDrag(containerRef, async (treeData, e) => {
const api = apiRef.current;
if (!note || !api || isReadOnly) return;
@ -112,6 +113,32 @@ export default function GeoView({ note, noteIds, viewConfig, saveConfig }: ViewM
}
});
// Touch bar.
const [ zoomLevel, setZoomLevel ] = useState<number>();
const onZoom = useCallback(() => {
if (!apiRef.current) return;
setZoomLevel(apiRef.current.getZoom());
}, []);
useTouchBar(({ TouchBar, parentComponent }) => {
const map = apiRef.current;
if (!note || !map) return;
return [
new TouchBar.TouchBarSlider({
label: "Zoom",
value: zoomLevel ?? map.getZoom(),
minValue: map.getMinZoom(),
maxValue: map.getMaxZoom(),
change: (newValue) => map.setZoom(newValue)
}),
new TouchBar.TouchBarButton({
label: "New geo note",
click: () => parentComponent?.triggerCommand("geoMapCreateChildNote"),
enabled: (state === State.Normal)
})
];
}, [ zoomLevel, state ]);
return (
<div className={`geo-view ${state === State.NewNote ? "placing-note" : ""}`}>
<Map
@ -126,6 +153,7 @@ export default function GeoView({ note, noteIds, viewConfig, saveConfig }: ViewM
}}
onClick={onClick}
onContextMenu={onContextMenu}
onZoom={hasTouchBar ? onZoom : undefined}
scale={hasScale}
>
{notes.map(note => <NoteWrapper note={note} isReadOnly={isReadOnly} />)}

View File

@ -17,25 +17,15 @@ interface MapProps {
children: ComponentChildren;
onClick?: (e: LeafletMouseEvent) => void;
onContextMenu?: (e: LeafletMouseEvent) => void;
onZoom?: () => void;
scale: boolean;
}
export interface MapApi {
containerPointToLatLng: L.Map["containerPointToLatLng"];
}
export default function Map({ coordinates, zoom, layerName, viewportChanged, children, onClick, onContextMenu, scale, apiRef, containerRef: _containerRef }: MapProps) {
export default function Map({ coordinates, zoom, layerName, viewportChanged, children, onClick, onContextMenu, scale, apiRef, containerRef: _containerRef, onZoom }: MapProps) {
const mapRef = useRef<L.Map>(null);
const containerRef = useSyncedRef<HTMLDivElement>(_containerRef);
useImperativeHandle(apiRef ?? null, () => {
const map = mapRef.current;
if (!map) return null;
return {
containerPointToLatLng: (point) => map.containerPointToLatLng(point)
} satisfies MapApi;
});
useImperativeHandle(apiRef ?? null, () => mapRef.current);
useEffect(() => {
if (!containerRef.current) return;
@ -119,6 +109,13 @@ export default function Map({ coordinates, zoom, layerName, viewportChanged, chi
}
}, [ mapRef, onContextMenu ]);
useEffect(() => {
if (onZoom && mapRef.current) {
mapRef.current.on("zoom", onZoom);
return () => mapRef.current?.off("zoom", onZoom);
}
}, [ mapRef, onZoom ]);
// Scale
useEffect(() => {
const map = mapRef.current;

View File

@ -1,5 +1,5 @@
import { MutableRef, useCallback, useContext, useDebugValue, useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks";
import { EventData, EventNames } from "../../components/app_context";
import { Inputs, MutableRef, useCallback, useContext, useDebugValue, useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks";
import { CommandListenerData, EventData, EventNames } from "../../components/app_context";
import { ParentComponent } from "./react_utils";
import SpacedUpdate from "../../services/spaced_update";
import { KeyboardActionNames, OptionNames } from "@triliumnext/commons";
@ -17,6 +17,7 @@ import { CSSProperties, DragEventHandler } from "preact/compat";
import keyboard_actions from "../../services/keyboard_actions";
import Mark from "mark.js";
import { DragData } from "../note_tree";
import Component from "../../components/component";
export function useTriliumEvent<T extends EventNames>(eventName: T, handler: (data: EventData<T>) => void) {
const parentComponent = useContext(ParentComponent);
@ -611,3 +612,23 @@ export function useNoteTreeDrag(containerRef: MutableRef<HTMLElement | null | un
};
}, [ containerRef, callback ]);
}
export function useTouchBar(
factory: (context: CommandListenerData<"buildTouchBar"> & { parentComponent: Component | null }) => void,
inputs: Inputs
) {
const parentComponent = useContext(ParentComponent);
useLegacyImperativeHandlers({
buildTouchBarCommand(context: CommandListenerData<"buildTouchBar">) {
return factory({
...context,
parentComponent
});
}
});
useEffect(() => {
parentComponent?.triggerCommand("refreshTouchBar");
}, inputs);
}

View File

@ -1,67 +0,0 @@
import ViewMode, { ViewModeArgs } from "../view_mode.js";
import L from "leaflet";
import type { GPX, LatLng, Layer, LeafletMouseEvent, Map, Marker } from "leaflet";
import SpacedUpdate from "../../../services/spaced_update.js";
import { t } from "../../../services/i18n.js";
import processNoteWithMarker, { processNoteWithGpxTrack } from "./markers.js";
import { hasTouchBar } from "../../../services/utils.js";
import toast from "../../../services/toast.js";
import { CommandListenerData, EventData } from "../../../components/app_context.js";
import { createNewNote, moveMarker, setupDragging } from "./editing.js";
import { openMapContextMenu } from "./context_menu.js";
import attributes from "../../../services/attributes.js";
import { DEFAULT_MAP_LAYER_NAME, MAP_LAYERS } from "./map_layer.js";
export default class GeoView extends ViewMode<MapData> {
async #onMapInitialized() {
if (hasTouchBar) {
map.on("zoom", () => {
if (!this.ignoreNextZoomEvent) {
this.triggerCommand("refreshTouchBar");
}
this.ignoreNextZoomEvent = false;
});
}
}
#changeState(newState: State) {
this._state = newState;
if (hasTouchBar) {
this.triggerCommand("refreshTouchBar");
}
}
buildTouchBarCommand({ TouchBar }: CommandListenerData<"buildTouchBar">) {
const map = this.map;
const that = this;
if (!map) {
return;
}
return [
new TouchBar.TouchBarSlider({
label: "Zoom",
value: map.getZoom(),
minValue: map.getMinZoom(),
maxValue: map.getMaxZoom(),
change(newValue) {
that.ignoreNextZoomEvent = true;
map.setZoom(newValue);
},
}),
new TouchBar.TouchBarButton({
label: "New geo note",
click: () => this.triggerCommand("geoMapCreateChildNote"),
enabled: (this._state === State.Normal)
})
];
}
}