From 4a02981c093e31b067f4e4f786d81cfa7c0c4561 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Thu, 4 Sep 2025 16:17:27 +0300 Subject: [PATCH] refactor(react/collections/geomap): display reactive icon, text --- .../src/widgets/collections/geomap/index.tsx | 36 ++++++++++++++++--- .../src/widgets/collections/geomap/marker.tsx | 7 ++-- .../widgets/view_widgets/geo_view/markers.ts | 22 ------------ 3 files changed, 36 insertions(+), 29 deletions(-) diff --git a/apps/client/src/widgets/collections/geomap/index.tsx b/apps/client/src/widgets/collections/geomap/index.tsx index 09d4b7760..8dc272604 100644 --- a/apps/client/src/widgets/collections/geomap/index.tsx +++ b/apps/client/src/widgets/collections/geomap/index.tsx @@ -1,13 +1,15 @@ import Map from "./map"; import "./index.css"; import { ViewModeProps } from "../interface"; -import { useNoteLabel, useSpacedUpdate } from "../../react/hooks"; +import { useNoteLabel, useNoteProperty, useSpacedUpdate } from "../../react/hooks"; import { DEFAULT_MAP_LAYER_NAME } from "./map_layer"; -import { LatLng } from "leaflet"; -import { useEffect, useState } from "preact/hooks"; +import { divIcon, LatLng } from "leaflet"; +import { useEffect, useMemo, useState } from "preact/hooks"; import Marker from "./marker"; import froca from "../../../services/froca"; import FNote from "../../../entities/fnote"; +import markerIcon from "leaflet/dist/images/marker-icon.png"; +import markerIconShadow from "leaflet/dist/images/marker-shadow.png"; const DEFAULT_COORDINATES: [number, number] = [3.878638227135724, 446.6630455551659]; const DEFAULT_ZOOM = 2; @@ -51,7 +53,33 @@ export default function GeoView({ note, noteIds, viewConfig, saveConfig }: ViewM function NoteMarker({ note }: { note: FNote }) { const [ location ] = useNoteLabel(note, LOCATION_ATTRIBUTE); + const [ colorClass ] = useNoteLabel(note, "colorClass"); + useNoteLabel(note, "iconClass"); // React to icon changes. + const title = useNoteProperty(note, "title"); + const iconClass = note.getIcon(); 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]); - return latLng && + return latLng && +} + +function buildIcon(bxIconClass: string, colorClass?: string, title?: string, noteIdLink?: string) { + let html = /*html*/`\ + + + + ${title ?? ""}`; + + if (noteIdLink) { + html = `
${html}
`; + } + + return divIcon({ + html, + iconSize: [25, 41], + iconAnchor: [12, 41] + }); } diff --git a/apps/client/src/widgets/collections/geomap/marker.tsx b/apps/client/src/widgets/collections/geomap/marker.tsx index 5f5830c63..559723b83 100644 --- a/apps/client/src/widgets/collections/geomap/marker.tsx +++ b/apps/client/src/widgets/collections/geomap/marker.tsx @@ -1,19 +1,20 @@ import { useContext, useEffect } from "preact/hooks"; import { ParentMap } from "./map"; -import { marker } from "leaflet"; +import { DivIcon, Icon, marker } from "leaflet"; export interface MarkerProps { coordinates: [ number, number ]; + icon?: Icon | DivIcon; } -export default function Marker({ coordinates }: MarkerProps) { +export default function Marker({ coordinates, icon }: MarkerProps) { const parentMap = useContext(ParentMap); useEffect(() => { if (!parentMap) return; const newMarker = marker(coordinates, { - + icon }); newMarker.addTo(parentMap); diff --git a/apps/client/src/widgets/view_widgets/geo_view/markers.ts b/apps/client/src/widgets/view_widgets/geo_view/markers.ts index 11aa45190..f5649551f 100644 --- a/apps/client/src/widgets/view_widgets/geo_view/markers.ts +++ b/apps/client/src/widgets/view_widgets/geo_view/markers.ts @@ -1,5 +1,3 @@ -import markerIcon from "leaflet/dist/images/marker-icon.png"; -import markerIconShadow from "leaflet/dist/images/marker-shadow.png"; import { marker, latLng, divIcon, Map, type Marker } from "leaflet"; import type FNote from "../../../entities/fnote.js"; import openContextMenu from "./context_menu.js"; @@ -11,8 +9,6 @@ import L from "leaflet"; let gpxLoaded = false; export default function processNoteWithMarker(map: Map, note: FNote, location: string, isEditable: boolean) { - const icon = buildIcon(note.getIcon(), note.getColorClass(), note.title, note.noteId); - const newMarker = marker(latLng(lat, lng), { icon, draggable: isEditable, @@ -78,21 +74,3 @@ export async function processNoteWithGpxTrack(map: Map, note: FNote) { track.addTo(map); return track; } - -function buildIcon(bxIconClass: string, colorClass?: string, title?: string, noteIdLink?: string) { - let html = /*html*/`\ - - - - ${title ?? ""}`; - - if (noteIdLink) { - html = `
${html}
`; - } - - return divIcon({ - html, - iconSize: [25, 41], - iconAnchor: [12, 41] - }); -}