diff --git a/src/MediaManager.html b/src/MediaManager.html index 9c35ba0..dbe3940 100644 --- a/src/MediaManager.html +++ b/src/MediaManager.html @@ -36,14 +36,14 @@ box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1); border-radius: 12px; padding: 16px; - margin-bottom: 16px; + margin-bottom: 8px; } .header { display: flex; align-items: center; justify-content: space-between; - margin-bottom: 16px; + margin-bottom: 8px; } h2 { @@ -295,7 +295,7 @@ background: var(--surface); padding: 16px; border-top: 1px solid var(--border); - margin: 0 -16px -16px -16px; + margin: 0 -16px 0 -16px; border-bottom-left-radius: 12px; border-bottom-right-radius: 12px; display: flex; @@ -385,7 +385,7 @@ background: var(--surface); color: var(--text); border-radius: 8px; - margin-top: 16px; + margin-top: 8px; font-family: monospace; font-size: 11px; overflow: hidden; @@ -784,44 +784,50 @@ this.checkDirty(); }; - MediaState.prototype.toggleSelection = function (id) { - var item = this.items.find(function (i) { return i.id === id; }); - if (!item) return; + MediaState.prototype.toggleSelection = function (id) { + var item = this.items.find(function (i) { return i.id === id; }); + if (!item) return; - var isSelected = this.selectedIds.has(id); + var isSelected = this.selectedIds.has(id); + var affectedIds = [id]; - if (isSelected) { - this.selectedIds.delete(id); - } else { - // Enforce one-pair rule: Max one Drive, one Shopify - var isDrive = (item.source === 'drive_only'); - var isShopify = (item.source === 'shopify_only'); + if (isSelected) { + this.selectedIds.delete(id); + } else { + // Enforce one-pair rule: Max one Drive, one Shopify + var isDrive = (item.source === 'drive_only'); + var isShopify = (item.source === 'shopify_only'); - if (isDrive) { - // Clear other Drive selections - var _this = this; - this.items.forEach(function (i) { - if (i.source === 'drive_only' && _this.selectedIds.has(i.id)) { - _this.selectedIds.delete(i.id); + if (isDrive) { + // Clear other Drive selections + var _this = this; + this.items.forEach(function (i) { + if (i.source === 'drive_only' && _this.selectedIds.has(i.id) && i.id !== id) { + _this.selectedIds.delete(i.id); + affectedIds.push(i.id); + } + }); + } else if (isShopify) { + // Clear other Shopify selections + var _this = this; + this.items.forEach(function (i) { + if (i.source === 'shopify_only' && _this.selectedIds.has(i.id) && i.id !== id) { + _this.selectedIds.delete(i.id); + affectedIds.push(i.id); + } + }); } - }); - } else if (isShopify) { - // Clear other Shopify selections - var _this = this; - this.items.forEach(function (i) { - if (i.source === 'shopify_only' && _this.selectedIds.has(i.id)) { - _this.selectedIds.delete(i.id); - } - }); - } - this.selectedIds.add(id); - } - ui.render(this.items); - }; + this.selectedIds.add(id); + } + + // Targeted updates + affectedIds.forEach(function (aid) { ui.updateCardState(aid); }); + }; MediaState.prototype.clearSelection = function () { + var affectedIds = Array.from(this.selectedIds); this.selectedIds.clear(); - ui.render(this.items); + affectedIds.forEach(function (aid) { ui.updateCardState(aid); }); }; MediaState.prototype.addItem = function (item) { @@ -830,14 +836,20 @@ this.checkDirty(); }; - MediaState.prototype.deleteItem = function (index) { - var item = this.items[index]; + MediaState.prototype.deleteItem = function (id) { + var item = this.items.find(function (i) { return i.id === id; }); + if (!item) { + console.warn("[MediaState] Item not found for deletion:", id); + return; + } if (item.source === 'new') { - this.items.splice(index, 1); + var index = this.items.indexOf(item); + if (index !== -1) this.items.splice(index, 1); + ui.render(this.items); // Full render only for actual removal } else { item._deleted = !item._deleted; + ui.updateCardState(id); // Targeted update for toggle } - ui.render(this.items); this.checkDirty(); }; @@ -1210,12 +1222,12 @@ // Link selection button var linkSelectionBtn = ''; if (!item._deleted && (item.source === 'drive_only' || item.source === 'shopify_only')) { - linkSelectionBtn = ''; + linkSelectionBtn = ''; } var actionBtn = item._deleted - ? '' - : ''; + ? '' + : ''; div.innerHTML += badge + @@ -1278,6 +1290,84 @@ return div; }; + UI.prototype.updateCardState = function (id) { + var item = state.items.find(function (i) { return i.id === id; }); + var el = this.grid.querySelector('[data-id="' + id + '"]'); + if (!item || !el) return; + + var isSelected = state.selectedIds.has(item.id); + + // 1. Update Container Class + el.className = 'media-item ' + (item._deleted ? 'deleted-item' : '') + (isSelected ? ' selected' : ''); + if (item.isProcessing) el.className += ' processing-card'; + + // 2. Update Badge + var badgeEl = el.querySelector('.badge'); + if (badgeEl) { + if (!item._deleted) { + if (item.source === 'synced') { + badgeEl.innerText = 'Synced'; + badgeEl.title = 'Synced'; + badgeEl.style.background = '#dcfce7'; + badgeEl.style.color = '#166534'; + } else if (item.source === 'drive_only') { + badgeEl.innerText = 'Drive'; + badgeEl.title = 'Drive Only'; + badgeEl.style.background = '#dbeafe'; + badgeEl.style.color = '#1e40af'; + } else if (item.source === 'shopify_only') { + badgeEl.innerText = 'Shopify'; + badgeEl.title = 'Shopify Only'; + badgeEl.style.background = '#fce7f3'; + badgeEl.style.color = '#9d174d'; + } + } else { + badgeEl.innerText = 'Deleted'; + badgeEl.title = ''; + badgeEl.style.background = '#fee2e2'; + badgeEl.style.color = '#991b1b'; + } + } + + // 3. Update Overlay Buttons + var overlay = el.querySelector('.media-overlay'); + if (overlay) { + // Remove existing link button if it exists + var oldLinkBtn = el.querySelector('#link-btn-' + id); + if (oldLinkBtn) oldLinkBtn.remove(); + + // Add link button back if NOT deleted + if (!item._deleted && (item.source === 'drive_only' || item.source === 'shopify_only')) { + var linkHtml = ''; + var viewBtn = overlay.querySelector('.btn-view'); + if (viewBtn) { + viewBtn.insertAdjacentHTML('afterend', linkHtml); + } else { + overlay.insertAdjacentHTML('afterbegin', linkHtml); + } + } + + // Update Delete/Restore button + var actionBtn = overlay.querySelector('.btn-delete') || overlay.querySelector('[title="Restore"]'); + if (actionBtn) { + if (item._deleted) { + actionBtn.className = 'icon-btn'; + actionBtn.innerHTML = 'â†Šī¸'; + actionBtn.title = 'Restore'; + } else { + actionBtn.className = 'icon-btn btn-delete'; + actionBtn.innerHTML = 'đŸ—‘ī¸'; + actionBtn.title = 'Delete'; + } + } + } + + // 4. Update global item count + var activeCount = state.items.filter(function (i) { return !i._deleted; }).length; + var countEl = document.getElementById('item-count'); + if (countEl) countEl.innerText = '(' + activeCount + ')'; + }; + UI.prototype.openPreview = function (id) { var item = state.items.find(function (i) { return i.id === id; }); if (!item) return; @@ -1446,11 +1536,12 @@ if (media) { ui.logStatus('fetch', 'Fetched full media state.', 'success'); const normalized = media.map(function (i) { + var source = i.source || (i.shopifyId && i.driveId ? 'synced' : (i.shopifyId ? 'shopify_only' : 'drive_only')); return { ...i, id: i.id || Math.random().toString(36).substr(2, 9), - status: i.source || 'drive_only', - source: i.source, + status: source, + source: source, _deleted: false }; });