@switchbot/homebridge-switchbot 5.0.0-beta.111 → 5.0.0-beta.112
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.
- package/dist/homebridge-ui/public/css/styles.css +111 -16
- package/dist/homebridge-ui/public/index.html +34 -60
- package/dist/homebridge-ui/public/js/app.js +103 -41
- package/dist/homebridge-ui/public/js/app.js.map +3 -3
- package/dist/homebridge-ui/public/js/discovery.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/discovery.js +24 -1
- package/dist/homebridge-ui/public/js/discovery.js.map +1 -1
- package/dist/homebridge-ui/public/js/discovery.ts +25 -1
- package/dist/homebridge-ui/public/js/render.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/render.js +78 -35
- package/dist/homebridge-ui/public/js/render.js.map +1 -1
- package/dist/homebridge-ui/public/js/render.ts +79 -35
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +1 -6
- package/dist/platform.js.map +1 -1
- package/docs/variables/default.html +1 -1
- package/package.json +9 -8
- package/src/homebridge-ui/public/css/styles.css +111 -16
- package/src/homebridge-ui/public/index.html +34 -60
- package/src/homebridge-ui/public/js/discovery.ts +25 -1
- package/src/homebridge-ui/public/js/render.ts +79 -35
- package/src/platform.ts +1 -6
- package/test/e2e/run-e2e.spec.ts +12 -10
- package/test/helpers/matter-harness.ts +2 -2
- package/todo/COMPLETED.md +13 -0
- package/switchbot-homebridge-switchbot-5.0.0.tgz +0 -0
|
@@ -75,12 +75,13 @@ body {
|
|
|
75
75
|
system-ui,
|
|
76
76
|
-apple-system,
|
|
77
77
|
Arial;
|
|
78
|
-
padding:
|
|
78
|
+
padding: 10px;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
h1 {
|
|
82
|
-
font-size:
|
|
82
|
+
font-size: 18px;
|
|
83
83
|
margin-top: 0;
|
|
84
|
+
margin-bottom: 10px;
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
h2 {
|
|
@@ -152,25 +153,25 @@ code {
|
|
|
152
153
|
}
|
|
153
154
|
|
|
154
155
|
.form-group {
|
|
155
|
-
margin-bottom:
|
|
156
|
+
margin-bottom: 10px;
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
label {
|
|
159
160
|
display: block;
|
|
160
|
-
margin-bottom:
|
|
161
|
+
margin-bottom: 4px;
|
|
161
162
|
font-weight: 500;
|
|
162
|
-
font-size:
|
|
163
|
+
font-size: 11px;
|
|
163
164
|
color: #6b7280;
|
|
164
165
|
}
|
|
165
166
|
|
|
166
167
|
input {
|
|
167
168
|
width: 100%;
|
|
168
169
|
max-width: 400px;
|
|
169
|
-
padding: 8px
|
|
170
|
+
padding: 6px 8px;
|
|
170
171
|
border: 1px solid #d1d5db;
|
|
171
172
|
border-radius: 6px;
|
|
172
173
|
font-family: system-ui, -apple-system, monospace;
|
|
173
|
-
font-size:
|
|
174
|
+
font-size: 12px;
|
|
174
175
|
transition: all 0.2s ease;
|
|
175
176
|
}
|
|
176
177
|
|
|
@@ -203,8 +204,8 @@ select:focus {
|
|
|
203
204
|
}
|
|
204
205
|
|
|
205
206
|
.status {
|
|
206
|
-
font-size:
|
|
207
|
-
margin-top:
|
|
207
|
+
font-size: 11px;
|
|
208
|
+
margin-top: 3px;
|
|
208
209
|
}
|
|
209
210
|
|
|
210
211
|
.status.ok {
|
|
@@ -221,27 +222,121 @@ select:focus {
|
|
|
221
222
|
}
|
|
222
223
|
|
|
223
224
|
.card {
|
|
224
|
-
padding:
|
|
225
|
+
padding: 12px;
|
|
225
226
|
border-radius: 8px;
|
|
226
|
-
margin-bottom:
|
|
227
|
+
margin-bottom: 10px;
|
|
227
228
|
}
|
|
228
229
|
|
|
229
|
-
.
|
|
230
|
-
padding: 10px
|
|
231
|
-
|
|
230
|
+
.card.compact {
|
|
231
|
+
padding: 10px;
|
|
232
|
+
margin-bottom: 10px;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.card.compact h2 {
|
|
236
|
+
margin-top: 0;
|
|
237
|
+
margin-bottom: 6px;
|
|
238
|
+
font-size: 13px;
|
|
239
|
+
font-weight: 600;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.card.compact .form-group {
|
|
232
243
|
margin-bottom: 6px;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.card.compact label {
|
|
247
|
+
font-size: 11px;
|
|
248
|
+
margin-bottom: 2px;
|
|
249
|
+
display: block;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.card.compact input {
|
|
253
|
+
padding: 5px 8px;
|
|
254
|
+
font-size: 12px;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.card.compact button {
|
|
258
|
+
padding: 6px 12px;
|
|
259
|
+
font-size: 12px;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.card.compact .status {
|
|
263
|
+
font-size: 11px;
|
|
264
|
+
margin-top: 4px;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.credentials-row {
|
|
268
|
+
display: flex;
|
|
269
|
+
flex-wrap: wrap;
|
|
270
|
+
gap: 8px;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.credentials-row .form-group {
|
|
274
|
+
flex: 1 1 100%;
|
|
275
|
+
min-width: 0;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
@media (min-width: 700px) {
|
|
279
|
+
.credentials-row {
|
|
280
|
+
gap: 10px;
|
|
281
|
+
align-items: start;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.credentials-row .form-group {
|
|
285
|
+
flex: 1 1 calc(50% - 5px);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.device-item {
|
|
290
|
+
padding: 5px 8px;
|
|
291
|
+
border-radius: 5px;
|
|
292
|
+
margin-bottom: 0;
|
|
233
293
|
display: flex;
|
|
234
|
-
gap:
|
|
294
|
+
gap: 8px;
|
|
235
295
|
align-items: center;
|
|
236
296
|
justify-content: space-between;
|
|
237
297
|
transition: all 0.2s ease;
|
|
298
|
+
height: 100%;
|
|
299
|
+
min-width: 0;
|
|
238
300
|
}
|
|
239
301
|
|
|
240
302
|
.device-item:hover {
|
|
241
|
-
transform: translateY(-
|
|
303
|
+
transform: translateY(-0.5px);
|
|
242
304
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
243
305
|
}
|
|
244
306
|
|
|
307
|
+
.device-actions {
|
|
308
|
+
display: flex;
|
|
309
|
+
flex-wrap: wrap;
|
|
310
|
+
gap: 6px;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
#devices.device-grid,
|
|
314
|
+
#discoveredDevices.device-grid,
|
|
315
|
+
ul.device-grid {
|
|
316
|
+
display: grid;
|
|
317
|
+
grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
|
|
318
|
+
gap: 6px;
|
|
319
|
+
padding-left: 0;
|
|
320
|
+
list-style: none;
|
|
321
|
+
margin: 0;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.device-item code {
|
|
325
|
+
display: inline-block;
|
|
326
|
+
max-width: 100%;
|
|
327
|
+
white-space: normal;
|
|
328
|
+
overflow-wrap: anywhere;
|
|
329
|
+
word-break: break-word;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
@media (max-width: 900px) {
|
|
333
|
+
.device-actions {
|
|
334
|
+
width: 100%;
|
|
335
|
+
justify-content: flex-start !important;
|
|
336
|
+
margin-left: 0 !important;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
245
340
|
.card {
|
|
246
341
|
padding: 16px;
|
|
247
342
|
border-radius: 8px;
|
|
@@ -9,65 +9,45 @@
|
|
|
9
9
|
<body>
|
|
10
10
|
<h1>🤖 SwitchBot Configuration</h1>
|
|
11
11
|
|
|
12
|
-
<div class="card">
|
|
12
|
+
<div class="card compact">
|
|
13
13
|
<h2>API Credentials</h2>
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
type="password"
|
|
23
|
-
id="
|
|
24
|
-
|
|
25
|
-
/>
|
|
26
|
-
<div class="status" id="tokenStatus"></div>
|
|
27
|
-
</div>
|
|
28
|
-
|
|
29
|
-
<div class="form-group">
|
|
30
|
-
<label for="secret">API Secret:</label>
|
|
31
|
-
<input
|
|
32
|
-
type="password"
|
|
33
|
-
id="secret"
|
|
34
|
-
placeholder="Enter your SwitchBot API secret"
|
|
35
|
-
/>
|
|
36
|
-
<div class="status" id="secretStatus"></div>
|
|
14
|
+
<div class="credentials-row">
|
|
15
|
+
<div class="form-group">
|
|
16
|
+
<label for="token">Token:</label>
|
|
17
|
+
<input type="password" id="token" placeholder="Enter token" />
|
|
18
|
+
<div class="status" id="tokenStatus"></div>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="form-group">
|
|
21
|
+
<label for="secret">Secret:</label>
|
|
22
|
+
<input type="password" id="secret" placeholder="Enter secret" />
|
|
23
|
+
<div class="status" id="secretStatus"></div>
|
|
24
|
+
</div>
|
|
37
25
|
</div>
|
|
38
|
-
|
|
39
|
-
<button id="saveBtn" onclick="saveCredentials()">Save Credentials</button>
|
|
26
|
+
<button id="saveBtn" onclick="saveCredentials()">Save</button>
|
|
40
27
|
<div id="saveStatus"></div>
|
|
41
28
|
</div>
|
|
42
29
|
|
|
43
|
-
<div class="card">
|
|
30
|
+
<div class="card compact">
|
|
44
31
|
<h2>Discover Devices</h2>
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
<input
|
|
54
|
-
type="checkbox"
|
|
55
|
-
id="autoAddAllCheckbox"
|
|
56
|
-
style="width: auto; margin: 0"
|
|
57
|
-
/>
|
|
58
|
-
<span>Auto-add all discovered devices</span>
|
|
32
|
+
<div style="margin-bottom: 6px">
|
|
33
|
+
<label style="display: flex; align-items: center; gap: 4px; cursor: pointer; font-size: 11px">
|
|
34
|
+
<input type="checkbox" id="autoAddAllCheckbox" style="width: auto; margin: 0" />
|
|
35
|
+
<span>Auto-add all</span>
|
|
36
|
+
<span
|
|
37
|
+
title="When enabled, Discover immediately adds all found devices to your config. Existing devices are skipped automatically."
|
|
38
|
+
style="font-size: 11px; opacity: 0.7"
|
|
39
|
+
>ⓘ</span>
|
|
59
40
|
</label>
|
|
41
|
+
<div style="margin-top: 2px; margin-left: 22px; font-size: 10px; opacity: 0.75; line-height: 1.25">
|
|
42
|
+
Adds all discovered devices automatically; already configured devices are skipped.
|
|
43
|
+
</div>
|
|
60
44
|
</div>
|
|
61
|
-
<button
|
|
62
|
-
|
|
63
|
-
onclick="discoverDevices()"
|
|
64
|
-
style="margin-bottom: 16px"
|
|
65
|
-
>
|
|
66
|
-
🔍 Discover Devices
|
|
45
|
+
<button id="discoverBtn" onclick="discoverDevices()" style="margin-bottom: 8px">
|
|
46
|
+
🔍 Discover
|
|
67
47
|
</button>
|
|
68
|
-
<div id="discoverStatus" style="margin-bottom:
|
|
48
|
+
<div id="discoverStatus" style="margin-bottom: 6px; font-size: 11px"></div>
|
|
69
49
|
<div id="discoveredList" style="display: none">
|
|
70
|
-
<h3 style="margin-top: 0">Available Devices</h3>
|
|
50
|
+
<h3 style="margin-top: 0; font-size: 12px; margin-bottom: 6px; font-weight: 600">Available Devices</h3>
|
|
71
51
|
<ul
|
|
72
52
|
id="discoveredDevices"
|
|
73
53
|
style="max-height: 300px; overflow-y: auto"
|
|
@@ -75,22 +55,16 @@
|
|
|
75
55
|
</div>
|
|
76
56
|
</div>
|
|
77
57
|
|
|
78
|
-
<div class="card">
|
|
58
|
+
<div class="card compact">
|
|
79
59
|
<h2>Configured Devices</h2>
|
|
80
|
-
<p>
|
|
81
|
-
This page lists devices found in your Homebridge config for the
|
|
82
|
-
SwitchBot platform. Use the copy button to insert device IDs into the
|
|
83
|
-
plugin configuration. Connection preference (BLE/OpenAPI) is shown when
|
|
84
|
-
available.
|
|
85
|
-
</p>
|
|
86
60
|
<div id="status">Loading…</div>
|
|
87
61
|
<ul id="devices"></ul>
|
|
88
62
|
<div
|
|
89
63
|
id="removeAllContainer"
|
|
90
64
|
style="
|
|
91
65
|
display: none;
|
|
92
|
-
margin-top:
|
|
93
|
-
padding-top:
|
|
66
|
+
margin-top: 12px;
|
|
67
|
+
padding-top: 10px;
|
|
94
68
|
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
|
95
69
|
"
|
|
96
70
|
>
|
|
@@ -99,8 +73,8 @@
|
|
|
99
73
|
style="
|
|
100
74
|
background: #dc2626;
|
|
101
75
|
width: 100%;
|
|
102
|
-
padding:
|
|
103
|
-
font-size:
|
|
76
|
+
padding: 7px 12px;
|
|
77
|
+
font-size: 12px;
|
|
104
78
|
font-weight: 500;
|
|
105
79
|
"
|
|
106
80
|
>
|
|
@@ -463,6 +463,17 @@ async function discoverDevices2() {
|
|
|
463
463
|
controlsDiv.appendChild(searchInput);
|
|
464
464
|
list.innerHTML = "";
|
|
465
465
|
list.appendChild(controlsDiv);
|
|
466
|
+
let deviceListContainer = document.getElementById("discoveredDevices");
|
|
467
|
+
if (!deviceListContainer) {
|
|
468
|
+
deviceListContainer = document.createElement("ul");
|
|
469
|
+
deviceListContainer.id = "discoveredDevices";
|
|
470
|
+
deviceListContainer.style.maxHeight = "400px";
|
|
471
|
+
deviceListContainer.style.overflowY = "auto";
|
|
472
|
+
deviceListContainer.style.marginTop = "12px";
|
|
473
|
+
deviceListContainer.style.padding = "0";
|
|
474
|
+
deviceListContainer.style.listStyle = "none";
|
|
475
|
+
list.appendChild(deviceListContainer);
|
|
476
|
+
}
|
|
466
477
|
list.style.display = "block";
|
|
467
478
|
await updateDiscoveryView(devices, preferences);
|
|
468
479
|
} catch (e) {
|
|
@@ -485,7 +496,15 @@ async function updateDiscoveryView(allDevices, preferences) {
|
|
|
485
496
|
const ul = await renderDiscoveredDevices(sorted, {
|
|
486
497
|
configuredIds
|
|
487
498
|
});
|
|
488
|
-
document.getElementById("discoveredDevices")
|
|
499
|
+
const existingList = document.getElementById("discoveredDevices");
|
|
500
|
+
if (existingList && existingList.parentNode) {
|
|
501
|
+
existingList.replaceWith(ul);
|
|
502
|
+
} else {
|
|
503
|
+
const listContainer = document.getElementById("discoveredList");
|
|
504
|
+
if (listContainer) {
|
|
505
|
+
listContainer.appendChild(ul);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
489
508
|
ul.id = "discoveredDevices";
|
|
490
509
|
const status = document.getElementById("discoverStatus");
|
|
491
510
|
if (status) {
|
|
@@ -1307,6 +1326,7 @@ function scrollToConfiguredDevice(deviceId) {
|
|
|
1307
1326
|
}
|
|
1308
1327
|
async function renderDiscoveredDevices(devices, options = {}) {
|
|
1309
1328
|
const ul = document.createElement("ul");
|
|
1329
|
+
ul.className = "device-grid";
|
|
1310
1330
|
ul.style.maxHeight = "400px";
|
|
1311
1331
|
ul.style.overflowY = "auto";
|
|
1312
1332
|
ul.style.marginTop = "12px";
|
|
@@ -1321,28 +1341,31 @@ async function renderDiscoveredDevices(devices, options = {}) {
|
|
|
1321
1341
|
const li = document.createElement("li");
|
|
1322
1342
|
li.className = "device-item";
|
|
1323
1343
|
li.style.display = "flex";
|
|
1324
|
-
li.style.
|
|
1325
|
-
li.style.
|
|
1326
|
-
li.style.
|
|
1327
|
-
li.style.
|
|
1328
|
-
li.style.
|
|
1344
|
+
li.style.flexDirection = "column";
|
|
1345
|
+
li.style.alignItems = "stretch";
|
|
1346
|
+
li.style.justifyContent = "flex-start";
|
|
1347
|
+
li.style.padding = "5px 8px";
|
|
1348
|
+
li.style.marginBottom = "0";
|
|
1349
|
+
li.style.borderRadius = "5px";
|
|
1329
1350
|
li.style.transition = "all 0.2s ease";
|
|
1330
1351
|
const info = document.createElement("div");
|
|
1331
|
-
info.style.flex = "1";
|
|
1352
|
+
info.style.flex = "1 1 auto";
|
|
1353
|
+
info.style.width = "100%";
|
|
1354
|
+
info.style.minWidth = "0";
|
|
1332
1355
|
const nameContainer = document.createElement("div");
|
|
1333
1356
|
nameContainer.style.display = "flex";
|
|
1334
1357
|
nameContainer.style.alignItems = "center";
|
|
1335
|
-
nameContainer.style.marginBottom = "
|
|
1358
|
+
nameContainer.style.marginBottom = "0";
|
|
1336
1359
|
nameContainer.style.flexWrap = "wrap";
|
|
1337
|
-
nameContainer.style.gap = "
|
|
1360
|
+
nameContainer.style.gap = "4px";
|
|
1338
1361
|
const name = document.createElement("div");
|
|
1339
1362
|
name.style.fontWeight = "500";
|
|
1340
|
-
name.style.fontSize = "
|
|
1363
|
+
name.style.fontSize = "13px";
|
|
1341
1364
|
name.textContent = d.name || d.id;
|
|
1342
1365
|
nameContainer.appendChild(name);
|
|
1343
1366
|
const duplicateBadge = document.createElement("span");
|
|
1344
1367
|
duplicateBadge.textContent = alreadyAdded ? "\u2713 Already Added" : "\u2795 New Device";
|
|
1345
|
-
duplicateBadge.style.cssText = alreadyAdded ? "background: #16a34a; color: white; padding:
|
|
1368
|
+
duplicateBadge.style.cssText = alreadyAdded ? "background: #16a34a; color: white; padding: 1px 5px; border-radius: 3px; font-size: 9px; font-weight: 600;" : "background: #2563eb; color: white; padding: 1px 5px; border-radius: 3px; font-size: 9px; font-weight: 600;";
|
|
1346
1369
|
nameContainer.appendChild(duplicateBadge);
|
|
1347
1370
|
if (d.connectionType) {
|
|
1348
1371
|
const badge = renderConnectionBadge(d.connectionType);
|
|
@@ -1358,10 +1381,13 @@ async function renderDiscoveredDevices(devices, options = {}) {
|
|
|
1358
1381
|
nameContainer.appendChild(renderSignalQualityBadge(d.rssi));
|
|
1359
1382
|
}
|
|
1360
1383
|
const details = document.createElement("div");
|
|
1361
|
-
details.style.fontSize = "
|
|
1384
|
+
details.style.fontSize = "10px";
|
|
1362
1385
|
details.style.opacity = "0.7";
|
|
1363
|
-
details.style.marginTop = "
|
|
1386
|
+
details.style.marginTop = "0";
|
|
1364
1387
|
details.style.fontFamily = "monospace";
|
|
1388
|
+
details.style.whiteSpace = "normal";
|
|
1389
|
+
details.style.overflowWrap = "anywhere";
|
|
1390
|
+
details.style.wordBreak = "break-word";
|
|
1365
1391
|
let detailsText = `ID: ${d.id} | Type: ${d.type} | Model: ${d.model || "N/A"}`;
|
|
1366
1392
|
if (d.hubDeviceId) {
|
|
1367
1393
|
detailsText += ` | Hub: ${d.hubDeviceId}`;
|
|
@@ -1374,9 +1400,10 @@ async function renderDiscoveredDevices(devices, options = {}) {
|
|
|
1374
1400
|
info.appendChild(details);
|
|
1375
1401
|
const addBtn = document.createElement("button");
|
|
1376
1402
|
addBtn.textContent = alreadyAdded ? "Already Added" : "Add to Config";
|
|
1377
|
-
addBtn.style.marginLeft = "
|
|
1378
|
-
addBtn.style.
|
|
1379
|
-
addBtn.style.
|
|
1403
|
+
addBtn.style.marginLeft = "0";
|
|
1404
|
+
addBtn.style.marginTop = "2px";
|
|
1405
|
+
addBtn.style.padding = "4px 9px";
|
|
1406
|
+
addBtn.style.fontSize = "11px";
|
|
1380
1407
|
addBtn.style.whiteSpace = "nowrap";
|
|
1381
1408
|
addBtn.style.flexShrink = "0";
|
|
1382
1409
|
addBtn.disabled = alreadyAdded;
|
|
@@ -1395,25 +1422,42 @@ async function renderDiscoveredDevices(devices, options = {}) {
|
|
|
1395
1422
|
const viewBtn = document.createElement("button");
|
|
1396
1423
|
viewBtn.textContent = "View in Config";
|
|
1397
1424
|
viewBtn.className = "secondary";
|
|
1398
|
-
viewBtn.style.marginLeft = "
|
|
1399
|
-
viewBtn.style.padding = "
|
|
1400
|
-
viewBtn.style.fontSize = "
|
|
1425
|
+
viewBtn.style.marginLeft = "0";
|
|
1426
|
+
viewBtn.style.padding = "4px 9px";
|
|
1427
|
+
viewBtn.style.fontSize = "11px";
|
|
1401
1428
|
viewBtn.onclick = async () => {
|
|
1402
1429
|
await loadConfiguredDevices2();
|
|
1403
1430
|
scrollToConfiguredDevice(d.id);
|
|
1404
1431
|
};
|
|
1405
1432
|
li.appendChild(info);
|
|
1406
|
-
const
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1433
|
+
const actions2 = document.createElement("div");
|
|
1434
|
+
actions2.className = "device-actions";
|
|
1435
|
+
actions2.style.display = "flex";
|
|
1436
|
+
actions2.style.alignItems = "center";
|
|
1437
|
+
actions2.style.flexWrap = "wrap";
|
|
1438
|
+
actions2.style.justifyContent = "flex-start";
|
|
1439
|
+
actions2.style.marginLeft = "0";
|
|
1440
|
+
actions2.style.width = "100%";
|
|
1441
|
+
actions2.style.marginTop = "2px";
|
|
1442
|
+
actions2.style.gap = "5px";
|
|
1443
|
+
actions2.appendChild(viewBtn);
|
|
1444
|
+
actions2.appendChild(addBtn);
|
|
1445
|
+
li.appendChild(actions2);
|
|
1412
1446
|
ul.appendChild(li);
|
|
1413
1447
|
continue;
|
|
1414
1448
|
}
|
|
1449
|
+
const actions = document.createElement("div");
|
|
1450
|
+
actions.className = "device-actions";
|
|
1451
|
+
actions.style.display = "flex";
|
|
1452
|
+
actions.style.flexWrap = "wrap";
|
|
1453
|
+
actions.style.justifyContent = "flex-start";
|
|
1454
|
+
actions.style.marginLeft = "0";
|
|
1455
|
+
actions.style.width = "100%";
|
|
1456
|
+
actions.style.marginTop = "2px";
|
|
1457
|
+
actions.style.gap = "5px";
|
|
1458
|
+
actions.appendChild(addBtn);
|
|
1415
1459
|
li.appendChild(info);
|
|
1416
|
-
li.appendChild(
|
|
1460
|
+
li.appendChild(actions);
|
|
1417
1461
|
ul.appendChild(li);
|
|
1418
1462
|
}
|
|
1419
1463
|
return ul;
|
|
@@ -1526,6 +1570,7 @@ function renderDeviceList(list) {
|
|
|
1526
1570
|
return;
|
|
1527
1571
|
}
|
|
1528
1572
|
status.textContent = `Found ${list.length} device(s)`;
|
|
1573
|
+
ul.classList.add("device-grid");
|
|
1529
1574
|
ul.innerHTML = "";
|
|
1530
1575
|
if (removeAllContainer) {
|
|
1531
1576
|
removeAllContainer.style.display = "block";
|
|
@@ -1534,21 +1579,32 @@ function renderDeviceList(list) {
|
|
|
1534
1579
|
const li = document.createElement("li");
|
|
1535
1580
|
li.className = "device-item";
|
|
1536
1581
|
li.setAttribute("data-device-id", normalizeId2(d.id));
|
|
1582
|
+
li.style.display = "flex";
|
|
1583
|
+
li.style.flexDirection = "column";
|
|
1584
|
+
li.style.alignItems = "stretch";
|
|
1585
|
+
li.style.marginBottom = "0";
|
|
1537
1586
|
const info = document.createElement("div");
|
|
1538
|
-
info.style.flex = "1";
|
|
1587
|
+
info.style.flex = "1 1 auto";
|
|
1588
|
+
info.style.width = "100%";
|
|
1589
|
+
info.style.minWidth = "0";
|
|
1539
1590
|
const nameContainer = document.createElement("div");
|
|
1540
1591
|
nameContainer.style.display = "flex";
|
|
1541
|
-
nameContainer.style.
|
|
1542
|
-
nameContainer.style.
|
|
1543
|
-
nameContainer.style.gap = "
|
|
1592
|
+
nameContainer.style.flexDirection = "column";
|
|
1593
|
+
nameContainer.style.alignItems = "flex-start";
|
|
1594
|
+
nameContainer.style.gap = "0";
|
|
1544
1595
|
const name = document.createElement("div");
|
|
1545
1596
|
name.style.fontWeight = "500";
|
|
1597
|
+
name.style.fontSize = "13px";
|
|
1546
1598
|
name.textContent = d.name || d.id;
|
|
1547
1599
|
const code = document.createElement("code");
|
|
1548
1600
|
code.textContent = d.id;
|
|
1549
|
-
code.style.fontSize = "
|
|
1601
|
+
code.style.fontSize = "10px";
|
|
1550
1602
|
code.style.opacity = "0.75";
|
|
1551
|
-
code.style.marginLeft = "
|
|
1603
|
+
code.style.marginLeft = "0";
|
|
1604
|
+
code.style.whiteSpace = "normal";
|
|
1605
|
+
code.style.overflowWrap = "anywhere";
|
|
1606
|
+
code.style.wordBreak = "break-word";
|
|
1607
|
+
code.style.maxWidth = "100%";
|
|
1552
1608
|
nameContainer.appendChild(name);
|
|
1553
1609
|
nameContainer.appendChild(code);
|
|
1554
1610
|
if (d.rssi !== void 0 && d.rssi !== null && d.rssi !== 0) {
|
|
@@ -1557,8 +1613,8 @@ function renderDeviceList(list) {
|
|
|
1557
1613
|
}
|
|
1558
1614
|
const meta = document.createElement("div");
|
|
1559
1615
|
meta.style.opacity = "0.75";
|
|
1560
|
-
meta.style.marginTop = "
|
|
1561
|
-
meta.style.fontSize = "
|
|
1616
|
+
meta.style.marginTop = "0";
|
|
1617
|
+
meta.style.fontSize = "11px";
|
|
1562
1618
|
const typeText = d.type ? `type: ${d.type}` : "";
|
|
1563
1619
|
const connText = d.connectionPreference ? `conn: ${d.connectionPreference}` : "";
|
|
1564
1620
|
const roomText = d.room ? `room: ${d.room}` : "";
|
|
@@ -1566,20 +1622,26 @@ function renderDeviceList(list) {
|
|
|
1566
1622
|
info.appendChild(nameContainer);
|
|
1567
1623
|
info.appendChild(meta);
|
|
1568
1624
|
const buttons = document.createElement("div");
|
|
1625
|
+
buttons.className = "device-actions";
|
|
1569
1626
|
buttons.style.display = "flex";
|
|
1570
|
-
buttons.style.
|
|
1627
|
+
buttons.style.flexWrap = "wrap";
|
|
1628
|
+
buttons.style.justifyContent = "flex-start";
|
|
1629
|
+
buttons.style.marginLeft = "0";
|
|
1630
|
+
buttons.style.width = "100%";
|
|
1631
|
+
buttons.style.marginTop = "2px";
|
|
1632
|
+
buttons.style.gap = "5px";
|
|
1571
1633
|
const editBtn = document.createElement("button");
|
|
1572
1634
|
editBtn.textContent = "\u270F\uFE0F Edit";
|
|
1573
|
-
editBtn.style.padding = "
|
|
1574
|
-
editBtn.style.fontSize = "
|
|
1635
|
+
editBtn.style.padding = "4px 9px";
|
|
1636
|
+
editBtn.style.fontSize = "11px";
|
|
1575
1637
|
editBtn.onclick = async () => {
|
|
1576
1638
|
const { editDevice: editDevice2 } = await Promise.resolve().then(() => (init_modals(), modals_exports));
|
|
1577
1639
|
await editDevice2(d);
|
|
1578
1640
|
};
|
|
1579
1641
|
const copyBtn = document.createElement("button");
|
|
1580
1642
|
copyBtn.textContent = "Copy ID";
|
|
1581
|
-
copyBtn.style.padding = "
|
|
1582
|
-
copyBtn.style.fontSize = "
|
|
1643
|
+
copyBtn.style.padding = "4px 9px";
|
|
1644
|
+
copyBtn.style.fontSize = "11px";
|
|
1583
1645
|
copyBtn.addEventListener("click", async () => {
|
|
1584
1646
|
try {
|
|
1585
1647
|
await navigator.clipboard.writeText(d.id);
|
|
@@ -1595,8 +1657,8 @@ function renderDeviceList(list) {
|
|
|
1595
1657
|
});
|
|
1596
1658
|
const deleteBtn = document.createElement("button");
|
|
1597
1659
|
deleteBtn.textContent = "\u{1F5D1}\uFE0F Delete";
|
|
1598
|
-
deleteBtn.style.padding = "
|
|
1599
|
-
deleteBtn.style.fontSize = "
|
|
1660
|
+
deleteBtn.style.padding = "4px 9px";
|
|
1661
|
+
deleteBtn.style.fontSize = "11px";
|
|
1600
1662
|
deleteBtn.style.background = "#ef4444";
|
|
1601
1663
|
deleteBtn.onclick = async () => {
|
|
1602
1664
|
const { deleteDeviceFromConfig: deleteDeviceFromConfig2 } = await Promise.resolve().then(() => (init_devices_delete(), devices_delete_exports));
|