Remove per-card NFO action buttons; add bulk NFO refresh for selected

This commit is contained in:
2026-02-26 20:52:21 +01:00
parent e6d9f9f342
commit 624c0db16e
4 changed files with 75 additions and 49 deletions

View File

@@ -120,3 +120,8 @@ For each task completed:
## TODO List: ## TODO List:
--- ---
1. ~~remove gui action button for each card~~
~~<div class="series-actions"><button class="btn btn-sm btn-secondary nfo-view-btn" data-key="he-is-my-master" title="View NFO"><i class="fas fa-eye"></i> View NFO</button><button class="btn btn-sm btn-secondary nfo-refresh-btn" data-key="he-is-my-master" title="Refresh NFO"><i class="fas fa-sync-alt"></i> Refresh</button></div>~~
2. ~~add nfo refresh action for all selected cards~~
~~so a button right next to "Select All" that call update nfo for all selected items~~

View File

@@ -36,6 +36,11 @@ AniWorld.SelectionManager = (function() {
if (downloadBtn) { if (downloadBtn) {
downloadBtn.addEventListener('click', downloadSelected); downloadBtn.addEventListener('click', downloadSelected);
} }
const refreshNfoBtn = document.getElementById('refresh-nfo-selected');
if (refreshNfoBtn) {
refreshNfoBtn.addEventListener('click', refreshNFOForSelected);
}
} }
/** /**
@@ -90,6 +95,11 @@ AniWorld.SelectionManager = (function() {
downloadBtn.disabled = selectedSeries.size === 0; downloadBtn.disabled = selectedSeries.size === 0;
const refreshNfoBtn = document.getElementById('refresh-nfo-selected');
if (refreshNfoBtn) {
refreshNfoBtn.disabled = selectedSeries.size === 0;
}
const allSelectableSelected = selectableKeys.every(function(key) { const allSelectableSelected = selectableKeys.every(function(key) {
return selectedSeries.has(key); return selectedSeries.has(key);
}); });
@@ -274,6 +284,60 @@ AniWorld.SelectionManager = (function() {
} }
} }
/**
* Get selected series keys
* @returns {Array<string>}
*/
function getSelectedKeys() {
return Array.from(selectedSeries);
}
/**
* Refresh NFO metadata for all selected series
*/
async function refreshNFOForSelected() {
if (selectedSeries.size === 0) {
AniWorld.UI.showToast('No series selected', 'warning');
return;
}
if (!AniWorld.NFOManager) {
AniWorld.UI.showToast('NFO Manager not available', 'error');
return;
}
const keys = Array.from(selectedSeries);
let successCount = 0;
let failCount = 0;
AniWorld.UI.showLoading('Refreshing NFO for ' + keys.length + ' series...');
for (const key of keys) {
try {
await AniWorld.NFOManager.refreshNFO(key);
successCount++;
} catch (error) {
console.error('Error refreshing NFO for ' + key + ':', error);
failCount++;
}
}
AniWorld.UI.hideLoading();
if (failCount === 0) {
AniWorld.UI.showToast('NFO refreshed for ' + successCount + ' series', 'success');
} else {
AniWorld.UI.showToast(
'NFO refreshed for ' + successCount + ' series, ' + failCount + ' failed',
failCount === keys.length ? 'error' : 'warning'
);
}
if (successCount > 0 && AniWorld.SeriesManager) {
AniWorld.SeriesManager.loadSeries();
}
}
/** /**
* Get selected series count * Get selected series count
* @returns {number} * @returns {number}
@@ -291,6 +355,8 @@ AniWorld.SelectionManager = (function() {
toggleSelectAll: toggleSelectAll, toggleSelectAll: toggleSelectAll,
clearSelection: clearSelection, clearSelection: clearSelection,
downloadSelected: downloadSelected, downloadSelected: downloadSelected,
refreshNFOForSelected: refreshNFOForSelected,
getSelectedKeys: getSelectedKeys,
getSelectionCount: getSelectionCount getSelectionCount: getSelectionCount
}; };
})(); })();

View File

@@ -237,46 +237,6 @@ AniWorld.SeriesManager = (function() {
}); });
}); });
// Bind NFO button events
grid.querySelectorAll('.nfo-create-btn').forEach(function(btn) {
btn.addEventListener('click', function(e) {
e.stopPropagation();
const seriesKey = e.currentTarget.dataset.key;
if (AniWorld.NFOManager) {
AniWorld.NFOManager.createNFO(seriesKey).then(function() {
// Reload series to reflect new NFO status
loadSeries();
}).catch(function(error) {
console.error('Error creating NFO:', error);
});
}
});
});
grid.querySelectorAll('.nfo-view-btn').forEach(function(btn) {
btn.addEventListener('click', function(e) {
e.stopPropagation();
const seriesKey = e.currentTarget.dataset.key;
if (AniWorld.NFOManager) {
AniWorld.NFOManager.showNFOModal(seriesKey);
}
});
});
grid.querySelectorAll('.nfo-refresh-btn').forEach(function(btn) {
btn.addEventListener('click', function(e) {
e.stopPropagation();
const seriesKey = e.currentTarget.dataset.key;
if (AniWorld.NFOManager) {
AniWorld.NFOManager.refreshNFO(seriesKey).then(function() {
// Reload series to reflect updated NFO
loadSeries();
}).catch(function(error) {
console.error('Error refreshing NFO:', error);
});
}
});
});
} }
/** /**
@@ -376,15 +336,6 @@ AniWorld.SeriesManager = (function() {
'<span class="series-site">' + serie.site + '</span>' + '<span class="series-site">' + serie.site + '</span>' +
'</div>' + '</div>' +
(isLoading ? getLoadingIndicatorHTML(serie) : '') + (isLoading ? getLoadingIndicatorHTML(serie) : '') +
'<div class="series-actions">' +
(hasNfo ?
'<button class="btn btn-sm btn-secondary nfo-view-btn" data-key="' + serie.key + '" title="View NFO">' +
'<i class="fas fa-eye"></i> View NFO</button>' +
'<button class="btn btn-sm btn-secondary nfo-refresh-btn" data-key="' + serie.key + '" title="Refresh NFO">' +
'<i class="fas fa-sync-alt"></i> Refresh</button>' :
'<button class="btn btn-sm btn-primary nfo-create-btn" data-key="' + serie.key + '" title="Create NFO">' +
'<i class="fas fa-plus"></i> Create NFO</button>') +
'</div>' +
'</div>'; '</div>';
} }

View File

@@ -141,6 +141,10 @@
<i class="fas fa-check-double"></i> <i class="fas fa-check-double"></i>
<span data-text="select-all">Select All</span> <span data-text="select-all">Select All</span>
</button> </button>
<button id="refresh-nfo-selected" class="btn btn-secondary" disabled title="Refresh NFO for selected series">
<i class="fas fa-sync-alt"></i>
<span>Refresh NFO</span>
</button>
<button id="download-selected" class="btn btn-success" disabled> <button id="download-selected" class="btn btn-success" disabled>
<i class="fas fa-download"></i> <i class="fas fa-download"></i>
<span data-text="download-selected">Download Selected</span> <span data-text="download-selected">Download Selected</span>