From 5a1a20df6c3d9fbe57c53e83cff74af365e7026a Mon Sep 17 00:00:00 2001 From: ThePetrovich Date: Wed, 2 Jul 2025 21:36:53 +0800 Subject: [PATCH] fix reactivity on saved point change --- src/lib/components/ControlPanel.svelte | 159 +++++++++-------------- src/lib/components/PointListModal.svelte | 34 +++-- 2 files changed, 81 insertions(+), 112 deletions(-) diff --git a/src/lib/components/ControlPanel.svelte b/src/lib/components/ControlPanel.svelte index ae60be1..6ba1bd5 100644 --- a/src/lib/components/ControlPanel.svelte +++ b/src/lib/components/ControlPanel.svelte @@ -9,7 +9,7 @@ Input, InputGroup, InputGroupText, - Icon + Icon, } from "@sveltestrap/sveltestrap"; import { getForecast } from "$lib/prediction"; @@ -58,12 +58,11 @@ let { handleClickSelectOnMap = () => console.log("Select on map clicked"), - handleClickPointListModal = () => console.log("Open Point List Modal") + handleClickPointListModal = () => console.log("Open Point List Modal"), }: Props = $props(); // State let isCollapsed = $state(false); - let startPoint = $state("Custom"); // Initialize date/time const now = new Date(); @@ -71,64 +70,31 @@ let startTime = $state(now.toISOString().split("T")[1].split(".")[0]); // Coordinate inputs - let inputLat = $state($FlightParametersStore.launch_latitude.toFixed(6)); - let inputLng = $state($FlightParametersStore.launch_longitude.toFixed(6)); - - // Reactive effects - $effect(() => { - $FlightParametersStore; - }); - - $effect(() => { - // Watch for saved points changes - $SavedPointsStore; - - // This effect also depends on startPoint, which is changed by setCoordinatesFromSavedPoint - // via other state variables. To avoid an infinite loop, we only call this when startPoint changes. - const sp = startPoint; - setCoordinatesFromSavedPoint(); - }); - - // Functions - function setCoordinatesFromSavedPoint() { - const lat = parseFloat(inputLat); - const lng = parseFloat(inputLng); - if (!isNaN(lat) && !isNaN(lng)) { - $FlightParametersStore.launch_latitude = lat; - $FlightParametersStore.launch_longitude = lng; - } - else { - const selectedOption = document.querySelector( - `#startPoint option[value="${startPoint}"]` - ) as HTMLOptionElement; - - if (selectedOption) { - const lat = parseFloat(selectedOption.getAttribute("data-lat") || "0"); - const lng = parseFloat(selectedOption.getAttribute("data-lng") || "0"); - const alt = parseFloat(selectedOption.getAttribute("data-alt") || "0"); - - inputLat = lat.toFixed(6); - inputLng = lng.toFixed(6); - $FlightParametersStore.launch_latitude = lat; - $FlightParametersStore.launch_longitude = lng; - $FlightParametersStore.launch_altitude = alt; - } - } - } + let inputLat = $derived($FlightParametersStore.start_point === "Custom" + ? $FlightParametersStore.launch_latitude.toFixed(6) + : $SavedPointsStore.find(point => point.name === $FlightParametersStore.start_point)?.lat.toFixed(6) || "0.000000"); + let inputLng = $derived($FlightParametersStore.start_point === "Custom" + ? $FlightParametersStore.launch_longitude.toFixed(6) + : $SavedPointsStore.find(point => point.name === $FlightParametersStore.start_point)?.lon.toFixed(6) || "0.000000"); + let inputAlt = $derived($FlightParametersStore.start_point === "Custom" + ? $FlightParametersStore.launch_altitude.toFixed(2) + : $SavedPointsStore.find(point => point.name === $FlightParametersStore.start_point)?.alt.toFixed(2) || "0.00"); function setToCustomOnChange() { - if (startPoint !== "Custom") { - startPoint = "Custom"; + if ($FlightParametersStore.start_point !== "Custom") { + $FlightParametersStore.start_point = "Custom"; } } function applyCoordinatesFromInput() { const lat = parseFloat(inputLat); const lng = parseFloat(inputLng); + const alt = parseFloat(inputAlt); if (!isNaN(lat) && !isNaN(lng)) { $FlightParametersStore.launch_latitude = lat; $FlightParametersStore.launch_longitude = lng; + $FlightParametersStore.launch_altitude = alt || 0; // Default to 0 if alt is NaN } else { console.error("Invalid coordinate input"); // TODO: Show validation error to user @@ -137,23 +103,27 @@ async function handleGetPrediction() { $FlightParametersStore.launch_datetime = `${startDate}T${startTime}Z`; + $FlightParametersStore.launch_latitude = parseFloat(inputLat); + $FlightParametersStore.launch_longitude = parseFloat(inputLng); + $FlightParametersStore.launch_altitude = parseFloat(inputAlt); writeLocalStorage("flightParameters", $FlightParametersStore); - getForecast($FlightParametersStore).then( - (data) => { + getForecast($FlightParametersStore) + .then((data) => { console.log("Forecast request successful:", data); addToast({ header: "Forecast Request", body: "Forecast request successful!", - color: "success" + color: "success", }); // Handle the response data as needed - }).catch((error) => { + }) + .catch((error) => { console.error("Error getting forecast:", error); addToast({ header: "Forecast Error", body: `Error getting forecast: ${error.message}`, - color: "danger" + color: "danger", }); }); } @@ -165,7 +135,7 @@ // Exported functions for parent components export function updateLaunchPosition(lat: number, lng: number) { $FlightParametersStore.launch_latitude = lat; - $FlightParametersStore.launch_longitude = lng; + $FlightParametersStore.launch_longitude = lng; inputLat = lat.toFixed(6); inputLng = lng.toFixed(6); setToCustomOnChange(); @@ -191,9 +161,17 @@ isCollapsed = !isCollapsed; } - onMount(async () => { - const savedPoints = await getSavedPoints(); - SavedPointsStore.set(savedPoints); + onMount(() => { + getSavedPoints() + .then((points) => SavedPointsStore.set(points)) + .catch((error) => { + addToast({ + header: "Error Loading Points", + body: `Failed to load saved points: ${error.message}`, + color: "danger", + }); + return []; + }); }); @@ -218,7 +196,7 @@ - + {#if !isCollapsed}
@@ -260,10 +238,19 @@ - + {#each $SavedPointsStore as point} - {/each} @@ -272,11 +259,7 @@ - @@ -286,39 +269,29 @@ - / - - - @@ -331,7 +304,7 @@ id="startHeight" class="form-control-sm" onchange={setToCustomOnChange} - bind:value={$FlightParametersStore.launch_altitude} + bind:value={inputAlt} /> @@ -370,9 +343,7 @@
- +
{/if} diff --git a/src/lib/components/PointListModal.svelte b/src/lib/components/PointListModal.svelte index ae57d1f..632cceb 100644 --- a/src/lib/components/PointListModal.svelte +++ b/src/lib/components/PointListModal.svelte @@ -18,10 +18,9 @@ import { getSavedPoints, savePoint, updatePoint, deletePoint } from '$lib/api/points'; // Props - let { isOpen = $bindable(false), onClose = () => {} } = $props(); + let { isOpen = $bindable(false), onClose = () => {}, onChange = () => {} } = $props(); // Runes - let points = $state([]); let selectedPoint = $state(null); let newPoint = $state({ id: 0, name: '', lat: 0, lon: 0, alt: 0 }); let isEditing = $state(false); @@ -32,18 +31,17 @@ let modalTitle = $derived(isEditing ? 'Редактирование точки' : 'Сохраненные точки'); // Table handler - let table = $derived(new TableHandler(points, { rowsPerPage: 10 })); + let table = $derived(new TableHandler($SavedPointsStore, { rowsPerPage: 10 })); - // Sync with store $effect(() => { - points = $SavedPointsStore || []; + onChange(); }); // On mount, fetch points onMount(async () => { const pts = await getSavedPoints(); - points = pts; - SavedPointsStore.set(points); + $SavedPointsStore = pts; + SavedPointsStore.set($SavedPointsStore); }); // Modal controls @@ -64,8 +62,8 @@ function handleDeletePoint(point: SavedPoint) { deletePoint(point.id).then(() => { - points = points.filter(p => p.id !== point.id); - SavedPointsStore.set(points); + $SavedPointsStore = $SavedPointsStore.filter(p => p.id !== point.id); + SavedPointsStore.set($SavedPointsStore); addToast({ header: 'Точка удалена', body: `Точка "${point.name}" успешно удалена.`, @@ -80,8 +78,8 @@ function handleSavePoint() { if (isEditing && selectedPoint) { updatePoint(newPoint).then(updatedPoint => { - points = points.map(p => (p.id === updatedPoint.id ? updatedPoint : p)); - SavedPointsStore.set(points); + $SavedPointsStore = $SavedPointsStore.map(p => (p.id === updatedPoint.id ? updatedPoint : p)); + SavedPointsStore.set($SavedPointsStore); resetForm(); addToast({ header: 'Точка обновлена', @@ -93,8 +91,8 @@ }); } else { savePoint(newPoint).then(savedPoint => { - points = [...points, savedPoint]; - SavedPointsStore.set(points); + $SavedPointsStore = [...$SavedPointsStore, savedPoint]; + SavedPointsStore.set($SavedPointsStore); resetForm(); addToast({ header: 'Точка сохранена', @@ -136,7 +134,7 @@ - + @@ -147,9 +145,9 @@ {#each table.rows as row} - - - + + +
ИмяНазвание точки Широта Долгота Высота
{row.name}{row.lat}{row.lon}{row.alt}{row.lat} °{row.lon} °{row.alt} м