chore(react/collections/geomap): bring back context menu

This commit is contained in:
Elian Doran 2025-09-04 21:26:09 +03:00
parent dd654fcd8d
commit 189b7e20db
No known key found for this signature in database
7 changed files with 34 additions and 36 deletions

View File

@ -60,7 +60,7 @@ async function confirmDeleteNoteBoxWithNote(title: string) {
return new Promise<ConfirmDialogResult | undefined>((res) => appContext.triggerCommand("showConfirmDeleteNoteBoxWithNoteDialog", { title, callback: res }));
}
async function prompt(props: PromptDialogOptions) {
export async function prompt(props: PromptDialogOptions) {
return new Promise<string | null>((res) => appContext.triggerCommand("showPromptDialog", { ...props, callback: res }));
}

View File

@ -1,8 +1,28 @@
import { LatLng } from "leaflet";
import { LOCATION_ATTRIBUTE } from ".";
import attributes from "../../../services/attributes";
import { prompt } from "../../../services/dialog";
import server from "../../../services/server";
import { t } from "../../../services/i18n";
import { CreateChildrenResponse } from "@triliumnext/commons";
const CHILD_NOTE_ICON = "bx bx-pin";
export async function moveMarker(noteId: string, latLng: LatLng | null) {
const value = latLng ? [latLng.lat, latLng.lng].join(",") : "";
await attributes.setLabel(noteId, LOCATION_ATTRIBUTE, value);
}
export async function createNewNote(noteId: string, e: LeafletMouseEvent) {
const title = await prompt({ message: t("relation_map.enter_title_of_new_note"), defaultValue: t("relation_map.default_new_note_title") });
if (title?.trim()) {
const { note } = await server.post<CreateChildrenResponse>(`notes/${noteId}/children?target=into`, {
title,
content: "",
type: "text"
});
attributes.setLabel(note.noteId, "iconClass", CHILD_NOTE_ICON);
moveMarker(note.noteId, e.latlng);
}
}

View File

@ -3,7 +3,7 @@ import appContext, { type CommandMappings } from "../../../components/app_contex
import contextMenu, { type MenuItem } from "../../../menus/context_menu.js";
import linkContextMenu from "../../../menus/link_context_menu.js";
import { t } from "../../../services/i18n.js";
import { createNewNote } from "./editing.js";
import { createNewNote } from "./api.js";
import { copyTextWithToast } from "../../../services/clipboard_ext.js";
import link from "../../../services/link.js";

View File

@ -3,7 +3,7 @@ import "./index.css";
import { ViewModeProps } from "../interface";
import { useNoteLabel, useNoteLabelBoolean, useNoteProperty, useSpacedUpdate } from "../../react/hooks";
import { DEFAULT_MAP_LAYER_NAME } from "./map_layer";
import { divIcon, LatLng } from "leaflet";
import { divIcon, LatLng, LeafletMouseEvent } from "leaflet";
import { useCallback, useEffect, useMemo, useState } from "preact/hooks";
import Marker from "./marker";
import froca from "../../../services/froca";
@ -12,6 +12,7 @@ import markerIcon from "leaflet/dist/images/marker-icon.png";
import markerIconShadow from "leaflet/dist/images/marker-shadow.png";
import appContext from "../../../components/app_context";
import { moveMarker } from "./api";
import openContextMenu from "./context_menu";
const DEFAULT_COORDINATES: [number, number] = [3.878638227135724, 446.6630455551659];
const DEFAULT_ZOOM = 2;
@ -84,6 +85,8 @@ function NoteMarker({ note, editable }: { note: FNote, editable: boolean }) {
moveMarker(note.noteId, newCoordinates);
}, [ note.noteId ]);
const onContextMenu = useCallback((e: LeafletMouseEvent) => openContextMenu(note.noteId, e, editable), [ note.noteId, editable ]);
return latLng && <Marker
coordinates={latLng}
icon={icon}
@ -91,6 +94,7 @@ function NoteMarker({ note, editable }: { note: FNote, editable: boolean }) {
onMouseDown={onMouseDown}
onDragged={editable ? onDragged : undefined}
onClick={!editable ? onClick : undefined}
onContextMenu={onContextMenu}
/>
}

View File

@ -1,6 +1,6 @@
import { useContext, useEffect } from "preact/hooks";
import { ParentMap } from "./map";
import { DivIcon, Icon, LatLng, Marker as LeafletMarker, marker, MarkerOptions } from "leaflet";
import { DivIcon, Icon, LatLng, Marker as LeafletMarker, LeafletMouseEvent, marker, MarkerOptions } from "leaflet";
export interface MarkerProps {
coordinates: [ number, number ];
@ -8,10 +8,11 @@ export interface MarkerProps {
onClick?: () => void;
onMouseDown?: (e: MouseEvent) => void;
onDragged?: ((newCoordinates: LatLng) => void);
onContextMenu: (e: LeafletMouseEvent) => void;
draggable?: boolean;
}
export default function Marker({ coordinates, icon, draggable, onClick, onDragged, onMouseDown }: MarkerProps) {
export default function Marker({ coordinates, icon, draggable, onClick, onDragged, onMouseDown, onContextMenu }: MarkerProps) {
const parentMap = useContext(ParentMap);
useEffect(() => {
@ -41,6 +42,10 @@ export default function Marker({ coordinates, icon, draggable, onClick, onDragge
});
}
if (onContextMenu) {
newMarker.on("contextmenu", e => onContextMenu(e))
}
newMarker.addTo(parentMap);
return () => newMarker.removeFrom(parentMap);

View File

@ -9,29 +9,6 @@ import type { DragData } from "../../note_tree.js";
import froca from "../../../services/froca.js";
import branches from "../../../services/branches.js";
const CHILD_NOTE_ICON = "bx bx-pin";
// TODO: Deduplicate
interface CreateChildResponse {
note: {
noteId: string;
};
}
export async function createNewNote(noteId: string, e: LeafletMouseEvent) {
const title = await dialog.prompt({ message: t("relation_map.enter_title_of_new_note"), defaultValue: t("relation_map.default_new_note_title") });
if (title?.trim()) {
const { note } = await server.post<CreateChildResponse>(`notes/${noteId}/children?target=into`, {
title,
content: "",
type: "text"
});
attributes.setLabel(note.noteId, "iconClass", CHILD_NOTE_ICON);
moveMarker(note.noteId, e.latlng);
}
}
export function setupDragging($container: JQuery<HTMLElement>, map: Map, mapNoteId: string) {
$container.on("dragover", (e) => {
// Allow drag.

View File

@ -7,14 +7,6 @@ import L from "leaflet";
let gpxLoaded = false;
export default function processNoteWithMarker(map: Map, note: FNote, location: string, isEditable: boolean) {
newMarker.on("contextmenu", (e) => {
openContextMenu(note.noteId, e, isEditable);
});
return newMarker;
}
export async function processNoteWithGpxTrack(map: Map, note: FNote) {
if (!gpxLoaded) {
const GPX = await import("leaflet-gpx");