refactor state refresh.
This commit is contained in:
parent
d9a4f92c04
commit
3ca730a82b
@ -1,9 +1,9 @@
|
|||||||
import { invoke } from '@tauri-apps/api/core';
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
import { Event, 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 } from 'jotai/utils';
|
import { atomFamily, atomWithRefresh } from 'jotai/utils';
|
||||||
import { FC, ReactNode, useCallback, useEffect, useRef } from 'react';
|
import { FC, ReactNode, useEffect, useRef } from 'react';
|
||||||
|
|
||||||
export type Channels = 'a' | 'b';
|
export type Channels = 'a' | 'b';
|
||||||
type ChannelState = {
|
type ChannelState = {
|
||||||
@ -15,7 +15,19 @@ type ChannelState = {
|
|||||||
boostLevel: number;
|
boostLevel: number;
|
||||||
maxBoostLevel: number;
|
maxBoostLevel: number;
|
||||||
};
|
};
|
||||||
|
type PeripheralItem = {
|
||||||
|
id: string;
|
||||||
|
address: string;
|
||||||
|
represent: string;
|
||||||
|
isConnected: boolean;
|
||||||
|
rssi: number | null;
|
||||||
|
battery: number | null;
|
||||||
|
};
|
||||||
type DeviceState = {
|
type DeviceState = {
|
||||||
|
id: string | null;
|
||||||
|
address: string | null;
|
||||||
|
represent: string | null;
|
||||||
|
isConnected: boolean | null;
|
||||||
rssi: number | null;
|
rssi: number | null;
|
||||||
battery: number | null;
|
battery: number | null;
|
||||||
};
|
};
|
||||||
@ -25,57 +37,136 @@ type BluetoothState = {
|
|||||||
connected: string | null;
|
connected: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const BleState = atom<BluetoothState>({
|
export const BleState = atomWithRefresh<BluetoothState>(async (get) => {
|
||||||
ready: null,
|
try {
|
||||||
searching: null,
|
const state = await invoke('central_device_state');
|
||||||
connected: null,
|
return {
|
||||||
|
ready: state.isReady,
|
||||||
|
searching: state.isScanning,
|
||||||
|
connected: state.connected,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[refresh central]', e);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
ready: null,
|
||||||
|
searching: null,
|
||||||
|
connected: null,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
export const DeviceState = atom<DeviceState>({
|
export const DeviceState = atomWithRefresh<DeviceState>(async (get) => {
|
||||||
rssi: null,
|
try {
|
||||||
battery: null,
|
const state = await invoke('connected_peripheral_state');
|
||||||
|
return {
|
||||||
|
id: state?.id,
|
||||||
|
address: state?.address,
|
||||||
|
represent: state?.represent,
|
||||||
|
isConnected: state?.isConnected,
|
||||||
|
rssi: state?.rssi,
|
||||||
|
battery: state?.battery,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[refresh connected]', e);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
id: null,
|
||||||
|
address: null,
|
||||||
|
represent: null,
|
||||||
|
isConnected: null,
|
||||||
|
rssi: null,
|
||||||
|
battery: null,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
export const FoundPeripherals = atomWithRefresh<PeripheralItem[]>(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 [];
|
||||||
});
|
});
|
||||||
const Channels: Record<Channels, PrimitiveAtom<ChannelState>> = {
|
const Channels: Record<Channels, PrimitiveAtom<ChannelState>> = {
|
||||||
a: atom<ChannelState>({
|
a: atomWithRefresh<ChannelState>(async (get) => {
|
||||||
playing: false,
|
try {
|
||||||
playMode: 'repeat-one',
|
const state = await invoke('channel_a_state');
|
||||||
strength: 0,
|
return {
|
||||||
maxStrength: 100,
|
playing: state.isPlaying,
|
||||||
boosting: false,
|
playMode: state.playMode,
|
||||||
boostLevel: 0,
|
strength: state.strength,
|
||||||
maxBoostLevel: 100,
|
maxStrength: state.maxStrength,
|
||||||
|
boosting: state.isBoosting,
|
||||||
|
boostLevel: state.boostLevel,
|
||||||
|
maxBoostLevel: state.maxBoostLevel,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[refresh channel a]', e);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
playing: false,
|
||||||
|
playMode: 'repeat-one',
|
||||||
|
strength: 0,
|
||||||
|
maxStrength: 100,
|
||||||
|
boosting: false,
|
||||||
|
boostLevel: 0,
|
||||||
|
maxBoostLevel: 100,
|
||||||
|
};
|
||||||
}),
|
}),
|
||||||
b: atom<ChannelState>({
|
b: atom<ChannelState>(async (get) => {
|
||||||
playing: false,
|
try {
|
||||||
playMode: 'repeat-one',
|
const state = await invoke('channel_b_state');
|
||||||
strength: 0,
|
return {
|
||||||
maxStrength: 100,
|
playing: state.isPlaying,
|
||||||
boosting: false,
|
playMode: state.playMode,
|
||||||
boostLevel: 0,
|
strength: state.strength,
|
||||||
maxBoostLevel: 100,
|
maxStrength: state.maxStrength,
|
||||||
|
boosting: state.isBoosting,
|
||||||
|
boostLevel: state.boostLevel,
|
||||||
|
maxBoostLevel: state.maxBoostLevel,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[refresh channel b]', e);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
playing: false,
|
||||||
|
playMode: 'repeat-one',
|
||||||
|
strength: 0,
|
||||||
|
maxStrength: 100,
|
||||||
|
boosting: false,
|
||||||
|
boostLevel: 0,
|
||||||
|
maxBoostLevel: 100,
|
||||||
|
};
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
export const ChannelState = atomFamily((channel: Channels) => Channels[channel]);
|
export const ChannelState = atomFamily((channel: Channels) => Channels[channel]);
|
||||||
|
|
||||||
const EstimWatchProvider: FC<{ children?: ReactNode }> = ({ children }) => {
|
const EstimWatchProvider: FC<{ children?: ReactNode }> = ({ children }) => {
|
||||||
const unlisten = useRef<UnlistenFn | null>(null);
|
const unlistenBle = useRef<UnlistenFn | null>(null);
|
||||||
const setBleState = useSetAtom(BleState);
|
const unlistenDevice = useRef<UnlistenFn | null>(null);
|
||||||
const handleAppStateRefresh = useCallback(async (event: Event<unknown>) => {
|
const unlistenPreipherals = useRef<UnlistenFn | null>(null);
|
||||||
try {
|
const unlistenChannelA = useRef<UnlistenFn | null>(null);
|
||||||
const newState = await invoke('refresh_application_state');
|
const unlistenChannelB = useRef<UnlistenFn | null>(null);
|
||||||
setBleState({
|
const refreshBle = useSetAtom(BleState);
|
||||||
ready: newState.central.is_ready,
|
const refreshDevice = useSetAtom(DeviceState);
|
||||||
searching: newState.central.is_scanning,
|
const refreshPeripherals = useSetAtom(FoundPeripherals);
|
||||||
connected: newState.central.connected,
|
const refreshChannelA = useSetAtom(ChannelState('a'));
|
||||||
});
|
const refreshChannelB = useSetAtom(ChannelState('b'));
|
||||||
} catch (e) {
|
|
||||||
console.error('[Answer refresh state]', e);
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async function () {
|
(async function () {
|
||||||
try {
|
try {
|
||||||
unlisten.current = await listen('app_state_updated', handleAppStateRefresh);
|
unlistenBle.current = await listen('central_state_updated', () => refreshBle());
|
||||||
|
unlistenDevice.current = await listen('peripheral_connected', () => refreshDevice());
|
||||||
|
unlistenPreipherals.current = await listen('peripherals_found', () => refreshPeripherals());
|
||||||
|
unlistenChannelA.current = await listen('channel_a_updated', () => refreshChannelA());
|
||||||
|
unlistenChannelB.current = await listen('channel_b_updated', () => refreshChannelB());
|
||||||
await invoke('activate_central_adapter');
|
await invoke('activate_central_adapter');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[Activate Adapter]', e);
|
console.error('[Activate Adapter]', e);
|
||||||
@ -87,7 +178,11 @@ const EstimWatchProvider: FC<{ children?: ReactNode }> = ({ children }) => {
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unlisten.current?.();
|
unlistenBle.current?.();
|
||||||
|
unlistenDevice.current?.();
|
||||||
|
unlistenPreipherals.current?.();
|
||||||
|
unlistenChannelA.current?.();
|
||||||
|
unlistenChannelB.current?.();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
return <>{children}</>;
|
return <>{children}</>;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user