diff --git a/package.json b/package.json index 1c055073..26e9d0a8 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "license": "GPL-3.0-only", "scripts": { "build": "pnpm check && rsbuild build", + "build:analyze": "BUNDLE_ANALYZE=true rsbuild build", "check": "biome check src/", "check:fix": "pnpm check --write src/", "format": "biome format --write src/", @@ -17,6 +18,9 @@ "simple-git-hooks": { "pre-commit": "npm run check:fix && npm run format" }, + "lint-staged": { + "*.{ts,tsx}": ["npm run check:fix", "npm run format"] + }, "repository": { "type": "git", "url": "git+https://github.com/meshtastic/web.git" diff --git a/src/components/PageComponents/Config/Device.tsx b/src/components/PageComponents/Config/Device.tsx index 9ef11904..17ee8cb2 100644 --- a/src/components/PageComponents/Config/Device.tsx +++ b/src/components/PageComponents/Config/Device.tsx @@ -46,7 +46,7 @@ export const Device = (): JSX.Element => { "Lost and Found": Protobuf.Config.Config_DeviceConfig_Role.LOST_AND_FOUND, "TAK Tracker": - Protobuf.Config.Config_DeviceConfig_Role.SENSOR, + Protobuf.Config.Config_DeviceConfig_Role.TAK_TRACKER, }, formatEnumName: true, }, diff --git a/src/components/PageComponents/Messages/ChannelChat.tsx b/src/components/PageComponents/Messages/ChannelChat.tsx index 47c9095c..08d79832 100644 --- a/src/components/PageComponents/Messages/ChannelChat.tsx +++ b/src/components/PageComponents/Messages/ChannelChat.tsx @@ -80,7 +80,7 @@ export const ChannelChat = ({
- +
); diff --git a/src/components/PageComponents/Messages/MessageInput.tsx b/src/components/PageComponents/Messages/MessageInput.tsx index 079cb448..2e7954c9 100644 --- a/src/components/PageComponents/Messages/MessageInput.tsx +++ b/src/components/PageComponents/Messages/MessageInput.tsx @@ -9,11 +9,13 @@ import { type JSX, useCallback, useMemo, useState } from "react"; export interface MessageInputProps { to: Types.Destination; channel: Types.ChannelNumber; + maxBytes: number; } export const MessageInput = ({ to, channel, + maxBytes, }: MessageInputProps): JSX.Element => { const { connection, @@ -24,6 +26,7 @@ export const MessageInput = ({ } = useDevice(); const myNodeNum = hardware.myNodeNum; const [localDraft, setLocalDraft] = useState(messageDraft); + const [messageBytes, setMessageBytes] = useState(maxBytes); const debouncedSetMessageDraft = useMemo( () => debounce(setMessageDraft, 300), @@ -60,8 +63,12 @@ export const MessageInput = ({ const handleInputChange = (e: React.ChangeEvent) => { const newValue = e.target.value; - setLocalDraft(newValue); - debouncedSetMessageDraft(newValue); + const byteLength = new Blob([newValue]).size; + if (byteLength <= maxBytes) { + setLocalDraft(newValue); + debouncedSetMessageDraft(newValue); + setMessageBytes(maxBytes - byteLength); + } }; return ( @@ -85,6 +92,9 @@ export const MessageInput = ({ onChange={handleInputChange} /> +
+ {messageBytes}/{maxBytes} +
diff --git a/src/components/PageLayout.tsx b/src/components/PageLayout.tsx index f25eecab..81ec4915 100644 --- a/src/components/PageLayout.tsx +++ b/src/components/PageLayout.tsx @@ -35,7 +35,7 @@ export const PageLayout = ({
{actions?.map((action, index) => (
- + ); })} diff --git a/src/pages/Messages.tsx b/src/pages/Messages.tsx index 533c7c48..02ce37c6 100644 --- a/src/pages/Messages.tsx +++ b/src/pages/Messages.tsx @@ -20,9 +20,12 @@ const MessagesPage = () => { const [activeChat, setActiveChat] = useState( Types.ChannelNumber.Primary, ); - const filteredNodes = Array.from(nodes.values()).filter( - (n) => n.num !== hardware.myNodeNum, - ); + const [searchTerm, setSearchTerm] = useState(""); + const filteredNodes = Array.from(nodes.values()).filter((node) => { + if (node.num === hardware.myNodeNum) return false; + const nodeName = node.user?.longName ?? `!${numberToHexUnpadded(node.num)}`; + return nodeName.toLowerCase().includes(searchTerm.toLowerCase()); + }); const allChannels = Array.from(channels.values()); const filteredChannels = allChannels.filter( (ch) => ch.role !== Protobuf.Channel.Channel_Role.DISABLED, @@ -56,6 +59,15 @@ const MessagesPage = () => { ))} +
+ setSearchTerm(e.target.value)} + className="w-full p-2 border border-gray-300 rounded bg-white text-black" + /> +
{filteredNodes.map((node) => ( { const { nodes, hardware, setDialogOpen } = useDevice(); const { setNodeNumToBeRemoved } = useAppStore(); + const [searchTerm, setSearchTerm] = useState(""); - const filteredNodes = Array.from(nodes.values()).filter( - (n) => n.num !== hardware.myNodeNum, - ); + const filteredNodes = Array.from(nodes.values()).filter((node) => { + if (node.num === hardware.myNodeNum) return false; + const nodeName = node.user?.longName ?? `!${numberToHexUnpadded(node.num)}`; + return nodeName.toLowerCase().includes(searchTerm.toLowerCase()); + }); return ( <>
+
+ setSearchTerm(e.target.value)} + className="w-full p-2 border border-gray-300 rounded bg-white text-black" + /> +