65 lines
3.2 KiB
C#
65 lines
3.2 KiB
C#
using System.IO;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Interop;
|
|
using System.Windows.Media.Imaging;
|
|
using QRCoder;
|
|
using VideoDownloader.Server;
|
|
|
|
namespace VideoDownloader.App.Browser;
|
|
|
|
/// <summary>M0 원격 접근 페어링: QR(주소+토큰 동시 전달) + 상태 표시.</summary>
|
|
public sealed class PairingWindow : Window
|
|
{
|
|
public PairingWindow(ServerHost server, string deviceName)
|
|
{
|
|
Title = "기기 연결 — Video Downloader";
|
|
Width = 420; Height = 560;
|
|
WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
|
Background = System.Windows.Media.Brushes.White;
|
|
|
|
var lanIp = GetLanIp();
|
|
var url = $"http://{lanIp}:{server.Port}/#t={server.Token}";
|
|
|
|
var qrPayload = new QRCodeGenerator().CreateQrCode(url, QRCodeGenerator.ECCLevel.M);
|
|
var qr = new QRCode(qrPayload);
|
|
var bmp = qr.GetGraphic(12);
|
|
|
|
var stack = new StackPanel { Margin = new Thickness(24) };
|
|
var title = new TextBlock { Text = "📱 폰 카메라로 QR 스캔", FontSize = 16, FontWeight = FontWeights.Bold, Margin = new Thickness(0, 0, 0, 4) };
|
|
var sub = new TextBlock { Text = "브라우저에서 바로 열립니다(앱 설치 불필요). 같은 Wi-Fi 에 있어야 합니다.", FontSize = 12, Foreground = System.Windows.Media.Brushes.Gray, TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0, 0, 0, 16) };
|
|
var img = new Image { Width = 300, Height = 300 };
|
|
using var ms = new MemoryStream();
|
|
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
|
|
ms.Position = 0;
|
|
img.Source = BitmapFrame.Create(ms, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
|
|
|
|
var urlBox = new TextBox { Text = url, IsReadOnly = true, FontSize = 11, Margin = new Thickness(0, 12, 0, 4), TextWrapping = TextWrapping.Wrap };
|
|
var copyBtn = new Button { Content = "주소 복사", Padding = new Thickness(14, 6, 14, 6), HorizontalAlignment = HorizontalAlignment.Left, Margin = new Thickness(0, 8, 0, 0) };
|
|
copyBtn.Click += (_, _) => { try { Clipboard.SetText(url); } catch { } };
|
|
var note = new TextBlock { Text = $"포트 {server.Port} · Windows 방화벽 확인이 뜨면 '허용'을 선택하세요\n토큰은 이 기기와 페어링된 폰에서만 유효합니다",
|
|
FontSize = 11, Foreground = System.Windows.Media.Brushes.Gray, TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0, 12, 0, 0) };
|
|
|
|
stack.Children.Add(title);
|
|
stack.Children.Add(sub);
|
|
stack.Children.Add(img);
|
|
stack.Children.Add(urlBox);
|
|
stack.Children.Add(copyBtn);
|
|
stack.Children.Add(note);
|
|
Content = stack;
|
|
}
|
|
|
|
/// <summary>LAN IPv4(게이트웨이 있는 첫 후보) — 없으면 loopback.</summary>
|
|
private static string GetLanIp()
|
|
{
|
|
try
|
|
{
|
|
using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0);
|
|
socket.Connect("8.8.8.8", 65530); // 외부 행선지 지정 → 라우팅되는 인터페이스 IP 획득(패킷 전송 없음)
|
|
return (socket.LocalEndPoint as IPEndPoint)?.Address.ToString() ?? "127.0.0.1";
|
|
}
|
|
catch { return "127.0.0.1"; }
|
|
}
|
|
}
|