From 4cf326661fb23a207eb2941c60510a6ecbaa3233 Mon Sep 17 00:00:00 2001 From: Sacha Weatherstone Date: Wed, 23 Feb 2022 14:14:33 +1100 Subject: [PATCH] WIP --- package.json | 3 +- pnpm-lock.yaml | 10 ++-- src/App.tsx | 4 +- src/components/Connection.tsx | 42 ++++++++++----- src/components/MapBox/MapboxProvider.tsx | 21 ++++---- src/components/MapBox/mapboxContext.ts | 9 ++-- src/components/connection/BLE.tsx | 10 ++-- src/components/connection/Serial.tsx | 10 ++-- src/components/generic/Card.tsx | 53 +++++++++++++++---- src/components/generic/ContextMenu.tsx | 7 +-- src/components/generic/Modal.tsx | 18 ++++--- .../generic/Sidebar/CollapsibleSection.tsx | 9 ++-- .../generic/Sidebar/ExternalSection.tsx | 15 ++++-- src/components/generic/button/Button.tsx | 32 ++++++----- src/components/generic/button/IconButton.tsx | 22 +++++--- src/components/generic/form/Checkbox.tsx | 5 +- src/components/generic/form/Input.tsx | 48 +++++++++-------- src/components/generic/form/Select.tsx | 5 +- src/components/layout/Sidebar/ButtonNav.tsx | 2 +- .../layout/Sidebar/Settings/Channels.tsx | 9 ++-- .../layout/Sidebar/Settings/Index.tsx | 7 +-- .../layout/Sidebar/Settings/Position.tsx | 7 +-- .../layout/Sidebar/Settings/Power.tsx | 7 +-- .../layout/Sidebar/Settings/Radio.tsx | 7 +-- .../layout/Sidebar/Settings/User.tsx | 7 +-- .../layout/Sidebar/Settings/WiFi.tsx | 7 +-- .../Sidebar/Settings/channels/Channels.tsx | 11 ++-- .../plugins/ExternalNotifications.tsx | 7 +-- .../Sidebar/Settings/plugins/RangeTest.tsx | 7 +-- .../Sidebar/Settings/plugins/Serial.tsx | 7 +-- .../Sidebar/Settings/plugins/StoreForward.tsx | 7 +-- src/components/layout/Sidebar/index.tsx | 5 +- src/components/menu/BottomNav.tsx | 5 +- src/components/modals/VersionInfo.tsx | 7 +-- src/core/slices/mapSlice.ts | 8 +-- src/hooks/useCreateMapbox.ts | 21 ++++---- src/hooks/useMapbox.ts | 4 +- src/index.tsx | 7 +-- src/pages/Extensions/Debug.tsx | 2 +- src/pages/Extensions/FileBrowser.tsx | 25 +++++---- src/pages/Extensions/Index.tsx | 10 +++- src/pages/Extensions/Info.tsx | 18 +++++-- src/pages/Extensions/Logs.tsx | 19 ++++--- src/pages/Map/MapContainer.tsx | 5 +- src/pages/Map/Marker.tsx | 24 +++++---- src/pages/Map/index.tsx | 5 +- src/pages/Messages/ChannelChat.tsx | 4 +- src/pages/Messages/DmChat.tsx | 4 +- src/pages/Messages/MessageBar.tsx | 16 ++++-- src/pages/Messages/index.tsx | 11 ++-- src/pages/Nodes/NodeCard.tsx | 15 +++--- src/pages/Nodes/index.tsx | 14 ++--- tailwind.config.cjs | 2 - vite.config.ts | 12 ++--- 54 files changed, 403 insertions(+), 255 deletions(-) diff --git a/package.json b/package.json index 796c6d4f..9cba499e 100644 --- a/package.json +++ b/package.json @@ -26,11 +26,12 @@ "@reduxjs/toolkit": "^1.7.2", "@tippyjs/react": "^4.2.6", "base64-js": "^1.5.1", - "framer-motion": "^6.2.6", + "framer-motion": "^6.2.7", "mapbox-gl": "^2.7.0", "prettier": "^2.5.1", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-draggable": "^4.4.4", "react-error-boundary": "^3.1.4", "react-flow-renderer": "^10.0.0-next.39", "react-hook-form": "^7.27.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a13d622f..add54fc5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,13 +15,14 @@ specifiers: '@vitejs/plugin-react': ^1.2.0 autoprefixer: ^10.4.2 base64-js: ^1.5.1 - framer-motion: ^6.2.6 + framer-motion: ^6.2.7 gzipper: ^7.0.0 mapbox-gl: ^2.7.0 postcss: ^8.4.6 prettier: ^2.5.1 react: ^17.0.2 react-dom: ^17.0.2 + react-draggable: ^4.4.4 react-error-boundary: ^3.1.4 react-flow-renderer: ^10.0.0-next.39 react-hook-form: ^7.27.1 @@ -53,11 +54,12 @@ dependencies: '@reduxjs/toolkit': 1.7.2_react-redux@7.2.6+react@17.0.2 '@tippyjs/react': 4.2.6_react-dom@17.0.2+react@17.0.2 base64-js: 1.5.1 - framer-motion: 6.2.6_react-dom@17.0.2+react@17.0.2 + framer-motion: 6.2.7_react-dom@17.0.2+react@17.0.2 mapbox-gl: 2.7.0 prettier: 2.5.1 react: 17.0.2 react-dom: 17.0.2_react@17.0.2 + react-draggable: 4.4.4_react-dom@17.0.2+react@17.0.2 react-error-boundary: 3.1.4_react@17.0.2 react-flow-renderer: 10.0.0-next.39_react-dom@17.0.2+react@17.0.2 react-hook-form: 7.27.1_react@17.0.2 @@ -3448,8 +3450,8 @@ packages: resolution: {integrity: sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg==} dev: true - /framer-motion/6.2.6_react-dom@17.0.2+react@17.0.2: - resolution: {integrity: sha512-7eGav5MxEEzDHozQTDY6+psTIOw2i2kM1QVoJOC3bCp9VOKoo+mKR5n7aT5JPh7ksEKFYJYz0GJDils/9S+oLA==} + /framer-motion/6.2.7_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-RExmZCFpJ3OCakoXmZz8iW8ZI5MoaHmVadydetvTSrNaKmZ7ZC/JDQpNyw1NoDG+fchRGP86lXoiTFSQuin+Cg==} peerDependencies: react: '>=16.8 || ^17.0.0 || ^18.0.0' react-dom: '>=16.8 || ^17.0.0 || ^18.0.0' diff --git a/src/App.tsx b/src/App.tsx index 333f003e..e028e12e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -13,10 +13,10 @@ import { NotFound } from '@pages/NotFound'; export const App = (): JSX.Element => { const route = useRoute(); - const darkMode = useAppSelector((state) => state.app.darkMode); + const appState = useAppSelector((state) => state.app); return ( -
+
diff --git a/src/components/Connection.tsx b/src/components/Connection.tsx index 5510935c..6534e607 100644 --- a/src/components/Connection.tsx +++ b/src/components/Connection.tsx @@ -1,6 +1,7 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect } from 'react'; -import { AnimatePresence } from 'framer-motion'; +import { AnimatePresence, m } from 'framer-motion'; import { BLE } from '@components/connection/BLE'; import { HTTP } from '@components/connection/HTTP'; @@ -21,10 +22,10 @@ import { Types } from '@meshtastic/meshtasticjs'; export const Connection = (): JSX.Element => { const dispatch = useAppDispatch(); - const state = useAppSelector((state) => state.meshtastic); + const meshtasticState = useAppSelector((state) => state.meshtastic); const appState = useAppSelector((state) => state.app); - React.useEffect(() => { + useEffect(() => { if (!import.meta.env.VITE_PUBLIC_HOSTED) { dispatch( setConnectionParams({ @@ -41,11 +42,11 @@ export const Connection = (): JSX.Element => { } }, [dispatch]); - React.useEffect(() => { - if (state.ready) { + useEffect(() => { + if (meshtasticState.ready) { dispatch(closeConnectionModal()); } - }, [state.ready, dispatch]); + }, [meshtasticState.ready, dispatch]); return ( @@ -67,14 +68,14 @@ export const Connection = (): JSX.Element => { dispatch(setConnType(parseInt(e.target.value))); }} disabled={ - state.deviceStatus === + meshtasticState.deviceStatus === Types.DeviceStatusEnum.DEVICE_CONNECTED } /> {appState.connType === connType.HTTP && ( @@ -82,7 +83,7 @@ export const Connection = (): JSX.Element => { {appState.connType === connType.BLE && ( @@ -90,7 +91,7 @@ export const Connection = (): JSX.Element => { {appState.connType === connType.SERIAL && ( @@ -98,8 +99,23 @@ export const Connection = (): JSX.Element => {
-
- {state.logs +
+ {meshtasticState.logs.length === 0 && ( +
+ +
+ )} + {meshtasticState.logs .filter((log) => { return ![ Types.Emitter.handleFromRadio, diff --git a/src/components/MapBox/MapboxProvider.tsx b/src/components/MapBox/MapboxProvider.tsx index a2da343f..f0c7c781 100644 --- a/src/components/MapBox/MapboxProvider.tsx +++ b/src/components/MapBox/MapboxProvider.tsx @@ -1,6 +1,7 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect, useRef } from 'react'; -import mapboxgl from 'mapbox-gl'; +import { ScaleControl } from 'mapbox-gl'; import { MapboxContext } from '@components/MapBox/mapboxContext'; import { @@ -26,7 +27,7 @@ export const MapboxProvider = ({ const darkMode = useAppSelector((state) => state.app.darkMode); const mapState = useAppSelector((state) => state.map); const dispatch = useAppDispatch(); - const ref = React.useRef(null); + const ref = useRef(null); const map = useCreateMapbox({ ref, @@ -41,9 +42,9 @@ export const MapboxProvider = ({ }, }); - React.useEffect(() => { + useEffect(() => { map?.on('load', () => { - map.addControl(new mapboxgl.ScaleControl()); + map.addControl(new ScaleControl()); }); map?.on('styledata', () => { if (!map.getSource('mapbox-dem')) { @@ -73,14 +74,14 @@ export const MapboxProvider = ({ }); }, [dispatch, map, mapState.exaggeration]); - React.useEffect(() => { + useEffect(() => { const center = map?.getCenter(); if (center !== mapState.latLng) { map?.setCenter(mapState.latLng); } }, [map, mapState.latLng]); - React.useEffect(() => { + useEffect(() => { if (['Light', 'Dark'].includes(mapState.style)) { dispatch(setMapStyle(darkMode ? 'Dark' : 'Light')); } @@ -89,7 +90,7 @@ export const MapboxProvider = ({ /** * Hill Shading */ - React.useEffect(() => { + useEffect(() => { if (map?.loaded()) { if (mapState.hillShade) { map.addLayer( @@ -111,7 +112,7 @@ export const MapboxProvider = ({ /** * Exaggeration */ - React.useEffect(() => { + useEffect(() => { if (map?.loaded()) { map.setTerrain({ source: 'mapbox-dem', @@ -123,7 +124,7 @@ export const MapboxProvider = ({ /** * Map Style */ - React.useEffect(() => { + useEffect(() => { if (map?.loaded()) { map.setStyle(MapStyles[mapState.style].data); } diff --git a/src/components/MapBox/mapboxContext.ts b/src/components/MapBox/mapboxContext.ts index 071e5d34..9faee065 100644 --- a/src/components/MapBox/mapboxContext.ts +++ b/src/components/MapBox/mapboxContext.ts @@ -1,12 +1,13 @@ -import React from 'react'; +import type React from 'react'; +import { createContext } from 'react'; -import type mapbox from 'mapbox-gl'; +import type { Map } from 'mapbox-gl'; export interface MapboxContextValue { ref: React.Ref; - map?: mapbox.Map; + map?: Map; } -export const MapboxContext = React.createContext( +export const MapboxContext = createContext( {} as MapboxContextValue, ); diff --git a/src/components/connection/BLE.tsx b/src/components/connection/BLE.tsx index 1c93ae74..94f649ae 100644 --- a/src/components/connection/BLE.tsx +++ b/src/components/connection/BLE.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import { FiArrowRightCircle } from 'react-icons/fi'; @@ -14,19 +15,19 @@ export interface BLEProps { } export const BLE = ({ connecting }: BLEProps): JSX.Element => { - const [bleDevices, setBleDevices] = React.useState([]); + const [bleDevices, setBleDevices] = useState([]); const { handleSubmit } = useForm<{ device?: BluetoothDevice; }>(); - const updateBleDeviceList = React.useCallback(async (): Promise => { + const updateBleDeviceList = useCallback(async (): Promise => { const ble = new IBLEConnection(); const devices = await ble.getDevices(); setBleDevices(devices); }, []); - React.useEffect(() => { + useEffect(() => { void updateBleDeviceList(); }, [updateBleDeviceList]); @@ -46,6 +47,7 @@ export const BLE = ({ connecting }: BLEProps): JSX.Element => { >
{device.name}
=> { await setConnection(connType.BLE); }} diff --git a/src/components/connection/Serial.tsx b/src/components/connection/Serial.tsx index 97e9ea6e..fcbcec63 100644 --- a/src/components/connection/Serial.tsx +++ b/src/components/connection/Serial.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import { FiArrowRightCircle } from 'react-icons/fi'; @@ -15,20 +16,20 @@ export interface SerialProps { } export const Serial = ({ connecting }: SerialProps): JSX.Element => { - const [serialDevices, setSerialDevices] = React.useState([]); + const [serialDevices, setSerialDevices] = useState([]); const dispatch = useAppDispatch(); const { handleSubmit } = useForm<{ device?: SerialPort; }>(); - const updateSerialDeviceList = React.useCallback(async (): Promise => { + const updateSerialDeviceList = useCallback(async (): Promise => { const serial = new ISerialConnection(); const devices = await serial.getPorts(); setSerialDevices(devices); }, []); - React.useEffect(() => { + useEffect(() => { void updateSerialDeviceList(); }, [updateSerialDeviceList]); @@ -53,6 +54,7 @@ export const Serial = ({ connecting }: SerialProps): JSX.Element => {

=> { dispatch( setConnectionParams({ diff --git a/src/components/generic/Card.tsx b/src/components/generic/Card.tsx index a94b62ca..bf95e070 100644 --- a/src/components/generic/Card.tsx +++ b/src/components/generic/Card.tsx @@ -1,21 +1,56 @@ import type React from 'react'; import { m } from 'framer-motion'; +import Draggable from 'react-draggable'; export interface CardProps { className?: string; + title?: string; + actions?: React.ReactNode; children: React.ReactNode; + border?: boolean; + draggable?: boolean; } -export const Card = ({ className, children }: CardProps): JSX.Element => { +export const Card = ({ + className, + title, + actions, + draggable, + border, + children, +}: CardProps): JSX.Element => { return ( - - {children} - + +
+ {(title || actions) && ( +
+
+
{title}
+ {actions} +
+
+ )} + + + {children} + +
+
); }; diff --git a/src/components/generic/ContextMenu.tsx b/src/components/generic/ContextMenu.tsx index 18fafe90..bed23a93 100644 --- a/src/components/generic/ContextMenu.tsx +++ b/src/components/generic/ContextMenu.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useState } from 'react'; import { FiActivity, FiAperture, FiTag } from 'react-icons/fi'; @@ -13,8 +14,8 @@ export const ContextMenu = ({ items, children, }: ContextMenuProps): JSX.Element => { - const [visible, setVisible] = React.useState(false); - const [position, setPosition] = React.useState({ x: 0, y: 0 }); + const [visible, setVisible] = useState(false); + const [position, setPosition] = useState({ x: 0, y: 0 }); return (
- -
-
- {title} -
-
+ {actions} } onClick={onClose} /> -
-
+ + } + className="relative flex-col gap-4 " + > {children}
diff --git a/src/components/generic/Sidebar/CollapsibleSection.tsx b/src/components/generic/Sidebar/CollapsibleSection.tsx index ff44b77c..3e83c33d 100644 --- a/src/components/generic/Sidebar/CollapsibleSection.tsx +++ b/src/components/generic/Sidebar/CollapsibleSection.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useState } from 'react'; import { AnimatePresence, m } from 'framer-motion'; import { FiArrowUp } from 'react-icons/fi'; @@ -14,13 +15,15 @@ export const CollapsibleSection = ({ icon, children, }: CollapsibleSectionProps): JSX.Element => { - const [open, setOpen] = React.useState(false); + const [open, setOpen] = useState(false); const toggleOpen = (): void => setOpen(!open); return ( void; } export const ExternalSection = ({ title, icon, + active, onClick, }: ExternalSectionProps): JSX.Element => { - const [open, setOpen] = React.useState(false); + const [open, setOpen] = useState(false); const toggleOpen = (): void => setOpen(!open); return ( - + diff --git a/src/components/generic/button/Button.tsx b/src/components/generic/button/Button.tsx index 4b99737b..4b6e72a5 100644 --- a/src/components/generic/button/Button.tsx +++ b/src/components/generic/button/Button.tsx @@ -1,35 +1,37 @@ -import React from 'react'; +import type React from 'react'; +import { useState } from 'react'; +import { m } from 'framer-motion'; import { FiCheck } from 'react-icons/fi'; -type DefaultButtonProps = JSX.IntrinsicElements['button']; - export enum ButtonSize { Small = 'small', Medium = 'medium', Large = 'large', } -export interface ButtonProps extends DefaultButtonProps { +export interface ButtonProps { icon?: JSX.Element; - active?: boolean; border?: boolean; + className?: string; + disabled?: boolean; + children?: React.ReactNode; size?: ButtonSize; + onClick?: () => void; confirmAction?: () => void; } export const Button = ({ icon, className, - active, border, size = ButtonSize.Medium, confirmAction, + onClick, disabled, children, - ...props }: ButtonProps): JSX.Element => { - const [hasConfirmed, setHasConfirmed] = React.useState(false); + const [hasConfirmed, setHasConfirmed] = useState(false); const handleConfirm = (): void => { if (typeof confirmAction == 'function') { @@ -44,9 +46,11 @@ export const Button = ({ }; return ( - + ); }; diff --git a/src/components/generic/button/IconButton.tsx b/src/components/generic/button/IconButton.tsx index b63bfe85..a62f7416 100644 --- a/src/components/generic/button/IconButton.tsx +++ b/src/components/generic/button/IconButton.tsx @@ -1,5 +1,7 @@ import type React from 'react'; +import { m } from 'framer-motion'; + import { Tooltip } from '@components/generic/Tooltip'; type DefaulButtonProps = JSX.IntrinsicElements['button']; @@ -7,26 +9,32 @@ type DefaulButtonProps = JSX.IntrinsicElements['button']; export interface IconButtonProps extends DefaulButtonProps { icon: React.ReactNode; tooltip?: string; + nested?: boolean; active?: boolean; } export const IconButton = ({ icon, - active, tooltip, + nested, + active, disabled, ...props }: IconButtonProps): JSX.Element => { return ( -
+ -
+
); }; diff --git a/src/components/generic/form/Checkbox.tsx b/src/components/generic/form/Checkbox.tsx index b8526b13..4f531b73 100644 --- a/src/components/generic/form/Checkbox.tsx +++ b/src/components/generic/form/Checkbox.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { forwardRef } from 'react'; import { Label } from '@components/generic/form/Label'; @@ -12,7 +13,7 @@ export interface CheckboxProps extends DefaultInputProps { error?: boolean; } -export const Checkbox = React.forwardRef( +export const Checkbox = forwardRef( function Input( { label, valid, validationMessage, id, error, ...props }: CheckboxProps, ref, diff --git a/src/components/generic/form/Input.tsx b/src/components/generic/form/Input.tsx index 0d2fc926..78c3a4f9 100644 --- a/src/components/generic/form/Input.tsx +++ b/src/components/generic/form/Input.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { forwardRef } from 'react'; import { InputWrapper } from '@components/generic/form/InputWrapper'; import { Label } from '@components/generic/form/Label'; @@ -13,25 +14,26 @@ export interface InputProps extends DefaultInputProps { suffix?: string; } -export const Input = React.forwardRef( - function Input({ label, error, action, suffix, ...props }: InputProps, ref) { - return ( -
- {label &&
- ); - }, -); +export const Input = forwardRef(function Input( + { label, error, action, suffix, ...props }: InputProps, + ref, +) { + return ( +
+ {label &&
+ ); +}); diff --git a/src/components/generic/form/Select.tsx b/src/components/generic/form/Select.tsx index 43a525ce..8aa64084 100644 --- a/src/components/generic/form/Select.tsx +++ b/src/components/generic/form/Select.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { forwardRef } from 'react'; import { InputWrapper } from '@components/generic/form/InputWrapper'; import { Label } from '@components/generic/form/Label'; @@ -16,7 +17,7 @@ export interface SelectProps extends DefaultSelectProps { small?: boolean; } -export const Select = React.forwardRef( +export const Select = forwardRef( ({ options, optionsEnum, label, error, small, ...props }, ref) => { const optionsEnumValues = optionsEnum ? Object.entries(optionsEnum).filter( diff --git a/src/components/layout/Sidebar/ButtonNav.tsx b/src/components/layout/Sidebar/ButtonNav.tsx index 365b5317..7d7cb3f2 100644 --- a/src/components/layout/Sidebar/ButtonNav.tsx +++ b/src/components/layout/Sidebar/ButtonNav.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import type React from 'react'; import { FiMessageCircle, FiSettings } from 'react-icons/fi'; import { RiMindMap, RiRoadMapLine } from 'react-icons/ri'; diff --git a/src/components/layout/Sidebar/Settings/Channels.tsx b/src/components/layout/Sidebar/Settings/Channels.tsx index 60ea0450..9c49ad82 100644 --- a/src/components/layout/Sidebar/Settings/Channels.tsx +++ b/src/components/layout/Sidebar/Settings/Channels.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useState } from 'react'; import { useForm } from 'react-hook-form'; import { FiSave } from 'react-icons/fi'; @@ -17,9 +18,9 @@ export const Channels = (): JSX.Element => { channels.find( (channel) => channel.role === Protobuf.Channel_Role.PRIMARY, ) ?? channels[0]; - const [usePreset, setUsePreset] = React.useState(true); - const [loading, setLoading] = React.useState(false); - const [selectedChannel, setSelectedChannel] = React.useState< + const [usePreset, setUsePreset] = useState(true); + const [loading, setLoading] = useState(false); + const [selectedChannel, setSelectedChannel] = useState< Protobuf.Channel | undefined >(); diff --git a/src/components/layout/Sidebar/Settings/Index.tsx b/src/components/layout/Sidebar/Settings/Index.tsx index ecd84afc..a7123ece 100644 --- a/src/components/layout/Sidebar/Settings/Index.tsx +++ b/src/components/layout/Sidebar/Settings/Index.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useState } from 'react'; import { FiAlignLeft, @@ -38,8 +39,8 @@ export interface SettingsProps { } export const Settings = ({ open, setOpen }: SettingsProps): JSX.Element => { - const [pluginsOpen, setPluginsOpen] = React.useState(false); - const [channelsOpen, setChannelsOpen] = React.useState(false); + const [pluginsOpen, setPluginsOpen] = useState(false); + const [channelsOpen, setChannelsOpen] = useState(false); const { rangeTestPluginEnabled, extNotificationPluginEnabled, diff --git a/src/components/layout/Sidebar/Settings/Position.tsx b/src/components/layout/Sidebar/Settings/Position.tsx index 3fdfb92a..e1bed79b 100644 --- a/src/components/layout/Sidebar/Settings/Position.tsx +++ b/src/components/layout/Sidebar/Settings/Position.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; import { FiSave } from 'react-icons/fi'; @@ -18,7 +19,7 @@ export const Position = (): JSX.Element => { const preferences = useAppSelector( (state) => state.meshtastic.radio.preferences, ); - const [loading, setLoading] = React.useState(false); + const [loading, setLoading] = useState(false); const { register, handleSubmit, formState, reset, control } = useForm({ defaultValues: { @@ -32,7 +33,7 @@ export const Position = (): JSX.Element => { }, }); - React.useEffect(() => { + useEffect(() => { reset(preferences); }, [reset, preferences]); diff --git a/src/components/layout/Sidebar/Settings/Power.tsx b/src/components/layout/Sidebar/Settings/Power.tsx index b98d756a..a7ecf0e8 100644 --- a/src/components/layout/Sidebar/Settings/Power.tsx +++ b/src/components/layout/Sidebar/Settings/Power.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import { FiSave } from 'react-icons/fi'; @@ -14,7 +15,7 @@ export const Power = (): JSX.Element => { const preferences = useAppSelector( (state) => state.meshtastic.radio.preferences, ); - const [loading, setLoading] = React.useState(false); + const [loading, setLoading] = useState(false); const { register, handleSubmit, formState, reset } = useForm({ defaultValues: { @@ -23,7 +24,7 @@ export const Power = (): JSX.Element => { }, }); - React.useEffect(() => { + useEffect(() => { reset(preferences); }, [reset, preferences]); diff --git a/src/components/layout/Sidebar/Settings/Radio.tsx b/src/components/layout/Sidebar/Settings/Radio.tsx index 690e4b1a..25aad83f 100644 --- a/src/components/layout/Sidebar/Settings/Radio.tsx +++ b/src/components/layout/Sidebar/Settings/Radio.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import { FiSave } from 'react-icons/fi'; @@ -14,13 +15,13 @@ export const Radio = (): JSX.Element => { const preferences = useAppSelector( (state) => state.meshtastic.radio.preferences, ); - const [loading, setLoading] = React.useState(false); + const [loading, setLoading] = useState(false); const { register, handleSubmit, formState, reset } = useForm({ defaultValues: preferences, }); - React.useEffect(() => { + useEffect(() => { reset(preferences); }, [reset, preferences]); diff --git a/src/components/layout/Sidebar/Settings/User.tsx b/src/components/layout/Sidebar/Settings/User.tsx index 1be1bb7a..08665136 100644 --- a/src/components/layout/Sidebar/Settings/User.tsx +++ b/src/components/layout/Sidebar/Settings/User.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import { FiSave } from 'react-icons/fi'; @@ -13,7 +14,7 @@ import { useAppSelector } from '@hooks/useAppSelector'; import { Protobuf } from '@meshtastic/meshtasticjs'; export const User = (): JSX.Element => { - const [loading, setLoading] = React.useState(false); + const [loading, setLoading] = useState(false); const myNodeNum = useAppSelector( (state) => state.meshtastic.radio.hardware, ).myNodeNum; @@ -40,7 +41,7 @@ export const User = (): JSX.Element => { }, }); - React.useEffect(() => { + useEffect(() => { reset({ longName: node?.user?.longName, shortName: node?.user?.shortName, diff --git a/src/components/layout/Sidebar/Settings/WiFi.tsx b/src/components/layout/Sidebar/Settings/WiFi.tsx index cbb79fee..1fe955c6 100644 --- a/src/components/layout/Sidebar/Settings/WiFi.tsx +++ b/src/components/layout/Sidebar/Settings/WiFi.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect, useState } from 'react'; import { useForm, useWatch } from 'react-hook-form'; import { FiSave } from 'react-icons/fi'; @@ -14,7 +15,7 @@ export const WiFi = (): JSX.Element => { const preferences = useAppSelector( (state) => state.meshtastic.radio.preferences, ); - const [loading, setLoading] = React.useState(false); + const [loading, setLoading] = useState(false); const { register, handleSubmit, formState, reset, control } = useForm({ defaultValues: preferences, @@ -32,7 +33,7 @@ export const WiFi = (): JSX.Element => { defaultValue: false, }); - React.useEffect(() => { + useEffect(() => { reset(preferences); }, [reset, preferences]); diff --git a/src/components/layout/Sidebar/Settings/channels/Channels.tsx b/src/components/layout/Sidebar/Settings/channels/Channels.tsx index a4c5605a..3f985599 100644 --- a/src/components/layout/Sidebar/Settings/channels/Channels.tsx +++ b/src/components/layout/Sidebar/Settings/channels/Channels.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect, useState } from 'react'; import { fromByteArray, toByteArray } from 'base64-js'; import { useForm } from 'react-hook-form'; @@ -18,9 +19,9 @@ export interface SettingsPanelProps { } export const SettingsPanel = ({ channel }: SettingsPanelProps): JSX.Element => { - const [loading, setLoading] = React.useState(false); - const [keySize, setKeySize] = React.useState<128 | 256>(256); - const [pskHidden, setPskHidden] = React.useState(true); + const [loading, setLoading] = useState(false); + const [keySize, setKeySize] = useState<128 | 256>(256); + const [pskHidden, setPskHidden] = useState(true); const { register, handleSubmit, setValue, formState, reset } = useForm< Omit & { psk: string; enabled: boolean } @@ -37,7 +38,7 @@ export const SettingsPanel = ({ channel }: SettingsPanelProps): JSX.Element => { }, }); - React.useEffect(() => { + useEffect(() => { reset({ enabled: [ Protobuf.Channel_Role.SECONDARY, diff --git a/src/components/layout/Sidebar/Settings/plugins/ExternalNotifications.tsx b/src/components/layout/Sidebar/Settings/plugins/ExternalNotifications.tsx index f3fb2d90..c2620c37 100644 --- a/src/components/layout/Sidebar/Settings/plugins/ExternalNotifications.tsx +++ b/src/components/layout/Sidebar/Settings/plugins/ExternalNotifications.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect, useState } from 'react'; import { useForm, useWatch } from 'react-hook-form'; import { FiSave } from 'react-icons/fi'; @@ -12,7 +13,7 @@ import { useAppSelector } from '@hooks/useAppSelector'; import type { Protobuf } from '@meshtastic/meshtasticjs'; export const ExternalNotificationsSettingsPlanel = (): JSX.Element => { - const [loading, setLoading] = React.useState(false); + const [loading, setLoading] = useState(false); const preferences = useAppSelector( (state) => state.meshtastic.radio.preferences, @@ -23,7 +24,7 @@ export const ExternalNotificationsSettingsPlanel = (): JSX.Element => { defaultValues: preferences, }); - React.useEffect(() => { + useEffect(() => { reset(preferences); }, [reset, preferences]); diff --git a/src/components/layout/Sidebar/Settings/plugins/RangeTest.tsx b/src/components/layout/Sidebar/Settings/plugins/RangeTest.tsx index 0939f7d2..11dd9765 100644 --- a/src/components/layout/Sidebar/Settings/plugins/RangeTest.tsx +++ b/src/components/layout/Sidebar/Settings/plugins/RangeTest.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect, useState } from 'react'; import { useForm, useWatch } from 'react-hook-form'; import { FiSave } from 'react-icons/fi'; @@ -12,7 +13,7 @@ import { useAppSelector } from '@hooks/useAppSelector'; import type { Protobuf } from '@meshtastic/meshtasticjs'; export const RangeTestSettingsPanel = (): JSX.Element => { - const [loading, setLoading] = React.useState(false); + const [loading, setLoading] = useState(false); const preferences = useAppSelector( (state) => state.meshtastic.radio.preferences, @@ -23,7 +24,7 @@ export const RangeTestSettingsPanel = (): JSX.Element => { defaultValues: preferences, }); - React.useEffect(() => { + useEffect(() => { reset(preferences); }, [reset, preferences]); diff --git a/src/components/layout/Sidebar/Settings/plugins/Serial.tsx b/src/components/layout/Sidebar/Settings/plugins/Serial.tsx index 4eb52c25..8673c88b 100644 --- a/src/components/layout/Sidebar/Settings/plugins/Serial.tsx +++ b/src/components/layout/Sidebar/Settings/plugins/Serial.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect, useState } from 'react'; import { useForm, useWatch } from 'react-hook-form'; import { FiSave } from 'react-icons/fi'; @@ -12,7 +13,7 @@ import { useAppSelector } from '@hooks/useAppSelector'; import type { Protobuf } from '@meshtastic/meshtasticjs'; export const SerialSettingsPanel = (): JSX.Element => { - const [loading, setLoading] = React.useState(false); + const [loading, setLoading] = useState(false); const preferences = useAppSelector( (state) => state.meshtastic.radio.preferences, @@ -23,7 +24,7 @@ export const SerialSettingsPanel = (): JSX.Element => { defaultValues: preferences, }); - React.useEffect(() => { + useEffect(() => { reset(preferences); }, [reset, preferences]); diff --git a/src/components/layout/Sidebar/Settings/plugins/StoreForward.tsx b/src/components/layout/Sidebar/Settings/plugins/StoreForward.tsx index f25e6a0c..6039484a 100644 --- a/src/components/layout/Sidebar/Settings/plugins/StoreForward.tsx +++ b/src/components/layout/Sidebar/Settings/plugins/StoreForward.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect, useState } from 'react'; import { useForm, useWatch } from 'react-hook-form'; import { FiSave } from 'react-icons/fi'; @@ -12,7 +13,7 @@ import { useAppSelector } from '@hooks/useAppSelector'; import type { Protobuf } from '@meshtastic/meshtasticjs'; export const StoreForwardSettingsPanel = (): JSX.Element => { - const [loading, setLoading] = React.useState(false); + const [loading, setLoading] = useState(false); const preferences = useAppSelector( (state) => state.meshtastic.radio.preferences, @@ -23,7 +24,7 @@ export const StoreForwardSettingsPanel = (): JSX.Element => { defaultValues: preferences, }); - React.useEffect(() => { + useEffect(() => { reset(preferences); }, [reset, preferences]); diff --git a/src/components/layout/Sidebar/index.tsx b/src/components/layout/Sidebar/index.tsx index 3146540e..d318c42c 100644 --- a/src/components/layout/Sidebar/index.tsx +++ b/src/components/layout/Sidebar/index.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useState } from 'react'; import { ButtonNav } from '@components/layout/Sidebar/ButtonNav'; import { Settings } from '@components/layout/Sidebar/Settings/Index'; @@ -9,7 +10,7 @@ export interface SidebarProps { } export const Sidebar = ({ children }: SidebarProps): JSX.Element => { - const [settingsOpen, setSettingsOpen] = React.useState(false); + const [settingsOpen, setSettingsOpen] = useState(false); const appState = useAppSelector((state) => state.app); diff --git a/src/components/menu/BottomNav.tsx b/src/components/menu/BottomNav.tsx index b0590bea..8c92b543 100644 --- a/src/components/menu/BottomNav.tsx +++ b/src/components/menu/BottomNav.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useState } from 'react'; import { FiBluetooth, @@ -31,7 +32,7 @@ import { VersionInfo } from '../modals/VersionInfo'; import { BottomNavItem } from './BottomNavItem'; export const BottomNav = (): JSX.Element => { - const [showVersionInfo, setShowVersionInfo] = React.useState(false); + const [showVersionInfo, setShowVersionInfo] = useState(false); const dispatch = useAppDispatch(); const meshtasticState = useAppSelector((state) => state.meshtastic); const appState = useAppSelector((state) => state.app); diff --git a/src/components/modals/VersionInfo.tsx b/src/components/modals/VersionInfo.tsx index f9e846a8..757c884d 100644 --- a/src/components/modals/VersionInfo.tsx +++ b/src/components/modals/VersionInfo.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect } from 'react'; import { AnimatePresence } from 'framer-motion'; import { MdUpgrade } from 'react-icons/md'; @@ -56,7 +57,7 @@ export const VersionInfo = ({ }, ); - React.useEffect(() => { + useEffect(() => { if (data) { const index = data.findIndex( (commit) => commit.sha.substring(0, 7) === process.env.COMMIT_HASH, @@ -90,7 +91,7 @@ export const VersionInfo = ({ data.map((commit) => (
) => { + setLatLng: (state, action: PayloadAction) => { state.latLng = action.payload; }, setZoom: (state, action: PayloadAction) => { diff --git a/src/hooks/useCreateMapbox.ts b/src/hooks/useCreateMapbox.ts index 80cf5f0b..49201483 100644 --- a/src/hooks/useCreateMapbox.ts +++ b/src/hooks/useCreateMapbox.ts @@ -1,30 +1,29 @@ import 'mapbox-gl/dist/mapbox-gl.css'; -import React from 'react'; +import type React from 'react'; +import { useEffect, useState } from 'react'; -import mapboxgl from 'mapbox-gl'; - -type AccessToken = string; +import { Map, MapboxOptions } from 'mapbox-gl'; export interface useMapboxProps { ref: React.RefObject; - accessToken: AccessToken; - options?: Partial; + accessToken: string; + options?: Partial; } export function useCreateMapbox({ ref, accessToken, options, -}: useMapboxProps): mapboxgl.Map | undefined { - const [mapInstance, setMapInstance] = React.useState(); - React.useEffect(() => { +}: useMapboxProps): Map | undefined { + const [mapInstance, setMapInstance] = useState(); + useEffect(() => { const container = ref.current as HTMLDivElement; if (mapInstance || !container) { return; } - mapboxgl.accessToken = accessToken; - const map = new mapboxgl.Map({ + const map = new Map({ + accessToken, container, antialias: true, ...options, diff --git a/src/hooks/useMapbox.ts b/src/hooks/useMapbox.ts index 46c0c3d3..bf7374ac 100644 --- a/src/hooks/useMapbox.ts +++ b/src/hooks/useMapbox.ts @@ -1,8 +1,8 @@ -import React from 'react'; +import { useContext } from 'react'; import type { MapboxContextValue } from '@components/MapBox/mapboxContext'; import { MapboxContext } from '@components/MapBox/mapboxContext'; export const useMapbox = (): MapboxContextValue => { - return React.useContext(MapboxContext); + return useContext(MapboxContext); }; diff --git a/src/index.tsx b/src/index.tsx index 5d79648b..7c4fba37 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,6 +1,7 @@ import '@app/index.css'; -import React from 'react'; +import type React from 'react'; +import { StrictMode } from 'react'; import { render } from 'react-dom'; import { domAnimation, LazyMotion } from 'framer-motion'; @@ -14,7 +15,7 @@ import { RouteProvider } from '@core/router'; import { store } from '@core/store'; render( - + @@ -25,6 +26,6 @@ render( - , + , document.getElementById('root'), ); diff --git a/src/pages/Extensions/Debug.tsx b/src/pages/Extensions/Debug.tsx index 55f65fe2..9c6a64f5 100644 --- a/src/pages/Extensions/Debug.tsx +++ b/src/pages/Extensions/Debug.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import type React from 'react'; import { Button } from '@app/components/generic/button/Button'; import { Card } from '@app/components/generic/Card'; diff --git a/src/pages/Extensions/FileBrowser.tsx b/src/pages/Extensions/FileBrowser.tsx index 56323b1b..38ec460d 100644 --- a/src/pages/Extensions/FileBrowser.tsx +++ b/src/pages/Extensions/FileBrowser.tsx @@ -1,8 +1,10 @@ -import React from 'react'; +import type React from 'react'; import { AnimatePresence, m } from 'framer-motion'; +import { FiFilePlus } from 'react-icons/fi'; import useSWR from 'swr'; +import { Button } from '@app/components/generic/button/Button'; import { Card } from '@app/components/generic/Card'; import { fetcher } from '@core/utils/fetcher'; import { useAppSelector } from '@hooks/useAppSelector'; @@ -29,22 +31,27 @@ export const FileBrowser = (): JSX.Element => { const connectionParams = useAppSelector( (state) => state.app.connectionParams, ); - const darkMode = useAppSelector((state) => state.app.darkMode); + const appState = useAppSelector((state) => state.app); + const meshtasticState = useAppSelector((state) => state.meshtastic); const { data } = useSWR( `${connectionParams.HTTP.tls ? 'https' : 'http'}://${ connectionParams.HTTP.address - }/json/spiffs/browse/static`, + }${ + meshtasticState.radio.hardware.firmwareVersion.includes('1.2') + ? '/json/spiffs/browse/static' + : '/json/fs/browse/static' + }`, fetcher, ); return (
- -
-
FileName
-
Actions
-
+ }>Upload File} + className="flex-grow flex-col" + >
{(!data || data?.data.files.length === 0) && ( @@ -55,7 +62,7 @@ export const FileBrowser = (): JSX.Element => { exit={{ opacity: 0 }} className="m-auto h-64 w-64 text-green-500" src={`/placeholders/${ - darkMode ? 'Files Dark.svg' : 'Files.svg' + appState.darkMode ? 'Files Dark.svg' : 'Files.svg' }`} />
diff --git a/src/pages/Extensions/Index.tsx b/src/pages/Extensions/Index.tsx index c4f7b2b9..9282c873 100644 --- a/src/pages/Extensions/Index.tsx +++ b/src/pages/Extensions/Index.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useState } from 'react'; import { FiFile, FiInfo } from 'react-icons/fi'; import { MdSubject } from 'react-icons/md'; @@ -14,7 +15,7 @@ import { Logs } from '@pages/Extensions/Logs'; import { Debug } from './Debug'; export const Extensions = (): JSX.Element => { - const [selectedExtension, setSelectedExtension] = React.useState< + const [selectedExtension, setSelectedExtension] = useState< 'info' | 'logs' | 'fileBrowser' | 'rangeTest' | 'debug' >('info'); @@ -29,6 +30,7 @@ export const Extensions = (): JSX.Element => { setSelectedExtension('info'); }} icon={} + active={selectedExtension === 'info'} title="Node Info" /> { setSelectedExtension('logs'); }} icon={} + active={selectedExtension === 'logs'} title="Logs" /> { setSelectedExtension('fileBrowser'); }} icon={} + active={selectedExtension === 'fileBrowser'} title="File Browser" /> { setSelectedExtension('rangeTest'); }} icon={} + active={selectedExtension === 'rangeTest'} title="Range Test" /> { setSelectedExtension('debug'); }} icon={} + active={selectedExtension === 'debug'} title="Debug" />
diff --git a/src/pages/Extensions/Info.tsx b/src/pages/Extensions/Info.tsx index 34b24932..a64043ea 100644 --- a/src/pages/Extensions/Info.tsx +++ b/src/pages/Extensions/Info.tsx @@ -1,7 +1,9 @@ -import React from 'react'; +import type React from 'react'; +import { FiRefreshCw } from 'react-icons/fi'; import JSONPretty from 'react-json-pretty'; +import { Button } from '@app/components/generic/button/Button'; import { Card } from '@app/components/generic/Card'; import { Hashicon } from '@emeraldpay/hashicon-react'; import { useAppSelector } from '@hooks/useAppSelector'; @@ -17,8 +19,16 @@ export const Info = (): JSX.Element => { ); return ( -
- +
+ }> + Refresh Node info + + } + className="xl:w-3/5" + >
@@ -27,7 +37,7 @@ export const Info = (): JSX.Element => {
- +
diff --git a/src/pages/Extensions/Logs.tsx b/src/pages/Extensions/Logs.tsx index d67f1c7e..c162530f 100644 --- a/src/pages/Extensions/Logs.tsx +++ b/src/pages/Extensions/Logs.tsx @@ -1,15 +1,16 @@ import type React from 'react'; import { AnimatePresence, m } from 'framer-motion'; -import { FiArrowRight, FiPaperclip } from 'react-icons/fi'; +import { FiArrowRight, FiPaperclip, FiX } from 'react-icons/fi'; +import { Button } from '@app/components/generic/button/Button'; import { Card } from '@app/components/generic/Card'; import { useAppSelector } from '@hooks/useAppSelector'; import { Protobuf, Types } from '@meshtastic/meshtasticjs'; export const Logs = (): JSX.Element => { - const logs = useAppSelector((state) => state.meshtastic.logs); - const darkMode = useAppSelector((state) => state.app.darkMode); + const meshtasticState = useAppSelector((state) => state.meshtastic); + const appState = useAppSelector((state) => state.app); type lookupType = { [key: number]: string }; @@ -49,14 +50,18 @@ export const Logs = (): JSX.Element => { return (
- + }>Clear Logs} + className="flex-grow overflow-y-auto" + > - {logs.length === 0 && ( + {meshtasticState.logs.length === 0 && (
{ exit={{ opacity: 0 }} className="m-auto h-64 w-64 text-green-500" src={`/placeholders/${ - darkMode ? 'View Code Dark.svg' : 'View Code.svg' + appState.darkMode ? 'View Code Dark.svg' : 'View Code.svg' }`} />
)}
- {logs.map((log, index) => ( + {meshtasticState.logs.map((log, index) => ( // { const { ref } = useMapbox(); - const ChangeMapStyle = React.useCallback( + const ChangeMapStyle = useCallback( (styleName: string, style: MapStyle) => { dispatch( setMapStyle( diff --git a/src/pages/Map/Marker.tsx b/src/pages/Map/Marker.tsx index 9fd267d5..fd457f48 100644 --- a/src/pages/Map/Marker.tsx +++ b/src/pages/Map/Marker.tsx @@ -1,13 +1,15 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; +import type React from 'react'; +import { useCallback, useEffect, useRef } from 'react'; +import { createPortal } from 'react-dom'; -import mapbox from 'mapbox-gl'; +import type { LngLatLike, MarkerOptions } from 'mapbox-gl'; +import { Marker as MapboxMarker } from 'mapbox-gl'; import { useMapbox } from '@hooks/useMapbox'; -export interface MarkerProps extends Omit { +export interface MarkerProps extends Omit { children?: React.ReactNode; - center: mapbox.LngLatLike; + center: LngLatLike; } export const Marker = ({ @@ -16,22 +18,22 @@ export const Marker = ({ ...props }: MarkerProps): JSX.Element => { const { map } = useMapbox(); - const ref = React.useRef(document.createElement('div')); + const ref = useRef(document.createElement('div')); - const addMarker = React.useCallback((): void => { + const addMarker = useCallback((): void => { if (map) { - const marker = new mapbox.Marker(ref.current, props).setLngLat(center); + const marker = new MapboxMarker(ref.current, props).setLngLat(center); marker.addTo(map); } }, [map, center, props]); - React.useEffect(() => { + useEffect(() => { map?.on('load', () => { addMarker(); }); }, [addMarker, map]); - React.useEffect(() => { + useEffect(() => { if (map?.loaded()) { addMarker(); } @@ -39,5 +41,5 @@ export const Marker = ({
{children}
; - return ReactDOM.createPortal(children, ref.current); + return createPortal(children, ref.current); }; diff --git a/src/pages/Map/index.tsx b/src/pages/Map/index.tsx index 25a131ba..5a56c034 100644 --- a/src/pages/Map/index.tsx +++ b/src/pages/Map/index.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useState } from 'react'; import mapboxgl from 'mapbox-gl'; import { FiMapPin } from 'react-icons/fi'; @@ -13,7 +14,7 @@ import { Marker } from '@pages/Map/Marker'; import { NodeCard } from '@pages/Nodes/NodeCard'; export const Map = (): JSX.Element => { - const [selectedNode, setSelectedNode] = React.useState(); + const [selectedNode, setSelectedNode] = useState(); const nodes = useAppSelector((state) => state.meshtastic.nodes); const myNodeNum = useAppSelector( diff --git a/src/pages/Messages/ChannelChat.tsx b/src/pages/Messages/ChannelChat.tsx index f47e1540..e3d19385 100644 --- a/src/pages/Messages/ChannelChat.tsx +++ b/src/pages/Messages/ChannelChat.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import type React from 'react'; import { m } from 'framer-motion'; import { FiSettings } from 'react-icons/fi'; @@ -41,7 +41,7 @@ export const ChannelChat = ({ setSelected={(): void => { setSelectedIndex(channel.index); }} - actions={} />} + actions={} />} > { setSelectedIndex(node.number); }} - actions={} />} + actions={} />} >
diff --git a/src/pages/Messages/MessageBar.tsx b/src/pages/Messages/MessageBar.tsx index e328a7da..90aaeeb5 100644 --- a/src/pages/Messages/MessageBar.tsx +++ b/src/pages/Messages/MessageBar.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useState } from 'react'; import { Input } from '@components/generic/form/Input'; import { connection } from '@core/connection'; @@ -14,9 +15,9 @@ export const MessageBar = ({ chatIndex }: MessageBarProps): JSX.Element => { const dispatch = useAppDispatch(); const meshtasticState = useAppSelector((state) => state.meshtastic); - const [isChannel, setIsChannel] = React.useState(false); + const [isChannel, setIsChannel] = useState(false); - React.useState(() => { + useState(() => { setIsChannel( meshtasticState.radio.channels.findIndex( (channel) => channel.index === chatIndex, @@ -24,7 +25,7 @@ export const MessageBar = ({ chatIndex }: MessageBarProps): JSX.Element => { ); }); - const [currentMessage, setCurrentMessage] = React.useState(''); + const [currentMessage, setCurrentMessage] = useState(''); const sendMessage = (): void => { if (meshtasticState.ready) { void connection.sendText( @@ -33,6 +34,13 @@ export const MessageBar = ({ chatIndex }: MessageBarProps): JSX.Element => { true, isChannel ? chatIndex-- : 0, (id) => { + console.log(`Chat Index, ${chatIndex}`); + console.log(`Chat Index --, ${chatIndex--}`); + + console.log( + `Chat Index computed, ${isChannel ? chatIndex-- : chatIndex}`, + ); + dispatch( ackMessage({ chatIndex: isChannel ? chatIndex-- : chatIndex, diff --git a/src/pages/Messages/index.tsx b/src/pages/Messages/index.tsx index 5d151ab7..7cb8d91b 100644 --- a/src/pages/Messages/index.tsx +++ b/src/pages/Messages/index.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect, useRef, useState } from 'react'; import { FiHash, FiMessageCircle } from 'react-icons/fi'; @@ -12,9 +13,9 @@ import { Message } from '@pages/Messages/Message'; import { MessageBar } from '@pages/Messages/MessageBar'; export const Messages = (): JSX.Element => { - const [selectedChatIndex, setSelectedChatIndex] = React.useState(0); + const [selectedChatIndex, setSelectedChatIndex] = useState(0); - const chatRef = React.useRef(null); + const chatRef = useRef(null); const myNodeNum = useAppSelector( (state) => state.meshtastic.radio.hardware, @@ -25,7 +26,7 @@ export const Messages = (): JSX.Element => { (state) => state.meshtastic.radio.channels, ).filter((ch) => ch.role !== Protobuf.Channel_Role.DISABLED); - React.useEffect(() => { + useEffect(() => { if (chatRef.current) { chatRef.current.scrollTop = chatRef.current.scrollHeight; } @@ -66,7 +67,7 @@ export const Messages = (): JSX.Element => {
- } /> + } />
{channels.findIndex((ch) => ch.index === selectedChatIndex) !== -1 ? ( diff --git a/src/pages/Nodes/NodeCard.tsx b/src/pages/Nodes/NodeCard.tsx index eb7218a9..d5993456 100644 --- a/src/pages/Nodes/NodeCard.tsx +++ b/src/pages/Nodes/NodeCard.tsx @@ -1,7 +1,8 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect, useState } from 'react'; import { m } from 'framer-motion'; -import mapbox from 'mapbox-gl'; +import { LngLat } from 'mapbox-gl'; import { BiCrown } from 'react-icons/bi'; import { FiAlignLeft, @@ -40,11 +41,11 @@ export const NodeCard = ({ setSelected, }: NodeCardProps): JSX.Element => { const { map } = useMapbox(); - const [infoOpen, setInfoOpen] = React.useState(false); + const [infoOpen, setInfoOpen] = useState(false); const [PositionConfidence, setPositionConfidence] = - React.useState('none'); + useState('none'); - React.useEffect(() => { + useEffect(() => { setPositionConfidence( node.currentPosition ? new Date(node.currentPosition.posTimestamp * 1000) > @@ -62,6 +63,7 @@ export const NodeCard = ({ actions={ <> { @@ -69,7 +71,7 @@ export const NodeCard = ({ setSelected(); if (PositionConfidence !== 'none' && node.currentPosition) { map?.flyTo({ - center: new mapbox.LngLat( + center: new LngLat( node.currentPosition.longitudeI / 1e7, node.currentPosition.latitudeI / 1e7, ), @@ -88,6 +90,7 @@ export const NodeCard = ({ } /> { e.stopPropagation(); diff --git a/src/pages/Nodes/index.tsx b/src/pages/Nodes/index.tsx index 52471be2..997af6ff 100644 --- a/src/pages/Nodes/index.tsx +++ b/src/pages/Nodes/index.tsx @@ -1,4 +1,5 @@ -import React from 'react'; +import type React from 'react'; +import { useEffect, useState } from 'react'; import { m } from 'framer-motion'; import type { Edge, Node } from 'react-flow-renderer'; @@ -15,15 +16,15 @@ import { Hashicon } from '@emeraldpay/hashicon-react'; import { useAppSelector } from '@hooks/useAppSelector'; export const Nodes = (): JSX.Element => { - const [graphNodes, setGraphNodes] = React.useState([]); - const [graphEdges, setGraphEdges] = React.useState([]); - const [selected, setSelected] = React.useState(0); + const [graphNodes, setGraphNodes] = useState([]); + const [graphEdges, setGraphEdges] = useState([]); + const [selected, setSelected] = useState(0); const nodes = useAppSelector((state) => state.meshtastic.nodes); const myNodeNum = useAppSelector( (state) => state.meshtastic.radio.hardware.myNodeNum, ); - React.useEffect(() => { + useEffect(() => { const tmpNodes: Node[] = []; // User Terminal tmpNodes.push({ @@ -45,7 +46,7 @@ export const Nodes = (): JSX.Element => { setGraphNodes(tmpNodes); }, [nodes, myNodeNum]); - React.useEffect(() => { + useEffect(() => { const tmpEdges: Edge[] = []; nodes.map((node, index) => { @@ -91,6 +92,7 @@ export const Nodes = (): JSX.Element => { }} actions={ { e.stopPropagation(); setSelected(node.number); diff --git a/tailwind.config.cjs b/tailwind.config.cjs index 5e922d40..b91eec88 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -11,9 +11,7 @@ module.exports = { extend: { colors: { primary: '#67ea94', - // primaryDark: '#1E293B', primaryDark: '#25262C', - // secondaryDark: '#0F172A', secondaryDark: '#1C1D23', accentDark: '25262C', }, diff --git a/vite.config.ts b/vite.config.ts index a3079cff..a08e1f16 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,5 +1,5 @@ import { execSync } from 'child_process'; -import path from 'path'; +import { resolve } from 'path'; import { visualizer } from 'rollup-plugin-visualizer'; import { defineConfig } from 'vite'; import importToCDN from 'vite-plugin-cdn-import'; @@ -79,11 +79,11 @@ export default defineConfig({ }, resolve: { alias: { - '@app': path.resolve(__dirname, './src'), - '@pages': path.resolve(__dirname, './src/pages'), - '@components': path.resolve(__dirname, './src/components'), - '@hooks': path.resolve(__dirname, './src/hooks'), - '@core': path.resolve(__dirname, './src/core'), + '@app': resolve(__dirname, './src'), + '@pages': resolve(__dirname, './src/pages'), + '@components': resolve(__dirname, './src/components'), + '@hooks': resolve(__dirname, './src/hooks'), + '@core': resolve(__dirname, './src/core'), '@skypack/': 'https://cdn.skypack.dev/', }, },