diff --git a/web/src/components/LeafletMap.tsx b/web/src/components/LeafletMap.tsx index 5e9394b3..08d325a6 100644 --- a/web/src/components/LeafletMap.tsx +++ b/web/src/components/LeafletMap.tsx @@ -5,8 +5,8 @@ import ReactDOMServer from "react-dom/server"; import { MapContainer, Marker, TileLayer, useMapEvents } from "react-leaflet"; const markerIcon = new DivIcon({ - className: "border-none", - html: ReactDOMServer.renderToString(), + className: "relative border-none", + html: ReactDOMServer.renderToString(), }); interface MarkerProps { @@ -41,11 +41,14 @@ interface MapProps { onChange?: (position: LatLng) => void; } +const DEFAULT_CENTER_LAT_LNG = new LatLng(48.8584, 2.2945); + const LeafletMap = (props: MapProps) => { + const position = props.latlng || DEFAULT_CENTER_LAT_LNG; return ( - + - {}} /> + {}} /> ); }; diff --git a/web/src/components/MemoEditor/ActionButton/LocationSelector.tsx b/web/src/components/MemoEditor/ActionButton/LocationSelector.tsx index 1e271d95..8ef609a2 100644 --- a/web/src/components/MemoEditor/ActionButton/LocationSelector.tsx +++ b/web/src/components/MemoEditor/ActionButton/LocationSelector.tsx @@ -16,7 +16,7 @@ interface Props { interface State { initilized: boolean; placeholder: string; - position: LatLng; + position?: LatLng; } const LocationSelector = (props: Props) => { @@ -24,7 +24,7 @@ const LocationSelector = (props: Props) => { const [state, setState] = useState({ initilized: false, placeholder: props.location?.placeholder || "", - position: new LatLng(props.location?.latitude || 0, props.location?.longitude || 0), + position: props.location ? new LatLng(props.location.latitude, props.location.longitude) : undefined, }); const [popoverOpen, setPopoverOpen] = useState(false); @@ -52,7 +52,7 @@ const LocationSelector = (props: Props) => { setState({ ...state, position: new LatLng(lat, lng), initilized: true }); }, (error) => { - handleError(error, "Error getting current position"); + handleError(error, "Failed to get current position"); }, ); } else { @@ -62,6 +62,11 @@ const LocationSelector = (props: Props) => { }, [popoverOpen]); useEffect(() => { + if (!state.position) { + setState({ ...state, placeholder: "" }); + return; + } + // Fetch reverse geocoding data. fetch(`https://nominatim.openstreetmap.org/reverse?lat=${state.position.lat}&lon=${state.position.lng}&format=json`) .then((response) => response.json()) @@ -96,7 +101,7 @@ const LocationSelector = (props: Props) => { {props.location.placeholder} - + )} @@ -106,25 +111,34 @@ const LocationSelector = (props: Props) => {
+ [{state.position.lat.toFixed(3)}, {state.position.lng.toFixed(3)}] + + ) : null + } onChange={(e) => setState((state) => ({ ...state, placeholder: e.target.value }))} />
diff --git a/web/src/components/MemoLocationView.tsx b/web/src/components/MemoLocationView.tsx new file mode 100644 index 00000000..71d0c9f7 --- /dev/null +++ b/web/src/components/MemoLocationView.tsx @@ -0,0 +1,35 @@ +import { LatLng } from "leaflet"; +import { MapPinIcon } from "lucide-react"; +import { useState } from "react"; +import { Location } from "@/types/proto/api/v1/memo_service"; +import LeafletMap from "./LeafletMap"; +import { Popover, PopoverContent, PopoverTrigger } from "./ui/Popover"; + +interface Props { + location: Location; +} + +const MemoLocationView: React.FC = (props: Props) => { + const { location } = props; + const [popoverOpen, setPopoverOpen] = useState(false); + + return ( + + +

+ + + {location.placeholder ? location.placeholder : `[${location.latitude}, ${location.longitude}]`} + +

+
+ +
+ +
+
+
+ ); +}; + +export default MemoLocationView; diff --git a/web/src/components/MemoView.tsx b/web/src/components/MemoView.tsx index ff856353..63e669cf 100644 --- a/web/src/components/MemoView.tsx +++ b/web/src/components/MemoView.tsx @@ -1,6 +1,6 @@ import { Tooltip } from "@mui/joy"; import clsx from "clsx"; -import { BookmarkIcon, MapPinIcon, MessageCircleMoreIcon } from "lucide-react"; +import { BookmarkIcon, MessageCircleMoreIcon } from "lucide-react"; import { memo, useCallback, useEffect, useRef, useState } from "react"; import { Link, useLocation } from "react-router-dom"; import useCurrentUser from "@/hooks/useCurrentUser"; @@ -16,6 +16,7 @@ import { isSuperUser } from "@/utils/user"; import MemoActionMenu from "./MemoActionMenu"; import MemoContent from "./MemoContent"; import MemoEditor from "./MemoEditor"; +import MemoLocationView from "./MemoLocationView"; import MemoReactionistView from "./MemoReactionListView"; import MemoRelationListView from "./MemoRelationListView"; import MemoResourceListView from "./MemoResourceListView"; @@ -198,14 +199,7 @@ const MemoView: React.FC = (props: Props) => { onDoubleClick={handleMemoContentDoubleClick} compact={props.compact && workspaceMemoRelatedSetting.enableAutoCompact} /> - {memo.location && ( -

- - - {memo.location.placeholder ? memo.location.placeholder : `[${memo.location.latitude}, ${memo.location.longitude}]`} - -

- )} + {memo.location && }