refactor: use TelemetryReadout and EntityCard components

Both were built and tested but never wired in — SeancePage.tsx was
reimplementing the same markup inline. Removes the duplication.
This commit is contained in:
Indiana
2026-07-21 03:45:11 +00:00
parent 0756e677b9
commit f0ee7dbdab
3 changed files with 129 additions and 192 deletions

View File

@@ -22,6 +22,8 @@ import { PlanchetteBoard } from '../components/PlanchetteBoard'
import { MatrixView } from '../components/MatrixView'
import { GraphView } from '../components/GraphView'
import { Transcript } from '../components/Transcript'
import { EntityCard } from '../components/EntityCard'
import { TelemetryReadout } from '../components/TelemetryReadout'
import { PlanchetteMachine } from '../lib/planchette'
import type { PlanchetteSnapshot } from '../lib/planchette'
import { EvpListener } from '../lib/evp'
@@ -335,90 +337,12 @@ function SeanceSession({ username }: { username: string }) {
</section>
<aside className="seance-side">
{entity ? (
<section className={`spirit-dossier ${dossierOpen ? 'open' : 'closed'}`}>
<button
type="button"
className="dossier-header"
onClick={() => setDossierOpen((o) => !o)}
aria-expanded={dossierOpen}
>
<span className="dossier-title">{t('seance.entity.title')}</span>
<span className="dossier-chevron" aria-hidden>
{dossierOpen ? '▾' : '◂'}
</span>
</button>
{dossierOpen && (
<div className="dossier-body">
<h3 className="dossier-name" style={{ color: `hsl(${entity.visual.hue} 85% 78%)` }}>
{entity.name}
</h3>
<p className="dossier-epithet">{entity.epithet}</p>
<div className="dossier-badges">
<span className={`rarity-badge rarity-${entity.rarity}`}>
{t(`seance.entity.rarity.${entity.rarity}`)}
</span>
{state.entityIsNew ? (
<span className="dossier-badge badge-new">{t('seance.entity.isNew')}</span>
) : (
<span className="dossier-badge badge-known">
{t('seance.entity.known', { count: entity.contact_count })}
</span>
)}
</div>
<div className="dossier-section">
<h4>{t('seance.entity.persona')}</h4>
<p className="dossier-persona">{entity.persona}</p>
</div>
<div className="dossier-section">
<h4>{t('seance.entity.voice')}</h4>
<dl className="voice-params">
<div>
<dt>id</dt>
<dd>{entity.voice.voice_id}</dd>
</div>
<div>
<dt>pitch</dt>
<dd>{entity.voice.pitch.toFixed(2)}</dd>
</div>
<div>
<dt>rate</dt>
<dd>{entity.voice.rate.toFixed(2)}</dd>
</div>
<div>
<dt>noise</dt>
<dd>{entity.voice.noise.toFixed(2)}</dd>
</div>
<div>
<dt>echo</dt>
<dd>{entity.voice.echo.toFixed(2)}</dd>
</div>
</dl>
</div>
{entity.quotes.length > 0 && (
<div className="dossier-section">
<h4>{t('seance.entity.quotes')}</h4>
<ul className="dossier-quotes">
{entity.quotes.slice(0, 4).map((q, i) => (
<li key={i}>“{q}”</li>
))}
</ul>
</div>
)}
</div>
)}
</section>
) : (
<section className="spirit-dossier empty">
<div className="dossier-body">
<p className="dossier-none">{t('seance.entity.none')}</p>
<p className="dossier-nonehint dim">{t('seance.entity.noneHint')}</p>
</div>
</section>
)}
<EntityCard
entity={entity}
isNew={state.entityIsNew}
open={dossierOpen}
onToggleOpen={() => setDossierOpen((o) => !o)}
/>
<section className="mode-panel">
{state.mode === 'wire' && <WirePanel />}
@@ -519,41 +443,10 @@ function ToastCard({ toast, onDismiss }: { toast: Toast; onDismiss: (id: number)
function WirePanel() {
const { state } = useSeance()
const { t } = useTranslation()
const tel = state.telemetry
return (
<div className="wire-panel">
<h4 className="panel-title">{t('seance.telemetry.title')}</h4>
{tel ? (
<div className="telemetry-grid">
<div className="tel-row">
<span className="tel-key">{t('seance.telemetry.jitter')}</span>
<span className="tel-val flicker-soft">
{tel.jitter_bytes_per_s.toFixed(1)} {t('seance.telemetry.units.bytes')}
</span>
</div>
<div className="tel-row">
<span className="tel-key">{t('seance.telemetry.latencyVar')}</span>
<span className="tel-val flicker-soft">
{tel.latency_variance_ms.toFixed(2)} {t('seance.telemetry.units.ms')}
</span>
</div>
<div className="tel-row">
<span className="tel-key">{t('seance.telemetry.latencyMean')}</span>
<span className="tel-val flicker-soft">
{tel.latency_mean_ms.toFixed(1)} {t('seance.telemetry.units.ms')}
</span>
</div>
<div className="tel-row">
<span className="tel-key">{t('seance.telemetry.dns')}</span>
<span className="tel-val flicker-soft">
{tel.dns_ms.toFixed(1)} {t('seance.telemetry.units.ms')}
</span>
</div>
</div>
) : (
<p className="dim flicker">{t('common.loading')}</p>
)}
<TelemetryReadout telemetry={state.telemetry} />
<p className="wire-count">{t('seance.anomaly.count', { count: state.anomalyCount })}</p>
{!state.passive && (
<p className="wire-hint dim">