mirror of
https://github.com/meshtastic/web.git
synced 2026-01-27 00:37:57 -05:00
Version Info and modal titles
This commit is contained in:
@@ -14,13 +14,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@emeraldpay/hashicon-react": "^0.5.2",
|
||||
"@meshtastic/meshtasticjs": "^0.6.45",
|
||||
"@meshtastic/meshtasticjs": "^0.6.46",
|
||||
"@reduxjs/toolkit": "^1.7.2",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
"base64-js": "^1.5.1",
|
||||
"cuid": "^2.1.8",
|
||||
"framer-motion": "^6.2.6",
|
||||
"graphql-request": "^4.0.0",
|
||||
"mapbox-gl": "^2.7.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
|
||||
99
pnpm-lock.yaml
generated
99
pnpm-lock.yaml
generated
@@ -3,7 +3,7 @@ lockfileVersion: 5.3
|
||||
specifiers:
|
||||
'@emeraldpay/hashicon-react': ^0.5.2
|
||||
'@hookform/devtools': ^4.0.2
|
||||
'@meshtastic/meshtasticjs': ^0.6.45
|
||||
'@meshtastic/meshtasticjs': ^0.6.46
|
||||
'@reduxjs/toolkit': ^1.7.2
|
||||
'@tippyjs/react': ^4.2.6
|
||||
'@types/mapbox-gl': ^2.6.1
|
||||
@@ -28,7 +28,6 @@ specifiers:
|
||||
eslint-plugin-react: ^7.28.0
|
||||
eslint-plugin-react-hooks: ^4.3.0
|
||||
framer-motion: ^6.2.6
|
||||
graphql-request: ^4.0.0
|
||||
gzipper: ^7.0.0
|
||||
mapbox-gl: ^2.7.0
|
||||
postcss: ^8.4.6
|
||||
@@ -62,13 +61,12 @@ specifiers:
|
||||
|
||||
dependencies:
|
||||
'@emeraldpay/hashicon-react': 0.5.2
|
||||
'@meshtastic/meshtasticjs': 0.6.45
|
||||
'@meshtastic/meshtasticjs': 0.6.46
|
||||
'@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
|
||||
cuid: 2.1.8
|
||||
framer-motion: 6.2.6_react-dom@17.0.2+react@17.0.2
|
||||
graphql-request: 4.0.0
|
||||
mapbox-gl: 2.7.0
|
||||
react: 17.0.2
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
@@ -1638,8 +1636,8 @@ packages:
|
||||
engines: {node: '>=6.0.0'}
|
||||
dev: false
|
||||
|
||||
/@meshtastic/meshtasticjs/0.6.45:
|
||||
resolution: {integrity: sha512-icAGMofpQ3hYqWhjYMLqMyhb0Xtk3GozEgOXScFTKVOaecDY0XIJmuvoBDfgD2lxNxDDPr0Dj77js+3JGxTcRg==}
|
||||
/@meshtastic/meshtasticjs/0.6.46:
|
||||
resolution: {integrity: sha512-XOaQz75kYDNvv1zK9KXy5te8V9AEyVXWK0JvK3v1v+WqAJ9UNvnNcaQTRsJBPG2elmE3cQkfEz+WfBus2wve8g==}
|
||||
dependencies:
|
||||
'@protobuf-ts/runtime': 2.2.2
|
||||
sub-events: 1.8.9
|
||||
@@ -2312,10 +2310,6 @@ packages:
|
||||
resolution: {integrity: sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=}
|
||||
dev: true
|
||||
|
||||
/asynckit/0.4.0:
|
||||
resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=}
|
||||
dev: false
|
||||
|
||||
/at-least-node/1.0.0:
|
||||
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
|
||||
engines: {node: '>= 4.0.0'}
|
||||
@@ -2578,13 +2572,6 @@ packages:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
dev: true
|
||||
|
||||
/combined-stream/1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
dev: false
|
||||
|
||||
/commander/2.20.3:
|
||||
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
|
||||
dev: true
|
||||
@@ -2648,14 +2635,6 @@ packages:
|
||||
yaml: 1.10.2
|
||||
dev: true
|
||||
|
||||
/cross-fetch/3.1.5:
|
||||
resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==}
|
||||
dependencies:
|
||||
node-fetch: 2.6.7
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/cross-spawn/7.0.3:
|
||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||
engines: {node: '>= 8'}
|
||||
@@ -2827,11 +2806,6 @@ packages:
|
||||
resolution: {integrity: sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=}
|
||||
dev: true
|
||||
|
||||
/delayed-stream/1.0.0:
|
||||
resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=}
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: false
|
||||
|
||||
/detective/5.2.0:
|
||||
resolution: {integrity: sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
@@ -3594,11 +3568,6 @@ packages:
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/extract-files/9.0.0:
|
||||
resolution: {integrity: sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==}
|
||||
engines: {node: ^10.17.0 || ^12.0.0 || >= 13.7.0}
|
||||
dev: false
|
||||
|
||||
/fast-deep-equal/3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
dev: true
|
||||
@@ -3713,15 +3682,6 @@ packages:
|
||||
resolution: {integrity: sha1-C+4AUBiusmDQo6865ljdATbsG5k=}
|
||||
dev: true
|
||||
|
||||
/form-data/3.0.1:
|
||||
resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==}
|
||||
engines: {node: '>= 6'}
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
mime-types: 2.1.34
|
||||
dev: false
|
||||
|
||||
/fraction.js/4.1.3:
|
||||
resolution: {integrity: sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg==}
|
||||
dev: true
|
||||
@@ -3882,18 +3842,6 @@ packages:
|
||||
resolution: {integrity: sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==}
|
||||
dev: true
|
||||
|
||||
/graphql-request/4.0.0:
|
||||
resolution: {integrity: sha512-cdqQLCXlBGkaLdkLYRl4LtkwaZU6TfpE7/tnUQFl3wXfUPWN74Ov+Q61VuIh+AltS789YfGB6whghmCmeXLvTw==}
|
||||
peerDependencies:
|
||||
graphql: 14 - 16
|
||||
dependencies:
|
||||
cross-fetch: 3.1.5
|
||||
extract-files: 9.0.0
|
||||
form-data: 3.0.1
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/grid-index/1.1.0:
|
||||
resolution: {integrity: sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==}
|
||||
dev: false
|
||||
@@ -4489,18 +4437,6 @@ packages:
|
||||
picomatch: 2.3.1
|
||||
dev: true
|
||||
|
||||
/mime-db/1.51.0:
|
||||
resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/mime-types/2.1.34:
|
||||
resolution: {integrity: sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dependencies:
|
||||
mime-db: 1.51.0
|
||||
dev: false
|
||||
|
||||
/mimic-fn/2.1.0:
|
||||
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -4562,18 +4498,6 @@ packages:
|
||||
resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=}
|
||||
dev: true
|
||||
|
||||
/node-fetch/2.6.7:
|
||||
resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==}
|
||||
engines: {node: 4.x || >=6.0.0}
|
||||
peerDependencies:
|
||||
encoding: ^0.1.0
|
||||
peerDependenciesMeta:
|
||||
encoding:
|
||||
optional: true
|
||||
dependencies:
|
||||
whatwg-url: 5.0.0
|
||||
dev: false
|
||||
|
||||
/node-modules-regexp/1.0.0:
|
||||
resolution: {integrity: sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -5858,10 +5782,6 @@ packages:
|
||||
resolution: {integrity: sha1-bkWxJj8gF/oKzH2J14sVuL932jI=}
|
||||
dev: false
|
||||
|
||||
/tr46/0.0.3:
|
||||
resolution: {integrity: sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=}
|
||||
dev: false
|
||||
|
||||
/tr46/1.0.1:
|
||||
resolution: {integrity: sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=}
|
||||
dependencies:
|
||||
@@ -6114,21 +6034,10 @@ packages:
|
||||
defaults: 1.0.3
|
||||
dev: true
|
||||
|
||||
/webidl-conversions/3.0.1:
|
||||
resolution: {integrity: sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=}
|
||||
dev: false
|
||||
|
||||
/webidl-conversions/4.0.2:
|
||||
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
|
||||
dev: true
|
||||
|
||||
/whatwg-url/5.0.0:
|
||||
resolution: {integrity: sha1-lmRU6HZUYuN2RNNib2dCzotwll0=}
|
||||
dependencies:
|
||||
tr46: 0.0.3
|
||||
webidl-conversions: 3.0.1
|
||||
dev: false
|
||||
|
||||
/whatwg-url/7.1.0:
|
||||
resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
|
||||
dependencies:
|
||||
|
||||
@@ -2,7 +2,6 @@ import React from 'react';
|
||||
|
||||
import { AnimatePresence } from 'framer-motion';
|
||||
|
||||
import { Card } from '@app/components/generic/Card';
|
||||
import { BLE } from '@components/connection/BLE';
|
||||
import { HTTP } from '@components/connection/HTTP';
|
||||
import { Serial } from '@components/connection/Serial';
|
||||
@@ -52,74 +51,72 @@ export const Connection = (): JSX.Element => {
|
||||
<AnimatePresence>
|
||||
{appState.connectionModalOpen && (
|
||||
<Modal
|
||||
className="w-full max-w-3xl"
|
||||
title="Connect to a device"
|
||||
onClose={(): void => {
|
||||
dispatch(closeConnectionModal());
|
||||
}}
|
||||
>
|
||||
<Card className="relative">
|
||||
<div className="flex max-w-3xl flex-grow gap-4 p-2">
|
||||
<div className="w-1/2">
|
||||
<div className="space-y-2">
|
||||
<Select
|
||||
label="Connection Method"
|
||||
optionsEnum={connType}
|
||||
value={appState.connType}
|
||||
onChange={(e): void => {
|
||||
dispatch(setConnType(parseInt(e.target.value)));
|
||||
}}
|
||||
disabled={
|
||||
<div className="flex max-w-3xl flex-grow gap-4">
|
||||
<div className="w-1/2">
|
||||
<div className="space-y-2">
|
||||
<Select
|
||||
label="Connection Method"
|
||||
optionsEnum={connType}
|
||||
value={appState.connType}
|
||||
onChange={(e): void => {
|
||||
dispatch(setConnType(parseInt(e.target.value)));
|
||||
}}
|
||||
disabled={
|
||||
state.deviceStatus ===
|
||||
Types.DeviceStatusEnum.DEVICE_CONNECTED
|
||||
}
|
||||
/>
|
||||
{appState.connType === connType.HTTP && (
|
||||
<HTTP
|
||||
connecting={
|
||||
state.deviceStatus ===
|
||||
Types.DeviceStatusEnum.DEVICE_CONNECTED
|
||||
}
|
||||
/>
|
||||
{appState.connType === connType.HTTP && (
|
||||
<HTTP
|
||||
connecting={
|
||||
state.deviceStatus ===
|
||||
Types.DeviceStatusEnum.DEVICE_CONNECTED
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{appState.connType === connType.BLE && (
|
||||
<BLE
|
||||
connecting={
|
||||
state.deviceStatus ===
|
||||
Types.DeviceStatusEnum.DEVICE_CONNECTED
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{appState.connType === connType.SERIAL && (
|
||||
<Serial
|
||||
connecting={
|
||||
state.deviceStatus ===
|
||||
Types.DeviceStatusEnum.DEVICE_CONNECTED
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-1/2">
|
||||
<div className="h-96 overflow-y-auto rounded-md bg-gray-200 p-2 dark:bg-secondaryDark dark:text-gray-400">
|
||||
{state.logs
|
||||
.filter((log) => {
|
||||
return ![
|
||||
Types.Emitter.handleFromRadio,
|
||||
Types.Emitter.handleMeshPacket,
|
||||
Types.Emitter.sendPacket,
|
||||
].includes(log.emitter);
|
||||
})
|
||||
.map((log, index) => (
|
||||
<div key={index} className="flex">
|
||||
<div className="truncate font-mono text-sm">
|
||||
{log.message}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{appState.connType === connType.BLE && (
|
||||
<BLE
|
||||
connecting={
|
||||
state.deviceStatus ===
|
||||
Types.DeviceStatusEnum.DEVICE_CONNECTED
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{appState.connType === connType.SERIAL && (
|
||||
<Serial
|
||||
connecting={
|
||||
state.deviceStatus ===
|
||||
Types.DeviceStatusEnum.DEVICE_CONNECTED
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
<div className="w-1/2">
|
||||
<div className="h-96 overflow-y-auto rounded-md bg-gray-200 dark:bg-secondaryDark dark:text-gray-400">
|
||||
{state.logs
|
||||
.filter((log) => {
|
||||
return ![
|
||||
Types.Emitter.handleFromRadio,
|
||||
Types.Emitter.handleMeshPacket,
|
||||
Types.Emitter.sendPacket,
|
||||
].includes(log.emitter);
|
||||
})
|
||||
.map((log, index) => (
|
||||
<div key={index} className="flex">
|
||||
<div className="truncate font-mono text-sm">
|
||||
{log.message}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
import type React from 'react';
|
||||
|
||||
import { m } from 'framer-motion';
|
||||
import { FiX } from 'react-icons/fi';
|
||||
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
|
||||
type DefaultDivProps = JSX.IntrinsicElements['div'];
|
||||
import { IconButton } from './button/IconButton';
|
||||
import { Card } from './Card';
|
||||
|
||||
export interface ModalProps extends DefaultDivProps {
|
||||
export interface ModalProps {
|
||||
title: string;
|
||||
onClose: () => void;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const Modal = ({
|
||||
title,
|
||||
onClose,
|
||||
children,
|
||||
className,
|
||||
...props
|
||||
}: ModalProps): JSX.Element => {
|
||||
const darkMode = useAppSelector((state) => state.app.darkMode);
|
||||
|
||||
@@ -32,8 +34,19 @@ export const Modal = ({
|
||||
>
|
||||
​
|
||||
</span>
|
||||
<div className={`inline-block align-middle ${className}`} {...props}>
|
||||
{children}
|
||||
<div className="inline-block w-full max-w-3xl align-middle">
|
||||
<Card
|
||||
className="relative flex-col gap-4
|
||||
"
|
||||
>
|
||||
<div className="flex justify-between">
|
||||
<div className="text-2xl font-medium dark:text-white">
|
||||
{title}
|
||||
</div>
|
||||
<IconButton icon={<FiX />} onClick={onClose} />
|
||||
</div>
|
||||
{children}
|
||||
</Card>
|
||||
</div>
|
||||
</m.div>
|
||||
</m.div>
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
FiWifi,
|
||||
FiX,
|
||||
} from 'react-icons/fi';
|
||||
import { MdUpgrade } from 'react-icons/md';
|
||||
import {
|
||||
RiArrowDownLine,
|
||||
RiArrowUpDownLine,
|
||||
@@ -124,19 +125,29 @@ export const BottomNav = (): JSX.Element => {
|
||||
<div className="flex">
|
||||
<VersionInfo
|
||||
visible={showVersionInfo}
|
||||
onclose={(): void => {
|
||||
onClose={(): void => {
|
||||
setShowVersionInfo(false);
|
||||
}}
|
||||
/>
|
||||
|
||||
<Tooltip content={`Current Commit`}>
|
||||
<Tooltip
|
||||
content={
|
||||
appState.updateAvaliable ? 'Update Avaliable' : 'Current Commit'
|
||||
}
|
||||
>
|
||||
<div
|
||||
onClick={(): void => {
|
||||
setShowVersionInfo(true);
|
||||
}}
|
||||
className="group flex cursor-pointer select-none border-l border-gray-300 p-1 hover:bg-gray-200 dark:border-gray-600 dark:text-white dark:hover:bg-primaryDark"
|
||||
className={`group flex cursor-pointer select-none border-l border-gray-300 p-1 hover:bg-gray-200 dark:border-gray-600 dark:text-white dark:hover:bg-primaryDark ${
|
||||
appState.updateAvaliable ? 'animate-pulse' : ''
|
||||
}`}
|
||||
>
|
||||
<FiGitBranch className="mr-1 p-0.5 group-active:scale-90" />
|
||||
{appState.updateAvaliable ? (
|
||||
<MdUpgrade className="mr-1 p-0.5 group-active:scale-90" />
|
||||
) : (
|
||||
<FiGitBranch className="mr-1 p-0.5 group-active:scale-90" />
|
||||
)}
|
||||
<p className="text-xs opacity-60">{process.env.COMMIT_HASH}</p>
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
@@ -1,59 +1,91 @@
|
||||
import React from 'react';
|
||||
|
||||
import { AnimatePresence } from 'framer-motion';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import { setUpdateAvaliable } from '@app/core/slices/appSlice.js';
|
||||
import { fetcher } from '@app/core/utils/fetcher.js';
|
||||
import { useAppDispatch } from '@app/hooks/useAppDispatch.js';
|
||||
import { Modal } from '@components/generic/Modal';
|
||||
|
||||
import { Card } from '../generic/Card';
|
||||
export interface Commit {
|
||||
sha: string;
|
||||
node_id: string;
|
||||
commit: {
|
||||
author: string;
|
||||
committer: string;
|
||||
message: string;
|
||||
tree: {
|
||||
sha: string;
|
||||
url: string;
|
||||
};
|
||||
url: string;
|
||||
comment_count: number;
|
||||
};
|
||||
url: string;
|
||||
html_url: string;
|
||||
comments_url: string;
|
||||
}
|
||||
|
||||
export interface VersionInfoProps {
|
||||
visible: boolean;
|
||||
onclose: () => void;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export const VersionInfo = ({
|
||||
visible,
|
||||
onclose,
|
||||
onClose,
|
||||
}: VersionInfoProps): JSX.Element => {
|
||||
// const { data } = useSWR<CommitHistory>(
|
||||
// `query {
|
||||
// repository(owner: "meshtastic", name: "meshtastic-web") {
|
||||
// ref(qualifiedName: "master") {
|
||||
// name
|
||||
// target {
|
||||
// ... on Commit {
|
||||
// history(first: 4) {
|
||||
// edges {
|
||||
// node {
|
||||
// abbreviatedOid
|
||||
// message
|
||||
// author {
|
||||
// avatarUrl
|
||||
// name
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }`,
|
||||
// fetcher,
|
||||
// );
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const { data } = useSWR<Commit[]>(
|
||||
'https://api.github.com/repos/meshtastic/meshtastic-web/commits?per_page=10',
|
||||
fetcher,
|
||||
{
|
||||
revalidateOnFocus: false,
|
||||
},
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (data) {
|
||||
const index = data.findIndex(
|
||||
(commit) => commit.sha.substring(0, 7) === process.env.COMMIT_HASH,
|
||||
);
|
||||
console.log(index);
|
||||
|
||||
if (index === -1 || index > 0) {
|
||||
dispatch(setUpdateAvaliable(true));
|
||||
}
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{visible && (
|
||||
<Modal
|
||||
title="Version Info"
|
||||
onClose={(): void => {
|
||||
onclose();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
<Card className="relative">
|
||||
<div className="w-full max-w-3xl p-10">Version Info</div>
|
||||
{/* {data?.sha} */}
|
||||
</Card>
|
||||
<div className="flex flex-col gap-1 dark:text-white">
|
||||
{data &&
|
||||
data.map((commit) => (
|
||||
<div
|
||||
key={commit.sha}
|
||||
className={`flex gap-2 rounded-md p-1 ${
|
||||
commit.sha.substring(0, 7) === process.env.COMMIT_HASH
|
||||
? 'bg-primary'
|
||||
: 'dark:bg-secondaryDark'
|
||||
}`}
|
||||
>
|
||||
<div className="my-auto font-mono text-sm">
|
||||
{commit.sha.substring(0, 7)}
|
||||
</div>
|
||||
<div className="truncate">{commit.commit.message}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Modal>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
@@ -22,6 +22,7 @@ interface AppState {
|
||||
HTTP: Types.HTTPConnectionParameters;
|
||||
SERIAL: Types.SerialConnectionParameters;
|
||||
};
|
||||
updateAvaliable: boolean;
|
||||
}
|
||||
|
||||
const initialState: AppState = {
|
||||
@@ -41,6 +42,7 @@ const initialState: AppState = {
|
||||
},
|
||||
SERIAL: {},
|
||||
},
|
||||
updateAvaliable: false,
|
||||
};
|
||||
|
||||
export const appSlice = createSlice({
|
||||
@@ -77,6 +79,9 @@ export const appSlice = createSlice({
|
||||
state.connectionParams[connType[action.payload.type]] =
|
||||
action.payload.params;
|
||||
},
|
||||
setUpdateAvaliable(state, action: PayloadAction<boolean>) {
|
||||
state.updateAvaliable = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -88,6 +93,7 @@ export const {
|
||||
setCurrentPage,
|
||||
setConnType,
|
||||
setConnectionParams,
|
||||
setUpdateAvaliable,
|
||||
} = appSlice.actions;
|
||||
|
||||
export default appSlice.reducer;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export default async function fetcher<JSON>(
|
||||
export const fetcher = async <JSON>(
|
||||
input: RequestInfo,
|
||||
init?: RequestInit,
|
||||
): Promise<JSON> {
|
||||
): Promise<JSON> => {
|
||||
const res = await fetch(input, init);
|
||||
return res.json() as Promise<JSON>;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import { request } from 'graphql-request';
|
||||
|
||||
export default async function gqlFetcher<JSON>(
|
||||
url: string,
|
||||
query?: string,
|
||||
): Promise<JSON> {
|
||||
// const res = await fetch(input, init);
|
||||
return await request<JSON>(url, query);
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { AnimatePresence, m } from 'framer-motion';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import { Card } from '@app/components/generic/Card';
|
||||
import fetcher from '@core/utils/fetcher';
|
||||
import { fetcher } from '@core/utils/fetcher';
|
||||
import { useAppSelector } from '@hooks/useAppSelector';
|
||||
|
||||
export interface File {
|
||||
|
||||
18
todo.txt
18
todo.txt
@@ -1,18 +0,0 @@
|
||||
Add desctiptions to form elements (below on mobile, to the right on desktop)
|
||||
add default value to undefined protobufs, (omit if default to keep them small (only for ota packets))
|
||||
add input validation min,max etc
|
||||
maybe make channel editor acordion?
|
||||
add url routing for settings tabs
|
||||
add loading blur to card (prop)
|
||||
form still considered dirty after save
|
||||
form prefix should be located in the input (absolute?)
|
||||
form suffix should focus input
|
||||
reset store on new connection
|
||||
redux actions seem to be dispatched twice
|
||||
add qr generator in channel editor
|
||||
no save button for channel config (bw,sf,cr,tx etc)
|
||||
should reset store beased on disconnect state, as it can be set by the lirary, not just user interactions
|
||||
way to set time for nodes, ntp?
|
||||
|
||||
meshtastic.js
|
||||
- fix entering device-reconnecting state and not re-connecting despite packets being received
|
||||
@@ -1,39 +0,0 @@
|
||||
export interface CommitHistory {
|
||||
data: Data;
|
||||
}
|
||||
|
||||
export interface Data {
|
||||
repository: Repository;
|
||||
}
|
||||
|
||||
export interface Repository {
|
||||
ref: Ref;
|
||||
}
|
||||
|
||||
export interface Ref {
|
||||
name: string;
|
||||
target: Target;
|
||||
}
|
||||
|
||||
export interface Target {
|
||||
history: History;
|
||||
}
|
||||
|
||||
export interface History {
|
||||
edges: Edge[];
|
||||
}
|
||||
|
||||
export interface Edge {
|
||||
node: Node;
|
||||
}
|
||||
|
||||
export interface Node {
|
||||
abbreviatedOid: string;
|
||||
message: string;
|
||||
author: Author;
|
||||
}
|
||||
|
||||
export interface Author {
|
||||
avatarUrl: string;
|
||||
name: string;
|
||||
}
|
||||
Reference in New Issue
Block a user