diff --git a/changelog.d/tsk-4owb7b-fix-forward.md b/changelog.d/tsk-4owb7b-fix-forward.md
new file mode 100644
index 000000000..bca37bc1d
--- /dev/null
+++ b/changelog.d/tsk-4owb7b-fix-forward.md
@@ -0,0 +1,2 @@
+### Fixed
+- reset the mounted ref on effect start so StrictMode's remount does not discard every load
\ No newline at end of file
diff --git a/desktop/src/apps/SettingsApp/BluetoothPanel.test.tsx b/desktop/src/apps/SettingsApp/BluetoothPanel.test.tsx
index bddc7b575..9f0ad91af 100644
--- a/desktop/src/apps/SettingsApp/BluetoothPanel.test.tsx
+++ b/desktop/src/apps/SettingsApp/BluetoothPanel.test.tsx
@@ -1,6 +1,7 @@
import { describe, it, expect, vi, afterEach } from "vitest";
import { render, screen, waitFor, act } from "@testing-library/react";
import { BluetoothPanel } from "./BluetoothPanel";
+import { StrictMode } from "react";
function json(obj: unknown, status = 200) {
return new Response(JSON.stringify(obj), {
@@ -96,3 +97,19 @@ describe("BluetoothPanel", () => {
vi.useRealTimers();
}, 15000);
});
+
+describe("BluetoothPanel StrictMode", () => {
+ it("loads devices even when mounted remounts under StrictMode", async () => {
+ vi.spyOn(globalThis, "fetch").mockResolvedValue(
+ json({
+ available: true,
+ adapters: [{ path: "/org/bluez/hci0", address: "AA:BB:CC:DD:EE:FF", powered: true }],
+ devices: [{ path: "/org/bluez/hci0/dev_11_22_33_44_55_66", address: "11:22:33:44:55:66", name: "TestDevice", paired: true, connected: true, trusted: true }],
+ })
+ );
+ render();
+ await waitFor(() => {
+ expect(screen.getByText("TestDevice")).toBeInTheDocument();
+ });
+ });
+});
diff --git a/desktop/src/apps/SettingsApp/BluetoothPanel.tsx b/desktop/src/apps/SettingsApp/BluetoothPanel.tsx
index fec553cbe..d50ff756a 100644
--- a/desktop/src/apps/SettingsApp/BluetoothPanel.tsx
+++ b/desktop/src/apps/SettingsApp/BluetoothPanel.tsx
@@ -9,6 +9,7 @@ export function BluetoothPanel() {
const mounted = useRef(true);
useEffect(() => {
+ mounted.current = true;
const load = async () => {
try {
const res = await fetch("/api/hardware/bluetooth", { credentials: "include" });
diff --git a/desktop/src/apps/SettingsApp/WifiPanel.test.tsx b/desktop/src/apps/SettingsApp/WifiPanel.test.tsx
index 9c910f0ac..284e9aa18 100644
--- a/desktop/src/apps/SettingsApp/WifiPanel.test.tsx
+++ b/desktop/src/apps/SettingsApp/WifiPanel.test.tsx
@@ -1,6 +1,7 @@
import { describe, it, expect, vi, afterEach } from "vitest";
import { render, screen, waitFor, act } from "@testing-library/react";
import { WifiPanel } from "./WifiPanel";
+import { StrictMode } from "react";
function json(obj: unknown, status = 200) {
return new Response(JSON.stringify(obj), {
@@ -92,4 +93,22 @@ it("refreshes access points every 10s and clears interval on unmount", async ()
expect(fetchSpy).toHaveBeenCalledTimes(2);
vi.useRealTimers();
}, 15000);
+});
+
+describe("WifiPanel StrictMode", () => {
+ it("loads access points even when mounted remounts under StrictMode", async () => {
+ vi.spyOn(globalThis, "fetch").mockResolvedValue(
+ json({
+ available: true,
+ wifi_enabled: true,
+ access_points: [
+ { ssid: "TestNetwork", strength: 75, frequency: 2437, secured: true, active: true },
+ ],
+ })
+ );
+ render();
+ await waitFor(() => {
+ expect(screen.getByText("TestNetwork")).toBeInTheDocument();
+ });
+ });
});
\ No newline at end of file
diff --git a/desktop/src/apps/SettingsApp/WifiPanel.tsx b/desktop/src/apps/SettingsApp/WifiPanel.tsx
index 9fc79a8f0..0bc87c46d 100644
--- a/desktop/src/apps/SettingsApp/WifiPanel.tsx
+++ b/desktop/src/apps/SettingsApp/WifiPanel.tsx
@@ -10,6 +10,7 @@ export function WifiPanel() {
const mounted = useRef(true);
useEffect(() => {
+ mounted.current = true;
const load = async () => {
try {
const res = await fetch("/api/hardware/wifi", { credentials: "include" });