From 973a07fef8565f2e153f712892858ce6a5659b43 Mon Sep 17 00:00:00 2001 From: Linrador <68631622+Linrador@users.noreply.github.com> Date: Sat, 2 May 2026 11:02:45 +0200 Subject: [PATCH] bugfixes --- backend/autostart_pause.go | 59 ++++++++++++++----- backend/server.go | 7 ++- frontend/src/App.tsx | 12 ++-- .../src/components/ui/RecorderSettings.tsx | 19 ++++++ 4 files changed, 74 insertions(+), 23 deletions(-) diff --git a/backend/autostart_pause.go b/backend/autostart_pause.go index 9ab3fed..1edea5f 100644 --- a/backend/autostart_pause.go +++ b/backend/autostart_pause.go @@ -18,13 +18,22 @@ var autostartPaused int32 // 0=false, 1=true var autostartSubsMu sync.Mutex type autostartStatePayload struct { - Paused bool `json:"paused"` - PausedByUser bool `json:"pausedByUser"` - PausedByDisk bool `json:"pausedByDisk"` + Enabled bool `json:"enabled"` + Active bool `json:"active"` + Paused bool `json:"paused"` + PausedByUser bool `json:"pausedByUser"` + PausedByDisk bool `json:"pausedByDisk"` + Reason string `json:"reason,omitempty"` } var autostartSubs = map[chan autostartStatePayload]struct{}{} +func isAutostartFeatureEnabled() bool { + s := getSettings() + + return s.UseChaturbateAPI || s.UseMyFreeCamsWatcher +} + func broadcastAutostartPaused() { state := getAutostartStatePayload() @@ -50,13 +59,28 @@ func isAutostartPaused() bool { } func getAutostartStatePayload() autostartStatePayload { + enabled := isAutostartFeatureEnabled() userPaused := atomic.LoadInt32(&autostartPaused) == 1 diskPaused := atomic.LoadInt32(&diskEmergency) == 1 + paused := userPaused || diskPaused + + reason := "" + switch { + case !enabled: + reason = "disabled" + case diskPaused: + reason = "disk" + case userPaused: + reason = "user" + } return autostartStatePayload{ - Paused: userPaused || diskPaused, + Enabled: enabled, + Active: enabled && !paused, + Paused: paused, PausedByUser: userPaused, PausedByDisk: diskPaused, + Reason: reason, } } @@ -138,19 +162,22 @@ func autostartStateHandler(w http.ResponseWriter, r *http.Request) { writeAutostartState(w) } -// GET/POST /api/autostart/pause (POST ohne Body pausiert) +// GET/POST /api/autostart/pause +// POST muss explizit paused=true/false enthalten. +// Wichtig: Kein "POST ohne Body pausiert" mehr, weil das beim Frontend-Refresh +// unbemerkt den Autostart stoppen kann. func autostartPauseQuickHandler(w http.ResponseWriter, r *http.Request) { - switch r.Method { - case http.MethodGet: - writeAutostartState(w) - return - case http.MethodPost: - setAutostartPaused(true) - writeAutostartState(w) - return - default: - http.Error(w, "Nur GET/POST erlaubt", http.StatusMethodNotAllowed) - return + autostartPauseHandler(w, r) +} + +func resetAutostartPauseOnStartup() { + old := getAutostartStatePayload() + + atomic.StoreInt32(&autostartPaused, 0) + + newState := getAutostartStatePayload() + if old != newState { + broadcastAutostartPaused() } } diff --git a/backend/server.go b/backend/server.go index ecf5098..372b234 100644 --- a/backend/server.go +++ b/backend/server.go @@ -98,6 +98,11 @@ func main() { } defer appLn.Close() + // ✅ Hier: alte manuelle Autostart-Pause beim echten App-Start zurücksetzen. + // Disk-Notbremse bleibt trotzdem aktiv, weil isAutostartPaused() + // zusätzlich diskEmergency prüft. + resetAutostartPauseOnStartup() + fixKeepRootFilesIntoModelSubdirs() postWorkQ.StartWorkers(1) @@ -137,10 +142,10 @@ func main() { } // Hintergrund-Worker + go startDiskSpaceGuard() go startChaturbateOnlinePoller(store) go startChaturbateAutoStartWorker(store) go startMyFreeCamsAutoStartWorker(store) - go startDiskSpaceGuard() // optional: Bootstrap nur im Hintergrund if getSettings().UseChaturbateAPI { diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index a937e60..ff962d3 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -642,7 +642,7 @@ function TrainingBeakerIcon(props: React.ComponentProps) { } export default function App() { - + const [trainingTabRunning, setTrainingTabRunning] = useState(false) const [splitProgressByFile, setSplitProgressByFile] = useState>({}) const splitProgressClearTimersRef = useRef>({}) @@ -2196,9 +2196,6 @@ export default function App() { prev?.id === updated.id ? mergeStoredModel(prev, updated) : prev ) - setPlayerModel((prev) => - prev?.id === updated.id ? mergeStoredModel(prev, updated) : prev - ) scheduleOverviewLoad() return } @@ -3255,7 +3252,6 @@ export default function App() { fillDonePageFromPrefetch, donePage, prefetchDonePage, - doneCount, loadDoneCount, ] ) @@ -4009,7 +4005,11 @@ export default function App() { doneTotal={doneCount} page={donePage} pageSize={donePageSize} - onPageSizeChange={setDonePageSize} + onPageSizeChange={(size) => { + setDonePageSize(size) + setDonePage(1) + donePrefetchRef.current = null + }} onPageChange={setDonePage} onOpenPlayer={openPlayer} onDeleteJob={handleDeleteJobWithUndo} diff --git a/frontend/src/components/ui/RecorderSettings.tsx b/frontend/src/components/ui/RecorderSettings.tsx index 38c1f7e..8131044 100644 --- a/frontend/src/components/ui/RecorderSettings.tsx +++ b/frontend/src/components/ui/RecorderSettings.tsx @@ -18,6 +18,7 @@ type RecorderSettings = { doneDir: string ffmpegPath?: string autoAddToDownloadList?: boolean + autoStartAddedDownloads?: boolean enableConcurrentDownloadsLimit?: boolean maxConcurrentDownloads?: number useChaturbateApi?: boolean @@ -58,6 +59,7 @@ const DEFAULTS: RecorderSettings = { doneDir: 'records/done', ffmpegPath: '', autoAddToDownloadList: true, + autoStartAddedDownloads: true, enableConcurrentDownloadsLimit: false, maxConcurrentDownloads: 20, useChaturbateApi: false, @@ -396,6 +398,8 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) { // ✅ falls backend die Felder noch nicht hat -> defaults nutzen autoAddToDownloadList: data.autoAddToDownloadList ?? DEFAULTS.autoAddToDownloadList, + autoStartAddedDownloads: + (data as any).autoStartAddedDownloads ?? DEFAULTS.autoStartAddedDownloads, enableConcurrentDownloadsLimit: (data as any).enableConcurrentDownloadsLimit ?? DEFAULTS.enableConcurrentDownloadsLimit, maxConcurrentDownloads: @@ -690,6 +694,7 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) { // ✅ Switch-Logik: Autostart nur sinnvoll, wenn Auto-Add aktiv ist const autoAddToDownloadList = !!value.autoAddToDownloadList + const autoStartAddedDownloads = !!value.autoStartAddedDownloads const enableConcurrentDownloadsLimit = !!(value as any).enableConcurrentDownloadsLimit const maxConcurrentDownloads = Math.max( 1, @@ -736,6 +741,7 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) { doneDir, ffmpegPath, autoAddToDownloadList, + autoStartAddedDownloads, enableConcurrentDownloadsLimit, maxConcurrentDownloads, useChaturbateApi, @@ -1284,6 +1290,19 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) { description="Neue Links/Modelle werden automatisch in die Downloadliste übernommen." /> + + setValue((v) => ({ + ...v, + autoStartAddedDownloads: checked, + autoAddToDownloadList: checked ? true : v.autoAddToDownloadList, + })) + } + label="Automatisch starten" + description="Neue Links aus der Zwischenablage werden automatisch gestartet. Aktiviert automatisch auch das Hinzufügen zur Downloadliste." + /> + setValue((v) => ({ ...v, useChaturbateApi: checked }))}