diff --git a/.github/workflows/crowdin-download.yml b/.github/workflows/crowdin-download.yml index a7fb3fd7c..d048fd8ae 100644 --- a/.github/workflows/crowdin-download.yml +++ b/.github/workflows/crowdin-download.yml @@ -17,7 +17,7 @@ jobs: uses: crowdin/github-action@v2 with: base_url: "https://meshtastic.crowdin.com/api/v2" - config: "./packages/web/crowdin.yml" + config: "./apps/web/crowdin.yml" upload_sources: false upload_translations: false download_translations: true diff --git a/.github/workflows/crowdin-upload-sources.yml b/.github/workflows/crowdin-upload-sources.yml index 99c2493c3..2ee766acf 100644 --- a/.github/workflows/crowdin-upload-sources.yml +++ b/.github/workflows/crowdin-upload-sources.yml @@ -5,7 +5,7 @@ on: # Monitor all .json files within the /i18n/locales/en/ directory. # This ensures the workflow triggers if any the English namespace files are modified on the main branch. paths: - - "/packages/web/public/i18n/locales/en/*.json" + - "/apps/web/public/i18n/locales/en/*.json" branches: [main] workflow_dispatch: # Allow manual triggering @@ -21,7 +21,7 @@ jobs: uses: crowdin/github-action@v2 with: base_url: "https://meshtastic.crowdin.com/api/v2" - config: "./packages/web/crowdin.yml" + config: "./apps/web/crowdin.yml" upload_sources: true upload_translations: false download_translations: false diff --git a/.github/workflows/crowdin-upload-translations.yml b/.github/workflows/crowdin-upload-translations.yml index 12bccece2..62a937d6b 100644 --- a/.github/workflows/crowdin-upload-translations.yml +++ b/.github/workflows/crowdin-upload-translations.yml @@ -15,7 +15,7 @@ jobs: uses: crowdin/github-action@v2 with: base_url: "https://meshtastic.crowdin.com/api/v2" - config: "./packages/web/crowdin.yml" + config: "./apps/web/crowdin.yml" upload_sources: false upload_translations: true download_translations: false diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 5da64a4e3..c30d6670e 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -39,18 +39,18 @@ jobs: run: pnpm run test - name: Build web package - working-directory: packages/web + working-directory: apps/web run: pnpm run build - name: Package output - working-directory: packages/web + working-directory: apps/web run: pnpm run package - name: Upload compressed build (artifact) uses: actions/upload-artifact@v4 with: name: web-build-nightly - path: packages/web/dist/build.tar + path: apps/web/dist/build.tar if-no-files-found: error - name: Compute tags and labels @@ -66,8 +66,8 @@ jobs: # Try to use latest release tag if it exists; fallback to package version; else date LATEST_TAG="$(gh release view --json tagName --jq .tagName 2>/dev/null || true)" - if [ -z "$LATEST_TAG" ] && [ -f packages/web/package.json ]; then - LATEST_TAG="v$(jq -r .version packages/web/package.json)" + if [ -z "$LATEST_TAG" ] && [ -f apps/web/package.json ]; then + LATEST_TAG="v$(jq -r .version apps/web/package.json)" fi if [ -n "${LATEST_TAG:-}" ] && [ "$LATEST_TAG" != "vnull" ]; then @@ -91,7 +91,7 @@ jobs: uses: redhat-actions/buildah-build@v2 with: containerfiles: | - ./packages/web/infra/Containerfile + ./apps/web/infra/Containerfile image: ${{ env.REGISTRY_IMAGE }} tags: | ${{ steps.meta.outputs.moving_tag }} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 204ff2782..9f728449b 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -51,4 +51,4 @@ jobs: run: pnpm run test - name: Build web package - run: pnpm --filter "./packages/web" run build + run: pnpm --filter "./apps/web" run build diff --git a/.github/workflows/release-packages.yml b/.github/workflows/release-packages.yml index 58a4920d2..ad02203d2 100644 --- a/.github/workflows/release-packages.yml +++ b/.github/workflows/release-packages.yml @@ -46,7 +46,7 @@ jobs: run: | set -euo pipefail if [ "${{ github.event.inputs.packages }}" = "all" ] || [ -z "${{ github.event.inputs.packages }}" ]; then - mapfile -t TARGETS < <(ls -d packages/* | grep -v 'packages/web') + mapfile -t TARGETS < <(ls -d packages/*) else IFS=',' read -ra TARGETS <<< "${{ github.event.inputs.packages }}" TARGETS=("${TARGETS[@]/#/packages/}") diff --git a/.github/workflows/release-web.yml b/.github/workflows/release-web.yml index 10bd8f353..cdc52c852 100644 --- a/.github/workflows/release-web.yml +++ b/.github/workflows/release-web.yml @@ -51,25 +51,25 @@ jobs: run: pnpm install --frozen-lockfile - name: Build web package - working-directory: packages/web + working-directory: apps/web run: pnpm run build - name: Create release archive - working-directory: packages/web + working-directory: apps/web run: pnpm run package - name: Upload archive (artifact) uses: actions/upload-artifact@v4 with: name: web-build - path: packages/web/dist/build.tar + path: apps/web/dist/build.tar if-no-files-found: error - name: Attach archive to GitHub Release if: ${{ github.event_name == 'release' || inputs.attach_to_release == true }} uses: softprops/action-gh-release@v2 with: - files: packages/web/dist/build.tar + files: apps/web/dist/build.tar tag_name: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.tag_name }} fail_on_unmatched_files: true env: @@ -134,7 +134,7 @@ jobs: uses: docker/build-push-action@v6 with: context: . - file: ./packages/web/infra/Containerfile + file: ./apps/web/infra/Containerfile platforms: linux/amd64,linux/arm64,linux/arm/v7 push: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.tag_name != '') }} tags: ${{ steps.meta.outputs.tags }} diff --git a/.gitignore b/.gitignore index 7c03ebef4..be3f9c39a 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,6 @@ packages/protobufs/packages/ts/dist *.pem *.crt *.key + +# Claude Code session locks +.claude/ diff --git a/.vscode/extensions.json b/.vscode/extensions.json index e11f647b3..858ea5ba1 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,3 +1,3 @@ { - "recommendations": ["bradlc.vscode-tailwindcss", "biomejs.biome"] + "recommendations": ["bradlc.vscode-tailwindcss", "oxc.oxc-vscode"] } diff --git a/README.md b/README.md index 0791b1a41..577e7efaa 100644 --- a/README.md +++ b/README.md @@ -9,89 +9,163 @@ ## Overview This monorepo consolidates the official [Meshtastic](https://meshtastic.org) web -interface and its supporting JavaScript libraries. It aims to provide a unified -development experience for interacting with Meshtastic devices. +interface, the domain-driven JavaScript SDK that drives it, and a set of +runtime-specific transport packages. Everything you need to read state from or +send commands to a Meshtastic device lives here. > [!NOTE] > You can find the main Meshtastic documentation at https://meshtastic.org/docs/introduction/. -### Projects within this Monorepo (`packages/`) +## Packages + +All projects live under `packages/`. + +| Package | Purpose | +| --- | --- | +| `packages/sdk` | Framework-agnostic TypeScript SDK. Domain-driven feature slices (device, chat, nodes, channels, config, telemetry, position, traceroute, files) built around a `MeshClient` orchestrator with `@preact/signals-core` reactive state. | +| `packages/sdk-react` | React hooks + `MeshProvider` on top of `@meshtastic/sdk`. Wraps signals in `useSyncExternalStore` for concurrent-safe renders. | +| `apps/web` | Reference React web client. Hosted at [client.meshtastic.org](https://client.meshtastic.org). | +| `packages/ui` | Shared Radix + Tailwind component library. | +| `packages/protobufs` | Generated TypeScript stubs from [`meshtastic/protobufs`](https://github.com/meshtastic/protobufs), produced via `buf generate`. Source of truth for every wire-level type. | +| `packages/transport-http` | HTTP transport for devices exposing a network interface. | +| `packages/transport-web-bluetooth` | Web Bluetooth transport for BLE-capable devices (browsers). | +| `packages/transport-web-serial` | Web Serial transport for USB-serial devices (browsers). | +| `packages/transport-node` | TCP transport for Node.js. | +| `packages/transport-node-serial` | Serial transport for Node.js. | +| `packages/transport-deno` | TCP transport for Deno. | +| `packages/transport-mock` | In-memory transport for tests. | + +All publishable packages ship to both [JSR](https://jsr.io/@meshtastic) and [NPM](https://www.npmjs.com/org/meshtastic). + +## Architecture + +`@meshtastic/sdk` organises its source by feature slice. Each slice follows the +same DDD layout: + +``` +features// + domain/ # entities & value objects — pure TypeScript types + application/ # use-cases (SendTextUseCase, FavoriteNodeUseCase, …) + infrastructure/ # protobuf ↔ domain mappers, admin-message adapters + state/ # signals-backed reactive stores + Client.ts # public facade exposing readable signals + command methods + index.ts +``` + +The shared kernel under `packages/sdk/src/core/` owns: + +- **`client/`** — `MeshClient`, the thin orchestrator that owns the transport, queue, event bus, and one instance of every slice client. +- **`transport/`** — the `Transport` interface every `transport-*` package implements. +- **`event-bus/`** — typed pub/sub channels populated by the packet codec. +- **`packet-codec/`** — frame parser (0x94 0xC3), `FromRadio` decoder, portnum router. +- **`queue/`**, **`xmodem/`** — packet ack/timeout pipeline and file-transfer protocol. +- **`signals/`** — signal and keyed-collection helpers consumed by every slice. +- **`logging/`** — `tslog` factory used consistently by every class. +- **`identifiers/`**, **`errors/`** — small primitives shared across slices. + +The protobuf boundary is strict: wire messages enter through the packet codec, +get mapped into domain entities inside `features/*/infrastructure/*Mapper.ts`, +and signals only ever expose the domain shape. + +``` + Transport ─▶ Packet codec ─▶ EventBus ─▶ Slice infrastructure + │ + ▼ + Signals (state) ─▶ sdk-react hooks ─▶ UI + ▲ + │ + Slice application (use-cases) ─▶ MeshClient.sendPacket ─▶ Queue ─▶ Transport +``` + +Expected domain errors are returned as `Result` via [`better-result`](https://www.npmjs.com/package/better-result); exceptions are reserved for programmer errors and truly exceptional conditions. -All projects are located within the `packages/` directory: +## Getting Started -- **`packages/web` (Meshtastic Web Client):** The official web interface, - designed to be hosted or served directly from a Meshtastic node. - - **[Hosted version](https://client.meshtastic.org)** -- **`packages/core`:** Core functionality for Meshtastic JS. -- **`packages/transport-node`:** TCP Transport for the NodeJS runtime. -- **`packages/transport-node-serial`:** NodeJS Serial Transport for the NodeJS runtime. -- **`packages/transport-deno`:** TCP Transport for the Deno runtime. -- **`packages/transport-http`:** HTTP Transport. -- **`packages/transport-web-bluetooth`:** Web Bluetooth Transport. -- **`packages/transport-web-serial`:** Web Serial Transport. -- **`packages/protobufs`:** Git submodule containing Meshtastic’s shared protobuf definitions, used to generate and publish the JSR protobuf package. +### Prerequisites -All `Meshtastic JS` packages (core and transports) are published both to -[JSR](https://jsr.io/@meshtastic). [NPM](https://www.npmjs.com/org/meshtastic) +You need [pnpm](https://pnpm.io/) installed. If you plan to regenerate +protobufs, also install the [Buf CLI](https://buf.build/docs/cli/installation/). ---- +### Setup -## Repository activity +```bash +git clone https://github.com/meshtastic/web.git +cd web +pnpm install +``` -| Project | Repobeats | -| :------------- | :-------------------------------------------------------------------------------------------------------------------- | -| Meshtastic Web | ![Alt](https://repobeats.axiom.co/api/embed/e5b062db986cb005d83e81724c00cb2b9cce8e4c.svg "Repobeats analytics image") | +### Run the web client ---- +```bash +pnpm --filter @meshtastic/web dev +``` -## Tech Stack +### Build everything -This monorepo leverages the following technologies: +```bash +pnpm -r build +``` -- **Runtime:** pnpm / Deno -- **Web Client:** React.js -- **Styling:** Tailwind CSS -- **Bundling:** Vite -- **Language:** TypeScript -- **Testing:** Vitest, React Testing Library +### Run tests ---- +```bash +pnpm -r test +``` -## Getting Started +### Lint + format -### Prerequisites +```bash +pnpm check +pnpm check:fix +``` + +## Developing + +### Adding a new feature slice to `@meshtastic/sdk` + +1. Create `packages/sdk/src/features//` with `domain/`, `application/`, `infrastructure/`, `state/` subdirectories plus an `index.ts` barrel. +2. Implement a signals-backed store in `state/`. +3. Subscribe to the relevant `EventBus` channel(s) inside a `Client.ts` class and write mapped domain entities to the store. +4. Wire the new client into `MeshClient` and re-export types from `packages/sdk/mod.ts`. +5. Add vitest coverage: domain invariants, use-cases against `createFakeTransport()`, and round-trip mapper fixtures. +6. If the slice has React callers, add a matching hook under `packages/sdk-react/src/hooks/`. -You'll need to have [pnpm](https://pnpm.io/) installed to work with this monorepo. -Follow the installation instructions on their home page. +### Adding a new transport -### Development Setup +Implement the `Transport` interface exported from `@meshtastic/sdk/transport`: -1. **Clone the repository:** - ```bash - git clone https://github.com/meshtastic/meshtastic-web.git - cd meshtastic-web - ``` -2. **Install dependencies for all packages:** - ```bash - pnpm install - ``` - This command installs all necessary dependencies for all packages within the - monorepo. -3. **Install the Buf CLI** - Required for building `packages/protobufs` - https://buf.build/docs/cli/installation/ +```ts +interface Transport { + toDevice: WritableStream; + fromDevice: ReadableStream; + disconnect(): Promise; +} +``` -### Running Projects +The SDK does the framing and decoding — transports only supply raw bytes. -#### Meshtastic Web Client +### Testing -Please refer to the [Meshtastic Web README](packages/web/README.md) for setup and usage. +Vitest is wired at the repo root and picks up `packages/*` projects. The SDK +ships `@meshtastic/sdk/testing` with `createFakeTransport()` for wiring tests +without real hardware. -### Feedback +## Publishing + +Each publishable package has `build:npm` / `publish:npm` / `prepare:jsr` / +`publish:jsr` scripts. See each package's `package.json` for details. + +## Repository activity + +| Project | Repobeats | +| :------------- | :-------------------------------------------------------------------------------------------------------------------- | +| Meshtastic Web | ![Alt](https://repobeats.axiom.co/api/embed/e5b062db986cb005d83e81724c00cb2b9cce8e4c.svg "Repobeats analytics image") | + +## Feedback If you encounter any issues, please report them in our [issues tracker](https://github.com/meshtastic/web/issues). Your feedback helps -improve the stability of future releases +improve the stability of future releases. ## Star history @@ -108,3 +182,7 @@ improve the stability of future releases + +## License + +GPL-3.0-only. See [LICENSE](LICENSE). diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 000000000..00cb21a7c --- /dev/null +++ b/TESTING.md @@ -0,0 +1,83 @@ +# Testing strategy + +How this monorepo proves correctness, and where coverage currently sits. + +## Levels + +Tests live in five tiers. Each PR should add coverage at the **lowest level that catches the regression**, and only climb tiers when that's not possible. + +| Tier | Scope | Tooling | Where | +| --- | --- | --- | --- | +| 1. **Unit** | Pure functions, value objects, mappers, single classes with mocked deps | `vitest run` (Node env) | `*.test.ts` colocated with source | +| 2. **Slice integration** | Use-case + store + mapper exercised against in-memory deps; assert outbound bytes and signal state | `vitest` + `createFakeTransport()` | `*.test.ts` in slice dirs | +| 3. **Client integration** | `MeshClient` end-to-end with a fake transport feeding canned `FromRadio` packets | `vitest` + `@meshtastic/sdk/testing` | `packages/sdk/tests/integration/` | +| 4. **Storage integration** | Real Drizzle queries against sql.js in-memory; or against `@vitest/browser` for OPFS | `vitest` (Node + browser) | `packages/sdk-storage-sqlocal/{src,tests}` | +| 5. **Hook / DOM** | React hooks render under `` / ``, react to signals | `vitest` + `@testing-library/react` + `jsdom` | `packages/sdk-react/tests/` | +| 6. **E2E / simulator** | Whole stack: SDK → transport → simulator/firmware. Catches protocol drift | `@vitest/browser` for OPFS; `meshtasticd` simulator over TCP for protocol | future `tests/e2e/` | + +## Per-package coverage gates + +| Package | Required floor | Notes | +| --- | --- | --- | +| `packages/sdk/core` | every primitive (signals, EventBus, Queue, packet-codec, identifiers) has a unit test; lifecycle covered by `MeshClient.test.ts` | adopt `c8` thresholds once stable | +| `packages/sdk/features/*` | each slice ships: 1 domain invariant test, 1 use-case test against fake transport, 1 mapper round-trip (where mappers exist) | Integration covered by `tests/integration/fake-transport.test.ts` | +| `packages/sdk-react` | each public hook has a `renderHook` test that asserts initial render + re-render on signal change | uses jsdom; provider wrapper required | +| `packages/sdk-storage-sqlocal` | every repository method tested against sql.js in-memory; **at least one OPFS-real test per repo** runs in browser mode | sql.js validates SQL correctness; OPFS validates VFS / Worker plumbing | +| `packages/transport-*` | minimum: framing round-trip, disconnect cleans up streams, error path emits status | low-level; ship as is | +| `packages/web` | component tests at `34` baseline; new SDK-driven UI components must add a hook-mock test | currently all green | + +## Current state (audit) + +| Package | Test files | Tests pass | Gaps | +| --- | --- | --- | --- | +| `packages/sdk` | 7 | 25 ✅ | nodes/channels/config/telemetry/position/traceroute/files slices have **no tests**; no `MeshClient` lifecycle test (only fake-transport integration); no schema migration test | +| `packages/sdk-react` | 1 | 2 ✅ | only `useMeshDevice` + a stubbed `useChat` test; missing `useNodes`, `useChannels`, `useConfig`, `useConnection`, `useTraceroute`, `useTelemetry`, `usePosition`, `useFileTransfer`, `useFavoriteNode`, `useIgnoreNode`, `useMeshRegistry`, `useClientById`, `useActiveClient`. No registry-aware re-render coverage. | +| `packages/sdk-storage-sqlocal` | 2 | 8 ✅ | sql.js only — **no real OPFS test**, no Worker boot test, no cross-tab BroadcastChannel test (mocked away), no migration v1→v2 test | +| `packages/web` | 34 | 294 ✅ | no `useConnections` test; new `meshRegistry` + `sdkStorage` modules untested; chat persistence end-to-end not exercised | +| `packages/transport-*` | 1 each (5 of 7) | varies | `transport-deno` + `transport-mock` have no tests; transports likely lack disconnect/error coverage | +| `packages/core` | 0 | n/a | legacy, slated for deletion in Phase C; tolerable | +| `packages/ui` | 0 | n/a | pure presentational; visual regression only | +| `packages/protobufs` | 0 | n/a | generated code; upstream's responsibility | + +## Concrete additions queued (priority order) + +1. **`packages/sdk` slice tests** — one Use-case + one Mapper test per slice (`nodes`, `channels`, `config`, `telemetry`, `position`, `traceroute`). Pattern: build a stub `MeshClient`, dispatch a synthetic event, assert signal value or outbound bytes. +2. **`packages/sdk-react` hook tests** — for every hook listed above, mount under ``, drive a signal change, assert `result.current`. One file, ~15 cases. +3. **`packages/sdk` `ChatClient` persistence test** — wire `InMemoryMessageRepository`, append messages, re-construct `ChatClient`, assert hydration. Validates the lazy-load contract. +4. **`packages/sdk-storage-sqlocal` migration test** — bootstrap empty DB, run `MIGRATIONS[]`, assert `_schema.version`. Then add a fake `version: 2` migration and prove it's applied idempotently. +5. **`packages/sdk-storage-sqlocal` browser mode** — add a second `vitest.browser.config.ts` using `@vitest/browser` (Playwright provider) so we exercise real OPFS + Worker. CI runs both modes. +6. **`packages/sdk-storage-sqlocal` BroadcastChannel test** — instantiate two `MultiTabCoordinator` instances in same process; one broadcasts, the other observes. (Node has no `BroadcastChannel` global; use `worker_threads`'s `BroadcastChannel` polyfill or jsdom env.) +7. **`packages/web` `meshRegistry` + `sdkStorage` lazy-init test** — assert `getStorageDb()` returns the same promise on repeated calls and only opens the DB once. +8. **`packages/sdk-react` registry test** — mount `` with two clients, switch active, confirm a hook re-renders against the new client. + +## E2E / simulator (Tier 6) — scope only + +Out of immediate scope; documenting for a follow-up PR. + +- Run `meshtasticd` (firmware simulator) in CI Docker via `services:` block. +- Spin up `MeshClient` with `TransportHTTP` pointed at the simulator's HTTP endpoint. +- Drive scripted scenarios: configure → send text → expect ack; channel update; node info exchange; traceroute. +- Use `@vitest/browser` so we also exercise the real OPFS persistence path during E2E. +- Run on `main` only (cost). Smoke subset on PR. + +Until that lands, `createFakeTransport()` covers the protocol layer at unit/integration speed. + +## Conventions + +- Test file colocated with source: `Foo.ts` → `Foo.test.ts`. +- Integration tests under `tests/integration/`. +- Browser-mode tests use the suffix `.browser.test.ts` so they can be filtered. +- Protobuf fixtures live in `__fixtures__/*.fixtures.ts` next to mappers; binary data committed as base64, not raw bytes. +- Each test imports concrete classes from the source path (`./Foo.ts`), not the package barrel — fast type-check, zero re-export drift. +- No mocked SDK from inside SDK tests. Use `createFakeTransport()` and real `MeshClient` instances. + +## Running + +```sh +pnpm -r test # all packages, Node env +pnpm --filter @meshtastic/sdk test +pnpm --filter @meshtastic/sdk-storage-sqlocal test +pnpm --filter meshtastic-web test +# future: +pnpm --filter @meshtastic/sdk-storage-sqlocal test:browser +``` diff --git a/packages/web/.npmrc b/apps/web/.npmrc similarity index 100% rename from packages/web/.npmrc rename to apps/web/.npmrc diff --git a/packages/web/.oxfmtrc.json b/apps/web/.oxfmtrc.json similarity index 100% rename from packages/web/.oxfmtrc.json rename to apps/web/.oxfmtrc.json diff --git a/packages/web/.oxlintrc.json b/apps/web/.oxlintrc.json similarity index 100% rename from packages/web/.oxlintrc.json rename to apps/web/.oxlintrc.json diff --git a/packages/web/CONTRIBUTING.md b/apps/web/CONTRIBUTING.md similarity index 100% rename from packages/web/CONTRIBUTING.md rename to apps/web/CONTRIBUTING.md diff --git a/packages/web/CONTRIBUTING_I18N_DEVELOPER_GUIDE.md b/apps/web/CONTRIBUTING_I18N_DEVELOPER_GUIDE.md similarity index 100% rename from packages/web/CONTRIBUTING_I18N_DEVELOPER_GUIDE.md rename to apps/web/CONTRIBUTING_I18N_DEVELOPER_GUIDE.md diff --git a/packages/web/CONTRIBUTING_TRANSLATIONS.md b/apps/web/CONTRIBUTING_TRANSLATIONS.md similarity index 100% rename from packages/web/CONTRIBUTING_TRANSLATIONS.md rename to apps/web/CONTRIBUTING_TRANSLATIONS.md diff --git a/packages/web/README.md b/apps/web/README.md similarity index 100% rename from packages/web/README.md rename to apps/web/README.md diff --git a/packages/web/crowdin.yml b/apps/web/crowdin.yml similarity index 100% rename from packages/web/crowdin.yml rename to apps/web/crowdin.yml diff --git a/packages/web/index.html b/apps/web/index.html similarity index 100% rename from packages/web/index.html rename to apps/web/index.html diff --git a/packages/web/infra/.dockerignore b/apps/web/infra/.dockerignore similarity index 100% rename from packages/web/infra/.dockerignore rename to apps/web/infra/.dockerignore diff --git a/packages/web/infra/Containerfile b/apps/web/infra/Containerfile similarity index 100% rename from packages/web/infra/Containerfile rename to apps/web/infra/Containerfile diff --git a/packages/web/infra/default.conf b/apps/web/infra/default.conf similarity index 100% rename from packages/web/infra/default.conf rename to apps/web/infra/default.conf diff --git a/packages/web/package.json b/apps/web/package.json similarity index 96% rename from packages/web/package.json rename to apps/web/package.json index ff938a208..a09ac7874 100644 --- a/packages/web/package.json +++ b/apps/web/package.json @@ -33,7 +33,9 @@ }, "dependencies": { "@hookform/resolvers": "^5.2.2", - "@meshtastic/core": "workspace:*", + "@meshtastic/sdk": "workspace:*", + "@meshtastic/sdk-react": "workspace:*", + "@meshtastic/sdk-storage-sqlocal": "workspace:*", "@meshtastic/transport-http": "workspace:*", "@meshtastic/transport-web-bluetooth": "workspace:*", "@meshtastic/transport-web-serial": "workspace:*", diff --git a/packages/web/public/apple-touch-icon.png b/apps/web/public/apple-touch-icon.png similarity index 100% rename from packages/web/public/apple-touch-icon.png rename to apps/web/public/apple-touch-icon.png diff --git a/packages/web/public/chirpy.svg b/apps/web/public/chirpy.svg similarity index 100% rename from packages/web/public/chirpy.svg rename to apps/web/public/chirpy.svg diff --git a/packages/web/public/devices/diy.svg b/apps/web/public/devices/diy.svg similarity index 100% rename from packages/web/public/devices/diy.svg rename to apps/web/public/devices/diy.svg diff --git a/packages/web/public/devices/heltec-ht62-esp32c3-sx1262.svg b/apps/web/public/devices/heltec-ht62-esp32c3-sx1262.svg similarity index 100% rename from packages/web/public/devices/heltec-ht62-esp32c3-sx1262.svg rename to apps/web/public/devices/heltec-ht62-esp32c3-sx1262.svg diff --git a/packages/web/public/devices/heltec-mesh-node-t114-case.svg b/apps/web/public/devices/heltec-mesh-node-t114-case.svg similarity index 100% rename from packages/web/public/devices/heltec-mesh-node-t114-case.svg rename to apps/web/public/devices/heltec-mesh-node-t114-case.svg diff --git a/packages/web/public/devices/heltec-mesh-node-t114.svg b/apps/web/public/devices/heltec-mesh-node-t114.svg similarity index 100% rename from packages/web/public/devices/heltec-mesh-node-t114.svg rename to apps/web/public/devices/heltec-mesh-node-t114.svg diff --git a/packages/web/public/devices/heltec-v3-case.svg b/apps/web/public/devices/heltec-v3-case.svg similarity index 100% rename from packages/web/public/devices/heltec-v3-case.svg rename to apps/web/public/devices/heltec-v3-case.svg diff --git a/packages/web/public/devices/heltec-v3.svg b/apps/web/public/devices/heltec-v3.svg similarity index 100% rename from packages/web/public/devices/heltec-v3.svg rename to apps/web/public/devices/heltec-v3.svg diff --git a/packages/web/public/devices/heltec-vision-master-e213.svg b/apps/web/public/devices/heltec-vision-master-e213.svg similarity index 100% rename from packages/web/public/devices/heltec-vision-master-e213.svg rename to apps/web/public/devices/heltec-vision-master-e213.svg diff --git a/packages/web/public/devices/heltec-vision-master-e290.svg b/apps/web/public/devices/heltec-vision-master-e290.svg similarity index 100% rename from packages/web/public/devices/heltec-vision-master-e290.svg rename to apps/web/public/devices/heltec-vision-master-e290.svg diff --git a/packages/web/public/devices/heltec-vision-master-t190.svg b/apps/web/public/devices/heltec-vision-master-t190.svg similarity index 100% rename from packages/web/public/devices/heltec-vision-master-t190.svg rename to apps/web/public/devices/heltec-vision-master-t190.svg diff --git a/packages/web/public/devices/heltec-wireless-paper-V1_0.svg b/apps/web/public/devices/heltec-wireless-paper-V1_0.svg similarity index 100% rename from packages/web/public/devices/heltec-wireless-paper-V1_0.svg rename to apps/web/public/devices/heltec-wireless-paper-V1_0.svg diff --git a/packages/web/public/devices/heltec-wireless-paper.svg b/apps/web/public/devices/heltec-wireless-paper.svg similarity index 100% rename from packages/web/public/devices/heltec-wireless-paper.svg rename to apps/web/public/devices/heltec-wireless-paper.svg diff --git a/packages/web/public/devices/heltec-wireless-tracker-V1-0.svg b/apps/web/public/devices/heltec-wireless-tracker-V1-0.svg similarity index 100% rename from packages/web/public/devices/heltec-wireless-tracker-V1-0.svg rename to apps/web/public/devices/heltec-wireless-tracker-V1-0.svg diff --git a/packages/web/public/devices/heltec-wireless-tracker.svg b/apps/web/public/devices/heltec-wireless-tracker.svg similarity index 100% rename from packages/web/public/devices/heltec-wireless-tracker.svg rename to apps/web/public/devices/heltec-wireless-tracker.svg diff --git a/packages/web/public/devices/heltec-wsl-v3.svg b/apps/web/public/devices/heltec-wsl-v3.svg similarity index 100% rename from packages/web/public/devices/heltec-wsl-v3.svg rename to apps/web/public/devices/heltec-wsl-v3.svg diff --git a/packages/web/public/devices/nano-g2-ultra.svg b/apps/web/public/devices/nano-g2-ultra.svg similarity index 100% rename from packages/web/public/devices/nano-g2-ultra.svg rename to apps/web/public/devices/nano-g2-ultra.svg diff --git a/packages/web/public/devices/pico.svg b/apps/web/public/devices/pico.svg similarity index 100% rename from packages/web/public/devices/pico.svg rename to apps/web/public/devices/pico.svg diff --git a/packages/web/public/devices/promicro.svg b/apps/web/public/devices/promicro.svg similarity index 100% rename from packages/web/public/devices/promicro.svg rename to apps/web/public/devices/promicro.svg diff --git a/packages/web/public/devices/rak-wismeshtap.svg b/apps/web/public/devices/rak-wismeshtap.svg similarity index 100% rename from packages/web/public/devices/rak-wismeshtap.svg rename to apps/web/public/devices/rak-wismeshtap.svg diff --git a/packages/web/public/devices/rak11310.svg b/apps/web/public/devices/rak11310.svg similarity index 100% rename from packages/web/public/devices/rak11310.svg rename to apps/web/public/devices/rak11310.svg diff --git a/packages/web/public/devices/rak2560.svg b/apps/web/public/devices/rak2560.svg similarity index 100% rename from packages/web/public/devices/rak2560.svg rename to apps/web/public/devices/rak2560.svg diff --git a/packages/web/public/devices/rak4631.svg b/apps/web/public/devices/rak4631.svg similarity index 100% rename from packages/web/public/devices/rak4631.svg rename to apps/web/public/devices/rak4631.svg diff --git a/packages/web/public/devices/rak4631_case.svg b/apps/web/public/devices/rak4631_case.svg similarity index 100% rename from packages/web/public/devices/rak4631_case.svg rename to apps/web/public/devices/rak4631_case.svg diff --git a/packages/web/public/devices/rpipicow.svg b/apps/web/public/devices/rpipicow.svg similarity index 100% rename from packages/web/public/devices/rpipicow.svg rename to apps/web/public/devices/rpipicow.svg diff --git a/packages/web/public/devices/seeed-sensecap-indicator.svg b/apps/web/public/devices/seeed-sensecap-indicator.svg similarity index 100% rename from packages/web/public/devices/seeed-sensecap-indicator.svg rename to apps/web/public/devices/seeed-sensecap-indicator.svg diff --git a/packages/web/public/devices/seeed-xiao-s3.svg b/apps/web/public/devices/seeed-xiao-s3.svg similarity index 100% rename from packages/web/public/devices/seeed-xiao-s3.svg rename to apps/web/public/devices/seeed-xiao-s3.svg diff --git a/packages/web/public/devices/station-g2.svg b/apps/web/public/devices/station-g2.svg similarity index 100% rename from packages/web/public/devices/station-g2.svg rename to apps/web/public/devices/station-g2.svg diff --git a/packages/web/public/devices/t-deck.svg b/apps/web/public/devices/t-deck.svg similarity index 100% rename from packages/web/public/devices/t-deck.svg rename to apps/web/public/devices/t-deck.svg diff --git a/packages/web/public/devices/t-echo.svg b/apps/web/public/devices/t-echo.svg similarity index 100% rename from packages/web/public/devices/t-echo.svg rename to apps/web/public/devices/t-echo.svg diff --git a/packages/web/public/devices/t-watch-s3.svg b/apps/web/public/devices/t-watch-s3.svg similarity index 100% rename from packages/web/public/devices/t-watch-s3.svg rename to apps/web/public/devices/t-watch-s3.svg diff --git a/packages/web/public/devices/tbeam-s3-core.svg b/apps/web/public/devices/tbeam-s3-core.svg similarity index 100% rename from packages/web/public/devices/tbeam-s3-core.svg rename to apps/web/public/devices/tbeam-s3-core.svg diff --git a/packages/web/public/devices/tbeam.svg b/apps/web/public/devices/tbeam.svg similarity index 100% rename from packages/web/public/devices/tbeam.svg rename to apps/web/public/devices/tbeam.svg diff --git a/packages/web/public/devices/tlora-c6.svg b/apps/web/public/devices/tlora-c6.svg similarity index 100% rename from packages/web/public/devices/tlora-c6.svg rename to apps/web/public/devices/tlora-c6.svg diff --git a/packages/web/public/devices/tlora-t3s3-epaper.svg b/apps/web/public/devices/tlora-t3s3-epaper.svg similarity index 100% rename from packages/web/public/devices/tlora-t3s3-epaper.svg rename to apps/web/public/devices/tlora-t3s3-epaper.svg diff --git a/packages/web/public/devices/tlora-t3s3-v1.svg b/apps/web/public/devices/tlora-t3s3-v1.svg similarity index 100% rename from packages/web/public/devices/tlora-t3s3-v1.svg rename to apps/web/public/devices/tlora-t3s3-v1.svg diff --git a/packages/web/public/devices/tlora-v2-1-1_6.svg b/apps/web/public/devices/tlora-v2-1-1_6.svg similarity index 100% rename from packages/web/public/devices/tlora-v2-1-1_6.svg rename to apps/web/public/devices/tlora-v2-1-1_6.svg diff --git a/packages/web/public/devices/tlora-v2-1-1_8.svg b/apps/web/public/devices/tlora-v2-1-1_8.svg similarity index 100% rename from packages/web/public/devices/tlora-v2-1-1_8.svg rename to apps/web/public/devices/tlora-v2-1-1_8.svg diff --git a/packages/web/public/devices/tracker-t1000-e.svg b/apps/web/public/devices/tracker-t1000-e.svg similarity index 100% rename from packages/web/public/devices/tracker-t1000-e.svg rename to apps/web/public/devices/tracker-t1000-e.svg diff --git a/packages/web/public/devices/unknown.svg b/apps/web/public/devices/unknown.svg similarity index 100% rename from packages/web/public/devices/unknown.svg rename to apps/web/public/devices/unknown.svg diff --git a/packages/web/public/devices/wio-tracker-wm1110.svg b/apps/web/public/devices/wio-tracker-wm1110.svg similarity index 100% rename from packages/web/public/devices/wio-tracker-wm1110.svg rename to apps/web/public/devices/wio-tracker-wm1110.svg diff --git a/packages/web/public/devices/wm1110_dev_kit.svg b/apps/web/public/devices/wm1110_dev_kit.svg similarity index 100% rename from packages/web/public/devices/wm1110_dev_kit.svg rename to apps/web/public/devices/wm1110_dev_kit.svg diff --git a/packages/web/public/favicon.ico b/apps/web/public/favicon.ico similarity index 100% rename from packages/web/public/favicon.ico rename to apps/web/public/favicon.ico diff --git a/packages/web/public/fonts/InterVariable-Italic.woff2 b/apps/web/public/fonts/InterVariable-Italic.woff2 similarity index 100% rename from packages/web/public/fonts/InterVariable-Italic.woff2 rename to apps/web/public/fonts/InterVariable-Italic.woff2 diff --git a/packages/web/public/fonts/InterVariable.woff2 b/apps/web/public/fonts/InterVariable.woff2 similarity index 100% rename from packages/web/public/fonts/InterVariable.woff2 rename to apps/web/public/fonts/InterVariable.woff2 diff --git a/packages/web/public/i18n/locales/be-BY/channels.json b/apps/web/public/i18n/locales/be-BY/channels.json similarity index 100% rename from packages/web/public/i18n/locales/be-BY/channels.json rename to apps/web/public/i18n/locales/be-BY/channels.json diff --git a/packages/web/public/i18n/locales/be-BY/commandPalette.json b/apps/web/public/i18n/locales/be-BY/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/be-BY/commandPalette.json rename to apps/web/public/i18n/locales/be-BY/commandPalette.json diff --git a/packages/web/public/i18n/locales/be-BY/common.json b/apps/web/public/i18n/locales/be-BY/common.json similarity index 100% rename from packages/web/public/i18n/locales/be-BY/common.json rename to apps/web/public/i18n/locales/be-BY/common.json diff --git a/packages/web/public/i18n/locales/be-BY/config.json b/apps/web/public/i18n/locales/be-BY/config.json similarity index 100% rename from packages/web/public/i18n/locales/be-BY/config.json rename to apps/web/public/i18n/locales/be-BY/config.json diff --git a/packages/web/public/i18n/locales/be-BY/connections.json b/apps/web/public/i18n/locales/be-BY/connections.json similarity index 100% rename from packages/web/public/i18n/locales/be-BY/connections.json rename to apps/web/public/i18n/locales/be-BY/connections.json diff --git a/packages/web/public/i18n/locales/be-BY/deviceConfig.json b/apps/web/public/i18n/locales/be-BY/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/be-BY/deviceConfig.json rename to apps/web/public/i18n/locales/be-BY/deviceConfig.json diff --git a/packages/web/public/i18n/locales/be-BY/dialog.json b/apps/web/public/i18n/locales/be-BY/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/be-BY/dialog.json rename to apps/web/public/i18n/locales/be-BY/dialog.json diff --git a/packages/web/public/i18n/locales/be-BY/map.json b/apps/web/public/i18n/locales/be-BY/map.json similarity index 100% rename from packages/web/public/i18n/locales/be-BY/map.json rename to apps/web/public/i18n/locales/be-BY/map.json diff --git a/packages/web/public/i18n/locales/be-BY/messages.json b/apps/web/public/i18n/locales/be-BY/messages.json similarity index 100% rename from packages/web/public/i18n/locales/be-BY/messages.json rename to apps/web/public/i18n/locales/be-BY/messages.json diff --git a/packages/web/public/i18n/locales/be-BY/moduleConfig.json b/apps/web/public/i18n/locales/be-BY/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/be-BY/moduleConfig.json rename to apps/web/public/i18n/locales/be-BY/moduleConfig.json diff --git a/packages/web/public/i18n/locales/be-BY/nodes.json b/apps/web/public/i18n/locales/be-BY/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/be-BY/nodes.json rename to apps/web/public/i18n/locales/be-BY/nodes.json diff --git a/packages/web/public/i18n/locales/be-BY/ui.json b/apps/web/public/i18n/locales/be-BY/ui.json similarity index 100% rename from packages/web/public/i18n/locales/be-BY/ui.json rename to apps/web/public/i18n/locales/be-BY/ui.json diff --git a/packages/web/public/i18n/locales/bg-BG/channels.json b/apps/web/public/i18n/locales/bg-BG/channels.json similarity index 100% rename from packages/web/public/i18n/locales/bg-BG/channels.json rename to apps/web/public/i18n/locales/bg-BG/channels.json diff --git a/packages/web/public/i18n/locales/bg-BG/commandPalette.json b/apps/web/public/i18n/locales/bg-BG/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/bg-BG/commandPalette.json rename to apps/web/public/i18n/locales/bg-BG/commandPalette.json diff --git a/packages/web/public/i18n/locales/bg-BG/common.json b/apps/web/public/i18n/locales/bg-BG/common.json similarity index 100% rename from packages/web/public/i18n/locales/bg-BG/common.json rename to apps/web/public/i18n/locales/bg-BG/common.json diff --git a/packages/web/public/i18n/locales/bg-BG/config.json b/apps/web/public/i18n/locales/bg-BG/config.json similarity index 100% rename from packages/web/public/i18n/locales/bg-BG/config.json rename to apps/web/public/i18n/locales/bg-BG/config.json diff --git a/packages/web/public/i18n/locales/bg-BG/connections.json b/apps/web/public/i18n/locales/bg-BG/connections.json similarity index 100% rename from packages/web/public/i18n/locales/bg-BG/connections.json rename to apps/web/public/i18n/locales/bg-BG/connections.json diff --git a/packages/web/public/i18n/locales/bg-BG/deviceConfig.json b/apps/web/public/i18n/locales/bg-BG/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/bg-BG/deviceConfig.json rename to apps/web/public/i18n/locales/bg-BG/deviceConfig.json diff --git a/packages/web/public/i18n/locales/bg-BG/dialog.json b/apps/web/public/i18n/locales/bg-BG/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/bg-BG/dialog.json rename to apps/web/public/i18n/locales/bg-BG/dialog.json diff --git a/packages/web/public/i18n/locales/bg-BG/map.json b/apps/web/public/i18n/locales/bg-BG/map.json similarity index 100% rename from packages/web/public/i18n/locales/bg-BG/map.json rename to apps/web/public/i18n/locales/bg-BG/map.json diff --git a/packages/web/public/i18n/locales/bg-BG/messages.json b/apps/web/public/i18n/locales/bg-BG/messages.json similarity index 100% rename from packages/web/public/i18n/locales/bg-BG/messages.json rename to apps/web/public/i18n/locales/bg-BG/messages.json diff --git a/packages/web/public/i18n/locales/bg-BG/moduleConfig.json b/apps/web/public/i18n/locales/bg-BG/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/bg-BG/moduleConfig.json rename to apps/web/public/i18n/locales/bg-BG/moduleConfig.json diff --git a/packages/web/public/i18n/locales/bg-BG/nodes.json b/apps/web/public/i18n/locales/bg-BG/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/bg-BG/nodes.json rename to apps/web/public/i18n/locales/bg-BG/nodes.json diff --git a/packages/web/public/i18n/locales/bg-BG/ui.json b/apps/web/public/i18n/locales/bg-BG/ui.json similarity index 100% rename from packages/web/public/i18n/locales/bg-BG/ui.json rename to apps/web/public/i18n/locales/bg-BG/ui.json diff --git a/packages/web/public/i18n/locales/cs-CZ/channels.json b/apps/web/public/i18n/locales/cs-CZ/channels.json similarity index 100% rename from packages/web/public/i18n/locales/cs-CZ/channels.json rename to apps/web/public/i18n/locales/cs-CZ/channels.json diff --git a/packages/web/public/i18n/locales/cs-CZ/commandPalette.json b/apps/web/public/i18n/locales/cs-CZ/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/cs-CZ/commandPalette.json rename to apps/web/public/i18n/locales/cs-CZ/commandPalette.json diff --git a/packages/web/public/i18n/locales/cs-CZ/common.json b/apps/web/public/i18n/locales/cs-CZ/common.json similarity index 100% rename from packages/web/public/i18n/locales/cs-CZ/common.json rename to apps/web/public/i18n/locales/cs-CZ/common.json diff --git a/packages/web/public/i18n/locales/cs-CZ/config.json b/apps/web/public/i18n/locales/cs-CZ/config.json similarity index 100% rename from packages/web/public/i18n/locales/cs-CZ/config.json rename to apps/web/public/i18n/locales/cs-CZ/config.json diff --git a/packages/web/public/i18n/locales/cs-CZ/connections.json b/apps/web/public/i18n/locales/cs-CZ/connections.json similarity index 100% rename from packages/web/public/i18n/locales/cs-CZ/connections.json rename to apps/web/public/i18n/locales/cs-CZ/connections.json diff --git a/packages/web/public/i18n/locales/cs-CZ/deviceConfig.json b/apps/web/public/i18n/locales/cs-CZ/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/cs-CZ/deviceConfig.json rename to apps/web/public/i18n/locales/cs-CZ/deviceConfig.json diff --git a/packages/web/public/i18n/locales/cs-CZ/dialog.json b/apps/web/public/i18n/locales/cs-CZ/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/cs-CZ/dialog.json rename to apps/web/public/i18n/locales/cs-CZ/dialog.json diff --git a/packages/web/public/i18n/locales/cs-CZ/map.json b/apps/web/public/i18n/locales/cs-CZ/map.json similarity index 100% rename from packages/web/public/i18n/locales/cs-CZ/map.json rename to apps/web/public/i18n/locales/cs-CZ/map.json diff --git a/packages/web/public/i18n/locales/cs-CZ/messages.json b/apps/web/public/i18n/locales/cs-CZ/messages.json similarity index 100% rename from packages/web/public/i18n/locales/cs-CZ/messages.json rename to apps/web/public/i18n/locales/cs-CZ/messages.json diff --git a/packages/web/public/i18n/locales/cs-CZ/moduleConfig.json b/apps/web/public/i18n/locales/cs-CZ/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/cs-CZ/moduleConfig.json rename to apps/web/public/i18n/locales/cs-CZ/moduleConfig.json diff --git a/packages/web/public/i18n/locales/cs-CZ/nodes.json b/apps/web/public/i18n/locales/cs-CZ/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/cs-CZ/nodes.json rename to apps/web/public/i18n/locales/cs-CZ/nodes.json diff --git a/packages/web/public/i18n/locales/cs-CZ/ui.json b/apps/web/public/i18n/locales/cs-CZ/ui.json similarity index 100% rename from packages/web/public/i18n/locales/cs-CZ/ui.json rename to apps/web/public/i18n/locales/cs-CZ/ui.json diff --git a/packages/web/public/i18n/locales/de-DE/channels.json b/apps/web/public/i18n/locales/de-DE/channels.json similarity index 100% rename from packages/web/public/i18n/locales/de-DE/channels.json rename to apps/web/public/i18n/locales/de-DE/channels.json diff --git a/packages/web/public/i18n/locales/de-DE/commandPalette.json b/apps/web/public/i18n/locales/de-DE/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/de-DE/commandPalette.json rename to apps/web/public/i18n/locales/de-DE/commandPalette.json diff --git a/packages/web/public/i18n/locales/de-DE/common.json b/apps/web/public/i18n/locales/de-DE/common.json similarity index 100% rename from packages/web/public/i18n/locales/de-DE/common.json rename to apps/web/public/i18n/locales/de-DE/common.json diff --git a/packages/web/public/i18n/locales/de-DE/config.json b/apps/web/public/i18n/locales/de-DE/config.json similarity index 100% rename from packages/web/public/i18n/locales/de-DE/config.json rename to apps/web/public/i18n/locales/de-DE/config.json diff --git a/packages/web/public/i18n/locales/de-DE/connections.json b/apps/web/public/i18n/locales/de-DE/connections.json similarity index 100% rename from packages/web/public/i18n/locales/de-DE/connections.json rename to apps/web/public/i18n/locales/de-DE/connections.json diff --git a/packages/web/public/i18n/locales/de-DE/deviceConfig.json b/apps/web/public/i18n/locales/de-DE/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/de-DE/deviceConfig.json rename to apps/web/public/i18n/locales/de-DE/deviceConfig.json diff --git a/packages/web/public/i18n/locales/de-DE/dialog.json b/apps/web/public/i18n/locales/de-DE/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/de-DE/dialog.json rename to apps/web/public/i18n/locales/de-DE/dialog.json diff --git a/packages/web/public/i18n/locales/de-DE/map.json b/apps/web/public/i18n/locales/de-DE/map.json similarity index 100% rename from packages/web/public/i18n/locales/de-DE/map.json rename to apps/web/public/i18n/locales/de-DE/map.json diff --git a/packages/web/public/i18n/locales/de-DE/messages.json b/apps/web/public/i18n/locales/de-DE/messages.json similarity index 100% rename from packages/web/public/i18n/locales/de-DE/messages.json rename to apps/web/public/i18n/locales/de-DE/messages.json diff --git a/packages/web/public/i18n/locales/de-DE/moduleConfig.json b/apps/web/public/i18n/locales/de-DE/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/de-DE/moduleConfig.json rename to apps/web/public/i18n/locales/de-DE/moduleConfig.json diff --git a/packages/web/public/i18n/locales/de-DE/nodes.json b/apps/web/public/i18n/locales/de-DE/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/de-DE/nodes.json rename to apps/web/public/i18n/locales/de-DE/nodes.json diff --git a/packages/web/public/i18n/locales/de-DE/ui.json b/apps/web/public/i18n/locales/de-DE/ui.json similarity index 100% rename from packages/web/public/i18n/locales/de-DE/ui.json rename to apps/web/public/i18n/locales/de-DE/ui.json diff --git a/packages/web/public/i18n/locales/en/channels.json b/apps/web/public/i18n/locales/en/channels.json similarity index 100% rename from packages/web/public/i18n/locales/en/channels.json rename to apps/web/public/i18n/locales/en/channels.json diff --git a/packages/web/public/i18n/locales/en/commandPalette.json b/apps/web/public/i18n/locales/en/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/en/commandPalette.json rename to apps/web/public/i18n/locales/en/commandPalette.json diff --git a/packages/web/public/i18n/locales/en/common.json b/apps/web/public/i18n/locales/en/common.json similarity index 99% rename from packages/web/public/i18n/locales/en/common.json rename to apps/web/public/i18n/locales/en/common.json index a3959dca6..ee7293171 100644 --- a/packages/web/public/i18n/locales/en/common.json +++ b/apps/web/public/i18n/locales/en/common.json @@ -3,6 +3,7 @@ "apply": "Apply", "addConnection": "Add Connection", "saveConnection": "Save connection", + "saveChanges": "Save changes", "backupKey": "Backup Key", "cancel": "Cancel", "connect": "Connect", diff --git a/packages/web/public/i18n/locales/en/config.json b/apps/web/public/i18n/locales/en/config.json similarity index 64% rename from packages/web/public/i18n/locales/en/config.json rename to apps/web/public/i18n/locales/en/config.json index dd1ba678a..2ecacc577 100644 --- a/packages/web/public/i18n/locales/en/config.json +++ b/apps/web/public/i18n/locales/en/config.json @@ -16,15 +16,15 @@ "label": "Configuration" }, "device": { - "title": "Device Settings", + "title": "Device", "description": "Settings for the device", "buttonPin": { "description": "Button pin override", - "label": "Button Pin" + "label": "Button GPIO" }, "buzzerPin": { "description": "Buzzer pin override", - "label": "Buzzer Pin" + "label": "Buzzer GPIO" }, "disableTripleClick": { "description": "Disable triple click", @@ -43,8 +43,8 @@ "label": "Node Info Broadcast Interval" }, "posixTimezone": { - "description": "The POSIX timezone string for the device", - "label": "POSIX Timezone" + "description": "Time zone for dates on the device screen and log.", + "label": "Time zone" }, "rebroadcastMode": { "description": "How to handle rebroadcasting", @@ -52,52 +52,75 @@ }, "role": { "description": "What role the device performs on the mesh", - "label": "Role" + "label": "Device Role" + }, + "options": { + "label": "Options", + "description": "Device role, rebroadcast mode, and node-info broadcast cadence" + }, + "hardware": { + "label": "Hardware", + "description": "Hardware-related toggles" + }, + "timeZone": { + "label": "Time Zone", + "description": "POSIX time zone for dates on the device screen and log" + }, + "gpio": { + "label": "GPIO", + "description": "GPIO pin overrides" + }, + "useBrowserTimeZone": { + "label": "Use browser time zone" } }, "bluetooth": { - "title": "Bluetooth Settings", + "title": "Bluetooth", "description": "Settings for the Bluetooth module", "note": "Note: Some devices (ESP32) cannot use both Bluetooth and WiFi at the same time.", "enabled": { "description": "Enable or disable Bluetooth", - "label": "Enabled" + "label": "Bluetooth enabled" }, "pairingMode": { "description": "Pin selection behaviour.", "label": "Pairing mode" }, "pin": { - "description": "Pin to use when pairing", - "label": "Pin" + "description": "PIN to use when pairing in fixed-PIN mode", + "label": "Fixed PIN" + }, + "bluetoothConfig": { + "label": "Bluetooth Config", + "description": "Bluetooth configuration" } }, "display": { "description": "Settings for the device display", - "title": "Display Settings", + "title": "Display", "headingBold": { "description": "Bolden the heading text", "label": "Bold Heading" }, "carouselDelay": { "description": "How fast to cycle through windows", - "label": "Carousel Delay" + "label": "Carousel interval" }, "compassNorthTop": { "description": "Fix north to the top of compass", - "label": "Compass North Top" + "label": "Always point north" }, "displayMode": { "description": "Screen layout variant", - "label": "Display Mode" + "label": "Display mode" }, "displayUnits": { "description": "Display metric or imperial units", - "label": "Display Units" + "label": "Display units" }, "flipScreen": { "description": "Flip display 180 degrees", - "label": "Flip Screen" + "label": "Flip screen" }, "gpsDisplayUnits": { "description": "Coordinate display format", @@ -105,31 +128,43 @@ }, "oledType": { "description": "Type of OLED screen attached to the device", - "label": "OLED Type" + "label": "OLED type" }, "screenTimeout": { "description": "Turn off the display after this long", - "label": "Screen Timeout" + "label": "Screen on for" }, "twelveHourClock": { - "description": "Use 12-hour clock format", - "label": "12-Hour Clock" + "description": "Display time in 12h format", + "label": "Use 12h clock format" }, "wakeOnTapOrMotion": { "description": "Wake the device on tap or motion", - "label": "Wake on Tap or Motion" + "label": "Wake on tap or motion" + }, + "deviceDisplay": { + "label": "Device Display", + "description": "Display orientation and clock" + }, + "advanced": { + "label": "Advanced", + "description": "Advanced display settings" + }, + "compassOrientation": { + "label": "Compass orientation", + "description": "Compass orientation relative to the screen" } }, "lora": { - "title": "Mesh Settings", - "description": "Settings for the LoRa mesh", + "title": "LoRa", + "description": "LoRa radio configuration", "bandwidth": { "description": "Channel bandwidth in kHz", "label": "Bandwidth" }, "boostedRxGain": { "description": "Boosted RX gain", - "label": "Boosted RX Gain" + "label": "RX Boosted Gain" }, "codingRate": { "description": "The denominator of the coding rate", @@ -140,24 +175,24 @@ "label": "Frequency Offset" }, "frequencySlot": { - "description": "LoRa frequency channel number", + "description": "Your node's operating frequency is calculated based on the region, modem preset, and this field. When 0, the slot is automatically calculated based on the primary channel name and will change from the default public slot.", "label": "Frequency Slot" }, "hopLimit": { - "description": "Maximum number of hops", - "label": "Hop Limit" + "description": "Sets the maximum number of hops, default is 3. Increasing hops also increases congestion and should be used carefully. 0 hop broadcast messages will not get ACKs.", + "label": "Number of Hops" }, "ignoreMqtt": { "description": "Don't forward MQTT messages over the mesh", "label": "Ignore MQTT" }, "modemPreset": { - "description": "Modem preset to use", - "label": "Modem Preset" + "description": "Available modem presets, default is Long Fast.", + "label": "Presets" }, "okToMqtt": { "description": "When set to true, this configuration indicates that the user approves the packet to be uploaded to MQTT. If set to false, remote nodes are requested not to forward packets to MQTT", - "label": "OK to MQTT" + "label": "Ok to MQTT" }, "overrideDutyCycle": { "description": "Override Duty Cycle", @@ -165,10 +200,10 @@ }, "overrideFrequency": { "description": "Override frequency", - "label": "Override Frequency" + "label": "Frequency Override" }, "region": { - "description": "Sets the region for your node", + "description": "The region where you will be using your radios.", "label": "Region" }, "spreadingFactor": { @@ -198,15 +233,23 @@ "radioSettings": { "label": "Radio Settings", "description": "Settings for the LoRa radio" + }, + "optionsCard": { + "label": "Options", + "description": "LoRa core options" + }, + "advancedCard": { + "label": "Advanced", + "description": "Advanced LoRa parameters" } }, "network": { - "title": "WiFi Config", - "description": "WiFi radio configuration", + "title": "Network", + "description": "Network configuration", "note": "Note: Some devices (ESP32) cannot use both Bluetooth and WiFi at the same time.", "addressMode": { "description": "Address assignment selection", - "label": "Address Mode" + "label": "IPv4 mode" }, "dns": { "description": "DNS Server", @@ -214,7 +257,7 @@ }, "ethernetEnabled": { "description": "Enable or disable the Ethernet port", - "label": "Enabled" + "label": "Ethernet enabled" }, "gateway": { "description": "Default Gateway", @@ -226,7 +269,7 @@ }, "psk": { "description": "Network password", - "label": "PSK" + "label": "Password" }, "ssid": { "description": "Network name", @@ -238,16 +281,17 @@ }, "wifiEnabled": { "description": "Enable or disable the WiFi radio", - "label": "Enabled" + "label": "WiFi enabled" }, "meshViaUdp": { - "label": "Mesh via UDP" + "label": "Enabled", + "description": "Forward mesh packets over UDP" }, "ntpServer": { - "label": "NTP Server" + "label": "NTP server" }, "rsyslogServer": { - "label": "Rsyslog Server" + "label": "rsyslog server" }, "ethernetConfigSettings": { "description": "Ethernet port configuration", @@ -268,18 +312,30 @@ "udpConfigSettings": { "description": "UDP over Mesh configuration", "label": "UDP Config" + }, + "wifiOptions": { + "label": "WiFi Options", + "description": "WiFi configuration" + }, + "ethernetOptionsCard": { + "label": "Ethernet Options", + "description": "Ethernet configuration" + }, + "advancedCard": { + "label": "Advanced", + "description": "NTP, rsyslog, IPv4 mode and address overrides" } }, "position": { - "title": "Position Settings", - "description": "Settings for the position module", + "title": "Position", + "description": "Position settings", "broadcastInterval": { - "description": "How often your position is sent out over the mesh", + "description": "The maximum interval that can elapse without a node broadcasting a position.", "label": "Broadcast Interval" }, "enablePin": { - "description": "GPS module enable pin override", - "label": "Enable Pin" + "description": "GPS enable GPIO pin override", + "label": "GPS EN GPIO" }, "fixedPosition": { "description": "Don't report GPS position, but a manually-specified one", @@ -299,35 +355,35 @@ }, "gpsMode": { "description": "Configure whether device GPS is Enabled, Disabled, or Not Present", - "label": "GPS Mode" + "label": "GPS Mode (Physical Hardware)" }, "gpsUpdateInterval": { - "description": "How often a GPS fix should be acquired", - "label": "GPS Update Interval" + "description": "How often should we try to get a GPS position (<10sec keeps GPS on).", + "label": "GPS Polling Interval" }, "positionFlags": { - "description": "Optional fields to include when assembling position messages. The more fields are selected, the larger the message will be leading to longer airtime usage and a higher risk of packet loss.", + "description": "Optional fields to include when assembling position messages. The more fields are included, the larger the message will be — leading to longer airtime and a higher risk of packet loss.", "label": "Position Flags" }, "receivePin": { - "description": "GPS module RX pin override", - "label": "Receive Pin" + "description": "GPS receive GPIO pin override", + "label": "GPS Receive GPIO" }, "smartPositionEnabled": { "description": "Only send position when there has been a meaningful change in location", - "label": "Enable Smart Position" + "label": "Smart Position" }, "smartPositionMinDistance": { - "description": "Minimum distance (in meters) that must be traveled before a position update is sent", - "label": "Smart Position Minimum Distance" + "description": "The minimum distance change in meters to be considered for a smart position broadcast.", + "label": "Smart Distance" }, "smartPositionMinInterval": { - "description": "Minimum interval (in seconds) that must pass before a position update is sent", - "label": "Smart Position Minimum Interval" + "description": "The fastest that position updates will be sent if the minimum distance has been satisfied.", + "label": "Smart Interval" }, "transmitPin": { - "description": "GPS module TX pin override", - "label": "Transmit Pin" + "description": "GPS transmit GPIO pin override", + "label": "GPS Transmit GPIO" }, "intervalsSettings": { "description": "How often to send position updates", @@ -346,16 +402,33 @@ "unset": "Unset", "vehicleHeading": "Vehicle heading", "vehicleSpeed": "Vehicle speed" + }, + "positionPacket": { + "label": "Position Packet", + "description": "Position broadcast configuration" + }, + "deviceGps": { + "label": "Device GPS", + "description": "Device GPS configuration" + }, + "advancedDeviceGps": { + "label": "Advanced Device GPS", + "description": "GPIO pin overrides for the GPS hardware" + }, + "useBrowserLocation": { + "label": "Use browser location", + "busy": "Reading location…", + "failed": "Could not read browser location" } }, "power": { "adcMultiplierOverride": { "description": "Used for tweaking battery voltage reading", - "label": "ADC Multiplier Override ratio" + "label": "ADC multiplier override ratio" }, "ina219Address": { "description": "Address of the INA219 battery monitor", - "label": "INA219 Address" + "label": "Battery INA_2XX I2C address" }, "lightSleepDuration": { "description": "How long the device will be in light sleep for", @@ -363,11 +436,11 @@ }, "minimumWakeTime": { "description": "Minimum amount of time the device will stay awake for after receiving a packet", - "label": "Minimum Wake Time" + "label": "Minimum wake time" }, "noConnectionBluetoothDisabled": { "description": "If the device does not receive a Bluetooth connection, the BLE radio will be disabled after this long", - "label": "No Connection Bluetooth Disabled" + "label": "Wait for Bluetooth duration" }, "powerSavingEnabled": { "description": "Select if powered from a low-current source (i.e. solar), to minimize power consumption as much as possible.", @@ -375,11 +448,11 @@ }, "shutdownOnBatteryDelay": { "description": "Automatically shutdown node after this long when on battery, 0 for indefinite", - "label": "Shutdown on battery delay" + "label": "Shutdown on power loss" }, "superDeepSleepDuration": { "description": "How long the device will be in super deep sleep for", - "label": "Super Deep Sleep Duration" + "label": "Super deep sleep duration" }, "powerConfigSettings": { "description": "Settings for the power module", @@ -388,23 +461,27 @@ "sleepSettings": { "description": "Sleep settings for the power module", "label": "Sleep Settings" + }, + "powerConfig": { + "label": "Power Config", + "description": "Power and sleep configuration" } }, "security": { "description": "Settings for the Security configuration", - "title": "Security Settings", + "title": "Security", "button_backupKey": "Backup Key", "adminChannelEnabled": { "description": "Allow incoming device control over the insecure legacy admin channel", - "label": "Allow Legacy Admin" + "label": "Legacy Admin channel" }, "enableDebugLogApi": { "description": "Output live debug logging over serial, view and export position-redacted device logs over Bluetooth", - "label": "Enable Debug Log API" + "label": "Debug log API enabled" }, "managed": { "description": "If enabled, device configuration options are only able to be changed remotely by a Remote Admin node via admin messages. Do not enable this option unless at least one suitable Remote Admin node has been setup, and the public key is stored in one of the fields above.", - "label": "Managed" + "label": "Managed Mode" }, "privateKey": { "description": "Used to create a shared key with a remote device", @@ -424,7 +501,7 @@ }, "serialOutputEnabled": { "description": "Serial Console over the Stream API", - "label": "Serial Output Enabled" + "label": "Serial console" }, "tertiaryAdminKey": { "description": "The tertiary public key authorized to send admin messages to this node", @@ -437,10 +514,26 @@ "loggingSettings": { "description": "Settings for Logging", "label": "Logging Settings" + }, + "directMessageKey": { + "label": "Direct Message Key", + "description": "Public + private direct-message keys" + }, + "adminKeysCard": { + "label": "Admin Keys", + "description": "Admin authentication keys" + }, + "logsCard": { + "label": "Logs", + "description": "Logging configuration" + }, + "administration": { + "label": "Administration", + "description": "Managed-mode and legacy admin channel" } }, "user": { - "title": "User Settings", + "title": "User", "description": "Configure your device name and identity settings", "longName": { "label": "Long Name", @@ -460,11 +553,23 @@ }, "isUnmessageable": { "label": "Unmessageable", - "description": "Used to identify unmonitored or infrastructure nodes so that messaging is not available to nodes that will never respond." + "description": "Unmonitored or Infrastructure" }, "isLicensed": { - "label": "Licensed amateur radio (HAM)", - "description": "Enable if you are a licensed amateur radio operator, enabling this option disables encryption and is not compatible with the default Meshtastic network." + "label": "Licensed amateur radio (Ham)", + "description": "Enabling this option disables encryption and is not compatible with the default Meshtastic network." + }, + "userConfig": { + "label": "User Config", + "description": "Identity and licensing" + }, + "nodeId": { + "label": "Node ID", + "description": "Read-only — assigned by the device" + }, + "hardwareModel": { + "label": "Hardware model", + "description": "Read-only — reported by the device" } } } diff --git a/packages/web/public/i18n/locales/en/connections.json b/apps/web/public/i18n/locales/en/connections.json similarity index 65% rename from packages/web/public/i18n/locales/en/connections.json rename to apps/web/public/i18n/locales/en/connections.json index de1b6b067..790a05f82 100644 --- a/packages/web/public/i18n/locales/en/connections.json +++ b/apps/web/public/i18n/locales/en/connections.json @@ -15,6 +15,26 @@ }, "lastConnectedAt": "Last connected: {{date}}", "neverConnected": "Never connected", + "default": "Default", + "button": { + "addConnection": "Add Connection", + "connect": "Connect", + "disconnect": "Disconnect", + "retry": "Retry", + "delete": "Delete", + "cancel": "Cancel", + "setDefault": "Set as default", + "unsetDefault": "Unset default", + "rename": "Rename", + "edit": "Edit" + }, + "renameConnection": "Rename connection", + "renameDescription": "Enter a new name for this connection.", + "nameLabel": "Name", + "editConnection": { + "title": "Edit Connection", + "description": "Modify the settings for this connection." + }, "toasts": { "connected": "Connected", "nowConnected": "{{name}} is now connected", @@ -29,6 +49,10 @@ "pickConnectionAgain": "Could not connect. You may need to reselect the device/port.", "added": "Connection added", "savedByName": "{{name}} saved.", - "savedCantConnect": "The connection was saved but could not connect." + "savedCantConnect": "The connection was saved but could not connect.", + "renamed": "Renamed", + "renamedByName": "Connection renamed to {{name}}.", + "updated": "Updated", + "updatedByName": "{{name}} has been updated." } } diff --git a/packages/web/public/i18n/locales/en/dialog.json b/apps/web/public/i18n/locales/en/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/en/dialog.json rename to apps/web/public/i18n/locales/en/dialog.json diff --git a/packages/web/public/i18n/locales/en/map.json b/apps/web/public/i18n/locales/en/map.json similarity index 100% rename from packages/web/public/i18n/locales/en/map.json rename to apps/web/public/i18n/locales/en/map.json diff --git a/packages/web/public/i18n/locales/en/messages.json b/apps/web/public/i18n/locales/en/messages.json similarity index 100% rename from packages/web/public/i18n/locales/en/messages.json rename to apps/web/public/i18n/locales/en/messages.json diff --git a/packages/web/public/i18n/locales/en/moduleConfig.json b/apps/web/public/i18n/locales/en/moduleConfig.json similarity index 58% rename from packages/web/public/i18n/locales/en/moduleConfig.json rename to apps/web/public/i18n/locales/en/moduleConfig.json index f35995984..1fea0be97 100644 --- a/packages/web/public/i18n/locales/en/moduleConfig.json +++ b/apps/web/public/i18n/locales/en/moduleConfig.json @@ -14,7 +14,7 @@ "tabTelemetry": "Telemetry" }, "ambientLighting": { - "title": "Ambient Lighting Settings", + "title": "Ambient Lighting", "description": "Settings for the Ambient Lighting module", "ledState": { "label": "LED State", @@ -35,217 +35,253 @@ "blue": { "label": "Blue", "description": "Sets the blue LED level. Values are 0-255" + }, + "ambientLightingConfig": { + "label": "Ambient Lighting Config", + "description": "Ambient Lighting configuration" } }, "audio": { - "title": "Audio Settings", + "title": "Audio", "description": "Settings for the Audio module", "codec2Enabled": { - "label": "Codec 2 Enabled", + "label": "CODEC 2 enabled", "description": "Enable Codec 2 audio encoding" }, "pttPin": { - "label": "PTT Pin", + "label": "PTT pin", "description": "GPIO pin to use for PTT" }, "bitrate": { - "label": "Bitrate", + "label": "CODEC2 sample rate", "description": "Bitrate to use for audio encoding" }, "i2sWs": { - "label": "i2S WS", + "label": "I2S word select", "description": "GPIO pin to use for i2S WS" }, "i2sSd": { - "label": "i2S SD", + "label": "I2S data in", "description": "GPIO pin to use for i2S SD" }, "i2sDin": { - "label": "i2S DIN", + "label": "I2S data out", "description": "GPIO pin to use for i2S DIN" }, "i2sSck": { - "label": "i2S SCK", + "label": "I2S clock", "description": "GPIO pin to use for i2S SCK" + }, + "audioConfig": { + "label": "Audio Config", + "description": "Audio configuration" } }, "cannedMessage": { - "title": "Canned Message Settings", + "title": "Canned Message", "description": "Settings for the Canned Message module", "moduleEnabled": { "label": "Module Enabled", "description": "Enable Canned Message" }, "rotary1Enabled": { - "label": "Rotary Encoder #1 Enabled", + "label": "Rotary encoder #1 enabled", "description": "Enable the rotary encoder" }, "inputbrokerPinA": { - "label": "Encoder Pin A", + "label": "GPIO pin for rotary encoder A port", "description": "GPIO Pin Value (1-39) For encoder port A" }, "inputbrokerPinB": { - "label": "Encoder Pin B", + "label": "GPIO pin for rotary encoder B port", "description": "GPIO Pin Value (1-39) For encoder port B" }, "inputbrokerPinPress": { - "label": "Encoder Pin Press", + "label": "GPIO pin for rotary encoder Press port", "description": "GPIO Pin Value (1-39) For encoder Press" }, "inputbrokerEventCw": { - "label": "Clockwise event", + "label": "Generate input event on CW", "description": "Select input event." }, "inputbrokerEventCcw": { - "label": "Counter Clockwise event", + "label": "Generate input event on CCW", "description": "Select input event." }, "inputbrokerEventPress": { - "label": "Press event", + "label": "Generate input event on Press", "description": "Select input event" }, "updown1Enabled": { - "label": "Up Down enabled", + "label": "Up/Down/Select input enabled", "description": "Enable the up / down encoder" }, "allowInputSource": { - "label": "Allow Input Source", + "label": "Allow input source", "description": "Select from: '_any', 'rotEnc1', 'upDownEnc1', 'cardkb'" }, "sendBell": { - "label": "Send Bell", + "label": "Send bell", "description": "Sends a bell character with each message" + }, + "cannedMessageConfig": { + "label": "Canned Message Config", + "description": "Canned Message configuration" + }, + "enabled": { + "label": "Canned message enabled", + "description": "Enable Canned Message" } }, "detectionSensor": { - "title": "Detection Sensor Settings", + "title": "Detection Sensor", "description": "Settings for the Detection Sensor module", "enabled": { - "label": "Enabled", + "label": "Detection Sensor enabled", "description": "Enable or disable Detection Sensor Module" }, "minimumBroadcastSecs": { - "label": "Minimum Broadcast Seconds", - "description": "The interval in seconds of how often we can send a message to the mesh when a state change is detected" + "label": "Minimum broadcast (seconds)", + "description": "Minimum interval between detection broadcasts" }, "stateBroadcastSecs": { - "label": "State Broadcast Seconds", - "description": "The interval in seconds of how often we should send a message to the mesh with the current state regardless of changes" + "label": "State broadcast (seconds)", + "description": "How often to broadcast detection state" }, "sendBell": { - "label": "Send Bell", - "description": "Send ASCII bell with alert message" + "label": "Send bell with alert message", + "description": "Send a bell character with the alert" }, "name": { - "label": "Friendly Name", - "description": "Used to format the message sent to mesh, max 20 Characters" + "label": "Friendly name", + "description": "Friendly name for the detected event" }, "monitorPin": { - "label": "Monitor Pin", - "description": "The GPIO pin to monitor for state changes" + "label": "GPIO pin to monitor", + "description": "GPIO pin to monitor for detection" }, "detectionTriggerType": { - "label": "Detection Triggered Type", - "description": "The type of trigger event to be used" + "label": "Detection trigger type", + "description": "Trigger type for detection" }, "usePullup": { - "label": "Use Pullup", - "description": "Whether or not use INPUT_PULLUP mode for GPIO pin" + "label": "Use INPUT_PULLUP mode", + "description": "Enable internal pull-up on the monitor pin" + }, + "detectionSensorConfig": { + "label": "Detection Sensor Config", + "description": "Detection Sensor configuration" } }, "externalNotification": { - "title": "External Notification Settings", + "title": "External Notification", "description": "Configure the external notification module", "enabled": { - "label": "Module Enabled", + "label": "External notification enabled", "description": "Enable External Notification" }, "outputMs": { - "label": "Output MS", + "label": "Output duration (milliseconds)", "description": "Output MS" }, "output": { - "label": "Output", + "label": "Output LED (GPIO)", "description": "Output" }, "outputVibra": { - "label": "Output Vibrate", + "label": "Output vibra (GPIO)", "description": "Output Vibrate" }, "outputBuzzer": { - "label": "Output Buzzer", + "label": "Output buzzer (GPIO)", "description": "Output Buzzer" }, "active": { - "label": "Active", + "label": "Output LED active high", "description": "Active" }, "alertMessage": { - "label": "Alert Message", + "label": "Alert message LED", "description": "Alert Message" }, "alertMessageVibra": { - "label": "Alert Message Vibrate", + "label": "Alert message vibra", "description": "Alert Message Vibrate" }, "alertMessageBuzzer": { - "label": "Alert Message Buzzer", + "label": "Alert message buzzer", "description": "Alert Message Buzzer" }, "alertBell": { - "label": "Alert Bell", + "label": "Alert bell LED", "description": "Should an alert be triggered when receiving an incoming bell?" }, "alertBellVibra": { - "label": "Alert Bell Vibrate", + "label": "Alert bell vibra", "description": "Alert Bell Vibrate" }, "alertBellBuzzer": { - "label": "Alert Bell Buzzer", + "label": "Alert bell buzzer", "description": "Alert Bell Buzzer" }, "usePwm": { - "label": "Use PWM", + "label": "Use PWM buzzer", "description": "Use PWM" }, "nagTimeout": { - "label": "Nag Timeout", + "label": "Nag timeout (seconds)", "description": "Nag Timeout" }, "useI2sAsBuzzer": { - "label": "Use I²S Pin as Buzzer", - "description": "Designate I²S Pin as Buzzer Output" + "label": "Use I2S as buzzer", + "description": "Use I2S output as buzzer driver" + }, + "externalNotificationConfig": { + "label": "External Notification Config", + "description": "External notification configuration" + }, + "notificationsOnMessage": { + "label": "Notifications on message receipt", + "description": "Alerts on incoming text messages" + }, + "notificationsOnAlert": { + "label": "Notifications on alert/bell receipt", + "description": "Alerts on incoming bell/alert packets" + }, + "advanced": { + "label": "Advanced", + "description": "Pin assignments and timing" } }, "mqtt": { - "title": "MQTT Settings", - "description": "Settings for the MQTT module", + "title": "MQTT", + "description": "MQTT module configuration", "enabled": { - "label": "Enabled", + "label": "MQTT enabled", "description": "Enable or disable MQTT" }, "address": { - "label": "MQTT Server Address", + "label": "Address", "description": "MQTT server address to use for default/custom servers" }, "username": { - "label": "MQTT Username", + "label": "Username", "description": "MQTT username to use for default/custom servers" }, "password": { - "label": "MQTT Password", + "label": "Password", "description": "MQTT password to use for default/custom servers" }, "encryptionEnabled": { - "label": "Encryption Enabled", + "label": "Encryption enabled", "description": "Enable or disable MQTT encryption. Note: All messages are sent to the MQTT broker unencrypted if this option is not enabled, even when your uplink channels have encryption keys set. This includes position data." }, "jsonEnabled": { - "label": "JSON Enabled", + "label": "JSON output enabled", "description": "Whether to send/consume JSON packets on MQTT" }, "tlsEnabled": { - "label": "TLS Enabled", + "label": "TLS enabled", "description": "Enable or disable TLS" }, "root": { @@ -253,20 +289,20 @@ "description": "MQTT root topic to use for default/custom servers" }, "proxyToClientEnabled": { - "label": "MQTT Client Proxy Enabled", + "label": "Proxy to client enabled", "description": "Utilizes the network connection to proxy MQTT messages to the client." }, "mapReportingEnabled": { - "label": "Map Reporting Enabled", - "description": "Your node will periodically send an unencrypted map report packet to the configured MQTT server, this includes id, short and long name, approximate location, hardware model, role, firmware version, LoRa region, modem preset and primary channel name." + "label": "Map reporting", + "description": "Your node will periodically send an unencrypted map report packet to the configured MQTT server, this includes id, long and short name, approximate location, hardware model, role, firmware version, LoRa region, modem preset and primary channel name." }, "mapReportSettings": { "publishIntervalSecs": { - "label": "Map Report Publish Interval (s)", + "label": "Map reporting interval (seconds)", "description": "Interval in seconds to publish map reports" }, "positionPrecision": { - "label": "Approximate Location", + "label": "Approximate location", "description": "Position shared will be accurate within this distance", "options": { "metric_km23": "Within 23 km", @@ -290,78 +326,108 @@ "imperial_ft300": "Within 300 feet", "imperial_ft150": "Within 150 feet" } + }, + "shouldReportLocation": { + "label": "I agree.", + "description": "I have read and understand the above. I voluntarily consent to the unencrypted transmission of my node data via MQTT.", + "consentHeader": "Consent to Share Unencrypted Node Data via MQTT", + "consentText": "By enabling this feature, you acknowledge and expressly consent to the transmission of your device's real-time geographic location over the MQTT protocol without encryption. This location data may be used for purposes such as live map reporting, device tracking, and related telemetry functions." } + }, + "mqttConfigCard": { + "label": "MQTT Config", + "description": "MQTT broker connection" + }, + "mapReportingCard": { + "label": "Map reporting", + "description": "Periodic unencrypted map report" } }, "neighborInfo": { - "title": "Neighbor Info Settings", + "title": "Neighbor Info", "description": "Settings for the Neighbor Info module", "enabled": { - "label": "Enabled", + "label": "Neighbor Info enabled", "description": "Enable or disable Neighbor Info Module" }, "updateInterval": { - "label": "Update Interval", + "label": "Update interval (seconds)", "description": "Interval in seconds of how often we should try to send our Neighbor Info to the mesh" + }, + "neighborInfoConfig": { + "label": "Neighbor Info Config", + "description": "Neighbor Info configuration" + }, + "transmitOverLora": { + "label": "Transmit over LoRa", + "description": "Whether NeighborInfo should be transmitted over LoRa. Not available on a channel with default key and name." } }, "paxcounter": { - "title": "Paxcounter Settings", + "title": "Paxcounter", "description": "Settings for the Paxcounter module", "enabled": { - "label": "Module Enabled", + "label": "Paxcounter enabled", "description": "Enable Paxcounter" }, "paxcounterUpdateInterval": { - "label": "Update Interval (seconds)", + "label": "Update interval (seconds)", "description": "How long to wait between sending paxcounter packets" }, "wifiThreshold": { - "label": "WiFi RSSI Threshold", + "label": "WiFi RSSI threshold (defaults to -80)", "description": "At what WiFi RSSI level should the counter increase. Defaults to -80." }, "bleThreshold": { - "label": "BLE RSSI Threshold", + "label": "BLE RSSI threshold (defaults to -80)", "description": "At what BLE RSSI level should the counter increase. Defaults to -80." + }, + "paxcounterConfig": { + "label": "Paxcounter Config", + "description": "Paxcounter configuration" } }, "rangeTest": { - "title": "Range Test Settings", + "title": "Range Test", "description": "Settings for the Range Test module", "enabled": { - "label": "Module Enabled", + "label": "Range test enabled", "description": "Enable Range Test" }, "sender": { - "label": "Message Interval", + "label": "Sender message interval (seconds)", "description": "How long to wait between sending test packets" }, "save": { - "label": "Save CSV to storage", + "label": "Save .CSV in storage (ESP32 only)", "description": "ESP32 Only" + }, + "rangeTestConfig": { + "label": "Range Test Config", + "description": "Range Test configuration" } }, "serial": { - "title": "Serial Settings", + "title": "Serial", "description": "Settings for the Serial module", "enabled": { - "label": "Module Enabled", + "label": "Serial enabled", "description": "Enable Serial output" }, "echo": { - "label": "Echo", + "label": "Echo enabled", "description": "Any packets you send will be echoed back to your device" }, "rxd": { - "label": "Receive Pin", + "label": "RX", "description": "Set the GPIO pin to the RXD pin you have set up." }, "txd": { - "label": "Transmit Pin", + "label": "TX", "description": "Set the GPIO pin to the TXD pin you have set up." }, "baud": { - "label": "Baud Rate", + "label": "Serial baud rate", "description": "The serial baud rate" }, "timeout": { @@ -369,23 +435,27 @@ "description": "Seconds to wait before we consider your packet as 'done'" }, "mode": { - "label": "Mode", + "label": "Serial mode", "description": "Select Mode" }, "overrideConsoleSerialPort": { - "label": "Override Console Serial Port", + "label": "Override console serial port", "description": "If you have a serial port connected to the console, this will override it." + }, + "serialConfig": { + "label": "Serial Config", + "description": "Serial module configuration" } }, "storeForward": { - "title": "Store & Forward Settings", + "title": "Store & Forward", "description": "Settings for the Store & Forward module", "enabled": { - "label": "Module Enabled", + "label": "Store & Forward enabled", "description": "Enable Store & Forward" }, "heartbeat": { - "label": "Heartbeat Enabled", + "label": "Heartbeat", "description": "Enable Store & Forward heartbeat" }, "records": { @@ -399,50 +469,66 @@ "historyReturnWindow": { "label": "History return window", "description": "Return records from this time window (minutes)" + }, + "storeForwardConfig": { + "label": "Store & Forward Config", + "description": "Store & Forward configuration" + }, + "isServer": { + "label": "Server", + "description": "Run as a Store & Forward server" } }, "telemetry": { - "title": "Telemetry Settings", + "title": "Telemetry", "description": "Settings for the Telemetry module", "deviceUpdateInterval": { - "label": "Device Metrics", + "label": "Device metrics update interval", "description": "Device metrics update interval (seconds)" }, "environmentUpdateInterval": { - "label": "Environment metrics update interval (seconds)", + "label": "Environment metrics update interval", "description": "" }, "environmentMeasurementEnabled": { - "label": "Module Enabled", + "label": "Environment metrics module enabled", "description": "Enable the Environment Telemetry" }, "environmentScreenEnabled": { - "label": "Displayed on Screen", + "label": "Environment metrics on-screen enabled", "description": "Show the Telemetry Module on the OLED" }, "environmentDisplayFahrenheit": { - "label": "Display Fahrenheit", + "label": "Environment metrics use Fahrenheit", "description": "Display temp in Fahrenheit" }, "airQualityEnabled": { - "label": "Air Quality Enabled", + "label": "Air quality metrics module enabled", "description": "Enable the Air Quality Telemetry" }, "airQualityInterval": { - "label": "Air Quality Update Interval", + "label": "Air quality metrics update interval", "description": "How often to send Air Quality data over the mesh" }, "powerMeasurementEnabled": { - "label": "Power Measurement Enabled", + "label": "Power metrics module enabled", "description": "Enable the Power Measurement Telemetry" }, "powerUpdateInterval": { - "label": "Power Update Interval", + "label": "Power metrics update interval", "description": "How often to send Power data over the mesh" }, "powerScreenEnabled": { - "label": "Power Screen Enabled", - "description": "Enable the Power Telemetry Screen" + "label": "Power metrics on-screen enabled", + "description": "Show power metrics on the device screen" + }, + "telemetryConfig": { + "label": "Telemetry Config", + "description": "Telemetry configuration" + }, + "deviceTelemetryEnabled": { + "label": "Send Device Telemetry", + "description": "Enable/Disable the device telemetry module to send metrics to the mesh." } } } diff --git a/packages/web/public/i18n/locales/en/nodes.json b/apps/web/public/i18n/locales/en/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/en/nodes.json rename to apps/web/public/i18n/locales/en/nodes.json diff --git a/packages/web/public/i18n/locales/en/ui.json b/apps/web/public/i18n/locales/en/ui.json similarity index 100% rename from packages/web/public/i18n/locales/en/ui.json rename to apps/web/public/i18n/locales/en/ui.json diff --git a/packages/web/public/i18n/locales/es-ES/channels.json b/apps/web/public/i18n/locales/es-ES/channels.json similarity index 100% rename from packages/web/public/i18n/locales/es-ES/channels.json rename to apps/web/public/i18n/locales/es-ES/channels.json diff --git a/packages/web/public/i18n/locales/es-ES/commandPalette.json b/apps/web/public/i18n/locales/es-ES/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/es-ES/commandPalette.json rename to apps/web/public/i18n/locales/es-ES/commandPalette.json diff --git a/packages/web/public/i18n/locales/es-ES/common.json b/apps/web/public/i18n/locales/es-ES/common.json similarity index 100% rename from packages/web/public/i18n/locales/es-ES/common.json rename to apps/web/public/i18n/locales/es-ES/common.json diff --git a/packages/web/public/i18n/locales/es-ES/config.json b/apps/web/public/i18n/locales/es-ES/config.json similarity index 100% rename from packages/web/public/i18n/locales/es-ES/config.json rename to apps/web/public/i18n/locales/es-ES/config.json diff --git a/packages/web/public/i18n/locales/es-ES/connections.json b/apps/web/public/i18n/locales/es-ES/connections.json similarity index 100% rename from packages/web/public/i18n/locales/es-ES/connections.json rename to apps/web/public/i18n/locales/es-ES/connections.json diff --git a/packages/web/public/i18n/locales/es-ES/deviceConfig.json b/apps/web/public/i18n/locales/es-ES/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/es-ES/deviceConfig.json rename to apps/web/public/i18n/locales/es-ES/deviceConfig.json diff --git a/packages/web/public/i18n/locales/es-ES/dialog.json b/apps/web/public/i18n/locales/es-ES/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/es-ES/dialog.json rename to apps/web/public/i18n/locales/es-ES/dialog.json diff --git a/packages/web/public/i18n/locales/es-ES/map.json b/apps/web/public/i18n/locales/es-ES/map.json similarity index 100% rename from packages/web/public/i18n/locales/es-ES/map.json rename to apps/web/public/i18n/locales/es-ES/map.json diff --git a/packages/web/public/i18n/locales/es-ES/messages.json b/apps/web/public/i18n/locales/es-ES/messages.json similarity index 100% rename from packages/web/public/i18n/locales/es-ES/messages.json rename to apps/web/public/i18n/locales/es-ES/messages.json diff --git a/packages/web/public/i18n/locales/es-ES/moduleConfig.json b/apps/web/public/i18n/locales/es-ES/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/es-ES/moduleConfig.json rename to apps/web/public/i18n/locales/es-ES/moduleConfig.json diff --git a/packages/web/public/i18n/locales/es-ES/nodes.json b/apps/web/public/i18n/locales/es-ES/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/es-ES/nodes.json rename to apps/web/public/i18n/locales/es-ES/nodes.json diff --git a/packages/web/public/i18n/locales/es-ES/ui.json b/apps/web/public/i18n/locales/es-ES/ui.json similarity index 100% rename from packages/web/public/i18n/locales/es-ES/ui.json rename to apps/web/public/i18n/locales/es-ES/ui.json diff --git a/packages/web/public/i18n/locales/fi-FI/channels.json b/apps/web/public/i18n/locales/fi-FI/channels.json similarity index 100% rename from packages/web/public/i18n/locales/fi-FI/channels.json rename to apps/web/public/i18n/locales/fi-FI/channels.json diff --git a/packages/web/public/i18n/locales/fi-FI/commandPalette.json b/apps/web/public/i18n/locales/fi-FI/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/fi-FI/commandPalette.json rename to apps/web/public/i18n/locales/fi-FI/commandPalette.json diff --git a/packages/web/public/i18n/locales/fi-FI/common.json b/apps/web/public/i18n/locales/fi-FI/common.json similarity index 100% rename from packages/web/public/i18n/locales/fi-FI/common.json rename to apps/web/public/i18n/locales/fi-FI/common.json diff --git a/packages/web/public/i18n/locales/fi-FI/config.json b/apps/web/public/i18n/locales/fi-FI/config.json similarity index 100% rename from packages/web/public/i18n/locales/fi-FI/config.json rename to apps/web/public/i18n/locales/fi-FI/config.json diff --git a/packages/web/public/i18n/locales/fi-FI/connections.json b/apps/web/public/i18n/locales/fi-FI/connections.json similarity index 100% rename from packages/web/public/i18n/locales/fi-FI/connections.json rename to apps/web/public/i18n/locales/fi-FI/connections.json diff --git a/packages/web/public/i18n/locales/fi-FI/deviceConfig.json b/apps/web/public/i18n/locales/fi-FI/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/fi-FI/deviceConfig.json rename to apps/web/public/i18n/locales/fi-FI/deviceConfig.json diff --git a/packages/web/public/i18n/locales/fi-FI/dialog.json b/apps/web/public/i18n/locales/fi-FI/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/fi-FI/dialog.json rename to apps/web/public/i18n/locales/fi-FI/dialog.json diff --git a/packages/web/public/i18n/locales/fi-FI/map.json b/apps/web/public/i18n/locales/fi-FI/map.json similarity index 100% rename from packages/web/public/i18n/locales/fi-FI/map.json rename to apps/web/public/i18n/locales/fi-FI/map.json diff --git a/packages/web/public/i18n/locales/fi-FI/messages.json b/apps/web/public/i18n/locales/fi-FI/messages.json similarity index 100% rename from packages/web/public/i18n/locales/fi-FI/messages.json rename to apps/web/public/i18n/locales/fi-FI/messages.json diff --git a/packages/web/public/i18n/locales/fi-FI/moduleConfig.json b/apps/web/public/i18n/locales/fi-FI/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/fi-FI/moduleConfig.json rename to apps/web/public/i18n/locales/fi-FI/moduleConfig.json diff --git a/packages/web/public/i18n/locales/fi-FI/nodes.json b/apps/web/public/i18n/locales/fi-FI/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/fi-FI/nodes.json rename to apps/web/public/i18n/locales/fi-FI/nodes.json diff --git a/packages/web/public/i18n/locales/fi-FI/ui.json b/apps/web/public/i18n/locales/fi-FI/ui.json similarity index 100% rename from packages/web/public/i18n/locales/fi-FI/ui.json rename to apps/web/public/i18n/locales/fi-FI/ui.json diff --git a/packages/web/public/i18n/locales/fr-FR/channels.json b/apps/web/public/i18n/locales/fr-FR/channels.json similarity index 100% rename from packages/web/public/i18n/locales/fr-FR/channels.json rename to apps/web/public/i18n/locales/fr-FR/channels.json diff --git a/packages/web/public/i18n/locales/fr-FR/commandPalette.json b/apps/web/public/i18n/locales/fr-FR/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/fr-FR/commandPalette.json rename to apps/web/public/i18n/locales/fr-FR/commandPalette.json diff --git a/packages/web/public/i18n/locales/fr-FR/common.json b/apps/web/public/i18n/locales/fr-FR/common.json similarity index 100% rename from packages/web/public/i18n/locales/fr-FR/common.json rename to apps/web/public/i18n/locales/fr-FR/common.json diff --git a/packages/web/public/i18n/locales/fr-FR/config.json b/apps/web/public/i18n/locales/fr-FR/config.json similarity index 100% rename from packages/web/public/i18n/locales/fr-FR/config.json rename to apps/web/public/i18n/locales/fr-FR/config.json diff --git a/packages/web/public/i18n/locales/fr-FR/connections.json b/apps/web/public/i18n/locales/fr-FR/connections.json similarity index 100% rename from packages/web/public/i18n/locales/fr-FR/connections.json rename to apps/web/public/i18n/locales/fr-FR/connections.json diff --git a/packages/web/public/i18n/locales/fr-FR/deviceConfig.json b/apps/web/public/i18n/locales/fr-FR/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/fr-FR/deviceConfig.json rename to apps/web/public/i18n/locales/fr-FR/deviceConfig.json diff --git a/packages/web/public/i18n/locales/fr-FR/dialog.json b/apps/web/public/i18n/locales/fr-FR/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/fr-FR/dialog.json rename to apps/web/public/i18n/locales/fr-FR/dialog.json diff --git a/packages/web/public/i18n/locales/fr-FR/map.json b/apps/web/public/i18n/locales/fr-FR/map.json similarity index 100% rename from packages/web/public/i18n/locales/fr-FR/map.json rename to apps/web/public/i18n/locales/fr-FR/map.json diff --git a/packages/web/public/i18n/locales/fr-FR/messages.json b/apps/web/public/i18n/locales/fr-FR/messages.json similarity index 100% rename from packages/web/public/i18n/locales/fr-FR/messages.json rename to apps/web/public/i18n/locales/fr-FR/messages.json diff --git a/packages/web/public/i18n/locales/fr-FR/moduleConfig.json b/apps/web/public/i18n/locales/fr-FR/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/fr-FR/moduleConfig.json rename to apps/web/public/i18n/locales/fr-FR/moduleConfig.json diff --git a/packages/web/public/i18n/locales/fr-FR/nodes.json b/apps/web/public/i18n/locales/fr-FR/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/fr-FR/nodes.json rename to apps/web/public/i18n/locales/fr-FR/nodes.json diff --git a/packages/web/public/i18n/locales/fr-FR/ui.json b/apps/web/public/i18n/locales/fr-FR/ui.json similarity index 100% rename from packages/web/public/i18n/locales/fr-FR/ui.json rename to apps/web/public/i18n/locales/fr-FR/ui.json diff --git a/packages/web/public/i18n/locales/hu-HU/channels.json b/apps/web/public/i18n/locales/hu-HU/channels.json similarity index 100% rename from packages/web/public/i18n/locales/hu-HU/channels.json rename to apps/web/public/i18n/locales/hu-HU/channels.json diff --git a/packages/web/public/i18n/locales/hu-HU/commandPalette.json b/apps/web/public/i18n/locales/hu-HU/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/hu-HU/commandPalette.json rename to apps/web/public/i18n/locales/hu-HU/commandPalette.json diff --git a/packages/web/public/i18n/locales/hu-HU/common.json b/apps/web/public/i18n/locales/hu-HU/common.json similarity index 100% rename from packages/web/public/i18n/locales/hu-HU/common.json rename to apps/web/public/i18n/locales/hu-HU/common.json diff --git a/packages/web/public/i18n/locales/hu-HU/config.json b/apps/web/public/i18n/locales/hu-HU/config.json similarity index 100% rename from packages/web/public/i18n/locales/hu-HU/config.json rename to apps/web/public/i18n/locales/hu-HU/config.json diff --git a/packages/web/public/i18n/locales/hu-HU/connections.json b/apps/web/public/i18n/locales/hu-HU/connections.json similarity index 100% rename from packages/web/public/i18n/locales/hu-HU/connections.json rename to apps/web/public/i18n/locales/hu-HU/connections.json diff --git a/packages/web/public/i18n/locales/hu-HU/deviceConfig.json b/apps/web/public/i18n/locales/hu-HU/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/hu-HU/deviceConfig.json rename to apps/web/public/i18n/locales/hu-HU/deviceConfig.json diff --git a/packages/web/public/i18n/locales/hu-HU/dialog.json b/apps/web/public/i18n/locales/hu-HU/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/hu-HU/dialog.json rename to apps/web/public/i18n/locales/hu-HU/dialog.json diff --git a/packages/web/public/i18n/locales/hu-HU/map.json b/apps/web/public/i18n/locales/hu-HU/map.json similarity index 100% rename from packages/web/public/i18n/locales/hu-HU/map.json rename to apps/web/public/i18n/locales/hu-HU/map.json diff --git a/packages/web/public/i18n/locales/hu-HU/messages.json b/apps/web/public/i18n/locales/hu-HU/messages.json similarity index 100% rename from packages/web/public/i18n/locales/hu-HU/messages.json rename to apps/web/public/i18n/locales/hu-HU/messages.json diff --git a/packages/web/public/i18n/locales/hu-HU/moduleConfig.json b/apps/web/public/i18n/locales/hu-HU/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/hu-HU/moduleConfig.json rename to apps/web/public/i18n/locales/hu-HU/moduleConfig.json diff --git a/packages/web/public/i18n/locales/hu-HU/nodes.json b/apps/web/public/i18n/locales/hu-HU/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/hu-HU/nodes.json rename to apps/web/public/i18n/locales/hu-HU/nodes.json diff --git a/packages/web/public/i18n/locales/hu-HU/ui.json b/apps/web/public/i18n/locales/hu-HU/ui.json similarity index 100% rename from packages/web/public/i18n/locales/hu-HU/ui.json rename to apps/web/public/i18n/locales/hu-HU/ui.json diff --git a/packages/web/public/i18n/locales/it-IT/channels.json b/apps/web/public/i18n/locales/it-IT/channels.json similarity index 100% rename from packages/web/public/i18n/locales/it-IT/channels.json rename to apps/web/public/i18n/locales/it-IT/channels.json diff --git a/packages/web/public/i18n/locales/it-IT/commandPalette.json b/apps/web/public/i18n/locales/it-IT/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/it-IT/commandPalette.json rename to apps/web/public/i18n/locales/it-IT/commandPalette.json diff --git a/packages/web/public/i18n/locales/it-IT/common.json b/apps/web/public/i18n/locales/it-IT/common.json similarity index 100% rename from packages/web/public/i18n/locales/it-IT/common.json rename to apps/web/public/i18n/locales/it-IT/common.json diff --git a/packages/web/public/i18n/locales/it-IT/config.json b/apps/web/public/i18n/locales/it-IT/config.json similarity index 100% rename from packages/web/public/i18n/locales/it-IT/config.json rename to apps/web/public/i18n/locales/it-IT/config.json diff --git a/packages/web/public/i18n/locales/it-IT/connections.json b/apps/web/public/i18n/locales/it-IT/connections.json similarity index 100% rename from packages/web/public/i18n/locales/it-IT/connections.json rename to apps/web/public/i18n/locales/it-IT/connections.json diff --git a/packages/web/public/i18n/locales/it-IT/deviceConfig.json b/apps/web/public/i18n/locales/it-IT/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/it-IT/deviceConfig.json rename to apps/web/public/i18n/locales/it-IT/deviceConfig.json diff --git a/packages/web/public/i18n/locales/it-IT/dialog.json b/apps/web/public/i18n/locales/it-IT/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/it-IT/dialog.json rename to apps/web/public/i18n/locales/it-IT/dialog.json diff --git a/packages/web/public/i18n/locales/it-IT/map.json b/apps/web/public/i18n/locales/it-IT/map.json similarity index 100% rename from packages/web/public/i18n/locales/it-IT/map.json rename to apps/web/public/i18n/locales/it-IT/map.json diff --git a/packages/web/public/i18n/locales/it-IT/messages.json b/apps/web/public/i18n/locales/it-IT/messages.json similarity index 100% rename from packages/web/public/i18n/locales/it-IT/messages.json rename to apps/web/public/i18n/locales/it-IT/messages.json diff --git a/packages/web/public/i18n/locales/it-IT/moduleConfig.json b/apps/web/public/i18n/locales/it-IT/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/it-IT/moduleConfig.json rename to apps/web/public/i18n/locales/it-IT/moduleConfig.json diff --git a/packages/web/public/i18n/locales/it-IT/nodes.json b/apps/web/public/i18n/locales/it-IT/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/it-IT/nodes.json rename to apps/web/public/i18n/locales/it-IT/nodes.json diff --git a/packages/web/public/i18n/locales/it-IT/ui.json b/apps/web/public/i18n/locales/it-IT/ui.json similarity index 100% rename from packages/web/public/i18n/locales/it-IT/ui.json rename to apps/web/public/i18n/locales/it-IT/ui.json diff --git a/packages/web/public/i18n/locales/ja-JP/channels.json b/apps/web/public/i18n/locales/ja-JP/channels.json similarity index 100% rename from packages/web/public/i18n/locales/ja-JP/channels.json rename to apps/web/public/i18n/locales/ja-JP/channels.json diff --git a/packages/web/public/i18n/locales/ja-JP/commandPalette.json b/apps/web/public/i18n/locales/ja-JP/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/ja-JP/commandPalette.json rename to apps/web/public/i18n/locales/ja-JP/commandPalette.json diff --git a/packages/web/public/i18n/locales/ja-JP/common.json b/apps/web/public/i18n/locales/ja-JP/common.json similarity index 100% rename from packages/web/public/i18n/locales/ja-JP/common.json rename to apps/web/public/i18n/locales/ja-JP/common.json diff --git a/packages/web/public/i18n/locales/ja-JP/config.json b/apps/web/public/i18n/locales/ja-JP/config.json similarity index 100% rename from packages/web/public/i18n/locales/ja-JP/config.json rename to apps/web/public/i18n/locales/ja-JP/config.json diff --git a/packages/web/public/i18n/locales/ja-JP/connections.json b/apps/web/public/i18n/locales/ja-JP/connections.json similarity index 100% rename from packages/web/public/i18n/locales/ja-JP/connections.json rename to apps/web/public/i18n/locales/ja-JP/connections.json diff --git a/packages/web/public/i18n/locales/ja-JP/deviceConfig.json b/apps/web/public/i18n/locales/ja-JP/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/ja-JP/deviceConfig.json rename to apps/web/public/i18n/locales/ja-JP/deviceConfig.json diff --git a/packages/web/public/i18n/locales/ja-JP/dialog.json b/apps/web/public/i18n/locales/ja-JP/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/ja-JP/dialog.json rename to apps/web/public/i18n/locales/ja-JP/dialog.json diff --git a/packages/web/public/i18n/locales/ja-JP/map.json b/apps/web/public/i18n/locales/ja-JP/map.json similarity index 100% rename from packages/web/public/i18n/locales/ja-JP/map.json rename to apps/web/public/i18n/locales/ja-JP/map.json diff --git a/packages/web/public/i18n/locales/ja-JP/messages.json b/apps/web/public/i18n/locales/ja-JP/messages.json similarity index 100% rename from packages/web/public/i18n/locales/ja-JP/messages.json rename to apps/web/public/i18n/locales/ja-JP/messages.json diff --git a/packages/web/public/i18n/locales/ja-JP/moduleConfig.json b/apps/web/public/i18n/locales/ja-JP/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/ja-JP/moduleConfig.json rename to apps/web/public/i18n/locales/ja-JP/moduleConfig.json diff --git a/packages/web/public/i18n/locales/ja-JP/nodes.json b/apps/web/public/i18n/locales/ja-JP/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/ja-JP/nodes.json rename to apps/web/public/i18n/locales/ja-JP/nodes.json diff --git a/packages/web/public/i18n/locales/ja-JP/ui.json b/apps/web/public/i18n/locales/ja-JP/ui.json similarity index 100% rename from packages/web/public/i18n/locales/ja-JP/ui.json rename to apps/web/public/i18n/locales/ja-JP/ui.json diff --git a/packages/web/public/i18n/locales/ko-KR/channels.json b/apps/web/public/i18n/locales/ko-KR/channels.json similarity index 100% rename from packages/web/public/i18n/locales/ko-KR/channels.json rename to apps/web/public/i18n/locales/ko-KR/channels.json diff --git a/packages/web/public/i18n/locales/ko-KR/commandPalette.json b/apps/web/public/i18n/locales/ko-KR/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/ko-KR/commandPalette.json rename to apps/web/public/i18n/locales/ko-KR/commandPalette.json diff --git a/packages/web/public/i18n/locales/ko-KR/common.json b/apps/web/public/i18n/locales/ko-KR/common.json similarity index 100% rename from packages/web/public/i18n/locales/ko-KR/common.json rename to apps/web/public/i18n/locales/ko-KR/common.json diff --git a/packages/web/public/i18n/locales/ko-KR/config.json b/apps/web/public/i18n/locales/ko-KR/config.json similarity index 100% rename from packages/web/public/i18n/locales/ko-KR/config.json rename to apps/web/public/i18n/locales/ko-KR/config.json diff --git a/packages/web/public/i18n/locales/ko-KR/connections.json b/apps/web/public/i18n/locales/ko-KR/connections.json similarity index 100% rename from packages/web/public/i18n/locales/ko-KR/connections.json rename to apps/web/public/i18n/locales/ko-KR/connections.json diff --git a/packages/web/public/i18n/locales/ko-KR/deviceConfig.json b/apps/web/public/i18n/locales/ko-KR/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/ko-KR/deviceConfig.json rename to apps/web/public/i18n/locales/ko-KR/deviceConfig.json diff --git a/packages/web/public/i18n/locales/ko-KR/dialog.json b/apps/web/public/i18n/locales/ko-KR/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/ko-KR/dialog.json rename to apps/web/public/i18n/locales/ko-KR/dialog.json diff --git a/packages/web/public/i18n/locales/ko-KR/map.json b/apps/web/public/i18n/locales/ko-KR/map.json similarity index 100% rename from packages/web/public/i18n/locales/ko-KR/map.json rename to apps/web/public/i18n/locales/ko-KR/map.json diff --git a/packages/web/public/i18n/locales/ko-KR/messages.json b/apps/web/public/i18n/locales/ko-KR/messages.json similarity index 100% rename from packages/web/public/i18n/locales/ko-KR/messages.json rename to apps/web/public/i18n/locales/ko-KR/messages.json diff --git a/packages/web/public/i18n/locales/ko-KR/moduleConfig.json b/apps/web/public/i18n/locales/ko-KR/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/ko-KR/moduleConfig.json rename to apps/web/public/i18n/locales/ko-KR/moduleConfig.json diff --git a/packages/web/public/i18n/locales/ko-KR/nodes.json b/apps/web/public/i18n/locales/ko-KR/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/ko-KR/nodes.json rename to apps/web/public/i18n/locales/ko-KR/nodes.json diff --git a/packages/web/public/i18n/locales/ko-KR/ui.json b/apps/web/public/i18n/locales/ko-KR/ui.json similarity index 100% rename from packages/web/public/i18n/locales/ko-KR/ui.json rename to apps/web/public/i18n/locales/ko-KR/ui.json diff --git a/packages/web/public/i18n/locales/nl-NL/channels.json b/apps/web/public/i18n/locales/nl-NL/channels.json similarity index 100% rename from packages/web/public/i18n/locales/nl-NL/channels.json rename to apps/web/public/i18n/locales/nl-NL/channels.json diff --git a/packages/web/public/i18n/locales/nl-NL/commandPalette.json b/apps/web/public/i18n/locales/nl-NL/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/nl-NL/commandPalette.json rename to apps/web/public/i18n/locales/nl-NL/commandPalette.json diff --git a/packages/web/public/i18n/locales/nl-NL/common.json b/apps/web/public/i18n/locales/nl-NL/common.json similarity index 100% rename from packages/web/public/i18n/locales/nl-NL/common.json rename to apps/web/public/i18n/locales/nl-NL/common.json diff --git a/packages/web/public/i18n/locales/nl-NL/config.json b/apps/web/public/i18n/locales/nl-NL/config.json similarity index 100% rename from packages/web/public/i18n/locales/nl-NL/config.json rename to apps/web/public/i18n/locales/nl-NL/config.json diff --git a/packages/web/public/i18n/locales/nl-NL/connections.json b/apps/web/public/i18n/locales/nl-NL/connections.json similarity index 100% rename from packages/web/public/i18n/locales/nl-NL/connections.json rename to apps/web/public/i18n/locales/nl-NL/connections.json diff --git a/packages/web/public/i18n/locales/nl-NL/deviceConfig.json b/apps/web/public/i18n/locales/nl-NL/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/nl-NL/deviceConfig.json rename to apps/web/public/i18n/locales/nl-NL/deviceConfig.json diff --git a/packages/web/public/i18n/locales/nl-NL/dialog.json b/apps/web/public/i18n/locales/nl-NL/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/nl-NL/dialog.json rename to apps/web/public/i18n/locales/nl-NL/dialog.json diff --git a/packages/web/public/i18n/locales/nl-NL/map.json b/apps/web/public/i18n/locales/nl-NL/map.json similarity index 100% rename from packages/web/public/i18n/locales/nl-NL/map.json rename to apps/web/public/i18n/locales/nl-NL/map.json diff --git a/packages/web/public/i18n/locales/nl-NL/messages.json b/apps/web/public/i18n/locales/nl-NL/messages.json similarity index 100% rename from packages/web/public/i18n/locales/nl-NL/messages.json rename to apps/web/public/i18n/locales/nl-NL/messages.json diff --git a/packages/web/public/i18n/locales/nl-NL/moduleConfig.json b/apps/web/public/i18n/locales/nl-NL/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/nl-NL/moduleConfig.json rename to apps/web/public/i18n/locales/nl-NL/moduleConfig.json diff --git a/packages/web/public/i18n/locales/nl-NL/nodes.json b/apps/web/public/i18n/locales/nl-NL/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/nl-NL/nodes.json rename to apps/web/public/i18n/locales/nl-NL/nodes.json diff --git a/packages/web/public/i18n/locales/nl-NL/ui.json b/apps/web/public/i18n/locales/nl-NL/ui.json similarity index 100% rename from packages/web/public/i18n/locales/nl-NL/ui.json rename to apps/web/public/i18n/locales/nl-NL/ui.json diff --git a/packages/web/public/i18n/locales/pl-PL/channels.json b/apps/web/public/i18n/locales/pl-PL/channels.json similarity index 100% rename from packages/web/public/i18n/locales/pl-PL/channels.json rename to apps/web/public/i18n/locales/pl-PL/channels.json diff --git a/packages/web/public/i18n/locales/pl-PL/commandPalette.json b/apps/web/public/i18n/locales/pl-PL/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/pl-PL/commandPalette.json rename to apps/web/public/i18n/locales/pl-PL/commandPalette.json diff --git a/packages/web/public/i18n/locales/pl-PL/common.json b/apps/web/public/i18n/locales/pl-PL/common.json similarity index 100% rename from packages/web/public/i18n/locales/pl-PL/common.json rename to apps/web/public/i18n/locales/pl-PL/common.json diff --git a/packages/web/public/i18n/locales/pl-PL/config.json b/apps/web/public/i18n/locales/pl-PL/config.json similarity index 100% rename from packages/web/public/i18n/locales/pl-PL/config.json rename to apps/web/public/i18n/locales/pl-PL/config.json diff --git a/packages/web/public/i18n/locales/pl-PL/connections.json b/apps/web/public/i18n/locales/pl-PL/connections.json similarity index 100% rename from packages/web/public/i18n/locales/pl-PL/connections.json rename to apps/web/public/i18n/locales/pl-PL/connections.json diff --git a/packages/web/public/i18n/locales/pl-PL/deviceConfig.json b/apps/web/public/i18n/locales/pl-PL/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/pl-PL/deviceConfig.json rename to apps/web/public/i18n/locales/pl-PL/deviceConfig.json diff --git a/packages/web/public/i18n/locales/pl-PL/dialog.json b/apps/web/public/i18n/locales/pl-PL/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/pl-PL/dialog.json rename to apps/web/public/i18n/locales/pl-PL/dialog.json diff --git a/packages/web/public/i18n/locales/pl-PL/map.json b/apps/web/public/i18n/locales/pl-PL/map.json similarity index 100% rename from packages/web/public/i18n/locales/pl-PL/map.json rename to apps/web/public/i18n/locales/pl-PL/map.json diff --git a/packages/web/public/i18n/locales/pl-PL/messages.json b/apps/web/public/i18n/locales/pl-PL/messages.json similarity index 100% rename from packages/web/public/i18n/locales/pl-PL/messages.json rename to apps/web/public/i18n/locales/pl-PL/messages.json diff --git a/packages/web/public/i18n/locales/pl-PL/moduleConfig.json b/apps/web/public/i18n/locales/pl-PL/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/pl-PL/moduleConfig.json rename to apps/web/public/i18n/locales/pl-PL/moduleConfig.json diff --git a/packages/web/public/i18n/locales/pl-PL/nodes.json b/apps/web/public/i18n/locales/pl-PL/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/pl-PL/nodes.json rename to apps/web/public/i18n/locales/pl-PL/nodes.json diff --git a/packages/web/public/i18n/locales/pl-PL/ui.json b/apps/web/public/i18n/locales/pl-PL/ui.json similarity index 100% rename from packages/web/public/i18n/locales/pl-PL/ui.json rename to apps/web/public/i18n/locales/pl-PL/ui.json diff --git a/packages/web/public/i18n/locales/pt-BR/channels.json b/apps/web/public/i18n/locales/pt-BR/channels.json similarity index 100% rename from packages/web/public/i18n/locales/pt-BR/channels.json rename to apps/web/public/i18n/locales/pt-BR/channels.json diff --git a/packages/web/public/i18n/locales/pt-BR/commandPalette.json b/apps/web/public/i18n/locales/pt-BR/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/pt-BR/commandPalette.json rename to apps/web/public/i18n/locales/pt-BR/commandPalette.json diff --git a/packages/web/public/i18n/locales/pt-BR/common.json b/apps/web/public/i18n/locales/pt-BR/common.json similarity index 100% rename from packages/web/public/i18n/locales/pt-BR/common.json rename to apps/web/public/i18n/locales/pt-BR/common.json diff --git a/packages/web/public/i18n/locales/pt-BR/config.json b/apps/web/public/i18n/locales/pt-BR/config.json similarity index 100% rename from packages/web/public/i18n/locales/pt-BR/config.json rename to apps/web/public/i18n/locales/pt-BR/config.json diff --git a/packages/web/public/i18n/locales/pt-BR/connections.json b/apps/web/public/i18n/locales/pt-BR/connections.json similarity index 100% rename from packages/web/public/i18n/locales/pt-BR/connections.json rename to apps/web/public/i18n/locales/pt-BR/connections.json diff --git a/packages/web/public/i18n/locales/pt-BR/deviceConfig.json b/apps/web/public/i18n/locales/pt-BR/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/pt-BR/deviceConfig.json rename to apps/web/public/i18n/locales/pt-BR/deviceConfig.json diff --git a/packages/web/public/i18n/locales/pt-BR/dialog.json b/apps/web/public/i18n/locales/pt-BR/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/pt-BR/dialog.json rename to apps/web/public/i18n/locales/pt-BR/dialog.json diff --git a/packages/web/public/i18n/locales/pt-BR/map.json b/apps/web/public/i18n/locales/pt-BR/map.json similarity index 100% rename from packages/web/public/i18n/locales/pt-BR/map.json rename to apps/web/public/i18n/locales/pt-BR/map.json diff --git a/packages/web/public/i18n/locales/pt-BR/messages.json b/apps/web/public/i18n/locales/pt-BR/messages.json similarity index 100% rename from packages/web/public/i18n/locales/pt-BR/messages.json rename to apps/web/public/i18n/locales/pt-BR/messages.json diff --git a/packages/web/public/i18n/locales/pt-BR/moduleConfig.json b/apps/web/public/i18n/locales/pt-BR/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/pt-BR/moduleConfig.json rename to apps/web/public/i18n/locales/pt-BR/moduleConfig.json diff --git a/packages/web/public/i18n/locales/pt-BR/nodes.json b/apps/web/public/i18n/locales/pt-BR/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/pt-BR/nodes.json rename to apps/web/public/i18n/locales/pt-BR/nodes.json diff --git a/packages/web/public/i18n/locales/pt-BR/ui.json b/apps/web/public/i18n/locales/pt-BR/ui.json similarity index 100% rename from packages/web/public/i18n/locales/pt-BR/ui.json rename to apps/web/public/i18n/locales/pt-BR/ui.json diff --git a/packages/web/public/i18n/locales/pt-PT/channels.json b/apps/web/public/i18n/locales/pt-PT/channels.json similarity index 100% rename from packages/web/public/i18n/locales/pt-PT/channels.json rename to apps/web/public/i18n/locales/pt-PT/channels.json diff --git a/packages/web/public/i18n/locales/pt-PT/commandPalette.json b/apps/web/public/i18n/locales/pt-PT/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/pt-PT/commandPalette.json rename to apps/web/public/i18n/locales/pt-PT/commandPalette.json diff --git a/packages/web/public/i18n/locales/pt-PT/common.json b/apps/web/public/i18n/locales/pt-PT/common.json similarity index 100% rename from packages/web/public/i18n/locales/pt-PT/common.json rename to apps/web/public/i18n/locales/pt-PT/common.json diff --git a/packages/web/public/i18n/locales/pt-PT/config.json b/apps/web/public/i18n/locales/pt-PT/config.json similarity index 100% rename from packages/web/public/i18n/locales/pt-PT/config.json rename to apps/web/public/i18n/locales/pt-PT/config.json diff --git a/packages/web/public/i18n/locales/pt-PT/connections.json b/apps/web/public/i18n/locales/pt-PT/connections.json similarity index 100% rename from packages/web/public/i18n/locales/pt-PT/connections.json rename to apps/web/public/i18n/locales/pt-PT/connections.json diff --git a/packages/web/public/i18n/locales/pt-PT/deviceConfig.json b/apps/web/public/i18n/locales/pt-PT/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/pt-PT/deviceConfig.json rename to apps/web/public/i18n/locales/pt-PT/deviceConfig.json diff --git a/packages/web/public/i18n/locales/pt-PT/dialog.json b/apps/web/public/i18n/locales/pt-PT/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/pt-PT/dialog.json rename to apps/web/public/i18n/locales/pt-PT/dialog.json diff --git a/packages/web/public/i18n/locales/pt-PT/map.json b/apps/web/public/i18n/locales/pt-PT/map.json similarity index 100% rename from packages/web/public/i18n/locales/pt-PT/map.json rename to apps/web/public/i18n/locales/pt-PT/map.json diff --git a/packages/web/public/i18n/locales/pt-PT/messages.json b/apps/web/public/i18n/locales/pt-PT/messages.json similarity index 100% rename from packages/web/public/i18n/locales/pt-PT/messages.json rename to apps/web/public/i18n/locales/pt-PT/messages.json diff --git a/packages/web/public/i18n/locales/pt-PT/moduleConfig.json b/apps/web/public/i18n/locales/pt-PT/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/pt-PT/moduleConfig.json rename to apps/web/public/i18n/locales/pt-PT/moduleConfig.json diff --git a/packages/web/public/i18n/locales/pt-PT/nodes.json b/apps/web/public/i18n/locales/pt-PT/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/pt-PT/nodes.json rename to apps/web/public/i18n/locales/pt-PT/nodes.json diff --git a/packages/web/public/i18n/locales/pt-PT/ui.json b/apps/web/public/i18n/locales/pt-PT/ui.json similarity index 100% rename from packages/web/public/i18n/locales/pt-PT/ui.json rename to apps/web/public/i18n/locales/pt-PT/ui.json diff --git a/packages/web/public/i18n/locales/ru-RU/channels.json b/apps/web/public/i18n/locales/ru-RU/channels.json similarity index 100% rename from packages/web/public/i18n/locales/ru-RU/channels.json rename to apps/web/public/i18n/locales/ru-RU/channels.json diff --git a/packages/web/public/i18n/locales/ru-RU/commandPalette.json b/apps/web/public/i18n/locales/ru-RU/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/ru-RU/commandPalette.json rename to apps/web/public/i18n/locales/ru-RU/commandPalette.json diff --git a/packages/web/public/i18n/locales/ru-RU/common.json b/apps/web/public/i18n/locales/ru-RU/common.json similarity index 100% rename from packages/web/public/i18n/locales/ru-RU/common.json rename to apps/web/public/i18n/locales/ru-RU/common.json diff --git a/packages/web/public/i18n/locales/ru-RU/config.json b/apps/web/public/i18n/locales/ru-RU/config.json similarity index 100% rename from packages/web/public/i18n/locales/ru-RU/config.json rename to apps/web/public/i18n/locales/ru-RU/config.json diff --git a/packages/web/public/i18n/locales/ru-RU/connections.json b/apps/web/public/i18n/locales/ru-RU/connections.json similarity index 100% rename from packages/web/public/i18n/locales/ru-RU/connections.json rename to apps/web/public/i18n/locales/ru-RU/connections.json diff --git a/packages/web/public/i18n/locales/ru-RU/dialog.json b/apps/web/public/i18n/locales/ru-RU/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/ru-RU/dialog.json rename to apps/web/public/i18n/locales/ru-RU/dialog.json diff --git a/packages/web/public/i18n/locales/ru-RU/map.json b/apps/web/public/i18n/locales/ru-RU/map.json similarity index 100% rename from packages/web/public/i18n/locales/ru-RU/map.json rename to apps/web/public/i18n/locales/ru-RU/map.json diff --git a/packages/web/public/i18n/locales/ru-RU/messages.json b/apps/web/public/i18n/locales/ru-RU/messages.json similarity index 100% rename from packages/web/public/i18n/locales/ru-RU/messages.json rename to apps/web/public/i18n/locales/ru-RU/messages.json diff --git a/packages/web/public/i18n/locales/ru-RU/moduleConfig.json b/apps/web/public/i18n/locales/ru-RU/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/ru-RU/moduleConfig.json rename to apps/web/public/i18n/locales/ru-RU/moduleConfig.json diff --git a/packages/web/public/i18n/locales/ru-RU/nodes.json b/apps/web/public/i18n/locales/ru-RU/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/ru-RU/nodes.json rename to apps/web/public/i18n/locales/ru-RU/nodes.json diff --git a/packages/web/public/i18n/locales/ru-RU/ui.json b/apps/web/public/i18n/locales/ru-RU/ui.json similarity index 100% rename from packages/web/public/i18n/locales/ru-RU/ui.json rename to apps/web/public/i18n/locales/ru-RU/ui.json diff --git a/packages/web/public/i18n/locales/sv-SE/channels.json b/apps/web/public/i18n/locales/sv-SE/channels.json similarity index 100% rename from packages/web/public/i18n/locales/sv-SE/channels.json rename to apps/web/public/i18n/locales/sv-SE/channels.json diff --git a/packages/web/public/i18n/locales/sv-SE/commandPalette.json b/apps/web/public/i18n/locales/sv-SE/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/sv-SE/commandPalette.json rename to apps/web/public/i18n/locales/sv-SE/commandPalette.json diff --git a/packages/web/public/i18n/locales/sv-SE/common.json b/apps/web/public/i18n/locales/sv-SE/common.json similarity index 100% rename from packages/web/public/i18n/locales/sv-SE/common.json rename to apps/web/public/i18n/locales/sv-SE/common.json diff --git a/packages/web/public/i18n/locales/sv-SE/config.json b/apps/web/public/i18n/locales/sv-SE/config.json similarity index 100% rename from packages/web/public/i18n/locales/sv-SE/config.json rename to apps/web/public/i18n/locales/sv-SE/config.json diff --git a/packages/web/public/i18n/locales/sv-SE/connections.json b/apps/web/public/i18n/locales/sv-SE/connections.json similarity index 100% rename from packages/web/public/i18n/locales/sv-SE/connections.json rename to apps/web/public/i18n/locales/sv-SE/connections.json diff --git a/packages/web/public/i18n/locales/sv-SE/deviceConfig.json b/apps/web/public/i18n/locales/sv-SE/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/sv-SE/deviceConfig.json rename to apps/web/public/i18n/locales/sv-SE/deviceConfig.json diff --git a/packages/web/public/i18n/locales/sv-SE/dialog.json b/apps/web/public/i18n/locales/sv-SE/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/sv-SE/dialog.json rename to apps/web/public/i18n/locales/sv-SE/dialog.json diff --git a/packages/web/public/i18n/locales/sv-SE/map.json b/apps/web/public/i18n/locales/sv-SE/map.json similarity index 100% rename from packages/web/public/i18n/locales/sv-SE/map.json rename to apps/web/public/i18n/locales/sv-SE/map.json diff --git a/packages/web/public/i18n/locales/sv-SE/messages.json b/apps/web/public/i18n/locales/sv-SE/messages.json similarity index 100% rename from packages/web/public/i18n/locales/sv-SE/messages.json rename to apps/web/public/i18n/locales/sv-SE/messages.json diff --git a/packages/web/public/i18n/locales/sv-SE/moduleConfig.json b/apps/web/public/i18n/locales/sv-SE/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/sv-SE/moduleConfig.json rename to apps/web/public/i18n/locales/sv-SE/moduleConfig.json diff --git a/packages/web/public/i18n/locales/sv-SE/nodes.json b/apps/web/public/i18n/locales/sv-SE/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/sv-SE/nodes.json rename to apps/web/public/i18n/locales/sv-SE/nodes.json diff --git a/packages/web/public/i18n/locales/sv-SE/ui.json b/apps/web/public/i18n/locales/sv-SE/ui.json similarity index 100% rename from packages/web/public/i18n/locales/sv-SE/ui.json rename to apps/web/public/i18n/locales/sv-SE/ui.json diff --git a/packages/web/public/i18n/locales/tr-TR/channels.json b/apps/web/public/i18n/locales/tr-TR/channels.json similarity index 100% rename from packages/web/public/i18n/locales/tr-TR/channels.json rename to apps/web/public/i18n/locales/tr-TR/channels.json diff --git a/packages/web/public/i18n/locales/tr-TR/commandPalette.json b/apps/web/public/i18n/locales/tr-TR/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/tr-TR/commandPalette.json rename to apps/web/public/i18n/locales/tr-TR/commandPalette.json diff --git a/packages/web/public/i18n/locales/tr-TR/common.json b/apps/web/public/i18n/locales/tr-TR/common.json similarity index 100% rename from packages/web/public/i18n/locales/tr-TR/common.json rename to apps/web/public/i18n/locales/tr-TR/common.json diff --git a/packages/web/public/i18n/locales/tr-TR/config.json b/apps/web/public/i18n/locales/tr-TR/config.json similarity index 100% rename from packages/web/public/i18n/locales/tr-TR/config.json rename to apps/web/public/i18n/locales/tr-TR/config.json diff --git a/packages/web/public/i18n/locales/tr-TR/connections.json b/apps/web/public/i18n/locales/tr-TR/connections.json similarity index 100% rename from packages/web/public/i18n/locales/tr-TR/connections.json rename to apps/web/public/i18n/locales/tr-TR/connections.json diff --git a/packages/web/public/i18n/locales/tr-TR/deviceConfig.json b/apps/web/public/i18n/locales/tr-TR/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/tr-TR/deviceConfig.json rename to apps/web/public/i18n/locales/tr-TR/deviceConfig.json diff --git a/packages/web/public/i18n/locales/tr-TR/dialog.json b/apps/web/public/i18n/locales/tr-TR/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/tr-TR/dialog.json rename to apps/web/public/i18n/locales/tr-TR/dialog.json diff --git a/packages/web/public/i18n/locales/tr-TR/map.json b/apps/web/public/i18n/locales/tr-TR/map.json similarity index 100% rename from packages/web/public/i18n/locales/tr-TR/map.json rename to apps/web/public/i18n/locales/tr-TR/map.json diff --git a/packages/web/public/i18n/locales/tr-TR/messages.json b/apps/web/public/i18n/locales/tr-TR/messages.json similarity index 100% rename from packages/web/public/i18n/locales/tr-TR/messages.json rename to apps/web/public/i18n/locales/tr-TR/messages.json diff --git a/packages/web/public/i18n/locales/tr-TR/moduleConfig.json b/apps/web/public/i18n/locales/tr-TR/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/tr-TR/moduleConfig.json rename to apps/web/public/i18n/locales/tr-TR/moduleConfig.json diff --git a/packages/web/public/i18n/locales/tr-TR/nodes.json b/apps/web/public/i18n/locales/tr-TR/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/tr-TR/nodes.json rename to apps/web/public/i18n/locales/tr-TR/nodes.json diff --git a/packages/web/public/i18n/locales/tr-TR/ui.json b/apps/web/public/i18n/locales/tr-TR/ui.json similarity index 100% rename from packages/web/public/i18n/locales/tr-TR/ui.json rename to apps/web/public/i18n/locales/tr-TR/ui.json diff --git a/packages/web/public/i18n/locales/uk-UA/channels.json b/apps/web/public/i18n/locales/uk-UA/channels.json similarity index 100% rename from packages/web/public/i18n/locales/uk-UA/channels.json rename to apps/web/public/i18n/locales/uk-UA/channels.json diff --git a/packages/web/public/i18n/locales/uk-UA/commandPalette.json b/apps/web/public/i18n/locales/uk-UA/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/uk-UA/commandPalette.json rename to apps/web/public/i18n/locales/uk-UA/commandPalette.json diff --git a/packages/web/public/i18n/locales/uk-UA/common.json b/apps/web/public/i18n/locales/uk-UA/common.json similarity index 100% rename from packages/web/public/i18n/locales/uk-UA/common.json rename to apps/web/public/i18n/locales/uk-UA/common.json diff --git a/packages/web/public/i18n/locales/uk-UA/config.json b/apps/web/public/i18n/locales/uk-UA/config.json similarity index 100% rename from packages/web/public/i18n/locales/uk-UA/config.json rename to apps/web/public/i18n/locales/uk-UA/config.json diff --git a/packages/web/public/i18n/locales/uk-UA/connections.json b/apps/web/public/i18n/locales/uk-UA/connections.json similarity index 100% rename from packages/web/public/i18n/locales/uk-UA/connections.json rename to apps/web/public/i18n/locales/uk-UA/connections.json diff --git a/packages/web/public/i18n/locales/uk-UA/deviceConfig.json b/apps/web/public/i18n/locales/uk-UA/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/uk-UA/deviceConfig.json rename to apps/web/public/i18n/locales/uk-UA/deviceConfig.json diff --git a/packages/web/public/i18n/locales/uk-UA/dialog.json b/apps/web/public/i18n/locales/uk-UA/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/uk-UA/dialog.json rename to apps/web/public/i18n/locales/uk-UA/dialog.json diff --git a/packages/web/public/i18n/locales/uk-UA/map.json b/apps/web/public/i18n/locales/uk-UA/map.json similarity index 100% rename from packages/web/public/i18n/locales/uk-UA/map.json rename to apps/web/public/i18n/locales/uk-UA/map.json diff --git a/packages/web/public/i18n/locales/uk-UA/messages.json b/apps/web/public/i18n/locales/uk-UA/messages.json similarity index 100% rename from packages/web/public/i18n/locales/uk-UA/messages.json rename to apps/web/public/i18n/locales/uk-UA/messages.json diff --git a/packages/web/public/i18n/locales/uk-UA/moduleConfig.json b/apps/web/public/i18n/locales/uk-UA/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/uk-UA/moduleConfig.json rename to apps/web/public/i18n/locales/uk-UA/moduleConfig.json diff --git a/packages/web/public/i18n/locales/uk-UA/nodes.json b/apps/web/public/i18n/locales/uk-UA/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/uk-UA/nodes.json rename to apps/web/public/i18n/locales/uk-UA/nodes.json diff --git a/packages/web/public/i18n/locales/uk-UA/ui.json b/apps/web/public/i18n/locales/uk-UA/ui.json similarity index 100% rename from packages/web/public/i18n/locales/uk-UA/ui.json rename to apps/web/public/i18n/locales/uk-UA/ui.json diff --git a/packages/web/public/i18n/locales/zh-CN/channels.json b/apps/web/public/i18n/locales/zh-CN/channels.json similarity index 100% rename from packages/web/public/i18n/locales/zh-CN/channels.json rename to apps/web/public/i18n/locales/zh-CN/channels.json diff --git a/packages/web/public/i18n/locales/zh-CN/commandPalette.json b/apps/web/public/i18n/locales/zh-CN/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/zh-CN/commandPalette.json rename to apps/web/public/i18n/locales/zh-CN/commandPalette.json diff --git a/packages/web/public/i18n/locales/zh-CN/common.json b/apps/web/public/i18n/locales/zh-CN/common.json similarity index 100% rename from packages/web/public/i18n/locales/zh-CN/common.json rename to apps/web/public/i18n/locales/zh-CN/common.json diff --git a/packages/web/public/i18n/locales/zh-CN/config.json b/apps/web/public/i18n/locales/zh-CN/config.json similarity index 100% rename from packages/web/public/i18n/locales/zh-CN/config.json rename to apps/web/public/i18n/locales/zh-CN/config.json diff --git a/packages/web/public/i18n/locales/zh-CN/connections.json b/apps/web/public/i18n/locales/zh-CN/connections.json similarity index 100% rename from packages/web/public/i18n/locales/zh-CN/connections.json rename to apps/web/public/i18n/locales/zh-CN/connections.json diff --git a/packages/web/public/i18n/locales/zh-CN/deviceConfig.json b/apps/web/public/i18n/locales/zh-CN/deviceConfig.json similarity index 100% rename from packages/web/public/i18n/locales/zh-CN/deviceConfig.json rename to apps/web/public/i18n/locales/zh-CN/deviceConfig.json diff --git a/packages/web/public/i18n/locales/zh-CN/dialog.json b/apps/web/public/i18n/locales/zh-CN/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/zh-CN/dialog.json rename to apps/web/public/i18n/locales/zh-CN/dialog.json diff --git a/packages/web/public/i18n/locales/zh-CN/map.json b/apps/web/public/i18n/locales/zh-CN/map.json similarity index 100% rename from packages/web/public/i18n/locales/zh-CN/map.json rename to apps/web/public/i18n/locales/zh-CN/map.json diff --git a/packages/web/public/i18n/locales/zh-CN/messages.json b/apps/web/public/i18n/locales/zh-CN/messages.json similarity index 100% rename from packages/web/public/i18n/locales/zh-CN/messages.json rename to apps/web/public/i18n/locales/zh-CN/messages.json diff --git a/packages/web/public/i18n/locales/zh-CN/moduleConfig.json b/apps/web/public/i18n/locales/zh-CN/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/zh-CN/moduleConfig.json rename to apps/web/public/i18n/locales/zh-CN/moduleConfig.json diff --git a/packages/web/public/i18n/locales/zh-CN/nodes.json b/apps/web/public/i18n/locales/zh-CN/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/zh-CN/nodes.json rename to apps/web/public/i18n/locales/zh-CN/nodes.json diff --git a/packages/web/public/i18n/locales/zh-CN/ui.json b/apps/web/public/i18n/locales/zh-CN/ui.json similarity index 100% rename from packages/web/public/i18n/locales/zh-CN/ui.json rename to apps/web/public/i18n/locales/zh-CN/ui.json diff --git a/packages/web/public/i18n/locales/zh-TW/channels.json b/apps/web/public/i18n/locales/zh-TW/channels.json similarity index 100% rename from packages/web/public/i18n/locales/zh-TW/channels.json rename to apps/web/public/i18n/locales/zh-TW/channels.json diff --git a/packages/web/public/i18n/locales/zh-TW/commandPalette.json b/apps/web/public/i18n/locales/zh-TW/commandPalette.json similarity index 100% rename from packages/web/public/i18n/locales/zh-TW/commandPalette.json rename to apps/web/public/i18n/locales/zh-TW/commandPalette.json diff --git a/packages/web/public/i18n/locales/zh-TW/common.json b/apps/web/public/i18n/locales/zh-TW/common.json similarity index 100% rename from packages/web/public/i18n/locales/zh-TW/common.json rename to apps/web/public/i18n/locales/zh-TW/common.json diff --git a/packages/web/public/i18n/locales/zh-TW/config.json b/apps/web/public/i18n/locales/zh-TW/config.json similarity index 100% rename from packages/web/public/i18n/locales/zh-TW/config.json rename to apps/web/public/i18n/locales/zh-TW/config.json diff --git a/packages/web/public/i18n/locales/zh-TW/connections.json b/apps/web/public/i18n/locales/zh-TW/connections.json similarity index 100% rename from packages/web/public/i18n/locales/zh-TW/connections.json rename to apps/web/public/i18n/locales/zh-TW/connections.json diff --git a/packages/web/public/i18n/locales/zh-TW/dashboard.json b/apps/web/public/i18n/locales/zh-TW/dashboard.json similarity index 100% rename from packages/web/public/i18n/locales/zh-TW/dashboard.json rename to apps/web/public/i18n/locales/zh-TW/dashboard.json diff --git a/packages/web/public/i18n/locales/zh-TW/dialog.json b/apps/web/public/i18n/locales/zh-TW/dialog.json similarity index 100% rename from packages/web/public/i18n/locales/zh-TW/dialog.json rename to apps/web/public/i18n/locales/zh-TW/dialog.json diff --git a/packages/web/public/i18n/locales/zh-TW/map.json b/apps/web/public/i18n/locales/zh-TW/map.json similarity index 100% rename from packages/web/public/i18n/locales/zh-TW/map.json rename to apps/web/public/i18n/locales/zh-TW/map.json diff --git a/packages/web/public/i18n/locales/zh-TW/messages.json b/apps/web/public/i18n/locales/zh-TW/messages.json similarity index 100% rename from packages/web/public/i18n/locales/zh-TW/messages.json rename to apps/web/public/i18n/locales/zh-TW/messages.json diff --git a/packages/web/public/i18n/locales/zh-TW/moduleConfig.json b/apps/web/public/i18n/locales/zh-TW/moduleConfig.json similarity index 100% rename from packages/web/public/i18n/locales/zh-TW/moduleConfig.json rename to apps/web/public/i18n/locales/zh-TW/moduleConfig.json diff --git a/packages/web/public/i18n/locales/zh-TW/nodes.json b/apps/web/public/i18n/locales/zh-TW/nodes.json similarity index 100% rename from packages/web/public/i18n/locales/zh-TW/nodes.json rename to apps/web/public/i18n/locales/zh-TW/nodes.json diff --git a/packages/web/public/i18n/locales/zh-TW/ui.json b/apps/web/public/i18n/locales/zh-TW/ui.json similarity index 100% rename from packages/web/public/i18n/locales/zh-TW/ui.json rename to apps/web/public/i18n/locales/zh-TW/ui.json diff --git a/packages/web/public/logo.svg b/apps/web/public/logo.svg similarity index 100% rename from packages/web/public/logo.svg rename to apps/web/public/logo.svg diff --git a/packages/web/public/robots.txt b/apps/web/public/robots.txt similarity index 100% rename from packages/web/public/robots.txt rename to apps/web/public/robots.txt diff --git a/packages/web/public/site.webmanifest b/apps/web/public/site.webmanifest similarity index 100% rename from packages/web/public/site.webmanifest rename to apps/web/public/site.webmanifest diff --git a/packages/web/src/App.tsx b/apps/web/src/App.tsx similarity index 100% rename from packages/web/src/App.tsx rename to apps/web/src/App.tsx diff --git a/packages/web/src/DeviceWrapper.tsx b/apps/web/src/DeviceWrapper.tsx similarity index 100% rename from packages/web/src/DeviceWrapper.tsx rename to apps/web/src/DeviceWrapper.tsx diff --git a/packages/web/src/__mocks__/README.md b/apps/web/src/__mocks__/README.md similarity index 100% rename from packages/web/src/__mocks__/README.md rename to apps/web/src/__mocks__/README.md diff --git a/packages/web/src/__mocks__/components/UI/Button.tsx b/apps/web/src/__mocks__/components/UI/Button.tsx similarity index 100% rename from packages/web/src/__mocks__/components/UI/Button.tsx rename to apps/web/src/__mocks__/components/UI/Button.tsx diff --git a/packages/web/src/__mocks__/components/UI/Checkbox.tsx b/apps/web/src/__mocks__/components/UI/Checkbox.tsx similarity index 100% rename from packages/web/src/__mocks__/components/UI/Checkbox.tsx rename to apps/web/src/__mocks__/components/UI/Checkbox.tsx diff --git a/packages/web/src/__mocks__/components/UI/Dialog/Dialog.tsx b/apps/web/src/__mocks__/components/UI/Dialog/Dialog.tsx similarity index 100% rename from packages/web/src/__mocks__/components/UI/Dialog/Dialog.tsx rename to apps/web/src/__mocks__/components/UI/Dialog/Dialog.tsx diff --git a/packages/web/src/__mocks__/components/UI/Label.tsx b/apps/web/src/__mocks__/components/UI/Label.tsx similarity index 100% rename from packages/web/src/__mocks__/components/UI/Label.tsx rename to apps/web/src/__mocks__/components/UI/Label.tsx diff --git a/packages/web/src/__mocks__/components/UI/Link.tsx b/apps/web/src/__mocks__/components/UI/Link.tsx similarity index 100% rename from packages/web/src/__mocks__/components/UI/Link.tsx rename to apps/web/src/__mocks__/components/UI/Link.tsx diff --git a/packages/web/src/components/Badge/ConnectionStatusBadge.tsx b/apps/web/src/components/Badge/ConnectionStatusBadge.tsx similarity index 100% rename from packages/web/src/components/Badge/ConnectionStatusBadge.tsx rename to apps/web/src/components/Badge/ConnectionStatusBadge.tsx diff --git a/packages/web/src/components/Badge/SupportedBadge.tsx b/apps/web/src/components/Badge/SupportedBadge.tsx similarity index 100% rename from packages/web/src/components/Badge/SupportedBadge.tsx rename to apps/web/src/components/Badge/SupportedBadge.tsx diff --git a/packages/web/src/components/BatteryStatus.tsx b/apps/web/src/components/BatteryStatus.tsx similarity index 100% rename from packages/web/src/components/BatteryStatus.tsx rename to apps/web/src/components/BatteryStatus.tsx diff --git a/packages/web/src/components/CommandPalette/index.tsx b/apps/web/src/components/CommandPalette/index.tsx similarity index 97% rename from packages/web/src/components/CommandPalette/index.tsx rename to apps/web/src/components/CommandPalette/index.tsx index 6098abb6e..5911bcef3 100644 --- a/packages/web/src/components/CommandPalette/index.tsx +++ b/apps/web/src/components/CommandPalette/index.tsx @@ -8,7 +8,8 @@ import { CommandList, } from "@components/UI/Command.tsx"; import { usePinnedItems } from "@core/hooks/usePinnedItems.ts"; -import { useAppStore, useDevice, useDeviceStore, useNodeDB } from "@core/stores"; +import { useNodesAsProto } from "@core/hooks/useNodesAsProto.ts"; +import { useAppStore, useDevice, useDeviceStore } from "@core/stores"; import { cn } from "@core/utils/cn.ts"; import { useNavigate } from "@tanstack/react-router"; import { useCommandState } from "cmdk"; @@ -61,7 +62,8 @@ export const CommandPalette = () => { useAppStore(); const { getDevices } = useDeviceStore(); const { setDialogOpen, connection } = useDevice(); - const { getNode } = useNodeDB(); + const allNodes = useNodesAsProto(); + const getNode = (n: number) => allNodes.find((node) => node.num === n); const { pinnedItems, togglePinnedItem } = usePinnedItems({ storageName: "pinnedCommandMenuGroups", }); diff --git a/packages/web/src/components/DeviceInfoPanel.tsx b/apps/web/src/components/DeviceInfoPanel.tsx similarity index 99% rename from packages/web/src/components/DeviceInfoPanel.tsx rename to apps/web/src/components/DeviceInfoPanel.tsx index 5f3325e28..3df92d74b 100644 --- a/packages/web/src/components/DeviceInfoPanel.tsx +++ b/apps/web/src/components/DeviceInfoPanel.tsx @@ -1,6 +1,6 @@ import type { ConnectionStatus } from "@app/core/stores/deviceStore/types.ts"; import { cn } from "@core/utils/cn.ts"; -import type { Protobuf } from "@meshtastic/core"; +import type { Protobuf } from "@meshtastic/sdk"; import { useNavigate } from "@tanstack/react-router"; import { ChevronRight, diff --git a/packages/web/src/components/Dialog/AddConnectionDialog/AddConnectionDialog.tsx b/apps/web/src/components/Dialog/AddConnectionDialog/AddConnectionDialog.tsx similarity index 100% rename from packages/web/src/components/Dialog/AddConnectionDialog/AddConnectionDialog.tsx rename to apps/web/src/components/Dialog/AddConnectionDialog/AddConnectionDialog.tsx diff --git a/packages/web/src/components/Dialog/AddConnectionDialog/validation.ts b/apps/web/src/components/Dialog/AddConnectionDialog/validation.ts similarity index 100% rename from packages/web/src/components/Dialog/AddConnectionDialog/validation.ts rename to apps/web/src/components/Dialog/AddConnectionDialog/validation.ts diff --git a/packages/web/src/components/Dialog/ClearAllStoresDialog/ClearAllStoresDialog.test.tsx b/apps/web/src/components/Dialog/ClearAllStoresDialog/ClearAllStoresDialog.test.tsx similarity index 100% rename from packages/web/src/components/Dialog/ClearAllStoresDialog/ClearAllStoresDialog.test.tsx rename to apps/web/src/components/Dialog/ClearAllStoresDialog/ClearAllStoresDialog.test.tsx diff --git a/packages/web/src/components/Dialog/ClearAllStoresDialog/ClearAllStoresDialog.tsx b/apps/web/src/components/Dialog/ClearAllStoresDialog/ClearAllStoresDialog.tsx similarity index 100% rename from packages/web/src/components/Dialog/ClearAllStoresDialog/ClearAllStoresDialog.tsx rename to apps/web/src/components/Dialog/ClearAllStoresDialog/ClearAllStoresDialog.tsx diff --git a/packages/web/src/components/Dialog/ClientNotificationDialog/ClientNotificationDialog.tsx b/apps/web/src/components/Dialog/ClientNotificationDialog/ClientNotificationDialog.tsx similarity index 100% rename from packages/web/src/components/Dialog/ClientNotificationDialog/ClientNotificationDialog.tsx rename to apps/web/src/components/Dialog/ClientNotificationDialog/ClientNotificationDialog.tsx diff --git a/packages/web/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.test.tsx b/apps/web/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.test.tsx similarity index 68% rename from packages/web/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.test.tsx rename to apps/web/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.test.tsx index 6740bb548..0d2545e1f 100644 --- a/packages/web/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.test.tsx +++ b/apps/web/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.test.tsx @@ -1,33 +1,25 @@ import { DeleteMessagesDialog } from "@components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx"; -import { type MessageStore, useMessages } from "@core/stores"; +import { useActiveClient } from "@meshtastic/sdk-react"; import { fireEvent, render, screen } from "@testing-library/react"; import { beforeEach, describe, expect, it, vi } from "vitest"; -vi.mock("@core/stores", () => ({ - CurrentDeviceContext: { - _currentValue: { deviceId: 1234 }, - }, - useMessages: vi.fn(() => ({ - deleteAllMessages: vi.fn(), +const mockClearAll = vi.fn(); + +vi.mock("@meshtastic/sdk-react", () => ({ + useActiveClient: vi.fn(() => ({ + chat: { clearAll: mockClearAll }, })), })); describe("DeleteMessagesDialog", () => { const mockOnOpenChange = vi.fn(); - const mockClearAllMessages = vi.fn(); beforeEach(() => { mockOnOpenChange.mockClear(); - mockClearAllMessages.mockClear(); - - const mockedUseMessages = vi.mocked(useMessages); - mockedUseMessages.mockImplementation( - () => - ({ - deleteAllMessages: mockClearAllMessages, - }) as unknown as MessageStore, - ); - mockedUseMessages.mockClear(); + mockClearAll.mockClear(); + vi.mocked(useActiveClient).mockReturnValue({ + chat: { clearAll: mockClearAll }, + } as never); }); it("calls onOpenChange with false when the close button (X) is clicked", () => { @@ -59,15 +51,23 @@ describe("DeleteMessagesDialog", () => { it("calls onOpenChange with false when the dismiss button is clicked", () => { render(); fireEvent.click(screen.getByRole("button", { name: "Dismiss" })); - expect(mockOnOpenChange).toHaveBeenCalledTimes(1); // Add count check + expect(mockOnOpenChange).toHaveBeenCalledTimes(1); + expect(mockOnOpenChange).toHaveBeenCalledWith(false); + }); + + it("calls chat.clearAll and onOpenChange with false when Clear Messages is clicked", () => { + render(); + fireEvent.click(screen.getByRole("button", { name: "Clear Messages" })); + expect(mockClearAll).toHaveBeenCalledTimes(1); + expect(mockOnOpenChange).toHaveBeenCalledTimes(1); expect(mockOnOpenChange).toHaveBeenCalledWith(false); }); - it("calls deleteAllMessages and onOpenChange with false when the clear messages button is clicked", () => { + it("no-ops gracefully when there is no active client", () => { + vi.mocked(useActiveClient).mockReturnValue(undefined); render(); fireEvent.click(screen.getByRole("button", { name: "Clear Messages" })); - expect(mockClearAllMessages).toHaveBeenCalledTimes(1); - expect(mockOnOpenChange).toHaveBeenCalledTimes(1); // Add count check + expect(mockClearAll).not.toHaveBeenCalled(); expect(mockOnOpenChange).toHaveBeenCalledWith(false); }); }); diff --git a/packages/web/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx b/apps/web/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx similarity index 86% rename from packages/web/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx rename to apps/web/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx index d061dd3dc..64a63b452 100644 --- a/packages/web/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx +++ b/apps/web/src/components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx @@ -1,4 +1,4 @@ -import { useMessages } from "@app/core/stores/index.ts"; +import { useActiveClient } from "@meshtastic/sdk-react"; import { AlertTriangleIcon } from "lucide-react"; import { useTranslation } from "react-i18next"; import { DialogWrapper } from "../DialogWrapper.tsx"; @@ -10,10 +10,10 @@ export interface DeleteMessagesDialogProps { export const DeleteMessagesDialog = ({ open, onOpenChange }: DeleteMessagesDialogProps) => { const { t } = useTranslation("dialog"); - const messageStore = useMessages(); + const meshClient = useActiveClient(); const handleConfirm = () => { - messageStore.deleteAllMessages(); + void meshClient?.chat.clearAll(); onOpenChange(false); }; diff --git a/packages/web/src/components/Dialog/DialogManager.tsx b/apps/web/src/components/Dialog/DialogManager.tsx similarity index 97% rename from packages/web/src/components/Dialog/DialogManager.tsx rename to apps/web/src/components/Dialog/DialogManager.tsx index 811e35a77..2302915e2 100644 --- a/packages/web/src/components/Dialog/DialogManager.tsx +++ b/apps/web/src/components/Dialog/DialogManager.tsx @@ -16,7 +16,7 @@ import { UnsafeRolesDialog } from "@components/Dialog/UnsafeRolesDialog/UnsafeRo import { useDevice } from "@core/stores"; export const DialogManager = () => { - const { channels, config, dialog, setDialogOpen } = useDevice(); + const { config, dialog, setDialogOpen } = useDevice(); return ( <> { onOpenChange={(open) => { setDialogOpen("QR", open); }} - channels={channels} loraConfig={config.lora} /> { - // Make each store a callable fn (like a Zustand hook), and attach .getState() const useDeviceStore = Object.assign(vi.fn(), { getState: () => ({ removeDevice: mockRemoveDevice }), }); - const useMessageStore = Object.assign(vi.fn(), { - getState: () => ({ removeMessageStore: mockRemoveMessageStore }), - }); - const useNodeDBStore = Object.assign(vi.fn(), { - getState: () => ({ removeNodeDB: mockRemoveNodeDB }), - }); return { CurrentDeviceContext: { @@ -29,8 +20,6 @@ vi.mock("@core/stores", () => { connection: { factoryResetDevice: mockFactoryResetDevice }, }), useDeviceStore, - useMessageStore, - useNodeDBStore, }; }); @@ -45,13 +34,10 @@ describe("FactoryResetDeviceDialog", () => { mockOnOpenChange.mockClear(); mockFactoryResetDevice.mockReset(); mockRemoveDevice.mockClear(); - mockRemoveMessageStore.mockClear(); - mockRemoveNodeDB.mockClear(); mockToast.mockClear(); }); - it("calls factoryResetDevice, closes dialog, and after reset resolves clears messages and node DB", async () => { - // Control the promise returned by factoryResetDevice + it("calls factoryResetDevice, closes dialog, and after reset resolves removes the device", async () => { let resolveReset: (() => void) | undefined; mockFactoryResetDevice.mockImplementation( () => @@ -63,21 +49,16 @@ describe("FactoryResetDeviceDialog", () => { render(); fireEvent.click(screen.getByRole("button", { name: "Factory Reset Device" })); - // Called immediately expect(mockFactoryResetDevice).toHaveBeenCalledTimes(1); - // DialogWrapper awaits onConfirm (which returns undefined), so close happens on next microtask await waitFor(() => { expect(mockOnOpenChange).toHaveBeenCalledTimes(1); expect(mockOnOpenChange).toHaveBeenCalledWith(false); }); - // Resolve the reset resolveReset?.(); expect(mockRemoveDevice).toHaveBeenCalledTimes(1); - expect(mockRemoveMessageStore).toHaveBeenCalledTimes(1); - expect(mockRemoveNodeDB).toHaveBeenCalledTimes(1); }); it("calls onOpenChange(false) and does not call factoryResetDevice when cancel is clicked", async () => { @@ -91,7 +72,5 @@ describe("FactoryResetDeviceDialog", () => { expect(mockFactoryResetDevice).not.toHaveBeenCalled(); expect(mockRemoveDevice).not.toHaveBeenCalled(); - expect(mockRemoveMessageStore).not.toHaveBeenCalled(); - expect(mockRemoveNodeDB).not.toHaveBeenCalled(); }); }); diff --git a/packages/web/src/components/Dialog/FactoryResetDeviceDialog/FactoryResetDeviceDialog.tsx b/apps/web/src/components/Dialog/FactoryResetDeviceDialog/FactoryResetDeviceDialog.tsx similarity index 87% rename from packages/web/src/components/Dialog/FactoryResetDeviceDialog/FactoryResetDeviceDialog.tsx rename to apps/web/src/components/Dialog/FactoryResetDeviceDialog/FactoryResetDeviceDialog.tsx index bf03e9692..42c90fcac 100644 --- a/packages/web/src/components/Dialog/FactoryResetDeviceDialog/FactoryResetDeviceDialog.tsx +++ b/apps/web/src/components/Dialog/FactoryResetDeviceDialog/FactoryResetDeviceDialog.tsx @@ -1,5 +1,5 @@ import { toast } from "@core/hooks/useToast.ts"; -import { useDevice, useDeviceStore, useMessageStore, useNodeDBStore } from "@core/stores"; +import { useDevice, useDeviceStore } from "@core/stores"; import { useTranslation } from "react-i18next"; import { DialogWrapper } from "../DialogWrapper.tsx"; @@ -23,8 +23,6 @@ export const FactoryResetDeviceDialog = ({ open, onOpenChange }: FactoryResetDev // The device will be wiped and disconnected without resolving the promise // so we proceed to clear all data associated with the device immediately useDeviceStore.getState().removeDevice(id); - useMessageStore.getState().removeMessageStore(id); - useNodeDBStore.getState().removeNodeDB(id); // Reload the app to ensure all ephemeral state is cleared window.location.href = "/"; diff --git a/packages/web/src/components/Dialog/ImportDialog.tsx b/apps/web/src/components/Dialog/ImportDialog.tsx similarity index 92% rename from packages/web/src/components/Dialog/ImportDialog.tsx rename to apps/web/src/components/Dialog/ImportDialog.tsx index bfbcf6f9d..ea33a7ea8 100644 --- a/packages/web/src/components/Dialog/ImportDialog.tsx +++ b/apps/web/src/components/Dialog/ImportDialog.tsx @@ -20,8 +20,8 @@ import { } from "@components/UI/Select.tsx"; import { Switch } from "@components/UI/Switch.tsx"; import { useDevice } from "@core/stores"; -import { deepCompareConfig } from "@core/utils/deepCompareConfig.ts"; -import { Protobuf } from "@meshtastic/core"; +import { Protobuf } from "@meshtastic/sdk"; +import { useConfigEditor } from "@meshtastic/sdk-react"; import { toByteArray } from "base64-js"; import { useEffect, useState } from "react"; import { Trans, useTranslation } from "react-i18next"; @@ -33,7 +33,8 @@ export interface ImportDialogProps { } export const ImportDialog = ({ open, onOpenChange }: ImportDialogProps) => { - const { setChange, channels, config } = useDevice(); + const { config } = useDevice(); + const editor = useConfigEditor(); const { t } = useTranslation("dialog"); const [importDialogInput, setImportDialogInput] = useState(""); const [channelSet, setChannelSet] = useState(); @@ -77,6 +78,7 @@ export const ImportDialog = ({ open, onOpenChange }: ImportDialogProps) => { }, [importDialogInput, t]); const apply = () => { + if (!editor) return; channelSet?.settings.forEach((ch: Protobuf.Channel.ChannelSettings, index: number) => { if (importIndex[index] === -1) { return; @@ -91,24 +93,15 @@ export const ImportDialog = ({ open, onOpenChange }: ImportDialogProps) => { settings: ch, }); - if (!deepCompareConfig(channels.get(importIndex[index] ?? 0), payload, true)) { - setChange( - { type: "channel", index: importIndex[index] ?? 0 }, - payload, - channels.get(importIndex[index] ?? 0), - ); - } + editor.setChannel(payload); }); if (channelSet?.loraConfig && updateConfig) { const payload = { ...config.lora, ...channelSet.loraConfig, - }; - - if (!deepCompareConfig(config.lora, payload, true)) { - setChange({ type: "config", variant: "lora" }, payload, config.lora); - } + } as Protobuf.Config.Config_LoRaConfig; + editor.setRadioSection("lora", payload); } // Reset state after import setImportDialogInput(""); diff --git a/packages/web/src/components/Dialog/LocationResponseDialog.tsx b/apps/web/src/components/Dialog/LocationResponseDialog.tsx similarity index 93% rename from packages/web/src/components/Dialog/LocationResponseDialog.tsx rename to apps/web/src/components/Dialog/LocationResponseDialog.tsx index b313cbd20..25d3d3994 100644 --- a/packages/web/src/components/Dialog/LocationResponseDialog.tsx +++ b/apps/web/src/components/Dialog/LocationResponseDialog.tsx @@ -1,5 +1,5 @@ -import { useNodeDB } from "@core/stores"; -import type { Protobuf, Types } from "@meshtastic/core"; +import { useNodeAsProto } from "@core/hooks/useNodesAsProto.ts"; +import type { Protobuf, Types } from "@meshtastic/sdk"; import { numberToHexUnpadded } from "@noble/curves/abstract/utils"; import { useTranslation } from "react-i18next"; import { @@ -23,9 +23,7 @@ export const LocationResponseDialog = ({ onOpenChange, }: LocationResponseDialogProps) => { const { t } = useTranslation("dialog"); - const { getNode } = useNodeDB(); - - const from = getNode(location?.from ?? 0); + const from = useNodeAsProto(location?.from ?? 0); const longName = from?.user?.longName ?? (from ? `!${numberToHexUnpadded(from?.num)}` : t("unknown.shortName")); const shortName = diff --git a/packages/web/src/components/Dialog/ManagedModeDialog.tsx b/apps/web/src/components/Dialog/ManagedModeDialog.tsx similarity index 100% rename from packages/web/src/components/Dialog/ManagedModeDialog.tsx rename to apps/web/src/components/Dialog/ManagedModeDialog.tsx diff --git a/packages/web/src/components/Dialog/NewDeviceDialog.tsx b/apps/web/src/components/Dialog/NewDeviceDialog.tsx similarity index 100% rename from packages/web/src/components/Dialog/NewDeviceDialog.tsx rename to apps/web/src/components/Dialog/NewDeviceDialog.tsx diff --git a/packages/web/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx b/apps/web/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx similarity index 98% rename from packages/web/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx rename to apps/web/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx index 16a292f46..0ee7001c0 100644 --- a/packages/web/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx +++ b/apps/web/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx @@ -27,9 +27,10 @@ import { import { useFavoriteNode } from "@core/hooks/useFavoriteNode.ts"; import { useIgnoreNode } from "@core/hooks/useIgnoreNode.ts"; import { toast } from "@core/hooks/useToast.ts"; -import { useAppStore, useDevice, useNodeDB } from "@core/stores"; +import { useNodeAsProto } from "@core/hooks/useNodesAsProto.ts"; +import { useAppStore, useDevice } from "@core/stores"; import { cn } from "@core/utils/cn.ts"; -import { Protobuf } from "@meshtastic/core"; +import { Protobuf } from "@meshtastic/sdk"; import { numberToHexUnpadded } from "@noble/curves/abstract/utils"; import { useNavigate } from "@tanstack/react-router"; import { fromByteArray } from "base64-js"; @@ -53,13 +54,12 @@ export interface NodeDetailsDialogProps { export const NodeDetailsDialog = ({ open, onOpenChange }: NodeDetailsDialogProps) => { const { t } = useTranslation("dialog"); const { setDialogOpen, connection } = useDevice(); - const { getNode } = useNodeDB(); const navigate = useNavigate(); const { setNodeNumToBeRemoved, nodeNumDetails } = useAppStore(); const { updateFavorite } = useFavoriteNode(); const { updateIgnored } = useIgnoreNode(); - const node = getNode(nodeNumDetails); + const node = useNodeAsProto(nodeNumDetails); const [isFavoriteState, setIsFavoriteState] = useState(node?.isFavorite ?? false); const [isIgnoredState, setIsIgnoredState] = useState(node?.isIgnored ?? false); diff --git a/packages/web/src/components/Dialog/PKIBackupDialog.tsx b/apps/web/src/components/Dialog/PKIBackupDialog.tsx similarity index 83% rename from packages/web/src/components/Dialog/PKIBackupDialog.tsx rename to apps/web/src/components/Dialog/PKIBackupDialog.tsx index 78ed2271c..4d7fa01cc 100644 --- a/packages/web/src/components/Dialog/PKIBackupDialog.tsx +++ b/apps/web/src/components/Dialog/PKIBackupDialog.tsx @@ -8,7 +8,8 @@ import { DialogHeader, DialogTitle, } from "@components/UI/Dialog.tsx"; -import { useDevice, useNodeDB } from "@core/stores"; +import { useMyNodeAsProto } from "@core/hooks/useNodesAsProto.ts"; +import { useDevice } from "@core/stores"; import { fromByteArray } from "base64-js"; import { DownloadIcon, PrinterIcon } from "lucide-react"; import React from "react"; @@ -22,7 +23,7 @@ export interface PkiBackupDialogProps { export const PkiBackupDialog = ({ open, onOpenChange }: PkiBackupDialogProps) => { const { t } = useTranslation("dialog"); const { config, setDialogOpen } = useDevice(); - const { getMyNode } = useNodeDB(); + const myNode = useMyNodeAsProto(); const privateKey = config.security?.privateKey; const publicKey = config.security?.publicKey; @@ -49,8 +50,8 @@ export const PkiBackupDialog = ({ open, onOpenChange }: PkiBackupDialogProps) => ${t("pkiBackup.header", { interpolation: { escapeValue: false }, - shortName: getMyNode()?.user?.shortName ?? t("unknown.shortName"), - longName: getMyNode()?.user?.longName ?? t("unknown.longName"), + shortName: myNode?.user?.shortName ?? t("unknown.shortName"), + longName: myNode?.user?.longName ?? t("unknown.longName"), })}