using LumaTunnel.Client.ViewModels; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media; using Windows.Foundation; namespace LumaTunnel.Client.Views; public sealed partial class DashboardPage : Page { private readonly Queue _upload = new(); private readonly Queue _download = new(); private DispatcherTimer? _timer; public DashboardViewModel ViewModel { get; } = new(); public DashboardPage() { InitializeComponent(); ViewModel.PropertyChanged += (_, args) => { if (args.PropertyName == nameof(ViewModel.ErrorText)) { ErrorBar.Message = ViewModel.ErrorText ?? string.Empty; ErrorBar.IsOpen = ViewModel.ErrorText is not null; } }; } private void OnLoaded(object sender, RoutedEventArgs e) { HttpEndpointText.Text = $"127.0.0.1:{AppServices.Profile.HttpPort}"; SocksEndpointText.Text = $"127.0.0.1:{AppServices.Profile.SocksPort}"; _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) }; _timer.Tick += OnTick; _timer.Start(); OnTick(null, null!); } private void OnUnloaded(object sender, RoutedEventArgs e) => _timer?.Stop(); private void OnTick(object? sender, object e) { var connections = AppServices.ProxyEngine.Connections; AppServices.TrafficMeter.Sample(); var uploadRate = AppServices.TrafficMeter.Current.UploadBytesPerSecond; var downloadRate = AppServices.TrafficMeter.Current.DownloadBytesPerSecond; Push(_upload, uploadRate); Push(_download, downloadRate); ViewModel.Refresh(uploadRate, downloadRate); ConnectionCountText.Text = connections.Count.ToString(System.Globalization.CultureInfo.InvariantCulture); DrawLines(); } private static void Push(Queue values, double value) { values.Enqueue(value); while (values.Count > 60) values.Dequeue(); } private void DrawLines() { var max = Math.Max(1, _upload.Concat(_download).DefaultIfEmpty().Max()); var width = Math.Max(100, TrafficCanvas.ActualWidth); UploadLine.Points = Points(_upload, max, width); DownloadLine.Points = Points(_download, max, width); } private static PointCollection Points(IEnumerable values, double max, double width) { var data = values.ToArray(); var points = new PointCollection(); for (var index = 0; index < data.Length; index++) points.Add(new Point(index * width / 59d, 145 - (data[index] / max * 135))); return points; } }