Feat : Prio order for auto stream record
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { useMemo, useState, type FormEvent } from 'react';
|
||||
import type { AgentView, WatchTarget } from '@stream-control/shared';
|
||||
import type { AgentView, PreemptionVerdict, WatchTarget } from '@stream-control/shared';
|
||||
import { DEFAULT_PRIORITY, priorityLabel } from '@stream-control/shared';
|
||||
import { api } from '../api';
|
||||
import { formatDateTime, formatDuration, formatRelative } from '../format';
|
||||
import { recordingContext, stateLabel, type RecordingContext } from '../streamers';
|
||||
import { preemption, recordingContext, stateLabel, type RecordingContext } from '../streamers';
|
||||
import { StreamerDetail } from './StreamerDetail';
|
||||
|
||||
interface Props {
|
||||
@@ -49,9 +50,9 @@ export function StreamersPage({
|
||||
}
|
||||
|
||||
/**
|
||||
* En direct d'abord, puis show privé, puis le reste ; à statut égal, les
|
||||
* favoris devant. L'ordre du statut prime : un direct en cours appelle une
|
||||
* décision, un favori hors-ligne non.
|
||||
* En direct d'abord, puis show privé, puis le reste ; à statut égal les
|
||||
* favoris devant, puis la priorité. L'ordre du statut prime : un direct en
|
||||
* cours appelle une décision, un favori hors-ligne non.
|
||||
*/
|
||||
const ordered = useMemo(
|
||||
() =>
|
||||
@@ -61,6 +62,7 @@ export function StreamersPage({
|
||||
return (
|
||||
rank(a) - rank(b) ||
|
||||
Number(b.favorite) - Number(a.favorite) ||
|
||||
b.priority - a.priority ||
|
||||
a.username.localeCompare(b.username)
|
||||
);
|
||||
}),
|
||||
@@ -174,6 +176,7 @@ function StreamerCard({
|
||||
const state = stateLabel(target);
|
||||
const agent = agents.find((candidate) => candidate.id === target.agentId) ?? null;
|
||||
const context = recordingContext(target, agent, targets);
|
||||
const verdict = preemption(target, context);
|
||||
const isLive = target.state === 'public';
|
||||
|
||||
const liveFor = isLive && target.statusChangedAt ? Date.now() - target.statusChangedAt : null;
|
||||
@@ -293,17 +296,23 @@ function StreamerCard({
|
||||
) : (
|
||||
<button
|
||||
className="primary"
|
||||
disabled={busy || !agent?.online || !isLive || Boolean(context.busyWith)}
|
||||
title={recordTitle(target, agent, context)}
|
||||
disabled={busy || !agent?.online || !isLive || verdict?.allowed === false}
|
||||
title={recordTitle(target, agent, context, verdict)}
|
||||
onClick={() => void run(() => api.recordTarget(target.id), 'Enregistrement lancé')}
|
||||
>
|
||||
● Enregistrer
|
||||
{verdict?.allowed ? '● Enregistrer ⚡' : '● Enregistrer'}
|
||||
</button>
|
||||
)}
|
||||
|
||||
<div className="spacer" />
|
||||
|
||||
<span className="muted small">{agent ? agent.name : 'aucun agent'}</span>
|
||||
<span className="muted small">
|
||||
{agent ? agent.name : 'aucun agent'}
|
||||
{/* Le rang par défaut resterait du bruit : il ne dit rien de plus que
|
||||
l'absence de réglage. */}
|
||||
{target.priority !== DEFAULT_PRIORITY && ` · ${priorityLabel(target.priority)}`}
|
||||
{target.preempt && <span title="Peut interrompre une capture de rang inférieur"> ⚡</span>}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<footer className="card-foot muted small">
|
||||
@@ -326,12 +335,14 @@ function recordTitle(
|
||||
target: WatchTarget,
|
||||
agent: AgentView | null,
|
||||
context: RecordingContext,
|
||||
verdict: PreemptionVerdict | null,
|
||||
): string {
|
||||
if (!target.agentId) return 'Assigne un agent à ce streamer (clique la fiche)';
|
||||
if (!agent?.online) return 'Agent hors-ligne';
|
||||
if (context.busyWith) {
|
||||
return `${agent.name} enregistre déjà ${context.busyWith} — une VM ne traite qu'un flux à la fois`;
|
||||
if (verdict?.allowed) {
|
||||
return `Interrompt la capture de ${context.busyWith} sur ${agent.name} — priorité supérieure`;
|
||||
}
|
||||
if (verdict) return `${agent.name} déjà pris : ${verdict.reason}`;
|
||||
if (target.state !== 'public') return "Le streamer n'est pas en direct";
|
||||
return agent.browser.enabled
|
||||
? "Ouvrir la page, passer en plein écran et lancer l'enregistrement"
|
||||
|
||||
Reference in New Issue
Block a user