'Hoster entfernen' already cancels active uploads AND removes jobs.
The separate 'doodstream.com abbrechen' etc. items were redundant
and confused users with two ways to do the same thing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
_completedUploadKeys tracked done uploads to prevent phantom preview
jobs when removeFromQueueOnDone auto-removes them. But when user
EXPLICITLY deleted a completed job from queue, the key remained —
silently blocking re-upload of the same file+hoster combination.
Now clears the completed key in removeJobFromIndex so deleted files
can be re-added. Safe with removeFromQueueOnDone because
syncSelectedFilesFromQueue runs before next buildQueuePreview.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
clearHistory() was the only configStore write call not awaited in its
IPC handler. The renderer received 'success' before the file write
completed — closing the app immediately after could leave history intact.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- hosters.js apiGet(): fixed regression from v2.3.8 where res.json()
consumed the body, making res.text() return empty on parse failure.
Now reads as text first, then parses JSON (matching VOE fix pattern).
- updater.js fetchJson(): same fix — read text first, parse JSON,
show actual server response in error message on failure.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- apiGet(): wrap res.json() in try-catch with descriptive error
message when server returns HTML instead of JSON
- URL-encode apiKey in upload server lookup URL template
(prevents broken URLs if key contains +, &, = chars)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously, both missing files (fs.statSync throws) and 0-byte files
produced the same error "Datei ist leer (0 Bytes)". Now:
- Missing files: "Datei nicht gefunden"
- Empty files: "Datei ist leer (0 Bytes)"
Also adds 3 edge case tests (throttle consume(0), unlimited rate,
semaphore release-without-acquire). All 66 tests passing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- throttle: consume(0) resolves immediately
- throttle: updateRate(0) makes consume instant (unlimited)
- semaphore: release without acquire clamps active to 0
All 66 tests passing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix 3 failing config-store tests: update expectations to match
multi-account array format (tests passed with old single-object format)
- backup-crypto: reject empty/null passwords on encrypt+decrypt
instead of producing weak keys silently
- updater: validate assetUrl and assetName before downloading
to prevent crash on incomplete update metadata
All 59 tests now passing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Consistent with all other user-data HTML attribute insertions
in the codebase that use escapeAttr().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- scaleParallelUploads used Math.max instead of Math.min, causing MORE
concurrent uploads instead of limiting them to the global count
- Settings debounce (350ms) was not flushed on app close — user changes
made right before closing were lost
- onRemoteClientCount IPC listener was re-registered on every
renderSettings() call, causing listener accumulation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 30-second timeout to health check wait loop in startUpload/
startSelectedUpload to prevent infinite spin if healthCheckRunning
gets stuck
- Clear _deletedJobIds Set when batch completes to prevent unbounded
memory growth over long sessions with many deletions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rebuild _jobIndexById after restoring queue from config on startup
(prevented progress updates from finding restored jobs)
- Show and focus mainWindow when files are dropped on floating
drop-target while window is minimized/hidden
- Escape status text in queue table HTML to prevent XSS from
unexpected status values
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Folder monitor: clear _seenFiles entry on file unlink so re-added
files (e.g. re-encoded) are detected again
- Sync IPC save (beforeunload): use atomic write pattern with backup
(.bak) creation, matching the async _atomicWrite behavior
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Critical: handleShutdownAfterFinish() captured shutdown mode in a
closure at scheduling time — changing mode during countdown was ignored,
causing unexpected system shutdown/restart/sleep.
Now reads shutdownMode at execution time, clears timer when mode
changes to 'nothing', clears orphaned timers before creating new ones,
and adds error handling on exec() calls.
Also: guard stats timer against double-start in upload-manager.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- batch-done handler: appendHistory failure no longer prevents the
upload-batch-done event from reaching the renderer (UI would get stuck)
- remote:input-event: validate x/y as finite numbers before passing
to sendInputEvent (prevents NaN/Infinity crash)
- VOE upload server: wrap JSON.parse in try-catch with clear error
message instead of raw stack trace
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Upload manager now rejects empty files (0 bytes) with clear error
message instead of sending useless uploads to the server
- Fix drag-drop zone highlight flickering caused by dragleave firing
on child elements (classic browser bug, fixed with enter/leave counter)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The error handler was missing clearTimeout for the auth timeout timer
and didn't clean up authenticated client state (signaling disconnect,
destroying capture window when last client drops).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Upload button no longer gets permanently stuck if startUpload()
throws after health check (try-catch with uploading=false reset)
- Wait for running health check instead of silently blocking upload
- Add abort signal check in VOE/Vidmoly upload generators
- Escape filenames with quotes/backslashes in multipart form headers
(all 4 uploaders: doodstream, voe, vidmoly, byse)
- Validate backup import structure before overwriting config
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Config write serialization via _writeQueue prevents concurrent
read-modify-write races between settings/queue/history saves
- Cancel active uploads on app quit (prevents zombie processes)
- Persist queue before update install (prevents queue loss)
- Sync IPC save in beforeunload (guarantees save before close)
- Fix double configStore.load() call
- Guard against status regression in handleProgress (done→uploading)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>