diff --git a/FoxTube/Classes/DownloadAgent.cs b/FoxTube/Classes/DownloadAgent.cs index af7a334..9484c8e 100644 --- a/FoxTube/Classes/DownloadAgent.cs +++ b/FoxTube/Classes/DownloadAgent.cs @@ -5,6 +5,8 @@ using Windows.Storage; using FoxTube.Classes; using Newtonsoft.Json; using Windows.UI.Popups; +using YoutubeExplode.Models.MediaStreams; +using Google.Apis.YouTube.v3.Data; namespace FoxTube.Controls { @@ -32,14 +34,14 @@ namespace FoxTube.Controls catch { } } - public void Add(string url) + public void Add(MediaStreamInfo info, Video meta, string qualty) { - items.Add(new DownloadItem(url)); + items.Add(new DownloadItem(info, meta, qualty)); } - private void Item_DownloadCanceled(object sender, params object[] e) + public void Remove(string id) { - items.Remove(sender as DownloadItem); + items.Remove(items.Find(x => x.Container.Id == id)); } public async void QuitPrompt() diff --git a/FoxTube/Classes/DownloadItemContainer.cs b/FoxTube/Classes/DownloadItemContainer.cs index f7e6fe2..05dcdbb 100644 --- a/FoxTube/Classes/DownloadItemContainer.cs +++ b/FoxTube/Classes/DownloadItemContainer.cs @@ -1,5 +1,5 @@ using System; -using YoutubeExplode.Models.MediaStreams; +using Windows.Storage; namespace FoxTube.Classes { @@ -8,9 +8,10 @@ namespace FoxTube.Classes public string Title { get; set; } public string Channel { get; set; } public string Id { get; set; } - public Uri Path { get; set; } + public Uri Path => File.Path.ToUri(); public Uri Thumbnail { get; set; } - public VideoQuality Quality { get; set; } + public string Quality { get; set; } public TimeSpan Duration { get; set; } + public StorageFile File { get; set; } } } diff --git a/FoxTube/Classes/Methods.cs b/FoxTube/Classes/Methods.cs index f7fa11e..b893da2 100644 --- a/FoxTube/Classes/Methods.cs +++ b/FoxTube/Classes/Methods.cs @@ -1,6 +1,8 @@ using Google.Apis.YouTube.v3; using System; +using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Text.RegularExpressions; using System.Web; using Windows.ApplicationModel.Core; @@ -31,6 +33,18 @@ namespace FoxTube return new Uri(url); } + public static string ReplaceInvalidChars(this string str, char newValue) + { + foreach (char i in Path.GetInvalidFileNameChars()) + str = str.Replace(i, newValue); + return str; + } + + public static string Last(this string[] arr) + { + return arr[arr.Length - 1]; + } + public static string GetAgo(DateTime dateTime) { TimeSpan span = DateTime.Now - dateTime; diff --git a/FoxTube/Controls/DownloadItem.xaml b/FoxTube/Controls/DownloadItem.xaml index 212cb5c..720434e 100644 --- a/FoxTube/Controls/DownloadItem.xaml +++ b/FoxTube/Controls/DownloadItem.xaml @@ -10,7 +10,7 @@ d:DesignWidth="1500"> - + @@ -19,10 +19,11 @@ - + + - + diff --git a/FoxTube/Controls/DownloadItem.xaml.cs b/FoxTube/Controls/DownloadItem.xaml.cs index a23e6e5..20a308a 100644 --- a/FoxTube/Controls/DownloadItem.xaml.cs +++ b/FoxTube/Controls/DownloadItem.xaml.cs @@ -7,6 +7,14 @@ using Windows.UI.Xaml.Media.Imaging; using Windows.System; using FoxTube.Classes; using YoutubeExplode.Models.MediaStreams; +using YoutubeExplode; +using Windows.Storage; +using Google.Apis.YouTube.v3.Data; +using System.Threading; +using System.Xml; +using Windows.UI.Popups; +using Windows.Storage.Pickers; +using System.Diagnostics; // The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 @@ -16,11 +24,18 @@ namespace FoxTube.Controls { public DownloadItemContainer Container { get; private set; } public bool InProgress { get; set; } = false; - - public DownloadItem(string url) + + YoutubeClient client = new YoutubeClient(); + ApplicationDataContainer settings = ApplicationData.Current.LocalSettings; + + CancellationTokenSource cts = new CancellationTokenSource(); + CancellationToken token; + Progress progress = new Progress(); + + public DownloadItem(MediaStreamInfo info, Video meta, string q) { this.InitializeComponent(); - Download(url); + Download(info, meta, q); } public DownloadItem(DownloadItemContainer container) @@ -29,11 +44,14 @@ namespace FoxTube.Controls Container = container; if (!File.Exists(container.Path.AbsolutePath)) - throw new FileNotFoundException(); + { + Methods.MainPage.Agent.Remove(Container.Id); + return; + } title.Text = Container.Title; thumbnail.Source = new BitmapImage(Container.Thumbnail); - quality.Text = $"Quality: {Container.Quality.GetVideoQualityLabel()}"; + quality.Text = $"Quality: {Container.Quality}"; duration.Text = $"Duration: {Container.Duration}"; channel.Text = $"Author: {Container.Channel}"; @@ -41,41 +59,71 @@ namespace FoxTube.Controls donePanel.Visibility = Visibility.Visible; } - void Download(string url) + async void Download(MediaStreamInfo info, Video meta, string q) { + InProgress = true; + Container = new DownloadItemContainer(); + + token = new CancellationTokenSource().Token; + progress.ProgressChanged += UpdateInfo; + + FolderPicker picker = new FolderPicker() + { + SuggestedStartLocation = PickerLocationId.Downloads, + ViewMode = PickerViewMode.Thumbnail + }; + picker.FileTypeFilter.Add(".shit"); //Because overwise it trhows an exception + + StorageFolder folder = await picker.PickSingleFolderAsync(); + if (folder == null) + Cancel(); + Container.File = await folder.CreateFileAsync($"{meta.Snippet.Title.ReplaceInvalidChars('_')}.{info.Container.GetFileExtension()}", CreationCollisionOption.GenerateUniqueName); + + //TO-DO: Create toast + + Container.Channel = meta.Snippet.ChannelTitle; + Container.Duration = XmlConvert.ToTimeSpan(meta.ContentDetails.Duration); + Container.Id = meta.Id; + Container.Quality = q; + Container.Thumbnail = meta.Snippet.Thumbnails.Medium.Url.ToUri(); + Container.Title = meta.Snippet.Title; + + thumbnail.Source = new BitmapImage(new Uri(meta.Snippet.Thumbnails.Medium.Url)); + title.Text = meta.Snippet.Title; + ext.Text = $"Extension: {info.Container.GetFileExtension()}"; + quality.Text = $"Quality: {q}"; + duration.Text = $"Duration: {XmlConvert.ToTimeSpan(meta.ContentDetails.Duration)}"; + channel.Text = $"Author: {meta.Snippet.ChannelTitle}"; + path.Text = Container.File.Path; + + progressPanel.Visibility = Visibility.Visible; + donePanel.Visibility = Visibility.Collapsed; + await client.DownloadMediaStreamAsync(info, await Container.File.OpenStreamForWriteAsync(), progress, token); + + progressPanel.Visibility = Visibility.Collapsed; + donePanel.Visibility = Visibility.Visible; + + InProgress = false; } - private void UpdateInfo(object sender, DownloadProgressChangedEventArgs e) + private void UpdateInfo(object sender, double e) { - progressBar.Value = e.ProgressPercentage; - perc.Text = $"{e.ProgressPercentage}%"; + status.Text = "Downloading"; + progressBar.Value = e; + perc.Text = $"{(int)e}%"; + + //TO-DO: Update toast } private void DownloadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) { - /*progressPanel.Visibility = Visibility.Collapsed; - donePanel.Visibility = Visibility.Visible; - - string node = $@" - - - {quality.Text.Split(' ')[1]} - {duration.Text.Split(' ')[1]} - {channel.Text.Split(' ')[1]} - -
- {uri} - {Id} -
-
"; - - DownloadComplete.Invoke(this, node);*/ + //TO-DO: Update toast } private async void open_Click(object sender, RoutedEventArgs e) { - await Launcher.LaunchUriAsync(Container.Path); + await Launcher.LaunchFileAsync(Container.File); } private void gotoOriginal_Click(object sender, RoutedEventArgs e) @@ -83,30 +131,28 @@ namespace FoxTube.Controls Methods.MainPage.GoToVideo(Container.Id); } - public void Cancel() + public async void Cancel() { - + status.Text = "Cancelling..."; + progressBar.IsIndeterminate = true; + cancel.IsEnabled = false; + cts.Cancel(); + await Container.File.DeleteAsync(); + Methods.MainPage.Agent.Remove(Container.Id); } - private void cancel_Click(object sender, RoutedEventArgs e) + private async void cancel_Click(object sender, RoutedEventArgs e) { - /*if(client.IsBusy) + if(InProgress) { MessageDialog dialog = new MessageDialog("Are you sure?", "Cancelling download"); - dialog.Commands.Add(new UICommand("Yes", (command) => - { - status.Text = "Cancelling..."; - progressBar.IsIndeterminate = true; - cancel.IsEnabled = false; - client.CancelAsync(); - DownloadCanceled.Invoke(this, null); - })); + dialog.Commands.Add(new UICommand("Yes", (command) => Cancel())); dialog.Commands.Add(new UICommand("No")); dialog.DefaultCommandIndex = 1; await dialog.ShowAsync(); - }*/ + } } } } diff --git a/FoxTube/FoxTube.csproj b/FoxTube/FoxTube.csproj index 52e3fc3..9961956 100644 --- a/FoxTube/FoxTube.csproj +++ b/FoxTube/FoxTube.csproj @@ -431,9 +431,6 @@ 4.3.2 - - 1.2.0 - 4.4.0 diff --git a/FoxTube/Pages/Downloads.xaml b/FoxTube/Pages/Downloads.xaml index d6ca56f..aa5ccd0 100644 --- a/FoxTube/Pages/Downloads.xaml +++ b/FoxTube/Pages/Downloads.xaml @@ -9,28 +9,9 @@ mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> - - - - - + - - - - - - - -