feat(ui): one-click 'Hide off-topic' toggle on the Trump feed
Lets the user collapse every post the AI judged off-topic (not crypto-related, never scored) so the feed shows only real signals. - PostCards exports isAiScored(post) as the single source of truth for what counts as noise — the card de-emphasis and the list filter now share it, so they can never disagree. - TrumpPageClient: 'Hide off-topic (N)' toggle in the filter row (only shown when N>0), with live noise count. Resets to page 1 on toggle. tsc + build clean. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,16 @@
|
||||
import { memo, useEffect, useState } from 'react'
|
||||
import type { TrumpPost } from '@/types'
|
||||
|
||||
/**
|
||||
* Was this post actually AI-scored, or filtered as off-topic noise before any
|
||||
* AI call? Single source of truth — used both by the card (to de-emphasise
|
||||
* noise) and by list views (to offer a "collapse off-topic" toggle), so the
|
||||
* two can never disagree about what counts as noise.
|
||||
*/
|
||||
export function isAiScored(post: Pick<TrumpPost, 'ai_confidence' | 'ai_reasoning'>): boolean {
|
||||
return (post.ai_confidence ?? 0) > 0 || !!post.ai_reasoning
|
||||
}
|
||||
|
||||
function fmtPct(n: number | null | undefined) {
|
||||
if (n == null || isNaN(n)) return '—' // null = window not yet closed
|
||||
const s = n.toFixed(2) + '%'
|
||||
@@ -102,14 +112,10 @@ const PostRow = memo(function PostRow({ post, selected, onClick }: PostRowProps)
|
||||
onClick?.()
|
||||
}
|
||||
|
||||
// Did this post actually get an AI score, or was it filtered as off-topic
|
||||
// noise before any AI call? Trump posts mostly aren't crypto-related, so the
|
||||
// entry filter / AI marks them relevant=false with confidence 0 and no
|
||||
// reasoning. Showing "AI confidence 0%" + an empty bar for those is
|
||||
// misleading — it reads as "AI looked and had zero confidence" when really
|
||||
// "this was skipped as not crypto-relevant". Treat a post as AI-scored only
|
||||
// when it has a real confidence or reasoning.
|
||||
const aiScored = post.ai_confidence > 0 || !!post.ai_reasoning
|
||||
// Off-topic Trump posts (most of them) are filtered before any AI call, so
|
||||
// they carry confidence 0 + no reasoning. Treat those as un-scored noise and
|
||||
// de-emphasise them. Shared helper so list-level "collapse off-topic" agrees.
|
||||
const aiScored = isAiScored(post)
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user