using System.Diagnostics; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Platform; using Avalonia.Platform.Storage; using OF_DL.Gui.ViewModels; namespace OF_DL.Gui.Views; public partial class MainWindow : Window { private const string DiscordInviteUrl = "https://discord.com/invite/6bUW8EJ53j"; private const string DocumentationUrl = "https://docs.ofdl.tools/"; private bool _hasInitialized; public MainWindowViewModel? ViewModel => DataContext as MainWindowViewModel; public MainWindow() { InitializeComponent(); Icon = new WindowIcon(AssetLoader.Open(new Uri("avares://OF DL.Gui/Assets/icon.ico"))); Opened += OnOpened; } private async void OnOpened(object? sender, EventArgs e) { if (_hasInitialized) { return; } _hasInitialized = true; if (DataContext is MainWindowViewModel vm) { await vm.InitializeAsync(); } } private async void OnBrowseFfmpegPathClick(object? sender, RoutedEventArgs e) { if (DataContext is not MainWindowViewModel vm) { return; } TopLevel? topLevel = GetTopLevel(this); if (topLevel?.StorageProvider == null) { return; } IReadOnlyList selectedFiles = await topLevel.StorageProvider.OpenFilePickerAsync( new FilePickerOpenOptions { Title = "Select FFmpeg executable", AllowMultiple = false }); IStorageFile? selectedFile = selectedFiles.FirstOrDefault(); if (selectedFile == null) { return; } string? localPath = selectedFile.TryGetLocalPath(); if (!string.IsNullOrWhiteSpace(localPath)) { vm.SetFfmpegPath(localPath); return; } vm.SetFfmpegPath(selectedFile.Name); } private async void OnBrowseFfprobePathClick(object? sender, RoutedEventArgs e) { if (DataContext is not MainWindowViewModel vm) { return; } TopLevel? topLevel = GetTopLevel(this); if (topLevel?.StorageProvider == null) { return; } IReadOnlyList selectedFiles = await topLevel.StorageProvider.OpenFilePickerAsync( new FilePickerOpenOptions { Title = "Select FFprobe executable", AllowMultiple = false }); IStorageFile? selectedFile = selectedFiles.FirstOrDefault(); if (selectedFile == null) { return; } string? localPath = selectedFile.TryGetLocalPath(); if (!string.IsNullOrWhiteSpace(localPath)) { vm.SetFfprobePath(localPath); return; } vm.SetFfprobePath(selectedFile.Name); } private async void OnBrowseDownloadPathClick(object? sender, RoutedEventArgs e) { if (DataContext is not MainWindowViewModel vm) { return; } TopLevel? topLevel = GetTopLevel(this); if (topLevel?.StorageProvider == null) { return; } IReadOnlyList selectedFolders = await topLevel.StorageProvider.OpenFolderPickerAsync( new FolderPickerOpenOptions { Title = "Select download folder", AllowMultiple = false }); IStorageFolder? selectedFolder = selectedFolders.FirstOrDefault(); if (selectedFolder == null) { return; } string? localPath = selectedFolder.TryGetLocalPath(); if (!string.IsNullOrWhiteSpace(localPath)) { vm.SetDownloadPath(localPath); return; } vm.SetDownloadPath(selectedFolder.Name); } private async void OnJoinDiscordClick(object? sender, RoutedEventArgs e) => await OpenExternalUrlAsync(DiscordInviteUrl); private async void OnDocumentationClick(object? sender, RoutedEventArgs e) => await OpenExternalUrlAsync(DocumentationUrl); private void OnFaqClick(object? sender, RoutedEventArgs e) { FaqWindow faqWindow = new() { WindowStartupLocation = WindowStartupLocation.CenterOwner }; faqWindow.Show(this); } private void OnAboutClick(object? sender, RoutedEventArgs e) { if (DataContext is not MainWindowViewModel vm) { return; } AboutWindow aboutWindow = new(vm.ProgramVersion, vm.FfmpegVersion, vm.FfprobeVersion) { WindowStartupLocation = WindowStartupLocation.CenterOwner }; aboutWindow.Show(this); } private async Task OpenExternalUrlAsync(string url) { try { ProcessStartInfo processStartInfo = new(url) { UseShellExecute = true }; Process.Start(processStartInfo); } catch { await Task.CompletedTask; } } private void OnModalOverlayClicked(object? sender, PointerPressedEventArgs e) { // Only handle clicks on the overlay itself (the Grid background) if (DataContext is not MainWindowViewModel vm) { return; } // Execute cancel command on the modal vm.CreatorConfigEditor.ModalViewModel?.CancelCommand?.Execute(null); } private void OnModalContentClicked(object? sender, PointerPressedEventArgs e) => // Stop the event from bubbling up to the overlay e.Handled = true; }