4 Commits

Author SHA1 Message Date
Markus Unterwaditzer
4d54ea03e8 Remove some global reset styles in favor of explicit border colors, restore button cursors 2026-04-24 02:00:57 +02:00
Markus Unterwaditzer
2b427c64d7 upgrade tailwind
* moved to vite plugin for tailwind (it's recommended now)
* removed autoprefixer (v4 uses its own CSS thing now)
* postcss.config.js was used to wire up tailwind and autoprefixer, so
  it's gone
* tailwind.config.ts is gone, because v4 stores config in app.css using
  css variables
* fixed some renamed classes
2026-04-24 01:58:53 +02:00
Markus Unterwaditzer
ed3ad389d0 downgrade tailwind for now, and fix build errors 2026-04-24 01:58:53 +02:00
dependabot[bot]
e2fd9de62d Bump the dependency-type group in /daemon/web with 18 updates
Bumps the dependency-type group in /daemon/web with 18 updates:

| Package | From | To |
| --- | --- | --- |
| [@sveltejs/adapter-auto](https://github.com/sveltejs/kit/tree/HEAD/packages/adapter-auto) | `3.3.1` | `7.0.1` |
| [@sveltejs/kit](https://github.com/sveltejs/kit/tree/HEAD/packages/kit) | `2.53.4` | `2.57.1` |
| [@sveltejs/vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte/tree/HEAD/packages/vite-plugin-svelte) | `6.2.1` | `7.0.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `24.7.0` | `25.6.0` |
| [autoprefixer](https://github.com/postcss/autoprefixer) | `10.4.21` | `10.5.0` |
| [eslint](https://github.com/eslint/eslint) | `9.37.0` | `10.2.0` |
| [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) | `9.1.2` | `10.1.8` |
| [eslint-plugin-svelte](https://github.com/sveltejs/eslint-plugin-svelte/tree/HEAD/packages/eslint-plugin-svelte) | `2.46.1` | `3.17.0` |
| [globals](https://github.com/sindresorhus/globals) | `15.15.0` | `17.5.0` |
| [prettier](https://github.com/prettier/prettier) | `3.6.2` | `3.8.3` |
| [prettier-plugin-svelte](https://github.com/sveltejs/prettier-plugin-svelte) | `3.4.0` | `3.5.1` |
| [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte) | `5.53.7` | `5.55.4` |
| [svelte-check](https://github.com/sveltejs/language-tools) | `4.3.2` | `4.4.6` |
| [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `3.4.18` | `4.2.2` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.9.3` | `6.0.2` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.46.0` | `8.58.2` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `7.3.2` | `8.0.8` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `3.2.4` | `4.1.4` |


Updates `@sveltejs/adapter-auto` from 3.3.1 to 7.0.1
- [Release notes](https://github.com/sveltejs/kit/releases)
- [Changelog](https://github.com/sveltejs/kit/blob/main/packages/adapter-auto/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/kit/commits/@sveltejs/adapter-auto@7.0.1/packages/adapter-auto)

Updates `@sveltejs/kit` from 2.53.4 to 2.57.1
- [Release notes](https://github.com/sveltejs/kit/releases)
- [Changelog](https://github.com/sveltejs/kit/blob/main/packages/kit/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/kit/commits/@sveltejs/kit@2.57.1/packages/kit)

Updates `@sveltejs/vite-plugin-svelte` from 6.2.1 to 7.0.0
- [Release notes](https://github.com/sveltejs/vite-plugin-svelte/releases)
- [Changelog](https://github.com/sveltejs/vite-plugin-svelte/blob/main/packages/vite-plugin-svelte/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/vite-plugin-svelte/commits/@sveltejs/vite-plugin-svelte@7.0.0/packages/vite-plugin-svelte)

Updates `@types/node` from 24.7.0 to 25.6.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `autoprefixer` from 10.4.21 to 10.5.0
- [Release notes](https://github.com/postcss/autoprefixer/releases)
- [Changelog](https://github.com/postcss/autoprefixer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/autoprefixer/compare/10.4.21...10.5.0)

Updates `eslint` from 9.37.0 to 10.2.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.37.0...v10.2.0)

Updates `eslint-config-prettier` from 9.1.2 to 10.1.8
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/commits/v10.1.8)

Updates `eslint-plugin-svelte` from 2.46.1 to 3.17.0
- [Release notes](https://github.com/sveltejs/eslint-plugin-svelte/releases)
- [Changelog](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/eslint-plugin-svelte/commits/eslint-plugin-svelte@3.17.0/packages/eslint-plugin-svelte)

Updates `globals` from 15.15.0 to 17.5.0
- [Release notes](https://github.com/sindresorhus/globals/releases)
- [Commits](https://github.com/sindresorhus/globals/compare/v15.15.0...v17.5.0)

Updates `prettier` from 3.6.2 to 3.8.3
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.6.2...3.8.3)

Updates `prettier-plugin-svelte` from 3.4.0 to 3.5.1
- [Changelog](https://github.com/sveltejs/prettier-plugin-svelte/blob/v3.5.1/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/prettier-plugin-svelte/commits/v3.5.1)

Updates `svelte` from 5.53.7 to 5.55.4
- [Release notes](https://github.com/sveltejs/svelte/releases)
- [Changelog](https://github.com/sveltejs/svelte/blob/main/packages/svelte/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/svelte/commits/svelte@5.55.4/packages/svelte)

Updates `svelte-check` from 4.3.2 to 4.4.6
- [Release notes](https://github.com/sveltejs/language-tools/releases)
- [Commits](https://github.com/sveltejs/language-tools/compare/svelte-check@4.3.2...svelte-check@4.4.6)

Updates `tailwindcss` from 3.4.18 to 4.2.2
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.2.2/packages/tailwindcss)

Updates `typescript` from 5.9.3 to 6.0.2
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.9.3...v6.0.2)

Updates `typescript-eslint` from 8.46.0 to 8.58.2
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.58.2/packages/typescript-eslint)

Updates `vite` from 7.3.2 to 8.0.8
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.8/packages/vite)

Updates `vitest` from 3.2.4 to 4.1.4
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.4/packages/vitest)

---
updated-dependencies:
- dependency-name: "@sveltejs/adapter-auto"
  dependency-version: 7.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dependency-type
- dependency-name: "@sveltejs/kit"
  dependency-version: 2.57.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dependency-type
- dependency-name: "@sveltejs/vite-plugin-svelte"
  dependency-version: 7.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dependency-type
- dependency-name: "@types/node"
  dependency-version: 25.6.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dependency-type
- dependency-name: autoprefixer
  dependency-version: 10.5.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dependency-type
- dependency-name: eslint
  dependency-version: 10.2.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dependency-type
- dependency-name: eslint-config-prettier
  dependency-version: 10.1.8
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dependency-type
- dependency-name: eslint-plugin-svelte
  dependency-version: 3.17.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dependency-type
- dependency-name: globals
  dependency-version: 17.5.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dependency-type
- dependency-name: prettier
  dependency-version: 3.8.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dependency-type
- dependency-name: prettier-plugin-svelte
  dependency-version: 3.5.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dependency-type
- dependency-name: svelte
  dependency-version: 5.55.4
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dependency-type
- dependency-name: svelte-check
  dependency-version: 4.4.6
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dependency-type
- dependency-name: tailwindcss
  dependency-version: 4.2.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dependency-type
- dependency-name: typescript
  dependency-version: 6.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dependency-type
- dependency-name: typescript-eslint
  dependency-version: 8.58.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dependency-type
- dependency-name: vite
  dependency-version: 8.0.8
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dependency-type
- dependency-name: vitest
  dependency-version: 4.1.4
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: dependency-type
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-24 01:58:53 +02:00
18 changed files with 1424 additions and 2989 deletions

View File

@@ -22,7 +22,7 @@ export default ts.config(
}, },
}, },
{ {
files: ['**/*.svelte'], files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
languageOptions: { languageOptions: {
parserOptions: { parserOptions: {
@@ -48,6 +48,11 @@ export default ts.config(
format: ['snake_case'], format: ['snake_case'],
}, },
], ],
// these rules should eventually be enabled, just disabled them to
// make dependency upgrades easier.
'svelte/prefer-svelte-reactivity': 'off',
'svelte/require-each-key': 'off',
'svelte/no-navigation-without-resolve': 'off',
}, },
} }
); );

File diff suppressed because it is too large Load Diff

View File

@@ -15,25 +15,26 @@
"fix": "eslint --fix ." "fix": "eslint --fix ."
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/adapter-auto": "^3.0.0", "@eslint/js": "^10.0.1",
"@sveltejs/adapter-auto": "^7.0.1",
"@sveltejs/adapter-static": "^3.0.5", "@sveltejs/adapter-static": "^3.0.5",
"@sveltejs/kit": "^2.53.4", "@sveltejs/kit": "^2.57.1",
"@sveltejs/vite-plugin-svelte": "^6.2.1", "@sveltejs/vite-plugin-svelte": "^7.0.0",
"@tailwindcss/vite": "^4.2.2",
"@types/eslint": "^9.6.0", "@types/eslint": "^9.6.0",
"@types/node": "^24.7.0", "@types/node": "^25.6.0",
"autoprefixer": "^10.4.20", "eslint": "^10.2.1",
"eslint": "^9.7.0", "eslint-config-prettier": "^10.1.8",
"eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^3.17.0",
"eslint-plugin-svelte": "^2.36.0", "globals": "^17.5.0",
"globals": "^15.0.0", "prettier": "^3.8.3",
"prettier": "^3.3.2", "prettier-plugin-svelte": "^3.5.1",
"prettier-plugin-svelte": "^3.2.6", "svelte": "^5.55.4",
"svelte": "^5.53.7", "svelte-check": "^4.4.6",
"svelte-check": "^4.0.0", "tailwindcss": "^4.2.2",
"tailwindcss": "^3.4.9", "typescript": "^6.0.3",
"typescript": "^5.0.0", "typescript-eslint": "^8.58.2",
"typescript-eslint": "^8.0.0", "vite": "^8.0.9",
"vite": "^7.3.2", "vitest": "^4.1.4"
"vitest": "^3.2.4"
} }
} }

View File

@@ -1,6 +0,0 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

View File

@@ -1,3 +1,16 @@
@import 'tailwindcss/base'; @import 'tailwindcss';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities'; @theme {
--color-rayhunter-blue: #4e4eb1;
--color-rayhunter-dark-blue: #3f3da0;
--color-rayhunter-green: #94ea18;
}
/* v4 dropped the v3 preflight rule that set `cursor: pointer` on buttons.
* Restore it so enabled buttons get the pointer cursor. */
@layer base {
button:not(:disabled),
[role='button']:not(:disabled) {
cursor: pointer;
}
}

View File

@@ -20,7 +20,7 @@
{#if action_errors.length > 0} {#if action_errors.length > 0}
<div <div
class="bg-red-100 border-red-100 drop-shadow p-4 flex flex-col gap-2 class="bg-red-100 border-red-100 drop-shadow-sm p-4 flex flex-col gap-2
border rounded-md flex-1 justify-between fixed z-10 right-3 bottom-3 ml-3" border rounded-md flex-1 justify-between fixed z-10 right-3 bottom-3 ml-3"
> >
<div class="flex flex-row justify-between"> <div class="flex flex-row justify-between">

View File

@@ -55,7 +55,7 @@
{#if show_alert} {#if show_alert}
<div <div
class="bg-yellow-100 border-yellow-400 drop-shadow p-4 flex flex-col gap-2 border rounded-md" class="bg-yellow-100 border-yellow-400 drop-shadow-sm p-4 flex flex-col gap-2 border rounded-md"
> >
<span class="text-xl font-bold flex flex-row items-center gap-2 text-yellow-700"> <span class="text-xl font-bold flex flex-row items-center gap-2 text-yellow-700">
<svg <svg

View File

@@ -164,7 +164,7 @@
<select <select
id="ui_level" id="ui_level"
bind:value={config.ui_level} bind:value={config.ui_level}
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-rayhunter-blue" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-rayhunter-blue"
> >
<option value={0}>0 - Invisible mode</option> <option value={0}>0 - Invisible mode</option>
<option value={1}>1 - Subtle mode (colored line)</option> <option value={1}>1 - Subtle mode (colored line)</option>
@@ -188,7 +188,7 @@
<select <select
id="key_input_mode" id="key_input_mode"
bind:value={config.key_input_mode} bind:value={config.key_input_mode}
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-rayhunter-blue" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-rayhunter-blue"
> >
<option value={0}>0 - Disable button control</option> <option value={0}>0 - Disable button control</option>
<option value={1}>1 - Double-tap power button to start new recording</option <option value={1}>1 - Double-tap power button to start new recording</option
@@ -202,7 +202,7 @@
id="colorblind_mode" id="colorblind_mode"
type="checkbox" type="checkbox"
bind:checked={config.colorblind_mode} bind:checked={config.colorblind_mode}
class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded" class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded-sm"
/> />
<label for="colorblind_mode" class="ml-2 block text-sm text-gray-700"> <label for="colorblind_mode" class="ml-2 block text-sm text-gray-700">
Colorblind Mode Colorblind Mode
@@ -210,7 +210,7 @@
</div> </div>
</div> </div>
<div class="border-t pt-4 mt-6 space-y-3"> <div class="border-t border-gray-200 pt-4 mt-6 space-y-3">
<h3 class="text-lg font-semibold text-gray-800 mb-4">Notification Settings</h3> <h3 class="text-lg font-semibold text-gray-800 mb-4">Notification Settings</h3>
<div> <div>
<label for="ntfy_url" class="block text-sm font-medium text-gray-700 mb-1"> <label for="ntfy_url" class="block text-sm font-medium text-gray-700 mb-1">
@@ -221,7 +221,7 @@
id="ntfy_url" id="ntfy_url"
type="url" type="url"
bind:value={config.ntfy_url} bind:value={config.ntfy_url}
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-rayhunter-blue" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-rayhunter-blue"
/> />
<p class="text-xs text-gray-500 mt-1"> <p class="text-xs text-gray-500 mt-1">
Test button below uses the saved configuration URL, not the input above Test button below uses the saved configuration URL, not the input above
@@ -259,7 +259,7 @@
</button> </button>
{#if testMessage} {#if testMessage}
<div <div
class="mt-2 p-2 rounded text-sm {testMessageType === 'error' class="mt-2 p-2 rounded-sm text-sm {testMessageType === 'error'
? 'bg-red-100 text-red-700' ? 'bg-red-100 text-red-700'
: 'bg-green-100 text-green-700'}" : 'bg-green-100 text-green-700'}"
> >
@@ -303,7 +303,7 @@
</div> </div>
</div> </div>
<div class="border-t pt-4 mt-6 space-y-3"> <div class="border-t border-gray-200 pt-4 mt-6 space-y-3">
<h3 class="text-lg font-semibold text-gray-800 mb-4">Storage Management</h3> <h3 class="text-lg font-semibold text-gray-800 mb-4">Storage Management</h3>
<div> <div>
@@ -318,7 +318,7 @@
type="number" type="number"
min="1" min="1"
bind:value={config.min_space_to_start_recording_mb} bind:value={config.min_space_to_start_recording_mb}
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-rayhunter-blue" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-rayhunter-blue"
/> />
<p class="text-xs text-gray-500 mt-1"> <p class="text-xs text-gray-500 mt-1">
Recording will not start if less than this amount of disk space is free Recording will not start if less than this amount of disk space is free
@@ -337,7 +337,7 @@
type="number" type="number"
min="1" min="1"
bind:value={config.min_space_to_continue_recording_mb} bind:value={config.min_space_to_continue_recording_mb}
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-rayhunter-blue" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-rayhunter-blue"
/> />
<p class="text-xs text-gray-500 mt-1"> <p class="text-xs text-gray-500 mt-1">
Recording will stop automatically if disk space drops below this level Recording will stop automatically if disk space drops below this level
@@ -346,7 +346,7 @@
</div> </div>
{#if config.device === 'orbic' || config.device === 'moxee' || config.device === 'tmobile' || config.device === 'wingtech'} {#if config.device === 'orbic' || config.device === 'moxee' || config.device === 'tmobile' || config.device === 'wingtech'}
<div class="border-t pt-4 mt-6 space-y-3"> <div class="border-t border-gray-200 pt-4 mt-6 space-y-3">
<h3 class="text-lg font-semibold text-gray-800 mb-4">WiFi Client Mode</h3> <h3 class="text-lg font-semibold text-gray-800 mb-4">WiFi Client Mode</h3>
<p class="text-xs text-gray-500"> <p class="text-xs text-gray-500">
Connect the device to an existing WiFi network for internet access (e.g. Connect the device to an existing WiFi network for internet access (e.g.
@@ -359,7 +359,7 @@
id="wifi_enabled" id="wifi_enabled"
type="checkbox" type="checkbox"
bind:checked={config.wifi_enabled} bind:checked={config.wifi_enabled}
class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded" class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded-sm"
/> />
<label for="wifi_enabled" class="ml-2 block text-sm text-gray-700"> <label for="wifi_enabled" class="ml-2 block text-sm text-gray-700">
Enable WiFi Enable WiFi
@@ -402,7 +402,7 @@
type="text" type="text"
bind:value={config.wifi_ssid} bind:value={config.wifi_ssid}
placeholder="MyWiFiNetwork" placeholder="MyWiFiNetwork"
class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-rayhunter-blue" class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-rayhunter-blue"
/> />
<button <button
type="button" type="button"
@@ -421,7 +421,7 @@
{#if scanResults.length > 0} {#if scanResults.length > 0}
<div <div
class="border border-gray-200 rounded-md max-h-40 overflow-y-auto divide-y" class="border border-gray-200 rounded-md max-h-40 overflow-y-auto divide-y divide-gray-200"
> >
{#each scanResults as network} {#each scanResults as network}
<button <button
@@ -449,7 +449,7 @@
<select <select
id="wifi_security" id="wifi_security"
bind:value={config.wifi_security} bind:value={config.wifi_security}
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-rayhunter-blue" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-rayhunter-blue"
> >
<option value="wpa_psk">WPA2 (WPA-PSK)</option> <option value="wpa_psk">WPA2 (WPA-PSK)</option>
<option value="sae">WPA3 (SAE)</option> <option value="sae">WPA3 (SAE)</option>
@@ -469,7 +469,7 @@
type="password" type="password"
bind:value={config.wifi_password} bind:value={config.wifi_password}
placeholder="Enter password" placeholder="Enter password"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-rayhunter-blue" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-rayhunter-blue"
/> />
<p class="text-xs text-gray-500 mt-1"> <p class="text-xs text-gray-500 mt-1">
Changing the network requires re-entering the password. Changing the network requires re-entering the password.
@@ -489,7 +489,7 @@
type="text" type="text"
bind:value={dnsServersInput} bind:value={dnsServersInput}
placeholder="9.9.9.9, 149.112.112.112" placeholder="9.9.9.9, 149.112.112.112"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-rayhunter-blue" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-rayhunter-blue"
/> />
<p class="text-xs text-gray-500 mt-1"> <p class="text-xs text-gray-500 mt-1">
Comma-separated. Used when WiFi is active. Defaults to 9.9.9.9, Comma-separated. Used when WiFi is active. Defaults to 9.9.9.9,
@@ -500,7 +500,7 @@
</div> </div>
{/if} {/if}
<div class="border-t pt-4 mt-6 space-y-3"> <div class="border-t border-gray-200 pt-4 mt-6 space-y-3">
<h3 class="text-lg font-semibold text-gray-800 mb-4">Device Security</h3> <h3 class="text-lg font-semibold text-gray-800 mb-4">Device Security</h3>
<div class="flex items-center"> <div class="flex items-center">
@@ -508,7 +508,7 @@
id="firewall_restrict_outbound" id="firewall_restrict_outbound"
type="checkbox" type="checkbox"
bind:checked={config.firewall_restrict_outbound} bind:checked={config.firewall_restrict_outbound}
class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded" class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded-sm"
/> />
<label <label
for="firewall_restrict_outbound" for="firewall_restrict_outbound"
@@ -548,7 +548,7 @@
: null; : null;
}} }}
placeholder="22, 80" placeholder="22, 80"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-rayhunter-blue" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-rayhunter-blue"
/> />
<p class="text-xs text-gray-500 mt-1"> <p class="text-xs text-gray-500 mt-1">
Comma-separated TCP ports, e.g. 22, 80 Comma-separated TCP ports, e.g. 22, 80
@@ -557,7 +557,7 @@
{/if} {/if}
</div> </div>
<div class="border-t pt-4 mt-6"> <div class="border-t border-gray-200 pt-4 mt-6">
<h3 class="text-lg font-semibold text-gray-800 mb-4"> <h3 class="text-lg font-semibold text-gray-800 mb-4">
Analyzer Heuristic Settings Analyzer Heuristic Settings
</h3> </h3>
@@ -567,7 +567,7 @@
id="imsi_requested" id="imsi_requested"
type="checkbox" type="checkbox"
bind:checked={config.analyzers.imsi_requested} bind:checked={config.analyzers.imsi_requested}
class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded" class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded-sm"
/> />
<label for="imsi_requested" class="ml-2 block text-sm text-gray-700"> <label for="imsi_requested" class="ml-2 block text-sm text-gray-700">
IMSI Requested Heuristic IMSI Requested Heuristic
@@ -579,7 +579,7 @@
id="connection_redirect_2g_downgrade" id="connection_redirect_2g_downgrade"
type="checkbox" type="checkbox"
bind:checked={config.analyzers.connection_redirect_2g_downgrade} bind:checked={config.analyzers.connection_redirect_2g_downgrade}
class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded" class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded-sm"
/> />
<label <label
for="connection_redirect_2g_downgrade" for="connection_redirect_2g_downgrade"
@@ -594,7 +594,7 @@
id="lte_sib6_and_7_downgrade" id="lte_sib6_and_7_downgrade"
type="checkbox" type="checkbox"
bind:checked={config.analyzers.lte_sib6_and_7_downgrade} bind:checked={config.analyzers.lte_sib6_and_7_downgrade}
class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded" class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded-sm"
/> />
<label <label
for="lte_sib6_and_7_downgrade" for="lte_sib6_and_7_downgrade"
@@ -609,7 +609,7 @@
id="null_cipher" id="null_cipher"
type="checkbox" type="checkbox"
bind:checked={config.analyzers.null_cipher} bind:checked={config.analyzers.null_cipher}
class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded" class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded-sm"
/> />
<label for="null_cipher" class="ml-2 block text-sm text-gray-700"> <label for="null_cipher" class="ml-2 block text-sm text-gray-700">
Null Cipher Heuristic Null Cipher Heuristic
@@ -621,7 +621,7 @@
id="nas_null_cipher" id="nas_null_cipher"
type="checkbox" type="checkbox"
bind:checked={config.analyzers.nas_null_cipher} bind:checked={config.analyzers.nas_null_cipher}
class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded" class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded-sm"
/> />
<label for="nas_null_cipher" class="ml-2 block text-sm text-gray-700"> <label for="nas_null_cipher" class="ml-2 block text-sm text-gray-700">
NAS Null Cipher Heuristic NAS Null Cipher Heuristic
@@ -633,7 +633,7 @@
id="incomplete_sib" id="incomplete_sib"
type="checkbox" type="checkbox"
bind:checked={config.analyzers.incomplete_sib} bind:checked={config.analyzers.incomplete_sib}
class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded" class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded-sm"
/> />
<label for="incomplete_sib" class="ml-2 block text-sm text-gray-700"> <label for="incomplete_sib" class="ml-2 block text-sm text-gray-700">
Incomplete SIB Heuristic Incomplete SIB Heuristic
@@ -645,7 +645,7 @@
id="test_analyzer" id="test_analyzer"
type="checkbox" type="checkbox"
bind:checked={config.analyzers.test_analyzer} bind:checked={config.analyzers.test_analyzer}
class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded" class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded-sm"
/> />
<label for="test_analyzer" class="ml-2 block text-sm text-gray-700"> <label for="test_analyzer" class="ml-2 block text-sm text-gray-700">
Test Heuristic (noisy!) Test Heuristic (noisy!)
@@ -656,7 +656,7 @@
id="diagnostic_analyzer" id="diagnostic_analyzer"
type="checkbox" type="checkbox"
bind:checked={config.analyzers.diagnostic_analyzer} bind:checked={config.analyzers.diagnostic_analyzer}
class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded" class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded-sm"
/> />
<label <label
for="diagnostic_analyzer" for="diagnostic_analyzer"
@@ -700,7 +700,7 @@
</form> </form>
{#if message} {#if message}
<div <div
class="mt-4 p-3 rounded {messageType === 'error' class="mt-4 p-3 rounded-sm {messageType === 'error'
? 'bg-red-100 text-red-700' ? 'bg-red-100 text-red-700'
: 'bg-green-100 text-green-700'}" : 'bg-green-100 text-green-700'}"
> >

View File

@@ -5,8 +5,8 @@
<div class="flex flex-row justify-end gap-2"> <div class="flex flex-row justify-end gap-2">
<DeleteButton <DeleteButton
text="Delete ALL Recordings" text="Delete ALL Recordings"
prompt={`Are you sure you want to delete ALL recordings?`} prompt="Are you sure you want to delete ALL recordings?"
url={`/api/delete-all-recordings`} url="/api/delete-all-recordings"
name="all recodings" name="all recodings"
/> />
</div> </div>

View File

@@ -44,7 +44,7 @@
</script> </script>
<div <div
class="{status_row_color} {status_border_color} drop-shadow p-4 flex flex-col gap-2 border rounded-md flex-1 overflow-x-auto overflow-y-hidden" class="{status_row_color} {status_border_color} drop-shadow-sm p-4 flex flex-col gap-2 border rounded-md flex-1 overflow-x-auto overflow-y-hidden"
> >
{#if current} {#if current}
<div class="flex flex-row justify-between gap-2"> <div class="flex flex-row justify-between gap-2">
@@ -82,7 +82,7 @@
> >
</div> </div>
{#if entry.stop_reason} {#if entry.stop_reason}
<div class="bg-yellow-50 border border-yellow-300 rounded p-2 text-yellow-800 text-sm"> <div class="bg-yellow-50 border border-yellow-300 rounded-sm p-2 text-yellow-800 text-sm">
{entry.stop_reason} {entry.stop_reason}
</div> </div>
{/if} {/if}
@@ -100,7 +100,7 @@
/> />
{/if} {/if}
</div> </div>
<div class="border-b {analysis_visible ? '' : 'hidden'}"> <div class="border-b border-gray-200 {analysis_visible ? '' : 'hidden'}">
<AnalysisView {entry} {manager} {current} /> <AnalysisView {entry} {manager} {current} />
</div> </div>
</div> </div>

View File

@@ -16,7 +16,7 @@
{#if $screenIsLgUp} {#if $screenIsLgUp}
<table class="table-auto text-left table"> <table class="table-auto text-left table">
<thead> <thead>
<tr class="bg-gray-100 drop-shadow"> <tr class="bg-gray-100 drop-shadow-sm">
<th class="p-2" scope="col">ID</th> <th class="p-2" scope="col">ID</th>
<th class="p-2" scope="col">Started</th> <th class="p-2" scope="col">Started</th>
<th class="p-2" scope="col">Last Message</th> <th class="p-2" scope="col">Last Message</th>

View File

@@ -36,7 +36,7 @@
} }
</script> </script>
<tr class="{status_row_color} drop-shadow"> <tr class="{status_row_color} drop-shadow-sm">
<td class="p-2">{entry.name}</td> <td class="p-2">{entry.name}</td>
<td class="p-2">{date_formatter.format(entry.start_time)}</td> <td class="p-2">{date_formatter.format(entry.start_time)}</td>
<td class="p-2" <td class="p-2"
@@ -65,8 +65,8 @@
</td> </td>
{/if} {/if}
</tr> </tr>
<tr class="{alternating_row_color} border-b {analysis_visible ? '' : 'hidden'}"> <tr class="{alternating_row_color} border-b border-gray-200 {analysis_visible ? '' : 'hidden'}">
<td class="border-t border-dashed p-2" colspan="9"> <td class="border-t border-gray-200 border-dashed p-2" colspan="9">
<AnalysisView {entry} {manager} {current} /> <AnalysisView {entry} {manager} {current} />
</td> </td>
</tr> </tr>

View File

@@ -35,7 +35,7 @@
{#if shown} {#if shown}
<div <div
class="fixed left-5 right-5 top-5 bottom-5 z-50 bg-white border border-white rounded-md class="fixed left-5 right-5 top-5 bottom-5 z-50 bg-white border border-white rounded-md
flex flex-col p-2 drop-shadow" flex flex-col p-2 drop-shadow-sm"
> >
<div class="flex justify-between items-center p-1"> <div class="flex justify-between items-center p-1">
<span class="text-2xl">{title}</span> <span class="text-2xl">{title}</span>

View File

@@ -6,7 +6,7 @@
stats: SystemStats; stats: SystemStats;
} = $props(); } = $props();
const table_cell_classes = 'border p-1 lg:p-2'; const table_cell_classes = 'border border-gray-200 p-1 lg:p-2';
let battery_level = $derived(stats.battery_status ? stats.battery_status.level : 0); let battery_level = $derived(stats.battery_status ? stats.battery_status.level : 0);
let bar_color = $derived.by(() => { let bar_color = $derived.by(() => {
@@ -36,29 +36,29 @@
</script> </script>
<div <div
class="flex-1 drop-shadow p-4 flex flex-col gap-2 border rounded-md bg-gray-100 border-gray-100" class="flex-1 drop-shadow-sm p-4 flex flex-col gap-2 border rounded-md bg-gray-100 border-gray-100"
> >
<p class="text-xl mb-2">System Information</p> <p class="text-xl mb-2">System Information</p>
<table class="table-auto border"> <table class="table-auto border border-gray-200">
<tbody> <tbody>
<tr class="border"> <tr class="border border-gray-200">
<th class={table_cell_classes}> Rayhunter Version </th> <th class={table_cell_classes}> Rayhunter Version </th>
<td class={table_cell_classes}>{stats.runtime_metadata.rayhunter_version}</td> <td class={table_cell_classes}>{stats.runtime_metadata.rayhunter_version}</td>
</tr> </tr>
<tr class="border"> <tr class="border border-gray-200">
<th class={table_cell_classes}> Storage </th> <th class={table_cell_classes}> Storage </th>
<td class={table_cell_classes}> <td class={table_cell_classes}>
{stats.disk_stats.used_percent} used ({stats.disk_stats.used_size} used / {stats {stats.disk_stats.used_percent} used ({stats.disk_stats.used_size} used / {stats
.disk_stats.available_size} available) .disk_stats.available_size} available)
</td> </td>
</tr> </tr>
<tr class="border-b"> <tr class="border-b border-gray-200">
<th class={table_cell_classes}> Memory (RAM) </th> <th class={table_cell_classes}> Memory (RAM) </th>
<td class={table_cell_classes}> <td class={table_cell_classes}>
Free: {stats.memory_stats.free}, Used: {stats.memory_stats.used} Free: {stats.memory_stats.free}, Used: {stats.memory_stats.used}
</td> </td>
</tr> </tr>
<tr class="border-b"> <tr class="border-b border-gray-200">
<th class={table_cell_classes}> Battery </th> <th class={table_cell_classes}> Battery </th>
<td class={table_cell_classes}> <td class={table_cell_classes}>
<svg <svg

View File

@@ -19,7 +19,9 @@ export function parse_ndjson(input: string): NewlineDeliminatedJson {
// however, if we've reached the end of the input, that means we // however, if we've reached the end of the input, that means we
// were given invalid nd-json // were given invalid nd-json
if (lines.length === 0) { if (lines.length === 0) {
throw new Error(`unable to parse invalid nd-json: ${e}, "${current_line}"`); throw new Error(`unable to parse invalid nd-json: ${e}, "${current_line}"`, {
cause: e,
});
} }
} }
} }

View File

@@ -57,7 +57,9 @@
<LogView bind:shown={logview_shown} /> <LogView bind:shown={logview_shown} />
<ConfigForm bind:shown={config_shown} /> <ConfigForm bind:shown={config_shown} />
<div class="p-4 xl:px-8 bg-rayhunter-blue drop-shadow flex flex-row justify-between items-center"> <div
class="p-4 xl:px-8 bg-rayhunter-blue drop-shadow-sm flex flex-row justify-between items-center"
>
<!-- https://www.w3.org/WAI/tutorials/images/decorative/ --> <!-- https://www.w3.org/WAI/tutorials/images/decorative/ -->
<img src="/rayhunter_text.png" alt="" class="h-10 xl:h-12" /> <img src="/rayhunter_text.png" alt="" class="h-10 xl:h-12" />
<div class="flex flex-row gap-4"> <div class="flex flex-row gap-4">
@@ -204,7 +206,7 @@
<div class="m-4 xl:mx-8 flex flex-col gap-4"> <div class="m-4 xl:mx-8 flex flex-col gap-4">
{#if update_error !== undefined} {#if update_error !== undefined}
<div <div
class="bg-red-100 border-red-100 drop-shadow p-4 flex flex-col gap-2 border rounded-md flex-1 justify-between" class="bg-red-100 border-red-100 drop-shadow-sm p-4 flex flex-col gap-2 border rounded-md flex-1 justify-between"
> >
<span class="text-2xl font-bold mb-2 flex flex-row items-center gap-2 text-red-600"> <span class="text-2xl font-bold mb-2 flex flex-row items-center gap-2 text-red-600">
<svg <svg
@@ -249,7 +251,7 @@
/> />
{:else} {:else}
<div <div
class="bg-red-100 border-red-100 drop-shadow p-4 flex flex-col gap-2 border rounded-md flex-1 justify-between" class="bg-red-100 border-red-100 drop-shadow-sm p-4 flex flex-col gap-2 border rounded-md flex-1 justify-between"
> >
<span <span
class="text-2xl font-bold mb-2 flex flex-row items-center gap-2 text-red-600" class="text-2xl font-bold mb-2 flex flex-row items-center gap-2 text-red-600"
@@ -295,7 +297,7 @@
type="checkbox" type="checkbox"
id="filter_threshold" id="filter_threshold"
bind:checked={filter_threshold} bind:checked={filter_threshold}
class="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-rayhunter-blue" class="px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-rayhunter-blue"
/> />
</div> </div>
</div> </div>

View File

@@ -1,19 +0,0 @@
import type { Config } from 'tailwindcss';
import { breakpoints } from './src/theme';
export default {
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {
colors: {
'rayhunter-blue': '#4e4eb1',
'rayhunter-dark-blue': '#3f3da0',
'rayhunter-green': '#94ea18',
},
screens: breakpoints,
},
},
plugins: [],
} as Config;

View File

@@ -1,5 +1,6 @@
import { defineConfig } from 'vitest/config'; import { defineConfig } from 'vitest/config';
import { sveltekit } from '@sveltejs/kit/vite'; import { sveltekit } from '@sveltejs/kit/vite';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({ export default defineConfig({
server: { server: {
@@ -26,7 +27,7 @@ export default defineConfig({
}, },
}, },
}, },
plugins: [sveltekit()], plugins: [tailwindcss(), sveltekit()],
build: { build: {
// Force everything into one HTML file. SvelteKit will still generate // Force everything into one HTML file. SvelteKit will still generate
// a lot of JS files but they are deadweight and will not be included // a lot of JS files but they are deadweight and will not be included