mirror of
https://github.com/meshtastic/meshtastic.git
synced 2024-12-24 05:04:11 -08:00
Add Trunk and lint non mdx files
This commit is contained in:
parent
f924461192
commit
d94b0e9a42
|
@ -1,4 +1,9 @@
|
|||
|
||||
|
||||
|
||||
{
|
||||
"plugins": ["@docusaurus"],
|
||||
"extends": ["plugin:@docusaurus/recommended"]
|
||||
}
|
||||
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:@docusaurus/recommended"],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@docusaurus", "@typescript-eslint"],
|
||||
"root": true
|
||||
}
|
|
@ -6,9 +6,9 @@ module.exports = {
|
|||
overrides: {
|
||||
removeViewBox: false, // https://github.com/svg/svgo/issues/1128
|
||||
sortAttrs: true,
|
||||
removeOffCanvasPaths: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
removeOffCanvasPaths: true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
@ -12,7 +12,6 @@ lint:
|
|||
- actionlint@1.6.22
|
||||
- gitleaks@8.15.2
|
||||
- git-diff-check
|
||||
- oxipng@8.0.0
|
||||
- shellcheck@0.9.0
|
||||
- prettier@2.8.2
|
||||
- shfmt@3.5.0
|
||||
|
|
6
.vscode/extensions.json
vendored
6
.vscode/extensions.json
vendored
|
@ -1,5 +1,3 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"trunk.io"
|
||||
]
|
||||
}
|
||||
"recommendations": ["trunk.io"]
|
||||
}
|
||||
|
|
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
|
@ -1,4 +1,7 @@
|
|||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "trunk.io"
|
||||
}
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "trunk.io",
|
||||
"files.associations": {
|
||||
"*.mdx": "markdown"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ Website and documentation source for the Meshtastic project.
|
|||
|
||||
## Stats
|
||||
|
||||
![Alt](https://repobeats.axiom.co/api/embed/9ef7282debe009789c697432a86499ac2b058a86.svg 'Repobeats analytics image')
|
||||
![Alt](https://repobeats.axiom.co/api/embed/9ef7282debe009789c697432a86499ac2b058a86.svg "Repobeats analytics image")
|
||||
|
||||
## Development & Building
|
||||
|
||||
|
|
|
@ -4,4 +4,4 @@ collapsible: true # make the category collapsible
|
|||
link:
|
||||
type: generated-index
|
||||
title: About Meshtastic
|
||||
slug: /about
|
||||
slug: /about
|
||||
|
|
|
@ -4,4 +4,4 @@ position: 4
|
|||
link:
|
||||
type: generated-index
|
||||
title: Configuration
|
||||
slug: /settings
|
||||
slug: /settings
|
||||
|
|
|
@ -4,4 +4,4 @@ position: 7
|
|||
link:
|
||||
type: generated-index
|
||||
title: Developers
|
||||
slug: /developers
|
||||
slug: /developers
|
||||
|
|
|
@ -4,4 +4,4 @@ position: 1
|
|||
link:
|
||||
slug: /development/device
|
||||
type: generated-index
|
||||
title: Device
|
||||
title: Device
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
position: 1 # float position is supported
|
||||
label: 'Style Guides'
|
||||
label: "Style Guides"
|
||||
collapsible: true # make the category collapsible
|
||||
link:
|
||||
slug: /development/docs/style-guide
|
||||
type: generated-index
|
||||
title: Style Guides
|
||||
title: Style Guides
|
||||
|
|
|
@ -4,4 +4,4 @@ position: 1
|
|||
link:
|
||||
type: generated-index
|
||||
title: Firmware
|
||||
slug: /development/firmware
|
||||
slug: /development/firmware
|
||||
|
|
|
@ -4,4 +4,4 @@ position: 20
|
|||
link:
|
||||
type: generated-index
|
||||
slug: /development/reference
|
||||
title: Reference Material
|
||||
title: Reference Material
|
||||
|
|
|
@ -4,4 +4,4 @@ position: 2
|
|||
link:
|
||||
type: generated-index
|
||||
title: Flashing Firmware
|
||||
slug: /getting-started/flashing-firmware
|
||||
slug: /getting-started/flashing-firmware
|
||||
|
|
|
@ -4,4 +4,4 @@ position: 1
|
|||
link:
|
||||
type: generated-index
|
||||
title: Installing Serial Drivers
|
||||
slug: /getting-started/serial-drivers
|
||||
slug: /getting-started/serial-drivers
|
||||
|
|
|
@ -4,4 +4,4 @@ position: 5
|
|||
link:
|
||||
type: generated-index
|
||||
title: Supported Hardware
|
||||
slug: hardware
|
||||
slug: hardware
|
||||
|
|
|
@ -4,4 +4,4 @@ position: 2
|
|||
link:
|
||||
type: generated-index
|
||||
title: Antennas
|
||||
slug: antenna
|
||||
slug: antenna
|
||||
|
|
|
@ -4,4 +4,4 @@ position: 1
|
|||
link:
|
||||
type: generated-index
|
||||
title: Supported Devices
|
||||
slug: supported-hardware
|
||||
slug: supported-hardware
|
||||
|
|
|
@ -4,4 +4,4 @@ position: 6
|
|||
link:
|
||||
type: generated-index
|
||||
title: Software
|
||||
slug: /software
|
||||
slug: /software
|
||||
|
|
|
@ -3,4 +3,4 @@ collapsible: true
|
|||
position: 1
|
||||
link:
|
||||
type: generated-index
|
||||
title: Android App
|
||||
title: Android App
|
||||
|
|
|
@ -3,4 +3,4 @@ collapsible: true
|
|||
position: 2
|
||||
link:
|
||||
type: generated-index
|
||||
title: Apple Applications
|
||||
title: Apple Applications
|
||||
|
|
|
@ -1,144 +1,145 @@
|
|||
// @ts-check
|
||||
|
||||
require('dotenv').config();
|
||||
require("dotenv").config();
|
||||
|
||||
/** @type {import('@docusaurus/types').Config} */
|
||||
const config = {
|
||||
title: 'Meshtastic',
|
||||
title: "Meshtastic",
|
||||
tagline:
|
||||
'An open source, off-grid, decentralized, mesh network built to run on affordable, low-power devices',
|
||||
url: 'https://meshtastic.org',
|
||||
baseUrl: '/',
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
favicon: 'design/web/favicon.ico',
|
||||
organizationName: 'meshtastic',
|
||||
projectName: 'meshtastic',
|
||||
"An open source, off-grid, decentralized, mesh network built to run on affordable, low-power devices",
|
||||
url: "https://meshtastic.org",
|
||||
baseUrl: "/",
|
||||
onBrokenLinks: "throw",
|
||||
onBrokenMarkdownLinks: "warn",
|
||||
favicon: "design/web/favicon.ico",
|
||||
organizationName: "meshtastic",
|
||||
projectName: "meshtastic",
|
||||
themeConfig: /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ {
|
||||
announcementBar: {
|
||||
id: '2_0',
|
||||
id: "2_0",
|
||||
content:
|
||||
'🎉 Meshtastic 2.0 Has Now Launched! Check it Out <a href="/2.0">Here</a> 🎉',
|
||||
'🎉 Meshtastic 2.0 Has Now Launched! Check it Out <a href="/2.0">Here</a> 🎉'
|
||||
},
|
||||
docs: {
|
||||
sidebar: {
|
||||
autoCollapseCategories: true,
|
||||
},
|
||||
autoCollapseCategories: true
|
||||
}
|
||||
},
|
||||
navbar: {
|
||||
title: 'Meshtastic',
|
||||
title: "Meshtastic",
|
||||
hideOnScroll: true,
|
||||
logo: {
|
||||
alt: 'Meshtastic Logo',
|
||||
src: 'design/logo/svg/Mesh_Logo_Black.svg',
|
||||
srcDark: 'design/logo/svg/Mesh_Logo_White.svg',
|
||||
alt: "Meshtastic Logo",
|
||||
src: "design/logo/svg/Mesh_Logo_Black.svg",
|
||||
srcDark: "design/logo/svg/Mesh_Logo_White.svg"
|
||||
},
|
||||
items: [
|
||||
{
|
||||
label: 'Docs',
|
||||
to: 'docs/introduction',
|
||||
label: "Docs",
|
||||
to: "docs/introduction"
|
||||
},
|
||||
{
|
||||
label: 'Downloads',
|
||||
to: 'downloads',
|
||||
label: "Downloads",
|
||||
to: "downloads"
|
||||
},
|
||||
{
|
||||
label: 'About',
|
||||
position: 'right',
|
||||
label: "About",
|
||||
position: "right",
|
||||
items: [
|
||||
{
|
||||
label: 'Introduction',
|
||||
to: 'docs/introduction',
|
||||
label: "Introduction",
|
||||
to: "docs/introduction"
|
||||
},
|
||||
{
|
||||
label: 'Getting Started',
|
||||
to: 'docs/getting-started',
|
||||
label: "Getting Started",
|
||||
to: "docs/getting-started"
|
||||
},
|
||||
{
|
||||
label: 'Contributing',
|
||||
to: 'docs/contributing',
|
||||
label: "Contributing",
|
||||
to: "docs/contributing"
|
||||
},
|
||||
{
|
||||
label: 'Legal',
|
||||
to: 'docs/legal',
|
||||
label: "Legal",
|
||||
to: "docs/legal"
|
||||
},
|
||||
{
|
||||
label: 'FAQs',
|
||||
to: 'docs/faq',
|
||||
},
|
||||
],
|
||||
label: "FAQs",
|
||||
to: "docs/faq"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/meshtastic',
|
||||
position: 'right',
|
||||
className: 'header-github-link',
|
||||
'aria-label': 'GitHub repository',
|
||||
},
|
||||
],
|
||||
href: "https://github.com/meshtastic",
|
||||
position: "right",
|
||||
className: "header-github-link",
|
||||
"aria-label": "GitHub repository"
|
||||
}
|
||||
]
|
||||
},
|
||||
footer: {
|
||||
copyright: `<a href="https://vercel.com/?utm_source=meshtastic&utm_campaign=oss">Powered by ▲ Vercel</a> | Meshtastic® is a registered trademark of Meshtastic LLC. | <a href="/docs/legal">Legal Information</a>.`,
|
||||
copyright: `<a href="https://vercel.com/?utm_source=meshtastic&utm_campaign=oss">Powered by ▲ Vercel</a> | Meshtastic® is a registered trademark of Meshtastic LLC. | <a href="/docs/legal">Legal Information</a>.`
|
||||
},
|
||||
algolia: {
|
||||
appId: 'IG2GQB8L3V',
|
||||
apiKey: '2e4348812173ec7ea6f7879c7032bb21',
|
||||
indexName: 'meshtastic',
|
||||
appId: "IG2GQB8L3V",
|
||||
// trunk-ignore(gitleaks/generic-api-key)
|
||||
apiKey: "2e4348812173ec7ea6f7879c7032bb21",
|
||||
indexName: "meshtastic",
|
||||
contextualSearch: false,
|
||||
searchPagePath: 'search',
|
||||
searchPagePath: "search"
|
||||
},
|
||||
colorMode: {
|
||||
respectPrefersColorScheme: true,
|
||||
respectPrefersColorScheme: true
|
||||
},
|
||||
mermaid: {
|
||||
theme: {light: 'base', dark: 'base'},
|
||||
theme: { light: "base", dark: "base" },
|
||||
options: {
|
||||
themeVariables: {
|
||||
primaryColor: '#67EA94',
|
||||
primaryTextColor: 'var(--tw-prose-headings)',
|
||||
primaryBorderColor: '#4D4D4D',
|
||||
lineColor: '#EAD667',
|
||||
secondaryColor: '#EA67BD',
|
||||
tertiaryColor: '#677CEA'
|
||||
},
|
||||
},
|
||||
primaryColor: "#67EA94",
|
||||
primaryTextColor: "var(--tw-prose-headings)",
|
||||
primaryBorderColor: "#4D4D4D",
|
||||
lineColor: "#EAD667",
|
||||
secondaryColor: "#EA67BD",
|
||||
tertiaryColor: "#677CEA"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
() => {
|
||||
return {
|
||||
name: 'docusaurus-tailwindcss',
|
||||
name: "docusaurus-tailwindcss",
|
||||
configurePostCss(postcssOptions) {
|
||||
postcssOptions.plugins.push(require('tailwindcss'));
|
||||
postcssOptions.plugins.push(require('autoprefixer'));
|
||||
postcssOptions.plugins.push(require("tailwindcss"));
|
||||
postcssOptions.plugins.push(require("autoprefixer"));
|
||||
return postcssOptions;
|
||||
},
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
],
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
"@docusaurus/preset-classic",
|
||||
/** @type {import('@docusaurus/preset-classic').Options} */
|
||||
{
|
||||
docs: {
|
||||
sidebarPath: require.resolve('./sidebars.js'),
|
||||
editUrl: 'https://github.com/meshtastic/meshtastic/edit/master/',
|
||||
sidebarPath: require.resolve("./sidebars.js"),
|
||||
editUrl: "https://github.com/meshtastic/meshtastic/edit/master/",
|
||||
breadcrumbs: false,
|
||||
showLastUpdateAuthor: true,
|
||||
showLastUpdateAuthor: true
|
||||
},
|
||||
theme: {
|
||||
customCss: require.resolve('./src/css/custom.css'),
|
||||
},
|
||||
},
|
||||
],
|
||||
customCss: require.resolve("./src/css/custom.css")
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
customFields: {
|
||||
API_URL: process.env.API_URL,
|
||||
API_URL: process.env.API_URL
|
||||
},
|
||||
markdown: {
|
||||
mermaid: true,
|
||||
mermaid: true
|
||||
},
|
||||
themes: ['@docusaurus/theme-mermaid'],
|
||||
themes: ["@docusaurus/theme-mermaid"]
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
"start": "docusaurus start",
|
||||
"build": "docusaurus build",
|
||||
"serve": "docusaurus serve",
|
||||
"clear": "docusaurus clear",
|
||||
"format": "prettier --write 'docs/**/*{.md,.mdx}' 'src/**/*.{ts,tsx}'",
|
||||
"lint": "eslint src/**/*.{ts,tsx}"
|
||||
"clear": "docusaurus clear"
|
||||
},
|
||||
"dependencies": {
|
||||
"@algolia/client-search": "^4.14.3",
|
||||
|
@ -22,9 +20,12 @@
|
|||
"@heroicons/react": "^2.0.13",
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"@meshtastic/meshtasticjs": "2.0.13-0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
||||
"@typescript-eslint/parser": "^5.48.2",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"base64-js": "^1.5.1",
|
||||
"dotenv": "^16.0.3",
|
||||
"eslint": "^8.32.0",
|
||||
"framer-motion": "^6.5.1",
|
||||
"postcss": "^8.4.21",
|
||||
"react": "^17.0.2",
|
||||
|
@ -37,6 +38,7 @@
|
|||
"use-breakpoint": "^3.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/eslint-plugin": "^2.2.0",
|
||||
"@docusaurus/module-type-aliases": "2.2.0",
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"@tsconfig/docusaurus": "^1.0.6",
|
||||
|
|
539
pnpm-lock.yaml
539
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
export const BatteryCalculator = (): JSX.Element => {
|
||||
return (
|
||||
|
@ -6,7 +6,7 @@ export const BatteryCalculator = (): JSX.Element => {
|
|||
<div className="card__header">
|
||||
<h3>Battery Calculator</h3>
|
||||
</div>
|
||||
<div className="card__body" style={{ display: 'flex', gap: '2rem' }}>
|
||||
<div className="card__body" style={{ display: "flex", gap: "2rem" }}>
|
||||
<div>
|
||||
<input placeholder="Search" />
|
||||
<input placeholder="Search" />
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { HTMLMotionProps, motion } from 'framer-motion';
|
||||
import { HTMLMotionProps, motion } from "framer-motion";
|
||||
|
||||
export const Button = ({ children, ...props }: HTMLMotionProps<'div'>) => {
|
||||
export const Button = ({ children, ...props }: HTMLMotionProps<"div">) => {
|
||||
return (
|
||||
<motion.div
|
||||
{...props}
|
||||
whileHover={{ scale: 1.1, backgroundColor: 'var(--tertiary)' }}
|
||||
whileHover={{ scale: 1.1, backgroundColor: "var(--tertiary)" }}
|
||||
whileTap={{ scale: 1.0 }}
|
||||
className="m-auto flex cursor-pointer rounded-full bg-secondary p-3 shadow-md"
|
||||
>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
export interface ColorModeProps {
|
||||
children: React.ReactNode;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
|
||||
import { Dialog } from '@headlessui/react';
|
||||
import { Dialog } from "@headlessui/react";
|
||||
|
||||
export interface ModalProps {
|
||||
open: boolean;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import Layout from '@theme/Layout';
|
||||
import Layout from "@theme/Layout";
|
||||
|
||||
export interface PageLayoutProps {
|
||||
title: string;
|
||||
|
@ -11,7 +11,7 @@ export interface PageLayoutProps {
|
|||
export const PageLayout = ({
|
||||
title,
|
||||
description,
|
||||
children,
|
||||
children
|
||||
}: PageLayoutProps): JSX.Element => {
|
||||
return (
|
||||
<Layout title={title} description={description}>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
export interface BadgeProps {
|
||||
name: string;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { Tab } from '@headlessui/react';
|
||||
import { Tab } from "@headlessui/react";
|
||||
|
||||
export interface CardTabProps {
|
||||
title: string;
|
||||
|
@ -11,7 +11,7 @@ export const CardTab = ({ title }: CardTabProps): JSX.Element => {
|
|||
<Tab
|
||||
className={({ selected }) =>
|
||||
`w-1/3 truncate rounded-md px-3 py-2 text-sm font-medium hover:bg-tertiary ${
|
||||
selected ? 'bg-secondary shadow-md' : ''
|
||||
selected ? "bg-secondary shadow-md" : ""
|
||||
}`
|
||||
}
|
||||
>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { IDevice, Stability } from '@site/src/data/device';
|
||||
import { IDevice, Stability } from "@site/src/data/device";
|
||||
|
||||
export interface HardwareCardProps {
|
||||
device: IDevice;
|
||||
|
@ -9,7 +9,7 @@ export interface HardwareCardProps {
|
|||
|
||||
export const HardwareCard = ({
|
||||
device,
|
||||
setDevice,
|
||||
setDevice
|
||||
}: HardwareCardProps): JSX.Element => {
|
||||
return (
|
||||
<li
|
||||
|
@ -41,12 +41,12 @@ export const HardwareCard = ({
|
|||
<div
|
||||
className={`my-auto h-3 w-3 rounded-full ${
|
||||
device.misc.Stability === Stability.Broken
|
||||
? 'bg-red-500'
|
||||
? "bg-red-500"
|
||||
: device.misc.Stability === Stability.Unstable
|
||||
? 'bg-orange-500'
|
||||
? "bg-orange-500"
|
||||
: device.misc.Stability === Stability.Semi
|
||||
? 'bg-cyan-500'
|
||||
: 'bg-green-500'
|
||||
? "bg-cyan-500"
|
||||
: "bg-green-500"
|
||||
}`}
|
||||
/>
|
||||
<div className="my-auto">{Stability[device.misc.Stability]}</div>
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { FiBluetooth, FiChevronRight, FiWifi, FiX } from 'react-icons/fi';
|
||||
import { useBreakpoint } from 'use-breakpoint';
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { FiBluetooth, FiChevronRight, FiWifi, FiX } from "react-icons/fi";
|
||||
import { useBreakpoint } from "use-breakpoint";
|
||||
|
||||
import { Tab } from '@headlessui/react';
|
||||
import type { IDevice } from '@site/src/data/device';
|
||||
import { Tab } from "@headlessui/react";
|
||||
import type { IDevice } from "@site/src/data/device";
|
||||
|
||||
import { Button } from '../../components/Button';
|
||||
import { BREAKPOINTS } from '../../utils/breakpoints';
|
||||
import { Modal } from '../Modal';
|
||||
import { Badge } from './Badge';
|
||||
import { CardTab } from './CardTab';
|
||||
import { InfoTab } from './Tabs/InfoTab';
|
||||
import { PinoutTab } from './Tabs/PinoutTab';
|
||||
import { PowerTab } from './Tabs/PowerTab';
|
||||
import { VariantSelectButton } from './VariantSelectButton';
|
||||
import { Button } from "../../components/Button";
|
||||
import { BREAKPOINTS } from "../../utils/breakpoints";
|
||||
import { Modal } from "../Modal";
|
||||
import { Badge } from "./Badge";
|
||||
import { CardTab } from "./CardTab";
|
||||
import { InfoTab } from "./Tabs/InfoTab";
|
||||
import { PinoutTab } from "./Tabs/PinoutTab";
|
||||
import { PowerTab } from "./Tabs/PowerTab";
|
||||
import { VariantSelectButton } from "./VariantSelectButton";
|
||||
|
||||
export interface HardwareModal {
|
||||
device: IDevice;
|
||||
|
@ -26,10 +26,10 @@ export interface HardwareModal {
|
|||
export const HardwareModal = ({
|
||||
device,
|
||||
open,
|
||||
close,
|
||||
close
|
||||
}: HardwareModal): JSX.Element => {
|
||||
const [hideDetails, setHideDetails] = useState(false);
|
||||
const { breakpoint } = useBreakpoint(BREAKPOINTS, 'md');
|
||||
const { breakpoint } = useBreakpoint(BREAKPOINTS, "md");
|
||||
|
||||
return (
|
||||
<Modal open={open} onClose={close}>
|
||||
|
@ -42,22 +42,22 @@ export const HardwareModal = ({
|
|||
<motion.div
|
||||
layout
|
||||
animate={
|
||||
breakpoint === 'sm'
|
||||
breakpoint === "sm"
|
||||
? hideDetails
|
||||
? 'hiddenSm'
|
||||
: 'visibleSm'
|
||||
? "hiddenSm"
|
||||
: "visibleSm"
|
||||
: hideDetails
|
||||
? 'hidden'
|
||||
: 'visible'
|
||||
? "hidden"
|
||||
: "visible"
|
||||
}
|
||||
variants={{
|
||||
hidden: { width: '100%', height: '100%' },
|
||||
hiddenSm: { height: '100%', width: '100%' },
|
||||
visible: { width: '20%', height: '100%' },
|
||||
visibleSm: { height: '33%', width: '100%' },
|
||||
hidden: { width: "100%", height: "100%" },
|
||||
hiddenSm: { height: "100%", width: "100%" },
|
||||
visible: { width: "20%", height: "100%" },
|
||||
visibleSm: { height: "33%", width: "100%" }
|
||||
}}
|
||||
transition={{
|
||||
type: 'just',
|
||||
type: "just"
|
||||
}}
|
||||
className="flex flex-col md:h-full md:flex-row"
|
||||
>
|
||||
|
@ -74,19 +74,19 @@ export const HardwareModal = ({
|
|||
<div className="absolute -bottom-5 z-20 flex w-full md:bottom-auto md:-right-5 md:h-full md:w-auto">
|
||||
<Button
|
||||
animate={
|
||||
breakpoint === 'sm'
|
||||
breakpoint === "sm"
|
||||
? hideDetails
|
||||
? 'hiddenSm'
|
||||
: 'visibleSm'
|
||||
? "hiddenSm"
|
||||
: "visibleSm"
|
||||
: hideDetails
|
||||
? 'hidden'
|
||||
: 'visible'
|
||||
? "hidden"
|
||||
: "visible"
|
||||
}
|
||||
variants={{
|
||||
hidden: { rotate: 180 },
|
||||
hiddenSm: { rotate: -90 },
|
||||
visible: { rotate: 0 },
|
||||
visibleSm: { rotate: 90 },
|
||||
visibleSm: { rotate: 90 }
|
||||
}}
|
||||
onClick={() => {
|
||||
setHideDetails(!hideDetails);
|
||||
|
@ -103,7 +103,7 @@ export const HardwareModal = ({
|
|||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className={`absolute -bottom-5 z-20 flex md:mt-0 md:hidden md:pb-2 ${
|
||||
hideDetails ? 'opacity-0' : 'opacity-100'
|
||||
hideDetails ? "opacity-0" : "opacity-100"
|
||||
}`}
|
||||
>
|
||||
<VariantSelectButton options={device.variants} />
|
||||
|
@ -137,7 +137,7 @@ export const HardwareModal = ({
|
|||
</motion.div>
|
||||
<div
|
||||
className={`h-7 bg-base opacity-0 md:h-auto md:w-7 ${
|
||||
hideDetails ? 'flex' : 'hidden'
|
||||
hideDetails ? "flex" : "hidden"
|
||||
}`}
|
||||
/>
|
||||
</motion.div>
|
||||
|
@ -148,7 +148,7 @@ export const HardwareModal = ({
|
|||
</div>
|
||||
<div
|
||||
className={`mt-1 flex flex-grow rounded-2xl bg-base p-2 shadow-inner transition-opacity duration-100 ease-linear md:mt-0 md:rounded-l-none md:rounded-r-2xl md:p-4 ${
|
||||
hideDetails ? 'opacity-0' : 'opacity-100'
|
||||
hideDetails ? "opacity-0" : "opacity-100"
|
||||
}`}
|
||||
>
|
||||
<Tab.Group
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { Tab } from '@headlessui/react';
|
||||
import { Tab } from "@headlessui/react";
|
||||
|
||||
import type { IDevice } from '../../../data/device';
|
||||
import type { IDevice } from "../../../data/device";
|
||||
|
||||
export interface InfoTabProps {
|
||||
device: IDevice;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { Tab } from '@headlessui/react';
|
||||
import { Tab } from "@headlessui/react";
|
||||
|
||||
import type { IDevice } from '../../../data/device';
|
||||
import type { IDevice } from "../../../data/device";
|
||||
|
||||
export interface PinoutTabProps {
|
||||
device: IDevice;
|
||||
|
@ -14,13 +14,13 @@ export const PinoutTab = ({ device }: PinoutTabProps): JSX.Element => {
|
|||
<div className="m-auto flex gap-4 rounded-lg bg-slate-700 px-2 py-1 shadow-md">
|
||||
{[
|
||||
device.pinout.slice(0, device.misc.pinoutSplit),
|
||||
device.pinout.slice(device.misc.pinoutSplit, device.pinout.length),
|
||||
device.pinout.slice(device.misc.pinoutSplit, device.pinout.length)
|
||||
].map((group, index) => (
|
||||
<div key={index}>
|
||||
{group.map((pin, pinIndex) => (
|
||||
<div
|
||||
className={`flex gap-1 ${
|
||||
index === 0 ? 'flex-row' : 'flex-row-reverse'
|
||||
index === 0 ? "flex-row" : "flex-row-reverse"
|
||||
}`}
|
||||
key={pinIndex}
|
||||
>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { Tab } from '@headlessui/react';
|
||||
import { Tab } from "@headlessui/react";
|
||||
|
||||
import type { IDevice } from '../../../data/device';
|
||||
import type { IDevice } from "../../../data/device";
|
||||
|
||||
export interface PowerTabProps {
|
||||
device: IDevice;
|
||||
}
|
||||
|
||||
export const PowerTab = ({ device }: PowerTabProps): JSX.Element => {
|
||||
export const PowerTab = ({}: PowerTabProps): JSX.Element => {
|
||||
return <Tab.Panel className="h-32">Content 1</Tab.Panel>;
|
||||
};
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import React, { Fragment, useState } from 'react';
|
||||
import React, { Fragment, useState } from "react";
|
||||
|
||||
import { motion } from 'framer-motion';
|
||||
import { FiCheck } from 'react-icons/fi';
|
||||
import { HiSelector } from 'react-icons/hi';
|
||||
import { motion } from "framer-motion";
|
||||
import { FiCheck } from "react-icons/fi";
|
||||
import { HiSelector } from "react-icons/hi";
|
||||
|
||||
import { Listbox, Transition } from '@headlessui/react';
|
||||
import type { Variant } from '@site/src/data/device.js';
|
||||
import { Listbox, Transition } from "@headlessui/react";
|
||||
import type { Variant } from "@site/src/data/device.js";
|
||||
|
||||
export interface VariantSelectButtonProps {
|
||||
options: Variant[];
|
||||
}
|
||||
|
||||
export const VariantSelectButton = ({
|
||||
options,
|
||||
options
|
||||
}: VariantSelectButtonProps): JSX.Element => {
|
||||
const [selected, setSelected] = useState(options[options.length - 1]);
|
||||
|
||||
|
@ -23,7 +23,7 @@ export const VariantSelectButton = ({
|
|||
<div className="relative select-none">
|
||||
<Listbox.Button as={Fragment}>
|
||||
<motion.button
|
||||
whileHover={{ backgroundColor: 'var(--tertiary)' }}
|
||||
whileHover={{ backgroundColor: "var(--tertiary)" }}
|
||||
whileTap={{ scale: 0.99 }}
|
||||
className="relative -mt-5 ml-2 flex w-fit gap-1 rounded-lg bg-secondary p-2 py-2 pl-3 pr-10 text-lg font-medium leading-6 shadow-md md:mt-2"
|
||||
>
|
||||
|
@ -50,7 +50,7 @@ export const VariantSelectButton = ({
|
|||
key={index}
|
||||
className={({ active }) =>
|
||||
`relative cursor-default select-none py-2 pl-3 pr-9 ${
|
||||
active ? 'bg-secondary' : ''
|
||||
active ? "bg-secondary" : ""
|
||||
}`
|
||||
}
|
||||
value={variant}
|
||||
|
@ -59,7 +59,7 @@ export const VariantSelectButton = ({
|
|||
<>
|
||||
<span
|
||||
className={`block truncate ${
|
||||
selected ? 'font-semibold' : 'font-normal'
|
||||
selected ? "font-semibold" : "font-normal"
|
||||
}`}
|
||||
>
|
||||
{variant.name}
|
||||
|
@ -68,7 +68,7 @@ export const VariantSelectButton = ({
|
|||
{selected ? (
|
||||
<span
|
||||
className={`absolute inset-y-0 right-0 flex items-center pr-4 ${
|
||||
active ? '' : 'text-primaryInv'
|
||||
active ? "" : "text-primaryInv"
|
||||
}`}
|
||||
>
|
||||
<FiCheck className="h-5 w-5" aria-hidden="true" />
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { FiExternalLink } from 'react-icons/fi';
|
||||
import { FiExternalLink } from "react-icons/fi";
|
||||
|
||||
export interface SocialCardProps {
|
||||
children: React.ReactNode;
|
||||
|
@ -11,7 +11,7 @@ export interface SocialCardProps {
|
|||
export const SocialCard = ({
|
||||
children,
|
||||
color,
|
||||
link,
|
||||
link
|
||||
}: SocialCardProps): JSX.Element => {
|
||||
return (
|
||||
<div
|
||||
|
|
|
@ -22,14 +22,14 @@
|
|||
--mute: #6b7280;
|
||||
--primaryInv: #242526;
|
||||
--secondaryInv: #18191a;
|
||||
--tertiaryInv: #4C4E50;
|
||||
--tertiaryInv: #4c4e50;
|
||||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
--base: #38393B;
|
||||
--base: #38393b;
|
||||
--primary: #242526;
|
||||
--secondary: #18191a;
|
||||
--tertiary: #4C4E50;
|
||||
--tertiary: #4c4e50;
|
||||
--mute: #9ca3af;
|
||||
--primaryInv: #ffffff;
|
||||
--secondaryInv: #e5e7eb;
|
||||
|
@ -143,53 +143,59 @@ a + .navbar__link > svg {
|
|||
@apply prose-invert;
|
||||
}
|
||||
[data-theme="dark"] .hideDark {
|
||||
@apply hidden
|
||||
@apply hidden;
|
||||
}
|
||||
[data-theme="dark"] .hideLight {
|
||||
@apply block
|
||||
@apply block;
|
||||
}
|
||||
.hideLight {
|
||||
@apply hidden
|
||||
@apply hidden;
|
||||
}
|
||||
.hideDark {
|
||||
@apply block
|
||||
@apply block;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown :where(li):not(:where([class~=not-prose] *)){
|
||||
margin-bottom:0;
|
||||
margin-top:0;
|
||||
}
|
||||
|
||||
.markdown :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose] *)){
|
||||
margin-bottom:0;
|
||||
.markdown :where(li):not(:where([class~="not-prose"] *)) {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: var(--ifm-heading-font-weight)
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: var(--ifm-h1-font-size)
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: var(--ifm-h2-font-size)
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: var(--ifm-h3-font-size)
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: var(--ifm-h4-font-size)
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: var(--ifm-h5-font-size)
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: var(--ifm-h6-font-size)
|
||||
}
|
||||
.markdown
|
||||
:where(ul ul, ul ol, ol ul, ol ol):not(:where([class~="not-prose"] *)) {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: var(--ifm-heading-font-weight);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: var(--ifm-h1-font-size);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: var(--ifm-h2-font-size);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: var(--ifm-h3-font-size);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: var(--ifm-h4-font-size);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: var(--ifm-h5-font-size);
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: var(--ifm-h6-font-size);
|
||||
}
|
||||
|
|
|
@ -7,12 +7,12 @@ export type DeepPartial<T> = T extends object
|
|||
export enum UseCase {
|
||||
Solar,
|
||||
Router,
|
||||
Portable,
|
||||
Portable
|
||||
}
|
||||
|
||||
enum PinUsage {
|
||||
LoRa,
|
||||
GNSS,
|
||||
GNSS
|
||||
}
|
||||
|
||||
export interface Pin {
|
||||
|
@ -25,38 +25,38 @@ export interface Pin {
|
|||
usage?: PinUsage;
|
||||
}
|
||||
|
||||
export type DeviceName = 'tbeam' | 'techo';
|
||||
export type DeviceName = "tbeam" | "techo";
|
||||
|
||||
export type BLEVersion = '4.2' | '5.0';
|
||||
export type BLEVersion = "4.2" | "5.0";
|
||||
|
||||
export type AntennaType = 'Integrated';
|
||||
export type AntennaType = "Integrated";
|
||||
|
||||
export type Chipset = 'ESP32' | 'NRF52';
|
||||
export type Chipset = "ESP32" | "NRF52";
|
||||
|
||||
export type Frequency = 433 | 868 | 915 | 923;
|
||||
|
||||
export type SerialAdapter = 'CP210X' | 'CH9102';
|
||||
export type SerialAdapter = "CP210X" | "CH9102";
|
||||
|
||||
export type GNSSModule = 'NEO-6M' | 'NEO-8M';
|
||||
export type GNSSModule = "NEO-6M" | "NEO-8M";
|
||||
|
||||
export type LORAModule = 'SX1276' | 'SX1262';
|
||||
export type LORAModule = "SX1276" | "SX1262";
|
||||
|
||||
export type Variant = DeepPartial<Omit<IDevice, 'variants'>> & { name: string };
|
||||
export type Variant = DeepPartial<Omit<IDevice, "variants">> & { name: string };
|
||||
|
||||
export enum Stability {
|
||||
Stable,
|
||||
Semi,
|
||||
Unstable,
|
||||
Broken,
|
||||
Broken
|
||||
}
|
||||
|
||||
export type Module =
|
||||
| 'cannedMessage'
|
||||
| 'externalNotification'
|
||||
| 'rangeTest'
|
||||
| 'rotaryEncoder'
|
||||
| 'storeAndForward'
|
||||
| 'telemetry';
|
||||
| "cannedMessage"
|
||||
| "externalNotification"
|
||||
| "rangeTest"
|
||||
| "rotaryEncoder"
|
||||
| "storeAndForward"
|
||||
| "telemetry";
|
||||
|
||||
export interface IDevice {
|
||||
name: string;
|
||||
|
|
|
@ -1,66 +1,66 @@
|
|||
import { IDevice, Stability, UseCase } from '../device';
|
||||
import { IDevice, Stability, UseCase } from "../device";
|
||||
|
||||
export const heltec: IDevice = {
|
||||
name: 'Heltec',
|
||||
name: "Heltec",
|
||||
misc: {
|
||||
Stability: Stability.Unstable,
|
||||
SuggestedUse: [UseCase.Portable],
|
||||
Gradient: 'bg-gradient-to-r from-pink-300 via-purple-300 to-indigo-400',
|
||||
Gradient: "bg-gradient-to-r from-pink-300 via-purple-300 to-indigo-400"
|
||||
},
|
||||
images: {
|
||||
Front: '/img/hardware/heltec-v2.png',
|
||||
Back: '',
|
||||
Front: "/img/hardware/heltec-v2.png",
|
||||
Back: ""
|
||||
},
|
||||
features: {
|
||||
BLE: true,
|
||||
WiFi: true,
|
||||
Modules: [
|
||||
'cannedMessage',
|
||||
'externalNotification',
|
||||
'rangeTest',
|
||||
'rotaryEncoder',
|
||||
'storeAndForward',
|
||||
'telemetry',
|
||||
],
|
||||
"cannedMessage",
|
||||
"externalNotification",
|
||||
"rangeTest",
|
||||
"rotaryEncoder",
|
||||
"storeAndForward",
|
||||
"telemetry"
|
||||
]
|
||||
},
|
||||
specifications: {
|
||||
BLEVersion: '4.2',
|
||||
BLEAntenna: 'Integrated',
|
||||
WiFiVersion: '2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS',
|
||||
WiFiAntenna: 'Integrated',
|
||||
Chipset: 'ESP32',
|
||||
Driver: 'CH9102',
|
||||
GNSS: 'NEO-6M',
|
||||
BLEVersion: "4.2",
|
||||
BLEAntenna: "Integrated",
|
||||
WiFiVersion: "2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS",
|
||||
WiFiAntenna: "Integrated",
|
||||
Chipset: "ESP32",
|
||||
Driver: "CH9102",
|
||||
GNSS: "NEO-6M",
|
||||
FlashSize: 4,
|
||||
Frequencies: [433, 868, 915, 923],
|
||||
LoRa: 'SX1262',
|
||||
LoRa: "SX1262",
|
||||
PSRAM: 8,
|
||||
RAM: undefined,
|
||||
RAM: undefined
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
name: 'TBeam 0.7',
|
||||
name: "TBeam 0.7",
|
||||
misc: {
|
||||
Stability: Stability.Unstable,
|
||||
Stability: Stability.Unstable
|
||||
},
|
||||
specifications: {
|
||||
Driver: 'CP210X',
|
||||
GNSS: 'NEO-6M',
|
||||
Frequencies: [868, 915],
|
||||
},
|
||||
Driver: "CP210X",
|
||||
GNSS: "NEO-6M",
|
||||
Frequencies: [868, 915]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TBeam 1.0',
|
||||
name: "TBeam 1.0",
|
||||
specifications: {
|
||||
Frequencies: [868, 915],
|
||||
},
|
||||
Frequencies: [868, 915]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TBeam 1.1',
|
||||
name: "TBeam 1.1",
|
||||
specifications: {
|
||||
Driver: 'CP210X',
|
||||
GNSS: 'NEO-6M',
|
||||
},
|
||||
},
|
||||
],
|
||||
Driver: "CP210X",
|
||||
GNSS: "NEO-6M"
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
@ -1,66 +1,66 @@
|
|||
import { IDevice, Stability, UseCase } from '../device';
|
||||
import { IDevice, Stability, UseCase } from "../device";
|
||||
|
||||
export const hydra: IDevice = {
|
||||
name: 'Hydra',
|
||||
name: "Hydra",
|
||||
misc: {
|
||||
Stability: Stability.Stable,
|
||||
SuggestedUse: [UseCase.Portable],
|
||||
Gradient: 'bg-gradient-to-r from-indigo-200 via-red-200 to-yellow-100',
|
||||
Gradient: "bg-gradient-to-r from-indigo-200 via-red-200 to-yellow-100"
|
||||
},
|
||||
images: {
|
||||
Front: '/img/hardware/Hydra-PCB.2.1.svg',
|
||||
Back: '',
|
||||
Front: "/img/hardware/Hydra-PCB.2.1.svg",
|
||||
Back: ""
|
||||
},
|
||||
features: {
|
||||
BLE: true,
|
||||
WiFi: true,
|
||||
Modules: [
|
||||
'cannedMessage',
|
||||
'externalNotification',
|
||||
'rangeTest',
|
||||
'rotaryEncoder',
|
||||
'storeAndForward',
|
||||
'telemetry',
|
||||
],
|
||||
"cannedMessage",
|
||||
"externalNotification",
|
||||
"rangeTest",
|
||||
"rotaryEncoder",
|
||||
"storeAndForward",
|
||||
"telemetry"
|
||||
]
|
||||
},
|
||||
specifications: {
|
||||
BLEVersion: '4.2',
|
||||
BLEAntenna: 'Integrated',
|
||||
WiFiVersion: '2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS',
|
||||
WiFiAntenna: 'Integrated',
|
||||
Chipset: 'ESP32',
|
||||
Driver: 'CH9102',
|
||||
GNSS: 'NEO-6M',
|
||||
BLEVersion: "4.2",
|
||||
BLEAntenna: "Integrated",
|
||||
WiFiVersion: "2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS",
|
||||
WiFiAntenna: "Integrated",
|
||||
Chipset: "ESP32",
|
||||
Driver: "CH9102",
|
||||
GNSS: "NEO-6M",
|
||||
FlashSize: 4,
|
||||
Frequencies: [433, 868, 915, 923],
|
||||
LoRa: 'SX1262',
|
||||
LoRa: "SX1262",
|
||||
PSRAM: 8,
|
||||
RAM: undefined,
|
||||
RAM: undefined
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
name: 'TBeam 0.7',
|
||||
name: "TBeam 0.7",
|
||||
misc: {
|
||||
Stability: Stability.Unstable,
|
||||
Stability: Stability.Unstable
|
||||
},
|
||||
specifications: {
|
||||
Driver: 'CP210X',
|
||||
GNSS: 'NEO-6M',
|
||||
Frequencies: [868, 915],
|
||||
},
|
||||
Driver: "CP210X",
|
||||
GNSS: "NEO-6M",
|
||||
Frequencies: [868, 915]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TBeam 1.0',
|
||||
name: "TBeam 1.0",
|
||||
specifications: {
|
||||
Frequencies: [868, 915],
|
||||
},
|
||||
Frequencies: [868, 915]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TBeam 1.1',
|
||||
name: "TBeam 1.1",
|
||||
specifications: {
|
||||
Driver: 'CP210X',
|
||||
GNSS: 'NEO-6M',
|
||||
},
|
||||
},
|
||||
],
|
||||
Driver: "CP210X",
|
||||
GNSS: "NEO-6M"
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
@ -1,66 +1,66 @@
|
|||
import { IDevice, Stability, UseCase } from '../device';
|
||||
import { IDevice, Stability, UseCase } from "../device";
|
||||
|
||||
export const nano_g1: IDevice = {
|
||||
name: 'Nano G1',
|
||||
name: "Nano G1",
|
||||
misc: {
|
||||
Stability: Stability.Unstable,
|
||||
SuggestedUse: [UseCase.Portable],
|
||||
Gradient: 'bg-gradient-to-r from-green-200 to-green-500',
|
||||
Gradient: "bg-gradient-to-r from-green-200 to-green-500"
|
||||
},
|
||||
images: {
|
||||
Front: '/img/hardware/nano_g1_front.svg',
|
||||
Back: '/img/hardware/nano_g1_back.svg',
|
||||
Front: "/img/hardware/nano_g1_front.svg",
|
||||
Back: "/img/hardware/nano_g1_back.svg"
|
||||
},
|
||||
features: {
|
||||
BLE: true,
|
||||
WiFi: true,
|
||||
Modules: [
|
||||
'cannedMessage',
|
||||
'externalNotification',
|
||||
'rangeTest',
|
||||
'rotaryEncoder',
|
||||
'storeAndForward',
|
||||
'telemetry',
|
||||
],
|
||||
"cannedMessage",
|
||||
"externalNotification",
|
||||
"rangeTest",
|
||||
"rotaryEncoder",
|
||||
"storeAndForward",
|
||||
"telemetry"
|
||||
]
|
||||
},
|
||||
specifications: {
|
||||
BLEVersion: '4.2',
|
||||
BLEAntenna: 'Integrated',
|
||||
WiFiVersion: '2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS',
|
||||
WiFiAntenna: 'Integrated',
|
||||
Chipset: 'ESP32',
|
||||
Driver: 'CH9102',
|
||||
GNSS: 'NEO-6M',
|
||||
BLEVersion: "4.2",
|
||||
BLEAntenna: "Integrated",
|
||||
WiFiVersion: "2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS",
|
||||
WiFiAntenna: "Integrated",
|
||||
Chipset: "ESP32",
|
||||
Driver: "CH9102",
|
||||
GNSS: "NEO-6M",
|
||||
FlashSize: 4,
|
||||
Frequencies: [433, 868, 915, 923],
|
||||
LoRa: 'SX1262',
|
||||
LoRa: "SX1262",
|
||||
PSRAM: 8,
|
||||
RAM: undefined,
|
||||
RAM: undefined
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
name: 'TBeam 0.7',
|
||||
name: "TBeam 0.7",
|
||||
misc: {
|
||||
Stability: Stability.Unstable,
|
||||
Stability: Stability.Unstable
|
||||
},
|
||||
specifications: {
|
||||
Driver: 'CP210X',
|
||||
GNSS: 'NEO-6M',
|
||||
Frequencies: [868, 915],
|
||||
},
|
||||
Driver: "CP210X",
|
||||
GNSS: "NEO-6M",
|
||||
Frequencies: [868, 915]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TBeam 1.0',
|
||||
name: "TBeam 1.0",
|
||||
specifications: {
|
||||
Frequencies: [868, 915],
|
||||
},
|
||||
Frequencies: [868, 915]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TBeam 1.1',
|
||||
name: "TBeam 1.1",
|
||||
specifications: {
|
||||
Driver: 'CP210X',
|
||||
GNSS: 'NEO-6M',
|
||||
},
|
||||
},
|
||||
],
|
||||
Driver: "CP210X",
|
||||
GNSS: "NEO-6M"
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
@ -1,66 +1,66 @@
|
|||
import { IDevice, Stability, UseCase } from '../device';
|
||||
import { IDevice, Stability, UseCase } from "../device";
|
||||
|
||||
export const rak19001: IDevice = {
|
||||
name: 'WisBlock 19001',
|
||||
name: "WisBlock 19001",
|
||||
misc: {
|
||||
Stability: Stability.Stable,
|
||||
SuggestedUse: [UseCase.Portable],
|
||||
Gradient: 'bg-gradient-to-r from-indigo-300 to-purple-400',
|
||||
Gradient: "bg-gradient-to-r from-indigo-300 to-purple-400"
|
||||
},
|
||||
images: {
|
||||
Front: '/img/hardware/rak/RAK19001.png',
|
||||
Back: '',
|
||||
Front: "/img/hardware/rak/RAK19001.png",
|
||||
Back: ""
|
||||
},
|
||||
features: {
|
||||
BLE: true,
|
||||
WiFi: true,
|
||||
Modules: [
|
||||
'cannedMessage',
|
||||
'externalNotification',
|
||||
'rangeTest',
|
||||
'rotaryEncoder',
|
||||
'storeAndForward',
|
||||
'telemetry',
|
||||
],
|
||||
"cannedMessage",
|
||||
"externalNotification",
|
||||
"rangeTest",
|
||||
"rotaryEncoder",
|
||||
"storeAndForward",
|
||||
"telemetry"
|
||||
]
|
||||
},
|
||||
specifications: {
|
||||
BLEVersion: '4.2',
|
||||
BLEAntenna: 'Integrated',
|
||||
WiFiVersion: '2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS',
|
||||
WiFiAntenna: 'Integrated',
|
||||
Chipset: 'ESP32',
|
||||
Driver: 'CH9102',
|
||||
GNSS: 'NEO-6M',
|
||||
BLEVersion: "4.2",
|
||||
BLEAntenna: "Integrated",
|
||||
WiFiVersion: "2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS",
|
||||
WiFiAntenna: "Integrated",
|
||||
Chipset: "ESP32",
|
||||
Driver: "CH9102",
|
||||
GNSS: "NEO-6M",
|
||||
FlashSize: 4,
|
||||
Frequencies: [433, 868, 915, 923],
|
||||
LoRa: 'SX1262',
|
||||
LoRa: "SX1262",
|
||||
PSRAM: 8,
|
||||
RAM: undefined,
|
||||
RAM: undefined
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
name: 'TBeam 0.7',
|
||||
name: "TBeam 0.7",
|
||||
misc: {
|
||||
Stability: Stability.Unstable,
|
||||
Stability: Stability.Unstable
|
||||
},
|
||||
specifications: {
|
||||
Driver: 'CP210X',
|
||||
GNSS: 'NEO-6M',
|
||||
Frequencies: [868, 915],
|
||||
},
|
||||
Driver: "CP210X",
|
||||
GNSS: "NEO-6M",
|
||||
Frequencies: [868, 915]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TBeam 1.0',
|
||||
name: "TBeam 1.0",
|
||||
specifications: {
|
||||
Frequencies: [868, 915],
|
||||
},
|
||||
Frequencies: [868, 915]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TBeam 1.1',
|
||||
name: "TBeam 1.1",
|
||||
specifications: {
|
||||
Driver: 'CP210X',
|
||||
GNSS: 'NEO-6M',
|
||||
},
|
||||
},
|
||||
],
|
||||
Driver: "CP210X",
|
||||
GNSS: "NEO-6M"
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
@ -1,66 +1,66 @@
|
|||
import { IDevice, Stability, UseCase } from '../device';
|
||||
import { IDevice, Stability, UseCase } from "../device";
|
||||
|
||||
export const rak19003: IDevice = {
|
||||
name: 'WisBlock 19003',
|
||||
name: "WisBlock 19003",
|
||||
misc: {
|
||||
Stability: Stability.Stable,
|
||||
SuggestedUse: [UseCase.Portable],
|
||||
Gradient: 'bg-gradient-to-b from-orange-500 to-yellow-300',
|
||||
Gradient: "bg-gradient-to-b from-orange-500 to-yellow-300"
|
||||
},
|
||||
images: {
|
||||
Front: '/img/hardware/rak/RAK19003.png',
|
||||
Back: '',
|
||||
Front: "/img/hardware/rak/RAK19003.png",
|
||||
Back: ""
|
||||
},
|
||||
features: {
|
||||
BLE: true,
|
||||
WiFi: true,
|
||||
Modules: [
|
||||
'cannedMessage',
|
||||
'externalNotification',
|
||||
'rangeTest',
|
||||
'rotaryEncoder',
|
||||
'storeAndForward',
|
||||
'telemetry',
|
||||
],
|
||||
"cannedMessage",
|
||||
"externalNotification",
|
||||
"rangeTest",
|
||||
"rotaryEncoder",
|
||||
"storeAndForward",
|
||||
"telemetry"
|
||||
]
|
||||
},
|
||||
specifications: {
|
||||
BLEVersion: '4.2',
|
||||
BLEAntenna: 'Integrated',
|
||||
WiFiVersion: '2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS',
|
||||
WiFiAntenna: 'Integrated',
|
||||
Chipset: 'ESP32',
|
||||
Driver: 'CH9102',
|
||||
GNSS: 'NEO-6M',
|
||||
BLEVersion: "4.2",
|
||||
BLEAntenna: "Integrated",
|
||||
WiFiVersion: "2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS",
|
||||
WiFiAntenna: "Integrated",
|
||||
Chipset: "ESP32",
|
||||
Driver: "CH9102",
|
||||
GNSS: "NEO-6M",
|
||||
FlashSize: 4,
|
||||
Frequencies: [433, 868, 915, 923],
|
||||
LoRa: 'SX1262',
|
||||
LoRa: "SX1262",
|
||||
PSRAM: 8,
|
||||
RAM: undefined,
|
||||
RAM: undefined
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
name: 'TBeam 0.7',
|
||||
name: "TBeam 0.7",
|
||||
misc: {
|
||||
Stability: Stability.Unstable,
|
||||
Stability: Stability.Unstable
|
||||
},
|
||||
specifications: {
|
||||
Driver: 'CP210X',
|
||||
GNSS: 'NEO-6M',
|
||||
Frequencies: [868, 915],
|
||||
},
|
||||
Driver: "CP210X",
|
||||
GNSS: "NEO-6M",
|
||||
Frequencies: [868, 915]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TBeam 1.0',
|
||||
name: "TBeam 1.0",
|
||||
specifications: {
|
||||
Frequencies: [868, 915],
|
||||
},
|
||||
Frequencies: [868, 915]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TBeam 1.1',
|
||||
name: "TBeam 1.1",
|
||||
specifications: {
|
||||
Driver: 'CP210X',
|
||||
GNSS: 'NEO-6M',
|
||||
},
|
||||
},
|
||||
],
|
||||
Driver: "CP210X",
|
||||
GNSS: "NEO-6M"
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
@ -1,277 +1,277 @@
|
|||
import { IDevice, Stability, UseCase } from '../device';
|
||||
import { IDevice, Stability, UseCase } from "../device";
|
||||
|
||||
export const tbeam: IDevice = {
|
||||
name: 'T-Beam',
|
||||
name: "T-Beam",
|
||||
misc: {
|
||||
Stability: Stability.Stable,
|
||||
SuggestedUse: [UseCase.Portable],
|
||||
Gradient: 'bg-gradient-to-r from-pink-500 via-red-500 to-yellow-500',
|
||||
pinoutSplit: 13,
|
||||
Gradient: "bg-gradient-to-r from-pink-500 via-red-500 to-yellow-500",
|
||||
pinoutSplit: 13
|
||||
},
|
||||
images: {
|
||||
Front: '/img/hardware/tbeam-v1.1.svg',
|
||||
Back: '',
|
||||
Front: "/img/hardware/tbeam-v1.1.svg",
|
||||
Back: ""
|
||||
},
|
||||
features: {
|
||||
BLE: true,
|
||||
WiFi: true,
|
||||
Modules: [
|
||||
'cannedMessage',
|
||||
'externalNotification',
|
||||
'rangeTest',
|
||||
'rotaryEncoder',
|
||||
'storeAndForward',
|
||||
'telemetry',
|
||||
],
|
||||
"cannedMessage",
|
||||
"externalNotification",
|
||||
"rangeTest",
|
||||
"rotaryEncoder",
|
||||
"storeAndForward",
|
||||
"telemetry"
|
||||
]
|
||||
},
|
||||
specifications: {
|
||||
BLEVersion: '4.2',
|
||||
BLEAntenna: 'Integrated',
|
||||
WiFiVersion: '2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS',
|
||||
WiFiAntenna: 'Integrated',
|
||||
Chipset: 'ESP32',
|
||||
Driver: 'CH9102',
|
||||
GNSS: 'NEO-6M',
|
||||
BLEVersion: "4.2",
|
||||
BLEAntenna: "Integrated",
|
||||
WiFiVersion: "2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS",
|
||||
WiFiAntenna: "Integrated",
|
||||
Chipset: "ESP32",
|
||||
Driver: "CH9102",
|
||||
GNSS: "NEO-6M",
|
||||
FlashSize: 4,
|
||||
Frequencies: [433, 868, 915, 923],
|
||||
LoRa: 'SX1262',
|
||||
LoRa: "SX1262",
|
||||
PSRAM: 8,
|
||||
RAM: undefined,
|
||||
RAM: undefined
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
name: 'TBeam 0.7',
|
||||
name: "TBeam 0.7",
|
||||
misc: {
|
||||
Stability: Stability.Unstable,
|
||||
Stability: Stability.Unstable
|
||||
},
|
||||
specifications: {
|
||||
Driver: 'CP210X',
|
||||
GNSS: 'NEO-6M',
|
||||
Frequencies: [868, 915],
|
||||
},
|
||||
Driver: "CP210X",
|
||||
GNSS: "NEO-6M",
|
||||
Frequencies: [868, 915]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TBeam 1.0',
|
||||
name: "TBeam 1.0",
|
||||
specifications: {
|
||||
Frequencies: [868, 915],
|
||||
},
|
||||
Frequencies: [868, 915]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TBeam 1.1',
|
||||
name: "TBeam 1.1",
|
||||
specifications: {
|
||||
Driver: 'CP210X',
|
||||
GNSS: 'NEO-6M',
|
||||
},
|
||||
},
|
||||
Driver: "CP210X",
|
||||
GNSS: "NEO-6M"
|
||||
}
|
||||
}
|
||||
],
|
||||
pinout: [
|
||||
{
|
||||
label: 'VP',
|
||||
name: 'IO1',
|
||||
label: "VP",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'VN',
|
||||
name: 'IO1',
|
||||
label: "VN",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'RST',
|
||||
name: 'IO1',
|
||||
label: "RST",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '15',
|
||||
name: 'IO1',
|
||||
label: "15",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '35',
|
||||
name: 'IO1',
|
||||
label: "35",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '32',
|
||||
name: 'IO1',
|
||||
label: "32",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '33',
|
||||
name: 'IO1',
|
||||
label: "33",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '25',
|
||||
name: 'IO1',
|
||||
label: "25",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '14',
|
||||
name: 'IO1',
|
||||
label: "14",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '13',
|
||||
name: 'IO1',
|
||||
label: "13",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '2',
|
||||
name: 'IO1',
|
||||
label: "2",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'GND',
|
||||
name: 'IO1',
|
||||
label: "GND",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '5V',
|
||||
name: 'IO1',
|
||||
label: "5V",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'TX',
|
||||
name: 'IO1',
|
||||
label: "TX",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'RX',
|
||||
name: 'IO1',
|
||||
label: "RX",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '23',
|
||||
name: 'IO1',
|
||||
label: "23",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '4',
|
||||
name: 'IO1',
|
||||
label: "4",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '0',
|
||||
name: 'IO1',
|
||||
label: "0",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'GND',
|
||||
name: 'IO1',
|
||||
label: "GND",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '3V3',
|
||||
name: 'IO1',
|
||||
label: "3V3",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'GND',
|
||||
name: 'IO1',
|
||||
label: "GND",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '22',
|
||||
name: 'IO1',
|
||||
label: "22",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '21',
|
||||
name: 'IO1',
|
||||
label: "21",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '3.3V',
|
||||
name: 'IO1',
|
||||
label: "3.3V",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'LoRa2',
|
||||
name: 'IO1',
|
||||
label: "LoRa2",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
y: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'LoRa1',
|
||||
name: 'IO1',
|
||||
label: "LoRa1",
|
||||
name: "IO1",
|
||||
offset: {
|
||||
x: 5,
|
||||
y: 5,
|
||||
},
|
||||
},
|
||||
],
|
||||
y: 5
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
@ -1,66 +1,66 @@
|
|||
import { IDevice, Stability, UseCase } from '../device';
|
||||
import { IDevice, Stability, UseCase } from "../device";
|
||||
|
||||
export const techo: IDevice = {
|
||||
name: 'T-Echo',
|
||||
name: "T-Echo",
|
||||
misc: {
|
||||
Stability: Stability.Semi,
|
||||
SuggestedUse: [UseCase.Portable],
|
||||
Gradient: 'bg-gradient-to-r from-gray-700 via-gray-900 to-black',
|
||||
Gradient: "bg-gradient-to-r from-gray-700 via-gray-900 to-black"
|
||||
},
|
||||
images: {
|
||||
Front: '/img/hardware/t-echo-lilygo.jpg',
|
||||
Back: '',
|
||||
Front: "/img/hardware/t-echo-lilygo.jpg",
|
||||
Back: ""
|
||||
},
|
||||
features: {
|
||||
BLE: true,
|
||||
WiFi: true,
|
||||
Modules: [
|
||||
'cannedMessage',
|
||||
'externalNotification',
|
||||
'rangeTest',
|
||||
'rotaryEncoder',
|
||||
'storeAndForward',
|
||||
'telemetry',
|
||||
],
|
||||
"cannedMessage",
|
||||
"externalNotification",
|
||||
"rangeTest",
|
||||
"rotaryEncoder",
|
||||
"storeAndForward",
|
||||
"telemetry"
|
||||
]
|
||||
},
|
||||
specifications: {
|
||||
BLEVersion: '4.2',
|
||||
BLEAntenna: 'Integrated',
|
||||
WiFiVersion: '2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS',
|
||||
WiFiAntenna: 'Integrated',
|
||||
Chipset: 'ESP32',
|
||||
Driver: 'CH9102',
|
||||
GNSS: 'NEO-6M',
|
||||
BLEVersion: "4.2",
|
||||
BLEAntenna: "Integrated",
|
||||
WiFiVersion: "2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS",
|
||||
WiFiAntenna: "Integrated",
|
||||
Chipset: "ESP32",
|
||||
Driver: "CH9102",
|
||||
GNSS: "NEO-6M",
|
||||
FlashSize: 4,
|
||||
Frequencies: [433, 868, 915, 923],
|
||||
LoRa: 'SX1262',
|
||||
LoRa: "SX1262",
|
||||
PSRAM: 8,
|
||||
RAM: undefined,
|
||||
RAM: undefined
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
name: 'TBeam 0.7',
|
||||
name: "TBeam 0.7",
|
||||
misc: {
|
||||
Stability: Stability.Unstable,
|
||||
Stability: Stability.Unstable
|
||||
},
|
||||
specifications: {
|
||||
Driver: 'CP210X',
|
||||
GNSS: 'NEO-6M',
|
||||
Frequencies: [868, 915],
|
||||
},
|
||||
Driver: "CP210X",
|
||||
GNSS: "NEO-6M",
|
||||
Frequencies: [868, 915]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TBeam 1.0',
|
||||
name: "TBeam 1.0",
|
||||
specifications: {
|
||||
Frequencies: [868, 915],
|
||||
},
|
||||
Frequencies: [868, 915]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'TBeam 1.1',
|
||||
name: "TBeam 1.1",
|
||||
specifications: {
|
||||
Driver: 'CP210X',
|
||||
GNSS: 'NEO-6M',
|
||||
},
|
||||
},
|
||||
],
|
||||
Driver: "CP210X",
|
||||
GNSS: "NEO-6M"
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
export interface IRegion {
|
||||
name: string;
|
||||
freqStart: number;
|
||||
freqEnd: number;
|
||||
dutyCycle: number;
|
||||
spacing: number;
|
||||
powerLimit: number;
|
||||
audioPermitted: boolean;
|
||||
frequencySwitching: boolean;
|
||||
wideLora: boolean;
|
||||
export interface IRegion {
|
||||
name: string;
|
||||
freqStart: number;
|
||||
freqEnd: number;
|
||||
dutyCycle: number;
|
||||
spacing: number;
|
||||
powerLimit: number;
|
||||
audioPermitted: boolean;
|
||||
frequencySwitching: boolean;
|
||||
wideLora: boolean;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { IRegion } from '../region';
|
||||
import { IRegion } from "../region";
|
||||
|
||||
export const ANZ: IRegion = {
|
||||
name: "ANZ",
|
||||
freqStart: 915.0,
|
||||
freqEnd: 928.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 30,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false,
|
||||
}
|
||||
name: "ANZ",
|
||||
freqStart: 915.0,
|
||||
freqEnd: 928.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 30,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { IRegion } from '../region';
|
||||
import { IRegion } from "../region";
|
||||
|
||||
export const CN: IRegion = {
|
||||
name: "CN",
|
||||
freqStart: 470.0,
|
||||
freqEnd: 510.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 19,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false,
|
||||
}
|
||||
name: "CN",
|
||||
freqStart: 470.0,
|
||||
freqEnd: 510.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 19,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { IRegion } from '../region';
|
||||
import { IRegion } from "../region";
|
||||
|
||||
export const EU_433: IRegion = {
|
||||
name: "EU_433",
|
||||
freqStart: 433.0,
|
||||
freqEnd: 434.0,
|
||||
dutyCycle: 10,
|
||||
spacing: 0,
|
||||
powerLimit: 12,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false,
|
||||
}
|
||||
name: "EU_433",
|
||||
freqStart: 433.0,
|
||||
freqEnd: 434.0,
|
||||
dutyCycle: 10,
|
||||
spacing: 0,
|
||||
powerLimit: 12,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { IRegion } from '../region';
|
||||
import { IRegion } from "../region";
|
||||
|
||||
export const EU_868: IRegion = {
|
||||
name: "EU_868",
|
||||
freqStart: 869.4,
|
||||
freqEnd: 869.65,
|
||||
dutyCycle: 10,
|
||||
spacing: 0,
|
||||
powerLimit: 27,
|
||||
audioPermitted: false,
|
||||
frequencySwitching: false,
|
||||
wideLora: false,
|
||||
}
|
||||
name: "EU_868",
|
||||
freqStart: 869.4,
|
||||
freqEnd: 869.65,
|
||||
dutyCycle: 10,
|
||||
spacing: 0,
|
||||
powerLimit: 27,
|
||||
audioPermitted: false,
|
||||
frequencySwitching: false,
|
||||
wideLora: false
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { IRegion } from '../region';
|
||||
import { IRegion } from "../region";
|
||||
|
||||
export const IN: IRegion = {
|
||||
name: "IN",
|
||||
freqStart: 865.0,
|
||||
freqEnd: 867.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 30,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false,
|
||||
}
|
||||
name: "IN",
|
||||
freqStart: 865.0,
|
||||
freqEnd: 867.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 30,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { IRegion } from '../region';
|
||||
import { IRegion } from "../region";
|
||||
|
||||
export const JP: IRegion = {
|
||||
name: "JP",
|
||||
freqStart: 920.8,
|
||||
freqEnd: 927.8,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 16,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false,
|
||||
}
|
||||
name: "JP",
|
||||
freqStart: 920.8,
|
||||
freqEnd: 927.8,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 16,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { IRegion } from '../region';
|
||||
import { IRegion } from "../region";
|
||||
|
||||
export const KR: IRegion = {
|
||||
name: "KR",
|
||||
freqStart: 920.0,
|
||||
freqEnd: 925.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 0,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false,
|
||||
}
|
||||
name: "KR",
|
||||
freqStart: 920.0,
|
||||
freqEnd: 925.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 0,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { IRegion } from '../region';
|
||||
import { IRegion } from "../region";
|
||||
|
||||
export const LORA_24: IRegion = {
|
||||
name: "LORA_24",
|
||||
freqStart: 2400.0,
|
||||
freqEnd: 2483.5,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 10,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: true,
|
||||
}
|
||||
name: "LORA_24",
|
||||
freqStart: 2400.0,
|
||||
freqEnd: 2483.5,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 10,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: true
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { IRegion } from '../region';
|
||||
import { IRegion } from "../region";
|
||||
|
||||
export const NZ_865: IRegion = {
|
||||
name: "NZ_865",
|
||||
freqStart: 864.0,
|
||||
freqEnd: 868.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 36,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false,
|
||||
}
|
||||
name: "NZ_865",
|
||||
freqStart: 864.0,
|
||||
freqEnd: 868.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 36,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { IRegion } from '../region';
|
||||
import { IRegion } from "../region";
|
||||
|
||||
export const RU: IRegion = {
|
||||
name: "RU",
|
||||
freqStart: 868.7,
|
||||
freqEnd: 869.2,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 20,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false,
|
||||
}
|
||||
name: "RU",
|
||||
freqStart: 868.7,
|
||||
freqEnd: 869.2,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 20,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { IRegion } from '../region';
|
||||
import { IRegion } from "../region";
|
||||
|
||||
export const TH: IRegion = {
|
||||
name: "TH",
|
||||
freqStart: 920.0,
|
||||
freqEnd: 925.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 16,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false,
|
||||
}
|
||||
name: "TH",
|
||||
freqStart: 920.0,
|
||||
freqEnd: 925.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 16,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { IRegion } from '../region';
|
||||
import { IRegion } from "../region";
|
||||
|
||||
export const TW: IRegion = {
|
||||
name: "TW",
|
||||
freqStart: 920.0,
|
||||
freqEnd: 925.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 0,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false,
|
||||
}
|
||||
name: "TW",
|
||||
freqStart: 920.0,
|
||||
freqEnd: 925.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 0,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { IRegion } from '../region';
|
||||
import { IRegion } from "../region";
|
||||
|
||||
export const UNSET: IRegion = {
|
||||
name: "UNSET",
|
||||
freqStart: 902.0,
|
||||
freqEnd: 928.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 30,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false,
|
||||
}
|
||||
name: "UNSET",
|
||||
freqStart: 902.0,
|
||||
freqEnd: 928.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 30,
|
||||
audioPermitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { IRegion } from '../region';
|
||||
import { IRegion } from "../region";
|
||||
|
||||
export const US: IRegion = {
|
||||
name: "US",
|
||||
freqStart: 902.0,
|
||||
freqEnd: 928.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 30,
|
||||
audioPrmitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false,
|
||||
}
|
||||
name: "US",
|
||||
freqStart: 902.0,
|
||||
freqEnd: 928.0,
|
||||
dutyCycle: 100,
|
||||
spacing: 0,
|
||||
powerLimit: 30,
|
||||
audioPrmitted: true,
|
||||
frequencySwitching: false,
|
||||
wideLora: false
|
||||
};
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { Showcase } from '../utils/apiTypes.js';
|
||||
import { useSelectedTags } from './useSelectedTags';
|
||||
import { Showcase } from "../utils/apiTypes.js";
|
||||
import { useSelectedTags } from "./useSelectedTags";
|
||||
|
||||
const filterNetworks = (
|
||||
showcaseNetworks: Showcase[],
|
||||
selectedTags: string[],
|
||||
selectedTags: string[]
|
||||
) => {
|
||||
if (selectedTags.length === 0) {
|
||||
return showcaseNetworks;
|
||||
|
@ -15,7 +15,7 @@ const filterNetworks = (
|
|||
return false;
|
||||
}
|
||||
return selectedTags.every((queryTag) =>
|
||||
showcaseNetwork.tags.find((searchTag) => searchTag.label === queryTag),
|
||||
showcaseNetwork.tags.find((searchTag) => searchTag.label === queryTag)
|
||||
);
|
||||
});
|
||||
};
|
||||
|
@ -24,6 +24,6 @@ export const useFilteredNetworks = (networks: Showcase[]) => {
|
|||
const selectedTags = useSelectedTags();
|
||||
return React.useMemo(
|
||||
() => filterNetworks(networks, selectedTags),
|
||||
[selectedTags],
|
||||
[selectedTags]
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { useLocation } from '@docusaurus/router';
|
||||
import { useLocation } from "@docusaurus/router";
|
||||
|
||||
import { readSearchTags } from '../pages/showcase/_components/TagSelect';
|
||||
import { readSearchTags } from "../pages/showcase/_components/TagSelect";
|
||||
|
||||
export const useSelectedTags = () => {
|
||||
const location = useLocation();
|
||||
|
|
|
@ -1,45 +1,44 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { FiTwitter } from 'react-icons/fi';
|
||||
|
||||
import { ChevronRightIcon } from '@heroicons/react/20/solid';
|
||||
import FlipClockCountdown from '@leenguyen/react-flip-clock-countdown';
|
||||
import Layout from '@theme/Layout';
|
||||
import { Dark, Light } from '/src/components/ColorMode';
|
||||
import { FiTwitter } from "react-icons/fi";
|
||||
|
||||
import { ChevronRightIcon } from "@heroicons/react/20/solid";
|
||||
import FlipClockCountdown from "@leenguyen/react-flip-clock-countdown";
|
||||
import Layout from "@theme/Layout";
|
||||
import { Dark, Light } from "/src/components/ColorMode";
|
||||
|
||||
const TwoPointZero = (): JSX.Element => {
|
||||
const stats = [
|
||||
{ label: 'Active Nodes', value: 'A Lot!' },
|
||||
{ label: 'Community Members', value: '4000+' },
|
||||
{ label: 'Firmware Commits', value: '4900+' },
|
||||
{ label: 'Community Donations', value: '$5700+' },
|
||||
{ label: "Active Nodes", value: "A Lot!" },
|
||||
{ label: "Community Members", value: "4000+" },
|
||||
{ label: "Firmware Commits", value: "4900+" },
|
||||
{ label: "Community Donations", value: "$5700+" }
|
||||
];
|
||||
const logos = [
|
||||
{
|
||||
name: 'Vercel',
|
||||
url: '/2.0/vercel-logotype-dark.svg',
|
||||
name: "Vercel",
|
||||
url: "/2.0/vercel-logotype-dark.svg"
|
||||
},
|
||||
{
|
||||
name: 'Cloudflare',
|
||||
url: '/2.0/CF_logo_horizontal_blktype.svg',
|
||||
name: "Cloudflare",
|
||||
url: "/2.0/CF_logo_horizontal_blktype.svg"
|
||||
},
|
||||
{
|
||||
name: 'RAK Wireless',
|
||||
url: '/2.0/RAK-blue-main.svg',
|
||||
name: "RAK Wireless",
|
||||
url: "/2.0/RAK-blue-main.svg"
|
||||
},
|
||||
{
|
||||
name: 'Open Collective',
|
||||
url: '/2.0/opencollectivelogo.svg',
|
||||
name: "Open Collective",
|
||||
url: "/2.0/opencollectivelogo.svg"
|
||||
},
|
||||
{
|
||||
name: 'LILYGO',
|
||||
url: '/2.0/LILYGO.png',
|
||||
name: "LILYGO",
|
||||
url: "/2.0/LILYGO.png"
|
||||
},
|
||||
{
|
||||
name: 'Discord',
|
||||
url: '/2.0/discord.svg',
|
||||
},
|
||||
name: "Discord",
|
||||
url: "/2.0/discord.svg"
|
||||
}
|
||||
];
|
||||
return (
|
||||
<Layout title="Meshtastic 2.0" description="Meshtastic 2.0 Landing Page">
|
||||
|
@ -60,11 +59,11 @@ const TwoPointZero = (): JSX.Element => {
|
|||
</Dark>
|
||||
<Light>
|
||||
<img
|
||||
className="h-11 w-auto"
|
||||
it
|
||||
src="/design/logo/svg/Mesh_Logo_Black.svg"
|
||||
alt="Meshtastic Logo"
|
||||
/>
|
||||
className="h-11 w-auto"
|
||||
it
|
||||
src="/design/logo/svg/Mesh_Logo_Black.svg"
|
||||
alt="Meshtastic Logo"
|
||||
/>
|
||||
</Light>
|
||||
</div>
|
||||
<div className="mt-20">
|
||||
|
@ -246,8 +245,8 @@ const TwoPointZero = (): JSX.Element => {
|
|||
<path d="M9.352 4C4.456 7.456 1 13.12 1 19.36c0 5.088 3.072 8.064 6.624 8.064 3.36 0 5.856-2.688 5.856-5.856 0-3.168-2.208-5.472-5.088-5.472-.576 0-1.344.096-1.536.192.48-3.264 3.552-7.104 6.624-9.024L9.352 4zm16.512 0c-4.8 3.456-8.256 9.12-8.256 15.36 0 5.088 3.072 8.064 6.624 8.064 3.264 0 5.856-2.688 5.856-5.856 0-3.168-2.304-5.472-5.184-5.472-.576 0-1.248.096-1.44.192.48-3.264 3.456-7.104 6.528-9.024L25.864 4z" />
|
||||
</svg>
|
||||
<p className="relative">
|
||||
Meshtastic is the neatest open source project I've ever
|
||||
seen!
|
||||
Meshtastic is the neatest open source project I've
|
||||
ever seen!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Meshtastic URL
|
|||
sidebar_label: c
|
||||
---
|
||||
|
||||
# Error : Something happened
|
||||
|
||||
Please go to [Android Usage](/docs/software/android/usage#join-a-channel) for more information.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
export interface avatarProps {
|
||||
imgUrl: string;
|
||||
|
@ -15,41 +15,31 @@ export const Avatar = ({
|
|||
imgUrl,
|
||||
name,
|
||||
userName,
|
||||
description,
|
||||
description
|
||||
}: avatarProps): JSX.Element => {
|
||||
return (
|
||||
<div className="card m-4 border-2 border-secondary">
|
||||
<div className="card__body">
|
||||
<div className="avatar">
|
||||
<img
|
||||
className="avatar__photo avatar__photo--sm"
|
||||
src={imgUrl}
|
||||
/>
|
||||
<img className="avatar__photo avatar__photo--sm" src={imgUrl} />
|
||||
<div className="avatar__intro">
|
||||
<div className="avatar__name">
|
||||
{name}
|
||||
</div>
|
||||
<small class="avatar__subtitle">
|
||||
{description}
|
||||
</small>
|
||||
<div className="avatar__name">{name}</div>
|
||||
<small className="avatar__subtitle">{description}</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export const AvatarLayout = ({
|
||||
list
|
||||
} :avatarLayoutProps): JSX.Element => {
|
||||
export const AvatarLayout = ({ list }: avatarLayoutProps): JSX.Element => {
|
||||
return (
|
||||
<div className="container">
|
||||
<div className="flex flex-wrap justify-center bg-primary">
|
||||
{list.map((e) => {
|
||||
return <Avatar/>
|
||||
})
|
||||
}
|
||||
return <Avatar />;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,122 +1,165 @@
|
|||
import React from 'react';
|
||||
import Layout from '@theme/Layout';
|
||||
import Link from '@docusaurus/Link';
|
||||
import React from "react";
|
||||
import Layout from "@theme/Layout";
|
||||
import Link from "@docusaurus/Link";
|
||||
|
||||
import {
|
||||
Avatar,
|
||||
AvatarLayout
|
||||
} from './_components/Avatar';
|
||||
import { Avatar, AvatarLayout } from "./_components/Avatar";
|
||||
|
||||
const Credits = (): JSX.Element => {
|
||||
const partnerLogos = [
|
||||
{
|
||||
name: 'Vercel',
|
||||
url: '/2.0/vercel-logotype-dark.svg',
|
||||
name: "Vercel",
|
||||
url: "/2.0/vercel-logotype-dark.svg"
|
||||
},
|
||||
{
|
||||
name: 'Cloudflare',
|
||||
url: '/2.0/CF_logo_horizontal_blktype.svg',
|
||||
name: "Cloudflare",
|
||||
url: "/2.0/CF_logo_horizontal_blktype.svg"
|
||||
},
|
||||
{
|
||||
name: 'RAK Wireless',
|
||||
url: '/2.0/RAK-blue-main.svg',
|
||||
name: "RAK Wireless",
|
||||
url: "/2.0/RAK-blue-main.svg"
|
||||
},
|
||||
{
|
||||
name: 'Open Collective',
|
||||
url: '/2.0/opencollectivelogo.svg',
|
||||
name: "Open Collective",
|
||||
url: "/2.0/opencollectivelogo.svg"
|
||||
},
|
||||
{
|
||||
name: 'LILYGO',
|
||||
url: '/2.0/LILYGO.png',
|
||||
name: "LILYGO",
|
||||
url: "/2.0/LILYGO.png"
|
||||
},
|
||||
{
|
||||
name: 'Discord',
|
||||
url: '/2.0/discord.svg',
|
||||
},
|
||||
name: "Discord",
|
||||
url: "/2.0/discord.svg"
|
||||
}
|
||||
];
|
||||
return(
|
||||
<Layout
|
||||
title="Credits"
|
||||
description="Meshtastic is made possible by the following people & organizations."
|
||||
>
|
||||
<main className="relative mt-20">
|
||||
<div className="container mx-auto p-6 leading-normal space-y-4">
|
||||
<h1>Credits</h1>
|
||||
<p>
|
||||
Meshtastic is community driven. Thousands of hours have been donated by volunteers who want to develop this amazing project. Whether you've submitted a pull request or triaged a bug in our Discord/Forum. You've made Meshtastic possible. Thank you for your contributions.
|
||||
</p>
|
||||
<p>
|
||||
We would also like to recognize those who have donated financially to the project. As Meshtastic has grown, we've aquired some ongoing costs to keep the project running. Thank you for your generous donations.
|
||||
</p>
|
||||
</div>
|
||||
<div className="container mx-auto p-6 leading-normal space-y-4">
|
||||
<h2>Fiscal Sponsors</h2>
|
||||
<p>
|
||||
We have partnered with both the <a className="underline" href="https://opencollective.com" target="_blank">Open Collective</a> and the <a className="underline" href="https://www.oscollective.org" target="_blank">Open Source Collective</a> to help us with a fiscal management framework and banking needs. They help support over three thousand open source projects including the PHP Foundation, F-Droid, Sonarr, LinuxServer and DarkReader. We are in good hands and good company.
|
||||
</p>
|
||||
<p>
|
||||
As with everything we do here, Open Collective provides a fully transparent framework for our budget and expenses. You can see what we’re bringing in, who is spending money and where that money is going <a className="underline" href="https://opencollective.com/meshtastic" target="_blank">here</a>.
|
||||
</p>
|
||||
<p>
|
||||
In addition to our partnership with Open Collective and Open Source Collective, we have also been approved into the <a className="underline" href="https://github.com/sponsors" target="_blank">GitHub Sponsors</a> program where we can set fundraising goals with GitHub.
|
||||
</p>
|
||||
<p>
|
||||
All donations made through GitHub will be deposited to our account with the Open Source Collective and managed by the Open Collective. This means we have a single place to monitor and maintain transparency of our finances.
|
||||
</p>
|
||||
<p>
|
||||
If you are able, please contribute to this amazing project.
|
||||
</p>
|
||||
<div className="indexCtasBody">
|
||||
<Link
|
||||
className={'button button--outline button--lg cta--button'}
|
||||
to={'https://opencollective.com/meshtastic/donate'}
|
||||
>
|
||||
Sponsor Meshtastic
|
||||
</Link>
|
||||
return (
|
||||
<Layout
|
||||
title="Credits"
|
||||
description="Meshtastic is made possible by the following people & organizations."
|
||||
>
|
||||
<main className="relative mt-20">
|
||||
<div className="container mx-auto p-6 leading-normal space-y-4">
|
||||
<h1>Credits</h1>
|
||||
<p>
|
||||
Meshtastic is community driven. Thousands of hours have been donated
|
||||
by volunteers who want to develop this amazing project. Whether
|
||||
you've submitted a pull request or triaged a bug in our
|
||||
Discord/Forum. You've made Meshtastic possible. Thank you for your
|
||||
contributions.
|
||||
</p>
|
||||
<p>
|
||||
We would also like to recognize those who have donated financially
|
||||
to the project. As Meshtastic has grown, we've aquired some ongoing
|
||||
costs to keep the project running. Thank you for your generous
|
||||
donations.
|
||||
</p>
|
||||
</div>
|
||||
<h3>
|
||||
Open Collective Donations
|
||||
{/*Open Collective Donations*/}
|
||||
<AvatarLayout list={[]}/>
|
||||
</h3>
|
||||
<h3>
|
||||
GitHub Sponsor Donations
|
||||
{/*GitHub Sponsor Donations*/}
|
||||
<AvatarLayout list={[]}/>
|
||||
</h3>
|
||||
</div>
|
||||
<div className="container mx-auto p-6 leading-normal space-y-4">
|
||||
<h2>Partnerships</h2>
|
||||
<div className="mt-12 grid grid-cols-2 gap-0.5 md:grid-cols-3 lg:mt-0 lg:grid-cols-2">
|
||||
{partnerLogos.map((logo) => (
|
||||
<div
|
||||
key={logo.name}
|
||||
className="col-span-1 flex justify-center bg-gray-50 py-8 px-8"
|
||||
<div className="container mx-auto p-6 leading-normal space-y-4">
|
||||
<h2>Fiscal Sponsors</h2>
|
||||
<p>
|
||||
We have partnered with both the{" "}
|
||||
<a
|
||||
className="underline"
|
||||
href="https://opencollective.com"
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
className="max-h-12"
|
||||
src={logo.url}
|
||||
alt={logo.name}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
Open Collective
|
||||
</a>{" "}
|
||||
and the{" "}
|
||||
<a
|
||||
className="underline"
|
||||
href="https://www.oscollective.org"
|
||||
target="_blank"
|
||||
>
|
||||
Open Source Collective
|
||||
</a>{" "}
|
||||
to help us with a fiscal management framework and banking needs.
|
||||
They help support over three thousand open source projects including
|
||||
the PHP Foundation, F-Droid, Sonarr, LinuxServer and DarkReader. We
|
||||
are in good hands and good company.
|
||||
</p>
|
||||
<p>
|
||||
As with everything we do here, Open Collective provides a fully
|
||||
transparent framework for our budget and expenses. You can see what
|
||||
we’re bringing in, who is spending money and where that money is
|
||||
going{" "}
|
||||
<a
|
||||
className="underline"
|
||||
href="https://opencollective.com/meshtastic"
|
||||
target="_blank"
|
||||
>
|
||||
here
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
<p>
|
||||
In addition to our partnership with Open Collective and Open Source
|
||||
Collective, we have also been approved into the{" "}
|
||||
<a
|
||||
className="underline"
|
||||
href="https://github.com/sponsors"
|
||||
target="_blank"
|
||||
>
|
||||
GitHub Sponsors
|
||||
</a>{" "}
|
||||
program where we can set fundraising goals with GitHub.
|
||||
</p>
|
||||
<p>
|
||||
All donations made through GitHub will be deposited to our account
|
||||
with the Open Source Collective and managed by the Open Collective.
|
||||
This means we have a single place to monitor and maintain
|
||||
transparency of our finances.
|
||||
</p>
|
||||
<p>If you are able, please contribute to this amazing project.</p>
|
||||
<div className="indexCtasBody">
|
||||
<Link
|
||||
className={"button button--outline button--lg cta--button"}
|
||||
to={"https://opencollective.com/meshtastic/donate"}
|
||||
>
|
||||
Sponsor Meshtastic
|
||||
</Link>
|
||||
</div>
|
||||
<h3>
|
||||
Open Collective Donations
|
||||
{/*Open Collective Donations*/}
|
||||
<AvatarLayout list={[]} />
|
||||
</h3>
|
||||
<h3>
|
||||
GitHub Sponsor Donations
|
||||
{/*GitHub Sponsor Donations*/}
|
||||
<AvatarLayout list={[]} />
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div className="container mx-auto p-6 leading-normal space-y-4">
|
||||
<h2>Contributors</h2>
|
||||
<p>
|
||||
Literally thousands of hours have gone into creating, maintaining, and improving Meshtastic. Without our contributors none of this would be possible. Thank you for donating the time for each and every commit, issue, and pull request.
|
||||
</p>
|
||||
{/*GitHub Organization Contributors*/}
|
||||
<AvatarLayout list={[]}/>
|
||||
</div>
|
||||
{/*Admin Bios*/}
|
||||
<div className="container mx-auto p-6 leading-normal space-y-4">
|
||||
<AvatarLayout list={[]}/>
|
||||
<div className="container mx-auto p-6 leading-normal space-y-4">
|
||||
<h2>Partnerships</h2>
|
||||
<div className="mt-12 grid grid-cols-2 gap-0.5 md:grid-cols-3 lg:mt-0 lg:grid-cols-2">
|
||||
{partnerLogos.map((logo) => (
|
||||
<div
|
||||
key={logo.name}
|
||||
className="col-span-1 flex justify-center bg-gray-50 py-8 px-8"
|
||||
>
|
||||
<img className="max-h-12" src={logo.url} alt={logo.name} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
<div className="container mx-auto p-6 leading-normal space-y-4">
|
||||
<h2>Contributors</h2>
|
||||
<p>
|
||||
Literally thousands of hours have gone into creating, maintaining,
|
||||
and improving Meshtastic. Without our contributors none of this
|
||||
would be possible. Thank you for donating the time for each and
|
||||
every commit, issue, and pull request.
|
||||
</p>
|
||||
{/*GitHub Organization Contributors*/}
|
||||
<AvatarLayout list={[]} />
|
||||
</div>
|
||||
{/*Admin Bios*/}
|
||||
<div className="container mx-auto p-6 leading-normal space-y-4">
|
||||
<AvatarLayout list={[]} />
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default Credits;
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Meshtastic URL
|
|||
sidebar_label: d
|
||||
---
|
||||
|
||||
# Error : Something happened
|
||||
|
||||
Please go to [Android Usage](/docs/software/android/usage#join-a-channel) for more information.
|
||||
Please go to [Android Usage](/docs/software/android/usage#join-a-channel) for more information.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
export interface downloadCardProps {
|
||||
client: string;
|
||||
|
@ -17,33 +17,33 @@ export const DownloadCard = ({
|
|||
imgUrl2,
|
||||
url2,
|
||||
notes,
|
||||
buttonText,
|
||||
buttonText
|
||||
}: downloadCardProps): JSX.Element => {
|
||||
return (
|
||||
<div className="card">
|
||||
<div
|
||||
className="card__header"
|
||||
style={{ display: 'flex', justifyContent: 'space-between' }}
|
||||
style={{ display: "flex", justifyContent: "space-between" }}
|
||||
>
|
||||
<h3>{client}</h3>
|
||||
</div>
|
||||
<div
|
||||
className="card__body"
|
||||
style={{ display: 'flex', justifyContent: 'center' }}
|
||||
style={{ display: "flex", justifyContent: "center" }}
|
||||
>
|
||||
{buttonText ? (
|
||||
<a href={url} className="button button--secondary button--block">
|
||||
{buttonText}
|
||||
</a>
|
||||
) : (
|
||||
<div>
|
||||
<a href={url}>
|
||||
<img alt="img1" style={{ height: '4rem' }} src={imgUrl}></img>
|
||||
</a>
|
||||
<a href={url2}>
|
||||
<img alt="img2" style={{ height: '4rem' }} src={imgUrl2}></img>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href={url}>
|
||||
<img alt="img1" style={{ height: "4rem" }} src={imgUrl}></img>
|
||||
</a>
|
||||
<a href={url2}>
|
||||
<img alt="img2" style={{ height: "4rem" }} src={imgUrl2}></img>
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="card__footer">{notes ? notes : null}</div>
|
||||
|
@ -56,89 +56,89 @@ export const PlaceholderCard = (): JSX.Element => {
|
|||
<div
|
||||
className="card"
|
||||
style={{
|
||||
width: '100%',
|
||||
animation: 'pulse 2s infinite',
|
||||
transform: 'scale(1)',
|
||||
display: 'flex',
|
||||
gap: '1rem',
|
||||
padding: '1rem',
|
||||
width: "100%",
|
||||
animation: "pulse 2s infinite",
|
||||
transform: "scale(1)",
|
||||
display: "flex",
|
||||
gap: "1rem",
|
||||
padding: "1rem"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: '1rem',
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
marginBottom: "1rem"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
height: '2rem',
|
||||
width: '8rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "2rem",
|
||||
width: "8rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
marginTop: '1rem',
|
||||
height: '1rem',
|
||||
width: '8rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
marginTop: "1rem",
|
||||
height: "1rem",
|
||||
width: "8rem"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="card__body"
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
height: '3rem',
|
||||
display: 'flex',
|
||||
jusifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "3rem",
|
||||
display: "flex",
|
||||
jusifyContent: "center",
|
||||
alignItems: "center"
|
||||
}}
|
||||
/>
|
||||
<a className="button disabled button--primary button--block"> </a>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: '8rem',
|
||||
height: '2rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
width: "8rem",
|
||||
height: "2rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: '11rem',
|
||||
height: '1rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
width: "11rem",
|
||||
height: "1rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: '9rem',
|
||||
height: '1rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
width: "9rem",
|
||||
height: "1rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: '13rem',
|
||||
height: '1rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
width: "13rem",
|
||||
height: "1rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: '11rem',
|
||||
height: '1rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
width: "11rem",
|
||||
height: "1rem"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { DeviceFirmwareResource } from '../../../utils/apiTypes.js';
|
||||
import { DeviceFirmwareResource } from "../../../utils/apiTypes.js";
|
||||
|
||||
export interface releaseCardProps {
|
||||
variant: string;
|
||||
|
@ -11,13 +11,13 @@ export interface releaseCardProps {
|
|||
export const FirmwareCard = ({
|
||||
variant,
|
||||
description,
|
||||
release,
|
||||
release
|
||||
}: releaseCardProps): JSX.Element => {
|
||||
return (
|
||||
<div className="card m-4 border-2 border-secondary">
|
||||
<div
|
||||
className="card__header"
|
||||
style={{ display: 'flex', justifyContent: 'space-between' }}
|
||||
style={{ display: "flex", justifyContent: "space-between" }}
|
||||
>
|
||||
<h3>{variant}</h3>
|
||||
{release?.length && (
|
||||
|
@ -64,86 +64,86 @@ export const PlaceholderFirmwareCard = (): JSX.Element => {
|
|||
<div
|
||||
className="card"
|
||||
style={{
|
||||
width: '100%',
|
||||
animation: 'pulse 2s infinite',
|
||||
transform: 'scale(1)',
|
||||
display: 'flex',
|
||||
gap: '1rem',
|
||||
padding: '1rem',
|
||||
width: "100%",
|
||||
animation: "pulse 2s infinite",
|
||||
transform: "scale(1)",
|
||||
display: "flex",
|
||||
gap: "1rem",
|
||||
padding: "1rem"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: '1rem',
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
marginBottom: "1rem"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
height: '2rem',
|
||||
width: '8rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "2rem",
|
||||
width: "8rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
marginTop: '1rem',
|
||||
height: '1rem',
|
||||
width: '8rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
marginTop: "1rem",
|
||||
height: "1rem",
|
||||
width: "8rem"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="card__body"
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
height: '3rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "3rem"
|
||||
}}
|
||||
/>
|
||||
<a className="button disabled button--primary button--block"> </a>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: '8rem',
|
||||
height: '2rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
width: "8rem",
|
||||
height: "2rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: '11rem',
|
||||
height: '1rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
width: "11rem",
|
||||
height: "1rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: '9rem',
|
||||
height: '1rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
width: "9rem",
|
||||
height: "1rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: '13rem',
|
||||
height: '1rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
width: "13rem",
|
||||
height: "1rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: '11rem',
|
||||
height: '1rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
width: "11rem",
|
||||
height: "1rem"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
export const HeaderText = ({ type, text, link }): JSX.Element => {
|
||||
const Header = type;
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { FaAndroid, FaApple } from 'react-icons/fa';
|
||||
import useSWR from 'swr';
|
||||
import { FaAndroid, FaApple } from "react-icons/fa";
|
||||
import useSWR from "swr";
|
||||
|
||||
import {
|
||||
ArrowTopRightOnSquareIcon,
|
||||
BoltIcon,
|
||||
ComputerDesktopIcon,
|
||||
CpuChipIcon,
|
||||
GlobeAltIcon,
|
||||
} from '@heroicons/react/24/solid';
|
||||
import Layout from '@theme/Layout';
|
||||
GlobeAltIcon
|
||||
} from "@heroicons/react/24/solid";
|
||||
import Layout from "@theme/Layout";
|
||||
|
||||
import { FirmwareReleases } from '../../utils/apiTypes.js';
|
||||
import { fetcher } from '../../utils/swr';
|
||||
import { FirmwareReleases } from "../../utils/apiTypes.js";
|
||||
import { fetcher } from "../../utils/swr";
|
||||
import {
|
||||
FirmwareCard,
|
||||
PlaceholderFirmwareCard,
|
||||
} from './_components/FirmwareCard';
|
||||
PlaceholderFirmwareCard
|
||||
} from "./_components/FirmwareCard";
|
||||
|
||||
const Firmware = (): JSX.Element => {
|
||||
const { data, error } = useSWR<FirmwareReleases>(
|
||||
'https://api.meshtastic.org/github/firmware/list',
|
||||
fetcher,
|
||||
"https://api.meshtastic.org/github/firmware/list",
|
||||
fetcher
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -9,8 +9,8 @@ sidebar_label: e
|
|||
<meta property="og:site_name" content="Meshtastic.org" />
|
||||
</head>
|
||||
|
||||
# QR Code Share Channel URL Should be opened in the appropriate app
|
||||
## QR Code Share Channel URL Should be opened in the appropriate app
|
||||
|
||||
## Meshtastic QR Code URL Format For Firmware version 2.0
|
||||
### Meshtastic QR Code URL Format For Firmware version 2.0
|
||||
|
||||
For Android use the QR code scanner in the app, on Apple devices use the camera to open the QR code URL in the Meshtastic App.
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { FiPlus } from 'react-icons/fi';
|
||||
import { FiPlus } from "react-icons/fi";
|
||||
|
||||
import { HardwareModal } from '@site/src/components/hardware/HardwareModal';
|
||||
import { IDevice } from '@site/src/data/device';
|
||||
import { HardwareModal } from "@site/src/components/hardware/HardwareModal";
|
||||
import { IDevice } from "@site/src/data/device";
|
||||
|
||||
import { HardwareCard } from '../../components/hardware/HardwareCard';
|
||||
import { PageLayout } from '../../components/PageLayout';
|
||||
import { heltec } from '../../data/devices/heltec';
|
||||
import { hydra } from '../../data/devices/hydra';
|
||||
import { nano_g1 } from '../../data/devices/nano_g1';
|
||||
import { rak19001 } from '../../data/devices/rak19001';
|
||||
import { rak19003 } from '../../data/devices/rak19003';
|
||||
import { tbeam } from '../../data/devices/tbeam';
|
||||
import { techo } from '../../data/devices/techo';
|
||||
import { HardwareCard } from "../../components/hardware/HardwareCard";
|
||||
import { PageLayout } from "../../components/PageLayout";
|
||||
import { heltec } from "../../data/devices/heltec";
|
||||
import { hydra } from "../../data/devices/hydra";
|
||||
import { nano_g1 } from "../../data/devices/nano_g1";
|
||||
import { rak19001 } from "../../data/devices/rak19001";
|
||||
import { rak19003 } from "../../data/devices/rak19003";
|
||||
import { tbeam } from "../../data/devices/tbeam";
|
||||
import { techo } from "../../data/devices/techo";
|
||||
|
||||
const Hardware = (): JSX.Element => {
|
||||
const hardware = [tbeam, hydra, rak19003, rak19001, nano_g1, heltec, techo];
|
||||
|
@ -31,7 +31,7 @@ const Hardware = (): JSX.Element => {
|
|||
<a
|
||||
href="#"
|
||||
className="border-indigo-500 text-indigo-600"
|
||||
aria-current={'page'}
|
||||
aria-current={"page"}
|
||||
>
|
||||
Devices
|
||||
</a>
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
import 'react-responsive-carousel/lib/styles/carousel.min.css'; // requires a loader
|
||||
import "react-responsive-carousel/lib/styles/carousel.min.css"; // requires a loader
|
||||
|
||||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { Carousel } from 'react-responsive-carousel';
|
||||
import { Carousel } from "react-responsive-carousel";
|
||||
|
||||
import Head from '@docusaurus/Head';
|
||||
import Link from '@docusaurus/Link';
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import Layout from '@theme/Layout';
|
||||
import Head from "@docusaurus/Head";
|
||||
import Link from "@docusaurus/Link";
|
||||
import useBaseUrl from "@docusaurus/useBaseUrl";
|
||||
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
|
||||
import Layout from "@theme/Layout";
|
||||
|
||||
import { SocialCard, SocialCardProps } from '../components/homepage/SocialCard';
|
||||
import { SocialCard, SocialCardProps } from "../components/homepage/SocialCard";
|
||||
|
||||
const features = [
|
||||
{
|
||||
title: 'Radio Mesh Text Messaging',
|
||||
imageUrl: 'img/homepage/messages.svg',
|
||||
title: "Radio Mesh Text Messaging",
|
||||
imageUrl: "img/homepage/messages.svg",
|
||||
description: (
|
||||
<>
|
||||
Off-grid messaging using inexpensive hardware to create your personal
|
||||
|
@ -23,11 +23,11 @@ const features = [
|
|||
Communicate kilometers/miles between nodes. Internet-connected relay
|
||||
nodes enable the conversation to move online too.
|
||||
</>
|
||||
),
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'Encryption',
|
||||
imageUrl: 'img/homepage/encryption.svg',
|
||||
title: "Encryption",
|
||||
imageUrl: "img/homepage/encryption.svg",
|
||||
description: (
|
||||
<>
|
||||
Messages are AES256 encrypted. Only radios supplied with your channel
|
||||
|
@ -35,22 +35,22 @@ const features = [
|
|||
Using multichannel settings you can send encrypted messages on one
|
||||
channel and still participate in a default Meshtastic mesh.
|
||||
</>
|
||||
),
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'Conserve Battery',
|
||||
imageUrl: 'img/homepage/battery.svg',
|
||||
title: "Conserve Battery",
|
||||
imageUrl: "img/homepage/battery.svg",
|
||||
description: (
|
||||
<>
|
||||
Go for days on end and on a single battery or extend it infinitely with
|
||||
a solar cell. Power management ensures the device will last the duration
|
||||
of your use.
|
||||
</>
|
||||
),
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'Extensible',
|
||||
imageUrl: 'img/homepage/extendable.svg',
|
||||
title: "Extensible",
|
||||
imageUrl: "img/homepage/extendable.svg",
|
||||
description: (
|
||||
<>
|
||||
Create a highly scalable mesh with hardware on a multitude of platforms
|
||||
|
@ -58,77 +58,98 @@ const features = [
|
|||
and produce real-time heatmaps, or maybe decentralized, encrypted
|
||||
messaging network, your imagination is the limit.
|
||||
</>
|
||||
),
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'Platform Agnostic',
|
||||
imageUrl: 'img/homepage/platforms.svg',
|
||||
title: "Platform Agnostic",
|
||||
imageUrl: "img/homepage/platforms.svg",
|
||||
description: (
|
||||
<>
|
||||
Meshtastic clients are built or being built for all major desktop and
|
||||
mobile platforms. Linux, Windows, Mac, Android, and iOS are all
|
||||
supported or well on their way to being supported.
|
||||
</>
|
||||
),
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'Open Source',
|
||||
imageUrl: 'img/homepage/opensource.svg',
|
||||
title: "Open Source",
|
||||
imageUrl: "img/homepage/opensource.svg",
|
||||
description: (
|
||||
<>
|
||||
All Meshtastic software is open source. If you want an improvement,
|
||||
submit a pull request or file an issue on Github. Happy coding!
|
||||
</>
|
||||
),
|
||||
},
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
const SocialCards: SocialCardProps[] = [
|
||||
{
|
||||
color: 'bg-[#5865F2]',
|
||||
link: 'https://discord.com/invite/UQJ5QuM7vq',
|
||||
color: "bg-[#5865F2]",
|
||||
link: "https://discord.com/invite/UQJ5QuM7vq",
|
||||
children: (
|
||||
<img alt="discord" className="m-auto h-10" src="/img/homepage/Discord-Logo-White.svg" />
|
||||
),
|
||||
<img
|
||||
alt="discord"
|
||||
className="m-auto h-10"
|
||||
src="/img/homepage/Discord-Logo-White.svg"
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
color: 'bg-[#ffffff]',
|
||||
link: 'https://twitter.com/TheMeshtastic',
|
||||
color: "bg-[#ffffff]",
|
||||
link: "https://twitter.com/TheMeshtastic",
|
||||
children: (
|
||||
<img alt="twitter" className="m-auto h-10" src="/img/homepage/Twitter-logo.svg" />
|
||||
),
|
||||
<img
|
||||
alt="twitter"
|
||||
className="m-auto h-10"
|
||||
src="/img/homepage/Twitter-logo.svg"
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
color: 'bg-[#FF0000]',
|
||||
link: 'https://www.youtube.com/meshtastic',
|
||||
color: "bg-[#FF0000]",
|
||||
link: "https://www.youtube.com/meshtastic",
|
||||
children: (
|
||||
<img alt="youtube" className="m-auto h-16" src="/img/homepage/YouTube-Logo-White.svg" />
|
||||
),
|
||||
<img
|
||||
alt="youtube"
|
||||
className="m-auto h-16"
|
||||
src="/img/homepage/YouTube-Logo-White.svg"
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
color: 'bg-[#ffffff]',
|
||||
link: 'https://meshtastic.discourse.group',
|
||||
color: "bg-[#ffffff]",
|
||||
link: "https://meshtastic.discourse.group",
|
||||
children: (
|
||||
<img alt="discourse"
|
||||
<img
|
||||
alt="discourse"
|
||||
className="m-auto h-12"
|
||||
src="/img/homepage/Discourse-Logo-White.svg"
|
||||
/>
|
||||
),
|
||||
)
|
||||
},
|
||||
{
|
||||
color: 'bg-[#FF4500]',
|
||||
link: 'https://reddit.com/r/meshtastic',
|
||||
color: "bg-[#FF4500]",
|
||||
link: "https://reddit.com/r/meshtastic",
|
||||
children: (
|
||||
<img alt="reddit" className="m-auto h-20" src="/img/homepage/Reddit-Logo-White.svg" />
|
||||
),
|
||||
<img
|
||||
alt="reddit"
|
||||
className="m-auto h-20"
|
||||
src="/img/homepage/Reddit-Logo-White.svg"
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
color: 'bg-[#ffffff]',
|
||||
link: 'https://github.com/meshtastic',
|
||||
color: "bg-[#ffffff]",
|
||||
link: "https://github.com/meshtastic",
|
||||
children: (
|
||||
<img alt="github" className="m-auto w-12" src="/img/homepage/GitHub-Logo-White.svg" />
|
||||
),
|
||||
},
|
||||
<img
|
||||
alt="github"
|
||||
className="m-auto w-12"
|
||||
src="/img/homepage/GitHub-Logo-White.svg"
|
||||
/>
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
function Feature({ imageUrl, title, description }) {
|
||||
|
@ -155,7 +176,7 @@ function Home() {
|
|||
<meta property="og:title" content="Meshtastic" />
|
||||
<meta
|
||||
property="og:image"
|
||||
content={useBaseUrl('design/web/social-preview-1200x630.png')}
|
||||
content={useBaseUrl("design/web/social-preview-1200x630.png")}
|
||||
/>
|
||||
<meta
|
||||
property="og:description"
|
||||
|
@ -164,14 +185,14 @@ function Home() {
|
|||
<meta property="og:url" content="https://meshtastic.org/" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
</Head>
|
||||
<header style={{ textAlign: 'center' }} className="hero hero--primary">
|
||||
<header style={{ textAlign: "center" }} className="hero hero--primary">
|
||||
<div className="container">
|
||||
<h1 className="hero__title">
|
||||
<img
|
||||
style={{ paddingTop: '2rem', paddingBottom: '2rem' }}
|
||||
style={{ paddingTop: "2rem", paddingBottom: "2rem" }}
|
||||
alt="Meshtastic Logo"
|
||||
className="header__logo"
|
||||
src={useBaseUrl('design/typelogo/typelogo.svg')}
|
||||
src={useBaseUrl("design/typelogo/typelogo.svg")}
|
||||
/>
|
||||
</h1>
|
||||
<p className="hero__subtitle">{siteConfig.tagline}</p>
|
||||
|
@ -222,23 +243,23 @@ function Home() {
|
|||
<ul
|
||||
className="mx-auto"
|
||||
style={{
|
||||
position: 'relative',
|
||||
display: 'grid',
|
||||
gap: '1.5rem',
|
||||
gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))',
|
||||
paddingLeft: '0',
|
||||
position: "relative",
|
||||
display: "grid",
|
||||
gap: "1.5rem",
|
||||
gridTemplateColumns: "repeat(auto-fill, minmax(280px, 1fr))",
|
||||
paddingLeft: "0"
|
||||
}}
|
||||
>
|
||||
<div className="card">
|
||||
<div
|
||||
className="card__header"
|
||||
style={{ display: 'flex', justifyContent: 'space-between' }}
|
||||
style={{ display: "flex", justifyContent: "space-between" }}
|
||||
>
|
||||
<h3>1. Purchase Supported Hardware</h3>
|
||||
</div>
|
||||
<div
|
||||
className="card__body"
|
||||
style={{ display: 'flex', justifyContent: 'center' }}
|
||||
style={{ display: "flex", justifyContent: "center" }}
|
||||
>
|
||||
<p>
|
||||
Hardware you will want to consider:
|
||||
|
@ -258,13 +279,13 @@ function Home() {
|
|||
<div className="card">
|
||||
<div
|
||||
className="card__header"
|
||||
style={{ display: 'flex', justifyContent: 'space-between' }}
|
||||
style={{ display: "flex", justifyContent: "space-between" }}
|
||||
>
|
||||
<h3>2. Flash & Configure Node</h3>
|
||||
</div>
|
||||
<div
|
||||
className="card__body"
|
||||
style={{ display: 'flex', justifyContent: 'center' }}
|
||||
style={{ display: "flex", justifyContent: "center" }}
|
||||
>
|
||||
<p>
|
||||
The Meshtastic Flasher application can assist you in flashing
|
||||
|
@ -275,13 +296,13 @@ function Home() {
|
|||
<div className="card">
|
||||
<div
|
||||
className="card__header"
|
||||
style={{ display: 'flex', justifyContent: 'space-between' }}
|
||||
style={{ display: "flex", justifyContent: "space-between" }}
|
||||
>
|
||||
<h3>3. Connect to Node</h3>
|
||||
</div>
|
||||
<div
|
||||
className="card__body"
|
||||
style={{ display: 'flex', justifyContent: 'center' }}
|
||||
style={{ display: "flex", justifyContent: "center" }}
|
||||
>
|
||||
<p>
|
||||
Applications are available for the following systems:
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { Showcase } from '../../../utils/apiTypes';
|
||||
import { mapUrl } from '../../../utils/map';
|
||||
import { CardTags } from './CardTags';
|
||||
import { Showcase } from "../../../utils/apiTypes";
|
||||
import { mapUrl } from "../../../utils/map";
|
||||
import { CardTags } from "./CardTags";
|
||||
|
||||
export interface CardProps {
|
||||
network: Showcase;
|
||||
|
@ -11,7 +11,7 @@ export interface CardProps {
|
|||
export const Card = React.memo(({ network }: CardProps) => (
|
||||
<div className="card">
|
||||
<div className="card__image">
|
||||
<div style={{ height: '140px' }}>
|
||||
<div style={{ height: "140px" }}>
|
||||
<img img={mapUrl(network.nodes ?? [])} alt={network.title} />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -23,7 +23,7 @@ export const Card = React.memo(({ network }: CardProps) => (
|
|||
<a
|
||||
href={`?id=${network.id}`}
|
||||
className="button button--primary button--block"
|
||||
style={{ marginBottom: '0.5rem' }}
|
||||
style={{ marginBottom: "0.5rem" }}
|
||||
>
|
||||
Read more
|
||||
</a>
|
||||
|
@ -36,72 +36,72 @@ export const PlaceholderCard = (): JSX.Element => (
|
|||
<div
|
||||
className="card"
|
||||
style={{
|
||||
animation: 'pulse 2s infinite',
|
||||
transform: 'scale(1)',
|
||||
animation: "pulse 2s infinite",
|
||||
transform: "scale(1)"
|
||||
}}
|
||||
>
|
||||
<div className="card__image">
|
||||
<div
|
||||
style={{
|
||||
height: '140px',
|
||||
height: "140px"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<div
|
||||
style={{
|
||||
width: '30%',
|
||||
height: '2rem',
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
marginBottom: '1rem',
|
||||
width: "30%",
|
||||
height: "2rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
marginBottom: "1rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '1rem',
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
marginBottom: '0.5rem',
|
||||
width: "100%",
|
||||
height: "1rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
marginBottom: "0.5rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '1rem',
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: "100%",
|
||||
height: "1rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="card__footer">
|
||||
<a
|
||||
className="button disabled button--primary button--block"
|
||||
style={{ marginBottom: '0.5rem' }}
|
||||
style={{ marginBottom: "0.5rem" }}
|
||||
>
|
||||
|
||||
</a>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
gap: '0.5rem',
|
||||
display: "flex",
|
||||
gap: "0.5rem"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: '4rem',
|
||||
height: '1.5rem',
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: "4rem",
|
||||
height: "1.5rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: '4rem',
|
||||
height: '1.5rem',
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: "4rem",
|
||||
height: "1.5rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { ShowcaseTag } from '../../../utils/apiTypes';
|
||||
import { ShowcaseTag } from "../../../utils/apiTypes";
|
||||
|
||||
export interface CardTagsProps {
|
||||
tags: ShowcaseTag[];
|
||||
|
@ -16,8 +16,8 @@ export const CardTags = ({ tags }: CardTagsProps) => {
|
|||
key={index}
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
marginRight: '0.3rem',
|
||||
userSelect: 'none',
|
||||
marginRight: "0.3rem",
|
||||
userSelect: "none"
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { FiHeart } from 'react-icons/fi';
|
||||
import useSWR from 'swr';
|
||||
import { FiHeart } from "react-icons/fi";
|
||||
import useSWR from "swr";
|
||||
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import { fetcher } from '@site/src/utils/swr';
|
||||
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
|
||||
import { fetcher } from "@site/src/utils/swr";
|
||||
|
||||
import { ShowcaseTag } from '../../../utils/apiTypes';
|
||||
import { ShowcaseTag } from "../../../utils/apiTypes";
|
||||
// import { TagList, Tags } from '../../../utils/showcase';
|
||||
import { PlaceholderTagSelect, TagSelect } from './TagSelect';
|
||||
import { PlaceholderTagSelect, TagSelect } from "./TagSelect";
|
||||
|
||||
export const Filters = (): JSX.Element => {
|
||||
const { siteConfig } = useDocusaurusContext();
|
||||
|
||||
const { data, error } = useSWR<ShowcaseTag[]>(
|
||||
`${siteConfig.customFields.API_URL}/showcase/tags`,
|
||||
fetcher,
|
||||
fetcher
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -23,10 +23,10 @@ export const Filters = (): JSX.Element => {
|
|||
{data && !error ? (
|
||||
<ul
|
||||
style={{
|
||||
padding: '0',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
flexWrap: 'wrap',
|
||||
padding: "0",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
flexWrap: "wrap"
|
||||
}}
|
||||
>
|
||||
{data.map((tag, i) => {
|
||||
|
@ -37,17 +37,17 @@ export const Filters = (): JSX.Element => {
|
|||
<div
|
||||
key={i}
|
||||
style={{
|
||||
boxSizing: 'border-box',
|
||||
position: 'relative',
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
height: '2rem',
|
||||
marginTop: '0.5rem',
|
||||
marginRight: '0.5rem',
|
||||
fontSize: '0.875rem',
|
||||
lineHeight: '1.25rem',
|
||||
verticalAlign: 'middle',
|
||||
userSelect: 'none',
|
||||
boxSizing: "border-box",
|
||||
position: "relative",
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
height: "2rem",
|
||||
marginTop: "0.5rem",
|
||||
marginRight: "0.5rem",
|
||||
fontSize: "0.875rem",
|
||||
lineHeight: "1.25rem",
|
||||
verticalAlign: "middle",
|
||||
userSelect: "none"
|
||||
}}
|
||||
>
|
||||
<TagSelect
|
||||
|
@ -55,12 +55,12 @@ export const Filters = (): JSX.Element => {
|
|||
id={id}
|
||||
label={label}
|
||||
icon={
|
||||
tag.label === 'Favorite' ? (
|
||||
tag.label === "Favorite" ? (
|
||||
<span
|
||||
style={{
|
||||
display: 'flex',
|
||||
marginLeft: '0.5rem',
|
||||
color: 'rgb(190 24 93)',
|
||||
display: "flex",
|
||||
marginLeft: "0.5rem",
|
||||
color: "rgb(190 24 93)"
|
||||
}}
|
||||
>
|
||||
<FiHeart />
|
||||
|
@ -71,8 +71,8 @@ export const Filters = (): JSX.Element => {
|
|||
backgroundColor: color,
|
||||
width: 10,
|
||||
height: 10,
|
||||
borderRadius: '50%',
|
||||
marginLeft: 8,
|
||||
borderRadius: "50%",
|
||||
marginLeft: 8
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import useSWR from 'swr';
|
||||
import useSWR from "swr";
|
||||
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import { Showcase } from '@site/src/utils/apiTypes';
|
||||
import { User } from '@site/src/utils/github';
|
||||
import { fetcher } from '@site/src/utils/swr';
|
||||
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
|
||||
import { Showcase } from "@site/src/utils/apiTypes";
|
||||
import { User } from "@site/src/utils/github";
|
||||
import { fetcher } from "@site/src/utils/swr";
|
||||
|
||||
interface NetworkProps {
|
||||
id: string;
|
||||
|
@ -16,12 +16,12 @@ export const Network = ({ id }: NetworkProps): JSX.Element => {
|
|||
|
||||
const { data, error } = useSWR<Showcase>(
|
||||
`${siteConfig.customFields.API_URL}/showcase/${id}`,
|
||||
fetcher,
|
||||
fetcher
|
||||
);
|
||||
|
||||
const githubData = useSWR<User>(
|
||||
`https://api.github.com/users/${data?.author?.githubUsername}`,
|
||||
fetcher,
|
||||
fetcher
|
||||
).data;
|
||||
|
||||
return (
|
||||
|
@ -48,15 +48,15 @@ export const Network = ({ id }: NetworkProps): JSX.Element => {
|
|||
<div
|
||||
className="card"
|
||||
style={{
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
maxWidth: '900px',
|
||||
marginLeft: "auto",
|
||||
marginRight: "auto",
|
||||
maxWidth: "900px"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="card__header"
|
||||
style={{
|
||||
margin: '8px',
|
||||
margin: "8px"
|
||||
}}
|
||||
>
|
||||
<h2>Bill of Materials</h2>
|
||||
|
@ -66,14 +66,14 @@ export const Network = ({ id }: NetworkProps): JSX.Element => {
|
|||
<div
|
||||
key={index}
|
||||
style={{
|
||||
borderTop: '2px solid gray',
|
||||
display: 'flex',
|
||||
borderTop: "2px solid gray",
|
||||
display: "flex"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: '4rem',
|
||||
display: 'flex',
|
||||
width: "4rem",
|
||||
display: "flex"
|
||||
}}
|
||||
>
|
||||
<img
|
||||
|
@ -81,13 +81,13 @@ export const Network = ({ id }: NetworkProps): JSX.Element => {
|
|||
height="auto"
|
||||
width="100%"
|
||||
style={{
|
||||
margin: 'auto',
|
||||
padding: '4px',
|
||||
display: 'block',
|
||||
maxWidth: '60px',
|
||||
maxHeight: '60px',
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
margin: "auto",
|
||||
padding: "4px",
|
||||
display: "block",
|
||||
maxWidth: "60px",
|
||||
maxHeight: "60px",
|
||||
width: "auto",
|
||||
height: "auto"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
@ -103,8 +103,8 @@ export const Network = ({ id }: NetworkProps): JSX.Element => {
|
|||
href={material.url}
|
||||
className="button button--outline button--secondary"
|
||||
style={{
|
||||
marginTop: 'auto',
|
||||
marginBottom: 'auto',
|
||||
marginTop: "auto",
|
||||
marginBottom: "auto"
|
||||
}}
|
||||
>
|
||||
View
|
||||
|
@ -129,74 +129,74 @@ export const PlaceholderNetwork = (): JSX.Element => {
|
|||
<div
|
||||
className="container"
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: window.innerWidth > 768 ? 'row' : 'column',
|
||||
gap: '2rem',
|
||||
display: "flex",
|
||||
flexDirection: window.innerWidth > 768 ? "row" : "column",
|
||||
gap: "2rem"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: window.innerWidth > 768 ? '60%' : '100%',
|
||||
width: window.innerWidth > 768 ? "60%" : "100%"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="card"
|
||||
style={{
|
||||
width: '100%',
|
||||
animation: 'pulse 2s infinite',
|
||||
transform: 'scale(1)',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '2rem',
|
||||
padding: '2rem',
|
||||
width: "100%",
|
||||
animation: "pulse 2s infinite",
|
||||
transform: "scale(1)",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "2rem",
|
||||
padding: "2rem"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
height: '4rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "4rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
height: '12rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "12rem"
|
||||
}}
|
||||
/>
|
||||
<div style={{ display: 'flex', gap: '1rem' }}>
|
||||
<div style={{ display: "flex", gap: "1rem" }}>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '999px',
|
||||
backgroundColor: 'gray',
|
||||
height: '4rem',
|
||||
width: '4rem',
|
||||
minWidth: '4rem',
|
||||
borderRadius: "999px",
|
||||
backgroundColor: "gray",
|
||||
height: "4rem",
|
||||
width: "4rem",
|
||||
minWidth: "4rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '1rem',
|
||||
width: '100%',
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "1rem",
|
||||
width: "100%"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
height: '1rem',
|
||||
width: "100%",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "1rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
height: '2rem',
|
||||
width: "100%",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "2rem"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
@ -205,108 +205,108 @@ export const PlaceholderNetwork = (): JSX.Element => {
|
|||
</div>
|
||||
<div
|
||||
style={{
|
||||
width: window.innerWidth > 768 ? '40%' : '100%',
|
||||
width: window.innerWidth > 768 ? "40%" : "100%"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="card"
|
||||
style={{
|
||||
width: '100%',
|
||||
animation: 'pulse 2s infinite',
|
||||
transform: 'scale(1)',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '2rem',
|
||||
padding: '2rem',
|
||||
width: "100%",
|
||||
animation: "pulse 2s infinite",
|
||||
transform: "scale(1)",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "2rem",
|
||||
padding: "2rem"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
height: '12rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "12rem"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
height: '2rem',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "2rem"
|
||||
}}
|
||||
/>
|
||||
<div style={{ display: 'flex', gap: '0.5rem' }}>
|
||||
<div style={{ display: "flex", gap: "0.5rem" }}>
|
||||
<div
|
||||
style={{
|
||||
width: '7rem',
|
||||
height: '1.8rem',
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: "7rem",
|
||||
height: "1.8rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: '7rem',
|
||||
height: '1.8rem',
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: "7rem",
|
||||
height: "1.8rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: '7rem',
|
||||
height: '1.8rem',
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
width: "7rem",
|
||||
height: "1.8rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}
|
||||
style={{ display: "flex", flexDirection: "column", gap: "1rem" }}
|
||||
>
|
||||
<div style={{ display: 'flex', gap: '1rem' }}>
|
||||
<div style={{ display: "flex", gap: "1rem" }}>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
height: '2.5rem',
|
||||
width: '20%',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "2.5rem",
|
||||
width: "20%"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
height: '2.5rem',
|
||||
width: '60%',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "2.5rem",
|
||||
width: "60%"
|
||||
}}
|
||||
/>
|
||||
<a
|
||||
className="button disabled button--primary button--block"
|
||||
style={{ width: '20%' }}
|
||||
style={{ width: "20%" }}
|
||||
>
|
||||
|
||||
</a>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: '1rem' }}>
|
||||
<div style={{ display: "flex", gap: "1rem" }}>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
height: '2.5rem',
|
||||
width: '20%',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "2.5rem",
|
||||
width: "20%"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
height: '2.5rem',
|
||||
width: '60%',
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
height: "2.5rem",
|
||||
width: "60%"
|
||||
}}
|
||||
/>
|
||||
<a
|
||||
className="button disabled button--primary button--block"
|
||||
style={{ width: '20%' }}
|
||||
style={{ width: "20%" }}
|
||||
>
|
||||
|
||||
</a>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { Showcase } from '../../../utils/apiTypes';
|
||||
import { Card, PlaceholderCard } from './Card';
|
||||
import { Showcase } from "../../../utils/apiTypes";
|
||||
import { Card, PlaceholderCard } from "./Card";
|
||||
|
||||
interface NetworkSectionProps {
|
||||
title: string;
|
||||
|
@ -14,26 +14,26 @@ export const NetworkSection = ({
|
|||
title,
|
||||
icon,
|
||||
iconColor,
|
||||
networks,
|
||||
networks
|
||||
}: NetworkSectionProps): JSX.Element => {
|
||||
return (
|
||||
<div className="margin-top--lg container">
|
||||
<div
|
||||
className="margin-bottom--sm"
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
display: "flex",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<h2>{title}</h2>
|
||||
{icon && (
|
||||
<span
|
||||
style={{
|
||||
marginBottom: '0.5rem',
|
||||
marginLeft: '0.5rem',
|
||||
fontSize: '1.25rem',
|
||||
lineHeight: '1.75rem',
|
||||
color: iconColor,
|
||||
marginBottom: "0.5rem",
|
||||
marginLeft: "0.5rem",
|
||||
fontSize: "1.25rem",
|
||||
lineHeight: "1.75rem",
|
||||
color: iconColor
|
||||
}}
|
||||
>
|
||||
{icon}
|
||||
|
@ -42,11 +42,11 @@ export const NetworkSection = ({
|
|||
</div>
|
||||
<ul
|
||||
style={{
|
||||
position: 'relative',
|
||||
display: 'grid',
|
||||
gap: '1.5rem',
|
||||
gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))',
|
||||
paddingLeft: '0',
|
||||
position: "relative",
|
||||
display: "grid",
|
||||
gap: "1.5rem",
|
||||
gridTemplateColumns: "repeat(auto-fill, minmax(280px, 1fr))",
|
||||
paddingLeft: "0"
|
||||
}}
|
||||
>
|
||||
{networks ? (
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { FiHeart, FiSearch } from 'react-icons/fi';
|
||||
import useSWR from 'swr';
|
||||
import { FiHeart, FiSearch } from "react-icons/fi";
|
||||
import useSWR from "swr";
|
||||
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import { useSelectedTags } from '@site/src/hooks/useSelectedTags';
|
||||
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
|
||||
import { useSelectedTags } from "@site/src/hooks/useSelectedTags";
|
||||
|
||||
import { useFilteredNetworks } from '../../../hooks/useFilteredNetworks';
|
||||
import { Showcase } from '../../../utils/apiTypes';
|
||||
import { fetcher } from '../../../utils/swr';
|
||||
import { NetworkSection } from './NetworkSection';
|
||||
import { useFilteredNetworks } from "../../../hooks/useFilteredNetworks";
|
||||
import { Showcase } from "../../../utils/apiTypes";
|
||||
import { fetcher } from "../../../utils/swr";
|
||||
import { NetworkSection } from "./NetworkSection";
|
||||
|
||||
export const Networks = (): JSX.Element => {
|
||||
const { siteConfig } = useDocusaurusContext();
|
||||
|
||||
const { data, error } = useSWR<Showcase[]>(
|
||||
`${siteConfig.customFields.API_URL}/showcase`,
|
||||
fetcher,
|
||||
fetcher
|
||||
);
|
||||
|
||||
const selectedTags = useSelectedTags();
|
||||
|
@ -32,7 +32,7 @@ export const Networks = (): JSX.Element => {
|
|||
icon={<FiHeart />}
|
||||
iconColor="rgb(190 24 93)"
|
||||
networks={data?.filter((network) =>
|
||||
network.tags.find((tag) => tag.label === 'Favorite'),
|
||||
network.tags.find((tag) => tag.label === "Favorite")
|
||||
)}
|
||||
/>
|
||||
<NetworkSection title="All networks" networks={data} />
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
import 'url-search-params-polyfill';
|
||||
import "url-search-params-polyfill";
|
||||
|
||||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { useHistory, useLocation } from '@docusaurus/router';
|
||||
import { ShowcaseTag } from '@site/src/utils/apiTypes';
|
||||
import { useHistory, useLocation } from "@docusaurus/router";
|
||||
import { ShowcaseTag } from "@site/src/utils/apiTypes";
|
||||
|
||||
import { toggleListItem } from '../../../utils/showcase';
|
||||
import { toggleListItem } from "../../../utils/showcase";
|
||||
|
||||
interface Props extends React.ComponentProps<'input'> {
|
||||
icon: React.ReactElement<React.ComponentProps<'svg'>>;
|
||||
interface Props extends React.ComponentProps<"input"> {
|
||||
icon: React.ReactElement<React.ComponentProps<"svg">>;
|
||||
label: React.ReactNode;
|
||||
tag: ShowcaseTag;
|
||||
}
|
||||
|
||||
export function readSearchTags(search: string): string[] {
|
||||
return new URLSearchParams(search).getAll('tags');
|
||||
return new URLSearchParams(search).getAll("tags");
|
||||
}
|
||||
|
||||
function replaceSearchTags(search: string, newTags: string[]) {
|
||||
const searchParams = new URLSearchParams(search);
|
||||
searchParams.delete('tags');
|
||||
newTags.forEach((tag) => searchParams.append('tags', tag));
|
||||
searchParams.delete("tags");
|
||||
newTags.forEach((tag) => searchParams.append("tags", tag));
|
||||
return searchParams.toString();
|
||||
}
|
||||
|
||||
|
@ -42,11 +42,11 @@ export const TagSelect = React.forwardRef<HTMLLabelElement, Props>(
|
|||
return (
|
||||
<button
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
display: "flex",
|
||||
alignItems: "center"
|
||||
}}
|
||||
className={`button button--sm button--outline button--secondary ${
|
||||
selected ? 'button--active' : ''
|
||||
selected ? "button--active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
toggleTag();
|
||||
|
@ -56,55 +56,55 @@ export const TagSelect = React.forwardRef<HTMLLabelElement, Props>(
|
|||
{icon}
|
||||
</button>
|
||||
);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
export const PlaceholderTagSelect = (): JSX.Element => (
|
||||
<div
|
||||
style={{
|
||||
boxSizing: 'border-box',
|
||||
position: 'relative',
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
height: '2rem',
|
||||
marginTop: '0.5rem',
|
||||
marginRight: '0.5rem',
|
||||
fontSize: '0.875rem',
|
||||
lineHeight: '1.25rem',
|
||||
verticalAlign: 'middle',
|
||||
userSelect: 'none',
|
||||
boxSizing: "border-box",
|
||||
position: "relative",
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
height: "2rem",
|
||||
marginTop: "0.5rem",
|
||||
marginRight: "0.5rem",
|
||||
fontSize: "0.875rem",
|
||||
lineHeight: "1.25rem",
|
||||
verticalAlign: "middle",
|
||||
userSelect: "none"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: '7rem',
|
||||
height: '1.8rem',
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
animation: 'pulse 2s infinite',
|
||||
transform: 'scale(1)',
|
||||
width: "7rem",
|
||||
height: "1.8rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
animation: "pulse 2s infinite",
|
||||
transform: "scale(1)"
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: '7rem',
|
||||
height: '1.8rem',
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
animation: 'pulse 2s infinite',
|
||||
transform: 'scale(1)',
|
||||
marginLeft: 8,
|
||||
width: "7rem",
|
||||
height: "1.8rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
animation: "pulse 2s infinite",
|
||||
transform: "scale(1)",
|
||||
marginLeft: 8
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: '7rem',
|
||||
height: '1.8rem',
|
||||
borderRadius: '0.4rem',
|
||||
backgroundColor: 'gray',
|
||||
animation: 'pulse 2s infinite',
|
||||
transform: 'scale(1)',
|
||||
marginLeft: 8,
|
||||
width: "7rem",
|
||||
height: "1.8rem",
|
||||
borderRadius: "0.4rem",
|
||||
backgroundColor: "gray",
|
||||
animation: "pulse 2s infinite",
|
||||
transform: "scale(1)",
|
||||
marginLeft: 8
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import 'url-search-params-polyfill';
|
||||
import "url-search-params-polyfill";
|
||||
|
||||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
import { useLocation } from '@docusaurus/router';
|
||||
import Layout from '@theme/Layout';
|
||||
import { useLocation } from "@docusaurus/router";
|
||||
import Layout from "@theme/Layout";
|
||||
|
||||
import { Filters } from './_components/Filters';
|
||||
import { Network } from './_components/Network';
|
||||
import { Networks } from './_components/Networks';
|
||||
import { Filters } from "./_components/Filters";
|
||||
import { Network } from "./_components/Network";
|
||||
import { Networks } from "./_components/Networks";
|
||||
|
||||
const Showcase = (): JSX.Element => {
|
||||
const location = useLocation();
|
||||
const id = new URLSearchParams(location.search).get('id');
|
||||
const id = new URLSearchParams(location.search).get("id");
|
||||
|
||||
return (
|
||||
<Layout
|
||||
|
@ -19,7 +19,7 @@ const Showcase = (): JSX.Element => {
|
|||
description="Portfolio of projects from the Meshtastic community"
|
||||
>
|
||||
<main className="margin-vert--lg">
|
||||
{!!id ? (
|
||||
{id ? (
|
||||
<Network id={id} />
|
||||
) : (
|
||||
<>
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { fromByteArray, toByteArray } from 'base64-js';
|
||||
import { fromByteArray, toByteArray } from "base64-js";
|
||||
|
||||
import { Protobuf } from '@meshtastic/meshtasticjs';
|
||||
import Layout from '@theme/Layout';
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
import Layout from "@theme/Layout";
|
||||
|
||||
const OEM = (): JSX.Element => {
|
||||
const [oemAesKey, setOemAesKey] = useState<Uint8Array>(new Uint8Array());
|
||||
const [oemFont, setOemFont] = useState<Protobuf.ScreenFonts>(
|
||||
Protobuf.ScreenFonts.FONT_MEDIUM,
|
||||
Protobuf.ScreenFonts.FONT_MEDIUM
|
||||
);
|
||||
const [oemIconBits, setOemIconBits] = useState<Uint8Array>(new Uint8Array());
|
||||
const [oemIconHeight, setOemIconHeight] = useState<number>(0);
|
||||
const [oemIconWidth, setOemIconWidth] = useState<number>(0);
|
||||
const [oemText, setOemText] = useState<string>('');
|
||||
const [oemText, setOemText] = useState<string>("");
|
||||
const [oemBytes, setOemBytes] = useState<Uint8Array>(new Uint8Array());
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
|
@ -26,14 +26,14 @@ const OEM = (): JSX.Element => {
|
|||
oemIconBits,
|
||||
oemIconHeight,
|
||||
oemIconWidth,
|
||||
oemText,
|
||||
}),
|
||||
oemText
|
||||
})
|
||||
);
|
||||
}, [oemAesKey, oemFont, oemIconBits, oemIconHeight, oemIconWidth, oemText]);
|
||||
|
||||
const enumOptions = Protobuf.ScreenFonts
|
||||
? Object.entries(Protobuf.ScreenFonts).filter(
|
||||
(value) => typeof value[1] === 'number',
|
||||
(value) => typeof value[1] === "number"
|
||||
)
|
||||
: [];
|
||||
|
||||
|
@ -102,8 +102,8 @@ const OEM = (): JSX.Element => {
|
|||
readFile(e.target.files[0]).then((data) => {
|
||||
setOemIconBits(
|
||||
new Uint8Array(
|
||||
data.split(',').map((s) => parseInt(s.trim(), 16)),
|
||||
),
|
||||
data.split(",").map((s) => parseInt(s.trim(), 16))
|
||||
)
|
||||
);
|
||||
});
|
||||
}}
|
||||
|
@ -137,7 +137,7 @@ const OEM = (): JSX.Element => {
|
|||
download="OEM.bin"
|
||||
onClick={() => {
|
||||
const blob = new Blob([oemBytes], {
|
||||
type: 'application/octet-stream',
|
||||
type: "application/octet-stream"
|
||||
});
|
||||
window.open(URL.createObjectURL(blob));
|
||||
}}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { Node } from './apiTypes.js';
|
||||
import { Node } from "./apiTypes.js";
|
||||
|
||||
export const mapUrl = (nodes: Node[]): string => {
|
||||
const width = 900;
|
||||
const height = 400;
|
||||
const access_token =
|
||||
'pk.eyJ1Ijoic2FjaGF3IiwiYSI6ImNrNW9meXozZjBsdW0zbHBjM2FnNnV6cmsifQ.3E4n8eFGD9ZOFo-XDVeZnQ';
|
||||
"pk.eyJ1Ijoic2FjaGF3IiwiYSI6ImNrNW9meXozZjBsdW0zbHBjM2FnNnV6cmsifQ.3E4n8eFGD9ZOFo-XDVeZnQ";
|
||||
const nodeCoords = nodes.map(
|
||||
({ latitude, longitude }) => `pin-l+67ea94(${longitude},${latitude})`,
|
||||
({ latitude, longitude }) => `pin-l+67ea94(${longitude},${latitude})`
|
||||
);
|
||||
|
||||
return `https://api.mapbox.com/styles/v1/mapbox/satellite-v9/static/${nodeCoords}/auto/${width}x${height}@2x?access_token=${access_token}`;
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
export const sortBy = <T>(array: T[], getter: (item: T) => unknown): T[] => {
|
||||
const sortedArray = [...array];
|
||||
sortedArray.sort((a, b) =>
|
||||
// @ts-ignore
|
||||
getter(a) > getter(b) ? 1 : getter(b) > getter(a) ? -1 : 0,
|
||||
getter(a) > getter(b) ? 1 : getter(b) > getter(a) ? -1 : 0
|
||||
);
|
||||
return sortedArray;
|
||||
};
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
// trunk-ignore(eslint/no-undef)
|
||||
module.exports = {
|
||||
content: ['./src/**/*.{js,jsx,ts,tsx}'],
|
||||
darkMode: 'class',
|
||||
content: ["./src/**/*.{js,jsx,ts,tsx}"],
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
accent: 'var(--accent)',
|
||||
base: 'var(--base)',
|
||||
primary: 'var(--primary)',
|
||||
secondary: 'var(--secondary)',
|
||||
tertiary: 'var(--tertiary)',
|
||||
mute: 'var(--mute)',
|
||||
primaryInv: 'var(--primaryInv)',
|
||||
secondaryInv: 'var(--secondaryInv)',
|
||||
tertiaryInv: 'var(--tertiaryInv)',
|
||||
},
|
||||
},
|
||||
accent: "var(--accent)",
|
||||
base: "var(--base)",
|
||||
primary: "var(--primary)",
|
||||
secondary: "var(--secondary)",
|
||||
tertiary: "var(--tertiary)",
|
||||
mute: "var(--mute)",
|
||||
primaryInv: "var(--primaryInv)",
|
||||
secondaryInv: "var(--secondaryInv)",
|
||||
tertiaryInv: "var(--tertiaryInv)"
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [require('@tailwindcss/typography')],
|
||||
// trunk-ignore(eslint/no-undef)
|
||||
plugins: [require("@tailwindcss/typography")]
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue