Projektdateien hinzufügen.

This commit is contained in:
Kevin Krüger
2023-07-24 12:00:34 +02:00
parent 656751e10b
commit 0d00a90942
210 changed files with 45049 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
namespace VideoBrowser.ViewModels
{
using System.Windows.Input;
using System.Windows.Media;
using VideoBrowser.Common;
using VideoBrowser.Controls.CefSharpBrowser.Helpers;
using VideoBrowser.Resources;
/// <summary>
/// Defines the <see cref="AboutViewModel" />.
/// </summary>
public class AboutViewModel
{
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="AboutViewModel"/> class.
/// </summary>
internal AboutViewModel()
{
this.ApplicationName = AppEnvironment.LongName;
this.ProjectUrlClickedCommand = new RelayCommand(this.OnProjectUrlClicked, nameof(this.ProjectUrlClickedCommand));
this.LinkedInCommand = new RelayCommand(this.OnLinkedIn, nameof(this.TwitterCommand));
this.TwitterCommand = new RelayCommand(this.OnTwitter, nameof(this.TwitterCommand));
}
#endregion Constructors
#region Properties
/// <summary>
/// Gets the AppIcon.
/// </summary>
public ImageSource AppIcon { get; } = Helpers.ImageHelper.ToImageSource(Properties.Resources.Icon);
/// <summary>
/// Gets the ApplicationName.
/// </summary>
public string ApplicationName { get; }
/// <summary>
/// Gets the Author.
/// </summary>
public string Author => $"By {AppEnvironment.Author}";
/// <summary>
/// Gets the Icon.
/// </summary>
public Geometry Icon => Icons.Info;
/// <summary>
/// Gets the LinkedInCommand.
/// </summary>
public ICommand LinkedInCommand { get; }
/// <summary>
/// Gets the ProjectUrl.
/// </summary>
public string ProjectUrl => AppEnvironment.ProjectUrl;
/// <summary>
/// Gets the ProjectUrlClickedCommand.
/// </summary>
public ICommand ProjectUrlClickedCommand { get; }
/// <summary>
/// Gets the TwitterCommand.
/// </summary>
public ICommand TwitterCommand { get; }
/// <summary>
/// Gets the Version.
/// </summary>
public string Version => $"Version {AppEnvironment.Version}";
#endregion Properties
#region Methods
/// <summary>
/// The OnLinkedIn.
/// </summary>
/// <param name="obj">The obj<see cref="object"/>.</param>
private void OnLinkedIn(object obj)
{
ProcessHelper.OpenUrl(@"https://www.linkedin.com/in/ynurcahyo/");
}
/// <summary>
/// The OnProjectUrlClicked.
/// </summary>
/// <param name="obj">The obj<see cref="object"/>.</param>
private void OnProjectUrlClicked(object obj)
{
ProcessHelper.OpenUrl(this.ProjectUrl);
}
/// <summary>
/// The OnTwitter.
/// </summary>
/// <param name="obj">The obj<see cref="object"/>.</param>
private void OnTwitter(object obj)
{
ProcessHelper.OpenUrl(@"https://twitter.com/txtnurcahyo");
}
#endregion Methods
}
}

View File

@@ -0,0 +1,94 @@
namespace VideoBrowser.ViewModels
{
using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows.Input;
using VideoBrowser.Common;
using VideoBrowser.Controls.CefSharpBrowser.Models;
using VideoBrowser.Extensions;
/// <summary>
/// Defines the <see cref="DownloadFlyoutViewModel" />.
/// </summary>
public class DownloadFlyoutViewModel : NotifyPropertyChanged
{
#region Fields
private bool _isOpen;
private string _message;
#endregion Fields
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="DownloadFlyoutViewModel"/> class.
/// </summary>
/// <param name="models">The models<see cref="ObservableCollection{DownloadItemModel}"/>.</param>
internal DownloadFlyoutViewModel(ObservableCollection<DownloadItemModel> models)
{
this.DownloadItemModels = models;
this.DownloadItemModels.CollectionChanged += this.OnDownloadItemModels_CollectionChanged;
this.ShowDownloadTabCommand = new RelayCommand(this.OnShowDownloadTab, nameof(this.ShowDownloadTabCommand));
}
#endregion Constructors
#region Properties
/// <summary>
/// Gets or sets the DownloadItemModels.
/// </summary>
public ObservableCollection<DownloadItemModel> DownloadItemModels { get; internal set; }
/// <summary>
/// Gets or sets a value indicating whether IsOpen.
/// </summary>
public bool IsOpen { get => _isOpen; set => this.Set(this.PropertyChangedHandler, ref _isOpen, value); }
/// <summary>
/// Gets or sets the Message.
/// </summary>
public string Message { get => _message; internal set => this.Set(this.PropertyChangedHandler, ref _message, value); }
/// <summary>
/// Gets or sets the ShowDownloadTabAction.
/// </summary>
public Action ShowDownloadTabAction { get; set; }
/// <summary>
/// Gets the ShowDownloadTabCommand.
/// </summary>
public ICommand ShowDownloadTabCommand { get; }
#endregion Properties
#region Methods
/// <summary>
/// The OnDownloadItemModels_CollectionChanged.
/// </summary>
/// <param name="sender">The sender<see cref="object"/>.</param>
/// <param name="e">The e<see cref="NotifyCollectionChangedEventArgs"/>.</param>
private void OnDownloadItemModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
this.IsOpen = true;
}
}
/// <summary>
/// The OnShowDownloadTab.
/// </summary>
/// <param name="obj">The obj<see cref="object"/>.</param>
private void OnShowDownloadTab(object obj)
{
this.ShowDownloadTabAction?.Invoke();
}
#endregion Methods
}
}

View File

@@ -0,0 +1,142 @@
namespace VideoBrowser.ViewModels
{
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using VideoBrowser.Common;
using VideoBrowser.Controls.CefSharpBrowser.Models;
using VideoBrowser.Core;
using VideoBrowser.Helpers;
using VideoBrowser.Models;
using VideoBrowser.Resources;
/// <summary>
/// Defines the <see cref="DownloadQueueViewModel" />.
/// </summary>
public class DownloadQueueViewModel
{
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="DownloadQueueViewModel"/> class.
/// </summary>
/// <param name="downloadItemModels">The downloadItemModels<see cref="ObservableCollection{DownloadItemModel}"/>.</param>
internal DownloadQueueViewModel(ObservableCollection<DownloadItemModel> downloadItemModels)
{
this.DownloadItemModels = downloadItemModels;
this.OperationCollectionView = CollectionViewSource.GetDefaultView(this.DownloadItemModels);
this.RemoveOperationCommand = new RelayCommand(this.OnRemoveOperation);
}
#endregion Constructors
#region Properties
/// <summary>
/// Gets the DownloadItemModels.
/// </summary>
public ObservableCollection<DownloadItemModel> DownloadItemModels { get; }
/// <summary>
/// Gets or sets the Icon.
/// </summary>
public Geometry Icon { get; set; } = Icons.Download;
/// <summary>
/// Gets the OperationCollectionView.
/// </summary>
public ICollectionView OperationCollectionView { get; }
/// <summary>
/// Gets the RemoveOperationCommand.
/// </summary>
public ICommand RemoveOperationCommand { get; }
/// <summary>
/// Gets or sets the ShowMessageAsync.
/// </summary>
public Action<string, string> ShowMessageAsync { get; set; }
#endregion Properties
#region Methods
/// <summary>
/// The Download.
/// </summary>
/// <param name="operation">The operation<see cref="Operation"/>.</param>
public void Download(Operation operation)
{
var operationModel = new OperationModel(operation) { PauseDownloadAction = this.OnPauseDownloadCalled, CancelDownloadAction = this.OnCancelDownloadCalled };
var element = (DispatcherObject)this.OperationCollectionView;
element.InvokeAsync(() =>
{
if (!this.DownloadItemModels.Contains(operationModel))
{
this.DownloadItemModels.Insert(0, operationModel);
DownloadQueueHandler.Add(operation);
}
else
{
var output = Path.GetFileName(operationModel.Operation.Output);
this.ShowMessageAsync("Download Canceled", $"The video/audio {output} is already downloaded");
}
});
}
/// <summary>
/// The OnCancelDownloadCalled.
/// </summary>
/// <param name="model">The model<see cref="DownloadItemModel"/>.</param>
internal void OnCancelDownloadCalled(DownloadItemModel model)
{
model.Dispose();
this.DownloadItemModels.Remove(model);
}
/// <summary>
/// The OnPauseDownloadCalled.
/// </summary>
/// <param name="model">The model<see cref="DownloadItemModel"/>.</param>
internal void OnPauseDownloadCalled(DownloadItemModel model)
{
if (!(model is OperationModel operationModel))
{
return;
}
var operation = operationModel.Operation;
var status = operation.Status;
if (status != OperationStatus.Paused && status != OperationStatus.Queued && status != OperationStatus.Working)
{
return;
}
if (status == OperationStatus.Paused)
{
operation.Resume();
model.PauseText = "Pause";
}
else
{
operation.Pause();
model.PauseText = "Resume";
}
}
/// <summary>
/// The OnRemoveVideo.
/// </summary>
/// <param name="obj">The obj<see cref="object"/>.</param>
private void OnRemoveOperation(object obj)
{
}
#endregion Methods
}
}

View File

@@ -0,0 +1,250 @@
namespace VideoBrowser.ViewModels
{
using Dragablz;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using VideoBrowser.Common;
using VideoBrowser.Controls.CefSharpBrowser;
using VideoBrowser.Controls.CefSharpBrowser.ViewModels;
using VideoBrowser.Core;
using VideoBrowser.Models;
using VideoBrowser.Views;
/// <summary>
/// Defines the <see cref="MainWindowViewModel" />.
/// </summary>
public class MainWindowViewModel : NotifyPropertyChanged
{
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="MainWindowViewModel"/> class.
/// </summary>
/// <param name="globalData">The globalData<see cref="GlobalData"/>.</param>
/// <param name="globalBrowserData">The globalBrowserData<see cref="GlobalBrowserData"/>.</param>
public MainWindowViewModel(GlobalBrowserData globalBrowserData)
{
this.ClosingCommand = new RelayCommand(this.OnClosing);
this.LoadedCommand = new RelayCommand(this.OnLoaded);
this.PressEscCommand = new RelayCommand(this.OnPressEsc);
this.PressF2Command = new RelayCommand(this.OnPressF2);
this.About = new AboutViewModel();
var downloadItemModels = globalBrowserData.DownloadItemModels;
this.DownloadQueueViewModel = new DownloadQueueViewModel(downloadItemModels) { ShowMessageAsync = this.ShowMessageAsync };
this.DownloadFlyoutViewModel = new DownloadFlyoutViewModel(downloadItemModels) { ShowDownloadTabAction = this.ShowDownloadTabAction };
this.WebBrowserTabControlViewModel = new WebBrowserTabControlViewModel(globalBrowserData)
{
CreateBrowserFunc = this.CreateBrowser
};
this.Initialize();
}
#endregion Constructors
#region Properties
/// <summary>
/// Gets the About.
/// </summary>
public AboutViewModel About { get; }
/// <summary>
/// Gets the CefWindowData.
/// </summary>
public CefWindowData CefWindowData => this.WebBrowserTabControlViewModel.CefWindowData;
/// <summary>
/// Gets the ClosingCommand.
/// </summary>
public RelayCommand ClosingCommand { get; }
/// <summary>
/// Gets the DownloadFlyoutViewModel.
/// </summary>
public DownloadFlyoutViewModel DownloadFlyoutViewModel { get; }
/// <summary>
/// Gets the DownloadQueueViewModel.
/// </summary>
public DownloadQueueViewModel DownloadQueueViewModel { get; }
/// <summary>
/// Gets the GlobalBrowserData.
/// </summary>
public GlobalBrowserData GlobalBrowserData => this.WebBrowserTabControlViewModel.GlobalBrowserData;
/// <summary>
/// Gets the LoadedCommand.
/// </summary>
public ICommand LoadedCommand { get; }
/// <summary>
/// Gets the PressEscCommand.
/// </summary>
public ICommand PressEscCommand { get; }
/// <summary>
/// Gets the PressF2Command.
/// </summary>
public ICommand PressF2Command { get; }
/// <summary>
/// Gets the Settings.
/// </summary>
public SettingsViewModel Settings => this.GlobalBrowserData.Settings;
/// <summary>
/// Gets the Title.
/// </summary>
public string Title => $"{AppEnvironment.Name}";
/// <summary>
/// Gets the WebBrowserTabControlViewModel.
/// </summary>
public WebBrowserTabControlViewModel WebBrowserTabControlViewModel { get; }
/// <summary>
/// Gets the DownloadAction.
/// </summary>
private Action<Operation> DownloadAction => this.DownloadQueueViewModel.Download;
#endregion Properties
#region Methods
/// <summary>
/// The CreateBrowser.
/// </summary>
/// <returns>The <see cref="HeaderedItemViewModel"/>.</returns>
internal TabItem CreateBrowser()
{
var model = new WebBrowserHeaderedItemViewModel(this.GlobalBrowserData, this.CefWindowData, this.DownloadAction);
return model;
}
/// <summary>
/// The Dispose.
/// </summary>
private void Dispose()
{
this.WebBrowserTabControlViewModel.Dispose();
var viewModels = this.GlobalBrowserData.WindowViewModels;
if (viewModels.Contains(this))
{
viewModels.Remove(this);
}
if (!viewModels.Any())
{
this.GlobalBrowserData.Dispose();
}
}
/// <summary>
/// The Initialize.
/// </summary>
private void Initialize()
{
var args = AppEnvironment.Arguments;
var url = Properties.Settings.Default.LastUrl;
if (args != null && args.Any())
{
url = args.First();
}
if (this.WebBrowserTabControlViewModel.TabItems.Any())
{
var browser = this.WebBrowserTabControlViewModel.TabItems.First();
if (browser is WebBrowserHeaderedItemViewModel model)
{
model.VideoBrowserViewModel.NavigateUrl = url;
}
}
}
/// <summary>
/// The OnClosing.
/// </summary>
/// <param name="obj">The obj<see cref="object"/>.</param>
private void OnClosing(object obj)
{
var (_, _, commandParameter) = (ValueTuple<object, EventArgs, object>)obj;
var window = (Window)commandParameter;
var settings = Properties.Settings.Default;
settings.WindowPosition = new Point(window.Left, window.Top);
settings.WindowWidth = window.ActualWidth;
settings.WindowHeight = window.Height;
settings.WindowState = window.WindowState;
settings.Save();
DownloadQueueHandler.Stop();
this.Dispose();
}
/// <summary>
/// The OnLoaded.
/// </summary>
/// <param name="obj">The obj<see cref="object"/>.</param>
private void OnLoaded(object obj)
{
var (_, _, commandParameter) = (ValueTuple<object, EventArgs, object>)obj;
var settings = Properties.Settings.Default;
var window = (MainWindow)commandParameter;
window.Left = settings.WindowPosition.X;
window.Top = settings.WindowPosition.Y;
window.Width = settings.WindowWidth;
window.Height = settings.WindowHeight;
window.WindowState = settings.WindowState;
this.CefWindowData.MainWindow = window;
DownloadQueueHandler.LimitDownloads = settings.ShowMaxSimDownloads;
DownloadQueueHandler.StartWatching(settings.MaxSimDownloads);
}
/// <summary>
/// The OnPressEsc.
/// </summary>
/// <param name="obj">The obj<see cref="object"/>.</param>
private void OnPressEsc(object obj)
{
// Leave full screen.
if (this.CefWindowData.IsFullScreen)
{
this.CefWindowData.IsFullScreenCommand.Execute(false);
}
}
/// <summary>
/// The OnPressF2.
/// </summary>
/// <param name="obj">The obj<see cref="object"/>.</param>
private void OnPressF2(object obj)
{
var window = this.CefWindowData.MainWindow;
window.Width = 1022;
window.Height = 900;
}
/// <summary>
/// The ShowDownloadTabAction.
/// </summary>
private void ShowDownloadTabAction()
{
var button = this.GlobalBrowserData.GetAddInButton(typeof(DownloadQueueButton));
button?.Command.Execute(this.WebBrowserTabControlViewModel);
}
/// <summary>
/// The ShowMessageAsync.
/// </summary>
/// <param name="title">The title<see cref="string"/>.</param>
/// <param name="message">The message<see cref="string"/>.</param>
private void ShowMessageAsync(string title, string message)
{
this.CefWindowData.ShowMessageAsync(title, message);
}
#endregion Methods
}
}

View File

@@ -0,0 +1,386 @@
namespace VideoBrowser.ViewModels
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using VideoBrowser.Common;
using VideoBrowser.Controls.CefSharpBrowser.ViewModels;
using VideoBrowser.Core;
using VideoBrowser.Extensions;
using VideoBrowser.Helpers;
/// <summary>
/// Defines the <see cref="UrlEditorViewModel" />.
/// </summary>
public class UrlEditorViewModel : NotifyPropertyChanged, IDisposable
{
#region Fields
private string _duration;
private string _fileName;
private string _fileSize;
private IList<VideoFormat> _formats;
private string _imageUrl;
private bool _isBusy;
private bool _isDownloadable;
private bool _isFocused;
private bool _isFormatComboBoxVisible;
private bool _isTextBoxFocused;
private bool _isVisible;
private string _navigateUrl;
private VideoFormat _selectedFormat;
private int _selectedFormatIndex;
private string _url;
private VideoInfo _videoInfo;
#endregion Fields
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="UrlEditorViewModel"/> class.
/// </summary>
/// <param name="reader">The reader<see cref="UrlReader"/>.</param>
/// <param name="settings">The settings<see cref="Settings"/>.</param>
internal UrlEditorViewModel(UrlReader reader, SettingsViewModel settings)
{
this.UrlReader = reader;
this.UrlReader.PropertyChanged += this.OnUrlReader_PropertyChanged;
this.Settings = settings;
this.DownloadCommand = new RelayCommand(this.OnDownload);
}
#endregion Constructors
#region Properties
/// <summary>
/// Gets the DownloadCommand.
/// </summary>
public ICommand DownloadCommand { get; }
/// <summary>
/// Gets or sets the Duration.
/// </summary>
public string Duration { get => this._duration; internal set => this.Set(this.PropertyChangedHandler, ref this._duration, value); }
/// <summary>
/// Gets or sets the FileName.
/// </summary>
public string FileName { get => this._fileName; internal set => this.Set(this.PropertyChangedHandler, ref this._fileName, value); }
/// <summary>
/// Gets or sets the FileSize.
/// </summary>
public string FileSize { get => _fileSize; internal set => this.Set(this.PropertyChangedHandler, ref _fileSize, value); }
/// <summary>
/// Gets or sets the Formats.
/// </summary>
public IList<VideoFormat> Formats { get => this._formats; internal set => this.Set(this.PropertyChangedHandler, ref this._formats, value); }
/// <summary>
/// Gets the GetFolderCommand.
/// </summary>
public ICommand GetFolderCommand => this.Settings.GetFolderCommand;
/// <summary>
/// Gets or sets the ImageUrl.
/// </summary>
public string ImageUrl { get => this._imageUrl; set => this.Set(this.PropertyChangedHandler, ref this._imageUrl, value); }
/// <summary>
/// Gets or sets a value indicating whether IsBusy.
/// </summary>
public bool IsBusy { get => _isBusy; set => this.Set(this.PropertyChangedHandler, ref _isBusy, value); }
/// <summary>
/// Gets or sets a value indicating whether IsDownloadable.
/// </summary>
public bool IsDownloadable { get => _isDownloadable; set => this.Set(this.PropertyChangedHandler, ref _isDownloadable, value); }
/// <summary>
/// Gets or sets a value indicating whether IsFocused.
/// </summary>
public bool IsFocused
{
get => _isFocused;
set
{
if (_isFocused == value)
{
return;
}
_isFocused = value;
this.InvokePropertiesChanged(this.OnPropertyChanged, nameof(this.IsFocused), nameof(this.IsVisible));
}
}
/// <summary>
/// Gets or sets a value indicating whether IsFormatComboBoxVisible.
/// </summary>
public bool IsFormatComboBoxVisible { get => _isFormatComboBoxVisible; set => this.Set(this.PropertyChangedHandler, ref _isFormatComboBoxVisible, value); }
/// <summary>
/// Gets or sets a value indicating whether IsTextBoxFocused.
/// </summary>
public bool IsTextBoxFocused { get => _isTextBoxFocused; set => this.Set(this.PropertyChangedHandler, ref _isTextBoxFocused, value); }
/// <summary>
/// Gets or sets a value indicating whether IsVisible.
/// </summary>
public bool IsVisible { get => this._isVisible && this.IsFocused; internal set => this.Set(this.PropertyChangedHandler, ref this._isVisible, value); }
/// <summary>
/// Gets or sets the NavigateUrl.
/// </summary>
public string NavigateUrl
{
get => this._navigateUrl;
set
{
if (this._navigateUrl == value)
{
return;
}
this._navigateUrl = value;
this.IsDownloadable = false;
if (this.UrlReader.IsDownloadable)
{
this.IsBusy = true;
Task.Run(() =>
{
this.VideoInfo = YoutubeDl.GetVideoInfo(this.NavigateUrl);
}).ContinueWith(this.LoadVideoInfo);
}
this.IsVisible = this.UrlReader.IsDownloadable;
this.OnPropertyChanged();
}
}
/// <summary>
/// Gets or sets the NavigateUrlCommand.
/// </summary>
public ICommand NavigateUrlCommand { get; internal set; }
/// <summary>
/// Gets or sets the SelectedFormat.
/// </summary>
public VideoFormat SelectedFormat
{
get => this._selectedFormat;
set
{
if (!this.Set(this.PropertyChangedHandler, ref this._selectedFormat, value))
{
return;
}
this.UpdateFileSize();
}
}
/// <summary>
/// Gets or sets the SelectedFormatIndex.
/// </summary>
public int SelectedFormatIndex { get => _selectedFormatIndex; set => this.Set(this.PropertyChangedHandler, ref _selectedFormatIndex, value); }
/// <summary>
/// Gets the Settings.
/// </summary>
public SettingsViewModel Settings { get; }
/// <summary>
/// Gets or sets the Url.
/// </summary>
public string Url { get => this._url; set => this.Set(this.PropertyChangedHandler, ref this._url, value); }
/// <summary>
/// Gets the UrlReader.
/// </summary>
public UrlReader UrlReader { get; }
/// <summary>
/// Gets or sets the VideoInfo.
/// </summary>
public VideoInfo VideoInfo
{
get => this._videoInfo;
set
{
if (this.VideoInfo != null)
{
this.VideoInfo.FileSizeUpdated -= this.OnVideoInfo_FileSizeUpdated;
}
this.Set(this.PropertyChangedHandler, ref this._videoInfo, value);
}
}
/// <summary>
/// Gets or sets the DownloadAction.
/// </summary>
internal Action<Operation> DownloadAction { get; set; }
/// <summary>
/// Gets or sets the ShowMessageAsyncAction.
/// </summary>
internal Action<string, string> ShowMessageAsyncAction { get; set; }
#endregion Properties
#region Methods
/// <summary>
/// The Dispose.
/// </summary>
public void Dispose()
{
this.UrlReader.PropertyChanged -= this.OnUrlReader_PropertyChanged;
}
/// <summary>
/// The LoadVideoInfo.
/// </summary>
/// <param name="task">The task<see cref="Task"/>.</param>
private void LoadVideoInfo(Task task)
{
this.IsBusy = false;
this.IsFocused = true;
this.IsTextBoxFocused = true;
this.IsDownloadable = false;
this.IsFormatComboBoxVisible = false;
if (this.VideoInfo.RequiresAuthentication)
{
////var auth = Dialogs.LoginDialog.Show(this);
}
else if (this.VideoInfo.Failure)
{
var message = "Couldn't retrieve video. Reason:\n\n" + this.VideoInfo.FailureReason;
this.ShowMessageAsyncAction.Invoke("The Video Not Downloadable", message);
Logger.Info(message);
return;
}
else
{
this.FileName = YoutubeHelper.FormatTitle(this.VideoInfo.Title);
this.VideoInfo.FileSizeUpdated += this.OnVideoInfo_FileSizeUpdated;
this.Duration = this.VideoInfo.Duration.FormatVideoLength();
this.Formats = YoutubeHelper.CheckFormats(this.VideoInfo.Formats);
this.ImageUrl = this.VideoInfo.ThumbnailUrl;
if (this.Formats.Any())
{
this.SelectedFormatIndex = this.Formats.Count - 1;
}
else
{
return;
}
}
this.IsFormatComboBoxVisible = this.VideoInfo.Formats.Count > 0;
this.IsDownloadable = true;
Properties.Settings.Default.LastUrl = this.NavigateUrl;
}
/// <summary>
/// The OnDownload.
/// </summary>
/// <param name="o">The o<see cref="object"/>.</param>
private void OnDownload(object o)
{
var format = this.SelectedFormat;
var formatTitle = format.AudioOnly ? format.AudioBitRate.ToString() : format.Format.ToString();
this.FileName = FileHelper.GetValidFilename(this.FileName);
var fileName = $"{this.FileName}-{formatTitle}.{format.Extension}";
var output = Path.Combine(this.Settings.OutputFolder, fileName);
if (File.Exists(output))
{
var message = $@"File ""{fileName}"" is already downloaded. If it was failed, delete it and try again.";
this.ShowMessageAsyncAction("Download Canceled", message);
return;
}
DownloadOperation operation = format.AudioOnly || format.HasAudioAndVideo
? new DownloadOperation(format, output)
: new DownloadOperation(format, YoutubeHelper.GetAudioFormat(format), output);
Task.Run(() => this.DownloadAction?.Invoke(operation));
}
/// <summary>
/// The OnUrlReader_PropertyChanged.
/// </summary>
/// <param name="sender">The sender<see cref="object"/>.</param>
/// <param name="e">The e<see cref="PropertyChangedEventArgs"/>.</param>
private void OnUrlReader_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(this.UrlReader.IsDownloadable):
break;
}
}
/// <summary>
/// The OnVideoInfo_FileSizeUpdated.
/// </summary>
/// <param name="sender">The sender<see cref="object"/>.</param>
/// <param name="e">The e<see cref="FileSizeUpdateEventArgs"/>.</param>
private void OnVideoInfo_FileSizeUpdated(object sender, FileSizeUpdateEventArgs e)
{
this.FileSize = FormatString.FormatFileSize(e.VideoFormat.FileSize);
}
/// <summary>
/// The UpdateFileSize.
/// </summary>
private void UpdateFileSize()
{
if (this.SelectedFormat == null)
{
this.FileSize = "Unkown size";
}
else if (this.SelectedFormat.FileSize == 0)
{
this.FileSize = "Getting file size...";
}
else
{
var total = this.SelectedFormat.FileSize;
// If the format is VideoOnly, combine audio and video size.
if (this.SelectedFormat.VideoOnly)
{
total += YoutubeHelper.GetAudioFormat(this.SelectedFormat).FileSize;
}
this.FileSize = FormatString.FormatFileSize(total);
}
}
#endregion Methods
}
}

View File

@@ -0,0 +1,41 @@
namespace VideoBrowser.ViewModels
{
using System.Windows.Media;
using VideoBrowser.Common;
using VideoBrowser.Extensions;
using VideoBrowser.Models;
using VideoBrowser.Resources;
/// <summary>
/// Defines the <see cref="VideoViewModel" />
/// </summary>
public class VideoViewModel : NotifyPropertyChanged
{
#region Fields
private double _downloadProgress;
private Video _video;
#endregion Fields
#region Properties
/// <summary>
/// Gets or sets the DownloadProgress
/// </summary>
public double DownloadProgress { get => this._downloadProgress; set => this.Set(this.PropertyChangedHandler, ref this._downloadProgress, value); }
/// <summary>
/// Gets or sets the Icon
/// </summary>
public Geometry Icon { get; set; } = Icons.SearchVideo;
/// <summary>
/// Gets or sets the Video
/// </summary>
public Video Video { get => this._video; set => this.Set(this.PropertyChangedHandler, ref this._video, value); }
#endregion Properties
}
}