diff --git a/apps/client/src/widgets/collections/geomap/context_menu.ts b/apps/client/src/widgets/collections/geomap/ContextMenus.ts similarity index 68% rename from apps/client/src/widgets/collections/geomap/context_menu.ts rename to apps/client/src/widgets/collections/geomap/ContextMenus.ts index 209532072b..d885037522 100644 --- a/apps/client/src/widgets/collections/geomap/context_menu.ts +++ b/apps/client/src/widgets/collections/geomap/ContextMenus.ts @@ -1,14 +1,49 @@ -import type { GeoMouseEvent } from "./map.js"; +import { useCallback, useContext, useEffect } from "preact/hooks"; + import appContext, { type CommandMappings } from "../../../components/app_context.js"; import contextMenu, { type MenuItem } from "../../../menus/context_menu.js"; -import linkContextMenu from "../../../menus/link_context_menu.js"; import NoteColorPicker from "../../../menus/custom-items/NoteColorPicker.jsx"; -import { t } from "../../../services/i18n.js"; -import { createNewNote } from "./api.js"; +import linkContextMenu from "../../../menus/link_context_menu.js"; import { copyTextWithToast } from "../../../services/clipboard_ext.js"; +import { t } from "../../../services/i18n.js"; import link from "../../../services/link.js"; +import { createNewNote } from "./api.js"; +import { type GeoMouseEvent,ParentMap, toMapLibreEvent } from "./map.js"; +import { MARKER_LAYER } from "./marker_data.js"; -export default function openContextMenu(noteId: string, e: GeoMouseEvent, isEditable: boolean) { +export default function ContextMenus({ note, isReadOnly }: { note: FNote, isReadOnly }) { + const map = useContext(ParentMap); + + const onContextMenu = useCallback((e: GeoMouseEvent) => { + if (!map) return; + const features = map.queryRenderedFeatures(e.point, { + layers: [ MARKER_LAYER ] + }); + + if (features.length > 0) { + // Marker context menu. + openContextMenu(features[0].properties.id, e, !isReadOnly); + } else { + // Empty area context menu. + openMapContextMenu(note.noteId, e, !isReadOnly); + } + }, [ map, note.noteId, isReadOnly ]); + + useEffect(() => { + if (!onContextMenu || !map) return; + + const handler = (e: maplibregl.MapMouseEvent) => { + e.preventDefault(); + onContextMenu(toMapLibreEvent(e)); + }; + map.on("contextmenu", handler); + return () => { map.off("contextmenu", handler); }; + }, [ map, onContextMenu ]); + + return null; +} + +export function openContextMenu(noteId: string, e: GeoMouseEvent, isEditable: boolean) { let items: MenuItem[] = [ ...buildGeoLocationItem(e), { kind: "separator" }, @@ -58,7 +93,7 @@ export function openMapContextMenu(noteId: string, e: GeoMouseEvent, isEditable: handler: () => createNewNote(noteId, e), uiIcon: "bx bx-plus" } - ] + ]; } contextMenu.show({ diff --git a/apps/client/src/widgets/collections/geomap/index.tsx b/apps/client/src/widgets/collections/geomap/index.tsx index 7076c08274..ffa9d594dd 100644 --- a/apps/client/src/widgets/collections/geomap/index.tsx +++ b/apps/client/src/widgets/collections/geomap/index.tsx @@ -1,8 +1,6 @@ import "./index.css"; import type maplibregl from "maplibre-gl"; -import { MapMouseEvent, Popup } from "maplibre-gl"; -import { RefObject } from "preact"; import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "preact/hooks"; import appContext from "../../../components/app_context"; @@ -20,11 +18,11 @@ import { ParentComponent } from "../../react/react_utils"; import TouchBar, { TouchBarButton, TouchBarSlider } from "../../react/TouchBar"; import { ViewModeProps } from "../interface"; import { createNewNote, moveMarker } from "./api"; -import openContextMenu, { openMapContextMenu } from "./context_menu"; +import ContextMenus from "./ContextMenus"; import Map, { GeoMouseEvent } from "./map"; import { DEFAULT_MAP_LAYER_NAME, MAP_LAYERS, MapLayer } from "./map_layer"; import Marker, { GpxTrack } from "./marker"; -import { MARKER_LAYER, MARKER_SVG, useMarkerData } from "./marker_data"; +import { MARKER_SVG, useMarkerData } from "./marker_data"; import Tooltips from "./Tooltips"; const DEFAULT_COORDINATES: [number, number] = [3.878638227135724, 446.6630455551659]; @@ -100,22 +98,6 @@ export default function GeoView({ note, noteIds, viewConfig, saveConfig }: ViewM } }, [ state ]); - const onContextMenu = useCallback((e: GeoMouseEvent) => { - const map = apiRef.current; - if (!map) return; - const features = map.queryRenderedFeatures(e.point, { - layers: [ MARKER_LAYER ] - }); - - if (features.length > 0) { - // Marker context menu. - openContextMenu(features[0].properties.id, e, !isReadOnly); - } else { - // Empty area context menu. - openMapContextMenu(note.noteId, e, !isReadOnly); - } - }, [ note.noteId, isReadOnly ]); - // Dragging const containerRef = useRef(null); const apiRef = useRef(null); @@ -175,10 +157,10 @@ export default function GeoView({ note, noteIds, viewConfig, saveConfig }: ViewM spacedUpdate.scheduleUpdate(); }} onClick={onClick} - onContextMenu={onContextMenu} scale={hasScale} > + } diff --git a/apps/client/src/widgets/collections/geomap/map.tsx b/apps/client/src/widgets/collections/geomap/map.tsx index 53d90e41ba..ee79c6c83b 100644 --- a/apps/client/src/widgets/collections/geomap/map.tsx +++ b/apps/client/src/widgets/collections/geomap/map.tsx @@ -29,7 +29,7 @@ interface MapProps { scale: boolean; } -function toMapLibreEvent(e: maplibregl.MapMouseEvent): GeoMouseEvent { +export function toMapLibreEvent(e: maplibregl.MapMouseEvent): GeoMouseEvent { return { latlng: { lat: e.lngLat.lat, lng: e.lngLat.lng }, originalEvent: e.originalEvent, @@ -176,17 +176,6 @@ export default function Map({ coordinates, zoom, layerData, viewportChanged, chi return () => { map.off("click", handler); }; }, [ map, onClick ]); - useEffect(() => { - if (!onContextMenu || !map) return; - - const handler = (e: maplibregl.MapMouseEvent) => { - e.preventDefault(); - onContextMenu(toMapLibreEvent(e)); - }; - map.on("contextmenu", handler); - return () => { map.off("contextmenu", handler); }; - }, [ map, onContextMenu ]); - useEffect(() => { if (!onZoom || !map) return;