This commit is contained in:
Linrador 2026-04-09 14:53:16 +02:00
parent ebd7c84a24
commit d4f2f90b08
5 changed files with 81 additions and 55 deletions

View File

@ -1,35 +1,67 @@
{ {
"items": [ "items": [
{ {
"modelKey": "sw33t_g1rl", "modelKey": "jam_cream",
"url": "https://www.myfreecams.com/#sw33t_g1rl", "url": "https://www.myfreecams.com/#jam_cream",
"mode": "probe_retry", "mode": "probe_retry",
"nextProbeAtMs": 1775732773528, "nextProbeAtMs": 1775738855792,
"currentShow": "offline", "currentShow": "offline",
"source": "watched" "source": "watched"
}, },
{ {
"modelKey": "sunshinegirlx", "modelKey": "tashinadoncaster",
"url": "https://chaturbate.com/sunshinegirlx/", "url": "https://chaturbate.com/tashinadoncaster/",
"mode": "wait_public", "mode": "wait_public",
"currentShow": "private", "currentShow": "private",
"imageUrl": "https://thumb.live.mmcdn.com/ri/sunshinegirlx.jpg", "imageUrl": "https://thumb.live.mmcdn.com/ri/tashinadoncaster.jpg",
"source": "watched" "source": "watched"
}, },
{ {
"modelKey": "yourhanna", "modelKey": "_jesslei_",
"url": "https://chaturbate.com/yourhanna/", "url": "https://chaturbate.com/_jesslei_/",
"mode": "wait_public", "mode": "wait_public",
"currentShow": "hidden", "currentShow": "private",
"imageUrl": "https://thumb.live.mmcdn.com/ri/yourhanna.jpg", "imageUrl": "https://thumb.live.mmcdn.com/ri/_jesslei_.jpg",
"source": "watched" "source": "watched"
}, },
{ {
"modelKey": "nataliecroft", "modelKey": "mary_meys",
"url": "https://chaturbate.com/nataliecroft/", "url": "https://chaturbate.com/mary_meys/",
"mode": "wait_public",
"currentShow": "private",
"imageUrl": "https://thumb.live.mmcdn.com/ri/mary_meys.jpg",
"source": "watched"
},
{
"modelKey": "jodeesolarz",
"url": "https://chaturbate.com/jodeesolarz/",
"mode": "wait_public",
"currentShow": "away",
"imageUrl": "https://thumb.live.mmcdn.com/ri/jodeesolarz.jpg",
"source": "watched"
},
{
"modelKey": "di_n_alex",
"url": "https://chaturbate.com/di_n_alex/",
"mode": "wait_public",
"currentShow": "private",
"imageUrl": "https://thumb.live.mmcdn.com/ri/di_n_alex.jpg",
"source": "watched"
},
{
"modelKey": "lora_lifelover",
"url": "https://chaturbate.com/lora_lifelover/",
"mode": "wait_public", "mode": "wait_public",
"currentShow": "hidden", "currentShow": "hidden",
"imageUrl": "https://thumb.live.mmcdn.com/ri/nataliecroft.jpg", "imageUrl": "https://thumb.live.mmcdn.com/ri/lora_lifelover.jpg",
"source": "watched"
},
{
"modelKey": "chaesoffel",
"url": "https://chaturbate.com/chaesoffel/",
"mode": "wait_public",
"currentShow": "hidden",
"imageUrl": "https://thumb.live.mmcdn.com/ri/chaesoffel.jpg",
"source": "watched" "source": "watched"
}, },
{ {
@ -41,42 +73,26 @@
"source": "watched" "source": "watched"
}, },
{ {
"modelKey": "love_vibe", "modelKey": "shirleendurrah",
"url": "https://chaturbate.com/love_vibe/", "url": "https://chaturbate.com/shirleendurrah/",
"mode": "wait_public", "mode": "wait_public",
"currentShow": "private", "currentShow": "private",
"imageUrl": "https://thumb.live.mmcdn.com/ri/love_vibe.jpg", "imageUrl": "https://thumb.live.mmcdn.com/ri/shirleendurrah.jpg",
"source": "watched" "source": "watched"
}, },
{ {
"modelKey": "georgiannahearn", "modelKey": "palmiratownzen",
"url": "https://chaturbate.com/georgiannahearn/", "url": "https://chaturbate.com/palmiratownzen/",
"mode": "wait_public",
"currentShow": "private",
"imageUrl": "https://thumb.live.mmcdn.com/ri/georgiannahearn.jpg",
"source": "watched"
},
{
"modelKey": "libbyshepard",
"url": "https://chaturbate.com/libbyshepard/",
"mode": "wait_public", "mode": "wait_public",
"currentShow": "away", "currentShow": "away",
"imageUrl": "https://thumb.live.mmcdn.com/ri/libbyshepard.jpg", "imageUrl": "https://thumb.live.mmcdn.com/ri/palmiratownzen.jpg",
"source": "watched" "source": "watched"
}, },
{ {
"modelKey": "minions_", "modelKey": "rafaelaloghry",
"url": "https://chaturbate.com/minions_/", "url": "https://chaturbate.com/rafaelaloghry/",
"mode": "wait_public",
"currentShow": "hidden",
"imageUrl": "https://thumb.live.mmcdn.com/ri/minions_.jpg",
"source": "watched"
},
{
"modelKey": "amanda_sayhey",
"url": "https://chaturbate.com/amanda_sayhey/",
"mode": "probe_retry", "mode": "probe_retry",
"nextProbeAtMs": 1775734021567, "nextProbeAtMs": 1775738868799,
"currentShow": "unknown", "currentShow": "unknown",
"source": "watched" "source": "watched"
} }

View File

@ -1,3 +0,0 @@
{
"items": []
}

View File

@ -3581,10 +3581,10 @@ export default function App() {
} }
const headerInfoPanelClass = const headerInfoPanelClass =
'rounded-lg border border-gray-200/70 bg-white/45 px-2.5 py-1.5 shadow-sm backdrop-blur dark:border-white/10 dark:bg-white/5 sm:rounded-xl sm:px-3 sm:py-2' 'rounded-lg border border-gray-200/70 bg-white/45 px-2.5 py-1.5 shadow-sm backdrop-blur dark:border-white/10 dark:bg-white/5 sm:flex sm:h-[47px] sm:items-center sm:rounded-xl sm:px-3 sm:py-0'
const headerStatBadgeClass = const headerStatBadgeClass =
'inline-flex h-7 items-center gap-1 rounded-full border border-gray-200/70 bg-white/70 px-2 text-[10px] font-semibold text-gray-900 shadow-sm backdrop-blur dark:border-white/10 dark:bg-white/10 dark:text-gray-100 sm:h-8 sm:gap-1.5 sm:px-2.5 sm:text-[11px]' 'inline-flex h-6 items-center gap-1 rounded-full border border-gray-200/70 bg-white/70 px-2 text-[10px] font-semibold text-gray-900 shadow-sm backdrop-blur dark:border-white/10 dark:bg-white/10 dark:text-gray-100 sm:h-7 sm:gap-1.5 sm:px-2.5 sm:text-[11px]'
return ( return (
<div className="min-h-[100dvh] bg-gray-50 text-gray-900 dark:bg-gray-950 dark:text-gray-100"> <div className="min-h-[100dvh] bg-gray-50 text-gray-900 dark:bg-gray-950 dark:text-gray-100">
@ -3599,9 +3599,9 @@ export default function App() {
<div className="flex items-center justify-between gap-3 sm:gap-4"> <div className="flex items-center justify-between gap-3 sm:gap-4">
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
{/* Desktop */} {/* Desktop */}
<div className="hidden sm:flex min-h-[48px] items-center"> <div className="hidden sm:flex h-[47px] items-stretch">
<div className={`min-w-0 ${headerInfoPanelClass}`}> <div className={`min-w-0 w-full ${headerInfoPanelClass}`}>
<div className="flex min-w-0 flex-wrap items-center gap-2.5"> <div className="flex min-w-0 w-full items-center gap-2.5">
<h1 className="shrink-0 text-lg font-semibold tracking-tight text-gray-900 dark:text-white"> <h1 className="shrink-0 text-lg font-semibold tracking-tight text-gray-900 dark:text-white">
Recorder Recorder
</h1> </h1>

View File

@ -232,7 +232,7 @@ export default function PerformanceMonitor({
? ` ? `
w-full min-w-0 rounded-lg border border-gray-200/70 bg-white/70 px-1.5 py-1 shadow-sm backdrop-blur w-full min-w-0 rounded-lg border border-gray-200/70 bg-white/70 px-1.5 py-1 shadow-sm backdrop-blur
dark:border-white/10 dark:bg-white/5 dark:border-white/10 dark:bg-white/5
sm:rounded-xl sm:px-2 sm:py-1.5 sm:flex sm:h-[47px] sm:items-center sm:rounded-xl sm:px-2 sm:py-0
` `
: ` : `
rounded-lg border border-gray-200/70 bg-white/70 px-2.5 py-1.5 shadow-sm backdrop-blur rounded-lg border border-gray-200/70 bg-white/70 px-2.5 py-1.5 shadow-sm backdrop-blur
@ -280,7 +280,7 @@ export default function PerformanceMonitor({
return ( return (
<div className={`${wrapperClass} ${className ?? ''}`}> <div className={`${wrapperClass} ${className ?? ''}`}>
<div className={panelClass}> <div className={panelClass}>
<div className="grid grid-cols-2 gap-1 md:grid-cols-4"> <div className="grid grid-cols-2 gap-1 md:grid-cols-4 sm:h-full sm:w-full sm:items-center">
{metrics.map((item) => ( {metrics.map((item) => (
<div <div
key={item.key} key={item.key}

View File

@ -76,9 +76,8 @@ function regenerateTaskId(file: string) {
return `regenerate-assets:${file}` return `regenerate-assets:${file}`
} }
function regenerateTaskTitle(file: string) { function regenerateTaskTitle(_file: string) {
const short = shortTaskFilename(file, 44) return 'Assets neu generieren'
return short ? `Assets neu generieren · ${short}` : 'Assets neu generieren'
} }
function assetsPhaseLabel(label?: string, phase?: string) { function assetsPhaseLabel(label?: string, phase?: string) {
@ -334,10 +333,10 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) {
status = 'running' status = 'running'
} else if (state === 'done') { } else if (state === 'done') {
status = 'done' status = 'done'
} else if (state === 'error') {
status = 'error'
} else if (cancelled) { } else if (cancelled) {
status = 'cancelled' status = 'cancelled'
} else if (state === 'error') {
status = 'error'
} }
const phases = Array.isArray(job?.phases) ? job.phases : [] const phases = Array.isArray(job?.phases) ? job.phases : []
@ -349,6 +348,18 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) {
String(runningPhase?.label || '').trim() || String(runningPhase?.label || '').trim() ||
String(queuedPhase?.label || '').trim() String(queuedPhase?.label || '').trim()
const relevantPhases = phases.filter((p: any) => {
const q = String(p?.queue || '').toLowerCase()
const ph = String(p?.phase || '').toLowerCase()
return (
(q === 'postwork' && ['meta', 'thumb', 'teaser', 'sprites'].includes(ph)) ||
(q === 'enrich' && ph === 'analyze')
)
})
const total = relevantPhases.length || 5
const done = relevantPhases.filter((p: any) => String(p?.state || '').toLowerCase() === 'done').length
const text = const text =
status === 'running' status === 'running'
? phaseLabel ? phaseLabel
@ -361,6 +372,8 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) {
status, status,
title: regenerateTaskTitle(file), title: regenerateTaskTitle(file),
text, text,
done: status === 'done' ? total : done,
total,
err: status === 'error' ? error || 'Fehler beim Regenerieren.' : undefined, err: status === 'error' ? error || 'Fehler beim Regenerieren.' : undefined,
cancellable: status === 'running', cancellable: status === 'running',
fading: false, fading: false,
@ -750,7 +763,7 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) {
...t, ...t,
status: 'cancelled', status: 'cancelled',
title: 'Assets generieren', title: 'Assets generieren',
text: 'Abgebrochen.', text: '',
err: undefined, err: undefined,
cancellable: false, cancellable: false,
fading: false, fading: false,
@ -931,7 +944,7 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) {
...t, ...t,
status: 'cancelled', status: 'cancelled',
title: 'Assets generieren', title: 'Assets generieren',
text: 'Abgebrochen.', text: '',
})) }))
fadeOutTask(setAssetsTask) fadeOutTask(setAssetsTask)
}} }}