214 lines
8.1 KiB
C#
214 lines
8.1 KiB
C#
using System;
|
|
using System.IO;
|
|
using Windows.UI.Xaml;
|
|
using Windows.UI.Xaml.Controls;
|
|
using System.Net;
|
|
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;
|
|
using Windows.UI.Notifications;
|
|
using Microsoft.Toolkit.Uwp.Notifications;
|
|
|
|
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
|
|
|
|
namespace FoxTube.Controls
|
|
{
|
|
public sealed partial class DownloadItem : UserControl
|
|
{
|
|
public DownloadItemContainer Container { get; private set; }
|
|
public bool InProgress { get; set; } = false;
|
|
|
|
YoutubeClient client = new YoutubeClient();
|
|
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
|
|
|
CancellationTokenSource cts = new CancellationTokenSource();
|
|
CancellationToken token;
|
|
Progress<double> progress = new Progress<double>();
|
|
NotificationData data = new NotificationData();
|
|
|
|
public DownloadItem(MediaStreamInfo info, Video meta, string q)
|
|
{
|
|
this.InitializeComponent();
|
|
Download(info, meta, q);
|
|
}
|
|
|
|
public DownloadItem(DownloadItemContainer container)
|
|
{
|
|
this.InitializeComponent();
|
|
|
|
Container = container;
|
|
if (!File.Exists(container.Path.AbsolutePath))
|
|
{
|
|
Methods.MainPage.Agent.Remove(Container.Id);
|
|
return;
|
|
}
|
|
|
|
title.Text = Container.Title;
|
|
thumbnail.Source = new BitmapImage(Container.Thumbnail);
|
|
quality.Text = $"Quality: {Container.Quality}";
|
|
duration.Text = $"Duration: {Container.Duration}";
|
|
channel.Text = $"Author: {Container.Channel}";
|
|
|
|
progressPanel.Visibility = Visibility.Collapsed;
|
|
donePanel.Visibility = Visibility.Visible;
|
|
}
|
|
|
|
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);
|
|
|
|
ToastContent toastContent = new ToastContent()
|
|
{
|
|
Visual = new ToastVisual()
|
|
{
|
|
BindingGeneric = new ToastBindingGeneric()
|
|
{
|
|
Children =
|
|
{
|
|
new AdaptiveText() { Text = "Downloading a video" },
|
|
new AdaptiveProgressBar()
|
|
{
|
|
Title = meta.Snippet.Title,
|
|
Status = "Downloading...",
|
|
Value = new BindableProgressBarValue("value")
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
Actions = new ToastActionsCustom()
|
|
{
|
|
Buttons =
|
|
{
|
|
new ToastButton("Cancel", $"dcancel|{Container.Id}")
|
|
{
|
|
ActivationType = ToastActivationType.Background
|
|
}
|
|
}
|
|
},
|
|
Launch = "download",
|
|
ActivationType = ToastActivationType.Foreground
|
|
};
|
|
|
|
data.Values["value"] = "0";
|
|
ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(toastContent.GetXml()) { Tag = $"download|{meta.Id}", Data = data });
|
|
|
|
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);
|
|
|
|
DownloadCompleted();
|
|
|
|
progressPanel.Visibility = Visibility.Collapsed;
|
|
donePanel.Visibility = Visibility.Visible;
|
|
|
|
InProgress = false;
|
|
}
|
|
|
|
private void UpdateInfo(object sender, double e)
|
|
{
|
|
status.Text = "Downloading";
|
|
progressBar.Value = e;
|
|
perc.Text = $"{(int)e * 100}%";
|
|
|
|
data.Values["value"] = e.ToString();
|
|
ToastNotificationManager.CreateToastNotifier().Update(data, $"download|{Container.Id}");
|
|
}
|
|
|
|
private void DownloadCompleted()
|
|
{
|
|
Windows.Data.Xml.Dom.XmlDocument template = new Windows.Data.Xml.Dom.XmlDocument();
|
|
template.LoadXml($@"<toast activationType='background' launch='download|{Container.Id}'>
|
|
<visual>
|
|
<binding template='ToastGeneric'>
|
|
<text>Download complete</text>
|
|
<text>{Container.Title}</text>
|
|
</binding>
|
|
</visual>
|
|
|
|
<actions>
|
|
<action content='Go to original'
|
|
activationType='foreground'
|
|
arguments='video|{Container.Id}'/>
|
|
</actions>
|
|
</toast>");
|
|
ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(template) { Tag = $"download|{Container.Id}" });
|
|
}
|
|
|
|
private async void open_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
await Launcher.LaunchFileAsync(Container.File);
|
|
}
|
|
|
|
private void gotoOriginal_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
Methods.MainPage.GoToVideo(Container.Id);
|
|
}
|
|
|
|
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 async void cancel_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if(InProgress)
|
|
{
|
|
MessageDialog dialog = new MessageDialog("Are you sure?", "Cancelling download");
|
|
|
|
dialog.Commands.Add(new UICommand("Yes", (command) => Cancel()));
|
|
dialog.Commands.Add(new UICommand("No"));
|
|
|
|
dialog.DefaultCommandIndex = 1;
|
|
await dialog.ShowAsync();
|
|
}
|
|
}
|
|
}
|
|
}
|