mirror of
https://github.com/zadam/trilium.git
synced 2025-10-29 02:28:57 +01:00
chore(react/collections/geomap): bring back dragging
This commit is contained in:
parent
ec40d20e6a
commit
5854adb806
8
apps/client/src/widgets/collections/geomap/api.ts
Normal file
8
apps/client/src/widgets/collections/geomap/api.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { LatLng } from "leaflet";
|
||||||
|
import { LOCATION_ATTRIBUTE } from ".";
|
||||||
|
import attributes from "../../../services/attributes";
|
||||||
|
|
||||||
|
export async function moveMarker(noteId: string, latLng: LatLng | null) {
|
||||||
|
const value = latLng ? [latLng.lat, latLng.lng].join(",") : "";
|
||||||
|
await attributes.setLabel(noteId, LOCATION_ATTRIBUTE, value);
|
||||||
|
}
|
||||||
@ -11,6 +11,7 @@ import FNote from "../../../entities/fnote";
|
|||||||
import markerIcon from "leaflet/dist/images/marker-icon.png";
|
import markerIcon from "leaflet/dist/images/marker-icon.png";
|
||||||
import markerIconShadow from "leaflet/dist/images/marker-shadow.png";
|
import markerIconShadow from "leaflet/dist/images/marker-shadow.png";
|
||||||
import appContext from "../../../components/app_context";
|
import appContext from "../../../components/app_context";
|
||||||
|
import { moveMarker } from "./api";
|
||||||
|
|
||||||
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;
|
||||||
@ -25,6 +26,7 @@ interface MapData {
|
|||||||
|
|
||||||
export default function GeoView({ note, noteIds, viewConfig, saveConfig }: ViewModeProps<MapData>) {
|
export default function GeoView({ note, noteIds, viewConfig, saveConfig }: ViewModeProps<MapData>) {
|
||||||
const [ layerName ] = useNoteLabel(note, "map:style");
|
const [ layerName ] = useNoteLabel(note, "map:style");
|
||||||
|
const [ isReadOnly ] = useNoteLabel(note, "readOnly");
|
||||||
const [ notes, setNotes ] = useState<FNote[]>([]);
|
const [ notes, setNotes ] = useState<FNote[]>([]);
|
||||||
const spacedUpdate = useSpacedUpdate(() => {
|
const spacedUpdate = useSpacedUpdate(() => {
|
||||||
if (viewConfig) {
|
if (viewConfig) {
|
||||||
@ -46,13 +48,13 @@ export default function GeoView({ note, noteIds, viewConfig, saveConfig }: ViewM
|
|||||||
spacedUpdate.scheduleUpdate();
|
spacedUpdate.scheduleUpdate();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{notes.map(note => <NoteMarker note={note} />)}
|
{notes.map(note => <NoteMarker note={note} editable={!isReadOnly} />)}
|
||||||
</Map>
|
</Map>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function NoteMarker({ note }: { note: FNote }) {
|
function NoteMarker({ note, editable }: { note: FNote, editable: boolean }) {
|
||||||
const [ location ] = useNoteLabel(note, LOCATION_ATTRIBUTE);
|
const [ location ] = useNoteLabel(note, LOCATION_ATTRIBUTE);
|
||||||
|
|
||||||
// React to changes
|
// React to changes
|
||||||
@ -65,17 +67,25 @@ function NoteMarker({ note }: { note: FNote }) {
|
|||||||
const latLng = location?.split(",", 2).map((el) => parseFloat(el)) as [ number, number ] | undefined;
|
const latLng = location?.split(",", 2).map((el) => parseFloat(el)) as [ number, number ] | undefined;
|
||||||
const icon = useMemo(() => buildIcon(iconClass, colorClass ?? undefined, title, note.noteId), [ iconClass, colorClass, title, note.noteId]);
|
const icon = useMemo(() => buildIcon(iconClass, colorClass ?? undefined, title, note.noteId), [ iconClass, colorClass, title, note.noteId]);
|
||||||
|
|
||||||
|
// Middle click to open in new tab
|
||||||
|
const onMouseDown = useCallback((e: MouseEvent) => {
|
||||||
|
if (e.button === 1) {
|
||||||
|
const hoistedNoteId = appContext.tabManager.getActiveContext()?.hoistedNoteId;
|
||||||
|
appContext.tabManager.openInNewTab(note.noteId, hoistedNoteId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}, [ note.noteId ]);
|
||||||
|
|
||||||
|
const onDragged = useCallback((newCoordinates: LatLng) => {
|
||||||
|
moveMarker(note.noteId, newCoordinates);
|
||||||
|
}, [ note.noteId ]);
|
||||||
|
|
||||||
return latLng && <Marker
|
return latLng && <Marker
|
||||||
coordinates={latLng}
|
coordinates={latLng}
|
||||||
icon={icon}
|
icon={icon}
|
||||||
mouseDown={useCallback((e: MouseEvent) => {
|
mouseDown={onMouseDown}
|
||||||
// Middle click to open in new tab
|
draggable={editable}
|
||||||
if (e.button === 1) {
|
dragged={onDragged}
|
||||||
const hoistedNoteId = appContext.tabManager.getActiveContext()?.hoistedNoteId;
|
|
||||||
appContext.tabManager.openInNewTab(note.noteId, hoistedNoteId);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}, [ note.noteId ])}
|
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,27 +1,41 @@
|
|||||||
import { useContext, useEffect } from "preact/hooks";
|
import { useContext, useEffect } from "preact/hooks";
|
||||||
import { ParentMap } from "./map";
|
import { ParentMap } from "./map";
|
||||||
import { DivIcon, Icon, marker } from "leaflet";
|
import { DivIcon, Icon, LatLng, Marker as LeafletMarker, marker, MarkerOptions } from "leaflet";
|
||||||
|
|
||||||
export interface MarkerProps {
|
export interface MarkerProps {
|
||||||
coordinates: [ number, number ];
|
coordinates: [ number, number ];
|
||||||
icon?: Icon | DivIcon;
|
icon?: Icon | DivIcon;
|
||||||
mouseDown?: (e: MouseEvent) => void;
|
mouseDown?: (e: MouseEvent) => void;
|
||||||
|
dragged: ((newCoordinates: LatLng) => void)
|
||||||
|
draggable?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Marker({ coordinates, icon, mouseDown }: MarkerProps) {
|
export default function Marker({ coordinates, icon, draggable, dragged, mouseDown }: MarkerProps) {
|
||||||
const parentMap = useContext(ParentMap);
|
const parentMap = useContext(ParentMap);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!parentMap) return;
|
if (!parentMap) return;
|
||||||
|
|
||||||
const newMarker = marker(coordinates, {
|
const options: MarkerOptions = { icon };
|
||||||
icon
|
if (draggable) {
|
||||||
});
|
options.draggable = true;
|
||||||
|
options.autoPan = true;
|
||||||
|
options.autoPanSpeed = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newMarker = marker(coordinates, options);
|
||||||
|
|
||||||
if (mouseDown) {
|
if (mouseDown) {
|
||||||
newMarker.on("mousedown", e => mouseDown(e.originalEvent));
|
newMarker.on("mousedown", e => mouseDown(e.originalEvent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dragged) {
|
||||||
|
newMarker.on("moveend", e => {
|
||||||
|
const coordinates = (e.target as LeafletMarker).getLatLng();
|
||||||
|
dragged(coordinates);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
newMarker.addTo(parentMap);
|
newMarker.addTo(parentMap);
|
||||||
|
|
||||||
return () => newMarker.removeFrom(parentMap);
|
return () => newMarker.removeFrom(parentMap);
|
||||||
|
|||||||
@ -18,11 +18,6 @@ interface CreateChildResponse {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
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") });
|
const title = await dialog.prompt({ message: t("relation_map.enter_title_of_new_note"), defaultValue: t("relation_map.default_new_note_title") });
|
||||||
|
|
||||||
|
|||||||
@ -9,19 +9,6 @@ import L from "leaflet";
|
|||||||
let gpxLoaded = false;
|
let gpxLoaded = false;
|
||||||
|
|
||||||
export default function processNoteWithMarker(map: Map, note: FNote, location: string, isEditable: boolean) {
|
export default function processNoteWithMarker(map: Map, note: FNote, location: string, isEditable: boolean) {
|
||||||
const newMarker = marker(latLng(lat, lng), {
|
|
||||||
icon,
|
|
||||||
draggable: isEditable,
|
|
||||||
autoPan: true,
|
|
||||||
autoPanSpeed: 5
|
|
||||||
}).addTo(map);
|
|
||||||
|
|
||||||
if (isEditable) {
|
|
||||||
newMarker.on("moveend", (e) => {
|
|
||||||
moveMarker(note.noteId, (e.target as Marker).getLatLng());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
newMarker.on("contextmenu", (e) => {
|
newMarker.on("contextmenu", (e) => {
|
||||||
openContextMenu(note.noteId, e, isEditable);
|
openContextMenu(note.noteId, e, isEditable);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -53,8 +53,4 @@ export default abstract class ViewMode<T extends object> extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get isReadOnly() {
|
|
||||||
return this.parentNote.hasLabel("readOnly");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user