알림목록 그리드형 실시간 데이터 수신표시 적용

This commit is contained in:
Macbook
2026-06-08 01:55:33 +09:00
parent bdc0ae8a25
commit ab6f65a31d
2 changed files with 30 additions and 1 deletions
@@ -27,6 +27,8 @@ import { useIndicatorSettings } from '../../hooks/useIndicatorSettings';
import TradeSignalChartCard from './TradeSignalChartCard'; import TradeSignalChartCard from './TradeSignalChartCard';
import TradeNotificationSignalCard from './TradeNotificationSignalCard'; import TradeNotificationSignalCard from './TradeNotificationSignalCard';
import TradeNotificationHScrollPane from './TradeNotificationHScrollPane'; import TradeNotificationHScrollPane from './TradeNotificationHScrollPane';
import VirtualLiveBadge from '../virtual/VirtualLiveBadge';
import type { VirtualLiveStatus } from '../../hooks/useVirtualTargetLiveStatus';
const IcTrash = () => ( const IcTrash = () => (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
@@ -215,6 +217,10 @@ const TradeNotificationListRow: React.FC<Props> = ({
chartActivitySeq, chartActivitySeq,
]); ]);
const receiving = useLiveReceiveFlash(receiveSignal, liveReceiveEnabled); const receiving = useLiveReceiveFlash(receiveSignal, liveReceiveEnabled);
const highlightReceiving = chartLiveReceiveHighlight && receiving;
const gridLiveStatus: VirtualLiveStatus = panelActive
? (ticker != null ? 'live' : 'connecting')
: 'idle';
const indicatorChartCount = indicatorCards.length; const indicatorChartCount = indicatorCards.length;
/** 보조지표 2개 이상이면 첫 1개만 보이고 나머지는 좌우 스크롤 */ /** 보조지표 2개 이상이면 첫 1개만 보이고 나머지는 좌우 스크롤 */
@@ -238,6 +244,7 @@ const TradeNotificationListRow: React.FC<Props> = ({
isBuy ? 'tnl-summary-card--buy' : 'tnl-summary-card--sell', isBuy ? 'tnl-summary-card--buy' : 'tnl-summary-card--sell',
!isListLayout ? 'tnl-summary-card--grid' : '', !isListLayout ? 'tnl-summary-card--grid' : '',
isSelected ? 'tnl-summary-card--selected' : '', isSelected ? 'tnl-summary-card--selected' : '',
!isListLayout && highlightReceiving ? 'tnl-summary-card--receiving' : '',
].filter(Boolean).join(' ')} ].filter(Boolean).join(' ')}
aria-label="알림 요약" aria-label="알림 요약"
> >
@@ -248,6 +255,12 @@ const TradeNotificationListRow: React.FC<Props> = ({
<span className="tnl-summary-sym">{sym || secondary}</span> <span className="tnl-summary-sym">{sym || secondary}</span>
</div> </div>
<div className="tnl-summary-head-actions"> <div className="tnl-summary-head-actions">
{!isListLayout && panelActive && (
<VirtualLiveBadge
status={gridLiveStatus}
receiving={highlightReceiving}
/>
)}
<span className={`tnl-signal ${isBuy ? 'tnl-signal--buy' : 'tnl-signal--sell'}`}> <span className={`tnl-signal ${isBuy ? 'tnl-signal--buy' : 'tnl-signal--sell'}`}>
{item.signalType} {item.signalType}
</span> </span>
@@ -366,7 +379,7 @@ const TradeNotificationListRow: React.FC<Props> = ({
isListLayout ? 'tnl-row--gallery' : 'tnl-row--grid', isListLayout ? 'tnl-row--gallery' : 'tnl-row--grid',
!item.isRead ? 'tnl-row--unread' : '', !item.isRead ? 'tnl-row--unread' : '',
isSelected ? 'tnl-row--selected' : '', isSelected ? 'tnl-row--selected' : '',
receiving ? 'tnl-row--receiving' : '', receiving && isListLayout ? 'tnl-row--receiving' : '',
].filter(Boolean).join(' '); ].filter(Boolean).join(' ');
if (!isListLayout) { if (!isListLayout) {
@@ -1478,6 +1478,22 @@
0 0 12px 2px color-mix(in srgb, var(--accent, #7aa2f7) 18%, transparent); 0 0 12px 2px color-mix(in srgb, var(--accent, #7aa2f7) 18%, transparent);
} }
/* 그리드형 — 실시간 수신 시 카드 외곽 형광 연두 (목록형 행 아웃라인과 동일) */
.tnl-summary-card--grid.tnl-summary-card--receiving {
border-color: var(--gc-receive-border) !important;
box-shadow: var(--gc-receive-shadow);
transition: box-shadow 0.15s ease-out, border-color 0.15s ease-out;
}
.tnl-summary-card--grid.tnl-summary-card--receiving.tnl-summary-card--selected {
border-color: var(--gc-receive-border) !important;
box-shadow: var(--gc-receive-shadow);
}
.tnl-summary-card--grid .tnl-summary-head-actions .vtd-live-badge {
margin-right: 2px;
}
.tnl-row--gallery.tnl-row--selected .tnl-hscroll-pane, .tnl-row--gallery.tnl-row--selected .tnl-hscroll-pane,
.tnl-row--gallery.tnl-row--selected .tnl-summary-card--selected { .tnl-row--gallery.tnl-row--selected .tnl-summary-card--selected {
border-color: var(--accent, #7aa2f7); border-color: var(--accent, #7aa2f7);