From 6c8bd6c52438d0fcace7df24a49155cbb8bc7bdf Mon Sep 17 00:00:00 2001 From: Vixalie Date: Fri, 28 Feb 2025 05:45:50 +0800 Subject: [PATCH] add bluetooth scan control. --- src/page-components/device/BleControl.tsx | 38 +++++++++++++++++++++-- src/pages/Device.tsx | 29 ++++++++++++++++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/src/page-components/device/BleControl.tsx b/src/page-components/device/BleControl.tsx index a068e75..073a529 100644 --- a/src/page-components/device/BleControl.tsx +++ b/src/page-components/device/BleControl.tsx @@ -1,14 +1,48 @@ +import { invoke } from '@tauri-apps/api/core'; import { useAtomValue } from 'jotai'; -import { FC } from 'react'; +import { FC, useCallback, useEffect, useRef, useState } from 'react'; import { BleState } from '../../context/EstimContext'; import styles from './BleControl.module.css'; const BleControl: FC = () => { const bleState = useAtomValue(BleState); + const timerRef = useRef(null); + const [searchRemains, setSearchRemains] = useState(60); + const handleStartScan = useCallback(async () => { + timerRef.current !== null && clearInterval(timerRef.current); + setSearchRemains(60); + 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 (
- + {bleState.searching && {searchRemains}s remains} +
); diff --git a/src/pages/Device.tsx b/src/pages/Device.tsx index dc052d2..85f9862 100644 --- a/src/pages/Device.tsx +++ b/src/pages/Device.tsx @@ -1,10 +1,37 @@ -import { FC } from 'react'; +import { listen, UnlistenFn } from '@tauri-apps/api/event'; +import { useSetAtom } from 'jotai'; +import { FC, useEffect, useRef } from 'react'; +import { BleState } from '../context/EstimContext'; import BleControl from '../page-components/device/BleControl'; import DeviceDetail from '../page-components/device/DeviceDetail'; import DeviceList from '../page-components/device/DeviceList'; import styles from './Device.module.css'; const Device: FC = () => { + const unlistenBleScanStart = useRef(null); + const unlistenBleScanStop = useRef(null); + const refreshBle = useSetAtom(BleState); + + useEffect(() => { + (async function () { + try { + unlistenBleScanStart.current = await listen('scanning_started', () => { + refreshBle(); + }); + unlistenBleScanStop.current = await listen('scanning_stopped', () => { + refreshBle(); + }); + } catch (error) { + console.error('[listen to scan]', error); + } + })(); + + return () => { + unlistenBleScanStart.current?.(); + unlistenBleScanStop.current?.(); + }; + }, []); + return (