feat: refine branded operator experience

Add the MBN-branded startup intro, semantic sidebar icons, and refined card-based operator visuals. Strengthen packaged UI and input smoke coverage for the updated experience.
This commit is contained in:
2026-07-24 01:26:13 +09:00
parent f43483533a
commit b050f2f06c
25 changed files with 2316 additions and 164 deletions

View File

@@ -286,6 +286,7 @@ public sealed partial class MainWindow : Window
}
ConfigureWindow();
StartStartupIntro();
await InitializeWebViewAsync();
if (!_closing)
{
@@ -304,6 +305,22 @@ public sealed partial class MainWindow : Window
var windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(windowHandle);
var appWindow = AppWindow.GetFromWindowId(windowId);
appWindow.Title = "V-Stock 증권정보송출시스템 for 매일경제TV (26.03.26)";
if (AppWindowTitleBar.IsCustomizationSupported())
{
var titleBar = appWindow.TitleBar;
titleBar.BackgroundColor = Windows.UI.Color.FromArgb(255, 8, 24, 43);
titleBar.ForegroundColor = Windows.UI.Color.FromArgb(255, 255, 255, 255);
titleBar.InactiveBackgroundColor = Windows.UI.Color.FromArgb(255, 14, 34, 59);
titleBar.InactiveForegroundColor = Windows.UI.Color.FromArgb(255, 191, 210, 230);
titleBar.ButtonBackgroundColor = Windows.UI.Color.FromArgb(255, 8, 24, 43);
titleBar.ButtonForegroundColor = Windows.UI.Color.FromArgb(255, 255, 255, 255);
titleBar.ButtonHoverBackgroundColor = Windows.UI.Color.FromArgb(255, 21, 49, 79);
titleBar.ButtonHoverForegroundColor = Windows.UI.Color.FromArgb(255, 255, 255, 255);
titleBar.ButtonPressedBackgroundColor = Windows.UI.Color.FromArgb(255, 244, 123, 32);
titleBar.ButtonPressedForegroundColor = Windows.UI.Color.FromArgb(255, 255, 255, 255);
titleBar.ButtonInactiveBackgroundColor = Windows.UI.Color.FromArgb(255, 14, 34, 59);
titleBar.ButtonInactiveForegroundColor = Windows.UI.Color.FromArgb(255, 191, 210, 230);
}
var iconPath = Path.Combine(AppContext.BaseDirectory, "Assets", "AppIcon.ico");
if (File.Exists(iconPath))
{
@@ -380,6 +397,7 @@ public sealed partial class MainWindow : Window
if (!_closing)
{
ShowError("WebView2 초기화에 실패했습니다.", exception.Message);
BeginDismissStartupIntro();
}
}
}
@@ -400,10 +418,10 @@ public sealed partial class MainWindow : Window
return;
}
LoadingOverlay.Visibility = Visibility.Collapsed;
if (!args.IsSuccess)
{
ShowError("원본 호환 화면을 불러오지 못했습니다.", args.WebErrorStatus.ToString());
BeginDismissStartupIntro();
}
}
@@ -737,6 +755,10 @@ public sealed partial class MainWindow : Window
{
_intentBusy = false;
PostState(state);
if (intent is LegacyReadyIntent)
{
BeginDismissStartupIntro();
}
}
}
catch (OperationCanceledException) when (_lifetimeCancellation.IsCancellationRequested)
@@ -759,6 +781,10 @@ public sealed partial class MainWindow : Window
writeOutcomeMayBeUnknown: dispatchStarted);
ObserveOperatorMutationQuarantine(failureState);
PostState(failureState);
if (intent is LegacyReadyIntent)
{
BeginDismissStartupIntro();
}
}
finally
{
@@ -1620,6 +1646,7 @@ public sealed partial class MainWindow : Window
if (!_closing)
{
ShowError("WebView2 프로세스가 중단되었습니다.", args.ProcessFailedKind.ToString());
BeginDismissStartupIntro();
}
}