diff options
| author | Luke Hoersten <[email protected]> | 2026-06-15 08:12:05 -0500 |
|---|---|---|
| committer | Luke Hoersten <[email protected]> | 2026-06-15 08:12:05 -0500 |
| commit | 1c426d953b3c8ae1f4f1bebb169fe2d668887eb9 (patch) | |
| tree | 215c6c8a7a58ac383afbaa7612cc902c41f497da | |
| parent | fc15eccfb6bb891f63b0ad37f14850464b0d90a6 (diff) | |
scrypted: debounce onBindingChanged so a multi-field Settings save registers once
| -rw-r--r-- | scrypted/scrypted-viewport.ts | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/scrypted/scrypted-viewport.ts b/scrypted/scrypted-viewport.ts index 28e04ed..fb2c4b8 100644 --- a/scrypted/scrypted-viewport.ts +++ b/scrypted/scrypted-viewport.ts @@ -407,14 +407,25 @@ class ScryptedViewportProvider extends ScryptedDeviceBase // Per-binding plumbing (camera subscription + /config registration) // ------------------------------------------------------------------------ + // Per-viewport debounce timer. Scrypted's Settings UI does one + // putSetting per field on save, so a typical "Save" with 5 fields + // changed used to register 5 times. Coalesce into a single apply. + private bindingDebounce = new Map<string, NodeJS.Timeout>(); + onBindingChanged = async (v: Viewport): Promise<void> => { const nid = v.nativeId!; - this.detachListener(nid); - // Any active stream for this viewport is now stale (camera may have - // changed). Stop it cleanly; the next event/wake will start fresh. - this.stopStream(v.name, /*sendSleep=*/ false); - this.attachListener(v); - await this.registerViewport(v); + const pending = this.bindingDebounce.get(nid); + if (pending) clearTimeout(pending); + this.bindingDebounce.set(nid, setTimeout(() => { + this.bindingDebounce.delete(nid); + this.detachListener(nid); + // Any active stream for this viewport is now stale (camera + // may have changed). Stop cleanly; next event/wake will + // start fresh. + this.stopStream(v.name, /*sendSleep=*/ false); + this.attachListener(v); + this.registerViewport(v).catch(() => {}); + }, 300)); }; private attachListener(v: Viewport) { |
