feat: add account enable/disable toggle

- Toggle button on each account card to activate/deactivate hosters
- Disabled accounts are greyed out and excluded from upload selection
- Credentials are preserved when deactivated

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Administrator 2026-03-12 04:17:46 +01:00
parent 0851bb09fc
commit 052bd940f1
3 changed files with 31 additions and 7 deletions

View File

@ -1,6 +1,6 @@
{
"name": "multi-hoster-uploader",
"version": "1.9.7",
"version": "1.9.8",
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
"main": "main.js",
"scripts": {

View File

@ -144,7 +144,7 @@ function getAvailableHosters() {
const hoster = config.hosters[name] || {};
return { name, hoster, hasCreds: hosterHasCredentials(name, hoster) };
})
.filter(item => item.hasCreds);
.filter(item => item.hasCreds && item.hoster.enabled !== false);
}
function syncSelectedUploadHosters() {
@ -2148,23 +2148,27 @@ function renderAccounts() {
}
container.innerHTML = accounts.map(({ name, hoster }) => {
const isDisabled = hoster.enabled === false;
const st = accountStatuses[name] || { status: 'unchecked', message: '' };
const statusLabels = { ok: 'Bereit', warn: 'Warnung', checking: 'Prüfe...', error: 'Fehler', unchecked: 'Nicht geprüft' };
const statusLabel = statusLabels[st.status] || 'Nicht geprüft';
const statusLabel = isDisabled ? 'Deaktiviert' : (statusLabels[st.status] || 'Nicht geprüft');
const statusClass = isDisabled ? 'disabled' : st.status;
const credLabel = getCredentialLabel(name, hoster);
const toggleLabel = isDisabled ? 'Aktivieren' : 'Deaktivieren';
return `
<div class="account-card" data-account="${name}">
<div class="account-card${isDisabled ? ' account-disabled' : ''}" data-account="${name}">
<div class="account-card-info">
<div class="account-card-title">${escapeHtml(getAccountDisplayName(name, hoster))}</div>
<div class="account-card-subtitle" title="${escapeAttr(credLabel)}">${escapeHtml(credLabel)}${st.message ? `${escapeHtml(st.message)}` : ''}</div>
<div class="account-card-subtitle" title="${escapeAttr(credLabel)}">${escapeHtml(credLabel)}${st.message && !isDisabled ? `${escapeHtml(st.message)}` : ''}</div>
</div>
<span class="account-status status-${st.status}">
<span class="account-status status-${statusClass}">
<span class="account-status-dot"></span>
${statusLabel}
</span>
<div class="account-card-actions">
<button class="btn btn-xs btn-secondary" data-account-check="${name}">Prüfen</button>
<button class="btn btn-xs btn-secondary" data-account-toggle="${name}">${toggleLabel}</button>
<button class="btn btn-xs btn-secondary" data-account-check="${name}" ${isDisabled ? 'disabled' : ''}>Prüfen</button>
<button class="btn btn-xs btn-secondary" data-account-edit="${name}">Bearbeiten</button>
<button class="btn btn-xs btn-danger" data-account-delete="${name}">Löschen</button>
</div>
@ -2172,6 +2176,9 @@ function renderAccounts() {
}).join('');
// Wire up buttons
container.querySelectorAll('[data-account-toggle]').forEach(btn => {
btn.addEventListener('click', () => toggleAccount(btn.dataset.accountToggle));
});
container.querySelectorAll('[data-account-edit]').forEach(btn => {
btn.addEventListener('click', () => openAccountModal(btn.dataset.accountEdit));
});
@ -2183,6 +2190,20 @@ function renderAccounts() {
});
}
async function toggleAccount(hosterName) {
const hosters = { ...config.hosters };
const hoster = { ...hosters[hosterName] };
hoster.enabled = hoster.enabled === false ? true : false;
hosters[hosterName] = hoster;
await window.api.saveConfig({ hosters });
config = await window.api.getConfig();
syncSelectedUploadHosters();
renderAccounts();
renderHosterSummary();
renderHosterModal();
renderSettings();
}
async function checkSingleAccount(hosterName) {
if (!hosterName || healthCheckRunning) return;
healthCheckRunning = true;

View File

@ -785,6 +785,9 @@ body {
.account-status.status-error { background: rgba(231, 76, 60, 0.2); color: var(--danger); }
.account-status.status-warn { background: rgba(240, 195, 108, 0.2); color: var(--warning); }
.account-status.status-unchecked { background: rgba(255, 255, 255, 0.05); color: var(--text-dim); }
.account-status.status-disabled { background: rgba(255, 255, 255, 0.05); color: var(--text-muted); }
.account-card.account-disabled { opacity: 0.5; }
.account-card.account-disabled:hover { opacity: 0.7; }
.account-status-dot {
width: 7px;