Browse Source

fix: linting issues

pull/380/head
Dan Ditomaso 1 year ago
parent
commit
57c76ce242
  1. 1
      package.json
  2. 42
      src/components/CommandPalette.tsx
  3. 10
      src/components/DeviceSelector.tsx
  4. 5
      src/components/Form/FormWrapper.tsx
  5. 8
      src/components/PageComponents/Map/NodeDetail.tsx
  6. 10
      src/components/PageComponents/Messages/Message.tsx
  7. 12
      src/components/UI/Avatar.tsx
  8. 2
      src/components/UI/Sidebar/sidebarButton.tsx
  9. 15
      src/components/generic/Table/index.tsx
  10. 1
      src/index.css
  11. 15
      src/pages/Map.tsx
  12. 79
      src/pages/Messages.tsx
  13. 9
      src/pages/Nodes.tsx

1
package.json

@ -87,5 +87,4 @@
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.7.3" "typescript": "^5.7.3"
} }
} }

42
src/components/CommandPalette.tsx

@ -126,11 +126,8 @@ export const CommandPalette = (): JSX.Element => {
const nodeNum = device.hardware.myNodeNum.toString(); const nodeNum = device.hardware.myNodeNum.toString();
return { return {
label: label: longName ?? nodeNum,
longName ?? nodeNum, icon: <Avatar text={shortName?.toString() ?? nodeNum} />,
icon: (
<Avatar text={shortName?.toString() ?? nodeNum} />
),
action() { action() {
setSelectedDevice(device.id); setSelectedDevice(device.id);
}, },
@ -255,8 +252,9 @@ export const CommandPalette = (): JSX.Element => {
label: "Red", label: "Red",
icon: ( icon: (
<span <span
className={`h-3 w-3 rounded-full ${darkMode ? "bg-[#f25555]" : "bg-[#f28585]" className={`h-3 w-3 rounded-full ${
}`} darkMode ? "bg-[#f25555]" : "bg-[#f28585]"
}`}
/> />
), ),
action() { action() {
@ -267,8 +265,9 @@ export const CommandPalette = (): JSX.Element => {
label: "Orange", label: "Orange",
icon: ( icon: (
<span <span
className={`h-3 w-3 rounded-full ${darkMode ? "bg-[#e1720b]" : "bg-[#edb17a]" className={`h-3 w-3 rounded-full ${
}`} darkMode ? "bg-[#e1720b]" : "bg-[#edb17a]"
}`}
/> />
), ),
action() { action() {
@ -279,8 +278,9 @@ export const CommandPalette = (): JSX.Element => {
label: "Yellow", label: "Yellow",
icon: ( icon: (
<span <span
className={`h-3 w-3 rounded-full ${darkMode ? "bg-[#ac8c1a]" : "bg-[#e0cc87]" className={`h-3 w-3 rounded-full ${
}`} darkMode ? "bg-[#ac8c1a]" : "bg-[#e0cc87]"
}`}
/> />
), ),
action() { action() {
@ -291,8 +291,9 @@ export const CommandPalette = (): JSX.Element => {
label: "Green", label: "Green",
icon: ( icon: (
<span <span
className={`h-3 w-3 rounded-full ${darkMode ? "bg-[#27a341]" : "bg-[#8bc9c5]" className={`h-3 w-3 rounded-full ${
}`} darkMode ? "bg-[#27a341]" : "bg-[#8bc9c5]"
}`}
/> />
), ),
action() { action() {
@ -303,8 +304,9 @@ export const CommandPalette = (): JSX.Element => {
label: "Blue", label: "Blue",
icon: ( icon: (
<span <span
className={`h-3 w-3 rounded-full ${darkMode ? "bg-[#2093fe]" : "bg-[#70afea]" className={`h-3 w-3 rounded-full ${
}`} darkMode ? "bg-[#2093fe]" : "bg-[#70afea]"
}`}
/> />
), ),
action() { action() {
@ -315,8 +317,9 @@ export const CommandPalette = (): JSX.Element => {
label: "Purple", label: "Purple",
icon: ( icon: (
<span <span
className={`h-3 w-3 rounded-full ${darkMode ? "bg-[#926bff]" : "bg-[#a09eef]" className={`h-3 w-3 rounded-full ${
}`} darkMode ? "bg-[#926bff]" : "bg-[#a09eef]"
}`}
/> />
), ),
action() { action() {
@ -327,8 +330,9 @@ export const CommandPalette = (): JSX.Element => {
label: "Pink", label: "Pink",
icon: ( icon: (
<span <span
className={`h-3 w-3 rounded-full ${darkMode ? "bg-[#e454c4]" : "bg-[#dba0c7]" className={`h-3 w-3 rounded-full ${
}`} darkMode ? "bg-[#e454c4]" : "bg-[#dba0c7]"
}`}
/> />
), ),
action() { action() {

10
src/components/DeviceSelector.tsx

@ -11,8 +11,8 @@ import {
SearchIcon, SearchIcon,
SunIcon, SunIcon,
} from "lucide-react"; } from "lucide-react";
import { Avatar } from "./UI/Avatar";
import type { JSX } from "react"; import type { JSX } from "react";
import { Avatar } from "./UI/Avatar";
export const DeviceSelector = (): JSX.Element => { export const DeviceSelector = (): JSX.Element => {
const { getDevices } = useDeviceStore(); const { getDevices } = useDeviceStore();
@ -45,7 +45,13 @@ export const DeviceSelector = (): JSX.Element => {
}} }}
active={selectedDevice === device.id} active={selectedDevice === device.id}
> >
<Avatar text={device.nodes.get(device.hardware.myNodeNum)?.user?.shortName.toString() ?? "UNK"} /> <Avatar
text={
device.nodes
.get(device.hardware.myNodeNum)
?.user?.shortName.toString() ?? "UNK"
}
/>
</DeviceSelectorButton> </DeviceSelectorButton>
))} ))}
<Separator /> <Separator />

5
src/components/Form/FormWrapper.tsx

@ -1,4 +1,5 @@
import { Label } from "@components/UI/Label.tsx"; import { Label } from "@components/UI/Label.tsx";
import type { JSX } from "react";
export interface FieldWrapperProps { export interface FieldWrapperProps {
label: string; label: string;
@ -17,7 +18,7 @@ export const FieldWrapper = ({
validationText, validationText,
}: FieldWrapperProps): JSX.Element => ( }: FieldWrapperProps): JSX.Element => (
<div className="pt-6 sm:pt-5"> <div className="pt-6 sm:pt-5">
<div role="group" aria-labelledby="label-notifications"> <fieldset aria-labelledby="label-notifications">
<div className="sm:grid sm:grid-cols-3 sm:items-baseline sm:gap-4"> <div className="sm:grid sm:grid-cols-3 sm:items-baseline sm:gap-4">
<Label>{label}</Label> <Label>{label}</Label>
<div className="sm:col-span-2"> <div className="sm:col-span-2">
@ -32,6 +33,6 @@ export const FieldWrapper = ({
</div> </div>
</div> </div>
</div> </div>
</div> </fieldset>
</div> </div>
); );

8
src/components/PageComponents/Map/NodeDetail.tsx

@ -1,3 +1,4 @@
import { Avatar } from "@app/components/UI/Avatar";
import { Separator } from "@app/components/UI/Seperator"; import { Separator } from "@app/components/UI/Seperator";
import { H5 } from "@app/components/UI/Typography/H5.tsx"; import { H5 } from "@app/components/UI/Typography/H5.tsx";
import { Subtle } from "@app/components/UI/Typography/Subtle.tsx"; import { Subtle } from "@app/components/UI/Typography/Subtle.tsx";
@ -17,7 +18,7 @@ import {
MountainSnow, MountainSnow,
Star, Star,
} from "lucide-react"; } from "lucide-react";
import { Avatar } from "@app/components/UI/Avatar"; import type { JSX } from "react";
export interface NodeDetailProps { export interface NodeDetailProps {
node: ProtobufType.Mesh.NodeInfo; node: ProtobufType.Mesh.NodeInfo;
@ -68,8 +69,9 @@ export const NodeDetail = ({ node }: NodeDetailProps): JSX.Element => {
{!!node.deviceMetrics?.batteryLevel && ( {!!node.deviceMetrics?.batteryLevel && (
<div <div
className="flex items-center gap-1" className="flex items-center gap-1"
title={`${node.deviceMetrics?.voltage?.toPrecision(3) ?? "Unknown" title={`${
} volts`} node.deviceMetrics?.voltage?.toPrecision(3) ?? "Unknown"
} volts`}
> >
{node.deviceMetrics?.batteryLevel > 100 ? ( {node.deviceMetrics?.batteryLevel > 100 ? (
<BatteryChargingIcon size={22} /> <BatteryChargingIcon size={22} />

10
src/components/PageComponents/Messages/Message.tsx

@ -29,8 +29,9 @@ export const Message = ({
<AlertCircleIcon size={16} className="my-auto text-textSecondary" /> <AlertCircleIcon size={16} className="my-auto text-textSecondary" />
)} )}
<span <span
className={`ml-4 border-l-2 border-l-backgroundPrimary pl-2 ${message.state === "ack" ? "text-textPrimary" : "text-textSecondary" className={`ml-4 border-l-2 border-l-backgroundPrimary pl-2 ${
}`} message.state === "ack" ? "text-textPrimary" : "text-textSecondary"
}`}
> >
{message.data} {message.data}
</span> </span>
@ -66,8 +67,9 @@ export const Message = ({
<AlertCircleIcon size={16} className="my-auto text-textSecondary" /> <AlertCircleIcon size={16} className="my-auto text-textSecondary" />
)} )}
<span <span
className={`ml-4 border-l-2 border-l-backgroundPrimary pl-2 ${message.state === "ack" ? "text-textPrimary" : "text-textSecondary" className={`ml-4 border-l-2 border-l-backgroundPrimary pl-2 ${
}`} message.state === "ack" ? "text-textPrimary" : "text-textSecondary"
}`}
> >
{message.data} {message.data}
</span> </span>

12
src/components/UI/Avatar.tsx

@ -72,28 +72,26 @@ export const Avatar: React.FC<AvatarProps> = ({
const bgColor = getColorFromText(); const bgColor = getColorFromText();
const isLight = ColorUtils.isLight(bgColor); const isLight = ColorUtils.isLight(bgColor);
const textColor = isLight ? "#000000" : "#FFFFFF"; const textColor = isLight ? "#000000" : "#FFFFFF";
const initials = text const initials = text.toUpperCase().slice(0, 4);
.toUpperCase()
.slice(0, 4);
return ( return (
<div <div
className={cn(` className={cn(
`
rounded-full rounded-full
flex flex
items-center items-center
justify-center justify-center
font-semibold`, font-semibold`,
sizes[size], sizes[size],
className) className,
} )}
style={{ style={{
backgroundColor: `rgb(${bgColor.r}, ${bgColor.g}, ${bgColor.b})`, backgroundColor: `rgb(${bgColor.r}, ${bgColor.g}, ${bgColor.b})`,
color: textColor, color: textColor,
}} }}
> >
<p className="p-1">{initials}</p> <p className="p-1">{initials}</p>
</div> </div>
); );
}; };

2
src/components/UI/Sidebar/sidebarButton.tsx

@ -18,7 +18,7 @@ export const SidebarButton = ({
Icon, Icon,
element, element,
onClick, onClick,
className className,
}: SidebarButtonProps): JSX.Element => ( }: SidebarButtonProps): JSX.Element => (
<Button <Button
onClick={onClick} onClick={onClick}

15
src/components/generic/Table/index.tsx

@ -74,15 +74,12 @@ export const Table = ({ headings, rows }: TableProps): JSX.Element => {
> >
<div className="flex gap-2"> <div className="flex gap-2">
{heading.title} {heading.title}
{sortColumn === heading.title && ( {sortColumn === heading.title &&
<> (sortOrder === "asc" ? (
{sortOrder === "asc" ? ( <ChevronUpIcon size={16} />
<ChevronUpIcon size={16} /> ) : (
) : ( <ChevronDownIcon size={16} />
<ChevronDownIcon size={16} /> ))}
)}
</>
)}
</div> </div>
</th> </th>
))} ))}

1
src/index.css

@ -97,6 +97,5 @@
} }
img { img {
-drag: none;
-webkit-user-drag: none; -webkit-user-drag: none;
} }

15
src/pages/Map.tsx

@ -1,4 +1,5 @@
import { NodeDetail } from "@app/components/PageComponents/Map/NodeDetail"; import { NodeDetail } from "@app/components/PageComponents/Map/NodeDetail";
import { Avatar } from "@app/components/UI/Avatar";
import { Subtle } from "@app/components/UI/Typography/Subtle.tsx"; import { Subtle } from "@app/components/UI/Typography/Subtle.tsx";
import { cn } from "@app/core/utils/cn.ts"; import { cn } from "@app/core/utils/cn.ts";
import { PageLayout } from "@components/PageLayout.tsx"; import { PageLayout } from "@components/PageLayout.tsx";
@ -7,6 +8,7 @@ import { SidebarSection } from "@components/UI/Sidebar/SidebarSection.tsx";
import { SidebarButton } from "@components/UI/Sidebar/sidebarButton.tsx"; import { SidebarButton } from "@components/UI/Sidebar/sidebarButton.tsx";
import { useAppStore } from "@core/stores/appStore.ts"; import { useAppStore } from "@core/stores/appStore.ts";
import { useDevice } from "@core/stores/deviceStore.ts"; import { useDevice } from "@core/stores/deviceStore.ts";
import type { Protobuf } from "@meshtastic/js";
import { numberToHexUnpadded } from "@noble/curves/abstract/utils"; import { numberToHexUnpadded } from "@noble/curves/abstract/utils";
import { bbox, lineString } from "@turf/turf"; import { bbox, lineString } from "@turf/turf";
import { import {
@ -18,8 +20,6 @@ import {
import { type JSX, useCallback, useEffect, useState } from "react"; import { type JSX, useCallback, useEffect, useState } from "react";
import { AttributionControl, Marker, Popup, useMap } from "react-map-gl"; import { AttributionControl, Marker, Popup, useMap } from "react-map-gl";
import MapGl from "react-map-gl/maplibre"; import MapGl from "react-map-gl/maplibre";
import type { Protobuf } from "@meshtastic/js";
import { Avatar } from "@app/components/UI/Avatar";
export const MapPage = (): JSX.Element => { export const MapPage = (): JSX.Element => {
const { nodes, waypoints } = useDevice(); const { nodes, waypoints } = useDevice();
@ -135,9 +135,7 @@ export const MapPage = (): JSX.Element => {
renderWorldCopies={false} renderWorldCopies={false}
maxPitch={0} maxPitch={0}
style={{ style={{
filter: darkMode filter: darkMode ? "brightness(0.8)" : "",
? "brightness(0.8)"
: "",
}} }}
dragRotate={false} dragRotate={false}
touchZoomRotate={false} touchZoomRotate={false}
@ -191,7 +189,12 @@ export const MapPage = (): JSX.Element => {
}} }}
> >
<div className="flex cursor-pointer gap-2 rounded-md bg-transparent p-1.5"> <div className="flex cursor-pointer gap-2 rounded-md bg-transparent p-1.5">
<Avatar text={node.user?.shortName.toString() ?? node.num.toString()} size="sm" /> <Avatar
text={
node.user?.shortName.toString() ?? node.num.toString()
}
size="sm"
/>
<Subtle className={cn(zoom < 12 && "hidden")}> <Subtle className={cn(zoom < 12 && "hidden")}>
{node.user?.longName || {node.user?.longName ||
`!${numberToHexUnpadded(node.num)}`} `!${numberToHexUnpadded(node.num)}`}

79
src/pages/Messages.tsx

@ -65,55 +65,60 @@ export const MessagesPage = (): JSX.Element => {
setChatType("direct"); setChatType("direct");
setActiveChat(node.num); setActiveChat(node.num);
}} }}
element={<Avatar text={node.user?.shortName.toString() ?? node.num.toString()} />} element={
<Avatar
text={node.user?.shortName.toString() ?? node.num.toString()}
/>
}
/> />
))} ))}
</SidebarSection> </SidebarSection>
</Sidebar> </Sidebar>
<div className="flex flex-col flex-grow"> <div className="flex flex-col flex-grow">
<PageLayout <PageLayout
label={`Messages: ${chatType === "broadcast" && currentChannel label={`Messages: ${
? getChannelName(currentChannel) chatType === "broadcast" && currentChannel
: chatType === "direct" && nodes.get(activeChat) ? getChannelName(currentChannel)
? (nodes.get(activeChat)?.user?.longName ?? nodeHex) : chatType === "direct" && nodes.get(activeChat)
: "Loading..." ? (nodes.get(activeChat)?.user?.longName ?? nodeHex)
}`} : "Loading..."
}`}
actions={ actions={
chatType === "direct" chatType === "direct"
? [ ? [
{ {
icon: nodes.get(activeChat)?.user?.publicKey.length icon: nodes.get(activeChat)?.user?.publicKey.length
? LockIcon ? LockIcon
: LockOpenIcon, : LockOpenIcon,
iconClasses: nodes.get(activeChat)?.user?.publicKey.length iconClasses: nodes.get(activeChat)?.user?.publicKey.length
? "text-green-600" ? "text-green-600"
: "text-yellow-300", : "text-yellow-300",
async onClick() { async onClick() {
const targetNode = nodes.get(activeChat)?.num; const targetNode = nodes.get(activeChat)?.num;
if (targetNode === undefined) return; if (targetNode === undefined) return;
toast({ toast({
title: nodes.get(activeChat)?.user?.publicKey.length title: nodes.get(activeChat)?.user?.publicKey.length
? "Chat is using PKI encryption." ? "Chat is using PKI encryption."
: "Chat is using PSK encryption.", : "Chat is using PSK encryption.",
}); });
},
}, },
}, {
{ icon: WaypointsIcon,
icon: WaypointsIcon, async onClick() {
async onClick() { const targetNode = nodes.get(activeChat)?.num;
const targetNode = nodes.get(activeChat)?.num; if (targetNode === undefined) return;
if (targetNode === undefined) return;
toast({
title: "Sending Traceroute, please wait...",
});
await connection?.traceRoute(targetNode).then(() =>
toast({ toast({
title: "Traceroute sent.", title: "Sending Traceroute, please wait...",
}), });
); await connection?.traceRoute(targetNode).then(() =>
toast({
title: "Traceroute sent.",
}),
);
},
}, },
}, ]
]
: [] : []
} }
> >

9
src/pages/Nodes.tsx

@ -52,8 +52,8 @@ export const NodesPage = (): JSX.Element => {
{node.user?.longName ?? {node.user?.longName ??
(node.user?.macaddr (node.user?.macaddr
? `Meshtastic ${base16 ? `Meshtastic ${base16
.stringify(node.user?.macaddr.subarray(4, 6) ?? []) .stringify(node.user?.macaddr.subarray(4, 6) ?? [])
.toLowerCase()}` .toLowerCase()}`
: `!${numberToHexUnpadded(node.num)}`)} : `!${numberToHexUnpadded(node.num)}`)}
</h1>, </h1>,
@ -89,8 +89,9 @@ export const NodesPage = (): JSX.Element => {
{node.lastHeard !== 0 {node.lastHeard !== 0
? node.viaMqtt === false && node.hopsAway === 0 ? node.viaMqtt === false && node.hopsAway === 0
? "Direct" ? "Direct"
: `${node.hopsAway.toString()} ${node.hopsAway > 1 ? "hops" : "hop" : `${node.hopsAway.toString()} ${
} away` node.hopsAway > 1 ? "hops" : "hop"
} away`
: "-"} : "-"}
{node.viaMqtt === true ? ", via MQTT" : ""} {node.viaMqtt === true ? ", via MQTT" : ""}
</Mono>, </Mono>,

Loading…
Cancel
Save