diff --git a/apps/client/src/components/app_context.ts b/apps/client/src/components/app_context.ts index d888eba6f..cba5c91af 100644 --- a/apps/client/src/components/app_context.ts +++ b/apps/client/src/components/app_context.ts @@ -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)) { diff --git a/apps/client/src/components/touch_bar.ts b/apps/client/src/components/touch_bar.ts index 7bf10d7f1..226318a92 100644 --- a/apps/client/src/components/touch_bar.ts +++ b/apps/client/src/components/touch_bar.ts @@ -23,11 +23,11 @@ export default class TouchBarComponent extends Component { this.$widget = $("
"); $(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(); }); } diff --git a/apps/client/src/widgets/collections/geomap/index.tsx b/apps/client/src/widgets/collections/geomap/index.tsx index df04a1225..43dbc4a7f 100644 --- a/apps/client/src/widgets/collections/geomap/index.tsx +++ b/apps/client/src/widgets/collections/geomap/index.tsx @@ -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(null); - const apiRef = useRef(null); + const apiRef = useRef(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(); + 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 (
{notes.map(note => )} diff --git a/apps/client/src/widgets/collections/geomap/map.tsx b/apps/client/src/widgets/collections/geomap/map.tsx index 8a7afb781..85c7b9b34 100644 --- a/apps/client/src/widgets/collections/geomap/map.tsx +++ b/apps/client/src/widgets/collections/geomap/map.tsx @@ -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(null); const containerRef = useSyncedRef(_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; diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx index cc4eb64fb..bc1c14689 100644 --- a/apps/client/src/widgets/react/hooks.tsx +++ b/apps/client/src/widgets/react/hooks.tsx @@ -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(eventName: T, handler: (data: EventData) => void) { const parentComponent = useContext(ParentComponent); @@ -611,3 +612,23 @@ export function useNoteTreeDrag(containerRef: MutableRef & { parentComponent: Component | null }) => void, + inputs: Inputs +) { + const parentComponent = useContext(ParentComponent); + + useLegacyImperativeHandlers({ + buildTouchBarCommand(context: CommandListenerData<"buildTouchBar">) { + return factory({ + ...context, + parentComponent + }); + } + }); + + useEffect(() => { + parentComponent?.triggerCommand("refreshTouchBar"); + }, inputs); +} diff --git a/apps/client/src/widgets/view_widgets/geo_view/index.ts b/apps/client/src/widgets/view_widgets/geo_view/index.ts deleted file mode 100644 index 4786748c2..000000000 --- a/apps/client/src/widgets/view_widgets/geo_view/index.ts +++ /dev/null @@ -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 { - - 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) - }) - ]; - } - -} -