diff --git a/Tornado3_2026Election/MainWindow.xaml b/Tornado3_2026Election/MainWindow.xaml index 79bb3fa..ccf6282 100644 --- a/Tornado3_2026Election/MainWindow.xaml +++ b/Tornado3_2026Election/MainWindow.xaml @@ -127,8 +127,10 @@ - - + + + + @@ -145,7 +147,12 @@ - + @@ -167,21 +174,73 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + IsCgConnected ? ConnectedStatusBrush : DisconnectedStatusBrush; + public Brush CgIntegrationCardBackgroundBrush => IsCgConnected ? ConnectedCardBackgroundBrush : DisconnectedCardBackgroundBrush; + + public Brush CgIntegrationCardBorderBrush => CgIntegrationBrush; + + public string CgIntegrationSignalText => IsCgConnected ? "CG 연결됨" : "CG 끊김"; + + public string CgIntegrationOperatorMessage => IsCgConnected ? "송출 가능" : "연결 확인 필요"; + public Brush DataNavigationIconBrush => Data.HasLiveDataSignal ? DataReceivingNavigationBrush : DataWaitingNavigationBrush; + public Brush SbsDataConnectionBrush => ResolveDataConnectionBrush(isMbcCni: false); + + public Brush SbsDataConnectionCardBackgroundBrush => ResolveDataConnectionCardBackgroundBrush(isMbcCni: false); + + public Brush SbsDataConnectionCardBorderBrush => SbsDataConnectionBrush; + + public string SbsDataConnectionSummary => ResolveDataConnectionSummary(isMbcCni: false); + + public string SbsDataConnectionDetail => ResolveDataConnectionDetail(isMbcCni: false); + + public Brush MbcCniDataConnectionBrush => ResolveDataConnectionBrush(isMbcCni: true); + + public Brush MbcCniDataConnectionCardBackgroundBrush => ResolveDataConnectionCardBackgroundBrush(isMbcCni: true); + + public Brush MbcCniDataConnectionCardBorderBrush => MbcCniDataConnectionBrush; + + public string MbcCniDataConnectionSummary => ResolveDataConnectionSummary(isMbcCni: true); + + public string MbcCniDataConnectionDetail => ResolveDataConnectionDetail(isMbcCni: true); + public string CgIntegrationDetail { get @@ -504,6 +544,93 @@ public sealed class MainViewModel : ObservableObject public string HeaderStatus => $"{Settings.SelectedStation.Name} / {CurrentPageTitle} / {Data.BroadcastPhaseBadgeText} / {OperationModeLabel}"; + private Brush ResolveDataConnectionBrush(bool isMbcCni) + { + if (!IsCurrentDataSource(isMbcCni)) + { + return WaitingStatusBrush; + } + + if (Data.IsRefreshing) + { + return ReceivingStatusBrush; + } + + if (Data.HasLiveDataSignal) + { + return ConnectedStatusBrush; + } + + return DisconnectedStatusBrush; + } + + private Brush ResolveDataConnectionCardBackgroundBrush(bool isMbcCni) + { + if (!IsCurrentDataSource(isMbcCni)) + { + return WaitingCardBackgroundBrush; + } + + if (Data.IsRefreshing) + { + return ReceivingCardBackgroundBrush; + } + + return Data.HasLiveDataSignal + ? ConnectedCardBackgroundBrush + : DisconnectedCardBackgroundBrush; + } + + private string ResolveDataConnectionSummary(bool isMbcCni) + { + if (!IsCurrentDataSource(isMbcCni)) + { + return "대기"; + } + + if (Data.IsRefreshing) + { + return "수신 중"; + } + + if (Data.HasLiveDataSignal) + { + return "연결됨"; + } + + if (!Data.IsCurrentApiSelectionSupported) + { + return "미지원"; + } + + return Data.LastRefreshAt == DateTimeOffset.MinValue ? "미수신" : "확인 필요"; + } + + private string ResolveDataConnectionDetail(bool isMbcCni) + { + if (!IsCurrentDataSource(isMbcCni)) + { + return isMbcCni + ? "광역의원 포함 MBC CNI 데이터" + : "광역단체장 포함 SBS 데이터"; + } + + return $"{Data.ElectionType} / {Data.BroadcastPhaseLabel} / {Data.StatusText}"; + } + + private bool IsCurrentDataSource(bool isMbcCni) + { + return IsMbcCniDataSource(Data.ElectionType) == isMbcCni; + } + + private static bool IsMbcCniDataSource(string electionType) + { + return string.Equals(electionType, "광역의원", StringComparison.Ordinal) || + string.Equals(electionType, "기초의원", StringComparison.Ordinal) || + string.Equals(electionType, "비례대표광역의원", StringComparison.Ordinal) || + string.Equals(electionType, "비례대표기초의원", StringComparison.Ordinal); + } + public void Navigate(string tag) { var targetPage = tag switch @@ -797,6 +924,17 @@ public sealed class MainViewModel : ObservableObject OnPropertyChanged(nameof(DataNavigationIconBrush)); } + if (args.PropertyName is nameof(DataViewModel.HasLiveDataSignal) + or nameof(DataViewModel.IsRefreshing) + or nameof(DataViewModel.LastRefreshAt) + or nameof(DataViewModel.StatusText) + or nameof(DataViewModel.ElectionType) + or nameof(DataViewModel.BroadcastPhase) + or nameof(DataViewModel.IsPollingEnabled)) + { + NotifyDataConnectionCardsChanged(); + } + if (args.PropertyName is nameof(DataViewModel.IsPollingEnabled) or nameof(DataViewModel.BroadcastPhase) or nameof(DataViewModel.ElectionType) @@ -812,11 +950,42 @@ public sealed class MainViewModel : ObservableObject } } + private void NotifyDataConnectionCardsChanged() + { + OnPropertyChanged( + nameof(DataNavigationIconBrush), + nameof(SbsDataConnectionBrush), + nameof(SbsDataConnectionCardBackgroundBrush), + nameof(SbsDataConnectionCardBorderBrush), + nameof(SbsDataConnectionSummary), + nameof(SbsDataConnectionDetail), + nameof(MbcCniDataConnectionBrush), + nameof(MbcCniDataConnectionCardBackgroundBrush), + nameof(MbcCniDataConnectionCardBorderBrush), + nameof(MbcCniDataConnectionSummary), + nameof(MbcCniDataConnectionDetail)); + } + private void RestoreSelection_PropertyChanged(object? sender, PropertyChangedEventArgs e) { QueueAutomaticSave(); } + private void NotifyCgConnectionStatusChanged() + { + OnPropertyChanged( + nameof(IsCgConnected), + nameof(CgIntegrationSummary), + nameof(CgIntegrationBrush), + nameof(CgIntegrationCardBackgroundBrush), + nameof(CgIntegrationCardBorderBrush), + nameof(CgIntegrationSignalText), + nameof(CgIntegrationOperatorMessage), + nameof(CgIntegrationDetail), + nameof(TornadoConnectionSummary), + nameof(TornadoConnectionDetail)); + } + private void Channel_PropertyChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName is nameof(ChannelScheduleViewModel.LoopEnabled) @@ -829,13 +998,7 @@ public sealed class MainViewModel : ObservableObject or nameof(ChannelScheduleViewModel.AdapterStateLabel) or nameof(ChannelScheduleViewModel.IsCgConnected)) { - OnPropertyChanged( - nameof(IsCgConnected), - nameof(CgIntegrationSummary), - nameof(CgIntegrationBrush), - nameof(CgIntegrationDetail), - nameof(TornadoConnectionSummary), - nameof(TornadoConnectionDetail)); + NotifyCgConnectionStatusChanged(); } }