Chat improvements
This commit is contained in:
@@ -59,7 +59,9 @@ export const Serial = (): JSX.Element => {
|
|||||||
void onConnect(port);
|
void onConnect(port);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
# {index} - {port.getInfo().usbVendorId} - {port.getInfo().usbProductId}
|
{`# ${index} - ${port.getInfo().usbVendorId} - ${
|
||||||
|
port.getInfo().usbProductId
|
||||||
|
}`}
|
||||||
</Button>
|
</Button>
|
||||||
))}
|
))}
|
||||||
{serialPorts.length === 0 && (
|
{serialPorts.length === 0 && (
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
import type React from "react";
|
import type React from "react";
|
||||||
import { ChangeEvent, useState } from "react";
|
|
||||||
|
|
||||||
import { Input } from "@app/components/form/Input.js";
|
|
||||||
import { IconButton } from "@app/components/IconButton.js";
|
|
||||||
import { Message } from "@components/PageComponents/Messages/Message.js";
|
import { Message } from "@components/PageComponents/Messages/Message.js";
|
||||||
import { useDevice } from "@core/providers/useDevice.js";
|
import { useDevice } from "@core/providers/useDevice.js";
|
||||||
import type { Channel } from "@core/stores/deviceStore.js";
|
import type { Channel } from "@core/stores/deviceStore.js";
|
||||||
import { MapPinIcon, PaperAirplaneIcon } from "@heroicons/react/24/outline";
|
|
||||||
import type { Types } from "@meshtastic/meshtasticjs";
|
import { MessageInput } from "./MessageInput.js";
|
||||||
|
|
||||||
export interface ChannelChatProps {
|
export interface ChannelChatProps {
|
||||||
channel: Channel;
|
channel: Channel;
|
||||||
@@ -15,21 +12,6 @@ export interface ChannelChatProps {
|
|||||||
|
|
||||||
export const ChannelChat = ({ channel }: ChannelChatProps): JSX.Element => {
|
export const ChannelChat = ({ channel }: ChannelChatProps): JSX.Element => {
|
||||||
const { nodes, connection, ackMessage } = useDevice();
|
const { nodes, connection, ackMessage } = useDevice();
|
||||||
const [currentMessage, setCurrentMessage] = useState("");
|
|
||||||
|
|
||||||
const sendMessage = (): void => {
|
|
||||||
void connection?.sendText(
|
|
||||||
currentMessage,
|
|
||||||
undefined,
|
|
||||||
true,
|
|
||||||
channel.config.index as Types.ChannelNumber,
|
|
||||||
(id) => {
|
|
||||||
ackMessage(channel.config.index, id);
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
setCurrentMessage("");
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-grow flex-col">
|
<div className="flex flex-grow flex-col">
|
||||||
@@ -50,37 +32,7 @@ export const ChannelChat = ({ channel }: ChannelChatProps): JSX.Element => {
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-2">
|
<MessageInput channel={channel} />
|
||||||
<form
|
|
||||||
className="w-full"
|
|
||||||
onSubmit={(e): void => {
|
|
||||||
e.preventDefault();
|
|
||||||
sendMessage();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="flex flex-grow gap-2">
|
|
||||||
<span className="w-full">
|
|
||||||
<Input
|
|
||||||
minLength={2}
|
|
||||||
label=""
|
|
||||||
placeholder="Enter Message"
|
|
||||||
value={currentMessage}
|
|
||||||
onChange={(e: ChangeEvent<HTMLInputElement>): void => {
|
|
||||||
setCurrentMessage(e.target.value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<IconButton
|
|
||||||
variant="secondary"
|
|
||||||
icon={<PaperAirplaneIcon className="h-4 text-slate-500" />}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<IconButton
|
|
||||||
variant="secondary"
|
|
||||||
icon={<MapPinIcon className="h-4 text-slate-500" />}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
import type React from "react";
|
||||||
|
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
|
||||||
|
import { Input } from "@app/components/form/Input.js";
|
||||||
|
import { IconButton } from "@app/components/IconButton.js";
|
||||||
|
import { useDevice } from "@core/providers/useDevice.js";
|
||||||
|
import type { Channel } from "@core/stores/deviceStore.js";
|
||||||
|
import { MapPinIcon, PaperAirplaneIcon } from "@heroicons/react/24/outline";
|
||||||
|
import type { Types } from "@meshtastic/meshtasticjs";
|
||||||
|
|
||||||
|
export interface MessageInputProps {
|
||||||
|
channel: Channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MessageInput = ({ channel }: MessageInputProps): JSX.Element => {
|
||||||
|
const { connection, ackMessage } = useDevice();
|
||||||
|
|
||||||
|
const { register, handleSubmit } = useForm<{
|
||||||
|
message: string;
|
||||||
|
}>({
|
||||||
|
defaultValues: {
|
||||||
|
message: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = handleSubmit((data) => {
|
||||||
|
void connection?.sendText(
|
||||||
|
data.message,
|
||||||
|
undefined,
|
||||||
|
true,
|
||||||
|
channel.config.index as Types.ChannelNumber,
|
||||||
|
(id) => {
|
||||||
|
ackMessage(channel.config.index, id);
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<form className="w-full" onSubmit={onSubmit}>
|
||||||
|
<div className="flex flex-grow gap-2">
|
||||||
|
<span className="w-full">
|
||||||
|
<Input
|
||||||
|
autoFocus
|
||||||
|
minLength={2}
|
||||||
|
label=""
|
||||||
|
placeholder="Enter Message"
|
||||||
|
{...register("message")}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<IconButton
|
||||||
|
variant="secondary"
|
||||||
|
icon={<PaperAirplaneIcon className="h-4 text-slate-500" />}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<IconButton
|
||||||
|
variant="secondary"
|
||||||
|
icon={<MapPinIcon className="h-4 text-slate-500" />}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user