You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

140 lines
3.9 KiB

import { create } from "@bufbuild/protobuf";
import { GenericInput } from "@components/Form/FormInput.tsx";
import { Button } from "@components/UI/Button.tsx";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@components/UI/Dialog.tsx";
import { useDevice, useNodeDB } from "@core/stores";
import { zodResolver } from "@hookform/resolvers/zod";
import { Protobuf } from "@meshtastic/core";
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import z from "zod";
import { Label } from "../UI/Label.tsx";
export interface User {
longName: string;
shortName: string;
}
export interface DeviceNameDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
}
export const DeviceNameDialog = ({
open,
onOpenChange,
}: DeviceNameDialogProps) => {
const { t } = useTranslation("dialog");
const { hardware, connection } = useDevice();
const { getNode } = useNodeDB();
const myNode = getNode(hardware.myNodeNum);
const defaultValues = {
shortName: myNode?.user?.shortName ?? "",
longName: myNode?.user?.longName ?? "",
};
const deviceNameSchema = z.object({
longName: z
.string()
.min(1, t("deviceName.validation.longNameMin"))
.max(40, t("deviceName.validation.longNameMax")),
shortName: z
.string()
.min(2, t("deviceName.validation.shortNameMin"))
.max(4, t("deviceName.validation.shortNameMax")),
});
const { getValues, reset, control, handleSubmit } = useForm<User>({
values: defaultValues,
resolver: zodResolver(deviceNameSchema),
});
const onSubmit = handleSubmit((data) => {
connection?.setOwner(
create(Protobuf.Mesh.UserSchema, {
...data,
}),
);
onOpenChange(false);
});
const handleReset = () => {
reset(defaultValues);
};
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent>
<DialogClose />
<DialogHeader>
<DialogTitle>{t("deviceName.title")}</DialogTitle>
<DialogDescription>{t("deviceName.description")}</DialogDescription>
</DialogHeader>
<form onSubmit={onSubmit} className="flex flex-col gap-4">
<div>
<Label htmlFor="longName">{t("deviceName.longName")}</Label>
<GenericInput
control={control}
field={{
name: "longName",
label: t("deviceName.longName"),
type: "text",
properties: {
className: "text-slate-900 dark:text-slate-200",
fieldLength: {
currentValueLength: getValues("longName").length,
max: 40,
min: 1,
showCharacterCount: true,
},
},
}}
/>
</div>
<div>
<Label htmlFor="shortName">{t("deviceName.shortName")}</Label>
<GenericInput
control={control}
field={{
name: "shortName",
label: t("deviceName.shortName"),
type: "text",
properties: {
fieldLength: {
currentValueLength: getValues("shortName").length,
max: 4,
min: 1,
showCharacterCount: true,
},
},
}}
/>
</div>
<DialogFooter>
<Button
type="button"
variant="destructive"
name="reset"
onClick={handleReset}
>
{t("button.reset")}
</Button>
<Button type="submit" name="save">
{t("button.save")}
</Button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
);
};