mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-06-01 18:53:34 -07:00
GPS feature webapp side: GPS mode selector, fixed mode lat/lon, API endpoint. Merging with Wifi client and webdav features
This commit is contained in:
committed by
Will Greenberg
parent
ac33ebaf53
commit
c107314194
@@ -781,6 +781,79 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border-t pt-4 mt-6 space-y-3">
|
||||
<h3 class="text-lg font-semibold text-gray-800 mb-4">GPS Settings</h3>
|
||||
|
||||
<div>
|
||||
<label for="gps_mode" class="block text-sm font-medium text-gray-700 mb-1">
|
||||
GPS Mode
|
||||
</label>
|
||||
<select
|
||||
id="gps_mode"
|
||||
bind:value={config.gps_mode}
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-rayhunter-blue"
|
||||
>
|
||||
<option value={0}>0 - Disabled</option>
|
||||
<option value={1}>1 - Fixed coordinates</option>
|
||||
<option value={2}>2 - API Endpoint</option>
|
||||
</select>
|
||||
<p class="text-xs text-gray-500 mt-1">
|
||||
{#if config.gps_mode === 2}
|
||||
POST latitude, longitude, and timestamp to <code>/api/gps</code> from
|
||||
any device on the network.
|
||||
{:else if config.gps_mode === 1}
|
||||
GPS coordinates are fixed to the values below.
|
||||
{:else}
|
||||
GPS is disabled; no coordinates will be tracked.
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{#if config.gps_mode === 1}
|
||||
<div>
|
||||
<label
|
||||
for="gps_fixed_latitude"
|
||||
class="block text-sm font-medium text-gray-700 mb-1"
|
||||
>
|
||||
Fixed Latitude
|
||||
</label>
|
||||
<input
|
||||
id="gps_fixed_latitude"
|
||||
type="number"
|
||||
min="-90"
|
||||
max="90"
|
||||
step="any"
|
||||
required
|
||||
bind:value={config.gps_fixed_latitude}
|
||||
placeholder="e.g. 37.7749"
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-rayhunter-blue"
|
||||
/>
|
||||
<p class="text-xs text-gray-500 mt-1">Decimal degrees, -90 to 90</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
for="gps_fixed_longitude"
|
||||
class="block text-sm font-medium text-gray-700 mb-1"
|
||||
>
|
||||
Fixed Longitude
|
||||
</label>
|
||||
<input
|
||||
id="gps_fixed_longitude"
|
||||
type="number"
|
||||
min="-180"
|
||||
max="180"
|
||||
step="any"
|
||||
required
|
||||
bind:value={config.gps_fixed_longitude}
|
||||
placeholder="e.g. -122.4194"
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-rayhunter-blue"
|
||||
/>
|
||||
<p class="text-xs text-gray-500 mt-1">Decimal degrees, -180 to 180</p>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 pt-4">
|
||||
<button
|
||||
type="submit"
|
||||
|
||||
@@ -46,6 +46,9 @@ export interface Config {
|
||||
firewall_restrict_outbound: boolean;
|
||||
firewall_allowed_ports: number[] | null;
|
||||
webdav: WebdavConfig;
|
||||
gps_mode: number;
|
||||
gps_fixed_latitude: number | null;
|
||||
gps_fixed_longitude: number | null;
|
||||
}
|
||||
|
||||
export interface WifiStatus {
|
||||
@@ -153,3 +156,20 @@ export interface TimeResponse {
|
||||
export async function get_daemon_time(): Promise<TimeResponse> {
|
||||
return JSON.parse(await req('GET', '/api/time'));
|
||||
}
|
||||
|
||||
export interface GpsData {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
export async function get_gps(): Promise<GpsData | null> {
|
||||
const response = await fetch('/api/gps');
|
||||
if (response.status === 404) {
|
||||
return null;
|
||||
}
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
return response.json();
|
||||
}
|
||||
throw new Error(await response.text());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { ManifestEntry } from '$lib/manifest.svelte';
|
||||
import { get_manifest, get_system_stats } from '$lib/utils.svelte';
|
||||
import { get_manifest, get_system_stats, get_gps, get_config, type GpsData } from '$lib/utils.svelte';
|
||||
import ManifestTable from '$lib/components/ManifestTable.svelte';
|
||||
import Card from '$lib/components/ManifestCard.svelte';
|
||||
import type { SystemStats } from '$lib/systemStats';
|
||||
@@ -22,7 +22,13 @@
|
||||
let update_error: string | undefined = $state(undefined);
|
||||
let logview_shown: boolean = $state(false);
|
||||
let config_shown: boolean = $state(false);
|
||||
let gps_data: GpsData | null = $state(null);
|
||||
let gps_mode: number = $state(0);
|
||||
$effect(() => {
|
||||
get_config().then((c) => {
|
||||
gps_mode = c.gps_mode;
|
||||
});
|
||||
|
||||
const interval = setInterval(async () => {
|
||||
try {
|
||||
// Don't update UI if browser tab isn't visible
|
||||
@@ -40,6 +46,7 @@
|
||||
current_entry = new_manifest.current_entry;
|
||||
|
||||
system_stats = await get_system_stats();
|
||||
gps_data = await get_gps();
|
||||
update_error = undefined;
|
||||
loaded = true;
|
||||
} catch (error) {
|
||||
@@ -283,6 +290,48 @@
|
||||
{/if}
|
||||
<SystemStatsTable stats={system_stats!} />
|
||||
</div>
|
||||
{#if gps_mode !== 0}
|
||||
<div class="bg-white border border-gray-200 drop-shadow rounded-md p-4 flex flex-col gap-2">
|
||||
<span class="text-lg font-semibold flex flex-row items-center gap-2">
|
||||
<svg
|
||||
class="w-5 h-5 text-rayhunter-blue"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M11.906 1.994a8.002 8.002 0 0 1 8.09 8.421 7.996 7.996 0 0 1-1.297 3.957.996.996 0 0 1-.133.204l-.108.129c-.178.243-.37.477-.573.699l-5.112 6.224a1 1 0 0 1-1.545 0L5.982 15.26l-.002-.002a18.146 18.146 0 0 1-.309-.38l-.133-.163a.999.999 0 0 1-.13-.202 7.995 7.995 0 0 1 6.498-12.518ZM15 9.997a3 3 0 1 1-5.999 0 3 3 0 0 1 5.999 0Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
GPS Status
|
||||
</span>
|
||||
{#if gps_data}
|
||||
<table class="w-full text-sm">
|
||||
<tbody>
|
||||
<tr class="border-b border-gray-100">
|
||||
<td class="py-1 pr-4 text-gray-500 font-medium">Latitude</td>
|
||||
<td class="py-1 font-mono">{gps_data.latitude.toFixed(6)}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-gray-100">
|
||||
<td class="py-1 pr-4 text-gray-500 font-medium">Longitude</td>
|
||||
<td class="py-1 font-mono">{gps_data.longitude.toFixed(6)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-1 pr-4 text-gray-500 font-medium">GPS Timestamp</td>
|
||||
<td class="py-1 font-mono">{gps_data.timestamp}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{:else}
|
||||
<span class="text-gray-400 text-sm">Awaiting GPS data...</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex flex-row gap-2">
|
||||
<div class="text-xl flex-1">History</div>
|
||||
|
||||
Reference in New Issue
Block a user