From 96a7953500c65c403418511ef2ee9e5d4e69718a Mon Sep 17 00:00:00 2001 From: Mateusz Skoczek Date: Sat, 19 Feb 2022 01:38:37 +0100 Subject: [PATCH] 1.0-dev6 (Option bar added and code cleaned) --- .../Enums/AudioFileExtension.cs | 0 .../Enums/MediaFileExtension.cs | 0 .../Enums/MediaType.cs | 0 .../Enums/StreamType.cs | 0 .../Enums/VideoFileExtension.cs | 0 .../PlaylistSearchEventArgs.cs | 10 ++ .../EventArgsObjects/VideoSearchEventArgs.cs | 9 + .../TwitchAccessTokenNotFoundException.cs | 0 .../TwitchAccessTokenNotValidException.cs | 0 .../Interfaces/IAStream.cs | 6 +- .../Interfaces/IPlaylistService.cs | 8 +- .../Interfaces/IVStream.cs | 2 +- .../Interfaces/IVideoService.cs | 9 +- .../Objects}/Stream.cs | 30 ++-- .../Services/Config.cs | 8 +- .../Services/MediaProcessor.cs | 20 +-- .../Services/Sources/Twitch/Auth.cs | 1 - .../Services/Sources/Twitch/Channel.cs | 2 +- .../Services/Sources/Twitch/Clip.cs | 4 +- .../Services/Sources/Twitch/Vod.cs | 15 +- VDownload.Core/VDownload.Core.csproj | 169 ++++++++++++++++++ VDownload.sln | 30 ++++ VDownload/App.xaml.cs | 16 +- VDownload/Assets/Icons/MainPage/About.png | Bin 0 -> 44862 bytes .../{GUI => }/Controls/SettingControl.xaml | 24 +-- .../{GUI => }/Controls/SettingControl.xaml.cs | 39 ++-- VDownload/Core/Enums/LogMessageType.cs | 9 - VDownload/Core/Globals/Assets.cs | 13 -- VDownload/Core/Services/Log.cs | 35 ---- .../GUI/Controls/MainPageLayoutControl.xaml | 21 --- .../Controls/MainPageLayoutControl.xaml.cs | 39 ---- VDownload/GUI/Views/Home/HomeMain.xaml.cs | 46 ----- VDownload/GUI/Views/Sources/SourcesMain.xaml | 31 ---- VDownload/Strings/en-US/Resources.resw | 76 ++++++-- VDownload/VDownload.csproj | 98 +++++----- .../About/AboutMain.xaml} | 7 +- VDownload/Views/About/AboutMain.xaml.cs | 30 ++++ VDownload/Views/Home/HomeMain.xaml | 92 ++++++++++ VDownload/Views/Home/HomeMain.xaml.cs | 69 +++++++ .../HomeOptionsBarAddPlaylistControl.xaml | 38 ++++ .../HomeOptionsBarAddPlaylistControl.xaml.cs | 60 +++++++ .../Home/HomeOptionsBarAddVideoControl.xaml | 34 ++++ .../HomeOptionsBarAddVideoControl.xaml.cs | 55 ++++++ VDownload/{GUI => }/Views/MainPage.xaml | 15 +- VDownload/{GUI => }/Views/MainPage.xaml.cs | 23 +-- .../Views/Settings/SettingsMain.xaml | 2 +- .../Views/Settings/SettingsMain.xaml.cs | 2 +- VDownload/Views/Sources/SourcesMain.xaml | 35 ++++ .../Views/Sources/SourcesMain.xaml.cs | 43 ++--- .../Subscriptions/SubscriptionsMain.xaml | 2 +- .../Subscriptions/SubscriptionsMain.xaml.cs | 2 +- 51 files changed, 856 insertions(+), 423 deletions(-) rename {VDownload/Core => VDownload.Core}/Enums/AudioFileExtension.cs (100%) rename {VDownload/Core => VDownload.Core}/Enums/MediaFileExtension.cs (100%) rename {VDownload/Core => VDownload.Core}/Enums/MediaType.cs (100%) rename {VDownload/Core => VDownload.Core}/Enums/StreamType.cs (100%) rename {VDownload/Core => VDownload.Core}/Enums/VideoFileExtension.cs (100%) create mode 100644 VDownload.Core/EventArgsObjects/PlaylistSearchEventArgs.cs create mode 100644 VDownload.Core/EventArgsObjects/VideoSearchEventArgs.cs rename {VDownload/Core => VDownload.Core}/Exceptions/TwitchAccessTokenNotFoundException.cs (100%) rename {VDownload/Core => VDownload.Core}/Exceptions/TwitchAccessTokenNotValidException.cs (100%) rename {VDownload/Core => VDownload.Core}/Interfaces/IAStream.cs (70%) rename {VDownload/Core => VDownload.Core}/Interfaces/IPlaylistService.cs (67%) rename {VDownload/Core => VDownload.Core}/Interfaces/IVStream.cs (93%) rename {VDownload/Core => VDownload.Core}/Interfaces/IVideoService.cs (97%) rename {VDownload/Core/Models => VDownload.Core/Objects}/Stream.cs (93%) rename {VDownload/Core => VDownload.Core}/Services/Config.cs (91%) rename {VDownload/Core => VDownload.Core}/Services/MediaProcessor.cs (99%) rename {VDownload/Core => VDownload.Core}/Services/Sources/Twitch/Auth.cs (99%) rename {VDownload/Core => VDownload.Core}/Services/Sources/Twitch/Channel.cs (99%) rename {VDownload/Core => VDownload.Core}/Services/Sources/Twitch/Clip.cs (99%) rename {VDownload/Core => VDownload.Core}/Services/Sources/Twitch/Vod.cs (95%) create mode 100644 VDownload.Core/VDownload.Core.csproj create mode 100644 VDownload/Assets/Icons/MainPage/About.png rename VDownload/{GUI => }/Controls/SettingControl.xaml (77%) rename VDownload/{GUI => }/Controls/SettingControl.xaml.cs (58%) delete mode 100644 VDownload/Core/Enums/LogMessageType.cs delete mode 100644 VDownload/Core/Globals/Assets.cs delete mode 100644 VDownload/Core/Services/Log.cs delete mode 100644 VDownload/GUI/Controls/MainPageLayoutControl.xaml delete mode 100644 VDownload/GUI/Controls/MainPageLayoutControl.xaml.cs delete mode 100644 VDownload/GUI/Views/Home/HomeMain.xaml.cs delete mode 100644 VDownload/GUI/Views/Sources/SourcesMain.xaml rename VDownload/{GUI/Views/Home/HomeMain.xaml => Views/About/AboutMain.xaml} (66%) create mode 100644 VDownload/Views/About/AboutMain.xaml.cs create mode 100644 VDownload/Views/Home/HomeMain.xaml create mode 100644 VDownload/Views/Home/HomeMain.xaml.cs create mode 100644 VDownload/Views/Home/HomeOptionsBarAddPlaylistControl.xaml create mode 100644 VDownload/Views/Home/HomeOptionsBarAddPlaylistControl.xaml.cs create mode 100644 VDownload/Views/Home/HomeOptionsBarAddVideoControl.xaml create mode 100644 VDownload/Views/Home/HomeOptionsBarAddVideoControl.xaml.cs rename VDownload/{GUI => }/Views/MainPage.xaml (85%) rename VDownload/{GUI => }/Views/MainPage.xaml.cs (76%) rename VDownload/{GUI => }/Views/Settings/SettingsMain.xaml (88%) rename VDownload/{GUI => }/Views/Settings/SettingsMain.xaml.cs (95%) create mode 100644 VDownload/Views/Sources/SourcesMain.xaml rename VDownload/{GUI => }/Views/Sources/SourcesMain.xaml.cs (73%) rename VDownload/{GUI => }/Views/Subscriptions/SubscriptionsMain.xaml (87%) rename VDownload/{GUI => }/Views/Subscriptions/SubscriptionsMain.xaml.cs (94%) diff --git a/VDownload/Core/Enums/AudioFileExtension.cs b/VDownload.Core/Enums/AudioFileExtension.cs similarity index 100% rename from VDownload/Core/Enums/AudioFileExtension.cs rename to VDownload.Core/Enums/AudioFileExtension.cs diff --git a/VDownload/Core/Enums/MediaFileExtension.cs b/VDownload.Core/Enums/MediaFileExtension.cs similarity index 100% rename from VDownload/Core/Enums/MediaFileExtension.cs rename to VDownload.Core/Enums/MediaFileExtension.cs diff --git a/VDownload/Core/Enums/MediaType.cs b/VDownload.Core/Enums/MediaType.cs similarity index 100% rename from VDownload/Core/Enums/MediaType.cs rename to VDownload.Core/Enums/MediaType.cs diff --git a/VDownload/Core/Enums/StreamType.cs b/VDownload.Core/Enums/StreamType.cs similarity index 100% rename from VDownload/Core/Enums/StreamType.cs rename to VDownload.Core/Enums/StreamType.cs diff --git a/VDownload/Core/Enums/VideoFileExtension.cs b/VDownload.Core/Enums/VideoFileExtension.cs similarity index 100% rename from VDownload/Core/Enums/VideoFileExtension.cs rename to VDownload.Core/Enums/VideoFileExtension.cs diff --git a/VDownload.Core/EventArgsObjects/PlaylistSearchEventArgs.cs b/VDownload.Core/EventArgsObjects/PlaylistSearchEventArgs.cs new file mode 100644 index 0000000..9a2e598 --- /dev/null +++ b/VDownload.Core/EventArgsObjects/PlaylistSearchEventArgs.cs @@ -0,0 +1,10 @@ +using System; + +namespace VDownload.Core.EventArgsObjects +{ + public class PlaylistSearchEventArgs : EventArgs + { + public string Phrase { get; set; } + public int Count { get; set; } + } +} diff --git a/VDownload.Core/EventArgsObjects/VideoSearchEventArgs.cs b/VDownload.Core/EventArgsObjects/VideoSearchEventArgs.cs new file mode 100644 index 0000000..c0d47e4 --- /dev/null +++ b/VDownload.Core/EventArgsObjects/VideoSearchEventArgs.cs @@ -0,0 +1,9 @@ +using System; + +namespace VDownload.Core.EventArgsObjects +{ + public class VideoSearchEventArgs : EventArgs + { + public string Phrase { get; set; } + } +} diff --git a/VDownload/Core/Exceptions/TwitchAccessTokenNotFoundException.cs b/VDownload.Core/Exceptions/TwitchAccessTokenNotFoundException.cs similarity index 100% rename from VDownload/Core/Exceptions/TwitchAccessTokenNotFoundException.cs rename to VDownload.Core/Exceptions/TwitchAccessTokenNotFoundException.cs diff --git a/VDownload/Core/Exceptions/TwitchAccessTokenNotValidException.cs b/VDownload.Core/Exceptions/TwitchAccessTokenNotValidException.cs similarity index 100% rename from VDownload/Core/Exceptions/TwitchAccessTokenNotValidException.cs rename to VDownload.Core/Exceptions/TwitchAccessTokenNotValidException.cs diff --git a/VDownload/Core/Interfaces/IAStream.cs b/VDownload.Core/Interfaces/IAStream.cs similarity index 70% rename from VDownload/Core/Interfaces/IAStream.cs rename to VDownload.Core/Interfaces/IAStream.cs index ef404b5..fc8a86f 100644 --- a/VDownload/Core/Interfaces/IAStream.cs +++ b/VDownload.Core/Interfaces/IAStream.cs @@ -1,15 +1,11 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using VDownload.Core.Enums; namespace VDownload.Core.Interfaces { public interface IAStream { - #region PARAMETERS + #region PROPERTIES Uri Url { get; } bool IsChunked { get; } diff --git a/VDownload/Core/Interfaces/IPlaylistService.cs b/VDownload.Core/Interfaces/IPlaylistService.cs similarity index 67% rename from VDownload/Core/Interfaces/IPlaylistService.cs rename to VDownload.Core/Interfaces/IPlaylistService.cs index 0d43580..76ab2bd 100644 --- a/VDownload/Core/Interfaces/IPlaylistService.cs +++ b/VDownload.Core/Interfaces/IPlaylistService.cs @@ -1,14 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Threading.Tasks; namespace VDownload.Core.Interfaces { internal interface IPlaylistService { - #region PARAMETERS + #region PROPERTIES string ID { get; } string Name { get; } diff --git a/VDownload/Core/Interfaces/IVStream.cs b/VDownload.Core/Interfaces/IVStream.cs similarity index 93% rename from VDownload/Core/Interfaces/IVStream.cs rename to VDownload.Core/Interfaces/IVStream.cs index 5e1c344..d35b57b 100644 --- a/VDownload/Core/Interfaces/IVStream.cs +++ b/VDownload.Core/Interfaces/IVStream.cs @@ -5,7 +5,7 @@ namespace VDownload.Core.Interfaces { public interface IVStream { - #region PARAMETERS + #region PROPERTIES Uri Url { get; } bool IsChunked { get; } diff --git a/VDownload/Core/Interfaces/IVideoService.cs b/VDownload.Core/Interfaces/IVideoService.cs similarity index 97% rename from VDownload/Core/Interfaces/IVideoService.cs rename to VDownload.Core/Interfaces/IVideoService.cs index 9c007e4..19a1735 100644 --- a/VDownload/Core/Interfaces/IVideoService.cs +++ b/VDownload.Core/Interfaces/IVideoService.cs @@ -3,14 +3,14 @@ using System.ComponentModel; using System.Threading; using System.Threading.Tasks; using VDownload.Core.Enums; -using VDownload.Core.Models; +using VDownload.Core.Objects; using Windows.Storage; namespace VDownload.Core.Interfaces { public interface IVideoService { - #region PARAMETERS + #region PROPERTIES string ID { get; } string Title { get; } @@ -49,15 +49,10 @@ namespace VDownload.Core.Interfaces #region EVENT HANDLERS event EventHandler DownloadingStarted; - event EventHandler DownloadingProgressChanged; - event EventHandler DownloadingCompleted; - event EventHandler ProcessingStarted; - event EventHandler ProcessingProgressChanged; - event EventHandler ProcessingCompleted; #endregion diff --git a/VDownload/Core/Models/Stream.cs b/VDownload.Core/Objects/Stream.cs similarity index 93% rename from VDownload/Core/Models/Stream.cs rename to VDownload.Core/Objects/Stream.cs index a4dca63..3bb97d0 100644 --- a/VDownload/Core/Models/Stream.cs +++ b/VDownload.Core/Objects/Stream.cs @@ -2,11 +2,24 @@ using VDownload.Core.Enums; using VDownload.Core.Interfaces; -namespace VDownload.Core.Models +namespace VDownload.Core.Objects { public class Stream : IVStream, IAStream { - #region PARAMETERS + #region CONSTRUCTORS + + public Stream(Uri url, bool isChunked, StreamType streamType) + { + Url = url; + IsChunked = isChunked; + StreamType = streamType; + } + + #endregion + + + + #region PROPERTIES public Uri Url { get; private set; } public bool IsChunked { get; private set; } @@ -19,18 +32,5 @@ namespace VDownload.Core.Models public string AudioCodec { get; set; } #endregion - - - - #region CONSTRUCTORS - - public Stream(Uri url, bool isChunked, StreamType streamType) - { - Url = url; - IsChunked = isChunked; - StreamType = streamType; - } - - #endregion } } diff --git a/VDownload/Core/Services/Config.cs b/VDownload.Core/Services/Config.cs similarity index 91% rename from VDownload/Core/Services/Config.cs rename to VDownload.Core/Services/Config.cs index 61d8341..2a0e20b 100644 --- a/VDownload/Core/Services/Config.cs +++ b/VDownload.Core/Services/Config.cs @@ -1,14 +1,11 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Windows.Media.Editing; using Windows.Storage; namespace VDownload.Core.Services { - internal class Config + public class Config { #region CONSTANTS @@ -25,7 +22,8 @@ namespace VDownload.Core.Services { "twitch_vod_downloading_chunk_retries_delay", 5000 }, { "media_transcoding_use_hardware_acceleration", true }, { "media_transcoding_use_mrfcrf444_algorithm", true }, - { "media_editing_algorithm", MediaTrimmingPreference.Fast } + { "media_editing_algorithm", (int)MediaTrimmingPreference.Fast }, + { "default_max_playlist_videos", 0 }, }; #endregion diff --git a/VDownload/Core/Services/MediaProcessor.cs b/VDownload.Core/Services/MediaProcessor.cs similarity index 99% rename from VDownload/Core/Services/MediaProcessor.cs rename to VDownload.Core/Services/MediaProcessor.cs index 0fadcc4..9a6cdc2 100644 --- a/VDownload/Core/Services/MediaProcessor.cs +++ b/VDownload.Core/Services/MediaProcessor.cs @@ -15,16 +15,6 @@ namespace VDownload.Core.Services { public class MediaProcessor { - #region PARAMETERS - - public StorageFile OutputFile { get; private set; } - public TimeSpan TrimStart { get; private set; } - public TimeSpan TrimEnd { get; private set; } - - #endregion - - - #region CONSTRUCTOR public MediaProcessor(StorageFile outputFile, TimeSpan trimStart, TimeSpan trimEnd) @@ -38,6 +28,16 @@ namespace VDownload.Core.Services + #region PROPERTIES + + public StorageFile OutputFile { get; private set; } + public TimeSpan TrimStart { get; private set; } + public TimeSpan TrimEnd { get; private set; } + + #endregion + + + #region STANDARD METHODS public async Task Run(StorageFile audioVideoInputFile, MediaFileExtension extension, MediaType mediaType, CancellationToken cancellationToken = default) diff --git a/VDownload/Core/Services/Sources/Twitch/Auth.cs b/VDownload.Core/Services/Sources/Twitch/Auth.cs similarity index 99% rename from VDownload/Core/Services/Sources/Twitch/Auth.cs rename to VDownload.Core/Services/Sources/Twitch/Auth.cs index 59671de..5c3c03d 100644 --- a/VDownload/Core/Services/Sources/Twitch/Auth.cs +++ b/VDownload.Core/Services/Sources/Twitch/Auth.cs @@ -14,7 +14,6 @@ namespace VDownload.Core.Services.Sources.Twitch { public class Auth { - #region CONSTANTS // CLIENT ID diff --git a/VDownload/Core/Services/Sources/Twitch/Channel.cs b/VDownload.Core/Services/Sources/Twitch/Channel.cs similarity index 99% rename from VDownload/Core/Services/Sources/Twitch/Channel.cs rename to VDownload.Core/Services/Sources/Twitch/Channel.cs index 3e21bb2..e435e40 100644 --- a/VDownload/Core/Services/Sources/Twitch/Channel.cs +++ b/VDownload.Core/Services/Sources/Twitch/Channel.cs @@ -24,7 +24,7 @@ namespace VDownload.Core.Services.Sources.Twitch - #region PARAMETERS + #region PROPERTIES public string ID { get; private set; } public string Name { get; private set; } diff --git a/VDownload/Core/Services/Sources/Twitch/Clip.cs b/VDownload.Core/Services/Sources/Twitch/Clip.cs similarity index 99% rename from VDownload/Core/Services/Sources/Twitch/Clip.cs rename to VDownload.Core/Services/Sources/Twitch/Clip.cs index 739da9c..71511a1 100644 --- a/VDownload/Core/Services/Sources/Twitch/Clip.cs +++ b/VDownload.Core/Services/Sources/Twitch/Clip.cs @@ -12,7 +12,7 @@ using System.Web; using VDownload.Core.Enums; using VDownload.Core.Exceptions; using VDownload.Core.Interfaces; -using VDownload.Core.Models; +using VDownload.Core.Objects; using Windows.Storage; namespace VDownload.Core.Services.Sources.Twitch @@ -38,7 +38,7 @@ namespace VDownload.Core.Services.Sources.Twitch - #region PARAMETERS + #region PROPERTIES public string ID { get; private set; } public string Title { get; private set; } diff --git a/VDownload/Core/Services/Sources/Twitch/Vod.cs b/VDownload.Core/Services/Sources/Twitch/Vod.cs similarity index 95% rename from VDownload/Core/Services/Sources/Twitch/Vod.cs rename to VDownload.Core/Services/Sources/Twitch/Vod.cs index a734f08..8a98905 100644 --- a/VDownload/Core/Services/Sources/Twitch/Vod.cs +++ b/VDownload.Core/Services/Sources/Twitch/Vod.cs @@ -11,7 +11,7 @@ using System.Threading.Tasks; using VDownload.Core.Enums; using VDownload.Core.Exceptions; using VDownload.Core.Interfaces; -using VDownload.Core.Models; +using VDownload.Core.Objects; using Windows.Storage; namespace VDownload.Core.Services.Sources.Twitch @@ -49,7 +49,7 @@ namespace VDownload.Core.Services.Sources.Twitch - #region PARAMETERS + #region PROPERTIES public string ID { get; private set; } public string Title { get; private set; } @@ -87,14 +87,9 @@ namespace VDownload.Core.Services.Sources.Twitch JToken response = JObject.Parse(await client.DownloadStringTaskAsync("https://api.twitch.tv/helix/videos")).GetValue("data")[0]; // Set parameters - Title = ((string)response["title"]).Replace("\n", ""); - Author = (string)response["user_name"]; - Date = Convert.ToDateTime(response["created_at"]); - Duration = TimeSpan.ParseExact((string)response["duration"], TimeFormats, null); - Views = (long)response["view_count"]; - Thumbnail = (string)response["thumbnail_url"] == string.Empty ? Globals.Assets.UnknownThumbnailImage : new Uri((string)response["thumbnail_url"]); + GetMetadataAsync(response); } - public void GetMetadataAsync(JToken response) + internal void GetMetadataAsync(JToken response) { // Set parameters Title = ((string)response["title"]).Replace("\n", ""); @@ -102,7 +97,7 @@ namespace VDownload.Core.Services.Sources.Twitch Date = Convert.ToDateTime(response["created_at"]); Duration = TimeSpan.ParseExact((string)response["duration"], TimeFormats, null); Views = (long)response["view_count"]; - Thumbnail = (string)response["thumbnail_url"] == string.Empty ? Globals.Assets.UnknownThumbnailImage : new Uri((string)response["thumbnail_url"]); + Thumbnail = (string)response["thumbnail_url"] == string.Empty ? null : new Uri((string)response["thumbnail_url"]); } // GET VOD STREAMS diff --git a/VDownload.Core/VDownload.Core.csproj b/VDownload.Core/VDownload.Core.csproj new file mode 100644 index 0000000..4196b29 --- /dev/null +++ b/VDownload.Core/VDownload.Core.csproj @@ -0,0 +1,169 @@ + + + + + Debug + AnyCPU + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8} + Library + Properties + VDownload.Core + VDownload.Core + en-US + UAP + 10.0.22000.0 + 10.0.18362.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + prompt + 4 + + + x86 + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + x86 + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + ARM + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + ARM + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + ARM64 + true + bin\ARM64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + ARM64 + bin\ARM64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + x64 + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + x64 + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + PackageReference + + + + + + + + + + + + + + + + + + + + + + + + + + 6.2.13 + + + 13.0.1 + + + 4.5.0 + + + + + + + 14.0 + + + + \ No newline at end of file diff --git a/VDownload.sln b/VDownload.sln index 66d5080..152e090 100644 --- a/VDownload.sln +++ b/VDownload.sln @@ -10,18 +10,25 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .editorconfig = .editorconfig EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VDownload.Core", "VDownload.Core\VDownload.Core.csproj", "{65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU Debug|ARM = Debug|ARM Debug|ARM64 = Debug|ARM64 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU Release|ARM = Release|ARM Release|ARM64 = Release|ARM64 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {324AB81A-F68D-424D-B90E-5402F5E44240}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {324AB81A-F68D-424D-B90E-5402F5E44240}.Debug|Any CPU.Build.0 = Debug|Any CPU + {324AB81A-F68D-424D-B90E-5402F5E44240}.Debug|Any CPU.Deploy.0 = Debug|Any CPU {324AB81A-F68D-424D-B90E-5402F5E44240}.Debug|ARM.ActiveCfg = Debug|ARM {324AB81A-F68D-424D-B90E-5402F5E44240}.Debug|ARM.Build.0 = Debug|ARM {324AB81A-F68D-424D-B90E-5402F5E44240}.Debug|ARM.Deploy.0 = Debug|ARM @@ -34,6 +41,9 @@ Global {324AB81A-F68D-424D-B90E-5402F5E44240}.Debug|x86.ActiveCfg = Debug|x86 {324AB81A-F68D-424D-B90E-5402F5E44240}.Debug|x86.Build.0 = Debug|x86 {324AB81A-F68D-424D-B90E-5402F5E44240}.Debug|x86.Deploy.0 = Debug|x86 + {324AB81A-F68D-424D-B90E-5402F5E44240}.Release|Any CPU.ActiveCfg = Release|Any CPU + {324AB81A-F68D-424D-B90E-5402F5E44240}.Release|Any CPU.Build.0 = Release|Any CPU + {324AB81A-F68D-424D-B90E-5402F5E44240}.Release|Any CPU.Deploy.0 = Release|Any CPU {324AB81A-F68D-424D-B90E-5402F5E44240}.Release|ARM.ActiveCfg = Release|ARM {324AB81A-F68D-424D-B90E-5402F5E44240}.Release|ARM.Build.0 = Release|ARM {324AB81A-F68D-424D-B90E-5402F5E44240}.Release|ARM.Deploy.0 = Release|ARM @@ -46,6 +56,26 @@ Global {324AB81A-F68D-424D-B90E-5402F5E44240}.Release|x86.ActiveCfg = Release|x86 {324AB81A-F68D-424D-B90E-5402F5E44240}.Release|x86.Build.0 = Release|x86 {324AB81A-F68D-424D-B90E-5402F5E44240}.Release|x86.Deploy.0 = Release|x86 + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Debug|ARM.ActiveCfg = Debug|ARM + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Debug|ARM.Build.0 = Debug|ARM + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Debug|ARM64.Build.0 = Debug|ARM64 + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Debug|x64.ActiveCfg = Debug|x64 + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Debug|x64.Build.0 = Debug|x64 + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Debug|x86.ActiveCfg = Debug|x86 + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Debug|x86.Build.0 = Debug|x86 + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Release|Any CPU.Build.0 = Release|Any CPU + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Release|ARM.ActiveCfg = Release|ARM + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Release|ARM.Build.0 = Release|ARM + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Release|ARM64.ActiveCfg = Release|ARM64 + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Release|ARM64.Build.0 = Release|ARM64 + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Release|x64.ActiveCfg = Release|x64 + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Release|x64.Build.0 = Release|x64 + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Release|x86.ActiveCfg = Release|x86 + {65C44D96-9C6C-47AD-A1F5-86BFAF2B15B8}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/VDownload/App.xaml.cs b/VDownload/App.xaml.cs index 19bb81a..53fdb16 100644 --- a/VDownload/App.xaml.cs +++ b/VDownload/App.xaml.cs @@ -25,30 +25,16 @@ namespace VDownload protected override async void OnLaunched(LaunchActivatedEventArgs e) { - Log.AddHeader("APP LAUNCHED"); - Log.Break(); - // Rebuild configuration file - Log.AddHeader("REBUILDING CONFIGURATION FILE"); - Config.Rebuild(); - Log.Add("Configuration file rebuilded successfully"); - Log.Break(); - - // Delete temp on start - // TODO - Debug.WriteLine(Config.GetValue("delete_temp_on_start")); if ((bool)Config.GetValue("delete_temp_on_start")) { - Log.AddHeader("DELETING TEMPORARY FILES"); IReadOnlyList tempItems = await ApplicationData.Current.TemporaryFolder.GetItemsAsync(); List tasks = new List(); foreach (IStorageItem item in tempItems) tasks.Add(item.DeleteAsync().AsTask()); await Task.WhenAll(tasks); - Log.Add("Temporary files deleted successfully"); - Log.Break(); } // Do not repeat app initialization when the Window already has content, @@ -70,7 +56,7 @@ namespace VDownload // When the navigation stack isn't restored navigate to the first page, // configuring the new page by passing required information as a navigation // parameter - rootFrame.Navigate(typeof(GUI.Views.MainPage), e.Arguments); + rootFrame.Navigate(typeof(Views.MainPage), e.Arguments); } // Ensure the current window is active diff --git a/VDownload/Assets/Icons/MainPage/About.png b/VDownload/Assets/Icons/MainPage/About.png new file mode 100644 index 0000000000000000000000000000000000000000..dceb0159d06c56a85248e1dd230fc1c24bc405eb GIT binary patch literal 44862 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 + + @@ -15,11 +17,13 @@ - + + + @@ -28,21 +32,21 @@ - + - - - + + + - + - - + + diff --git a/VDownload/GUI/Controls/SettingControl.xaml.cs b/VDownload/Controls/SettingControl.xaml.cs similarity index 58% rename from VDownload/GUI/Controls/SettingControl.xaml.cs rename to VDownload/Controls/SettingControl.xaml.cs index 4c951ab..74b2ac0 100644 --- a/VDownload/GUI/Controls/SettingControl.xaml.cs +++ b/VDownload/Controls/SettingControl.xaml.cs @@ -1,34 +1,24 @@ -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; +using Windows.UI; using Windows.UI.Xaml; -using Windows.UI.Xaml.Automation; 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 User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 - -namespace VDownload.GUI.Controls +namespace VDownload.Controls { public sealed partial class SettingControl : UserControl { - // INIT + #region CONSTRUCTORS + public SettingControl() { this.InitializeComponent(); } - // SETTING CONTENT - public FrameworkElement SettingContent { get; set; } + #endregion + + + + #region PROPERTIES // ICON public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(IconElement), typeof(SettingControl), new PropertyMetadata(null)); @@ -54,12 +44,9 @@ namespace VDownload.GUI.Controls set => SetValue(DescriptionProperty, value); } - // DESCRIPTION COLOR - public static readonly DependencyProperty DescriptionColorProperty = DependencyProperty.Register("DescriptionColor", typeof(Brush), typeof(SettingControl), new PropertyMetadata(new SolidColorBrush((Color)Application.Current.Resources["SystemBaseMediumColor"]))); - public Brush DescriptionColor - { - get => (Brush)GetValue(DescriptionColorProperty); - set => SetValue(DescriptionColorProperty, value); - } + // SETTING CONTENT + public FrameworkElement SettingContent { get; set; } + + #endregion } } diff --git a/VDownload/Core/Enums/LogMessageType.cs b/VDownload/Core/Enums/LogMessageType.cs deleted file mode 100644 index a7b1d24..0000000 --- a/VDownload/Core/Enums/LogMessageType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace VDownload.Core.Enums -{ - public enum LogMessageType - { - Header, - Normal, - Break, - } -} diff --git a/VDownload/Core/Globals/Assets.cs b/VDownload/Core/Globals/Assets.cs deleted file mode 100644 index f47277a..0000000 --- a/VDownload/Core/Globals/Assets.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace VDownload.Core.Globals -{ - public static class Assets - { - public static readonly Uri UnknownThumbnailImage = new Uri("ms-appx:///Assets/Other/UnknownThumbnail.png"); - } -} diff --git a/VDownload/Core/Services/Log.cs b/VDownload/Core/Services/Log.cs deleted file mode 100644 index e1b8a1a..0000000 --- a/VDownload/Core/Services/Log.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using VDownload.Core.Enums; - -namespace VDownload.Core.Services -{ - public class Log - { - private static List<(DateTime? Time, string Message, LogMessageType MessageType)> MessageList = new List<(DateTime? Time, string Message, LogMessageType MessageType)>(); - - public static void AddHeader(string message) - { - MessageList.Add((DateTime.Now, message, LogMessageType.Header)); - Debug.WriteLine(message); - } - - public static void Add(string message) - { - MessageList.Add((DateTime.Now, message, LogMessageType.Normal)); - Debug.WriteLine(message); - } - - public static void Break() - { - MessageList.Add((null, string.Empty, LogMessageType.Break)); - } - - - public static void Clear() - { - MessageList.Clear(); - } - } -} diff --git a/VDownload/GUI/Controls/MainPageLayoutControl.xaml b/VDownload/GUI/Controls/MainPageLayoutControl.xaml deleted file mode 100644 index df95278..0000000 --- a/VDownload/GUI/Controls/MainPageLayoutControl.xaml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - diff --git a/VDownload/GUI/Controls/MainPageLayoutControl.xaml.cs b/VDownload/GUI/Controls/MainPageLayoutControl.xaml.cs deleted file mode 100644 index 9d63ccc..0000000 --- a/VDownload/GUI/Controls/MainPageLayoutControl.xaml.cs +++ /dev/null @@ -1,39 +0,0 @@ -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; - -// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 - -namespace VDownload.GUI.Controls -{ - public sealed partial class MainPageLayoutControl : UserControl - { - // INIT - public MainPageLayoutControl() - { - this.InitializeComponent(); - } - - // PAGE CONTENT - public FrameworkElement PageContent { get; set; } - - // TITLE - public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(MainPageLayoutControl), new PropertyMetadata(string.Empty)); - public string Title - { - get => (string)GetValue(TitleProperty); - set => SetValue(TitleProperty, value); - } - } -} diff --git a/VDownload/GUI/Views/Home/HomeMain.xaml.cs b/VDownload/GUI/Views/Home/HomeMain.xaml.cs deleted file mode 100644 index a34cd91..0000000 --- a/VDownload/GUI/Views/Home/HomeMain.xaml.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using VDownload.Core.Enums; -using VDownload.Core.Interfaces; -using Windows.Foundation; -using Windows.Foundation.Collections; -using Windows.Storage; -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 VDownload.GUI.Views.Home -{ - /// - /// An empty page that can be used on its own or navigated to within a Frame. - /// - public sealed partial class HomeMain : Page - { - public HomeMain() - { - this.InitializeComponent(); - } - - private async void Button_Click(object sender, RoutedEventArgs e) - { - IPlaylistService videoServices = new Core.Services.Sources.Twitch.Channel("jacexdowozwideo"); - await videoServices.GetMetadataAsync(); - Stopwatch sw = Stopwatch.StartNew(); - await videoServices.GetVideosAsync(500); - sw.Stop(); - Debug.WriteLine(((Core.Services.Sources.Twitch.Channel)videoServices).Videos.Length); - Debug.WriteLine(sw.Elapsed.TotalSeconds); - - } - } -} diff --git a/VDownload/GUI/Views/Sources/SourcesMain.xaml b/VDownload/GUI/Views/Sources/SourcesMain.xaml deleted file mode 100644 index 7a4cfbb..0000000 --- a/VDownload/GUI/Views/Sources/SourcesMain.xaml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - + + diff --git a/VDownload/Views/Home/HomeOptionsBarAddPlaylistControl.xaml.cs b/VDownload/Views/Home/HomeOptionsBarAddPlaylistControl.xaml.cs new file mode 100644 index 0000000..7503ee9 --- /dev/null +++ b/VDownload/Views/Home/HomeOptionsBarAddPlaylistControl.xaml.cs @@ -0,0 +1,60 @@ +using System; +using VDownload.Core.EventArgsObjects; +using VDownload.Core.Services; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; + +namespace VDownload.Views.Home +{ + public sealed partial class HomeOptionsBarAddPlaylistControl : UserControl + { + #region CONSTRUCTORS + + public HomeOptionsBarAddPlaylistControl() + { + this.InitializeComponent(); + } + + #endregion + + + + #region PROPERTIES + + // MAX VIDEOS NUMBERBOX DEFAULT VALUE + public int DefaultMaxPlaylistVideos = (int)Config.GetValue("default_max_playlist_videos"); + + // SEARCH BUTTON EVENT HANDLER + public event EventHandler SearchButtonClicked; + + #endregion + + + + #region EVENT HANDLERS + + // SEARCH BUTTON CLICKED + private void HomeOptionsBarAddPlaylistControlSearchButton_Click(object sender, RoutedEventArgs e) + { + // Close info box + HomeOptionsBarAddPlaylistControlInfoBox.IsOpen = false; + + // Invoke search button event handlers + PlaylistSearchEventArgs args = new PlaylistSearchEventArgs + { + Phrase = HomeOptionsBarAddPlaylistControlUrlTextBox.Text, + Count = int.Parse(HomeOptionsBarAddPlaylistControlMaxVideosNumberBox.Text), + }; + SearchButtonClicked?.Invoke(this, args); + } + + // HELP BUTTON CLICKED + private void HomeOptionsBarAddPlaylistControlHelpButton_Click(object sender, RoutedEventArgs e) + { + // Switch info box + HomeOptionsBarAddPlaylistControlInfoBox.IsOpen = !HomeOptionsBarAddPlaylistControlInfoBox.IsOpen; + } + + #endregion + } +} diff --git a/VDownload/Views/Home/HomeOptionsBarAddVideoControl.xaml b/VDownload/Views/Home/HomeOptionsBarAddVideoControl.xaml new file mode 100644 index 0000000..4051cc5 --- /dev/null +++ b/VDownload/Views/Home/HomeOptionsBarAddVideoControl.xaml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + diff --git a/VDownload/Views/Home/HomeOptionsBarAddVideoControl.xaml.cs b/VDownload/Views/Home/HomeOptionsBarAddVideoControl.xaml.cs new file mode 100644 index 0000000..a99852a --- /dev/null +++ b/VDownload/Views/Home/HomeOptionsBarAddVideoControl.xaml.cs @@ -0,0 +1,55 @@ +using System; +using VDownload.Core.EventArgsObjects; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; + +namespace VDownload.Views.Home +{ + public sealed partial class HomeOptionsBarAddVideoControl : UserControl + { + #region CONSTRUCTORS + + public HomeOptionsBarAddVideoControl() + { + this.InitializeComponent(); + } + + #endregion + + + + #region PROPERTIES + + // SEARCH BUTTON EVENT HANDLER + public event EventHandler SearchButtonClicked; + + #endregion + + + + #region EVENT HANDLERS + + // SEARCH BUTTON CLICKED + private void HomeOptionsBarAddVideoControlSearchButton_Click(object sender, RoutedEventArgs e) + { + // Close info box + HomeOptionsBarAddVideoControlInfoBox.IsOpen = false; + + // Invoke search button event handlers + VideoSearchEventArgs args = new VideoSearchEventArgs + { + Phrase = HomeOptionsBarAddVideoControlUrlTextBox.Text + }; + SearchButtonClicked?.Invoke(this, args); + } + + // HELP BUTTON CLICKED + private void HomeOptionsBarAddVideoControlHelpButton_Click(object sender, RoutedEventArgs e) + { + // Switch info box + HomeOptionsBarAddVideoControlInfoBox.IsOpen = !HomeOptionsBarAddVideoControlInfoBox.IsOpen; + } + + #endregion + } +} diff --git a/VDownload/GUI/Views/MainPage.xaml b/VDownload/Views/MainPage.xaml similarity index 85% rename from VDownload/GUI/Views/MainPage.xaml rename to VDownload/Views/MainPage.xaml index 644d461..4fa71b4 100644 --- a/VDownload/GUI/Views/MainPage.xaml +++ b/VDownload/Views/MainPage.xaml @@ -1,5 +1,5 @@  + + 0,48,0,0 0 + + - + - + @@ -44,6 +48,11 @@ + + + + + diff --git a/VDownload/GUI/Views/MainPage.xaml.cs b/VDownload/Views/MainPage.xaml.cs similarity index 76% rename from VDownload/GUI/Views/MainPage.xaml.cs rename to VDownload/Views/MainPage.xaml.cs index 5c2e4e4..a748f69 100644 --- a/VDownload/GUI/Views/MainPage.xaml.cs +++ b/VDownload/Views/MainPage.xaml.cs @@ -1,28 +1,20 @@ -// Internal - -// System -using System; +using System; +using System.Collections.Generic; using Windows.ApplicationModel.Core; -using Windows.UI; -using Windows.UI.ViewManagement; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; -using Windows.Foundation; -using System.Collections.Generic; -namespace VDownload.GUI.Views +namespace VDownload.Views { public sealed partial class MainPage : Page { - #region INIT + #region CONSTRUCTORS - // CONSTRUCTOR public MainPage() { - InitializeComponent(); + this.InitializeComponent(); // Hide default title bar. - ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar; CoreApplicationViewTitleBar coreTitleBar = CoreApplication.GetCurrentView().TitleBar; coreTitleBar.ExtendViewIntoTitleBar = true; Window.Current.SetTitleBar(AppTitleBar); @@ -39,12 +31,13 @@ namespace VDownload.GUI.Views #region NAVIGATION PANEL // PAGES DICTIONARY - private Dictionary Pages = new Dictionary() + private readonly Dictionary Pages = new Dictionary() { {"home", typeof(Home.HomeMain)}, {"subscriptions", typeof(Subscriptions.SubscriptionsMain)}, + {"about", typeof(About.AboutMain)}, {"sources", typeof(Sources.SourcesMain)}, - {"settings", typeof(Settings.SettingsMain)} + {"settings", typeof(Settings.SettingsMain)}, }; // ON ITEM INVOKED diff --git a/VDownload/GUI/Views/Settings/SettingsMain.xaml b/VDownload/Views/Settings/SettingsMain.xaml similarity index 88% rename from VDownload/GUI/Views/Settings/SettingsMain.xaml rename to VDownload/Views/Settings/SettingsMain.xaml index 2749213..9a1c1f3 100644 --- a/VDownload/GUI/Views/Settings/SettingsMain.xaml +++ b/VDownload/Views/Settings/SettingsMain.xaml @@ -1,5 +1,5 @@  /// An empty page that can be used on its own or navigated to within a Frame. diff --git a/VDownload/Views/Sources/SourcesMain.xaml b/VDownload/Views/Sources/SourcesMain.xaml new file mode 100644 index 0000000..0a38443 --- /dev/null +++ b/VDownload/Views/Sources/SourcesMain.xaml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + +