- {pending
+ {pending || remote.pending
? "Saving switches..."
- : unsaved
+ : unsaved || remote.unsaved
? "Switch assignments have unsaved changes."
: "Changes save automatically and apply straight away."}
+ {remote.error && (
+
+ {remote.error}
+
+ Retry save
+
+
+ )}
{(error || state?.error) && (
{error || state?.error}
@@ -496,7 +589,7 @@ export function SwitchesSection({ controller, onDraftChange, suspended = false }
)}
)}
- {!settings.bindings.length && !draft ? (
+ {!settings.bindings.length && !remoteRows.length && !draft ? (
No switches yet
@@ -504,15 +597,25 @@ export function SwitchesSection({ controller, onDraftChange, suspended = false }
Automatic scanning needs a Select switch. Manual scanning also
needs Next and Previous.
-
- Add switch
-
+
+
+ Add switch
+
+
+ Add remote switch
+
+
) : (
@@ -583,23 +686,95 @@ export function SwitchesSection({ controller, onDraftChange, suspended = false }
);
})}
+ {remoteRows.map(({ slot, index }) => {
+ const binding = remoteBinding(slot, index);
+ const open = expanded === binding.id;
+ const name = binding.name || `Remote switch ${index + 1}`;
+ return (
+
+
+
+
+
{name}
+
{summary(binding)}
+
+
+
{
+ if (el) editRefs.current.set(binding.id, el);
+ else editRefs.current.delete(binding.id);
+ }}
+ aria-expanded={open}
+ aria-controls={open ? `${listId}-${binding.id}` : undefined}
+ aria-label={`${open ? "Close" : "Edit"} ${name}`}
+ disabled={!!draft}
+ onClick={() => setExpanded(open ? null : binding.id)}
+ >
+ {open ? "Close" : "Edit"}
+
+
{
+ focusAfter.current = newId;
+ setSlot(index, null);
+ }}
+ >
+
+
+
+ {open && (
+ setSlot(index, slotFrom(next))}
+ onLearn={() => {}}
+ onDone={() => {
+ focusAfter.current = binding.id;
+ setExpanded(null);
+ }}
+ onRemove={() => {
+ focusAfter.current = newId;
+ setSlot(index, null);
+ }}
+ nameRef={nameRef}
+ remote={{ slot: index, free: freeSlots, onSlot: (to) => moveSlot(index, to) }}
+ />
+ )}
+
+ );
+ })}
{draft && (
-
+ {draftSlot === null ?
:
}
-
New switch
+
{draftSlot === null ? "New switch" : "New remote switch"}
- {draft.key
- ? "Name it and choose its actions, then save."
- : "Learn its key first."}
+ {draftSlot !== null
+ ? "Choose its number and actions, then save."
+ : draft.key
+ ? "Name it and choose its actions, then save."
+ : "Learn its key first."}
s !== draftSlot),
+ onSlot: (slot) => {
+ setDraftSlot(slot);
+ setDraft({ ...draft, key: `Remote ${slot + 1}` });
+ },
+ }
+ }
/>
)}
@@ -622,6 +809,14 @@ export function SwitchesSection({ controller, onDraftChange, suspended = false }
>
Add switch
+
+ Add remote switch
+
)}