@tomorrowos/sdk 0.7.2 → 0.7.4
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomorrowos/sdk",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4",
|
|
4
4
|
"description": "TomorrowOS CMS server SDK - WebSocket transport, pairing, device commands, optional static CMS UI. Includes CLI (tomorrowos init / build) and starter templates.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-cms",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4",
|
|
4
4
|
"description": "CMS server on @tomorrowos/sdk. Add your UI (React, static files, etc.) alongside this server.",
|
|
5
5
|
"private": true,
|
|
6
6
|
"type": "module",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"build-player": "tomorrowos build --platform tizen"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@tomorrowos/sdk": "^0.7.
|
|
13
|
+
"@tomorrowos/sdk": "^0.7.4",
|
|
14
14
|
"dotenv": "^17.2.3"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
@@ -103,6 +103,7 @@
|
|
|
103
103
|
<h2>Assets</h2>
|
|
104
104
|
<button type="button" class="primary" id="addAssetBtn" title="Add image or video">+</button>
|
|
105
105
|
</div>
|
|
106
|
+
<p class="hint playlist-assets-hint">Drag ⋮⋮ to reorder assets. Save playlist to keep the new order.</p>
|
|
106
107
|
<input
|
|
107
108
|
type="file"
|
|
108
109
|
id="fileInput"
|
|
@@ -15,6 +15,9 @@ let playlistDraftActive = false;
|
|
|
15
15
|
/** @type {{ id: string, assetId?: string, url: string, name: string, type: string, durationMs: number }[]} */
|
|
16
16
|
let editorItems = [];
|
|
17
17
|
|
|
18
|
+
/** Item id currently being dragged in the asset list (reorder). */
|
|
19
|
+
let draggingEditorItemId = null;
|
|
20
|
+
|
|
18
21
|
/** @type {string|null} */
|
|
19
22
|
let publishModalDeviceId = null;
|
|
20
23
|
let publishInProgress = false;
|
|
@@ -670,9 +673,75 @@ function loadEditorFromSelection() {
|
|
|
670
673
|
updatePlaylistEditorVisibility();
|
|
671
674
|
}
|
|
672
675
|
|
|
676
|
+
function clearPlaylistItemDropTargets() {
|
|
677
|
+
document
|
|
678
|
+
.querySelectorAll(".playlist-item--drop-target, .playlist-item--dragging")
|
|
679
|
+
.forEach((el) => {
|
|
680
|
+
el.classList.remove("playlist-item--drop-target", "playlist-item--dragging");
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
function reorderEditorItems(fromId, toId) {
|
|
685
|
+
const fromIdx = editorItems.findIndex((x) => x.id === fromId);
|
|
686
|
+
const toIdx = editorItems.findIndex((x) => x.id === toId);
|
|
687
|
+
if (fromIdx < 0 || toIdx < 0 || fromIdx === toIdx) return;
|
|
688
|
+
const [moved] = editorItems.splice(fromIdx, 1);
|
|
689
|
+
editorItems.splice(toIdx, 0, moved);
|
|
690
|
+
renderEditorAssets();
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
function attachPlaylistItemDragDrop(li, item) {
|
|
694
|
+
li.dataset.itemId = item.id;
|
|
695
|
+
|
|
696
|
+
const handle = document.createElement("button");
|
|
697
|
+
handle.type = "button";
|
|
698
|
+
handle.className = "playlist-item-drag-handle";
|
|
699
|
+
handle.setAttribute("aria-label", "Drag to reorder");
|
|
700
|
+
handle.title = "Drag to reorder";
|
|
701
|
+
handle.textContent = "⋮⋮";
|
|
702
|
+
handle.draggable = true;
|
|
703
|
+
|
|
704
|
+
handle.addEventListener("dragstart", (e) => {
|
|
705
|
+
e.dataTransfer.setData("text/plain", item.id);
|
|
706
|
+
e.dataTransfer.effectAllowed = "move";
|
|
707
|
+
draggingEditorItemId = item.id;
|
|
708
|
+
li.classList.add("playlist-item--dragging");
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
handle.addEventListener("dragend", () => {
|
|
712
|
+
draggingEditorItemId = null;
|
|
713
|
+
clearPlaylistItemDropTargets();
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
li.addEventListener("dragover", (e) => {
|
|
717
|
+
e.preventDefault();
|
|
718
|
+
e.dataTransfer.dropEffect = "move";
|
|
719
|
+
if (draggingEditorItemId && draggingEditorItemId !== item.id) {
|
|
720
|
+
li.classList.add("playlist-item--drop-target");
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
li.addEventListener("dragleave", (e) => {
|
|
725
|
+
if (!li.contains(e.relatedTarget)) {
|
|
726
|
+
li.classList.remove("playlist-item--drop-target");
|
|
727
|
+
}
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
li.addEventListener("drop", (e) => {
|
|
731
|
+
e.preventDefault();
|
|
732
|
+
li.classList.remove("playlist-item--drop-target");
|
|
733
|
+
const fromId = e.dataTransfer.getData("text/plain") || draggingEditorItemId;
|
|
734
|
+
if (!fromId || fromId === item.id) return;
|
|
735
|
+
reorderEditorItems(fromId, item.id);
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
li.insertBefore(handle, li.firstChild);
|
|
739
|
+
}
|
|
740
|
+
|
|
673
741
|
function renderEditorAssets() {
|
|
674
742
|
const list = document.getElementById("playlistList");
|
|
675
743
|
const empty = document.getElementById("playlistEmpty");
|
|
744
|
+
draggingEditorItemId = null;
|
|
676
745
|
list.querySelectorAll(".playlist-item").forEach((el) => el.remove());
|
|
677
746
|
|
|
678
747
|
if (!isPlaylistEditorOpen()) {
|
|
@@ -696,6 +765,7 @@ function renderEditorAssets() {
|
|
|
696
765
|
if (item.type === "image" || item.type === "video") {
|
|
697
766
|
const thumb = document.createElement(item.type === "video" ? "video" : "img");
|
|
698
767
|
thumb.className = "playlist-item-thumb";
|
|
768
|
+
thumb.draggable = false;
|
|
699
769
|
try {
|
|
700
770
|
thumb.src = absoluteMediaUrl(item.url);
|
|
701
771
|
} catch {
|
|
@@ -752,6 +822,7 @@ function renderEditorAssets() {
|
|
|
752
822
|
li.appendChild(name);
|
|
753
823
|
li.appendChild(meta);
|
|
754
824
|
li.appendChild(actions);
|
|
825
|
+
attachPlaylistItemDragDrop(li, item);
|
|
755
826
|
list.appendChild(li);
|
|
756
827
|
}
|
|
757
828
|
}
|
|
@@ -120,7 +120,7 @@ body {
|
|
|
120
120
|
|
|
121
121
|
.devices-grid {
|
|
122
122
|
display: grid;
|
|
123
|
-
grid-template-columns: repeat(auto-fill, minmax(
|
|
123
|
+
grid-template-columns: repeat(auto-fill, minmax(308px, 1fr));
|
|
124
124
|
gap: 0.85rem;
|
|
125
125
|
}
|
|
126
126
|
|
|
@@ -214,14 +214,16 @@ body {
|
|
|
214
214
|
|
|
215
215
|
.device-meta-top {
|
|
216
216
|
display: grid;
|
|
217
|
-
grid-template-columns: minmax(0, 1fr)
|
|
218
|
-
gap: 0.
|
|
219
|
-
align-items:
|
|
217
|
+
grid-template-columns: minmax(0, 1fr) 6.5rem;
|
|
218
|
+
gap: 0.5rem;
|
|
219
|
+
align-items: start;
|
|
220
220
|
margin-bottom: 0.35rem;
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
.device-meta--primary {
|
|
224
224
|
min-width: 0;
|
|
225
|
+
font-size: 0.77rem;
|
|
226
|
+
gap: 0.32rem;
|
|
225
227
|
}
|
|
226
228
|
|
|
227
229
|
.device-meta--secondary {
|
|
@@ -229,11 +231,11 @@ body {
|
|
|
229
231
|
}
|
|
230
232
|
|
|
231
233
|
.device-screenshot-slot {
|
|
232
|
-
width:
|
|
233
|
-
|
|
234
|
+
width: 6.5rem;
|
|
235
|
+
aspect-ratio: 13 / 9;
|
|
234
236
|
flex-shrink: 0;
|
|
235
237
|
border: 1px solid transparent;
|
|
236
|
-
border-radius:
|
|
238
|
+
border-radius: 4px;
|
|
237
239
|
background: #fafaf9;
|
|
238
240
|
overflow: hidden;
|
|
239
241
|
}
|
|
@@ -242,7 +244,6 @@ body {
|
|
|
242
244
|
display: block;
|
|
243
245
|
width: 100%;
|
|
244
246
|
height: 100%;
|
|
245
|
-
min-height: 4.85rem;
|
|
246
247
|
padding: 0;
|
|
247
248
|
border: 0;
|
|
248
249
|
background: transparent;
|
|
@@ -253,7 +254,6 @@ body {
|
|
|
253
254
|
display: block;
|
|
254
255
|
width: 100%;
|
|
255
256
|
height: 100%;
|
|
256
|
-
min-height: 4.85rem;
|
|
257
257
|
object-fit: cover;
|
|
258
258
|
object-position: center;
|
|
259
259
|
}
|
|
@@ -429,12 +429,52 @@ button.danger {
|
|
|
429
429
|
font-size: 0.875rem;
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
+
.playlist-assets-hint {
|
|
433
|
+
margin: 0 0 0.75rem;
|
|
434
|
+
font-size: 0.78rem;
|
|
435
|
+
}
|
|
436
|
+
|
|
432
437
|
.playlist-item {
|
|
433
438
|
border: 1px solid #e4e1dc;
|
|
434
439
|
border-radius: 8px;
|
|
435
440
|
padding: 0.65rem;
|
|
436
441
|
margin-bottom: 0.5rem;
|
|
437
442
|
background: #fafaf9;
|
|
443
|
+
position: relative;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.playlist-item--dragging {
|
|
447
|
+
opacity: 0.55;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
.playlist-item--drop-target {
|
|
451
|
+
border-color: #ff8a3d;
|
|
452
|
+
box-shadow: 0 0 0 2px rgba(255, 138, 61, 0.25);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.playlist-item-drag-handle {
|
|
456
|
+
display: block;
|
|
457
|
+
width: 100%;
|
|
458
|
+
margin: 0 0 0.45rem;
|
|
459
|
+
padding: 0.2rem 0;
|
|
460
|
+
border: 0;
|
|
461
|
+
border-radius: 4px;
|
|
462
|
+
background: transparent;
|
|
463
|
+
color: #888;
|
|
464
|
+
font-size: 0.95rem;
|
|
465
|
+
line-height: 1;
|
|
466
|
+
letter-spacing: 0.08em;
|
|
467
|
+
cursor: grab;
|
|
468
|
+
touch-action: none;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.playlist-item-drag-handle:active {
|
|
472
|
+
cursor: grabbing;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
.playlist-item-drag-handle:hover {
|
|
476
|
+
color: #444;
|
|
477
|
+
background: #f0eeea;
|
|
438
478
|
}
|
|
439
479
|
|
|
440
480
|
.playlist-item-thumb {
|