209 lines
5.4 KiB
C#
209 lines
5.4 KiB
C#
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);
|
|
}
|
|
}
|