DownloadAgent
This commit is contained in:
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml;
|
||||||
|
using Windows.ApplicationModel.Background;
|
||||||
|
using Windows.Storage;
|
||||||
|
using Windows.UI.Notifications;
|
||||||
|
|
||||||
|
namespace FoxTube.Background
|
||||||
|
{
|
||||||
|
public sealed class BackgroundProcessor : IBackgroundTask
|
||||||
|
{
|
||||||
|
public List<Notification> Notifications = new List<Notification>();
|
||||||
|
|
||||||
|
private DateTime lastCheck;
|
||||||
|
private ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
||||||
|
|
||||||
|
BackgroundTaskDeferral def;
|
||||||
|
public async void Run(IBackgroundTaskInstance taskInstance)
|
||||||
|
{
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
def = taskInstance.GetDeferral();
|
||||||
|
|
||||||
|
if (settings.Values["notificationsHistory"] != null)
|
||||||
|
doc.LoadXml(settings.Values["notificationsHistory"] as string);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null));
|
||||||
|
doc.AppendChild(doc.CreateElement("notifications"));
|
||||||
|
settings.Values.Add("notificationsHistory", doc.InnerXml);
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckAccount();
|
||||||
|
|
||||||
|
CheckAnnouncements();
|
||||||
|
|
||||||
|
def.Complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckAccount()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckAnnouncements()
|
||||||
|
{
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
doc.Load(XmlReader.Create("http://foxgame.hol.es/ftp.xml"));
|
||||||
|
if ((XmlConvert.ToDateTime((doc["posts"].FirstChild as XmlElement).GetAttribute("time"), XmlDateTimeSerializationMode.Utc) - DateTime.UtcNow).TotalSeconds > 0)
|
||||||
|
Notifications.Add(new Notification(NotificationType.Internal,
|
||||||
|
doc["posts"].FirstChild["notificationHeader"].InnerText,
|
||||||
|
doc["posts"].FirstChild["content"].InnerText,
|
||||||
|
XmlConvert.ToDateTime((doc["posts"].FirstChild as XmlElement).GetAttribute("time"),
|
||||||
|
XmlDateTimeSerializationMode.Local), (doc["posts"].FirstChild as XmlElement).GetAttribute("image")));
|
||||||
|
if ((bool)settings.Values["newmessagesNotification"] == true)
|
||||||
|
SendNotification(Notifications.Last());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendNotification(Notification notification)
|
||||||
|
{
|
||||||
|
ToastNotificationManager.CreateToastNotifier().Show(notification.GetToast(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{FC9128D7-E3AA-48ED-8641-629794B88B28}</ProjectGuid>
|
||||||
|
<OutputType>winmdobj</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>FoxTube.Background</RootNamespace>
|
||||||
|
<AssemblyName>FoxTube.Background</AssemblyName>
|
||||||
|
<DefaultLanguage>en-US</DefaultLanguage>
|
||||||
|
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||||
|
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.17134.0</TargetPlatformVersion>
|
||||||
|
<TargetPlatformMinVersion>10.0.15063.0</TargetPlatformMinVersion>
|
||||||
|
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<AllowCrossPlatformRetargeting>false</AllowCrossPlatformRetargeting>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<OutputPath>bin\x86\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<OutputPath>bin\x64\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="BackgroundProcessor.cs" />
|
||||||
|
<Compile Include="Notification.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="ToastTemplates.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||||
|
<Version>6.1.5</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System.Net.WebClient">
|
||||||
|
<HintPath>..\..\..\..\..\..\Program Files (x86)\Microsoft SDKs\UWPNuGetPackages\microsoft.netcore.universalwindowsplatform\6.1.5\ref\uap10.0.15138\System.Net.WebClient.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||||
|
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Windows.Data.Xml.Dom;
|
||||||
|
using Windows.UI;
|
||||||
|
using Windows.UI.Notifications;
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Media;
|
||||||
|
using Windows.UI.Xaml.Media.Imaging;
|
||||||
|
|
||||||
|
namespace FoxTube.Background
|
||||||
|
{
|
||||||
|
public enum NotificationType
|
||||||
|
{
|
||||||
|
Video, Comment, Post, Internal
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Notification
|
||||||
|
{
|
||||||
|
public string Channel { get; set; }
|
||||||
|
public string Content { get; set; }
|
||||||
|
public DateTime TimeStamp { get; set; }
|
||||||
|
public NotificationType Type { get; set; }
|
||||||
|
public string Avatar { get; set; }
|
||||||
|
public string Thumbnail { get; set; }
|
||||||
|
|
||||||
|
public Notification(NotificationType type,
|
||||||
|
string channelName, string content, DateTime date,
|
||||||
|
string thumbnailUrl, string avatarUrl = "ms-appx:///Assets/Icons/Profile.png")
|
||||||
|
{
|
||||||
|
Channel = channelName;
|
||||||
|
Content = content;
|
||||||
|
TimeStamp = date;
|
||||||
|
Type = type;
|
||||||
|
Avatar = avatarUrl;
|
||||||
|
Thumbnail = thumbnailUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UIElement GetNotification()
|
||||||
|
{
|
||||||
|
StackPanel stackPanel = new StackPanel() { Margin = new Thickness(10, 0, 0, 0) };
|
||||||
|
|
||||||
|
//Channel
|
||||||
|
switch (Type)
|
||||||
|
{
|
||||||
|
case NotificationType.Comment:
|
||||||
|
stackPanel.Children.Add(new TextBlock()
|
||||||
|
{
|
||||||
|
FontSize = 14,
|
||||||
|
FontStyle = Windows.UI.Text.FontStyle.Italic,
|
||||||
|
Foreground = new SolidColorBrush(Colors.Gray),
|
||||||
|
Text = string.Format("{0} replied to your comment", Channel)
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotificationType.Internal:
|
||||||
|
stackPanel.Children.Add(new TextBlock()
|
||||||
|
{
|
||||||
|
FontSize = 14,
|
||||||
|
FontStyle = Windows.UI.Text.FontStyle.Italic,
|
||||||
|
Foreground = new SolidColorBrush(Colors.Gray),
|
||||||
|
Text = Channel
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotificationType.Post:
|
||||||
|
stackPanel.Children.Add(new TextBlock()
|
||||||
|
{
|
||||||
|
FontSize = 14,
|
||||||
|
FontStyle = Windows.UI.Text.FontStyle.Italic,
|
||||||
|
Foreground = new SolidColorBrush(Colors.Gray),
|
||||||
|
Text = string.Format("{0} published new post", Channel)
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotificationType.Video:
|
||||||
|
stackPanel.Children.Add(new TextBlock()
|
||||||
|
{
|
||||||
|
FontSize = 14,
|
||||||
|
FontStyle = Windows.UI.Text.FontStyle.Italic,
|
||||||
|
Foreground = new SolidColorBrush(Colors.Gray),
|
||||||
|
Text = string.Format("{0} uploaded new video", Channel)
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Content
|
||||||
|
stackPanel.Children.Add(new TextBlock()
|
||||||
|
{
|
||||||
|
TextWrapping = TextWrapping.WrapWholeWords,
|
||||||
|
Text = Content,
|
||||||
|
});
|
||||||
|
//Time
|
||||||
|
stackPanel.Children.Add(new TextBlock()
|
||||||
|
{
|
||||||
|
FontSize = 13,
|
||||||
|
Foreground = new SolidColorBrush(Colors.Gray),
|
||||||
|
Text = TimeStamp.ToString()
|
||||||
|
});
|
||||||
|
PersonPicture avatar = new PersonPicture()
|
||||||
|
{
|
||||||
|
Height = 50,
|
||||||
|
VerticalAlignment = VerticalAlignment.Top,
|
||||||
|
ProfilePicture = string.IsNullOrWhiteSpace(Avatar) ? null : new BitmapImage(new Uri(Avatar))
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid grid = new Grid();
|
||||||
|
grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(50) });
|
||||||
|
grid.ColumnDefinitions.Add(new ColumnDefinition());
|
||||||
|
|
||||||
|
grid.Children.Add(avatar);
|
||||||
|
Grid.SetColumn(stackPanel, 1);
|
||||||
|
grid.Children.Add(stackPanel);
|
||||||
|
|
||||||
|
Button item = new Button()
|
||||||
|
{
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Stretch,
|
||||||
|
HorizontalContentAlignment = HorizontalAlignment.Left,
|
||||||
|
Background = new SolidColorBrush(Colors.Transparent),
|
||||||
|
Content = grid
|
||||||
|
};
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ToastNotification GetToast(int assignedId)
|
||||||
|
{
|
||||||
|
XmlDocument template = new XmlDocument();
|
||||||
|
switch (Type)
|
||||||
|
{
|
||||||
|
case NotificationType.Comment:
|
||||||
|
template.LoadXml($@"<toast launch='type=comment&action=open&id={assignedId}'>
|
||||||
|
<visual>
|
||||||
|
<binding template='ToastGeneric'>
|
||||||
|
<image placement='appLogoOverride' hint-crop='circle' src='{Avatar}'/>
|
||||||
|
<text>{Channel} posted a new comment</text>
|
||||||
|
<text>{Content}</text>
|
||||||
|
</binding>
|
||||||
|
</visual>
|
||||||
|
|
||||||
|
<actions>
|
||||||
|
<input id='textBox' type='text' placeHolderContent='Send a reply'/>
|
||||||
|
|
||||||
|
<action content='Send' imageUri='Assets/Icons/Send.png'
|
||||||
|
hint-inputId='textBox' activationType='background'
|
||||||
|
arguments='type=comment&action=sendReply&id={assignedId}'/>
|
||||||
|
|
||||||
|
<action content='Like'
|
||||||
|
arguments='type=comment&action=like&id={assignedId}'/>
|
||||||
|
</actions>
|
||||||
|
</toast>");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotificationType.Video:
|
||||||
|
template.LoadXml($@"<toast launch='action=viewPhoto&photoId=92187'>
|
||||||
|
<visual>
|
||||||
|
<binding template='ToastGeneric'>
|
||||||
|
<image placement='appLogoOverride' hint-crop='circle' src='{Avatar}'/>
|
||||||
|
<text>{Channel} uploaded a new video</text>
|
||||||
|
<text>{Content}</text>
|
||||||
|
<image src='{Thumbnail}'/>
|
||||||
|
</binding>
|
||||||
|
</visual>
|
||||||
|
|
||||||
|
<actions>
|
||||||
|
<action content='Watch later'
|
||||||
|
activationType='background'
|
||||||
|
arguments='likePhoto&photoId=92187'/>
|
||||||
|
<action content='Go to channel'
|
||||||
|
arguments='action=commentPhoto&photoId=92187'/>
|
||||||
|
</actions>
|
||||||
|
</toast>");
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("FoxTube.Background")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("FoxTube.Background")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FoxTube.Background
|
||||||
|
{
|
||||||
|
public static class ToastTemplates
|
||||||
|
{
|
||||||
|
public static string Comment =
|
||||||
|
@"<toast launch='action=openThread&threadId=92187'>
|
||||||
|
<visual>
|
||||||
|
<binding template='ToastGeneric'>
|
||||||
|
<image placement='appLogoOverride' hint-crop='circle' src='Assets/Icons/Profile.png'/>
|
||||||
|
<text>[ChannelName] posted a new comment</text>
|
||||||
|
<text>[VideoName]</text>
|
||||||
|
</binding>
|
||||||
|
</visual>
|
||||||
|
|
||||||
|
<actions>
|
||||||
|
<input id='textBox' type='text' placeHolderContent='Send a reply'/>
|
||||||
|
|
||||||
|
<action content='Send' imageUri='Assets/Icons/Send.png'
|
||||||
|
hint-inputId='textBox' activationType='background'
|
||||||
|
arguments='action=reply&threadId=92187'/>
|
||||||
|
|
||||||
|
<action content='Like'
|
||||||
|
arguments='action=commentPhoto&photoId=92187'/>
|
||||||
|
<action content='Go to comment'
|
||||||
|
arguments='action=commentPhoto&photoId=92187'/>
|
||||||
|
</actions>
|
||||||
|
</toast>";
|
||||||
|
public static string Video =
|
||||||
|
@"<toast launch='action=viewPhoto&photoId=92187'>
|
||||||
|
<visual>
|
||||||
|
<binding template='ToastGeneric'>
|
||||||
|
<image placement='appLogoOverride' hint-crop='circle' src='Assets/Icons/Profile.png'/>
|
||||||
|
<text>[ChannelName] uploaded a new video</text>
|
||||||
|
<text>[VideoName]</text>
|
||||||
|
<image src='Assets/videoThumbSample.png'/>
|
||||||
|
</binding>
|
||||||
|
</visual>
|
||||||
|
|
||||||
|
<actions>
|
||||||
+22
@@ -5,16 +5,21 @@ VisualStudioVersion = 15.0.27428.1
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoxTube", "FoxTube\FoxTube.csproj", "{2597B816-7316-4D20-BA6C-D78001E89C1A}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoxTube", "FoxTube\FoxTube.csproj", "{2597B816-7316-4D20-BA6C-D78001E89C1A}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoxTube.Background", "FoxTube.Background\FoxTube.Background.csproj", "{FC9128D7-E3AA-48ED-8641-629794B88B28}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Debug|ARM = Debug|ARM
|
Debug|ARM = Debug|ARM
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
Debug|x86 = Debug|x86
|
Debug|x86 = Debug|x86
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
Release|ARM = Release|ARM
|
Release|ARM = Release|ARM
|
||||||
Release|x64 = Release|x64
|
Release|x64 = Release|x64
|
||||||
Release|x86 = Release|x86
|
Release|x86 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Debug|ARM.ActiveCfg = Debug|ARM
|
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||||
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Debug|ARM.Build.0 = Debug|ARM
|
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Debug|ARM.Build.0 = Debug|ARM
|
||||||
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Debug|ARM.Deploy.0 = Debug|ARM
|
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||||
@@ -24,6 +29,7 @@ Global
|
|||||||
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Debug|x86.ActiveCfg = Debug|x86
|
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Debug|x86.Build.0 = Debug|x86
|
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Debug|x86.Build.0 = Debug|x86
|
||||||
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Debug|x86.Deploy.0 = Debug|x86
|
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Debug|x86.Deploy.0 = Debug|x86
|
||||||
|
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Release|ARM.ActiveCfg = Release|ARM
|
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Release|ARM.ActiveCfg = Release|ARM
|
||||||
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Release|ARM.Build.0 = Release|ARM
|
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Release|ARM.Build.0 = Release|ARM
|
||||||
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Release|ARM.Deploy.0 = Release|ARM
|
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Release|ARM.Deploy.0 = Release|ARM
|
||||||
@@ -33,6 +39,22 @@ Global
|
|||||||
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Release|x86.ActiveCfg = Release|x86
|
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Release|x86.ActiveCfg = Release|x86
|
||||||
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Release|x86.Build.0 = Release|x86
|
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Release|x86.Build.0 = Release|x86
|
||||||
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Release|x86.Deploy.0 = Release|x86
|
{2597B816-7316-4D20-BA6C-D78001E89C1A}.Release|x86.Deploy.0 = Release|x86
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Debug|ARM.Build.0 = Debug|ARM
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Release|ARM.ActiveCfg = Release|ARM
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Release|ARM.Build.0 = Release|ARM
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Release|x64.Build.0 = Release|x64
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{FC9128D7-E3AA-48ED-8641-629794B88B28}.Release|x86.Build.0 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@@ -1,5 +1,7 @@
|
|||||||
using System;
|
using MyToolkit.Multimedia;
|
||||||
|
using System;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Windows.UI;
|
using Windows.UI;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
@@ -70,5 +72,40 @@ namespace FoxTube
|
|||||||
else block.Inlines.Add(new Run { Text = item });
|
else block.Inlines.Add(new Run { Text = item });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string QualityToString(YouTubeQuality quality)
|
||||||
|
{
|
||||||
|
switch(quality)
|
||||||
|
{
|
||||||
|
case YouTubeQuality.NotAvailable:
|
||||||
|
return "N/A";
|
||||||
|
case YouTubeQuality.Quality1080P:
|
||||||
|
return "1080p";
|
||||||
|
case YouTubeQuality.Quality144P:
|
||||||
|
return "144p";
|
||||||
|
case YouTubeQuality.Quality2160P:
|
||||||
|
return "2160p";
|
||||||
|
case YouTubeQuality.Quality240P:
|
||||||
|
return "240p";
|
||||||
|
case YouTubeQuality.Quality270P:
|
||||||
|
return "270p";
|
||||||
|
case YouTubeQuality.Quality360P:
|
||||||
|
return "360p";
|
||||||
|
case YouTubeQuality.Quality480P:
|
||||||
|
return "480p";
|
||||||
|
case YouTubeQuality.Quality520P:
|
||||||
|
return "520p";
|
||||||
|
case YouTubeQuality.Quality720P:
|
||||||
|
return "720p";
|
||||||
|
case YouTubeQuality.QualityHigh:
|
||||||
|
return "[Audio only] High quality";
|
||||||
|
case YouTubeQuality.QualityLow:
|
||||||
|
return "[Audio only] Low quality";
|
||||||
|
case YouTubeQuality.QualityMedium:
|
||||||
|
return "[Audio only] Medium quality";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+143
-16
@@ -3,6 +3,11 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Windows.Data.Xml.Dom;
|
||||||
|
using Windows.UI;
|
||||||
|
using Windows.UI.Notifications;
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
using Windows.UI.Xaml.Media;
|
using Windows.UI.Xaml.Media;
|
||||||
using Windows.UI.Xaml.Media.Imaging;
|
using Windows.UI.Xaml.Media.Imaging;
|
||||||
|
|
||||||
@@ -10,35 +15,157 @@ namespace FoxTube
|
|||||||
{
|
{
|
||||||
public enum NotificationType
|
public enum NotificationType
|
||||||
{
|
{
|
||||||
NewVideo, NewComment, NewPost, Update
|
Video, Comment, Post, Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Notification
|
public class Notification
|
||||||
{
|
{
|
||||||
public string Header { get; set; }
|
public string Channel { get; set; }
|
||||||
public string message { get; set; }
|
public string Content { get; set; }
|
||||||
public DateTime time { get; set; }
|
public DateTime TimeStamp { get; set; }
|
||||||
public NotificationType Type { get; set; }
|
public NotificationType Type { get; set; }
|
||||||
public string Avatar { get; set; }
|
public string Avatar { get; set; }
|
||||||
public string Thumbnail { get; set; }
|
public string Thumbnail { get; set; }
|
||||||
|
|
||||||
public Notification(string header, string content, DateTime date, NotificationType type, string avatar = "ms-appx:///Assets/NewsAvatar.png", string thumbnail = "ms-appx:///Assets/AnnouncementThumb.png")
|
public Notification(NotificationType type,
|
||||||
|
string channelName, string content, DateTime date,
|
||||||
|
string thumbnailUrl, string avatarUrl = "ms-appx:///Assets/Icons/Profile.png")
|
||||||
{
|
{
|
||||||
Header = header;
|
Channel = channelName;
|
||||||
message = content;
|
Content = content;
|
||||||
time = date;
|
TimeStamp = date;
|
||||||
Type = type;
|
Type = type;
|
||||||
Avatar = avatar;
|
Avatar = avatarUrl;
|
||||||
Thumbnail = thumbnail;
|
Thumbnail = thumbnailUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string returnTimecode(bool twelveFormat = true)
|
public UIElement GetNotification()
|
||||||
{
|
{
|
||||||
TimeSpan diff = DateTime.Now - time;
|
StackPanel stackPanel = new StackPanel() { Margin = new Thickness(10, 0, 0, 0) };
|
||||||
if (diff.TotalDays == 0)
|
|
||||||
return string.Format("{0}:{1}", time.Hour, time.Minute);
|
//Channel
|
||||||
else
|
switch (Type)
|
||||||
return string.Format("{0}/{1} {2}:{3}", time.Month, time.Day, time.Hour, time.Minute);
|
{
|
||||||
|
case NotificationType.Comment:
|
||||||
|
stackPanel.Children.Add(new TextBlock()
|
||||||
|
{
|
||||||
|
FontSize = 14,
|
||||||
|
FontStyle = Windows.UI.Text.FontStyle.Italic,
|
||||||
|
Foreground = new SolidColorBrush(Colors.Gray),
|
||||||
|
Text = string.Format("{0} replied to your comment", Channel)
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotificationType.Internal:
|
||||||
|
stackPanel.Children.Add(new TextBlock()
|
||||||
|
{
|
||||||
|
FontSize = 14,
|
||||||
|
FontStyle = Windows.UI.Text.FontStyle.Italic,
|
||||||
|
Foreground = new SolidColorBrush(Colors.Gray),
|
||||||
|
Text = Channel
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotificationType.Post:
|
||||||
|
stackPanel.Children.Add(new TextBlock()
|
||||||
|
{
|
||||||
|
FontSize = 14,
|
||||||
|
FontStyle = Windows.UI.Text.FontStyle.Italic,
|
||||||
|
Foreground = new SolidColorBrush(Colors.Gray),
|
||||||
|
Text = string.Format("{0} published new post", Channel)
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotificationType.Video:
|
||||||
|
stackPanel.Children.Add(new TextBlock()
|
||||||
|
{
|
||||||
|
FontSize = 14,
|
||||||
|
FontStyle = Windows.UI.Text.FontStyle.Italic,
|
||||||
|
Foreground = new SolidColorBrush(Colors.Gray),
|
||||||
|
Text = string.Format("{0} uploaded new video", Channel)
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Content
|
||||||
|
stackPanel.Children.Add(new TextBlock()
|
||||||
|
{
|
||||||
|
TextWrapping = TextWrapping.WrapWholeWords,
|
||||||
|
Text = Content,
|
||||||
|
});
|
||||||
|
//Time
|
||||||
|
stackPanel.Children.Add(new TextBlock()
|
||||||
|
{
|
||||||
|
FontSize = 13,
|
||||||
|
Foreground = new SolidColorBrush(Colors.Gray),
|
||||||
|
Text = TimeStamp.ToString()
|
||||||
|
});
|
||||||
|
PersonPicture avatar = new PersonPicture()
|
||||||
|
{
|
||||||
|
Height = 50,
|
||||||
|
VerticalAlignment = VerticalAlignment.Top,
|
||||||
|
ProfilePicture = string.IsNullOrWhiteSpace(Avatar) ? null : new BitmapImage(new Uri(Avatar))
|
||||||
|
};
|
||||||
|
|
||||||
|
Grid grid = new Grid();
|
||||||
|
grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(50) });
|
||||||
|
grid.ColumnDefinitions.Add(new ColumnDefinition());
|
||||||
|
|
||||||
|
grid.Children.Add(avatar);
|
||||||
|
Grid.SetColumn(stackPanel, 1);
|
||||||
|
grid.Children.Add(stackPanel);
|
||||||
|
|
||||||
|
Button item = new Button()
|
||||||
|
{
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Stretch,
|
||||||
|
HorizontalContentAlignment = HorizontalAlignment.Left,
|
||||||
|
Background = new SolidColorBrush(Colors.Transparent),
|
||||||
|
Content = grid
|
||||||
|
};
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ToastNotification GetToast(int assignedId)
|
||||||
|
{
|
||||||
|
System.Xml.XmlDocument template = new System.Xml.XmlDocument();
|
||||||
|
switch(Type)
|
||||||
|
{
|
||||||
|
case NotificationType.Comment:
|
||||||
|
template.Load("ms-appx:///Assets/Notifications/Comment.xml");
|
||||||
|
template["toast"]["visual"]["binding"]["image"].SetAttribute("src", Avatar);
|
||||||
|
template["toast"]["visual"]["binding"].ChildNodes[1].InnerText = string.Format("{0} posted a new comment", Channel);
|
||||||
|
template["toast"]["visual"]["binding"].LastChild.InnerText = Content;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotificationType.Video:
|
||||||
|
template.Load("ms-appx:///Assets/Notifications/Video.xml");
|
||||||
|
(template["toast"]["visual"]["binding"].FirstChild as System.Xml.XmlElement).SetAttribute("src", Avatar);
|
||||||
|
template["toast"]["visual"]["binding"].ChildNodes[1].InnerText = string.Format("{0} uploaded a new video", Channel);
|
||||||
|
template["toast"]["visual"]["binding"].ChildNodes[2].InnerText = Content;
|
||||||
|
(template["toast"]["visual"]["binding"].LastChild as System.Xml.XmlElement).SetAttribute("src", Thumbnail);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotificationType.Internal:
|
||||||
|
template.Load("ms-appx:///Assets/Notifications/Internal.xml");
|
||||||
|
if(!string.IsNullOrWhiteSpace(Thumbnail))
|
||||||
|
(template["toast"]["visual"]["binding"].FirstChild as System.Xml.XmlElement).SetAttribute("src", Avatar);
|
||||||
|
template["toast"]["visual"]["binding"].LastChild.InnerText = Channel;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotificationType.Post:
|
||||||
|
template.Load("ms-appx:///Assets/Notifications/Video.xml");
|
||||||
|
(template["toast"]["visual"]["binding"].FirstChild as System.Xml.XmlElement).SetAttribute("src", Thumbnail);
|
||||||
|
(template["toast"]["visual"]["binding"].ChildNodes[1] as System.Xml.XmlElement).SetAttribute("src", Avatar);
|
||||||
|
template["toast"]["visual"]["binding"].ChildNodes[2].InnerText = string.Format("{0} published a new post", Channel);
|
||||||
|
template["toast"]["visual"]["binding"].ChildNodes[3].InnerText = Content;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlDocument toastXml = new XmlDocument();
|
||||||
|
toastXml.LoadXml(template.InnerXml);
|
||||||
|
|
||||||
|
return new ToastNotification(toastXml);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FoxTube
|
||||||
|
{
|
||||||
|
public class ObjectEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public List<object> Parameters = new List<object>();
|
||||||
|
public ObjectEventArgs(params object[] args)
|
||||||
|
{
|
||||||
|
foreach (object a in args)
|
||||||
|
Parameters.Add(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,47 +24,50 @@ using Google.Apis.Util.Store;
|
|||||||
using Google.Apis.YouTube.v3;
|
using Google.Apis.YouTube.v3;
|
||||||
using Google.Apis.Auth.OAuth2.Responses;
|
using Google.Apis.Auth.OAuth2.Responses;
|
||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
|
using Google.Apis.YouTube.v3.Data;
|
||||||
|
|
||||||
namespace FoxTube
|
namespace FoxTube
|
||||||
{
|
{
|
||||||
public class SecretsVault
|
public class SecretsVault
|
||||||
{
|
{
|
||||||
#region Static Information
|
#region Static Information
|
||||||
public static NetworkCredential EmailCredential { get => new NetworkCredential("youwillneverknowthisadress@gmail.com", "thisisthepassword12345"); }
|
public static NetworkCredential EmailCredential => new NetworkCredential("youwillneverknowthisadress@gmail.com", "thisisthepassword12345");
|
||||||
public static SecretsVault Vault { get => Methods.MainPage.Vault; }
|
private static ClientSecrets Secrets => new ClientSecrets()
|
||||||
public static string AccountId => Methods.MainPage.Vault.userId;
|
|
||||||
private static ClientSecrets Secrets
|
|
||||||
{
|
|
||||||
get => new ClientSecrets()
|
|
||||||
{
|
{
|
||||||
ClientId = "349735264870-2ekqlm0a4mkg3mmrfcv90s3qp3o15dq0.apps.googleusercontent.com",
|
ClientId = "349735264870-2ekqlm0a4mkg3mmrfcv90s3qp3o15dq0.apps.googleusercontent.com",
|
||||||
ClientSecret = "BkVZOAaCU2Zclf0Zlicg6y2_"
|
ClientSecret = "BkVZOAaCU2Zclf0Zlicg6y2_"
|
||||||
};
|
};
|
||||||
}
|
|
||||||
public static bool IsAuthorized { get => Vault.IsLoged; }
|
|
||||||
|
|
||||||
public static YouTubeService NoAuthService
|
public static SecretsVault Vault => Methods.MainPage.Vault;
|
||||||
{
|
|
||||||
get => new YouTubeService(new BaseClientService.Initializer()
|
public static string AccountId => Methods.MainPage.Vault.userId;
|
||||||
|
public static bool IsAuthorized => Vault.IsLoged;
|
||||||
|
|
||||||
|
public static Google.Apis.YouTube.v3.Data.Channel UserChannel => Methods.MainPage.Vault.channel;
|
||||||
|
public static List<KeyValuePair<string, string>> WatchLater => Methods.MainPage.Vault.later;
|
||||||
|
public static List<string> UserHistory => Methods.MainPage.Vault.history;
|
||||||
|
public static List<string> Subscriptions => Methods.MainPage.Vault.subs;
|
||||||
|
|
||||||
|
public static YouTubeService NoAuthService => new YouTubeService(new BaseClientService.Initializer()
|
||||||
{
|
{
|
||||||
ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0",
|
ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0",
|
||||||
ApplicationName = "FoxTube"
|
ApplicationName = "FoxTube"
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
public static YouTubeService Service
|
public static YouTubeService Service => new YouTubeService(new BaseClientService.Initializer()
|
||||||
{
|
|
||||||
get => new YouTubeService(new BaseClientService.Initializer()
|
|
||||||
{
|
{
|
||||||
HttpClientInitializer = Vault.Credential,
|
HttpClientInitializer = Vault.Credential,
|
||||||
ApplicationName = "FoxTube"
|
ApplicationName = "FoxTube"
|
||||||
});
|
});
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Object containers
|
#region Object containers
|
||||||
public bool IsLoged = false;
|
public bool IsLoged = false;
|
||||||
public string userId;
|
public string userId;
|
||||||
|
public List<string> history = new List<string>();
|
||||||
|
public List<string> subs = new List<string>();
|
||||||
|
public List<KeyValuePair<string, string>> later = new List<KeyValuePair<string, string>>();
|
||||||
|
public Google.Apis.YouTube.v3.Data.Channel channel;
|
||||||
public UserCredential Credential;
|
public UserCredential Credential;
|
||||||
public event EventHandler AuthorizationStateChanged;
|
public event EventHandler AuthorizationStateChanged;
|
||||||
|
|
||||||
@@ -78,9 +81,56 @@ namespace FoxTube
|
|||||||
AuthorizationStateChanged.Invoke(this, null);
|
AuthorizationStateChanged.Invoke(this, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = Service.Channels.List("snippet");
|
var request = Service.Channels.List("snippet,contentDetails");
|
||||||
request.Mine = true;
|
request.Mine = true;
|
||||||
userId = (await request.ExecuteAsync()).Items[0].Id;
|
channel = (await request.ExecuteAsync()).Items[0];
|
||||||
|
userId = channel.Id;
|
||||||
|
|
||||||
|
var historyRequest = Service.PlaylistItems.List("snippet");
|
||||||
|
historyRequest.PlaylistId = channel.ContentDetails.RelatedPlaylists.WatchHistory;
|
||||||
|
historyRequest.MaxResults = 50;
|
||||||
|
var response = await historyRequest.ExecuteAsync();
|
||||||
|
history.Clear();
|
||||||
|
foreach (PlaylistItem i in response.Items)
|
||||||
|
history.Add(i.Snippet.ResourceId.VideoId);
|
||||||
|
|
||||||
|
var laterRequest = Service.PlaylistItems.List("snippet");
|
||||||
|
laterRequest.PlaylistId = channel.ContentDetails.RelatedPlaylists.WatchLater;
|
||||||
|
laterRequest.MaxResults = 50;
|
||||||
|
var laterResponse = await laterRequest.ExecuteAsync();
|
||||||
|
later.Clear();
|
||||||
|
|
||||||
|
foreach (PlaylistItem i in laterResponse.Items)
|
||||||
|
later.Add(new KeyValuePair<string, string>(i.Id, i.Snippet.ResourceId.VideoId));
|
||||||
|
|
||||||
|
string nextToken = laterResponse.NextPageToken;
|
||||||
|
while (nextToken != null)
|
||||||
|
{
|
||||||
|
laterRequest.PageToken = nextToken;
|
||||||
|
laterResponse = await laterRequest.ExecuteAsync();
|
||||||
|
foreach (PlaylistItem i in laterResponse.Items)
|
||||||
|
later.Add(new KeyValuePair<string, string>(i.Id, i.Snippet.ResourceId.VideoId));
|
||||||
|
|
||||||
|
nextToken = laterResponse.NextPageToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
SubscriptionsResource.ListRequest subRequest = SecretsVault.Service.Subscriptions.List("snippet");
|
||||||
|
subRequest.Mine = true;
|
||||||
|
subRequest.MaxResults = 50;
|
||||||
|
SubscriptionListResponse subResponse = await subRequest.ExecuteAsync();
|
||||||
|
subs.Clear();
|
||||||
|
|
||||||
|
foreach (Subscription s in subResponse.Items)
|
||||||
|
subs.Add(s.Snippet.ResourceId.ChannelId);
|
||||||
|
|
||||||
|
nextToken = subResponse.NextPageToken;
|
||||||
|
while(nextToken != null)
|
||||||
|
{
|
||||||
|
subRequest.PageToken = nextToken;
|
||||||
|
subResponse = await subRequest.ExecuteAsync();
|
||||||
|
foreach (Subscription s in subResponse.Items)
|
||||||
|
subs.Add(s.Snippet.ResourceId.ChannelId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void Deauthenticate()
|
public async void Deauthenticate()
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml;
|
||||||
|
using System.IO;
|
||||||
|
using MyToolkit.Multimedia;
|
||||||
|
|
||||||
|
namespace FoxTube.Controls
|
||||||
|
{
|
||||||
|
public class DownloadAgent
|
||||||
|
{
|
||||||
|
public List<DownloadItem> Items = new List<DownloadItem>();
|
||||||
|
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
string path = $@"{Directory.GetCurrentDirectory()}\DownloadHistory.xml";
|
||||||
|
public DownloadAgent()
|
||||||
|
{
|
||||||
|
if (File.Exists(path))
|
||||||
|
doc.Load(path);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null));
|
||||||
|
doc.AppendChild(doc.CreateElement("downloads"));
|
||||||
|
doc.Save(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(XmlElement e in doc["downloads"].ChildNodes)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Items.Add(new DownloadItem(
|
||||||
|
e["details"]["id"].InnerText,
|
||||||
|
e["title"].InnerText,
|
||||||
|
e["snippet"]["author"].InnerText,
|
||||||
|
e["snippet"]["image"].InnerText,
|
||||||
|
e["snippet"]["duration"].InnerText,
|
||||||
|
e["snippet"]["quality"].InnerText,
|
||||||
|
e["details"]["path"].InnerText));
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(string id, YouTubeQuality quality)
|
||||||
|
{
|
||||||
|
DownloadItem item = new DownloadItem(id, quality);
|
||||||
|
item.DownloadCanceled += Item_DownloadCanceled;
|
||||||
|
item.DownloadComplete += Item_DownloadComplete;
|
||||||
|
|
||||||
|
Items.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Item_DownloadComplete(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
doc["downloads"].AppendChild((e as ObjectEventArgs).Parameters[0] as XmlElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Item_DownloadCanceled(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Items.Remove(sender as DownloadItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
<UserControl
|
||||||
|
x:Class="FoxTube.Controls.DownloadItem"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="using:FoxTube.Controls"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="100"
|
||||||
|
d:DesignWidth="1500">
|
||||||
|
|
||||||
|
<!--<Button HorizontalAlignment="Stretch" Background="WhiteSmoke" Height="100" Padding="0" HorizontalContentAlignment="Stretch"/>-->
|
||||||
|
<Grid Background="WhiteSmoke" Height="100">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Image Name="thumbnail" Source="/Assets/videoThumbSample.png"/>
|
||||||
|
<TextBlock Name="title" Grid.Column="1" Margin="5" TextWrapping="WrapWholeWords" Text="[Title]" FontSize="20" MaxLines="3"/>
|
||||||
|
|
||||||
|
<StackPanel Grid.Column="2" Margin="5">
|
||||||
|
<TextBlock Text="Extension:" Foreground="Gray"/>
|
||||||
|
<TextBlock Text="Quality:" Foreground="Gray" Name="quality"/>
|
||||||
|
<TextBlock Text="Duration:" Foreground="Gray" Name="duration"/>
|
||||||
|
<TextBlock Text="Author:" Foreground="Gray" Name="channel"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Name="donePanel" Grid.Column="3" Orientation="Horizontal" Visibility="Collapsed">
|
||||||
|
<Button Name="open" Click="open_Click" Width="80" Height="80" Padding="0" Background="Transparent">
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="30" HorizontalAlignment="Center"/>
|
||||||
|
<TextBlock Text="Open" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
<Button Name="gotoOriginal" Click="gotoOriginal_Click" Width="80" Height="80" Padding="0" Background="Transparent">
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="30" HorizontalAlignment="Center"/>
|
||||||
|
<TextBlock Text="Go to original" TextWrapping="WrapWholeWords" HorizontalTextAlignment="Center" HorizontalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Name="progressPanel" Grid.Column="4" Margin="10">
|
||||||
|
<TextBlock Name="status" Text="Initializing..." HorizontalAlignment="Left"/>
|
||||||
|
<ProgressBar Name="progressBar" Width="200" IsIndeterminate="True" Foreground="Red"/>
|
||||||
|
<TextBlock Name="perc" Text="--%"/>
|
||||||
|
<Button Content="Cancel" Name="cancel" Click="cancel_Click" HorizontalAlignment="Right"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Foundation.Collections;
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Controls.Primitives;
|
||||||
|
using Windows.UI.Xaml.Data;
|
||||||
|
using Windows.UI.Xaml.Input;
|
||||||
|
using Windows.UI.Xaml.Media;
|
||||||
|
using Windows.UI.Xaml.Navigation;
|
||||||
|
using System.Net;
|
||||||
|
using Windows.UI.Xaml.Media.Imaging;
|
||||||
|
using Windows.System;
|
||||||
|
using MyToolkit.Multimedia;
|
||||||
|
using Windows.Storage;
|
||||||
|
using Google.Apis.YouTube.v3;
|
||||||
|
using Google.Apis.YouTube.v3.Data;
|
||||||
|
using Windows.UI.Popups;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
|
||||||
|
|
||||||
|
namespace FoxTube.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class DownloadItem : UserControl
|
||||||
|
{
|
||||||
|
string uri;
|
||||||
|
string Id;
|
||||||
|
|
||||||
|
public event EventHandler DownloadCanceled;
|
||||||
|
public event EventHandler DownloadComplete;
|
||||||
|
|
||||||
|
WebClient client = new WebClient();
|
||||||
|
|
||||||
|
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
||||||
|
public DownloadItem(string id, YouTubeQuality q)
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
|
||||||
|
client.DownloadFileCompleted += DownloadCompleted;
|
||||||
|
client.DownloadProgressChanged += UpdateInfo;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Download(id, q);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (client.IsBusy)
|
||||||
|
client.CancelAsync();
|
||||||
|
new MessageDialog("We were unable to download video due to connection problems or internal YouTube server error. Please, try again later.", "Failed to download").ShowAsync();
|
||||||
|
throw new FileNotFoundException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async void Download(string id, YouTubeQuality q)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
VideosResource.ListRequest request = SecretsVault.NoAuthService.Videos.List("snippet");
|
||||||
|
request.Id = id;
|
||||||
|
var response = (await request.ExecuteAsync()).Items[0];
|
||||||
|
|
||||||
|
Uri url = (await YouTube.GetVideoUriAsync(id, q)).Uri;
|
||||||
|
|
||||||
|
client.DownloadFileAsync(url, settings.Values["defaultDownload"] as string + $@"\{response.Snippet.Title} - {response.Snippet.ChannelTitle}.mp4");
|
||||||
|
|
||||||
|
thumbnail.Source = new BitmapImage(new Uri(response.Snippet.Thumbnails.Standard.Url));
|
||||||
|
title.Text = response.Snippet.Title;
|
||||||
|
channel.Text = $"Author: {response.Snippet.ChannelTitle}";
|
||||||
|
|
||||||
|
quality.Text = $"Quality: {Methods.QualityToString(q)}"; TimeSpan ts = XmlConvert.ToTimeSpan(response.ContentDetails.Duration);
|
||||||
|
duration.Text = string.Format("Duration: {0}{1:00}:{2:00} | ", ts.Hours == 0 ? "" : ts.Hours + ":", ts.Minutes, ts.Seconds);
|
||||||
|
|
||||||
|
uri = settings.Values["defaultDownload"] as string + $@"\{response.Snippet.Title} - {response.Snippet.ChannelTitle}.mp4";
|
||||||
|
|
||||||
|
status.Text = "Downloading...";
|
||||||
|
perc.Text = "0%";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateInfo(object sender, DownloadProgressChangedEventArgs e)
|
||||||
|
{
|
||||||
|
progressBar.Value = e.ProgressPercentage;
|
||||||
|
perc.Text = $"{e.ProgressPercentage}%";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DownloadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
|
||||||
|
{
|
||||||
|
progressPanel.Visibility = Visibility.Collapsed;
|
||||||
|
donePanel.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
|
XmlElement node = new XmlDocument().CreateElement("item");
|
||||||
|
node.InnerXml = $@"<item>
|
||||||
|
<title{title.Text}></title>
|
||||||
|
<snippet>
|
||||||
|
<quality>{quality.Text.Split(' ')[1]}</quality>
|
||||||
|
<duration>{duration.Text.Split(' ')[1]}</duration>
|
||||||
|
<author>{channel.Text.Split(' ')[1]}</author>
|
||||||
|
</snippet>
|
||||||
|
<details>
|
||||||
|
<path>{uri}</path>
|
||||||
|
<id>{Id}</id>
|
||||||
|
</details>
|
||||||
|
</item>";
|
||||||
|
|
||||||
|
DownloadComplete.Invoke(this, new ObjectEventArgs(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadItem(string videoId, string videoName, string channelName, string thumbUrl, string length, string videoQuality, string path)
|
||||||
|
{
|
||||||
|
if (!File.Exists(path))
|
||||||
|
throw new FileNotFoundException();
|
||||||
|
|
||||||
|
title.Text = videoName;
|
||||||
|
thumbnail.Source = new BitmapImage(new Uri(thumbUrl));
|
||||||
|
quality.Text = $"Quality: {videoQuality}";
|
||||||
|
duration.Text = $"Duration: {length}";
|
||||||
|
channel.Text = $"Author: {channelName}";
|
||||||
|
|
||||||
|
progressPanel.Visibility = Visibility.Collapsed;
|
||||||
|
donePanel.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
|
uri = path;
|
||||||
|
Id = videoId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void open_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(uri))
|
||||||
|
await Launcher.LaunchUriAsync(new Uri(uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void gotoOriginal_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Methods.MainPage.GoToVideo(Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void cancel_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if(client.IsBusy)
|
||||||
|
{
|
||||||
|
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("No"));
|
||||||
|
|
||||||
|
dialog.DefaultCommandIndex = 1;
|
||||||
|
await dialog.ShowAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,11 @@
|
|||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid Grid.Row="0" Background="Black">
|
<Grid Grid.Row="0" Background="Black">
|
||||||
<Image Name="thumbnail" Source="Assets/videoThumbSample.png" Stretch="Fill"/>
|
<Image Name="thumbnail" Source="Assets/videoThumbSample.png" Stretch="Fill"/>
|
||||||
|
<Grid Background="#7FFFFFFF" Name="watched" Visibility="Collapsed">
|
||||||
|
<StackPanel Margin="5" Background="WhiteSmoke" VerticalAlignment="Top" HorizontalAlignment="Left" Padding="5,2,5,2" BorderBrush="Gray" BorderThickness="1">
|
||||||
|
<TextBlock Text="Watched" Foreground="Gray" FontSize="12"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
<StackPanel Margin="0,0,5,5" Background="WhiteSmoke" VerticalAlignment="Bottom" HorizontalAlignment="Right" Padding="5,2,5,0" Height="20">
|
<StackPanel Margin="0,0,5,5" Background="WhiteSmoke" VerticalAlignment="Bottom" HorizontalAlignment="Right" Padding="5,2,5,0" Height="20">
|
||||||
<TextBlock Name="info" Text="[Duration] | [Published at]" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Gray" FontSize="12"/>
|
<TextBlock Name="info" Text="[Duration] | [Published at]" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Gray" FontSize="12"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace FoxTube
|
|||||||
views.Text = string.Format("{0} views", item.Statistics.ViewCount);
|
views.Text = string.Format("{0} views", item.Statistics.ViewCount);
|
||||||
|
|
||||||
string duration;
|
string duration;
|
||||||
if (item.ContentDetails.Duration != null || item.ContentDetails.Duration != "")
|
if (!string.IsNullOrWhiteSpace(item.ContentDetails.Duration))
|
||||||
{
|
{
|
||||||
TimeSpan ts = XmlConvert.ToTimeSpan(item.ContentDetails.Duration);
|
TimeSpan ts = XmlConvert.ToTimeSpan(item.ContentDetails.Duration);
|
||||||
duration = string.Format("{0}{1:00}:{2:00} | ", ts.Hours == 0 ? "" : ts.Hours + ":", ts.Minutes, ts.Seconds);
|
duration = string.Format("{0}{1:00}:{2:00} | ", ts.Hours == 0 ? "" : ts.Hours + ":", ts.Minutes, ts.Seconds);
|
||||||
@@ -94,6 +94,9 @@ namespace FoxTube
|
|||||||
|
|
||||||
avatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url));
|
avatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url));
|
||||||
channelName.Text = item1.Snippet.Title;
|
channelName.Text = item1.Snippet.Title;
|
||||||
|
|
||||||
|
if (SecretsVault.UserHistory.Contains(item.Id))
|
||||||
|
watched.Visibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Button_Click(object sender, RoutedEventArgs e)
|
private async void Button_Click(object sender, RoutedEventArgs e)
|
||||||
|
|||||||
@@ -11,7 +11,14 @@
|
|||||||
|
|
||||||
<Button Padding="0" Background="WhiteSmoke" HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" Margin="2" Click="Button_Click">
|
<Button Padding="0" Background="WhiteSmoke" HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" Margin="2" Click="Button_Click">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Grid>
|
||||||
<Image Name="thumbnail" Source="Assets/videoThumbSample.png"/>
|
<Image Name="thumbnail" Source="Assets/videoThumbSample.png"/>
|
||||||
|
<Grid Background="#7FFFFFFF" Name="watched" Visibility="Collapsed">
|
||||||
|
<StackPanel Margin="5" Background="WhiteSmoke" VerticalAlignment="Top" HorizontalAlignment="Left" Padding="5,2,5,2" BorderBrush="Gray" BorderThickness="1">
|
||||||
|
<TextBlock Text="Watched" Foreground="Gray" FontSize="12"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
<Grid Margin="10" HorizontalAlignment="Stretch">
|
<Grid Margin="10" HorizontalAlignment="Stretch">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
|
|||||||
@@ -91,6 +91,9 @@ namespace FoxTube
|
|||||||
avatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url));
|
avatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url));
|
||||||
channelName.Text = item1.Snippet.Title;
|
channelName.Text = item1.Snippet.Title;
|
||||||
channelSubs.Text = string.Format("{0} subscribers", item1.Statistics.SubscriberCount);
|
channelSubs.Text = string.Format("{0} subscribers", item1.Statistics.SubscriberCount);
|
||||||
|
|
||||||
|
if (SecretsVault.UserHistory.Contains(item.Id))
|
||||||
|
watched.Visibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void channelLink_Click(object sender, RoutedEventArgs e)
|
private void channelLink_Click(object sender, RoutedEventArgs e)
|
||||||
|
|||||||
@@ -97,9 +97,14 @@
|
|||||||
<DependentUpon>App.xaml</DependentUpon>
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Classes\Methods.cs" />
|
<Compile Include="Classes\Methods.cs" />
|
||||||
|
<Compile Include="Classes\ObjectEventArgs.cs" />
|
||||||
<Compile Include="Controls\CommentCard.xaml.cs">
|
<Compile Include="Controls\CommentCard.xaml.cs">
|
||||||
<DependentUpon>CommentCard.xaml</DependentUpon>
|
<DependentUpon>CommentCard.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Controls\DownloadAgent.cs" />
|
||||||
|
<Compile Include="Controls\DownloadItem.xaml.cs">
|
||||||
|
<DependentUpon>DownloadItem.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Controls\SuggestionsQueries.xaml.cs">
|
<Compile Include="Controls\SuggestionsQueries.xaml.cs">
|
||||||
<DependentUpon>SuggestionsQueries.xaml</DependentUpon>
|
<DependentUpon>SuggestionsQueries.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -112,6 +117,9 @@
|
|||||||
<Compile Include="Pages\CommentsPage.xaml.cs">
|
<Compile Include="Pages\CommentsPage.xaml.cs">
|
||||||
<DependentUpon>CommentsPage.xaml</DependentUpon>
|
<DependentUpon>CommentsPage.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Pages\Downloads.xaml.cs">
|
||||||
|
<DependentUpon>Downloads.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Pages\Feedback.xaml.cs">
|
<Compile Include="Pages\Feedback.xaml.cs">
|
||||||
<DependentUpon>Feedback.xaml</DependentUpon>
|
<DependentUpon>Feedback.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -173,6 +181,8 @@
|
|||||||
<Content Include="Assets\AnnouncementThumb.png" />
|
<Content Include="Assets\AnnouncementThumb.png" />
|
||||||
<Content Include="Assets\ChannelCoverTemplate.png" />
|
<Content Include="Assets\ChannelCoverTemplate.png" />
|
||||||
<Content Include="Assets\FoxGame.png" />
|
<Content Include="Assets\FoxGame.png" />
|
||||||
|
<Content Include="Assets\Icons\Profile.png" />
|
||||||
|
<Content Include="Assets\Icons\Send.png" />
|
||||||
<Content Include="Assets\LargeTile.scale-100.png" />
|
<Content Include="Assets\LargeTile.scale-100.png" />
|
||||||
<Content Include="Assets\LargeTile.scale-125.png" />
|
<Content Include="Assets\LargeTile.scale-125.png" />
|
||||||
<Content Include="Assets\LargeTile.scale-150.png" />
|
<Content Include="Assets\LargeTile.scale-150.png" />
|
||||||
@@ -217,6 +227,24 @@
|
|||||||
<Content Include="Assets\Wide310x150Logo.scale-125.png" />
|
<Content Include="Assets\Wide310x150Logo.scale-125.png" />
|
||||||
<Content Include="Assets\Wide310x150Logo.scale-150.png" />
|
<Content Include="Assets\Wide310x150Logo.scale-150.png" />
|
||||||
<Content Include="Assets\Wide310x150Logo.scale-400.png" />
|
<Content Include="Assets\Wide310x150Logo.scale-400.png" />
|
||||||
|
<Content Include="Notifications\Comment.xml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Notifications\Download.xml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Notifications\DownloadComplete.xml" />
|
||||||
|
<Content Include="Notifications\downloadHistorySample.xml" />
|
||||||
|
<Content Include="Notifications\Internal.xml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Notifications\Post.xml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Notifications\ServerLogSamlpe.xml" />
|
||||||
|
<Content Include="Notifications\Video.xml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Content>
|
||||||
<Content Include="Properties\Default.rd.xml" />
|
<Content Include="Properties\Default.rd.xml" />
|
||||||
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
||||||
<Content Include="Assets\SplashScreen.scale-200.png" />
|
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||||
@@ -234,6 +262,10 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="Controls\DownloadItem.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="Controls\SuggestionsQueries.xaml">
|
<Page Include="Controls\SuggestionsQueries.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
@@ -250,6 +282,10 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="Pages\Downloads.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="Pages\Feedback.xaml">
|
<Page Include="Pages\Feedback.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
@@ -343,6 +379,9 @@
|
|||||||
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls">
|
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls">
|
||||||
<Version>3.0.0</Version>
|
<Version>3.0.0</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="MyToolkit">
|
||||||
|
<Version>2.5.16</Version>
|
||||||
|
</PackageReference>
|
||||||
<PackageReference Include="MyToolkit.Extended">
|
<PackageReference Include="MyToolkit.Extended">
|
||||||
<Version>2.5.16</Version>
|
<Version>2.5.16</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
@@ -353,6 +392,12 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="FoxTube_TemporaryKey.pfx" />
|
<None Include="FoxTube_TemporaryKey.pfx" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\FoxTube.Background\FoxTube.Background.csproj">
|
||||||
|
<Project>{fc9128d7-e3aa-48ed-8641-629794b88b28}</Project>
|
||||||
|
<Name>FoxTube.Background</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<toast launch="action=openThread&threadId=92187">
|
||||||
|
<visual>
|
||||||
|
<binding template="ToastGeneric">
|
||||||
|
<image placement="appLogoOverride" hint-crop="circle" src="Assets/Icons/Profile.png"/>
|
||||||
|
<text>[ChannelName] posted a new comment</text>
|
||||||
|
<text>[VideoName]</text>
|
||||||
|
</binding>
|
||||||
|
</visual>
|
||||||
|
|
||||||
|
<actions>
|
||||||
|
<input id="textBox" type="text" placeHolderContent="Send a reply"/>
|
||||||
|
|
||||||
|
<action content="Send" imageUri="Assets/Icons/Send.png"
|
||||||
|
hint-inputId="textBox" activationType="background"
|
||||||
|
arguments="action=reply&threadId=92187"/>
|
||||||
|
|
||||||
|
<action content="Like"
|
||||||
|
arguments="action=commentPhoto&photoId=92187"/>
|
||||||
|
<action content="Go to comment"
|
||||||
|
arguments="action=commentPhoto&photoId=92187"/>
|
||||||
|
</actions>
|
||||||
|
</toast>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<toast launch="action=viewPhoto&photoId=92187">
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<toast launch="action=viewPhoto&photoId=92187">
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<toast launch="action=openThread&threadId=92187">
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<toast launch="action=openThread&threadId=92187">
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<posts>
|
||||||
|
<post time="YYYY-MM-DDThh:mm:ss-03" image="http://foxtube.hol.es/foxtube/FILE_NAME.png Hero image (not implemented yet)">
|
||||||
|
<notificationHeader>Short headline for toast notifications</notificationHeader>
|
||||||
|
<header>Main headline for full post</header>
|
||||||
|
<content>Announcement body (beware of special characters)</content>
|
||||||
|
</post>
|
||||||
|
</posts>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<toast launch="action=viewPhoto&photoId=92187">
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<downloads>
|
||||||
|
<item>
|
||||||
|
<title></title>
|
||||||
|
<snippet>
|
||||||
|
<quality></quality>
|
||||||
|
<duration></duration>
|
||||||
|
<author></author>
|
||||||
|
<image></image>
|
||||||
|
</snippet>
|
||||||
|
<details>
|
||||||
|
<path></path>
|
||||||
|
<id></id>
|
||||||
|
</details>
|
||||||
|
</item>
|
||||||
|
</downloads>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<Page
|
||||||
|
x:Class="FoxTube.Pages.Downloads"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="using:FoxTube.Pages"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
|
||||||
|
<Grid Padding="5">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock FontSize="28" Text="Downloads"/>
|
||||||
|
<Grid VerticalAlignment="Top">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Button Name="openFolder" Click="openFolder_Click" Content="Open folder" Margin="5"/>
|
||||||
|
<TextBlock Name="path" IsTextSelectionEnabled="True" Grid.Column="1" Text="C://Users/Admin/Downloads" VerticalAlignment="Center"/>
|
||||||
|
<Button Name="changePath" Click="changePath_Click" Grid.Column="2" Content="Change path" Margin="5"/>
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
<ScrollViewer Grid.Row="1">
|
||||||
|
<StackPanel Margin="5" Name="stack"/>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
</Page>
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
using FoxTube.Controls;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Foundation.Collections;
|
||||||
|
using Windows.Storage;
|
||||||
|
using Windows.Storage.Pickers;
|
||||||
|
using Windows.System;
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Controls.Primitives;
|
||||||
|
using Windows.UI.Xaml.Data;
|
||||||
|
using Windows.UI.Xaml.Input;
|
||||||
|
using Windows.UI.Xaml.Media;
|
||||||
|
using Windows.UI.Xaml.Navigation;
|
||||||
|
|
||||||
|
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
|
||||||
|
|
||||||
|
namespace FoxTube.Pages
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class Downloads : Page
|
||||||
|
{
|
||||||
|
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
||||||
|
public Downloads()
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
path.Text = settings.Values["defaultDownload"] as string;
|
||||||
|
|
||||||
|
foreach (DownloadItem item in Methods.MainPage.Agent.Items)
|
||||||
|
stack.Children.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void changePath_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
FolderPicker picker = new FolderPicker()
|
||||||
|
{
|
||||||
|
SuggestedStartLocation = PickerLocationId.Desktop,
|
||||||
|
ViewMode = PickerViewMode.Thumbnail
|
||||||
|
};
|
||||||
|
|
||||||
|
StorageFolder p = await picker.PickSingleFolderAsync();
|
||||||
|
if (p != null)
|
||||||
|
settings.Values["defaultDownload"] = p.Path;
|
||||||
|
path.Text = settings.Values["defaultDownload"] as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void openFolder_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
await Launcher.LaunchUriAsync(new Uri(settings.Values["defaultDownload"] as string));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,6 +55,7 @@ namespace FoxTube
|
|||||||
public sealed partial class MainPage : Page
|
public sealed partial class MainPage : Page
|
||||||
{
|
{
|
||||||
public SecretsVault Vault = new SecretsVault();
|
public SecretsVault Vault = new SecretsVault();
|
||||||
|
public DownloadAgent Agent = new DownloadAgent();
|
||||||
|
|
||||||
RightPaneState paneState = RightPaneState.Full;
|
RightPaneState paneState = RightPaneState.Full;
|
||||||
bool isForcedCollapsed = false;
|
bool isForcedCollapsed = false;
|
||||||
@@ -95,6 +96,9 @@ namespace FoxTube
|
|||||||
if (settings.Values["safeSearch"] == null)
|
if (settings.Values["safeSearch"] == null)
|
||||||
settings.Values.Add("safeSearch", 0);
|
settings.Values.Add("safeSearch", 0);
|
||||||
|
|
||||||
|
if (settings.Values["defaultDownload"] == null)
|
||||||
|
settings.Values.Add("defaultDownload", Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\DownloadedVideos");
|
||||||
|
|
||||||
content.Navigate(typeof(Home));
|
content.Navigate(typeof(Home));
|
||||||
|
|
||||||
Vault.AuthorizationStateChanged += Vault_AuthorizationStateChanged;
|
Vault.AuthorizationStateChanged += Vault_AuthorizationStateChanged;
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ namespace FoxTube
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
MessageDialog message = new MessageDialog("We was unable to send your feedback due to connection problems or internal server error. Please, try again later.", "Failed to send your feedback");
|
MessageDialog message = new MessageDialog("We were unable to send your feedback due to connection problems or internal server error. Please, try again later.", "Failed to send your feedback");
|
||||||
await message.ShowAsync();
|
await message.ShowAsync();
|
||||||
export.IsEnabled = true;
|
export.IsEnabled = true;
|
||||||
upload.IsEnabled = true;
|
upload.IsEnabled = true;
|
||||||
|
|||||||
@@ -87,20 +87,26 @@
|
|||||||
<CommandBar VerticalAlignment="Bottom" Name="commandbar">
|
<CommandBar VerticalAlignment="Bottom" Name="commandbar">
|
||||||
<AppBarButton Name="download" Icon="Download" Label="Download video">
|
<AppBarButton Name="download" Icon="Download" Label="Download video">
|
||||||
<AppBarButton.Flyout>
|
<AppBarButton.Flyout>
|
||||||
<MenuFlyout>
|
<MenuFlyout x:Name="downloadSelector">
|
||||||
<MenuFlyoutItem Text="Select quality:" IsEnabled="False"/>
|
<MenuFlyoutItem Text="Select quality:" IsEnabled="False"/>
|
||||||
<MenuFlyoutSeparator/>
|
<MenuFlyoutSeparator/>
|
||||||
<MenuFlyoutItem Text="No items are available" IsEnabled="False"/>
|
<MenuFlyoutItem Text="No items are available" IsEnabled="False"/>
|
||||||
</MenuFlyout>
|
</MenuFlyout>
|
||||||
</AppBarButton.Flyout>
|
</AppBarButton.Flyout>
|
||||||
</AppBarButton>
|
</AppBarButton>
|
||||||
<AppBarToggleButton Name="addLater" Icon="Clock" Label="Watch later" Visibility="Collapsed"/>
|
<AppBarToggleButton Name="addLater" Click="addLater_Click" Icon="Clock" Label="Watch later" Visibility="Collapsed"/>
|
||||||
<AppBarButton Name="refresh" Click="refresh_Click" Icon="Refresh" Label="Refresh page"/>
|
<AppBarButton Name="refresh" Click="refresh_Click" Icon="Refresh" Label="Refresh page"/>
|
||||||
<AppBarButton Name="share" Click="share_Click" Icon="Share" Label="Share"/>
|
<AppBarButton Name="share" Click="share_Click" Icon="Share" Label="Share"/>
|
||||||
<AppBarButton Name="openBrowser" Click="openBrowser_Click" Icon="Globe" Label="Open in browser"/>
|
<AppBarButton Name="openBrowser" Click="openBrowser_Click" Icon="Globe" Label="Open in browser"/>
|
||||||
|
|
||||||
<CommandBar.SecondaryCommands>
|
<CommandBar.SecondaryCommands>
|
||||||
<AppBarButton Name="addToPlaylist" Icon="Add" Label="Add to playlist" Visibility="Collapsed"/>
|
<AppBarButton Name="addToPlaylist" Click="addToPlaylist_Click" Icon="Add" Label="Add to playlist" Visibility="Collapsed">
|
||||||
|
<AppBarButton.Flyout>
|
||||||
|
<MenuFlyout>
|
||||||
|
|
||||||
|
</MenuFlyout>
|
||||||
|
</AppBarButton.Flyout>
|
||||||
|
</AppBarButton>
|
||||||
<AppBarButton Icon="Flag" Label="Report this video" Visibility="Collapsed"/>
|
<AppBarButton Icon="Flag" Label="Report this video" Visibility="Collapsed"/>
|
||||||
</CommandBar.SecondaryCommands>
|
</CommandBar.SecondaryCommands>
|
||||||
</CommandBar>
|
</CommandBar>
|
||||||
|
|||||||
+111
-4
@@ -30,6 +30,8 @@ using Windows.UI.Text;
|
|||||||
using Windows.UI;
|
using Windows.UI;
|
||||||
using FoxTube.Pages;
|
using FoxTube.Pages;
|
||||||
|
|
||||||
|
using MyToolkit.Multimedia;
|
||||||
|
|
||||||
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
|
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
|
||||||
|
|
||||||
namespace FoxTube
|
namespace FoxTube
|
||||||
@@ -41,11 +43,16 @@ namespace FoxTube
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class Video : Page
|
public sealed partial class Video : Page
|
||||||
{
|
{
|
||||||
|
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
|
||||||
|
|
||||||
string videoId;
|
string videoId;
|
||||||
Google.Apis.YouTube.v3.Data.Video item;
|
Google.Apis.YouTube.v3.Data.Video item;
|
||||||
|
|
||||||
|
List<string> downloads = new List<string>();
|
||||||
|
|
||||||
bool wide;
|
bool wide;
|
||||||
bool isExtended = false;
|
bool isExtended = false;
|
||||||
|
bool isAddedToLater = false;
|
||||||
|
|
||||||
Rating userRating = Rating.None;
|
Rating userRating = Rating.None;
|
||||||
|
|
||||||
@@ -82,6 +89,7 @@ namespace FoxTube
|
|||||||
grid.ColumnDefinitions[1].Width = new GridLength(0);
|
grid.ColumnDefinitions[1].Width = new GridLength(0);
|
||||||
|
|
||||||
pivot.SelectedIndex = 0;
|
pivot.SelectedIndex = 0;
|
||||||
|
pivot_SelectionChanged(this, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +150,8 @@ namespace FoxTube
|
|||||||
|
|
||||||
channelAvatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url));
|
channelAvatar.ProfilePicture = new BitmapImage(new Uri(item1.Snippet.Thumbnails.Medium.Url));
|
||||||
channelName.Text = item.Snippet.ChannelTitle;
|
channelName.Text = item.Snippet.ChannelTitle;
|
||||||
subscribers.Text = item1.Statistics.SubscriberCount + " subscribers";
|
subscribers.Text = string.Format("{0:0,0} subscribers", item1.Statistics.SubscriberCount);
|
||||||
|
|
||||||
|
|
||||||
if(SecretsVault.IsAuthorized)
|
if(SecretsVault.IsAuthorized)
|
||||||
{
|
{
|
||||||
@@ -157,6 +166,15 @@ namespace FoxTube
|
|||||||
userRating = Rating.Dislike;
|
userRating = Rating.Dislike;
|
||||||
dislike.Foreground = new SolidColorBrush(Colors.Red);
|
dislike.Foreground = new SolidColorBrush(Colors.Red);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*addLater.Visibility = Visibility.Visible;
|
||||||
|
addToPlaylist.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
|
if (SecretsVault.WatchLater.Contains(item.Id))
|
||||||
|
{
|
||||||
|
isAddedToLater = true;
|
||||||
|
addLater.IsChecked = true;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
player = new VideoPlayer(item, item1.Snippet.Thumbnails.Medium.Url);
|
player = new VideoPlayer(item, item1.Snippet.Thumbnails.Medium.Url);
|
||||||
@@ -164,11 +182,30 @@ namespace FoxTube
|
|||||||
|
|
||||||
playerPlaceholder.Children.Add(player);
|
playerPlaceholder.Children.Add(player);
|
||||||
|
|
||||||
|
LoadDownloads();
|
||||||
|
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
grid.Visibility = Visibility.Visible;
|
grid.Visibility = Visibility.Visible;
|
||||||
LoadingScreen.Visibility = Visibility.Collapsed;
|
LoadingScreen.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
LoadRelatedVideos();
|
LoadRelatedVideos();
|
||||||
|
|
||||||
|
if (SecretsVault.IsAuthorized && SecretsVault.UserHistory[0] != item.Id)
|
||||||
|
{
|
||||||
|
await SecretsVault.Service.PlaylistItems.Insert(new PlaylistItem()
|
||||||
|
{
|
||||||
|
Snippet = new PlaylistItemSnippet()
|
||||||
|
{
|
||||||
|
ResourceId = new ResourceId()
|
||||||
|
{
|
||||||
|
Kind = "youtube#video",
|
||||||
|
VideoId = item.Id
|
||||||
|
},
|
||||||
|
PlaylistId = SecretsVault.UserChannel.ContentDetails.RelatedPlaylists.WatchHistory
|
||||||
|
}
|
||||||
|
}, "snippet").ExecuteAsync();
|
||||||
|
SecretsVault.UserHistory.Insert(0, item.Id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -176,6 +213,46 @@ namespace FoxTube
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async void LoadDownloads()
|
||||||
|
{
|
||||||
|
Debug.WriteLine("Loading download options...");
|
||||||
|
downloadSelector.Items.Clear();
|
||||||
|
|
||||||
|
YouTubeUri[] uris = await YouTube.GetUrisAsync(item.Id);
|
||||||
|
if (uris.Length > 0)
|
||||||
|
foreach (YouTubeUri u in uris)
|
||||||
|
{
|
||||||
|
if (u.HasAudio && u.HasVideo)
|
||||||
|
{
|
||||||
|
downloads.Add(u.Uri.AbsoluteUri);
|
||||||
|
MenuFlyoutItem menuItem = new MenuFlyoutItem()
|
||||||
|
{
|
||||||
|
Text = Methods.QualityToString(u.VideoQuality)
|
||||||
|
};
|
||||||
|
menuItem.Click += downloadItemSelected;
|
||||||
|
downloadSelector.Items.Add(menuItem);
|
||||||
|
}
|
||||||
|
else if (u.HasAudio)
|
||||||
|
{
|
||||||
|
downloads.Add(u.Uri.AbsoluteUri);
|
||||||
|
MenuFlyoutItem menuItem = new MenuFlyoutItem()
|
||||||
|
{
|
||||||
|
Text = Methods.QualityToString(u.AudioQuality)
|
||||||
|
};
|
||||||
|
menuItem.Click += downloadItemSelected;
|
||||||
|
downloadSelector.Items.Add(menuItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
download.Visibility = Visibility.Collapsed;
|
||||||
|
Debug.WriteLine("Done");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadItemSelected(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
async void LoadRelatedVideos()
|
async void LoadRelatedVideos()
|
||||||
{
|
{
|
||||||
loadingRelated.Refresh();
|
loadingRelated.Refresh();
|
||||||
@@ -183,6 +260,7 @@ namespace FoxTube
|
|||||||
|
|
||||||
SearchResource.ListRequest request = SecretsVault.IsAuthorized? SecretsVault.Service.Search.List("snippet") : SecretsVault.NoAuthService.Search.List("snippet");
|
SearchResource.ListRequest request = SecretsVault.IsAuthorized? SecretsVault.Service.Search.List("snippet") : SecretsVault.NoAuthService.Search.List("snippet");
|
||||||
request.RelatedToVideoId = videoId;
|
request.RelatedToVideoId = videoId;
|
||||||
|
request.SafeSearch = (SearchResource.ListRequest.SafeSearchEnum)(int)settings.Values["safeSearch"];
|
||||||
request.MaxResults = 20;
|
request.MaxResults = 20;
|
||||||
request.Type = "video";
|
request.Type = "video";
|
||||||
|
|
||||||
@@ -297,8 +375,6 @@ namespace FoxTube
|
|||||||
|
|
||||||
toDescription.Visibility = Visibility.Collapsed;
|
toDescription.Visibility = Visibility.Collapsed;
|
||||||
grid.ColumnDefinitions[1].Width = new GridLength(400);
|
grid.ColumnDefinitions[1].Width = new GridLength(400);
|
||||||
|
|
||||||
pivot.SelectedIndex = 0;
|
|
||||||
}
|
}
|
||||||
else if (e.NewSize.Width <= 1000 & e.PreviousSize.Width > 1000)
|
else if (e.NewSize.Width <= 1000 & e.PreviousSize.Width > 1000)
|
||||||
{
|
{
|
||||||
@@ -317,9 +393,10 @@ namespace FoxTube
|
|||||||
|
|
||||||
toDescription.Visibility = Visibility.Visible;
|
toDescription.Visibility = Visibility.Visible;
|
||||||
grid.ColumnDefinitions[1].Width = new GridLength(0);
|
grid.ColumnDefinitions[1].Width = new GridLength(0);
|
||||||
|
}
|
||||||
|
|
||||||
pivot.SelectedIndex = 0;
|
pivot.SelectedIndex = 0;
|
||||||
}
|
pivot_SelectionChanged(this, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toDescription_Click(object sender, RoutedEventArgs e)
|
private void toDescription_Click(object sender, RoutedEventArgs e)
|
||||||
@@ -500,5 +577,35 @@ namespace FoxTube
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void addLater_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
isAddedToLater = !isAddedToLater;
|
||||||
|
if(isAddedToLater)
|
||||||
|
{
|
||||||
|
PlaylistItem pi = await SecretsVault.Service.PlaylistItems.Insert(new PlaylistItem()
|
||||||
|
{
|
||||||
|
Snippet = new PlaylistItemSnippet()
|
||||||
|
{
|
||||||
|
ResourceId = new ResourceId()
|
||||||
|
{
|
||||||
|
Kind = "youtube#video",
|
||||||
|
VideoId = item.Id
|
||||||
|
},
|
||||||
|
PlaylistId = SecretsVault.UserChannel.ContentDetails.RelatedPlaylists.WatchLater
|
||||||
|
}
|
||||||
|
}, "snippet").ExecuteAsync();
|
||||||
|
SecretsVault.WatchLater.Insert(0, new KeyValuePair<string, string>(pi.Id, item.Id));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//await SecretsVault.Service.PlaylistItems.Delete(SecretsVault.WatchLater[])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addToPlaylist_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user