Files
meshtastic-web/packages/web/src/components/Dialog/LocationResponseDialog.tsx
T
68ec7ee5d8 Persistent nodedb (#780)
* Refactor  and consolitdate store imports

- Created a new index file in the core stores directory to export all stores from a single module.
- Updated imports to use consolidated store exports.

* Remove unnecessary import

* Update imports

* First steps to persist nodeDB

* Use named exports

* Change store import after merge

* Persistent nodeDB initial work

* Key mishmatch warning, new serialization handler

* Minor copilot changes

* Add NODEDB_RETENTION_NUM

* Updated tests

* Refactor PKI mismatch logic

* Clear persisted db on reset

* Only persist on featureFlag

* Mock featureFlag in tests

---------

Co-authored-by: philon- <philon-@users.noreply.github.com>
2025-08-24 09:23:20 -04:00

96 lines
2.9 KiB
TypeScript

import { useNodeDB } from "@core/stores";
import type { Protobuf, Types } from "@meshtastic/core";
import { numberToHexUnpadded } from "@noble/curves/abstract/utils";
import { useTranslation } from "react-i18next";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from "../UI/Dialog.tsx";
export interface LocationResponseDialogProps {
location: Types.PacketMetadata<Protobuf.Mesh.Position> | undefined;
open: boolean;
onOpenChange: () => void;
}
export const LocationResponseDialog = ({
location,
open,
onOpenChange,
}: LocationResponseDialogProps) => {
const { t } = useTranslation("dialog");
const { getNode } = useNodeDB();
const from = getNode(location?.from ?? 0);
const longName =
from?.user?.longName ??
(from ? `!${numberToHexUnpadded(from?.num)}` : t("unknown.shortName"));
const shortName =
from?.user?.shortName ??
(from
? `${numberToHexUnpadded(from?.num).substring(0, 4)}`
: t("unknown.shortName"));
const position = location?.data;
const hasCoordinates =
position &&
typeof position.latitudeI === "number" &&
typeof position.longitudeI === "number" &&
typeof position.altitude === "number";
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent>
<DialogClose />
<DialogHeader>
<DialogTitle>
{t("locationResponse.title", {
interpolation: { escapeValue: false },
identifier: `${longName} (${shortName})`,
})}
</DialogTitle>
</DialogHeader>
<DialogDescription>
{hasCoordinates ? (
<div className="ml-5 flex">
<span className="ml-4 border-l-2 border-l-backgroundPrimary pl-2 text-textPrimary">
<p>
{t("locationResponse.coordinates")}
<a
className="text-blue-500 dark:text-blue-400"
href={`https://www.openstreetmap.org/?mlat=${
position.latitudeI ?? 0 / 1e7
}&mlon=${position.longitudeI ?? 0 / 1e7}&layers=N`}
target="_blank"
rel="noreferrer"
>
{" "}
{position.latitudeI ?? 0 / 1e7},{" "}
{position.longitudeI ?? 0 / 1e7}
</a>
</p>
<p>
{t("locationResponse.altitude")} {position.altitude}
{(position.altitude ?? 0) < 1
? t("unit.meter.one")
: t("unit.meter.plural")}
</p>
</span>
</div>
) : (
// Optional: Show a message if coordinates are not available
<p className="text-textPrimary">
{t("locationResponse.noCoordinates")}
</p>
)}
</DialogDescription>
</DialogContent>
</Dialog>
);
};