import { LatLng } from "leaflet";
import { uniqBy } from "lodash-es";
import { LinkIcon, LoaderIcon, MapPinIcon, PaperclipIcon, PlusIcon } from "lucide-react";
import { observer } from "mobx-react-lite";
import { useContext, useState } from "react";
import { Button } from "@/components/ui/button";
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
import { Attachment } from "@/types/proto/api/v1/attachment_service";
import { Location, MemoRelation } from "@/types/proto/api/v1/memo_service";
import { useTranslate } from "@/utils/i18n";
import { MemoEditorContext } from "../types";
import { LinkMemoDialog } from "./InsertMenu/LinkMemoDialog";
import { LocationDialog } from "./InsertMenu/LocationDialog";
import { useFileUpload } from "./InsertMenu/useFileUpload";
import { useLinkMemo } from "./InsertMenu/useLinkMemo";
import { useLocation } from "./InsertMenu/useLocation";
interface Props {
isUploading?: boolean;
location?: Location;
onLocationChange: (location?: Location) => void;
}
const InsertMenu = observer((props: Props) => {
const t = useTranslate();
const context = useContext(MemoEditorContext);
const [linkDialogOpen, setLinkDialogOpen] = useState(false);
const [locationDialogOpen, setLocationDialogOpen] = useState(false);
const { fileInputRef, uploadingFlag, handleFileInputChange, handleUploadClick } = useFileUpload((attachments: Attachment[]) => {
context.setAttachmentList([...context.attachmentList, ...attachments]);
});
const linkMemo = useLinkMemo({
isOpen: linkDialogOpen,
currentMemoName: context.memoName,
existingRelations: context.relationList,
onAddRelation: (relation: MemoRelation) => {
context.setRelationList(uniqBy([...context.relationList, relation], (r) => r.relatedMemo?.name));
setLinkDialogOpen(false);
},
});
const location = useLocation(props.location);
const isUploading = uploadingFlag || props.isUploading;
const handleLocationClick = () => {
setLocationDialogOpen(true);
if (!props.location && !location.locationInitialized) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
location.handlePositionChange(new LatLng(position.coords.latitude, position.coords.longitude));
},
(error) => {
console.error("Geolocation error:", error);
},
);
}
}
};
const handleLocationConfirm = () => {
const newLocation = location.getLocation();
if (newLocation) {
props.onLocationChange(newLocation);
setLocationDialogOpen(false);
}
};
const handleLocationCancel = () => {
location.reset();
setLocationDialogOpen(false);
};
const handlePositionChange = (position: LatLng) => {
location.handlePositionChange(position);
fetch(`https://nominatim.openstreetmap.org/reverse?lat=${position.lat}&lon=${position.lng}&format=json`)
.then((response) => response.json())
.then((data) => {
if (data?.display_name) {
location.setPlaceholder(data.display_name);
} else {
location.setPlaceholder(`${position.lat.toFixed(6)}, ${position.lng.toFixed(6)}`);
}
})
.catch((error) => {
console.error("Failed to fetch reverse geocoding data:", error);
location.setPlaceholder(`${position.lat.toFixed(6)}, ${position.lng.toFixed(6)}`);
});
};
return (
<>
{t("common.upload")}
setLinkDialogOpen(true)}>
{t("tooltip.link-memo")}
{t("tooltip.select-location")}
{/* Hidden file input */}
>
);
});
export default InsertMenu;