Add Windows desktop version
This commit is contained in:
208
windows/StreamPlayer.Desktop/Views/MainWindow.axaml.cs
Normal file
208
windows/StreamPlayer.Desktop/Views/MainWindow.axaml.cs
Normal file
@@ -0,0 +1,208 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Threading;
|
||||
using StreamPlayer.Desktop.Models;
|
||||
using StreamPlayer.Desktop.ViewModels;
|
||||
|
||||
namespace StreamPlayer.Desktop.Views;
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private readonly CancellationTokenSource _lifetimeCts = new();
|
||||
private MainWindowViewModel? _viewModel;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContextChanged += OnDataContextChanged;
|
||||
Opened += OnOpened;
|
||||
Closed += OnClosed;
|
||||
AttachViewModel(DataContext as MainWindowViewModel);
|
||||
}
|
||||
|
||||
private void OnDataContextChanged(object? sender, EventArgs e)
|
||||
{
|
||||
AttachViewModel(DataContext as MainWindowViewModel);
|
||||
}
|
||||
|
||||
private void AttachViewModel(MainWindowViewModel? newViewModel)
|
||||
{
|
||||
if (_viewModel != null)
|
||||
{
|
||||
_viewModel.ChannelRequested -= OnChannelRequested;
|
||||
_viewModel.UpdateAvailable -= OnUpdateAvailable;
|
||||
_viewModel.DeviceStatusEvaluated -= OnDeviceStatusEvaluated;
|
||||
_viewModel.ErrorRaised -= OnErrorRaised;
|
||||
}
|
||||
|
||||
_viewModel = newViewModel;
|
||||
if (_viewModel != null)
|
||||
{
|
||||
_viewModel.ChannelRequested += OnChannelRequested;
|
||||
_viewModel.UpdateAvailable += OnUpdateAvailable;
|
||||
_viewModel.DeviceStatusEvaluated += OnDeviceStatusEvaluated;
|
||||
_viewModel.ErrorRaised += OnErrorRaised;
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnOpened(object? sender, EventArgs e)
|
||||
{
|
||||
if (_viewModel == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
await _viewModel.InitializeAsync(_lifetimeCts.Token);
|
||||
await _viewModel.CheckForUpdatesAsync(_lifetimeCts.Token);
|
||||
await _viewModel.VerifyDeviceAsync(_lifetimeCts.Token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClosed(object? sender, EventArgs e)
|
||||
{
|
||||
_lifetimeCts.Cancel();
|
||||
_lifetimeCts.Dispose();
|
||||
AttachViewModel(null);
|
||||
}
|
||||
|
||||
private void OnChannelRequested(object? sender, StreamChannel channel)
|
||||
{
|
||||
if (channel == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
var player = new PlayerWindow(channel);
|
||||
player.Show(this);
|
||||
});
|
||||
}
|
||||
|
||||
private async void OnUpdateAvailable(object? sender, UpdateInfo info)
|
||||
{
|
||||
var mandatory = info.IsMandatory(AppVersion.VersionCode);
|
||||
var dialog = new UpdateDialog(info, mandatory);
|
||||
var result = await dialog.ShowDialog<UpdateDialogAction>(this);
|
||||
switch (result)
|
||||
{
|
||||
case UpdateDialogAction.Download:
|
||||
LaunchUrl(info.DownloadUrl);
|
||||
if (mandatory)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
break;
|
||||
case UpdateDialogAction.ViewRelease:
|
||||
LaunchUrl(string.IsNullOrWhiteSpace(info.ReleasePageUrl)
|
||||
? info.DownloadUrl
|
||||
: info.ReleasePageUrl);
|
||||
if (mandatory)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
break;
|
||||
case UpdateDialogAction.Exit:
|
||||
Close();
|
||||
break;
|
||||
case UpdateDialogAction.Skip:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnDeviceStatusEvaluated(object? sender, DeviceStatus status)
|
||||
{
|
||||
if (!status.IsBlocked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var dialog = new BlockedDialog(status.Reason, status.TokenPart);
|
||||
await dialog.ShowDialog(this);
|
||||
Close();
|
||||
}
|
||||
|
||||
private async void OnErrorRaised(object? sender, string message)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
await ShowInfoAsync("Aviso", message);
|
||||
}
|
||||
|
||||
private static void LaunchUrl(string? url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = url,
|
||||
UseShellExecute = true
|
||||
});
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private Task ShowInfoAsync(string title, string message)
|
||||
{
|
||||
var okButton = new Button
|
||||
{
|
||||
Content = "Aceptar",
|
||||
HorizontalAlignment = HorizontalAlignment.Right,
|
||||
Width = 120
|
||||
};
|
||||
|
||||
var stack = new StackPanel
|
||||
{
|
||||
Spacing = 12
|
||||
};
|
||||
stack.Children.Add(new TextBlock
|
||||
{
|
||||
Text = message,
|
||||
TextWrapping = TextWrapping.Wrap
|
||||
});
|
||||
stack.Children.Add(okButton);
|
||||
|
||||
var dialog = new Window
|
||||
{
|
||||
Title = title,
|
||||
Width = 420,
|
||||
SizeToContent = SizeToContent.Height,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterOwner,
|
||||
CanResize = false,
|
||||
Content = new Border
|
||||
{
|
||||
Padding = new Thickness(20),
|
||||
Child = stack
|
||||
}
|
||||
};
|
||||
|
||||
okButton.Click += (_, _) => dialog.Close();
|
||||
|
||||
return dialog.ShowDialog(this);
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user