57 lines
2.1 KiB
TypeScript
57 lines
2.1 KiB
TypeScript
import { useMemo } from 'react'
|
|
import type { SituationUpdate, ConflictEvent } from '@/data/mockData'
|
|
import { processTickerText } from '@/utils/tickerText'
|
|
|
|
interface NewsTickerProps {
|
|
updates?: SituationUpdate[]
|
|
conflictEvents?: ConflictEvent[]
|
|
className?: string
|
|
}
|
|
|
|
export function NewsTicker({ updates = [], conflictEvents = [], className = '' }: NewsTickerProps) {
|
|
const items = useMemo(() => {
|
|
const list: { id: string; text: string }[] = []
|
|
for (const e of conflictEvents || []) {
|
|
const text = processTickerText(e.title || '')
|
|
if (text) list.push({ id: `ev-${e.event_id}`, text })
|
|
}
|
|
for (const u of updates || []) {
|
|
const text = processTickerText(u.summary || '')
|
|
if (text) list.push({ id: `up-${u.id}`, text })
|
|
}
|
|
return list.slice(0, 30)
|
|
}, [updates, conflictEvents])
|
|
|
|
const baseCls = 'flex items-center overflow-hidden'
|
|
const defaultCls = 'border-b border-military-border/50 bg-military-panel/60 py-1.5'
|
|
const wrapperCls = className ? `${baseCls} ${className}` : `${baseCls} ${defaultCls}`
|
|
|
|
if (items.length === 0) {
|
|
return (
|
|
<div className={wrapperCls}>
|
|
<span className="shrink-0 pr-2 text-[10px] uppercase text-military-text-secondary">滚动情报</span>
|
|
<span className="text-[11px] text-military-text-secondary">暂无资讯</span>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const content = items.map((i) => i.text).join(' ◆ ')
|
|
const duration = Math.max(180, Math.min(480, content.length * 0.8))
|
|
|
|
return (
|
|
<div className={wrapperCls}>
|
|
<span className="shrink-0 pr-2 text-[10px] font-medium uppercase tracking-wider text-cyan-400">滚动情报</span>
|
|
<div className="min-w-0 flex-1 overflow-hidden">
|
|
<div
|
|
className="inline-flex whitespace-nowrap text-[11px] text-military-text-secondary"
|
|
style={{ animation: `ticker ${duration}s linear infinite` }}
|
|
>
|
|
<span className="px-2">{content}</span>
|
|
<span className="px-2 text-cyan-400/60">◆</span>
|
|
<span className="px-2">{content}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|