mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	chore(react/collections): bring back touch bar
This commit is contained in:
		| @@ -650,7 +650,7 @@ export class AppContext extends Component { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     getComponentByEl(el: HTMLElement) { |     getComponentByEl(el: HTMLElement) { | ||||||
|         return $(el).closest(".component").prop("component"); |         return $(el).closest("[data-component-id]").prop("component"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     addBeforeUnloadListener(obj: BeforeUploadListener | (() => boolean)) { |     addBeforeUnloadListener(obj: BeforeUploadListener | (() => boolean)) { | ||||||
|   | |||||||
| @@ -23,11 +23,11 @@ export default class TouchBarComponent extends Component { | |||||||
|         this.$widget = $("<div>"); |         this.$widget = $("<div>"); | ||||||
|  |  | ||||||
|         $(window).on("focusin", async (e) => { |         $(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"); |             this.$activeModal = $target.closest(".modal-dialog"); | ||||||
|             const parentComponentEl = $target.closest(".component"); |             this.lastFocusedComponent = appContext.getComponentByEl(focusedEl); | ||||||
|             this.lastFocusedComponent = appContext.getComponentByEl(parentComponentEl[0]); |  | ||||||
|             this.#refreshTouchBar(); |             this.#refreshTouchBar(); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import Map, { MapApi } from "./map"; | import Map, { MapApi } from "./map"; | ||||||
| import "./index.css"; | import "./index.css"; | ||||||
| import { ViewModeProps } from "../interface"; | 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 { DEFAULT_MAP_LAYER_NAME } from "./map_layer"; | ||||||
| import { divIcon, GPXOptions, LatLng, LeafletMouseEvent } from "leaflet"; | import { divIcon, GPXOptions, LatLng, LeafletMouseEvent } from "leaflet"; | ||||||
| import { useCallback, useEffect, useMemo, useRef, useState } from "preact/hooks"; | import { useCallback, useEffect, useMemo, useRef, useState } from "preact/hooks"; | ||||||
| @@ -17,6 +17,7 @@ import toast from "../../../services/toast"; | |||||||
| import { t } from "../../../services/i18n"; | import { t } from "../../../services/i18n"; | ||||||
| import server from "../../../services/server"; | import server from "../../../services/server"; | ||||||
| import branches from "../../../services/branches"; | import branches from "../../../services/branches"; | ||||||
|  | import { hasTouchBar } from "../../../services/utils"; | ||||||
|  |  | ||||||
| const DEFAULT_COORDINATES: [number, number] = [3.878638227135724, 446.6630455551659]; | const DEFAULT_COORDINATES: [number, number] = [3.878638227135724, 446.6630455551659]; | ||||||
| const DEFAULT_ZOOM = 2; | const DEFAULT_ZOOM = 2; | ||||||
| @@ -90,7 +91,7 @@ export default function GeoView({ note, noteIds, viewConfig, saveConfig }: ViewM | |||||||
|  |  | ||||||
|     // Dragging |     // Dragging | ||||||
|     const containerRef = useRef<HTMLDivElement>(null); |     const containerRef = useRef<HTMLDivElement>(null); | ||||||
|     const apiRef = useRef<MapApi>(null); |     const apiRef = useRef<L.Map>(null); | ||||||
|     useNoteTreeDrag(containerRef, async (treeData, e) => { |     useNoteTreeDrag(containerRef, async (treeData, e) => { | ||||||
|         const api = apiRef.current; |         const api = apiRef.current; | ||||||
|         if (!note || !api || isReadOnly) return; |         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 ( |     return ( | ||||||
|         <div className={`geo-view ${state === State.NewNote ? "placing-note" : ""}`}> |         <div className={`geo-view ${state === State.NewNote ? "placing-note" : ""}`}> | ||||||
|             <Map |             <Map | ||||||
| @@ -126,6 +153,7 @@ export default function GeoView({ note, noteIds, viewConfig, saveConfig }: ViewM | |||||||
|                 }} |                 }} | ||||||
|                 onClick={onClick} |                 onClick={onClick} | ||||||
|                 onContextMenu={onContextMenu} |                 onContextMenu={onContextMenu} | ||||||
|  |                 onZoom={hasTouchBar ? onZoom : undefined} | ||||||
|                 scale={hasScale} |                 scale={hasScale} | ||||||
|             > |             > | ||||||
|                 {notes.map(note => <NoteWrapper note={note} isReadOnly={isReadOnly} />)} |                 {notes.map(note => <NoteWrapper note={note} isReadOnly={isReadOnly} />)} | ||||||
|   | |||||||
| @@ -17,25 +17,15 @@ interface MapProps { | |||||||
|     children: ComponentChildren; |     children: ComponentChildren; | ||||||
|     onClick?: (e: LeafletMouseEvent) => void; |     onClick?: (e: LeafletMouseEvent) => void; | ||||||
|     onContextMenu?: (e: LeafletMouseEvent) => void; |     onContextMenu?: (e: LeafletMouseEvent) => void; | ||||||
|  |     onZoom?: () => void; | ||||||
|     scale: boolean; |     scale: boolean; | ||||||
| } | } | ||||||
|  |  | ||||||
| export interface MapApi { | export default function Map({ coordinates, zoom, layerName, viewportChanged, children, onClick, onContextMenu, scale, apiRef, containerRef: _containerRef, onZoom }: MapProps) { | ||||||
|     containerPointToLatLng: L.Map["containerPointToLatLng"]; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export default function Map({ coordinates, zoom, layerName, viewportChanged, children, onClick, onContextMenu, scale, apiRef, containerRef: _containerRef }: MapProps) { |  | ||||||
|     const mapRef = useRef<L.Map>(null); |     const mapRef = useRef<L.Map>(null); | ||||||
|     const containerRef = useSyncedRef<HTMLDivElement>(_containerRef); |     const containerRef = useSyncedRef<HTMLDivElement>(_containerRef); | ||||||
|  |  | ||||||
|     useImperativeHandle(apiRef ?? null, () => { |     useImperativeHandle(apiRef ?? null, () => mapRef.current); | ||||||
|         const map = mapRef.current; |  | ||||||
|         if (!map) return null; |  | ||||||
|  |  | ||||||
|         return { |  | ||||||
|             containerPointToLatLng: (point) => map.containerPointToLatLng(point) |  | ||||||
|         } satisfies MapApi; |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     useEffect(() => { |     useEffect(() => { | ||||||
|         if (!containerRef.current) return; |         if (!containerRef.current) return; | ||||||
| @@ -119,6 +109,13 @@ export default function Map({ coordinates, zoom, layerName, viewportChanged, chi | |||||||
|         } |         } | ||||||
|     }, [ mapRef, onContextMenu ]); |     }, [ mapRef, onContextMenu ]); | ||||||
|  |  | ||||||
|  |     useEffect(() => { | ||||||
|  |         if (onZoom && mapRef.current) { | ||||||
|  |             mapRef.current.on("zoom", onZoom); | ||||||
|  |             return () => mapRef.current?.off("zoom", onZoom); | ||||||
|  |         } | ||||||
|  |     }, [ mapRef, onZoom ]); | ||||||
|  |  | ||||||
|     // Scale |     // Scale | ||||||
|     useEffect(() => { |     useEffect(() => { | ||||||
|         const map = mapRef.current; |         const map = mapRef.current; | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { MutableRef, useCallback, useContext, useDebugValue, useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks"; | import { Inputs, MutableRef, useCallback, useContext, useDebugValue, useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks"; | ||||||
| import { EventData, EventNames } from "../../components/app_context"; | import { CommandListenerData, EventData, EventNames } from "../../components/app_context"; | ||||||
| import { ParentComponent } from "./react_utils"; | import { ParentComponent } from "./react_utils"; | ||||||
| import SpacedUpdate from "../../services/spaced_update"; | import SpacedUpdate from "../../services/spaced_update"; | ||||||
| import { KeyboardActionNames, OptionNames } from "@triliumnext/commons"; | import { KeyboardActionNames, OptionNames } from "@triliumnext/commons"; | ||||||
| @@ -17,6 +17,7 @@ import { CSSProperties, DragEventHandler } from "preact/compat"; | |||||||
| 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 { DragData } from "../note_tree"; | ||||||
|  | import Component from "../../components/component"; | ||||||
|  |  | ||||||
| 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); | ||||||
| @@ -611,3 +612,23 @@ export function useNoteTreeDrag(containerRef: MutableRef<HTMLElement | null | un | |||||||
|         }; |         }; | ||||||
|     }, [ containerRef, callback ]); |     }, [ 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); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -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) |  | ||||||
|             }) |  | ||||||
|         ]; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
		Reference in New Issue
	
	Block a user