feat(collections/geomap): show toast if drag not enabled

This commit is contained in:
Elian Doran
2025-09-12 21:06:54 +03:00
parent 338f3d536f
commit dd6003172d
3 changed files with 55 additions and 18 deletions

View File

@@ -966,7 +966,9 @@
"no_attachments": "This note has no attachments." "no_attachments": "This note has no attachments."
}, },
"book": { "book": {
"no_children_help": "This collection doesn't have any child notes so there's nothing to display. See <a href=\"https://triliumnext.github.io/Docs/Wiki/book-note.html\">wiki</a> for details." "no_children_help": "This collection doesn't have any child notes so there's nothing to display. See <a href=\"https://triliumnext.github.io/Docs/Wiki/book-note.html\">wiki</a> for details.",
"drag_locked_title": "Locked for editing",
"drag_locked_message": "Dragging not allowed since the collection is locked for editing."
}, },
"editable_code": { "editable_code": {
"placeholder": "Type the content of your code note here..." "placeholder": "Type the content of your code note here..."

View File

@@ -91,24 +91,32 @@ export default function GeoView({ note, noteIds, viewConfig, saveConfig }: ViewM
// Dragging // Dragging
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
const apiRef = useRef<L.Map>(null); const apiRef = useRef<L.Map>(null);
useNoteTreeDrag(containerRef, async (treeData, e) => { useNoteTreeDrag(containerRef, {
const api = apiRef.current; dragEnabled: !isReadOnly,
if (!note || !api || isReadOnly) return; dragNotEnabledMessage: {
icon: "bx bx-lock-alt",
title: t("book.drag_locked_title"),
message: t("book.drag_locked_message")
},
async callback(treeData, e) {
const api = apiRef.current;
if (!note || !api || isReadOnly) return;
const { noteId } = treeData[0]; const { noteId } = treeData[0];
const offset = containerRef.current?.getBoundingClientRect(); const offset = containerRef.current?.getBoundingClientRect();
const x = e.clientX - (offset?.left ?? 0); const x = e.clientX - (offset?.left ?? 0);
const y = e.clientY - (offset?.top ?? 0); const y = e.clientY - (offset?.top ?? 0);
const latlng = api.containerPointToLatLng([ x, y ]); const latlng = api.containerPointToLatLng([ x, y ]);
const targetNote = await froca.getNote(noteId, true); const targetNote = await froca.getNote(noteId, true);
const parents = targetNote?.getParentNoteIds(); const parents = targetNote?.getParentNoteIds();
if (parents?.includes(note.noteId)) { if (parents?.includes(note.noteId)) {
await moveMarker(noteId, latlng); await moveMarker(noteId, latlng);
} else { } else {
await branches.cloneNoteToParentNote(noteId, noteId); await branches.cloneNoteToParentNote(noteId, noteId);
await moveMarker(noteId, latlng); await moveMarker(noteId, latlng);
}
} }
}); });

View File

@@ -18,6 +18,7 @@ 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"; import Component from "../../components/component";
import toast, { ToastOptions } from "../../services/toast";
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);
@@ -588,17 +589,35 @@ export function useImperativeSearchHighlighlighting(highlightedTokens: string[]
}; };
} }
export function useNoteTreeDrag(containerRef: MutableRef<HTMLElement | null | undefined>, callback: (data: DragData[], e: DragEvent) => void) { export function useNoteTreeDrag(containerRef: MutableRef<HTMLElement | null | undefined>, { dragEnabled, dragNotEnabledMessage, callback }: {
dragEnabled: boolean,
dragNotEnabledMessage: Omit<ToastOptions, "id" | "closeAfter">;
callback: (data: DragData[], e: DragEvent) => void
}) {
useEffect(() => { useEffect(() => {
const container = containerRef.current; const container = containerRef.current;
if (!container) return; if (!container) return;
function onDragEnter(e: DragEvent) {
if (!dragEnabled) {
toast.showPersistent({
...dragNotEnabledMessage,
id: "drag-not-enabled",
closeAfter: 5000
});
}
}
function onDragOver(e: DragEvent) { function onDragOver(e: DragEvent) {
// Allow drag.
e.preventDefault(); e.preventDefault();
} }
function onDrop(e: DragEvent) { function onDrop(e: DragEvent) {
toast.closePersistent("drag-not-enabled");
if (!dragEnabled) {
return;
}
const data = e.dataTransfer?.getData('text'); const data = e.dataTransfer?.getData('text');
if (!data) { if (!data) {
return; return;
@@ -612,12 +631,20 @@ export function useNoteTreeDrag(containerRef: MutableRef<HTMLElement | null | un
callback(parsedData, e); callback(parsedData, e);
} }
function onDragLeave() {
toast.closePersistent("drag-not-enabled");
}
container.addEventListener("dragenter", onDragEnter);
container.addEventListener("dragover", onDragOver); container.addEventListener("dragover", onDragOver);
container.addEventListener("drop", onDrop); container.addEventListener("drop", onDrop);
container.addEventListener("dragleave", onDragLeave)
return () => { return () => {
container.removeEventListener("dragenter", onDragEnter);
container.removeEventListener("dragover", onDragOver); container.removeEventListener("dragover", onDragOver);
container.removeEventListener("drop", onDrop); container.removeEventListener("drop", onDrop);
container.removeEventListener("dragleave", onDragLeave);
}; };
}, [ containerRef, callback ]); }, [ containerRef, callback ]);
} }