bugfixes
This commit is contained in:
parent
de4bfe8cef
commit
973a07fef8
@ -18,13 +18,22 @@ var autostartPaused int32 // 0=false, 1=true
|
|||||||
var autostartSubsMu sync.Mutex
|
var autostartSubsMu sync.Mutex
|
||||||
|
|
||||||
type autostartStatePayload struct {
|
type autostartStatePayload struct {
|
||||||
Paused bool `json:"paused"`
|
Enabled bool `json:"enabled"`
|
||||||
PausedByUser bool `json:"pausedByUser"`
|
Active bool `json:"active"`
|
||||||
PausedByDisk bool `json:"pausedByDisk"`
|
Paused bool `json:"paused"`
|
||||||
|
PausedByUser bool `json:"pausedByUser"`
|
||||||
|
PausedByDisk bool `json:"pausedByDisk"`
|
||||||
|
Reason string `json:"reason,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var autostartSubs = map[chan autostartStatePayload]struct{}{}
|
var autostartSubs = map[chan autostartStatePayload]struct{}{}
|
||||||
|
|
||||||
|
func isAutostartFeatureEnabled() bool {
|
||||||
|
s := getSettings()
|
||||||
|
|
||||||
|
return s.UseChaturbateAPI || s.UseMyFreeCamsWatcher
|
||||||
|
}
|
||||||
|
|
||||||
func broadcastAutostartPaused() {
|
func broadcastAutostartPaused() {
|
||||||
state := getAutostartStatePayload()
|
state := getAutostartStatePayload()
|
||||||
|
|
||||||
@ -50,13 +59,28 @@ func isAutostartPaused() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getAutostartStatePayload() autostartStatePayload {
|
func getAutostartStatePayload() autostartStatePayload {
|
||||||
|
enabled := isAutostartFeatureEnabled()
|
||||||
userPaused := atomic.LoadInt32(&autostartPaused) == 1
|
userPaused := atomic.LoadInt32(&autostartPaused) == 1
|
||||||
diskPaused := atomic.LoadInt32(&diskEmergency) == 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{
|
return autostartStatePayload{
|
||||||
Paused: userPaused || diskPaused,
|
Enabled: enabled,
|
||||||
|
Active: enabled && !paused,
|
||||||
|
Paused: paused,
|
||||||
PausedByUser: userPaused,
|
PausedByUser: userPaused,
|
||||||
PausedByDisk: diskPaused,
|
PausedByDisk: diskPaused,
|
||||||
|
Reason: reason,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,19 +162,22 @@ func autostartStateHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
writeAutostartState(w)
|
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) {
|
func autostartPauseQuickHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
switch r.Method {
|
autostartPauseHandler(w, r)
|
||||||
case http.MethodGet:
|
}
|
||||||
writeAutostartState(w)
|
|
||||||
return
|
func resetAutostartPauseOnStartup() {
|
||||||
case http.MethodPost:
|
old := getAutostartStatePayload()
|
||||||
setAutostartPaused(true)
|
|
||||||
writeAutostartState(w)
|
atomic.StoreInt32(&autostartPaused, 0)
|
||||||
return
|
|
||||||
default:
|
newState := getAutostartStatePayload()
|
||||||
http.Error(w, "Nur GET/POST erlaubt", http.StatusMethodNotAllowed)
|
if old != newState {
|
||||||
return
|
broadcastAutostartPaused()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -98,6 +98,11 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer appLn.Close()
|
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()
|
fixKeepRootFilesIntoModelSubdirs()
|
||||||
|
|
||||||
postWorkQ.StartWorkers(1)
|
postWorkQ.StartWorkers(1)
|
||||||
@ -137,10 +142,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hintergrund-Worker
|
// Hintergrund-Worker
|
||||||
|
go startDiskSpaceGuard()
|
||||||
go startChaturbateOnlinePoller(store)
|
go startChaturbateOnlinePoller(store)
|
||||||
go startChaturbateAutoStartWorker(store)
|
go startChaturbateAutoStartWorker(store)
|
||||||
go startMyFreeCamsAutoStartWorker(store)
|
go startMyFreeCamsAutoStartWorker(store)
|
||||||
go startDiskSpaceGuard()
|
|
||||||
|
|
||||||
// optional: Bootstrap nur im Hintergrund
|
// optional: Bootstrap nur im Hintergrund
|
||||||
if getSettings().UseChaturbateAPI {
|
if getSettings().UseChaturbateAPI {
|
||||||
|
|||||||
@ -642,7 +642,7 @@ function TrainingBeakerIcon(props: React.ComponentProps<typeof BeakerIcon>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
|
|
||||||
const [trainingTabRunning, setTrainingTabRunning] = useState(false)
|
const [trainingTabRunning, setTrainingTabRunning] = useState(false)
|
||||||
const [splitProgressByFile, setSplitProgressByFile] = useState<Record<string, BackgroundSplitProgress>>({})
|
const [splitProgressByFile, setSplitProgressByFile] = useState<Record<string, BackgroundSplitProgress>>({})
|
||||||
const splitProgressClearTimersRef = useRef<Record<string, number>>({})
|
const splitProgressClearTimersRef = useRef<Record<string, number>>({})
|
||||||
@ -2196,9 +2196,6 @@ export default function App() {
|
|||||||
prev?.id === updated.id ? mergeStoredModel(prev, updated) : prev
|
prev?.id === updated.id ? mergeStoredModel(prev, updated) : prev
|
||||||
)
|
)
|
||||||
|
|
||||||
setPlayerModel((prev) =>
|
|
||||||
prev?.id === updated.id ? mergeStoredModel(prev, updated) : prev
|
|
||||||
)
|
|
||||||
scheduleOverviewLoad()
|
scheduleOverviewLoad()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -3255,7 +3252,6 @@ export default function App() {
|
|||||||
fillDonePageFromPrefetch,
|
fillDonePageFromPrefetch,
|
||||||
donePage,
|
donePage,
|
||||||
prefetchDonePage,
|
prefetchDonePage,
|
||||||
doneCount,
|
|
||||||
loadDoneCount,
|
loadDoneCount,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@ -4009,7 +4005,11 @@ export default function App() {
|
|||||||
doneTotal={doneCount}
|
doneTotal={doneCount}
|
||||||
page={donePage}
|
page={donePage}
|
||||||
pageSize={donePageSize}
|
pageSize={donePageSize}
|
||||||
onPageSizeChange={setDonePageSize}
|
onPageSizeChange={(size) => {
|
||||||
|
setDonePageSize(size)
|
||||||
|
setDonePage(1)
|
||||||
|
donePrefetchRef.current = null
|
||||||
|
}}
|
||||||
onPageChange={setDonePage}
|
onPageChange={setDonePage}
|
||||||
onOpenPlayer={openPlayer}
|
onOpenPlayer={openPlayer}
|
||||||
onDeleteJob={handleDeleteJobWithUndo}
|
onDeleteJob={handleDeleteJobWithUndo}
|
||||||
|
|||||||
@ -18,6 +18,7 @@ type RecorderSettings = {
|
|||||||
doneDir: string
|
doneDir: string
|
||||||
ffmpegPath?: string
|
ffmpegPath?: string
|
||||||
autoAddToDownloadList?: boolean
|
autoAddToDownloadList?: boolean
|
||||||
|
autoStartAddedDownloads?: boolean
|
||||||
enableConcurrentDownloadsLimit?: boolean
|
enableConcurrentDownloadsLimit?: boolean
|
||||||
maxConcurrentDownloads?: number
|
maxConcurrentDownloads?: number
|
||||||
useChaturbateApi?: boolean
|
useChaturbateApi?: boolean
|
||||||
@ -58,6 +59,7 @@ const DEFAULTS: RecorderSettings = {
|
|||||||
doneDir: 'records/done',
|
doneDir: 'records/done',
|
||||||
ffmpegPath: '',
|
ffmpegPath: '',
|
||||||
autoAddToDownloadList: true,
|
autoAddToDownloadList: true,
|
||||||
|
autoStartAddedDownloads: true,
|
||||||
enableConcurrentDownloadsLimit: false,
|
enableConcurrentDownloadsLimit: false,
|
||||||
maxConcurrentDownloads: 20,
|
maxConcurrentDownloads: 20,
|
||||||
useChaturbateApi: false,
|
useChaturbateApi: false,
|
||||||
@ -396,6 +398,8 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) {
|
|||||||
|
|
||||||
// ✅ falls backend die Felder noch nicht hat -> defaults nutzen
|
// ✅ falls backend die Felder noch nicht hat -> defaults nutzen
|
||||||
autoAddToDownloadList: data.autoAddToDownloadList ?? DEFAULTS.autoAddToDownloadList,
|
autoAddToDownloadList: data.autoAddToDownloadList ?? DEFAULTS.autoAddToDownloadList,
|
||||||
|
autoStartAddedDownloads:
|
||||||
|
(data as any).autoStartAddedDownloads ?? DEFAULTS.autoStartAddedDownloads,
|
||||||
enableConcurrentDownloadsLimit:
|
enableConcurrentDownloadsLimit:
|
||||||
(data as any).enableConcurrentDownloadsLimit ?? DEFAULTS.enableConcurrentDownloadsLimit,
|
(data as any).enableConcurrentDownloadsLimit ?? DEFAULTS.enableConcurrentDownloadsLimit,
|
||||||
maxConcurrentDownloads:
|
maxConcurrentDownloads:
|
||||||
@ -690,6 +694,7 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) {
|
|||||||
|
|
||||||
// ✅ Switch-Logik: Autostart nur sinnvoll, wenn Auto-Add aktiv ist
|
// ✅ Switch-Logik: Autostart nur sinnvoll, wenn Auto-Add aktiv ist
|
||||||
const autoAddToDownloadList = !!value.autoAddToDownloadList
|
const autoAddToDownloadList = !!value.autoAddToDownloadList
|
||||||
|
const autoStartAddedDownloads = !!value.autoStartAddedDownloads
|
||||||
const enableConcurrentDownloadsLimit = !!(value as any).enableConcurrentDownloadsLimit
|
const enableConcurrentDownloadsLimit = !!(value as any).enableConcurrentDownloadsLimit
|
||||||
const maxConcurrentDownloads = Math.max(
|
const maxConcurrentDownloads = Math.max(
|
||||||
1,
|
1,
|
||||||
@ -736,6 +741,7 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) {
|
|||||||
doneDir,
|
doneDir,
|
||||||
ffmpegPath,
|
ffmpegPath,
|
||||||
autoAddToDownloadList,
|
autoAddToDownloadList,
|
||||||
|
autoStartAddedDownloads,
|
||||||
enableConcurrentDownloadsLimit,
|
enableConcurrentDownloadsLimit,
|
||||||
maxConcurrentDownloads,
|
maxConcurrentDownloads,
|
||||||
useChaturbateApi,
|
useChaturbateApi,
|
||||||
@ -1284,6 +1290,19 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) {
|
|||||||
description="Neue Links/Modelle werden automatisch in die Downloadliste übernommen."
|
description="Neue Links/Modelle werden automatisch in die Downloadliste übernommen."
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<LabeledSwitch
|
||||||
|
checked={!!value.autoStartAddedDownloads}
|
||||||
|
onChange={(checked) =>
|
||||||
|
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."
|
||||||
|
/>
|
||||||
|
|
||||||
<LabeledSwitch
|
<LabeledSwitch
|
||||||
checked={!!value.useChaturbateApi}
|
checked={!!value.useChaturbateApi}
|
||||||
onChange={(checked) => setValue((v) => ({ ...v, useChaturbateApi: checked }))}
|
onChange={(checked) => setValue((v) => ({ ...v, useChaturbateApi: checked }))}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user