2026-08-27 21:38:51 +02:00
|
|
|
import type { ConnectedDeviceInfo, ReplayDeviceSlot } from "./types";
|
2026-08-25 07:51:38 +02:00
|
|
|
|
|
|
|
|
export interface DeviceRemapEntry {
|
|
|
|
|
slotLabel: string;
|
|
|
|
|
recordedBleName: string;
|
|
|
|
|
matchedDeviceIndex: number | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-08-27 21:38:51 +02:00
|
|
|
* Best-effort name match from a session's device slots to the
|
2026-08-25 07:51:38 +02:00
|
|
|
* currently-connected devices. Web Bluetooth exposes no stable hardware id
|
|
|
|
|
* across sessions, so this is inherently approximate: two devices sharing an
|
|
|
|
|
* identical advertised name are indistinguishable and must be disambiguated
|
|
|
|
|
* manually in the remap UI - this isn't a bug, it's a hard BLE limitation.
|
|
|
|
|
*/
|
|
|
|
|
export function autoMapDeviceSlots(
|
2026-08-27 21:38:51 +02:00
|
|
|
slots: ReplayDeviceSlot[],
|
2026-08-25 07:51:38 +02:00
|
|
|
connectedDevices: ConnectedDeviceInfo[],
|
|
|
|
|
): DeviceRemapEntry[] {
|
|
|
|
|
const usedIndexes = new Set<number>();
|
|
|
|
|
|
|
|
|
|
return slots.map((slot) => {
|
|
|
|
|
const normalizedSlotName = slot.recordedBleName.trim().toLowerCase();
|
|
|
|
|
|
|
|
|
|
const exact = connectedDevices.find(
|
|
|
|
|
(d) => !usedIndexes.has(d.index) && d.name.trim().toLowerCase() === normalizedSlotName,
|
|
|
|
|
);
|
|
|
|
|
const partial =
|
|
|
|
|
exact ??
|
|
|
|
|
connectedDevices.find(
|
|
|
|
|
(d) =>
|
|
|
|
|
!usedIndexes.has(d.index) &&
|
|
|
|
|
(d.name.toLowerCase().includes(normalizedSlotName) ||
|
|
|
|
|
normalizedSlotName.includes(d.name.toLowerCase())),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (partial) usedIndexes.add(partial.index);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
slotLabel: slot.slotLabel,
|
|
|
|
|
recordedBleName: slot.recordedBleName,
|
|
|
|
|
matchedDeviceIndex: partial?.index ?? null,
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
}
|