diff --git a/src/context/EstimContext.tsx b/src/context/EstimContext.tsx index b1417db..55a0b84 100644 --- a/src/context/EstimContext.tsx +++ b/src/context/EstimContext.tsx @@ -2,7 +2,7 @@ import { invoke } from '@tauri-apps/api/core'; import { listen, UnlistenFn } from '@tauri-apps/api/event'; import { message } from '@tauri-apps/plugin-dialog'; import { atom, PrimitiveAtom, useSetAtom } from 'jotai'; -import { atomFamily, atomWithRefresh } from 'jotai/utils'; +import { atomFamily, atomWithRefresh, RESET } from 'jotai/utils'; import { FC, ReactNode, useEffect, useRef } from 'react'; export type Channels = 'a' | 'b'; @@ -18,7 +18,7 @@ type ChannelState = { type PeripheralItem = { id: string; address: string; - represent: string; + represent: string | null; isConnected: boolean; rssi: number | null; battery: number | null; @@ -77,22 +77,24 @@ export const DeviceState = atomWithRefresh(async (get) => { battery: null, }; }); -export const FoundPeripherals = atomWithRefresh(async (get) => { - try { - const peripherals = await invoke('found_peripherals'); - return peripherals.map((peripheral: PeripheralItem) => ({ - id: peripheral.id, - address: peripheral.address, - represent: peripheral.represent, - isConnected: peripheral.isConnected, - rssi: peripheral.rssi, - battery: peripheral.battery, - })); - } catch (e) { - console.error('[refresh found]', e); - } - return []; -}); +export const FoundPeripherals = atom( + [] as PeripheralItem[], + (get, set, item: PeripheralItem | typeof RESET) => { + if (item === RESET) { + void set(FoundPeripherals, []); + } else { + void set(FoundPeripherals, (prev) => { + const foundIndex = prev.findIndex((i) => i.id === item.id); + if (foundIndex !== -1) { + prev[foundIndex] = item; + } else { + prev.push(item); + } + return prev; + }); + } + }, +); const Channels: Record> = { a: atomWithRefresh(async (get) => { try { @@ -164,7 +166,9 @@ const EstimWatchProvider: FC<{ children?: ReactNode }> = ({ children }) => { try { unlistenBle.current = await listen('central_state_updated', () => refreshBle()); unlistenDevice.current = await listen('peripheral_connected', () => refreshDevice()); - unlistenPreipherals.current = await listen('peripherals_found', () => refreshPeripherals()); + unlistenPreipherals.current = await listen('peripheral_found', (event) => { + refreshPeripherals(event.payload); + }); unlistenChannelA.current = await listen('channel_a_updated', () => refreshChannelA()); unlistenChannelB.current = await listen('channel_b_updated', () => refreshChannelB()); await invoke('activate_central_adapter'); diff --git a/src/icons/IconBattery.tsx b/src/icons/IconBattery.tsx index 3b9e5ec..f71d5d6 100644 --- a/src/icons/IconBattery.tsx +++ b/src/icons/IconBattery.tsx @@ -34,7 +34,6 @@ const IconBattery: FC = ({ return 'material-symbols-light:battery-error'; } }, [level]); - console.debug('[icon battery]', level, batteryIcon); return ; }; diff --git a/src/page-components/device/BleControl.tsx b/src/page-components/device/BleControl.tsx index 073a529..626e977 100644 --- a/src/page-components/device/BleControl.tsx +++ b/src/page-components/device/BleControl.tsx @@ -1,16 +1,19 @@ import { invoke } from '@tauri-apps/api/core'; -import { useAtomValue } from 'jotai'; +import { useAtomValue, useSetAtom } from 'jotai'; +import { RESET } from 'jotai/utils'; import { FC, useCallback, useEffect, useRef, useState } from 'react'; -import { BleState } from '../../context/EstimContext'; +import { BleState, FoundPeripherals } from '../../context/EstimContext'; import styles from './BleControl.module.css'; const BleControl: FC = () => { const bleState = useAtomValue(BleState); + const setFound = useSetAtom(FoundPeripherals); const timerRef = useRef(null); const [searchRemains, setSearchRemains] = useState(60); const handleStartScan = useCallback(async () => { timerRef.current !== null && clearInterval(timerRef.current); setSearchRemains(60); + setFound(RESET); try { await invoke('start_scan_devices'); timerRef.current = setInterval(() => {