diff --git a/src/context/EstimContext.tsx b/src/context/EstimContext.tsx index 044d5cc..1d7b86e 100644 --- a/src/context/EstimContext.tsx +++ b/src/context/EstimContext.tsx @@ -56,24 +56,37 @@ export const DeviceState = atomWithRefresh(async (get) => } return null; }); -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; +const Peripherals = atom([]); +export const FoundPeripherals = atom(null, (get, set, item: PeripheralItem | typeof RESET) => { + if (item === RESET) { + void set(Peripherals, []); + } else { + void set(Peripherals, (prev) => { + let replaced = false; + const newPeripherals = prev.map((i) => { + if (i.id === item.id) { + replaced = true; + return item; } else { - prev.push(item); + return i; } - return prev; }); - } - }, -); + if (!replaced) { + newPeripherals.push(item); + } + return newPeripherals; + }); + } +}); +export const AvailablePeripherals = atom((get) => { + const peripherals = get(Peripherals); + return peripherals.filter((i) => !i.isUnknown); +}); +export const UnknownPeripherals = atom((get) => { + const peripherals = get(Peripherals); + console.debug('[origin peripherals]', peripherals); + return peripherals.filter((i) => i.isUnknown); +}); const Channels: Record> = { a: atomWithRefresh(async (get) => { try { diff --git a/src/page-components/device/DeviceList.module.css b/src/page-components/device/DeviceList.module.css index ce41bb4..5bb895e 100644 --- a/src/page-components/device/DeviceList.module.css +++ b/src/page-components/device/DeviceList.module.css @@ -5,4 +5,43 @@ flex-direction: column; align-items: stretch; } + .devices_list_layout { + padding-inline: calc(var(--spacing) * 2); + display: flex; + flex-direction: column; + align-items: stretch; + gap: calc(var(--spacing) * 4); + } + .devices_list { + display: flex; + flex-direction: column; + align-items: stretch; + gap: calc(var(--spacing) * 2); + .device_card { + padding-inline: calc(var(--spacing) * 2); + padding-block: calc(var(--spacing) * 3); + border-radius: calc(var(--border-radius) * 2); + background-color: var(--color-dark-surface); + color: var(--color-dark-on-surface); + display: flex; + flex-direction: row; + align-items: center; + gap: calc(var(--spacing) * 1); + .device_name { + flex: 1; + font-size: calc(var(--font-size) * 1.3); + overflow: hidden; + text-overflow: ellipsis; + } + &:hover { + background-color: color-mix(in oklch, var(--color-dark-on-surface) 8%, transparent); + } + } + .empty_prompt { + padding-block: calc(var(--spacing) * 1); + text-align: center; + font-size: calc(var(--font-size) * 0.8); + color: var(--color-dark-on-surface-variant); + } + } } diff --git a/src/page-components/device/DeviceList.tsx b/src/page-components/device/DeviceList.tsx index a21b9ed..cbe9897 100644 --- a/src/page-components/device/DeviceList.tsx +++ b/src/page-components/device/DeviceList.tsx @@ -1,11 +1,34 @@ +import { useAtomValue } from 'jotai'; import { FC } from 'react'; import { ScrollArea } from '../../components/ScrollArea'; +import { AvailablePeripherals } from '../../context/EstimContext'; +import IconRssi from '../../icons/IconRssi'; import styles from './DeviceList.module.css'; +const AvailableDevices: FC = () => { + const devices = useAtomValue(AvailablePeripherals); + + return ( +
+ {devices.length === 0 &&
No available devices.
} + {devices.map((device, index) => ( +
+
{device.represent}
+ +
+ ))} +
+ ); +}; + const DeviceList: FC = () => { return (
- + +
+ +
+
); };