Archived
1
0
This commit is contained in:
Michael Gordeev
2018-12-12 21:15:38 +03:00
parent aa3214cc60
commit 1105460cae
11 changed files with 179 additions and 88 deletions
+11 -7
View File
@@ -12,6 +12,7 @@ using Windows.ApplicationModel.Background;
using Windows.ApplicationModel.Core;
using Windows.Globalization;
using Windows.Storage;
using Windows.System;
using Windows.System.Power;
using Windows.UI.Notifications;
using Windows.UI.Popups;
@@ -161,11 +162,6 @@ namespace FoxTube
switch(arguments[0])
{
case "dcancel":
Debug.WriteLine("Cancel has been required");
try { Methods.MainPage.Agent.Remove(arguments[1]); }
catch { }
break;
case "later":
try
{
@@ -194,6 +190,9 @@ namespace FoxTube
Debug.WriteLine(e.Message);
}
break;
case "download":
await Launcher.LaunchFileAsync(await StorageFile.GetFileFromPathAsync(arguments[1]));
break;
}
}
}
@@ -237,6 +236,12 @@ namespace FoxTube
case "channel":
Methods.MainPage.GoToChannel(args[1]);
break;
case "download":
Methods.MainPage.GoToDownloads();
break;
case "dcancel":
DownloadAgent.Remove(args[1]);
break;
}
}
@@ -273,8 +278,7 @@ namespace FoxTube
await ApplicationData.Current.RoamingFolder.CreateFileAsync("watchlater.json", CreationCollisionOption.ReplaceExisting),
JsonConvert.SerializeObject(SecretsVault.WatchLater));*/
//Saving downloads
Methods.MainPage.Agent.QuitPrompt();
ToastNotificationManager.CreateToastNotifier().Show(Background.Notification.GetInternalToast(null, "All data saved", "", null, null));
DownloadAgent.QuitPrompt();
deferral.Complete();
}
}
+39 -33
View File
@@ -1,70 +1,76 @@
using System;
using System.Collections.Generic;
using System.IO;
using Windows.Storage;
using FoxTube.Classes;
using Newtonsoft.Json;
using Windows.UI.Popups;
using YoutubeExplode.Models.MediaStreams;
using Google.Apis.YouTube.v3.Data;
using Windows.Foundation;
using System.Diagnostics;
using FoxTube.Controls;
namespace FoxTube.Controls
namespace FoxTube
{
public class DownloadAgent
public static class DownloadAgent
{
public List<DownloadItem> items = new List<DownloadItem>();
StorageFolder roaming = ApplicationData.Current.RoamingFolder;
public IAsyncOperation<IUICommand> prompt;
public DownloadAgent()
{
Initialize();
Windows.UI.Core.Preview.SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += (s, a) => QuitPrompt();
}
public static List<DownloadItem> items = new List<DownloadItem>();
private static ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
public static StorageFolder Downloads { get; set; }
public async void Initialize()
public static async void Initialize()
{
Downloads = await KnownFolders.VideosLibrary.CreateFolderAsync("FoxTube", CreationCollisionOption.OpenIfExists);
try
{
List<DownloadItemContainer> containers = JsonConvert.DeserializeObject<List<DownloadItemContainer>>(await FileIO.ReadTextAsync(await roaming.GetFileAsync("downloads.json")));
foreach (DownloadItemContainer i in containers)
try { items.Add(new DownloadItem(i)); }
catch (FileNotFoundException) { }
List<DownloadItemContainer> containers = JsonConvert.DeserializeObject<List<DownloadItemContainer>>((string)settings.Values["downloads"]);
containers.ForEach(i => items.Add(new DownloadItem(i)));
}
catch { }
}
public void Add(MediaStreamInfo info, Video meta, string qualty)
public static void Add(MediaStreamInfo info, Video meta, string qualty)
{
items.Add(new DownloadItem(info, meta, qualty));
items.Insert(0, new DownloadItem(info, meta, qualty));
}
public void Remove(string id)
public static void CancelItem(string id)
{
DownloadItem item = items.Find(x => x.Container.Id == id);
if (item == null || !item.InProgress)
return;
item.CancelPrompt();
}
public static void Remove(string id)
{
DownloadItem item = items.Find(x => x.Container.Id == id);
if (item == null)
return;
if (item.InProgress)
item.cancel_Click(this, null);
else
item.Cancel();
else
items.Remove(item);
}
public async void QuitPrompt()
public static void QuitPrompt()
{
foreach (DownloadItem i in items.FindAll(x => x.InProgress))
foreach (DownloadItem i in items.FindAll(i => i.InProgress))
i.Cancel();
items.RemoveAll(x => x.InProgress);
List<DownloadItemContainer> containers = new List<DownloadItemContainer>();
foreach (DownloadItem i in items)
containers.Add(i.Container);
items.ForEach(i => containers.Add(i.Container));
await FileIO.WriteTextAsync(
await roaming.CreateFileAsync("downloads.json", CreationCollisionOption.ReplaceExisting),
JsonConvert.SerializeObject(containers));
string data = JsonConvert.SerializeObject(containers);
try
{
settings.Values["downloads"] = data;
}
catch
{
settings.Values.Add("downloads", data);
}
}
}
}
+2 -2
View File
@@ -8,10 +8,10 @@ namespace FoxTube.Classes
public string Title { get; set; }
public string Channel { get; set; }
public string Id { get; set; }
public Uri Path => File.Path.ToUri();
public string Name { get; set; }
public string Extension { get; set; }
public Uri Thumbnail { get; set; }
public string Quality { get; set; }
public TimeSpan Duration { get; set; }
public StorageFile File { get; set; }
}
}
+2 -2
View File
@@ -20,7 +20,7 @@
</Grid.ColumnDefinitions>
<Image Name="thumbnail" Source="/Assets/videoThumbSample.png"/>
<TextBlock Name="title" Grid.Column="1" Margin="5" TextWrapping="WrapWholeWords" Text="[Title]" FontSize="20" MaxLines="2"/>
<TextBlock Margin="5" Name="path" Grid.Column="1" VerticalAlignment="Bottom" Text="C://Users/Michael Gordeev/Downloads/[Title].mp4" Foreground="LightGray"/>
<TextBlock Margin="5" Name="path" Grid.Column="1" VerticalAlignment="Bottom" Text="C://Users/Michael Gordeev/Downloads/[Title].mp4" Foreground="LightGray" MaxLines="1" TextWrapping="WrapWholeWords"/>
<StackPanel Grid.Column="2" Margin="5">
<TextBlock Text="Extension:" Foreground="Gray" Name="ext"/>
@@ -47,7 +47,7 @@
<TextBlock Name="status" Text="Initializing..." HorizontalAlignment="Left"/>
<ProgressBar Name="progressBar" Width="200" Maximum="1" IsIndeterminate="True" Foreground="Red"/>
<TextBlock Name="perc" Text="--%"/>
<Button Content="Cancel" Name="cancel" Click="cancel_Click" HorizontalAlignment="Right"/>
<Button Content="Cancel" Name="cancel" Click="CancelPrompt" HorizontalAlignment="Right"/>
</StackPanel>
</Grid>
</UserControl>
+42 -28
View File
@@ -15,19 +15,17 @@ using Windows.UI.Popups;
using Windows.Storage.Pickers;
using Windows.UI.Notifications;
using Microsoft.Toolkit.Uwp.Notifications;
using Windows.Foundation;
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
using System.Diagnostics;
namespace FoxTube.Controls
{
public sealed partial class DownloadItem : UserControl
{
public DownloadItemContainer Container { get; private set; }
public StorageFile file;
public bool InProgress { get; set; } = false;
YoutubeClient client = new YoutubeClient();
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token;
@@ -45,17 +43,28 @@ namespace FoxTube.Controls
this.InitializeComponent();
Container = container;
if (!File.Exists(container.Path.AbsolutePath))
Initialize();
}
public async void Initialize()
{
try
{
Methods.MainPage.Agent.Remove(Container.Id);
file = await DownloadAgent.Downloads.GetFileAsync(Container.Name);
}
catch
{
DownloadAgent.Remove(Container.Id);
return;
}
title.Text = Container.Title;
path.Text = file.Name;
thumbnail.Source = new BitmapImage(Container.Thumbnail);
quality.Text = $"Quality: {Container.Quality}";
duration.Text = $"Duration: {Container.Duration}";
channel.Text = $"Author: {Container.Channel}";
ext.Text = $"Extension: {Container.Extension}";
progressPanel.Visibility = Visibility.Collapsed;
donePanel.Visibility = Visibility.Visible;
@@ -66,20 +75,11 @@ namespace FoxTube.Controls
InProgress = true;
Container = new DownloadItemContainer();
token = new CancellationTokenSource().Token;
token = cts.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);
file = await DownloadAgent.Downloads.CreateFileAsync($"{meta.Snippet.Title.ReplaceInvalidChars('_')}.{info.Container.GetFileExtension()}", CreationCollisionOption.GenerateUniqueName);
Container.Name = file.Name;
ToastContent toastContent = new ToastContent()
{
@@ -123,6 +123,7 @@ namespace FoxTube.Controls
Container.Quality = q;
Container.Thumbnail = meta.Snippet.Thumbnails.Medium.Url.ToUri();
Container.Title = meta.Snippet.Title;
Container.Extension = info.Container.GetFileExtension();
thumbnail.Source = new BitmapImage(new Uri(meta.Snippet.Thumbnails.Medium.Url));
title.Text = meta.Snippet.Title;
@@ -130,19 +131,20 @@ namespace FoxTube.Controls
quality.Text = $"Quality: {q}";
duration.Text = $"Duration: {XmlConvert.ToTimeSpan(meta.ContentDetails.Duration)}";
channel.Text = $"Author: {meta.Snippet.ChannelTitle}";
path.Text = Container.File.Path;
path.Text = file.Name;
progressPanel.Visibility = Visibility.Visible;
donePanel.Visibility = Visibility.Collapsed;
await client.DownloadMediaStreamAsync(info, await Container.File.OpenStreamForWriteAsync(), progress, token);
DownloadCompleted();
await client.DownloadMediaStreamAsync(info, await file.OpenStreamForWriteAsync(), progress, token);
progressPanel.Visibility = Visibility.Collapsed;
donePanel.Visibility = Visibility.Visible;
InProgress = false;
if(!cts.IsCancellationRequested)
DownloadCompleted();
}
private void UpdateInfo(object sender, double e)
@@ -158,7 +160,7 @@ namespace FoxTube.Controls
private void DownloadCompleted()
{
Windows.Data.Xml.Dom.XmlDocument template = new Windows.Data.Xml.Dom.XmlDocument();
template.LoadXml($@"<toast activationType='background' launch='download|{Container.Id}'>
template.LoadXml($@"<toast activationType='background' launch='download|{file.Path}'>
<visual>
<binding template='ToastGeneric'>
<text>Download complete</text>
@@ -177,7 +179,7 @@ namespace FoxTube.Controls
private async void open_Click(object sender, RoutedEventArgs e)
{
await Launcher.LaunchFileAsync(Container.File);
await Launcher.LaunchFileAsync(file);
}
private void gotoOriginal_Click(object sender, RoutedEventArgs e)
@@ -193,13 +195,25 @@ namespace FoxTube.Controls
cts.Cancel();
try
{
await Container.File.DeleteAsync();
await file.DeleteAsync();
}
catch { }
Methods.MainPage.Agent.Remove(Container.Id);
Windows.Data.Xml.Dom.XmlDocument template = new Windows.Data.Xml.Dom.XmlDocument();
template.LoadXml($@"<toast activationType='foreground' launch='download'>
<visual>
<binding template='ToastGeneric'>
<text>Download canceled</text>
<text>{Container.Title}</text>
</binding>
</visual>
</toast>");
ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(template) { Tag = $"download|{Container.Id}" });
DownloadAgent.Remove(Container.Id);
}
public async void cancel_Click(object sender, RoutedEventArgs e)
public async void CancelPrompt(object sender = null, RoutedEventArgs e = null)
{
if(InProgress)
{
+11
View File
@@ -51,4 +51,15 @@
</Grid>
</Grid>
</Button>
<UserControl.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem Icon="Play" Text="Play"/>
<MenuFlyoutItem Icon="Contact" Text="View channel"/>
<MenuFlyoutSeparator/>
<MenuFlyoutItem Icon="Link" Text="Copy link"/>
<MenuFlyoutItem Icon="Share" Text="Share"/>
<MenuFlyoutSeparator/>
<MenuFlyoutItem Icon="Download" Text="Download"/>
</MenuFlyout>
</UserControl.ContextFlyout>
</UserControl>
+3 -1
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" IgnorableNamespaces="uap mp uap3">
<Identity Name="foxtube-5d1cba1f-d7d5-472b-acb7-beb360bab268" Publisher="CN=XFox" Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="5d1cba1f-d7d5-472b-acb7-beb360bab268" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
@@ -41,5 +41,7 @@
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<uap3:Capability Name="backgroundMediaPlayback" />
<uap:Capability Name="videosLibrary" />
</Capabilities>
</Package>
+25 -5
View File
@@ -9,9 +9,29 @@
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ScrollViewer>
<StackPanel>
<ItemsControl Name="stack"/>
</StackPanel>
</ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock Name="path" IsTextSelectionEnabled="True" TextWrapping="WrapWholeWords"/>
<Button Grid.Column="1" Content="Open folder" Name="open" Click="Open_Click" VerticalAlignment="Center"/>
</Grid>
<ScrollViewer Grid.Row="1">
<StackPanel Name="stack"/>
</ScrollViewer>
<TextBlock Grid.Row="1" Name="empty" HorizontalAlignment="Center" VerticalAlignment="Top" FontSize="28" Text="You haven't downloaded anything yet" Margin="10" TextWrapping="WrapWholeWords" Foreground="Gray" FontWeight="SemiBold"/>
<CommandBar DefaultLabelPosition="Right" Grid.Row="2">
<AppBarButton Label="Refresh" Icon="Refresh" Click="Refresh"/>
</CommandBar>
</Grid>
</Page>
+35 -7
View File
@@ -25,18 +25,46 @@ namespace FoxTube.Pages
public Downloads()
{
this.InitializeComponent();
try
{
stack.ItemsSource = Methods.MainPage.Agent.items;
}
catch { }
SetPath();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
stack.ItemsSource = null;
stack.Items.Clear();
stack.Children.Clear();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
DownloadAgent.items.ForEach(i =>
{
stack.Children.Add(i);
i.Initialize();
});
empty.Visibility = stack.Children.Count > 0 ? Visibility.Collapsed : Visibility.Visible;
}
void SetPath()
{
path.Text = DownloadAgent.Downloads.Path;
}
void Refresh(object sender, RoutedEventArgs e)
{
stack.Children.Clear();
DownloadAgent.items.ForEach(i =>
{
stack.Children.Add(i);
i.Initialize();
});
empty.Visibility = stack.Children.Count > 0 ? Visibility.Collapsed : Visibility.Visible;
}
private async void Open_Click(object sender, RoutedEventArgs e)
{
await Launcher.LaunchFolderAsync(DownloadAgent.Downloads);
}
/*private async void changePath_Click(object sender, RoutedEventArgs e)
+8 -2
View File
@@ -39,8 +39,6 @@ namespace FoxTube
public sealed partial class MainPage : Page
{
public DownloadAgent Agent = new DownloadAgent();
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
Sender s = Sender.None;
@@ -96,6 +94,9 @@ namespace FoxTube
SecretsVault.NotPurchased += () => removeAds.Visibility = Visibility.Visible;
SecretsVault.CheckAuthorization();
SecretsVault.CheckAddons();
DownloadAgent.Initialize();
SetTitleBar();
Initialize();
}
@@ -362,6 +363,11 @@ namespace FoxTube
content.Navigate(typeof(PlaylistPage), id);
}
public void GoToDownloads()
{
content.Navigate(typeof(Downloads));
}
private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (videoPlaceholder.Content != null)
+1 -1
View File
@@ -266,7 +266,7 @@ namespace FoxTube.Pages
private void downloadItemSelected(object sender, RoutedEventArgs e)
{
Methods.MainPage.Agent.Add(((sender as MenuFlyoutItem).Tag as object[])[0] as MediaStreamInfo, item, ((sender as MenuFlyoutItem).Tag as object[])[1] as string);
DownloadAgent.Add(((sender as MenuFlyoutItem).Tag as object[])[0] as MediaStreamInfo, item, ((sender as MenuFlyoutItem).Tag as object[])[1] as string);
}
async void LoadRelatedVideos()