This commit is contained in:
Sacha Weatherstone
2022-02-07 00:00:55 +11:00
parent e43b04990b
commit 8d184578f0
109 changed files with 3495 additions and 3632 deletions
+69
View File
@@ -0,0 +1,69 @@
import React from 'react';
import useSWR from 'swr';
import fetcher from '@app/core/utils/fetcher';
import { useAppSelector } from '@app/hooks/useAppSelector';
export interface File {
nameModified: string;
name: string;
size: number;
}
export interface Files {
data: {
files: File[];
fileSystem: {
total: number;
used: number;
free: number;
};
};
status: string;
}
export const FileBrowser = (): JSX.Element => {
const connectionParams = useAppSelector(
(state) => state.app.connectionParams,
);
const { data } = useSWR<Files>(
`${connectionParams.HTTP.tls ? 'https' : 'http'}://${
connectionParams.HTTP.address
}/json/spiffs/browse/static`,
fetcher,
);
return (
<div className="flex h-full w-full select-none flex-col gap-4 p-4">
<div className="w-full flex-grow rounded-md bg-gray-200 dark:bg-primaryDark">
<div className="flex h-10 w-full rounded-t-md bg-gray-300 px-4 text-lg font-semibold dark:bg-zinc-700 dark:text-white">
<div className="my-auto w-1/3">FileName</div>
<div className="my-auto w-1/3">Actions</div>
</div>
<div className="px-4">
{data?.data.files.map((file) => (
<div
key={file.name}
className="flex h-10 w-full border-b border-gray-500 px-4 font-medium dark:text-white"
>
<div className="my-auto w-1/3">
<a
target="_blank"
rel="noopener noreferrer"
href={`${connectionParams.HTTP.tls ? 'https' : 'http'}://${
connectionParams.HTTP.address
}/${file.name.replace('static/', '')}`}
>
{file.name.replace('static/', '').replace('.gz', '')}
</a>
</div>
<div className="my-auto w-1/3"></div>
</div>
))}
</div>
</div>
</div>
);
};
+55
View File
@@ -0,0 +1,55 @@
import React from 'react';
import { FiFile, FiInfo } from 'react-icons/fi';
import { RiPinDistanceFill } from 'react-icons/ri';
import { VscExtensions } from 'react-icons/vsc';
import { Layout } from '@app/components/layout';
import { ExternalSection } from '@app/components/layout/Sidebar/sections/ExternalSection';
import { FileBrowser } from './FileBrowser';
import { Info } from './Info';
export const Extensions = (): JSX.Element => {
const [selectedExtension, setSelectedExtension] = React.useState<
'info' | 'fileBrowser' | 'rangeTest'
>('info');
return (
<Layout
title="Extensions"
icon={<VscExtensions />}
sidebarContents={
<div className="absolute flex h-full w-full flex-col dark:bg-primaryDark">
<ExternalSection
onClick={(): void => {
setSelectedExtension('info');
}}
icon={<FiInfo />}
title="Node Info"
/>
<ExternalSection
onClick={(): void => {
setSelectedExtension('fileBrowser');
}}
icon={<FiFile />}
title="File Browser"
/>
<ExternalSection
onClick={(): void => {
setSelectedExtension('rangeTest');
}}
icon={<RiPinDistanceFill />}
title="Range Test"
/>
</div>
}
>
<div className="w-full">
{selectedExtension === 'info' && <Info />}
{selectedExtension === 'fileBrowser' && <FileBrowser />}
</div>
</Layout>
);
};
+42
View File
@@ -0,0 +1,42 @@
import React from 'react';
import { m } from 'framer-motion';
import JSONPretty from 'react-json-pretty';
import { useAppSelector } from '@app/hooks/useAppSelector.js';
// eslint-disable-next-line import/no-unresolved
import skypack_hashicon from '@skypack/@emeraldpay/hashicon-react';
const Hashicon = skypack_hashicon.Hashicon;
// import { Hashicon } from '@emeraldpay/hashicon-react';
export const Info = (): JSX.Element => {
const hardwareInfo = useAppSelector(
(state) => state.meshtastic.radio.hardware,
);
const node = useAppSelector((state) =>
state.meshtastic.nodes.find(
(node) => node.number === hardwareInfo.myNodeNum,
),
);
return (
<div className="flex w-full select-none flex-col gap-4 p-4">
<m.div
whileHover={{ scale: 1.01 }}
className="flex w-full flex-col gap-4 rounded-md p-8 shadow-md dark:bg-primaryDark"
>
<div className="m-auto">
<Hashicon value={hardwareInfo.myNodeNum.toString()} size={180} />
</div>
<div className="text-center text-lg font-medium dark:text-white">
{node?.user?.longName || 'Unknown'}
</div>
</m.div>
<div className="rounded-md p-8 shadow-md dark:bg-primaryDark">
<JSONPretty data={hardwareInfo} />
</div>
</div>
);
};