feat(ui): visually de-emphasise off-topic Trump posts in the feed

Follow-up to fe88acb. Noise posts (not crypto-relevant, never AI-scored) now
read as 'skip me' at a glance in the list — no need to open them:

- sentiment chip → muted 'off-topic · not crypto' tag (was a colored chip)
- post text → dimmer (ink-4) + shorter preview (90 vs 180 chars)
- aside → single muted 'SKIPPED' tag instead of HOLD pill + empty AI metric

Scored posts (real crypto signals) are visually unchanged — full signal pill,
target chip, impact, and AI confidence.

tsc + build clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
k
2026-05-30 03:19:31 +08:00
parent fe88acb5a0
commit 3f35a3fba2
+68 -33
View File
@@ -129,47 +129,82 @@ const PostRow = memo(function PostRow({ post, selected, onClick }: PostRowProps)
<span>·</span> <span>·</span>
<TimeAgo iso={post.published_at} suffix=" ago" /> <TimeAgo iso={post.published_at} suffix=" ago" />
<span>·</span> <span>·</span>
<span className={`chip ${post.sentiment === 'bullish' ? 'up' : post.sentiment === 'bearish' ? 'down' : 'neutral'}`} style={{ padding: '2px 8px', fontSize: 11 }}> {aiScored ? (
{post.sentiment} <span className={`chip ${post.sentiment === 'bullish' ? 'up' : post.sentiment === 'bearish' ? 'down' : 'neutral'}`} style={{ padding: '2px 8px', fontSize: 11 }}>
</span> {post.sentiment}
</span>
) : (
<span style={{
padding: '2px 8px', fontSize: 11, fontWeight: 600,
borderRadius: 4, color: 'var(--ink-4)',
background: 'var(--bg-sunk)', border: '1px solid var(--line)',
letterSpacing: '0.02em',
}}>
off-topic · not crypto
</span>
)}
</div> </div>
<p className="text" style={expanded ? { display: 'block', overflow: 'visible', WebkitLineClamp: 'unset' } : {}}> <p
{expanded ? post.text : (post.text.slice(0, 180) + (post.text.length > 180 ? '…' : ''))} className="text"
style={{
...(expanded ? { display: 'block', overflow: 'visible', WebkitLineClamp: 'unset' } : {}),
// Noise posts are de-emphasised: dimmer text + shorter preview so
// the reader can skip them at a glance without opening.
...(aiScored ? {} : { color: 'var(--ink-4)' }),
}}
>
{expanded
? post.text
: (post.text.slice(0, aiScored ? 180 : 90) + (post.text.length > (aiScored ? 180 : 90) ? '…' : ''))}
</p> </p>
</div> </div>
<div className="post-aside"> <div className="post-aside">
<SignalPill signal={post.signal} /> {aiScored ? (
{/* Target asset chip for actionable signals */} <>
{post.target_asset && (post.signal === 'buy' || post.signal === 'short') && ( <SignalPill signal={post.signal} />
{/* Target asset chip for actionable signals */}
{post.target_asset && (post.signal === 'buy' || post.signal === 'short') && (
<span style={{
fontSize: 10, fontWeight: 700, fontFamily: 'var(--mono)',
padding: '2px 6px', borderRadius: 4,
background: post.signal === 'buy' ? 'rgba(34,197,94,0.12)' : 'rgba(239,68,68,0.12)',
color: post.signal === 'buy' ? '#22c55e' : '#ef4444',
letterSpacing: '0.04em',
}}>
{post.target_asset}
{post.expected_move_pct ? ` +${post.expected_move_pct}%` : ''}
</span>
)}
<div className="impact-mini">
{impact ? (
<>
<span className="tf">1h peak</span>
<span className={`delta ${impact.m1h == null ? '' : impact.m1h >= 0 ? 'up' : 'down'}`}>
{impact.m1h == null ? '…' : fmtPct(impact.m1h)}
</span>
</>
) : (
<span className="tf">no data</span>
)}
</div>
<div className="row gap-s" style={{ fontSize: 11, color: 'var(--ink-3)' }}>
<span>AI</span>
<span className="mono" style={{ color: 'var(--ink-2)', fontWeight: 500 }}>
{post.ai_confidence}%
</span>
</div>
</>
) : (
// Noise post: no signal, no AI score. Show a single muted SKIPPED
// tag instead of HOLD pill + empty AI metric, so the row reads as
// "ignore this" at a glance.
<span style={{ <span style={{
fontSize: 10, fontWeight: 700, fontFamily: 'var(--mono)', fontSize: 10, fontWeight: 700, letterSpacing: '0.06em',
padding: '2px 6px', borderRadius: 4, color: 'var(--ink-4)', textTransform: 'uppercase',
background: post.signal === 'buy' ? 'rgba(34,197,94,0.12)' : 'rgba(239,68,68,0.12)',
color: post.signal === 'buy' ? '#22c55e' : '#ef4444',
letterSpacing: '0.04em',
}}> }}>
{post.target_asset} skipped
{post.expected_move_pct ? ` +${post.expected_move_pct}%` : ''}
</span> </span>
)} )}
<div className="impact-mini">
{impact ? (
<>
<span className="tf">1h peak</span>
<span className={`delta ${impact.m1h == null ? '' : impact.m1h >= 0 ? 'up' : 'down'}`}>
{impact.m1h == null ? '…' : fmtPct(impact.m1h)}
</span>
</>
) : (
<span className="tf">no data</span>
)}
</div>
<div className="row gap-s" style={{ fontSize: 11, color: 'var(--ink-3)' }}>
<span>AI</span>
<span className="mono" style={{ color: 'var(--ink-2)', fontWeight: 500 }}>
{aiScored ? `${post.ai_confidence}%` : '—'}
</span>
</div>
</div> </div>
</div> </div>