mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-06-06 21:21:54 -07:00
Collapse ntfy settings if unused
Like in the webdav settings, have a checkbox that expands a few form fields.
This commit is contained in:
committed by
Markus Unterwaditzer
parent
c2ba5a2a6c
commit
3e53aef145
@@ -11,6 +11,7 @@
|
|||||||
type WifiNetwork,
|
type WifiNetwork,
|
||||||
} from '../utils.svelte';
|
} from '../utils.svelte';
|
||||||
import Modal from './Modal.svelte';
|
import Modal from './Modal.svelte';
|
||||||
|
import ExpandableInput from './ExpandableInput.svelte';
|
||||||
|
|
||||||
let { shown = $bindable() }: { shown: boolean } = $props();
|
let { shown = $bindable() }: { shown: boolean } = $props();
|
||||||
let config = $state<Config | null>(null);
|
let config = $state<Config | null>(null);
|
||||||
@@ -27,15 +28,12 @@
|
|||||||
let scanning = $state(false);
|
let scanning = $state(false);
|
||||||
let scanResults = $state<WifiNetwork[]>([]);
|
let scanResults = $state<WifiNetwork[]>([]);
|
||||||
let dnsServersInput = $state('');
|
let dnsServersInput = $state('');
|
||||||
let webdavExpanded = $state(false);
|
|
||||||
let webdavUrlInput = $state<HTMLInputElement | null>(null);
|
|
||||||
|
|
||||||
async function load_config() {
|
async function load_config() {
|
||||||
try {
|
try {
|
||||||
loading = true;
|
loading = true;
|
||||||
config = await get_config();
|
config = await get_config();
|
||||||
dnsServersInput = config.dns_servers ? config.dns_servers.join(', ') : '';
|
dnsServersInput = config.dns_servers ? config.dns_servers.join(', ') : '';
|
||||||
webdavExpanded = config.webdav.url.trim() !== '';
|
|
||||||
message = '';
|
message = '';
|
||||||
messageType = null;
|
messageType = null;
|
||||||
poll_wifi_status();
|
poll_wifi_status();
|
||||||
@@ -215,95 +213,90 @@
|
|||||||
|
|
||||||
<div class="border-t border-gray-200 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>
|
|
||||||
<label for="ntfy_url" class="block text-sm font-medium text-gray-700 mb-1">
|
|
||||||
ntfy URL for Sending Notifications (if unset you will not receive
|
|
||||||
notifications)
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
id="ntfy_url"
|
|
||||||
type="url"
|
|
||||||
bind:value={config.ntfy_url}
|
|
||||||
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">
|
|
||||||
Test button below uses the saved configuration URL, not the input above
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<ExpandableInput
|
||||||
<button
|
bind:value={config.ntfy_url}
|
||||||
type="button"
|
checkboxId="ntfy_enabled"
|
||||||
onclick={send_test_notification}
|
inputId="ntfy_url"
|
||||||
disabled={testingNotification}
|
label="Enable ntfy notifications"
|
||||||
class="bg-rayhunter-blue hover:bg-rayhunter-dark-blue disabled:opacity-50 disabled:cursor-not-allowed text-white font-bold py-2 px-4 rounded-md flex flex-row gap-1 items-center"
|
inputLabel="ntfy URL"
|
||||||
>
|
inputPlaceholder="https://ntfy.sh/my-rayhunter"
|
||||||
{#if testingNotification}
|
inputHelp="Test button below uses the saved configuration URL, not the input above"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onclick={send_test_notification}
|
||||||
|
disabled={testingNotification}
|
||||||
|
class="bg-rayhunter-blue hover:bg-rayhunter-dark-blue disabled:opacity-50 disabled:cursor-not-allowed text-white font-bold py-2 px-4 rounded-md flex flex-row gap-1 items-center"
|
||||||
|
>
|
||||||
|
{#if testingNotification}
|
||||||
|
<div
|
||||||
|
class="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"
|
||||||
|
></div>
|
||||||
|
Sending...
|
||||||
|
{:else}
|
||||||
|
<svg
|
||||||
|
class="w-4 h-4"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
Send Test Notification
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
{#if testMessage}
|
||||||
<div
|
<div
|
||||||
class="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"
|
class="mt-2 p-2 rounded-sm text-sm {testMessageType === 'error'
|
||||||
></div>
|
? 'bg-red-100 text-red-700'
|
||||||
Sending...
|
: 'bg-green-100 text-green-700'}"
|
||||||
{:else}
|
|
||||||
<svg
|
|
||||||
class="w-4 h-4"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
>
|
||||||
<path
|
{testMessage}
|
||||||
stroke-linecap="round"
|
</div>
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-width="2"
|
|
||||||
d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
Send Test Notification
|
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</div>
|
||||||
{#if testMessage}
|
|
||||||
<div
|
|
||||||
class="mt-2 p-2 rounded-sm text-sm {testMessageType === 'error'
|
|
||||||
? 'bg-red-100 text-red-700'
|
|
||||||
: 'bg-green-100 text-green-700'}"
|
|
||||||
>
|
|
||||||
{testMessage}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<div class="block text-sm font-medium text-gray-700 mb-1">
|
<div class="block text-sm font-medium text-gray-700 mb-1">
|
||||||
Enabled Notification Types
|
Enabled Notification Types
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="enable_warning_notifications"
|
||||||
|
value="Warning"
|
||||||
|
bind:group={config.enabled_notifications}
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
for="enable_warning_notifications"
|
||||||
|
class="ml-2 block text-sm text-gray-700"
|
||||||
|
>
|
||||||
|
Warnings
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="enable_lowbattery_notifications"
|
||||||
|
value="LowBattery"
|
||||||
|
bind:group={config.enabled_notifications}
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
for="enable_lowbattery_notifications"
|
||||||
|
class="ml-2 block text-sm text-gray-700"
|
||||||
|
>
|
||||||
|
Low Battery
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
</ExpandableInput>
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
id="enable_warning_notifications"
|
|
||||||
value="Warning"
|
|
||||||
bind:group={config.enabled_notifications}
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
for="enable_warning_notifications"
|
|
||||||
class="ml-2 block text-sm text-gray-700"
|
|
||||||
>
|
|
||||||
Warnings
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
id="enable_lowbattery_notifications"
|
|
||||||
value="LowBattery"
|
|
||||||
bind:group={config.enabled_notifications}
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
for="enable_lowbattery_notifications"
|
|
||||||
class="ml-2 block text-sm text-gray-700"
|
|
||||||
>
|
|
||||||
Low Battery
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="border-t border-gray-200 pt-4 mt-6 space-y-3">
|
<div class="border-t border-gray-200 pt-4 mt-6 space-y-3">
|
||||||
@@ -355,53 +348,15 @@
|
|||||||
.qmdl and .ndjson files are uploaded in the background to the WebDAV server.
|
.qmdl and .ndjson files are uploaded in the background to the WebDAV server.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="flex items-center">
|
<ExpandableInput
|
||||||
<input
|
bind:value={config.webdav.url}
|
||||||
id="webdav_enabled"
|
checkboxId="webdav_enabled"
|
||||||
type="checkbox"
|
inputId="webdav_url"
|
||||||
checked={webdavExpanded}
|
label="Enable WebDAV upload"
|
||||||
onchange={(e) => {
|
inputLabel="Server URL"
|
||||||
webdavExpanded = e.currentTarget.checked;
|
inputPlaceholder="https://dav.example.com/rayhunter/"
|
||||||
if (webdavExpanded) {
|
inputHelp="Files are uploaded via HTTP PUT under this base URL. No folders are created, and folders in this base URL are assumed to exist already."
|
||||||
setTimeout(() => webdavUrlInput?.focus(), 0);
|
>
|
||||||
} else {
|
|
||||||
if (config) config.webdav.url = '';
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded-sm"
|
|
||||||
/>
|
|
||||||
<label for="webdav_enabled" class="ml-2 block text-sm text-gray-700">
|
|
||||||
Enable WebDAV upload
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if webdavExpanded}
|
|
||||||
<div>
|
|
||||||
<label
|
|
||||||
for="webdav_url"
|
|
||||||
class="block text-sm font-medium text-gray-700 mb-1"
|
|
||||||
>
|
|
||||||
Server URL
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
id="webdav_url"
|
|
||||||
type="url"
|
|
||||||
bind:this={webdavUrlInput}
|
|
||||||
bind:value={config.webdav.url}
|
|
||||||
onblur={() => {
|
|
||||||
if (config && config.webdav.url.trim() === '') {
|
|
||||||
webdavExpanded = false;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
placeholder="https://dav.example.com/rayhunter/"
|
|
||||||
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">
|
|
||||||
Files are uploaded via HTTP PUT under this base URL. No folders are
|
|
||||||
created, and folders in this base URL are assumed to exist already.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label
|
<label
|
||||||
for="webdav_username"
|
for="webdav_username"
|
||||||
@@ -512,7 +467,7 @@
|
|||||||
When enabled, the local files are removed after a successful upload.
|
When enabled, the local files are removed after a successful upload.
|
||||||
Otherwise the manifest is just marked as uploaded.
|
Otherwise the manifest is just marked as uploaded.
|
||||||
</p>
|
</p>
|
||||||
{/if}
|
</ExpandableInput>
|
||||||
</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'}
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
|
|
||||||
|
let {
|
||||||
|
value = $bindable(''),
|
||||||
|
checkboxId,
|
||||||
|
inputId,
|
||||||
|
label,
|
||||||
|
inputLabel,
|
||||||
|
inputPlaceholder = '',
|
||||||
|
inputHelp = '',
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
value: string;
|
||||||
|
checkboxId: string;
|
||||||
|
inputId: string;
|
||||||
|
label: string;
|
||||||
|
inputLabel: string;
|
||||||
|
inputPlaceholder?: string;
|
||||||
|
inputHelp?: string;
|
||||||
|
children?: Snippet;
|
||||||
|
} = $props();
|
||||||
|
|
||||||
|
let expanded = $state(value.trim() !== '');
|
||||||
|
let inputElement = $state<HTMLInputElement | null>(null);
|
||||||
|
|
||||||
|
function handle_checkbox_change(e: Event) {
|
||||||
|
expanded = (e.currentTarget as HTMLInputElement).checked;
|
||||||
|
if (expanded) {
|
||||||
|
setTimeout(() => inputElement?.focus(), 0);
|
||||||
|
} else {
|
||||||
|
value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_input_blur() {
|
||||||
|
if (value.trim() === '') {
|
||||||
|
expanded = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex items-center">
|
||||||
|
<input
|
||||||
|
id={checkboxId}
|
||||||
|
type="checkbox"
|
||||||
|
checked={expanded}
|
||||||
|
onchange={handle_checkbox_change}
|
||||||
|
class="h-4 w-4 text-rayhunter-blue focus:ring-rayhunter-blue border-gray-300 rounded-sm"
|
||||||
|
/>
|
||||||
|
<label for={checkboxId} class="ml-2 block text-sm text-gray-700">
|
||||||
|
{label}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if expanded}
|
||||||
|
<div>
|
||||||
|
<label for={inputId} class="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
{inputLabel}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id={inputId}
|
||||||
|
type="text"
|
||||||
|
bind:this={inputElement}
|
||||||
|
bind:value
|
||||||
|
onblur={handle_input_blur}
|
||||||
|
placeholder={inputPlaceholder}
|
||||||
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-rayhunter-blue"
|
||||||
|
/>
|
||||||
|
{#if inputHelp}
|
||||||
|
<p class="text-xs text-gray-500 mt-1">
|
||||||
|
{inputHelp}
|
||||||
|
</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{@render children?.()}
|
||||||
|
{/if}
|
||||||
Reference in New Issue
Block a user