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": [
{
"modelKey": "sw33t_g1rl",
"url": "https://www.myfreecams.com/#sw33t_g1rl",
"modelKey": "jam_cream",
"url": "https://www.myfreecams.com/#jam_cream",
"mode": "probe_retry",
"nextProbeAtMs": 1775732773528,
"nextProbeAtMs": 1775738855792,
"currentShow": "offline",
"source": "watched"
},
{
"modelKey": "sunshinegirlx",
"url": "https://chaturbate.com/sunshinegirlx/",
"modelKey": "tashinadoncaster",
"url": "https://chaturbate.com/tashinadoncaster/",
"mode": "wait_public",
"currentShow": "private",
"imageUrl": "https://thumb.live.mmcdn.com/ri/sunshinegirlx.jpg",
"imageUrl": "https://thumb.live.mmcdn.com/ri/tashinadoncaster.jpg",
"source": "watched"
},
{
"modelKey": "yourhanna",
"url": "https://chaturbate.com/yourhanna/",
"modelKey": "_jesslei_",
"url": "https://chaturbate.com/_jesslei_/",
"mode": "wait_public",
"currentShow": "hidden",
"imageUrl": "https://thumb.live.mmcdn.com/ri/yourhanna.jpg",
"currentShow": "private",
"imageUrl": "https://thumb.live.mmcdn.com/ri/_jesslei_.jpg",
"source": "watched"
},
{
"modelKey": "nataliecroft",
"url": "https://chaturbate.com/nataliecroft/",
"modelKey": "mary_meys",
"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",
"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"
},
{
@ -41,42 +73,26 @@
"source": "watched"
},
{
"modelKey": "love_vibe",
"url": "https://chaturbate.com/love_vibe/",
"modelKey": "shirleendurrah",
"url": "https://chaturbate.com/shirleendurrah/",
"mode": "wait_public",
"currentShow": "private",
"imageUrl": "https://thumb.live.mmcdn.com/ri/love_vibe.jpg",
"imageUrl": "https://thumb.live.mmcdn.com/ri/shirleendurrah.jpg",
"source": "watched"
},
{
"modelKey": "georgiannahearn",
"url": "https://chaturbate.com/georgiannahearn/",
"mode": "wait_public",
"currentShow": "private",
"imageUrl": "https://thumb.live.mmcdn.com/ri/georgiannahearn.jpg",
"source": "watched"
},
{
"modelKey": "libbyshepard",
"url": "https://chaturbate.com/libbyshepard/",
"modelKey": "palmiratownzen",
"url": "https://chaturbate.com/palmiratownzen/",
"mode": "wait_public",
"currentShow": "away",
"imageUrl": "https://thumb.live.mmcdn.com/ri/libbyshepard.jpg",
"imageUrl": "https://thumb.live.mmcdn.com/ri/palmiratownzen.jpg",
"source": "watched"
},
{
"modelKey": "minions_",
"url": "https://chaturbate.com/minions_/",
"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/",
"modelKey": "rafaelaloghry",
"url": "https://chaturbate.com/rafaelaloghry/",
"mode": "probe_retry",
"nextProbeAtMs": 1775734021567,
"nextProbeAtMs": 1775738868799,
"currentShow": "unknown",
"source": "watched"
}

View File

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

View File

@ -3581,10 +3581,10 @@ export default function App() {
}
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 =
'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 (
<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="min-w-0 flex-1">
{/* Desktop */}
<div className="hidden sm:flex min-h-[48px] items-center">
<div className={`min-w-0 ${headerInfoPanelClass}`}>
<div className="flex min-w-0 flex-wrap items-center gap-2.5">
<div className="hidden sm:flex h-[47px] items-stretch">
<div className={`min-w-0 w-full ${headerInfoPanelClass}`}>
<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">
Recorder
</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
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
@ -280,7 +280,7 @@ export default function PerformanceMonitor({
return (
<div className={`${wrapperClass} ${className ?? ''}`}>
<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) => (
<div
key={item.key}

View File

@ -76,9 +76,8 @@ function regenerateTaskId(file: string) {
return `regenerate-assets:${file}`
}
function regenerateTaskTitle(file: string) {
const short = shortTaskFilename(file, 44)
return short ? `Assets neu generieren · ${short}` : 'Assets neu generieren'
function regenerateTaskTitle(_file: string) {
return 'Assets neu generieren'
}
function assetsPhaseLabel(label?: string, phase?: string) {
@ -334,10 +333,10 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) {
status = 'running'
} else if (state === 'done') {
status = 'done'
} else if (state === 'error') {
status = 'error'
} else if (cancelled) {
status = 'cancelled'
} else if (state === 'error') {
status = 'error'
}
const phases = Array.isArray(job?.phases) ? job.phases : []
@ -348,6 +347,18 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) {
const phaseLabel =
String(runningPhase?.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 =
status === 'running'
@ -361,6 +372,8 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) {
status,
title: regenerateTaskTitle(file),
text,
done: status === 'done' ? total : done,
total,
err: status === 'error' ? error || 'Fehler beim Regenerieren.' : undefined,
cancellable: status === 'running',
fading: false,
@ -750,7 +763,7 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) {
...t,
status: 'cancelled',
title: 'Assets generieren',
text: 'Abgebrochen.',
text: '',
err: undefined,
cancellable: false,
fading: false,
@ -931,7 +944,7 @@ export default function RecorderSettings({ onAssetsGenerated }: Props) {
...t,
status: 'cancelled',
title: 'Assets generieren',
text: 'Abgebrochen.',
text: '',
}))
fadeOutTask(setAssetsTask)
}}