Commit fcb9e377 authored by Johnny's avatar Johnny

chore: streamline memo editor insert menu

parent b32cba35
import { LatLng } from "leaflet"; import { LatLng } from "leaflet";
import { uniqBy } from "lodash-es"; import { uniqBy } from "lodash-es";
import { FileIcon, LinkIcon, LoaderIcon, MapPinIcon, Maximize2Icon, MoreHorizontalIcon, PlusIcon } from "lucide-react"; import { FileIcon, LinkIcon, LoaderIcon, MapPinIcon, Maximize2Icon, MoreHorizontalIcon, PlusIcon, type LucideIcon } from "lucide-react";
import { useEffect, useState } from "react"; import { useCallback, useEffect, useMemo, useState } from "react";
import { useDebounce } from "react-use"; import { useDebounce } from "react-use";
import { useReverseGeocoding } from "@/components/map"; import { useReverseGeocoding } from "@/components/map";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
...@@ -26,6 +26,7 @@ import type { LocalFile } from "../types/attachment"; ...@@ -26,6 +26,7 @@ import type { LocalFile } from "../types/attachment";
const InsertMenu = (props: InsertMenuProps) => { const InsertMenu = (props: InsertMenuProps) => {
const t = useTranslate(); const t = useTranslate();
const { state, actions, dispatch } = useEditorContext(); const { state, actions, dispatch } = useEditorContext();
const { location: initialLocation, onLocationChange, onToggleFocusMode, isUploading: isUploadingProp } = props;
const [linkDialogOpen, setLinkDialogOpen] = useState(false); const [linkDialogOpen, setLinkDialogOpen] = useState(false);
const [locationDialogOpen, setLocationDialogOpen] = useState(false); const [locationDialogOpen, setLocationDialogOpen] = useState(false);
...@@ -70,11 +71,15 @@ const InsertMenu = (props: InsertMenuProps) => { ...@@ -70,11 +71,15 @@ const InsertMenu = (props: InsertMenuProps) => {
} }
}, [displayName]); }, [displayName]);
const isUploading = selectingFlag || props.isUploading; const isUploading = selectingFlag || isUploadingProp;
const handleLocationClick = () => { const handleOpenLinkDialog = useCallback(() => {
setLinkDialogOpen(true);
}, []);
const handleLocationClick = useCallback(() => {
setLocationDialogOpen(true); setLocationDialogOpen(true);
if (!props.location && !location.locationInitialized) { if (!initialLocation && !location.locationInitialized) {
if (navigator.geolocation) { if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition( navigator.geolocation.getCurrentPosition(
(position) => { (position) => {
...@@ -86,24 +91,54 @@ const InsertMenu = (props: InsertMenuProps) => { ...@@ -86,24 +91,54 @@ const InsertMenu = (props: InsertMenuProps) => {
); );
} }
} }
}; }, [initialLocation, location]);
const handleLocationConfirm = () => { const handleLocationConfirm = useCallback(() => {
const newLocation = location.getLocation(); const newLocation = location.getLocation();
if (newLocation) { if (newLocation) {
props.onLocationChange(newLocation); onLocationChange(newLocation);
setLocationDialogOpen(false); setLocationDialogOpen(false);
} }
}; }, [location, onLocationChange]);
const handleLocationCancel = () => { const handleLocationCancel = useCallback(() => {
location.reset(); location.reset();
setLocationDialogOpen(false); setLocationDialogOpen(false);
}; }, [location]);
const handlePositionChange = (position: LatLng) => { const handlePositionChange = useCallback((position: LatLng) => {
location.handlePositionChange(position); location.handlePositionChange(position);
}; }, [location]);
const handleToggleFocusMode = useCallback(() => {
onToggleFocusMode?.();
setMoreSubmenuOpen(false);
}, [onToggleFocusMode]);
const menuItems = useMemo(
() =>
[
{
key: "upload",
label: t("common.upload"),
icon: FileIcon,
onClick: handleUploadClick,
},
{
key: "link",
label: t("tooltip.link-memo"),
icon: LinkIcon,
onClick: handleOpenLinkDialog,
},
{
key: "location",
label: t("tooltip.select-location"),
icon: MapPinIcon,
onClick: handleLocationClick,
},
] satisfies Array<{ key: string; label: string; icon: LucideIcon; onClick: () => void }>,
[handleLocationClick, handleOpenLinkDialog, handleUploadClick, t],
);
return ( return (
<> <>
...@@ -114,18 +149,12 @@ const InsertMenu = (props: InsertMenuProps) => { ...@@ -114,18 +149,12 @@ const InsertMenu = (props: InsertMenuProps) => {
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent align="start"> <DropdownMenuContent align="start">
<DropdownMenuItem onClick={handleUploadClick}> {menuItems.map((item) => (
<FileIcon className="w-4 h-4" /> <DropdownMenuItem key={item.key} onClick={item.onClick}>
{t("common.upload")} <item.icon className="w-4 h-4" />
</DropdownMenuItem> {item.label}
<DropdownMenuItem onClick={() => setLinkDialogOpen(true)}> </DropdownMenuItem>
<LinkIcon className="w-4 h-4" /> ))}
{t("tooltip.link-memo")}
</DropdownMenuItem>
<DropdownMenuItem onClick={handleLocationClick}>
<MapPinIcon className="w-4 h-4" />
{t("tooltip.select-location")}
</DropdownMenuItem>
{/* View submenu with Focus Mode */} {/* View submenu with Focus Mode */}
<DropdownMenuSub open={moreSubmenuOpen} onOpenChange={setMoreSubmenuOpen}> <DropdownMenuSub open={moreSubmenuOpen} onOpenChange={setMoreSubmenuOpen}>
<DropdownMenuSubTrigger onPointerEnter={handleTriggerEnter} onPointerLeave={handleTriggerLeave}> <DropdownMenuSubTrigger onPointerEnter={handleTriggerEnter} onPointerLeave={handleTriggerLeave}>
...@@ -133,15 +162,9 @@ const InsertMenu = (props: InsertMenuProps) => { ...@@ -133,15 +162,9 @@ const InsertMenu = (props: InsertMenuProps) => {
{t("common.more")} {t("common.more")}
</DropdownMenuSubTrigger> </DropdownMenuSubTrigger>
<DropdownMenuSubContent onPointerEnter={handleContentEnter} onPointerLeave={handleContentLeave}> <DropdownMenuSubContent onPointerEnter={handleContentEnter} onPointerLeave={handleContentLeave}>
<DropdownMenuItem <DropdownMenuItem onClick={handleToggleFocusMode}>
onClick={() => {
props.onToggleFocusMode?.();
setMoreSubmenuOpen(false);
}}
>
<Maximize2Icon className="w-4 h-4" /> <Maximize2Icon className="w-4 h-4" />
{t("editor.focus-mode")} {t("editor.focus-mode")}
<span className="ml-auto text-xs text-muted-foreground opacity-60">⌘⇧F</span>
</DropdownMenuItem> </DropdownMenuItem>
</DropdownMenuSubContent> </DropdownMenuSubContent>
</DropdownMenuSub> </DropdownMenuSub>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment