Archived
1
0
This repository has been archived on 2026-04-22. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
FoxTube/FoxTube/Controls/DownloadItem.xaml.cs
T
2018-10-24 21:07:08 +03:00

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();
}
}
}
}