basically complete retrieving found peripherals.

This commit is contained in:
Vixalie 2025-02-28 13:20:27 +08:00
parent 63c7d49943
commit c6043b612f
3 changed files with 28 additions and 22 deletions

View File

@ -2,7 +2,7 @@ import { invoke } from '@tauri-apps/api/core';
import { listen, UnlistenFn } from '@tauri-apps/api/event'; import { listen, UnlistenFn } from '@tauri-apps/api/event';
import { message } from '@tauri-apps/plugin-dialog'; import { message } from '@tauri-apps/plugin-dialog';
import { atom, PrimitiveAtom, useSetAtom } from 'jotai'; 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'; import { FC, ReactNode, useEffect, useRef } from 'react';
export type Channels = 'a' | 'b'; export type Channels = 'a' | 'b';
@ -18,7 +18,7 @@ type ChannelState = {
type PeripheralItem = { type PeripheralItem = {
id: string; id: string;
address: string; address: string;
represent: string; represent: string | null;
isConnected: boolean; isConnected: boolean;
rssi: number | null; rssi: number | null;
battery: number | null; battery: number | null;
@ -77,22 +77,24 @@ export const DeviceState = atomWithRefresh<DeviceState>(async (get) => {
battery: null, battery: null,
}; };
}); });
export const FoundPeripherals = atomWithRefresh<PeripheralItem[]>(async (get) => { export const FoundPeripherals = atom(
try { [] as PeripheralItem[],
const peripherals = await invoke('found_peripherals'); (get, set, item: PeripheralItem | typeof RESET) => {
return peripherals.map((peripheral: PeripheralItem) => ({ if (item === RESET) {
id: peripheral.id, void set(FoundPeripherals, []);
address: peripheral.address, } else {
represent: peripheral.represent, void set(FoundPeripherals, (prev) => {
isConnected: peripheral.isConnected, const foundIndex = prev.findIndex((i) => i.id === item.id);
rssi: peripheral.rssi, if (foundIndex !== -1) {
battery: peripheral.battery, prev[foundIndex] = item;
})); } else {
} catch (e) { prev.push(item);
console.error('[refresh found]', e);
} }
return []; return prev;
}); });
}
},
);
const Channels: Record<Channels, PrimitiveAtom<ChannelState>> = { const Channels: Record<Channels, PrimitiveAtom<ChannelState>> = {
a: atomWithRefresh<ChannelState>(async (get) => { a: atomWithRefresh<ChannelState>(async (get) => {
try { try {
@ -164,7 +166,9 @@ const EstimWatchProvider: FC<{ children?: ReactNode }> = ({ children }) => {
try { try {
unlistenBle.current = await listen('central_state_updated', () => refreshBle()); unlistenBle.current = await listen('central_state_updated', () => refreshBle());
unlistenDevice.current = await listen('peripheral_connected', () => refreshDevice()); 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()); unlistenChannelA.current = await listen('channel_a_updated', () => refreshChannelA());
unlistenChannelB.current = await listen('channel_b_updated', () => refreshChannelB()); unlistenChannelB.current = await listen('channel_b_updated', () => refreshChannelB());
await invoke('activate_central_adapter'); await invoke('activate_central_adapter');

View File

@ -34,7 +34,6 @@ const IconBattery: FC<IconBatteryProps> = ({
return 'material-symbols-light:battery-error'; return 'material-symbols-light:battery-error';
} }
}, [level]); }, [level]);
console.debug('[icon battery]', level, batteryIcon);
return <Icon icon={batteryIcon} width={width} height={height} stroke={stroke} />; return <Icon icon={batteryIcon} width={width} height={height} stroke={stroke} />;
}; };

View File

@ -1,16 +1,19 @@
import { invoke } from '@tauri-apps/api/core'; 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 { FC, useCallback, useEffect, useRef, useState } from 'react';
import { BleState } from '../../context/EstimContext'; import { BleState, FoundPeripherals } from '../../context/EstimContext';
import styles from './BleControl.module.css'; import styles from './BleControl.module.css';
const BleControl: FC = () => { const BleControl: FC = () => {
const bleState = useAtomValue(BleState); const bleState = useAtomValue(BleState);
const setFound = useSetAtom(FoundPeripherals);
const timerRef = useRef<number | null>(null); const timerRef = useRef<number | null>(null);
const [searchRemains, setSearchRemains] = useState(60); const [searchRemains, setSearchRemains] = useState(60);
const handleStartScan = useCallback(async () => { const handleStartScan = useCallback(async () => {
timerRef.current !== null && clearInterval(timerRef.current); timerRef.current !== null && clearInterval(timerRef.current);
setSearchRemains(60); setSearchRemains(60);
setFound(RESET);
try { try {
await invoke('start_scan_devices'); await invoke('start_scan_devices');
timerRef.current = setInterval(() => { timerRef.current = setInterval(() => {