WeddingPlatform.Web 1.0.0.0
지도, 갤러리, 방명록, 계좌 안내와 배경음악을 링크 하나에 담는 무료 모바일 청첩장 서비스입니다.
로딩중...
검색중...
일치하는것 없음
MainWindow.xaml.cs
이 파일의 문서화 페이지로 가기
1using Dreamine.Hybrid.Wpf.Controls;
2using Dreamine.Hybrid.Wpf.Hosting;
3using Microsoft.Web.WebView2.Wpf;
4using System.ComponentModel;
5using System.Diagnostics;
6using System.Net.Http;
7using System.Runtime.InteropServices;
8using System.Windows;
9using System.Windows.Controls;
10
12
21public partial class MainWindow : Window
22{
31 private readonly DreamineBlazorServerHostOptions _serverOptions;
32
57 public MainWindow(DreamineBlazorServerHostOptions serverOptions)
58 {
59 _serverOptions = serverOptions ?? throw new ArgumentNullException(nameof(serverOptions));
60 InitializeComponent();
61
62 if (DesignerProperties.GetIsInDesignMode(this)) return;
63
64 Loaded += OnLoaded;
65 Closed += (_, _) => Application.Current?.Shutdown();
66 }
67
92 private async void OnLoaded(object sender, RoutedEventArgs e)
93 {
94 try
95 {
96 var baseUrl = $"http://127.0.0.1:{_serverOptions.Port}";
97 if (!_serverOptions.UseEmbeddedWebView)
98 {
99 await OpenExternalAdminAsync(baseUrl, _serverOptions.InstanceId, "/admin");
100 return;
101 }
102
103 var webView = HybridWebViewHost.CreateWebView();
104 WebViewHost.Child = webView;
105
106 await NavigateAsync(webView, baseUrl, _serverOptions.InstanceId, "/admin");
107 }
108 catch (Exception ex)
109 {
111 }
112 }
113
170 private async Task OpenExternalAdminAsync(string baseUrl, string expectedInstanceId,
171 string path = "/admin", int timeoutMs = 15000, int intervalMs = 500)
172 {
173 var targetUrl = $"{baseUrl}{path}";
174 var alive = await WaitForInstanceAsync(baseUrl, expectedInstanceId, timeoutMs, intervalMs);
175 if (!alive)
176 {
177 ShowExternalBrowserMessage(targetUrl, "관리자 서버를 아직 확인하지 못했습니다.");
178 return;
179 }
180
181 OpenUrl(targetUrl);
182 ShowExternalBrowserMessage(targetUrl, "관리자 화면을 기본 브라우저에서 열었습니다.");
183 }
184
249 private static async Task NavigateAsync(WebView2 webView, string baseUrl, string expectedInstanceId,
250 string path = "/admin", int timeoutMs = 15000, int intervalMs = 500)
251 {
252 var targetUrl = $"{baseUrl}{path}";
253 try
254 {
255 if (!await WaitForInstanceAsync(baseUrl, expectedInstanceId, timeoutMs, intervalMs))
256 {
257 await HybridWebViewHost.ShowOfflineMessageAsync(webView, targetUrl);
258 return;
259 }
260
261 webView.Source = new Uri(targetUrl);
262 }
263 catch (TaskCanceledException) { }
264 catch (COMException ex)
265 {
267 }
268 catch (InvalidOperationException ex)
269 {
271 }
272 }
273
322 private static async Task<bool> WaitForInstanceAsync(string baseUrl, string expectedInstanceId,
323 int timeoutMs, int intervalMs)
324 {
325 var instanceUrl = $"{baseUrl}/_dreamine/instance";
326 await Task.Delay(1200);
327
328 using var cts = new CancellationTokenSource(timeoutMs);
329 using var http = new HttpClient();
330
331 while (!cts.IsCancellationRequested)
332 {
333 try
334 {
335 var id = await http.GetStringAsync(instanceUrl, cts.Token);
336 if (string.Equals(id.Trim(), expectedInstanceId, StringComparison.Ordinal))
337 {
338 return true;
339 }
340 }
341 catch (HttpRequestException) { }
342 catch (TaskCanceledException) { }
343
344 await Task.Delay(intervalMs, cts.Token);
345 }
346
347 return false;
348 }
349
374 private void ShowExternalBrowserMessage(string targetUrl, string message)
375 {
376 var panel = new StackPanel
377 {
378 Margin = new Thickness(32),
379 VerticalAlignment = VerticalAlignment.Center,
380 HorizontalAlignment = HorizontalAlignment.Center,
381 MaxWidth = 520
382 };
383
384 panel.Children.Add(new TextBlock
385 {
386 Text = message,
387 FontSize = 22,
388 FontWeight = FontWeights.Bold,
389 TextAlignment = TextAlignment.Center,
390 Margin = new Thickness(0, 0, 0, 12)
391 });
392 panel.Children.Add(new TextBlock
393 {
394 Text = targetUrl,
395 FontSize = 14,
396 TextAlignment = TextAlignment.Center,
397 TextWrapping = TextWrapping.Wrap,
398 Margin = new Thickness(0, 0, 0, 20)
399 });
400
401 var button = new Button
402 {
403 Content = "관리자 화면 다시 열기",
404 Padding = new Thickness(18, 8, 18, 8),
405 HorizontalAlignment = HorizontalAlignment.Center
406 };
407 button.Click += (_, _) => OpenUrl(targetUrl);
408 panel.Children.Add(button);
409
410 WebViewHost.Child = panel;
411 }
412
429 private static void OpenUrl(string url)
430 {
431 Process.Start(new ProcessStartInfo(url)
432 {
433 UseShellExecute = true
434 });
435 }
436
453 private static void ShowStartupError(Exception ex)
454 {
455 Debug.WriteLine($"[WeddingPlatform.WebView2.StartupFailed] {ex}");
456 MessageBox.Show(
457 $"관리자 화면(WebView2)을 초기화하지 못했습니다.\n\n{ex.Message}",
458 "Wedding Platform",
459 MessageBoxButton.OK,
460 MessageBoxImage.Error);
461 }
462}
readonly DreamineBlazorServerHostOptions _serverOptions
static async Task< bool > WaitForInstanceAsync(string baseUrl, string expectedInstanceId, int timeoutMs, int intervalMs)
static void OpenUrl(string url)
void ShowExternalBrowserMessage(string targetUrl, string message)
async void OnLoaded(object sender, RoutedEventArgs e)
async Task OpenExternalAdminAsync(string baseUrl, string expectedInstanceId, string path="/admin", int timeoutMs=15000, int intervalMs=500)
static void ShowStartupError(Exception ex)
MainWindow(DreamineBlazorServerHostOptions serverOptions)
static async Task NavigateAsync(WebView2 webView, string baseUrl, string expectedInstanceId, string path="/admin", int timeoutMs=15000, int intervalMs=500)