Fixes
@@ -1,6 +0,0 @@
|
||||
[submodule "design"]
|
||||
path = design
|
||||
url = https://github.com/meshtastic/meshtastic-design/
|
||||
[submodule "public/design"]
|
||||
path = public/design
|
||||
url = https://github.com/meshtastic/meshtastic-design/
|
||||
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 745 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 15 KiB |
@@ -2,7 +2,13 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="/design/web/favicon.ico" />
|
||||
<link rel="shortcut icon" href="favicon.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png" />
|
||||
<link rel="manifest" href="site.webmanifest" />
|
||||
<link rel="mask-icon" href="safari-pinned-tab.svg" color="#67ea94" />
|
||||
<meta name="theme-color" content="#67ea94" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta
|
||||
name="description"
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M1090 2655 c-399 -585 -725 -1068 -724 -1072 0 -4 58 -47 129 -95
|
||||
l128 -88 27 38 c60 84 1422 2085 1426 2096 3 9 -244 187 -258 186 -2 0 -329
|
||||
-480 -728 -1065z"/>
|
||||
<path d="M3211 3669 c-18 -4 -45 -16 -60 -26 -30 -23 -1420 -2054 -1414 -2066
|
||||
4 -6 236 -166 254 -175 4 -1 287 409 630 912 343 503 624 914 625 913 1 -1
|
||||
282 -411 624 -912 343 -500 624 -911 625 -912 1 -2 61 38 133 88 111 76 131
|
||||
93 122 107 -43 78 -1391 2029 -1411 2044 -33 25 -85 36 -128 27z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 893 B |
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "Meshtastic",
|
||||
"short_name": "Meshtastic",
|
||||
"start_url": ".",
|
||||
"description": "Meshtastic web app",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#67ea94",
|
||||
"background_color": "#67ea94",
|
||||
"display": "standalone"
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 1115 116" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.5;">
|
||||
<g transform="matrix(1.05081,0,0,0.602459,-74.3378,-345.171)">
|
||||
<g>
|
||||
<g transform="matrix(0.973838,0,0,1.69858,-1.56777,-229.112)">
|
||||
<path d="M81.582,577.266L148.536,478.804" style="fill:none;stroke:black;stroke-width:14.11px;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.961342,0,0,1.67678,882.45,-216.54)">
|
||||
<path d="M81.582,577.266L148.536,478.804" style="fill:none;stroke:black;stroke-width:14.86px;"/>
|
||||
</g>
|
||||
<g transform="matrix(12.0448,0,0,21.0595,-7445.39,-7644.88)">
|
||||
<text x="640.988px" y="399.072px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:12px;">ESHT</text>
|
||||
</g>
|
||||
<g transform="matrix(0.977299,0,0,1.70462,-43.6432,50.5292)">
|
||||
<path d="M187.032,410.85L250.896,317.192L314.907,410.702" style="fill:none;stroke:black;stroke-width:13.85px;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.977299,0,0,1.70462,468.182,53.0697)">
|
||||
<path d="M187.032,410.85L250.896,317.192L314.907,410.702" style="fill:none;stroke:black;stroke-width:13.85px;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.571939,0,0,1,784.482,759.924)">
|
||||
<text x="0px" y="0px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:252.715px;">ST</text>
|
||||
</g>
|
||||
<g transform="matrix(0.571939,0,0,1,1030.51,760.498)">
|
||||
<text x="0px" y="0px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:252.715px;">C</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -135,20 +135,21 @@ const App = () => {
|
||||
|
||||
connection.onRoutingPacketEvent.subscribe((routingPacket) => {
|
||||
console.log(routingPacket);
|
||||
// console.log(messages);
|
||||
|
||||
messages.map((message) => {
|
||||
console.log(
|
||||
`${
|
||||
routingPacket.payloadVariant.oneofKind === 'decoded'
|
||||
? routingPacket.payloadVariant.decoded.requestId
|
||||
: null
|
||||
} === ${message.message.packet.id}: ${
|
||||
routingPacket.payloadVariant.oneofKind === 'decoded'
|
||||
? routingPacket.payloadVariant.decoded.requestId
|
||||
: null === message.message.packet.id
|
||||
}`,
|
||||
);
|
||||
});
|
||||
// messages.map((message) => {
|
||||
// console.log(
|
||||
// `${
|
||||
// routingPacket.payloadVariant.oneofKind === 'decoded'
|
||||
// ? routingPacket.payloadVariant.decoded.requestId
|
||||
// : null
|
||||
// } === ${message.message.packet.id}: ${
|
||||
// routingPacket.payloadVariant.oneofKind === 'decoded'
|
||||
// ? routingPacket.payloadVariant.decoded.requestId
|
||||
// : null === message.message.packet.id
|
||||
// }`,
|
||||
// );
|
||||
// });
|
||||
// messages.find((message) => {
|
||||
// message.message.packet.id === routingPacket.decoded.requestId;
|
||||
// });
|
||||
@@ -156,32 +157,6 @@ const App = () => {
|
||||
}, []);
|
||||
return (
|
||||
<div className="flex flex-col h-screen w-screen">
|
||||
{/* <Head>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
href="/design/web/apple-touch-icon.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="32x32"
|
||||
href="/design/web/favicon-32x32.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="16x16"
|
||||
href="/design/web/favicon-16x16.png"
|
||||
/>
|
||||
<link rel="manifest" href="/design/web/site.webmanifest" />
|
||||
<link
|
||||
rel="mask-icon"
|
||||
href="/design/web/safari-pinned-tab.svg"
|
||||
color="#67ea94"
|
||||
/>
|
||||
<meta name="theme-color" content="#67ea94" />
|
||||
</Head> */}
|
||||
<Header
|
||||
status={deviceStatus}
|
||||
IsReady={isReady}
|
||||
|
||||
@@ -105,6 +105,7 @@ const Main = (props: MainProps) => {
|
||||
Language={props.Language}
|
||||
SetLanguage={props.SetLanguage}
|
||||
Translations={props.Translations}
|
||||
myId={props.MyNodeInfo.myNodeNum}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -14,7 +14,7 @@ const Header = (props: HeaderProps) => {
|
||||
return (
|
||||
<nav className="w-full shadow-md">
|
||||
<div className="flex w-full container mx-auto justify-between px-6 py-4">
|
||||
<img src="/design/typelogo/typelogo.svg" height="30" width="200" />
|
||||
<img src="/typelogo.svg" height="30" width="200" />
|
||||
|
||||
<div className="flex items-center">
|
||||
<div className="flex pl-4">
|
||||
|
||||
@@ -4,7 +4,7 @@ import { FaCaretDown, FaCaretRight, FaSpinner } from 'react-icons/fa';
|
||||
|
||||
interface NavItemProps {
|
||||
isDropdown: boolean;
|
||||
open?: boolean;
|
||||
open: boolean;
|
||||
isNested: boolean;
|
||||
titleContent: ReactNode;
|
||||
dropdownContent?: ReactNode;
|
||||
|
||||
@@ -22,6 +22,7 @@ interface SidebarProps {
|
||||
Language: LanguageEnum;
|
||||
SetLanguage: Function;
|
||||
Translations: languageTemplate;
|
||||
myId: number;
|
||||
}
|
||||
|
||||
const Sidebar = (props: SidebarProps) => {
|
||||
@@ -37,6 +38,7 @@ const Sidebar = (props: SidebarProps) => {
|
||||
IsReady={props.IsReady}
|
||||
Nodes={props.Nodes}
|
||||
Translations={props.Translations}
|
||||
myId={props.myId}
|
||||
/>
|
||||
<SidebarDeviceSettings
|
||||
IsReady={props.IsReady}
|
||||
|
||||
@@ -35,6 +35,7 @@ const SidebarChannels = (props: SidebarChannelsProps) => {
|
||||
key={index}
|
||||
isDropdown={true}
|
||||
isNested={true}
|
||||
open={false}
|
||||
titleContent={
|
||||
<div className="flex">
|
||||
{channel.index} - {Protobuf.Channel_Role[channel.role]}
|
||||
@@ -44,6 +45,7 @@ const SidebarChannels = (props: SidebarChannelsProps) => {
|
||||
<NavItem
|
||||
isDropdown={false}
|
||||
isNested={false}
|
||||
open={false}
|
||||
titleContent={
|
||||
<div className="w-full">
|
||||
<div className="flex justify-between border-b hover:bg-gray-200">
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
import React from 'react';
|
||||
|
||||
import { FaDesktop, FaUsers } from 'react-icons/fa';
|
||||
import {
|
||||
FaBatteryHalf,
|
||||
FaClock,
|
||||
FaCrown,
|
||||
FaDesktop,
|
||||
FaMapMarkerAlt,
|
||||
FaMountain,
|
||||
FaUsers,
|
||||
} from 'react-icons/fa';
|
||||
|
||||
import type { Types } from '@meshtastic/meshtasticjs';
|
||||
|
||||
@@ -11,6 +19,7 @@ interface sidebarNodesProps {
|
||||
IsReady: boolean;
|
||||
Nodes: Types.NodeInfoPacket[];
|
||||
Translations: languageTemplate;
|
||||
myId: number;
|
||||
}
|
||||
|
||||
const SidebarNodes = (props: sidebarNodesProps) => {
|
||||
@@ -39,7 +48,11 @@ const SidebarNodes = (props: sidebarNodesProps) => {
|
||||
open={false}
|
||||
titleContent={
|
||||
<div key={index} className="flex">
|
||||
<FaDesktop className="my-auto mr-2" />
|
||||
{node.data.num === props.myId ? (
|
||||
<FaCrown className="text-yellow-500 my-auto mr-2" />
|
||||
) : (
|
||||
<FaDesktop className="my-auto mr-2" />
|
||||
)}
|
||||
<div className="m-auto">{node.data.user?.longName}</div>
|
||||
</div>
|
||||
}
|
||||
@@ -47,6 +60,7 @@ const SidebarNodes = (props: sidebarNodesProps) => {
|
||||
<NavItem
|
||||
isDropdown={false}
|
||||
isNested={true}
|
||||
open={false}
|
||||
titleContent={
|
||||
<div>
|
||||
<p>
|
||||
@@ -58,15 +72,34 @@ const SidebarNodes = (props: sidebarNodesProps) => {
|
||||
{node.packet?.rxRssi ? node.packet.rxRssi : 'Unknown'}
|
||||
</p>
|
||||
<p>
|
||||
Last heard:{' '}
|
||||
{node.data?.lastHeard ? node.data.lastHeard : 'Unknown'}
|
||||
</p>
|
||||
<p>
|
||||
Loc:{' '}
|
||||
{node.data?.position
|
||||
? `alt: ${node.data?.position.altitude}, lat: ${node.data?.position.latitudeI}, lng: ${node.data?.position.longitudeI}, time: ${node.data?.position.time}, batt: ${node.data?.position.batteryLevel}`
|
||||
: 'Unknown'}
|
||||
{`Last heard: ${
|
||||
node.data?.lastHeard
|
||||
? new Date(node.data.lastHeard).toLocaleString()
|
||||
: 'Unknown'
|
||||
}`}{' '}
|
||||
{}
|
||||
</p>
|
||||
<div className="flex">
|
||||
<FaMapMarkerAlt className="my-auto mr-2" />
|
||||
<p>
|
||||
{node.data.position?.latitudeI},
|
||||
{node.data.position?.longitudeI}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex">
|
||||
<FaMountain className="my-auto mr-2" />
|
||||
<p>{node.data.position?.altitude}</p>
|
||||
</div>
|
||||
|
||||
<div className="flex">
|
||||
<FaClock className="my-auto mr-2" />
|
||||
<p>{node.data.position?.time}</p>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<FaBatteryHalf className="my-auto mr-2" />
|
||||
<p>{node.data.position?.batteryLevel}</p>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -19,6 +19,7 @@ const SidebarUISettings = (props: SidebarUISettingsProps) => {
|
||||
<NavItem
|
||||
isDropdown={true}
|
||||
isNested={false}
|
||||
open={false}
|
||||
titleContent={
|
||||
<div className="flex">
|
||||
<FaCog className="my-auto mr-2" />
|
||||
@@ -30,6 +31,7 @@ const SidebarUISettings = (props: SidebarUISettingsProps) => {
|
||||
<NavItem
|
||||
isDropdown={false}
|
||||
isNested={true}
|
||||
open={false}
|
||||
titleContent={
|
||||
<>
|
||||
<div className="my-auto">
|
||||
@@ -71,6 +73,7 @@ const SidebarUISettings = (props: SidebarUISettingsProps) => {
|
||||
onClick={() => {
|
||||
props.SetLanguage(LanguageEnum.ENGLISH);
|
||||
}}
|
||||
open={false}
|
||||
isDropdown={false}
|
||||
isNested={true}
|
||||
titleContent={
|
||||
@@ -81,6 +84,7 @@ const SidebarUISettings = (props: SidebarUISettingsProps) => {
|
||||
onClick={() => {
|
||||
props.SetLanguage(LanguageEnum.JAPANESE);
|
||||
}}
|
||||
open={false}
|
||||
isDropdown={false}
|
||||
isNested={true}
|
||||
titleContent={
|
||||
|
||||