estim_control/src/page-components/device/BleControl.tsx
2025-03-07 17:09:57 +08:00

56 lines
1.7 KiB
TypeScript

import { invoke } from '@tauri-apps/api/core';
import { useAtomValue, useSetAtom } from 'jotai';
import { RESET } from 'jotai/utils';
import { FC, useCallback, useEffect, useRef, useState } from 'react';
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<number | null>(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(() => {
setSearchRemains((s) => s - 1);
}, 1000);
} catch (e) {
console.error('[start scan]', e);
}
}, []);
const handleStopScan = useCallback(async () => {
try {
await invoke('stop_scan_devices');
} catch (e) {
console.error('[stop scan]', e);
}
}, []);
useEffect(() => {
if (searchRemains === 0) {
timerRef.current && clearInterval(timerRef.current);
handleStopScan();
}
}, [searchRemains]);
return (
<div className={styles.ble_control}>
{bleState.searching && <span>{searchRemains}s remains</span>}
<button
className="filled"
disabled={!bleState.ready}
onClick={() => (bleState.searching ? handleStopScan() : handleStartScan())}>
{!bleState.searching ? 'Scan' : 'Stop'}
</button>
<button disabled={!bleState.ready || !bleState.connected}>Disconnect</button>
</div>
);
};
export default BleControl;