@o-lukas/homebridge-smartthings-tv 3.0.0-alpha.1 → 3.0.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -153,154 +153,322 @@
153
153
  </div>
154
154
 
155
155
  <script>
156
+ // Simple logger helpers
157
+ function _log(name, ...args) {
158
+ try {
159
+ console.log(`[index.html] ${name}`, ...args);
160
+ } catch (e) {
161
+ // ignore logging errors
162
+ }
163
+ }
164
+
165
+ function _logError(name, err) {
166
+ try {
167
+ // prefer structured console.error, but guard against failures
168
+ if (console && console.error) {
169
+ console.error(`[index.html] ${name}`, err);
170
+ } else {
171
+ _log(`${name} - error`, err && (err.stack || err));
172
+ }
173
+ } catch (e) {
174
+ // ensure logging never throws
175
+ try { _log(`${name} - failed to log error`, e); } catch (_) { /* ignore */ }
176
+ }
177
+ }
178
+
156
179
  function showWizard() {
157
- homebridge.disableSaveButton();
158
- homebridge.hideSchemaForm();
159
- document.getElementById('wizard').style.display = "block";
160
- document.getElementById('oauth-start').style.display = "none";
161
- document.getElementById('pat-warning').style.display = "none";
180
+ _log('showWizard - start');
181
+ try {
182
+ homebridge.disableSaveButton();
183
+ homebridge.hideSchemaForm();
184
+ document.getElementById('wizard').style.display = "block";
185
+ document.getElementById('oauth-start').style.display = "none";
186
+ document.getElementById('pat-warning').style.display = "none";
187
+ _log('showWizard - done');
188
+ } catch (err) {
189
+ _logError('showWizard - error', err);
190
+ throw err;
191
+ }
162
192
  }
163
193
 
164
194
  function hideWizard() {
165
- homebridge.enableSaveButton();
166
- homebridge.showSchemaForm();
167
- document.getElementById('wizard').style.display = "none";
168
- document.getElementById('oauth-start').style.display = "block";
169
- document.getElementById('pat-warning').style.display = "none";
195
+ _log('hideWizard - start');
196
+ try {
197
+ homebridge.enableSaveButton();
198
+ homebridge.showSchemaForm();
199
+ document.getElementById('wizard').style.display = "none";
200
+ document.getElementById('oauth-start').style.display = "block";
201
+ document.getElementById('pat-warning').style.display = "none";
202
+ _log('hideWizard - done');
203
+ } catch (err) {
204
+ _logError('hideWizard - error', err);
205
+ throw err;
206
+ }
170
207
  }
171
208
 
172
209
  async function updateUi() {
173
- const pluginConfig = await homebridge.getPluginConfig();
174
- if (pluginConfig.length === 0) {
175
- pluginConfig[0] = {
176
- platform: "smartthings-tv",
177
- tokenType: "oauth"
178
- };
179
- await homebridge.updatePluginConfig(pluginConfig);
180
- }
210
+ _log('updateUi - start');
211
+ try {
212
+ const pluginConfig = await homebridge.getPluginConfig();
213
+ _log('updateUi - got pluginConfig', pluginConfig);
214
+
215
+ // determine whether wizard is currently visible so we don't close it on config change
216
+ const wizardEl = document.getElementById('wizard');
217
+ const wizardOpen = !!(wizardEl && window.getComputedStyle(wizardEl).display !== 'none');
218
+ _log('updateUi - wizardOpen', wizardOpen);
219
+
220
+ if (pluginConfig.length === 0) {
221
+ _log('updateUi - pluginConfig empty, initializing default');
222
+ pluginConfig[0] = {
223
+ platform: "smartthings-tv",
224
+ tokenType: "oauth"
225
+ };
226
+ await homebridge.updatePluginConfig(pluginConfig);
227
+ _log('updateUi - default pluginConfig saved');
228
+ }
181
229
 
182
- switch (pluginConfig[0].tokenType) {
183
- case "oauth":
184
- homebridge.showSchemaForm();
185
- document.getElementById('wizard').style.display = "none";
186
- document.getElementById('oauth-start').style.display = "block";
187
- document.getElementById('pat-warning').style.display = "none";
188
- break;
189
-
190
- case "pat":
191
- default:
192
- homebridge.showSchemaForm();
193
- document.getElementById('wizard').style.display = "none";
194
- document.getElementById('oauth-start').style.display = "none";
195
- document.getElementById('pat-warning').style.display =
196
- pluginConfig[0].disablePatWarning === true ? "none" : "block";
197
- break;
198
- }
230
+ // Update UI elements but avoid closing the wizard if it's already open.
231
+ switch (pluginConfig[0].tokenType) {
232
+ case "oauth":
233
+ _log('updateUi - tokenType oauth');
234
+ homebridge.showSchemaForm();
235
+ // Only toggle wizard visibility when it's not currently open.
236
+ if (!wizardOpen) {
237
+ document.getElementById('wizard').style.display = "none";
238
+ document.getElementById('oauth-start').style.display = "block";
239
+ document.getElementById('pat-warning').style.display = "none";
240
+ _log('updateUi - wizard was closed, showing oauth-start');
241
+ } else {
242
+ _log('updateUi - wizard open, leaving wizard visible');
243
+ }
244
+ break;
245
+
246
+ case "pat":
247
+ default:
248
+ _log('updateUi - tokenType pat or default', pluginConfig[0].tokenType);
249
+ homebridge.showSchemaForm();
250
+ if (!wizardOpen) {
251
+ document.getElementById('wizard').style.display = "none";
252
+ document.getElementById('oauth-start').style.display = "none";
253
+ document.getElementById('pat-warning').style.display =
254
+ pluginConfig[0].disablePatWarning === true ? "none" : "block";
255
+ _log('updateUi - wizard was closed, applied pat/default visibility');
256
+ } else {
257
+ _log('updateUi - wizard open, leaving wizard visible');
258
+ }
259
+ break;
260
+ }
199
261
 
200
- document.getElementById('oauth-client-id').value = pluginConfig[0].oauthClientId ?? '';
201
- document.getElementById('oauth-client-secret').value = pluginConfig[0].oauthClientSecret ?? '';
262
+ document.getElementById('oauth-client-id').value = pluginConfig[0].oauthClientId ?? '';
263
+ document.getElementById('oauth-client-secret').value = pluginConfig[0].oauthClientSecret ?? '';
264
+
265
+ _log('updateUi - end');
266
+ } catch (err) {
267
+ _logError('updateUi - error', err);
268
+ throw err;
269
+ }
202
270
  }
203
271
 
204
272
  function validateStep(id) {
205
- var form = document.getElementById(id);
206
- if (form.checkValidity() === false) {
207
- form.classList.add('was-validated');
208
- return false;
209
- } else {
210
- nextStep();
211
- return true;
273
+ _log('validateStep - start', id);
274
+ try {
275
+ var form = document.getElementById(id);
276
+ if (form.checkValidity() === false) {
277
+ _log('validateStep - invalid', id);
278
+ form.classList.add('was-validated');
279
+ return false;
280
+ } else {
281
+ _log('validateStep - valid, advancing');
282
+ nextStep();
283
+ return true;
284
+ }
285
+ } catch (err) {
286
+ _logError('validateStep - error', err);
287
+ throw err;
212
288
  }
213
289
  }
214
290
 
215
291
  async function validateStep1() {
216
- if (validateStep('step1Form')) {
217
- const pluginConfig = await homebridge.getPluginConfig();
218
- pluginConfig[0].oauthClientId = document.getElementById('oauth-client-id').value;
219
- pluginConfig[0].oauthClientSecret = document.getElementById('oauth-client-secret').value;
220
-
221
- await homebridge.updatePluginConfig(pluginConfig);
292
+ _log('validateStep1 - start');
293
+ try {
294
+ if (validateStep('step1Form')) {
295
+ const pluginConfig = await homebridge.getPluginConfig();
296
+ _log('validateStep1 - current pluginConfig', pluginConfig);
297
+ pluginConfig[0].oauthClientId = document.getElementById('oauth-client-id').value;
298
+ pluginConfig[0].oauthClientSecret = document.getElementById('oauth-client-secret').value;
299
+ _log('validateStep1 - updating pluginConfig', {
300
+ oauthClientId: pluginConfig[0].oauthClientId ? '***' : '',
301
+ oauthClientSecret: pluginConfig[0].oauthClientSecret ? '***' : ''
302
+ });
303
+ await homebridge.updatePluginConfig(pluginConfig);
304
+ _log('validateStep1 - update complete');
305
+ } else {
306
+ _log('validateStep1 - form invalid, abort');
307
+ }
308
+ } catch (err) {
309
+ _logError('validateStep1 - error', err);
310
+ throw err;
222
311
  }
223
312
  }
224
313
 
225
314
  async function validateStep2() {
226
- nextStep();
227
- requestAuthCode();
315
+ _log('validateStep2 - start');
316
+ try {
317
+ nextStep();
318
+ _log('validateStep2 - requested nextStep, calling requestAuthCode');
319
+ requestAuthCode();
320
+ _log('validateStep2 - requestAuthCode called (not awaited)');
321
+ } catch (err) {
322
+ _logError('validateStep2 - error', err);
323
+ throw err;
324
+ }
228
325
  }
229
326
 
230
327
  async function validateStep3() {
231
- if (validateStep('step3Form')) {
232
- homebridge.showSpinner();
233
-
234
- try {
235
- await requestAuthToken();
236
- } catch {
237
- homebridge.toast.error("Could not request authorization token");
238
- } finally {
239
- homebridge.hideSpinner();
328
+ _log('validateStep3 - start');
329
+ try {
330
+ if (validateStep('step3Form')) {
331
+ homebridge.showSpinner();
332
+ _log('validateStep3 - spinner shown, requesting token');
333
+ try {
334
+ await requestAuthToken();
335
+ _log('validateStep3 - requestAuthToken succeeded');
336
+ } catch (err) {
337
+ _logError('validateStep3 - requestAuthToken error', err);
338
+ homebridge.toast.error("Could not request authorization token");
339
+ } finally {
340
+ homebridge.hideSpinner();
341
+ _log('validateStep3 - spinner hidden');
342
+ }
343
+ } else {
344
+ _log('validateStep3 - form invalid, abort');
240
345
  }
346
+ } catch (err) {
347
+ _logError('validateStep3 - error', err);
348
+ throw err;
241
349
  }
242
350
  }
243
351
 
244
352
  async function validateStep4() {
245
- if (validateStep('step4Form')) {
246
- const pluginConfig = await homebridge.getPluginConfig();
247
- pluginConfig[0].oauthRefreshToken = document.getElementById('oauth-refresh-token').value;
248
-
249
- await homebridge.updatePluginConfig(pluginConfig);
250
- await homebridge.savePluginConfig();
251
-
252
- homebridge.toast.success("Restart Homebridge to apply the changes.", "OAuth Config Saved");
253
-
254
- hideWizard();
255
- updateUi();
353
+ _log('validateStep4 - start');
354
+ try {
355
+ if (validateStep('step4Form')) {
356
+ const pluginConfig = await homebridge.getPluginConfig();
357
+ _log('validateStep4 - got pluginConfig', pluginConfig);
358
+ pluginConfig[0].oauthRefreshToken = document.getElementById('oauth-refresh-token').value;
359
+ _log('validateStep4 - setting oauthRefreshToken ***');
360
+
361
+ await homebridge.updatePluginConfig(pluginConfig);
362
+ await homebridge.savePluginConfig();
363
+
364
+ homebridge.toast.success("Restart Homebridge to apply the changes.", "OAuth Config Saved");
365
+
366
+ hideWizard();
367
+ updateUi();
368
+ _log('validateStep4 - complete');
369
+ } else {
370
+ _log('validateStep4 - form invalid, abort');
371
+ }
372
+ } catch (err) {
373
+ _logError('validateStep4 - error', err);
374
+ throw err;
256
375
  }
257
376
  }
258
377
 
259
378
  function nextStep() {
260
- let activeTab = document.querySelector('.nav-pills .active');
261
- let nextTab = activeTab.nextElementSibling;
262
- if (nextTab) changeTab(nextTab);
379
+ _log('nextStep - start');
380
+ try {
381
+ let activeTab = document.querySelector('.nav-pills .active');
382
+ let nextTab = activeTab.nextElementSibling;
383
+ _log('nextStep - activeTab', activeTab ? activeTab.getAttribute('data-target') : null, 'nextTab', nextTab ? nextTab.getAttribute('data-target') : null);
384
+ if (nextTab) changeTab(nextTab);
385
+ _log('nextStep - done');
386
+ } catch (err) {
387
+ _logError('nextStep - error', err);
388
+ throw err;
389
+ }
263
390
  }
264
391
 
265
392
  function prevStep() {
266
- let activeTab = document.querySelector('.nav-pills .active');
267
- let prevTab = activeTab.previousElementSibling;
268
- if (prevTab) changeTab(prevTab);
393
+ _log('prevStep - start');
394
+ try {
395
+ let activeTab = document.querySelector('.nav-pills .active');
396
+ let prevTab = activeTab.previousElementSibling;
397
+ _log('prevStep - activeTab', activeTab ? activeTab.getAttribute('data-target') : null, 'prevTab', prevTab ? prevTab.getAttribute('data-target') : null);
398
+ if (prevTab) changeTab(prevTab);
399
+ _log('prevStep - done');
400
+ } catch (err) {
401
+ _logError('prevStep - error', err);
402
+ throw err;
403
+ }
269
404
  }
270
405
 
271
406
  function changeTab(targetTab) {
272
- document.querySelector('.nav-pills .active').classList.remove('active');
273
- document.querySelector('.tab-pane.show').classList.remove('show', 'active');
274
-
275
- targetTab.classList.add('active');
276
- document.querySelector(targetTab.getAttribute('data-target')).classList.add('show', 'active');
407
+ _log('changeTab - start', targetTab ? targetTab.getAttribute('data-target') : targetTab);
408
+ try {
409
+ document.querySelector('.nav-pills .active').classList.remove('active');
410
+ document.querySelector('.tab-pane.show').classList.remove('show', 'active');
411
+
412
+ targetTab.classList.add('active');
413
+ document.querySelector(targetTab.getAttribute('data-target')).classList.add('show', 'active');
414
+ _log('changeTab - done', targetTab.getAttribute('data-target'));
415
+ } catch (err) {
416
+ _logError('changeTab - error', err);
417
+ throw err;
418
+ }
277
419
  }
278
420
 
279
421
  async function requestAuthCode() {
280
- const authUrl = await homebridge.request('/authCode', {
281
- clientId: document.getElementById('oauth-client-id').value,
282
- clientSecret: document.getElementById('oauth-client-secret').value,
283
- redirectUrl: document.getElementById('oauth-redirect-url').value,
284
- scopes: document.getElementById('oauth-scopes').value
285
- });
286
-
287
- window.open(authUrl, "_blank");
422
+ _log('requestAuthCode - start');
423
+ try {
424
+ const payload = {
425
+ clientId: document.getElementById('oauth-client-id').value,
426
+ clientSecret: document.getElementById('oauth-client-secret').value,
427
+ redirectUrl: document.getElementById('oauth-redirect-url').value,
428
+ scopes: document.getElementById('oauth-scopes').value
429
+ };
430
+ _log('requestAuthCode - payload', { clientId: payload.clientId ? '***' : '', redirectUrl: payload.redirectUrl, scopes: payload.scopes });
431
+
432
+ const authUrl = await homebridge.request('/authCode', payload);
433
+ _log('requestAuthCode - got authUrl', authUrl);
434
+
435
+ window.open(authUrl, "_blank");
436
+ _log('requestAuthCode - window.open called');
437
+ return authUrl;
438
+ } catch (err) {
439
+ _logError('requestAuthCode - error', err);
440
+ throw err;
441
+ }
288
442
  }
289
443
 
290
444
  async function requestAuthToken() {
291
- const authToken = await homebridge.request('/authToken', {
292
- code: document.getElementById('oauth-code').value,
293
- redirectUrl: document.getElementById('oauth-redirect-url').value,
294
- scopes: document.getElementById('oauth-scopes').value
295
- });
296
-
297
- document.getElementById('oauth-access-token').value = authToken.access_token;
298
- document.getElementById('oauth-refresh-token').value = authToken.refresh_token;
445
+ _log('requestAuthToken - start');
446
+ try {
447
+ const payload = {
448
+ code: document.getElementById('oauth-code').value,
449
+ redirectUrl: document.getElementById('oauth-redirect-url').value,
450
+ scopes: document.getElementById('oauth-scopes').value
451
+ };
452
+ _log('requestAuthToken - payload', { code: payload.code ? '***' : '', redirectUrl: payload.redirectUrl, scopes: payload.scopes });
453
+
454
+ const authToken = await homebridge.request('/authToken', payload);
455
+ _log('requestAuthToken - got authToken', { access: authToken?.access_token ? '***' : null, refresh: authToken?.refresh_token ? '***' : null });
456
+
457
+ document.getElementById('oauth-access-token').value = authToken.access_token;
458
+ document.getElementById('oauth-refresh-token').value = authToken.refresh_token;
459
+ _log('requestAuthToken - tokens set in UI');
460
+ return authToken;
461
+ } catch (err) {
462
+ _logError('requestAuthToken - error', err);
463
+ throw err;
464
+ }
299
465
  }
300
466
 
467
+ _log('initializing - calling updateUi');
301
468
  updateUi();
302
469
 
303
470
  window.homebridge.addEventListener('configChanged', (event) => {
471
+ _log('homebridge.configChanged event received', event);
304
472
  updateUi();
305
473
  });
306
474
  </script>
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "displayName": "Homebridge SmartThings TV",
3
3
  "name": "@o-lukas/homebridge-smartthings-tv",
4
4
  "type": "module",
5
- "version": "3.0.0-alpha.1",
5
+ "version": "3.0.0-alpha.3",
6
6
  "description": "This is a plugin for Homebridge. It offers some basic functions to control Samsung TVs using the SmartThings API.",
7
7
  "author": "o-lukas",
8
8
  "license": "MIT",