mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 03:29:02 +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]); | ||||||
| 
 | 
 | ||||||
|     return latLng && <Marker |  | ||||||
|         coordinates={latLng} |  | ||||||
|         icon={icon} |  | ||||||
|         mouseDown={useCallback((e: MouseEvent) => { |  | ||||||
|     // Middle click to open in new tab
 |     // Middle click to open in new tab
 | ||||||
|  |     const onMouseDown = useCallback((e: MouseEvent) => { | ||||||
|         if (e.button === 1) { |         if (e.button === 1) { | ||||||
|             const hoistedNoteId = appContext.tabManager.getActiveContext()?.hoistedNoteId; |             const hoistedNoteId = appContext.tabManager.getActiveContext()?.hoistedNoteId; | ||||||
|             appContext.tabManager.openInNewTab(note.noteId, hoistedNoteId); |             appContext.tabManager.openInNewTab(note.noteId, hoistedNoteId); | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|         }, [ note.noteId ])} |     }, [ note.noteId ]); | ||||||
|  | 
 | ||||||
|  |     const onDragged = useCallback((newCoordinates: LatLng) => { | ||||||
|  |         moveMarker(note.noteId, newCoordinates); | ||||||
|  |     }, [ note.noteId ]); | ||||||
|  | 
 | ||||||
|  |     return latLng && <Marker | ||||||
|  |         coordinates={latLng} | ||||||
|  |         icon={icon} | ||||||
|  |         mouseDown={onMouseDown} | ||||||
|  |         draggable={editable} | ||||||
|  |         dragged={onDragged} | ||||||
|     /> |     /> | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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
	 Elian Doran
						Elian Doran