diff --git a/FoxTube/App.xaml.cs b/FoxTube/App.xaml.cs index f101394..81ef8e7 100644 --- a/FoxTube/App.xaml.cs +++ b/FoxTube/App.xaml.cs @@ -252,6 +252,20 @@ namespace FoxTube case "dcancel": DownloadAgent.Cancel(args[1]); break; + case "clipboard": + switch (args[1]) + { + case "video": + Methods.MainPage.GoToVideo(args[2]); + break; + case "channel": + Methods.MainPage.GoToChannel(args[2]); + break; + case "playlist": + Methods.MainPage.GoToPlaylist(args[2]); + break; + } + break; } } diff --git a/FoxTube/Assets/Data/Package.zip b/FoxTube/Assets/Data/Package.zip new file mode 100644 index 0000000..862d989 Binary files /dev/null and b/FoxTube/Assets/Data/Package.zip differ diff --git a/FoxTube/Assets/Data/Patchnotes.xml b/FoxTube/Assets/Data/Patchnotes.xml index d300d6f..d898cb7 100644 --- a/FoxTube/Assets/Data/Patchnotes.xml +++ b/FoxTube/Assets/Data/Patchnotes.xml @@ -1,5 +1,43 @@  + + + ### What's new: +- Added localization contribution system +- Added ability to completely collapse command bars (check settings) +- Added feature that checks your clipboard and suggests you to open YouTube page in the app if there is any (check settings) +- Added additional analytics tools to detect authorization fails +- Added video speed controller (check video settings) +- Test ads are now shown +- Fixed gaps in grids +- Fixed some cases when on maximizing video it pauses/continues +- Fixed missing inbox items due to incompatible date formats +- Fixed inability to unsubscribe from channel +- Fixed minimization of videos with unusual aspect ratios +- Fixed some cases when video continues to play in the background after closing/reloading video page + +### NB: +Since Microsoft hasn't fixed ad banners I'm forced to release the test ones. It will help me to optimize mechanics of ads delivery and make you fill more comfortable when the real ones will appear. Feedback is welcomed. + + ### Что нового: +- Теперь вы можете помочь нам переводить приложение на новые языки! +- Добавлена возможность полностью скрывать панель команд (см. Настройки) +- Добавлена функция которая сканирует ваш буфер обмена и, если там есть YouTube-ссылка, предлагает открыть соответствующую страницу в приложении (см. Настройки) +- Добавлены дополнительные инструменты аналитики для обнаружения ошибок авторизации +- Добавлен ползунок управления скоростью воспроизведения видео (см. Настройки видео) +- Теперь показываются тестовая реклама +- Исправлены пропуски в сетках +- Исправлены некоторые случаи при которых разворачивание видео останавливало/воспроизодило видео +- Исправлены пропущенные сообщения из-за несовместимых форматов дат системы +- Исправлена невозможность отписаться от канала +- Исправлено сворачивание видео с необычными соотношениями сторон +- Исправлены некоторые случаи при которых видео продолжало воспроизводиться в фоне после закрытия/обновления страницы видео + +### NB: +Поскольку Майкрософт все еще не исправили реальные рекламные баннеры, мне необходимо выпустить тестовые. Это поможет мне оптимизировать процесс доставки рекламы и позволит вам чувствовать себя более комфортно когда будут запущены настоящие. Отзывы приветствуются. + + + ### What's new: diff --git a/FoxTube/Classes/AdaptiveCommandBar.cs b/FoxTube/Classes/AdaptiveCommandBar.cs new file mode 100644 index 0000000..3b88891 --- /dev/null +++ b/FoxTube/Classes/AdaptiveCommandBar.cs @@ -0,0 +1,12 @@ +using Windows.UI.Xaml.Controls; + +namespace FoxTube.Classes +{ + class AdaptiveCommandBar : CommandBar + { + public AdaptiveCommandBar() + { + ClosedDisplayMode = SettingsStorage.AppBarClosedMode; + } + } +} diff --git a/FoxTube/Classes/Methods.cs b/FoxTube/Classes/Methods.cs index 99a1a9c..c744546 100644 --- a/FoxTube/Classes/Methods.cs +++ b/FoxTube/Classes/Methods.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net.Mail; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Xml; @@ -44,7 +45,8 @@ namespace FoxTube public static Uri ToUri(this string url) { - return string.IsNullOrWhiteSpace(url) ? null : new Uri(url); + try { return string.IsNullOrWhiteSpace(url) ? null : new Uri(url); } + catch { return null; } } public static string GuardFromNull(string str) @@ -52,6 +54,20 @@ namespace FoxTube return str ?? string.Empty; } + public static void SendMail(string content) + { + MailMessage msg = new MailMessage(); + msg.To.Add("michael.xfox@outlook.com"); + msg.From = new MailAddress(SecretsVault.EmailCredential.UserName); + msg.Subject = "[Automatic message] FoxTube service message"; + msg.Body = content; + + SmtpClient client = new SmtpClient("smtp.gmail.com", 587); + client.EnableSsl = true; + client.Credentials = SecretsVault.EmailCredential; + client.Send(msg); + } + [Obsolete] public static string GetChars(this string str, int count) { diff --git a/FoxTube/Classes/SecretsVault.cs b/FoxTube/Classes/SecretsVault.cs index ad71473..c30e909 100644 --- a/FoxTube/Classes/SecretsVault.cs +++ b/FoxTube/Classes/SecretsVault.cs @@ -14,6 +14,7 @@ using Google.Apis.Oauth2.v2.Data; using Google.Apis.Oauth2.v2; using static Google.Apis.Auth.OAuth2.UwpCodeReceiver; using Microsoft.AppCenter.Analytics; +using System.Net; namespace FoxTube { @@ -26,17 +27,18 @@ namespace FoxTube public static event ObjectEventHandler Purchased; //Rising when app finds out that it's not a PRO version //Properties - private static ClientSecrets Secrets => new ClientSecrets() + public static NetworkCredential EmailCredential => new NetworkCredential("mikhailagord@gmail.com", "JkY39w$.7?bT57O,8k3a"); + private static ClientSecrets Secrets => new ClientSecrets { ClientId = "349735264870-2ekqlm0a4mkg3mmrfcv90s3qp3o15dq0.apps.googleusercontent.com", ClientSecret = "BkVZOAaCU2Zclf0Zlicg6y2_" }; - private static YouTubeService NoAuthService => new YouTubeService(new BaseClientService.Initializer() + private static YouTubeService NoAuthService => new YouTubeService(new BaseClientService.Initializer { ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0", ApplicationName = "FoxTube" }); - public static BaseClientService.Initializer Initializer => new BaseClientService.Initializer() + public static BaseClientService.Initializer Initializer => new BaseClientService.Initializer { HttpClientInitializer = Credential, ApplicationName = "FoxTube" @@ -44,7 +46,7 @@ namespace FoxTube public static YouTubeService Service => IsAuthorized ? new YouTubeService(Initializer) : NoAuthService; public static HttpClient HttpClient { get; } = new HttpClient(); - private static bool TestAds => false; //TODO: Change this bool + private static bool TestAds => true; //TODO: Change this bool public static string AppId => TestAds ? "d25517cb-12d4-4699-8bdc-52040c712cab" : "9ncqqxjtdlfh"; public static string AdUnitId => TestAds ? "test" : "1100044398"; public static bool AdsDisabled { get; private set; } = true; @@ -82,8 +84,10 @@ namespace FoxTube try { await Service.Subscriptions.Delete(s.Id).ExecuteAsync(); } catch { return true; } - SubscriptionsChanged?.Invoke(null, "remove", s.Snippet.ResourceId.ChannelId); + SubscriptionsChanged?.Invoke(null, "remove", s); Subscriptions.Remove(s); + + SaveSubscriptions(); return false; } else @@ -105,6 +109,8 @@ namespace FoxTube return false; Subscriptions.Add(s); SubscriptionsChanged?.Invoke(null, "add", s); + + SaveSubscriptions(); return true; } } @@ -207,6 +213,9 @@ namespace FoxTube catch (Exception e) { AuthorizationStateChanged?.Invoke(args: new bool?[] { null }); + Methods.SendMail($@"Exception: {e.GetType()} +Message: {e.Message} +Stack trace: {e.StackTrace}"); Analytics.TrackEvent("Failed to retrieve user's info", new Dictionary { { "Exception", e.GetType().ToString() }, @@ -221,24 +230,36 @@ namespace FoxTube /// public static void SaveSubscriptions() { - Dictionary subs = new Dictionary(); - foreach(Subscription i in Subscriptions) - try - { - subs.Add(i.Snippet.ResourceId.ChannelId, i.Snippet.Thumbnails.Default__.Url); - } - catch (Exception e) - { - Analytics.TrackEvent("Failed to save user's subscription", new Dictionary + try + { + Dictionary subs = new Dictionary(); + foreach (Subscription i in Subscriptions) + try + { + subs.Add(i.Snippet.ResourceId.ChannelId, i.Snippet.Thumbnails.Default__.Url); + } + catch (Exception e) + { + Analytics.TrackEvent("Failed to save user's subscription", new Dictionary { { "Exception", e.GetType().ToString() }, { "Message", e.Message }, { "Channel ID", i.Snippet.ResourceId.ChannelId }, { "StackTrace", e.StackTrace } }); - continue; - } - ApplicationData.Current.RoamingSettings.Values["subscriptions"] = JsonConvert.SerializeObject(subs); + continue; + } + ApplicationData.Current.RoamingSettings.Values["subscriptions"] = JsonConvert.SerializeObject(subs); + } + catch (Exception e) + { + Analytics.TrackEvent("Failed to write user's subscriptions", new Dictionary + { + { "Exception", e.GetType().ToString() }, + { "Message", e.Message }, + { "StackTrace", e.StackTrace } + }); + } } /// diff --git a/FoxTube/Classes/SettingsStorage.cs b/FoxTube/Classes/SettingsStorage.cs index 0287a05..db64941 100644 --- a/FoxTube/Classes/SettingsStorage.cs +++ b/FoxTube/Classes/SettingsStorage.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.Linq; using Windows.ApplicationModel; using Windows.Storage; +using Windows.UI.Xaml.Controls; namespace FoxTube { @@ -34,6 +35,9 @@ namespace FoxTube public TimeSpan uptime = TimeSpan.FromSeconds(0); public bool promptReview = true; public bool promptFeedback = true; + + public bool processClipboard = true; + public bool minimizeCommandbar = false; } public static class SettingsStorage @@ -221,6 +225,26 @@ namespace FoxTube } } + public static bool ProcessClipboard + { + get => Container.processClipboard; + set + { + Container.processClipboard = value; + SaveData(); + } + } + + public static AppBarClosedDisplayMode AppBarClosedMode + { + get => Container.minimizeCommandbar ? AppBarClosedDisplayMode.Minimal : AppBarClosedDisplayMode.Compact; + set + { + Container.minimizeCommandbar = value == AppBarClosedDisplayMode.Minimal; + SaveData(); + } + } + //Settings storage private static readonly ApplicationDataContainer storage = ApplicationData.Current.RoamingSettings; private static SettingsContainer Container = new SettingsContainer(); diff --git a/FoxTube/Controls/Adverts/CardAdvert.xaml.cs b/FoxTube/Controls/Adverts/CardAdvert.xaml.cs index 7959d53..6c1789a 100644 --- a/FoxTube/Controls/Adverts/CardAdvert.xaml.cs +++ b/FoxTube/Controls/Adverts/CardAdvert.xaml.cs @@ -3,6 +3,7 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Microsoft.Advertising.WinRT.UI; using Windows.UI.Xaml.Media.Imaging; +using Microsoft.Toolkit.Uwp.UI.Controls; namespace FoxTube.Controls.Adverts { @@ -23,6 +24,7 @@ namespace FoxTube.Controls.Adverts private void ErrorOccurred(object sender, NativeAdErrorEventArgs e) { + (Parent as AdaptiveGridView)?.Items.Remove(this); System.Diagnostics.Debug.WriteLine("Error has occured while loading ad"); } diff --git a/FoxTube/Controls/ChannelCard.xaml.cs b/FoxTube/Controls/ChannelCard.xaml.cs index c9f1c99..933b444 100644 --- a/FoxTube/Controls/ChannelCard.xaml.cs +++ b/FoxTube/Controls/ChannelCard.xaml.cs @@ -1,5 +1,6 @@ using Google.Apis.YouTube.v3; using Google.Apis.YouTube.v3.Data; +using Microsoft.Toolkit.Uwp.UI.Controls; using System; using Windows.ApplicationModel.DataTransfer; using Windows.ApplicationModel.Resources; @@ -73,6 +74,7 @@ namespace FoxTube.Controls } catch (Exception e) { + (Parent as AdaptiveGridView)?.Items.Remove(this); Visibility = Visibility.Collapsed; Microsoft.AppCenter.Analytics.Analytics.TrackEvent("VideoCard loading failed", new System.Collections.Generic.Dictionary() { diff --git a/FoxTube/Controls/Player/PlayerControls.cs b/FoxTube/Controls/Player/PlayerControls.cs index ae6e295..c7d8894 100644 --- a/FoxTube/Controls/Player/PlayerControls.cs +++ b/FoxTube/Controls/Player/PlayerControls.cs @@ -79,6 +79,7 @@ namespace FoxTube Slider volume; Slider seek; + Slider playbackSpeed; ProgressBar seekIndicator; ComboBox captions; @@ -130,6 +131,7 @@ namespace FoxTube next.Click += Next_Click; volume.ValueChanged += Volume_ValueChanged; + playbackSpeed.ValueChanged += PlaybackSpeed_ValueChanged; live.Click += Live_Click; captionsSwitch.Toggled += CaptionsSwitch_Toggled; @@ -142,7 +144,7 @@ namespace FoxTube Rect view = new Rect(0, 0, centerTrigger.ActualWidth, centerTrigger.ActualHeight); Point p = e.GetPosition(centerTrigger); - if (!view.Contains(p) || e.PointerDeviceType != Windows.Devices.Input.PointerDeviceType.Mouse) + if (!view.Contains(p) || e.PointerDeviceType != Windows.Devices.Input.PointerDeviceType.Mouse || State != PlayerDisplayState.Normal) return; if (Player.CurrentState == Windows.UI.Xaml.Media.MediaElementState.Playing) @@ -158,6 +160,11 @@ namespace FoxTube base.OnApplyTemplate(); } + private void PlaybackSpeed_ValueChanged(object sender, RangeBaseValueChangedEventArgs e) + { + Player.PlaybackRate = playbackSpeed.Value; + } + void AssignControls() { minimize = GetTemplateChild("MinimizeButton") as Button; @@ -183,6 +190,7 @@ namespace FoxTube volume = GetTemplateChild("VolumeSlider") as Slider; seek = GetTemplateChild("ProgressSlider") as Slider; + playbackSpeed = GetTemplateChild("PlaybackSpeedSlider") as Slider; seekIndicator = GetTemplateChild("SeekIndicator") as ProgressBar; captions = GetTemplateChild("CaptionsSelector") as ComboBox; diff --git a/FoxTube/Controls/PlaylistCard.xaml.cs b/FoxTube/Controls/PlaylistCard.xaml.cs index 8ed514f..bdc5ecd 100644 --- a/FoxTube/Controls/PlaylistCard.xaml.cs +++ b/FoxTube/Controls/PlaylistCard.xaml.cs @@ -1,6 +1,7 @@ using Google.Apis.YouTube.v3; using Google.Apis.YouTube.v3.Data; using Microsoft.AppCenter.Analytics; +using Microsoft.Toolkit.Uwp.UI.Controls; using System; using System.Collections.Generic; using Windows.ApplicationModel.DataTransfer; @@ -52,6 +53,7 @@ namespace FoxTube.Controls } catch (Exception e) { + (Parent as AdaptiveGridView)?.Items.Remove(this); Visibility = Visibility.Collapsed; Analytics.TrackEvent("PlaylistCard loading failed", new Dictionary() { diff --git a/FoxTube/Controls/VideoCard.xaml.cs b/FoxTube/Controls/VideoCard.xaml.cs index 1c22402..5373e0b 100644 --- a/FoxTube/Controls/VideoCard.xaml.cs +++ b/FoxTube/Controls/VideoCard.xaml.cs @@ -15,6 +15,7 @@ using YoutubeExplode.Models.MediaStreams; using Windows.Foundation; using FoxTube.Pages; using Windows.Networking.Connectivity; +using Microsoft.Toolkit.Uwp.UI.Controls; namespace FoxTube.Controls { @@ -98,8 +99,12 @@ namespace FoxTube.Controls } LoadAddTo(); - thumbnail.Source = new BitmapImage(item.Snippet.Thumbnails.Medium.Url.ToUri()); - avatar.ProfilePicture = new BitmapImage((await new YoutubeClient().GetChannelAsync(item.Snippet.ChannelId)).LogoUrl.ToUri()) { DecodePixelWidth = 46, DecodePixelHeight = 46 }; + try + { + thumbnail.Source = new BitmapImage(item.Snippet.Thumbnails.Medium.Url.ToUri()); + avatar.ProfilePicture = new BitmapImage((await new YoutubeClient().GetChannelAsync(item.Snippet.ChannelId)).LogoUrl.ToUri()) { DecodePixelWidth = 46, DecodePixelHeight = 46 }; + } + catch { } if (SecretsVault.History.Contains(item.Id)) watched.Visibility = Visibility.Visible; @@ -114,6 +119,7 @@ namespace FoxTube.Controls } catch (Exception e) { + (Parent as AdaptiveGridView)?.Items.Remove(this); Visibility = Visibility.Collapsed; Analytics.TrackEvent("VideoCard loading failed", new Dictionary() { diff --git a/FoxTube/FoxTube.csproj b/FoxTube/FoxTube.csproj index cadd022..bfc9bbe 100644 --- a/FoxTube/FoxTube.csproj +++ b/FoxTube/FoxTube.csproj @@ -103,6 +103,7 @@ App.xaml + @@ -183,6 +184,9 @@ PlaylistPage.xaml + + Translate.xaml + Subscriptions.xaml @@ -270,6 +274,7 @@ + @@ -279,6 +284,8 @@ + + @@ -389,6 +396,10 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + Designer MSBuild:Compile @@ -458,6 +469,9 @@ 4.3.2 + + 4.3.0 + 4.7.0 diff --git a/FoxTube/Pages/ChannelPage.xaml b/FoxTube/Pages/ChannelPage.xaml index 8a42d62..7e8879b 100644 --- a/FoxTube/Pages/ChannelPage.xaml +++ b/FoxTube/Pages/ChannelPage.xaml @@ -8,6 +8,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:pages="using:FoxTube.Pages" xmlns:controls="using:FoxTube.Controls" + xmlns:classes="using:FoxTube.Classes" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> @@ -95,10 +96,10 @@ - + - + diff --git a/FoxTube/Pages/History.xaml b/FoxTube/Pages/History.xaml index 2ac64d3..07fc324 100644 --- a/FoxTube/Pages/History.xaml +++ b/FoxTube/Pages/History.xaml @@ -7,6 +7,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:foxtube="using:FoxTube" xmlns:controls="using:FoxTube.Controls" + xmlns:classes="using:FoxTube.Classes" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> @@ -56,9 +57,9 @@ - + - + diff --git a/FoxTube/Pages/Home.xaml b/FoxTube/Pages/Home.xaml index 4a14c14..a9ed7f8 100644 --- a/FoxTube/Pages/Home.xaml +++ b/FoxTube/Pages/Home.xaml @@ -7,6 +7,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:pages="using:FoxTube.Pages" xmlns:controls="using:FoxTube.Controls" + xmlns:classes="using:FoxTube.Classes" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> @@ -54,8 +55,8 @@ - + - + diff --git a/FoxTube/Pages/MainPage.xaml b/FoxTube/Pages/MainPage.xaml index fff3ece..02448ca 100644 --- a/FoxTube/Pages/MainPage.xaml +++ b/FoxTube/Pages/MainPage.xaml @@ -8,7 +8,7 @@ xmlns:ui="using:Microsoft.UI.Xaml.Controls" xmlns:controls="using:FoxTube.Controls"> - + diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index 9f73150..3d28cef 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Collections.Generic; using Windows.UI; using Windows.UI.ViewManagement; @@ -7,7 +8,6 @@ using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Navigation; using Windows.UI.Xaml.Media.Imaging; -using System.Xml; using Google.Apis.YouTube.v3.Data; using Windows.ApplicationModel.Core; using Windows.System; @@ -18,6 +18,10 @@ using Microsoft.Services.Store.Engagement; using Windows.UI.Xaml.Shapes; using Windows.UI.Xaml.Media; using FoxTube.Controls; +using Microsoft.AppCenter.Analytics; +using Windows.ApplicationModel.DataTransfer; +using Windows.UI.Notifications; +using System.Xml; namespace FoxTube { @@ -77,9 +81,77 @@ namespace FoxTube if(StoreServicesFeedbackLauncher.IsSupported()) feedback.Visibility = Visibility.Visible; + if(SettingsStorage.ProcessClipboard) + { + Clipboard.ContentChanged += ParseClipboard; + ParseClipboard(this); + } + PromptFeedback(); } + async void ParseClipboard(object sender = null, object e = null) + { + if (sender == null && Window.Current.CoreWindow.ActivationMode != Windows.UI.Core.CoreWindowActivationMode.Deactivated) + return; + try + { + string link = await Clipboard.GetContent().GetTextAsync(); + + if (!link.Contains("youtube") && !link.Contains("youtu.be")) + return; + + string id; + string type; + string name; + + if (YoutubeExplode.YoutubeClient.TryParseChannelId(link, out id)) + { + type = "channel"; + name = (await new YoutubeExplode.YoutubeClient().GetChannelAsync(id)).Title; + goto Complete; + } + else if (YoutubeExplode.YoutubeClient.TryParsePlaylistId(link, out id)) + { + type = "playlist"; + name = (await new YoutubeExplode.YoutubeClient().GetPlaylistAsync(id)).Title; + goto Complete; + } + else if (YoutubeExplode.YoutubeClient.TryParseUsername(link, out id)) + { + id = await new YoutubeExplode.YoutubeClient().GetChannelIdAsync(id); + type = "channel"; + name = (await new YoutubeExplode.YoutubeClient().GetChannelAsync(id)).Title; + goto Complete; + } + else if (YoutubeExplode.YoutubeClient.TryParseVideoId(link, out id)) + { + type = "video"; + name = (await new YoutubeExplode.YoutubeClient().GetVideoAsync(id)).Title; + goto Complete; + } + return; + + Complete: + Windows.Data.Xml.Dom.XmlDocument toastXml = new Windows.Data.Xml.Dom.XmlDocument(); + toastXml.LoadXml($@" + + + {resources.GetString("/Main/clipboardHead")} + {name} + {resources.GetString($"/Main/{type}")} + + + + + + "); + ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(toastXml)); + return; + } + catch { } + } + async void PromptFeedback() { if (SettingsStorage.Uptime.TotalHours >= 12 && SettingsStorage.PromptFeedback) @@ -157,9 +229,9 @@ namespace FoxTube break; case "remove": - if (nav.MenuItems.Find(i => ((i as Microsoft.UI.Xaml.Controls.NavigationViewItem).Content as StackPanel).Tag.ToString() == (string)args[1]) is Microsoft.UI.Xaml.Controls.NavigationViewItem item) + if(nav.MenuItems.Contains((Subscription)args[1])) { - nav.MenuItems.Remove(item); + nav.MenuItems.Remove(args[1]); if (SecretsVault.Subscriptions.Count >= 10) nav.MenuItems.Add(SecretsVault.Subscriptions[9]); } @@ -266,6 +338,7 @@ namespace FoxTube private void SignIn_Click(object sender, RoutedEventArgs e) { SecretsVault.Authorize(); + Analytics.TrackEvent("Initialized authorization sequence"); } private void Logout_Click(object sender, RoutedEventArgs e) @@ -338,7 +411,7 @@ namespace FoxTube public void MinimizeVideo() { videoPlaceholder.Width = 432; - videoPlaceholder.Height = 243; + videoPlaceholder.Height = 432 * (videoPlaceholder.Frame.Content as VideoPage).Player.ActualHeight / (videoPlaceholder.Frame.Content as VideoPage).Player.ActualWidth; videoPlaceholder.VerticalAlignment = VerticalAlignment.Bottom; videoPlaceholder.HorizontalAlignment = HorizontalAlignment.Right; videoPlaceholder.Margin = new Thickness(0, 0, 25, 50); diff --git a/FoxTube/Pages/PlaylistPage.xaml b/FoxTube/Pages/PlaylistPage.xaml index 7de6904..158b93f 100644 --- a/FoxTube/Pages/PlaylistPage.xaml +++ b/FoxTube/Pages/PlaylistPage.xaml @@ -6,6 +6,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:controls="using:FoxTube.Controls" + xmlns:classes="using:FoxTube.Classes" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> @@ -76,7 +77,7 @@ - + @@ -87,6 +88,6 @@ - + diff --git a/FoxTube/Pages/Search.xaml b/FoxTube/Pages/Search.xaml index 76ad1e6..110774f 100644 --- a/FoxTube/Pages/Search.xaml +++ b/FoxTube/Pages/Search.xaml @@ -7,6 +7,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:controls="using:FoxTube.Controls" + xmlns:classes="using:FoxTube.Classes" mc:Ignorable="d"> @@ -72,9 +73,9 @@ - + - + diff --git a/FoxTube/Pages/Settings.xaml b/FoxTube/Pages/Settings.xaml index 92b0b35..7aa33f4 100644 --- a/FoxTube/Pages/Settings.xaml +++ b/FoxTube/Pages/Settings.xaml @@ -19,6 +19,11 @@ + + + + + diff --git a/FoxTube/Pages/Settings.xaml.cs b/FoxTube/Pages/Settings.xaml.cs index 8a4d4c3..2c3c295 100644 --- a/FoxTube/Pages/Settings.xaml.cs +++ b/FoxTube/Pages/Settings.xaml.cs @@ -29,6 +29,9 @@ namespace FoxTube case "about": pivot.SelectedItem = aboutTab; break; + case "translate": + pivot.SelectedItem = translateTab; + break; default: inboxId = (string)e.Parameter; pivot.SelectedItem = inboxTab; diff --git a/FoxTube/Pages/SettingsPages/General.xaml b/FoxTube/Pages/SettingsPages/General.xaml index 0123479..87188e6 100644 --- a/FoxTube/Pages/SettingsPages/General.xaml +++ b/FoxTube/Pages/SettingsPages/General.xaml @@ -26,6 +26,10 @@ + + + + diff --git a/FoxTube/Pages/SettingsPages/General.xaml.cs b/FoxTube/Pages/SettingsPages/General.xaml.cs index a4452e3..50db48f 100644 --- a/FoxTube/Pages/SettingsPages/General.xaml.cs +++ b/FoxTube/Pages/SettingsPages/General.xaml.cs @@ -27,6 +27,9 @@ namespace FoxTube.Pages.SettingsPages quality.Items.Add(new ComboBoxItem() { Tag = i.GetVideoQualityLabel(), Content = i.GetVideoQualityLabel() }); quality.SelectedItem = quality.Items.ToList().Find(i => ((ComboBoxItem)i).Tag.ToString() == SettingsStorage.VideoQuality); + clipboardProcessing.IsOn = SettingsStorage.ProcessClipboard; + minimizedCB.IsOn = SettingsStorage.AppBarClosedMode == AppBarClosedDisplayMode.Minimal; + mobileWarning.IsOn = SettingsStorage.CheckConnection; autoplay.IsOn = SettingsStorage.Autoplay; @@ -152,5 +155,15 @@ namespace FoxTube.Pages.SettingsPages { CoreApplication.Exit(); } + + private void MinimizedCB_Toggled(object sender, RoutedEventArgs e) + { + SettingsStorage.AppBarClosedMode = minimizedCB.IsOn ? AppBarClosedDisplayMode.Minimal : AppBarClosedDisplayMode.Compact; + } + + private void ClipboardProcessing_Toggled(object sender, RoutedEventArgs e) + { + SettingsStorage.ProcessClipboard = clipboardProcessing.IsOn; + } } } diff --git a/FoxTube/Pages/SettingsPages/Inbox.xaml.cs b/FoxTube/Pages/SettingsPages/Inbox.xaml.cs index 73955a1..de60f58 100644 --- a/FoxTube/Pages/SettingsPages/Inbox.xaml.cs +++ b/FoxTube/Pages/SettingsPages/Inbox.xaml.cs @@ -35,14 +35,14 @@ namespace FoxTube.Pages.SettingsPages items.Add(new InboxItem( e.GetAttribute("version"), e["content"][SettingsStorage.Language].InnerText, - DateTime.Parse(e.GetAttribute("time")))); + DateTime.Parse(e.GetAttribute("time"), System.Globalization.CultureInfo.GetCultureInfo("en-US").DateTimeFormat))); doc.Load("http://foxgame-studio.000webhostapp.com/foxtube-messages.xml"); foreach (XmlElement e in doc["posts"].ChildNodes) items.Add(new InboxItem( e["header"][SettingsStorage.Language].InnerText, e["content"][SettingsStorage.Language].InnerText, - DateTime.Parse(e.GetAttribute("time")), + DateTime.Parse(e.GetAttribute("time"), System.Globalization.CultureInfo.GetCultureInfo("en-US").DateTimeFormat), e["id"].InnerText, e["contentHeader"].InnerText)); } diff --git a/FoxTube/Pages/SettingsPages/Translate.xaml b/FoxTube/Pages/SettingsPages/Translate.xaml new file mode 100644 index 0000000..da5eb7a --- /dev/null +++ b/FoxTube/Pages/SettingsPages/Translate.xaml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FoxTube/Pages/VideoPage.xaml.cs b/FoxTube/Pages/VideoPage.xaml.cs index fed868b..26765dd 100644 --- a/FoxTube/Pages/VideoPage.xaml.cs +++ b/FoxTube/Pages/VideoPage.xaml.cs @@ -95,6 +95,12 @@ namespace FoxTube.Pages Initialize(e.Parameter as object[]); } + protected override void OnNavigatedFrom(NavigationEventArgs e) + { + base.OnNavigatedFrom(e); + Player.Player.Stop(); + } + public async void Initialize(object[] ids) { try @@ -391,6 +397,8 @@ namespace FoxTube.Pages foreach (SearchResult video in response.Items) relatedVideos.Add(new VideoCard(video.Id.VideoId)); + + relatedVideos.Children.Insert(1, new Controls.Adverts.CardAdvert()); } private void Player_Minimize(object sender, params object[] e) diff --git a/FoxTube/Strings/en-US/General.resw b/FoxTube/Strings/en-US/General.resw index 5e381f6..e064f97 100644 --- a/FoxTube/Strings/en-US/General.resw +++ b/FoxTube/Strings/en-US/General.resw @@ -210,4 +210,19 @@ Auto + + Interface + + + Use compact command bar + + + Use compact command bar + + + Process YouTube links from your clipboard + + + Process YouTube links from your clipboard + \ No newline at end of file diff --git a/FoxTube/Strings/en-US/Main.resw b/FoxTube/Strings/en-US/Main.resw index 61f9bae..269ff76 100644 --- a/FoxTube/Strings/en-US/Main.resw +++ b/FoxTube/Strings/en-US/Main.resw @@ -126,6 +126,12 @@ Channel + + We've found this on your clipboard + + + Open in FoxTube + Close the app diff --git a/FoxTube/Strings/en-US/Translate.resw b/FoxTube/Strings/en-US/Translate.resw new file mode 100644 index 0000000..4fa42af --- /dev/null +++ b/FoxTube/Strings/en-US/Translate.resw @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Thanks for your contribution into my application. It's very important to me. It will take some time to process your package, correct mistakes and prepare it for integration. I will send you an e-mail when it's done. +Cheers, +XFox + +This is an automatic message. Please, don't respond it. Nah, ok, only if you want to :) + + + Package certification result + + + Choose another file + + + You can help us make this app even better by contributing to its development by translating this app + + + Export to PC (.zip) + + + Export + + + Failed + + + Failed to read file. File's structure is corrupted + + + We were unable to send your submission due to connection problems or internal server error. Please, try again later. + + + Failed to send your package + + + File + + + It's quite simple: + + + 1. Choose language you you want to translate on + + + Choose language... + + + 2. Save language pack file to your PC + + + 3. Open archive's files with any text editor you want (Notepad, Wordpad, Notepad++, VS Code, etc.) + + + 4. Edit file by translating nececcary words and sentences + + + 5. Upload final package to our servers + + + Help us translate this app + + + It takes about 2-3 weeks to process new language pack and include it to the next update +Thank you for your help 😉 + +Cheers, + + + In progress... + + + Language pack scheme + + + View log + + + not found + + + Passed + + + FoxTube language pack contribution + + + Upload + + + Your language pack has been sent! + + + Thank you! It's very imortant for us. You help us making the app better + + + Choose file to upload + + + FoxTube auto reply + + \ No newline at end of file diff --git a/FoxTube/Strings/en-US/VideoPage.resw b/FoxTube/Strings/en-US/VideoPage.resw index 732f809..1b3e246 100644 --- a/FoxTube/Strings/en-US/VideoPage.resw +++ b/FoxTube/Strings/en-US/VideoPage.resw @@ -303,4 +303,7 @@ Auto + + Playback speed + \ No newline at end of file diff --git a/FoxTube/Strings/ru-RU/General.resw b/FoxTube/Strings/ru-RU/General.resw index 4f0b6e0..b17047d 100644 --- a/FoxTube/Strings/ru-RU/General.resw +++ b/FoxTube/Strings/ru-RU/General.resw @@ -210,4 +210,19 @@ Авто + + Интерфейс + + + Использовать компактную панель команд + + + Использовать компактную панель команд + + + Обрабатывать ссылки YouTube из буфера обмена + + + Обрабатывать ссылки YouTube из буфера обмена + \ No newline at end of file diff --git a/FoxTube/Strings/ru-RU/Main.resw b/FoxTube/Strings/ru-RU/Main.resw index 56a9cd4..587c34a 100644 --- a/FoxTube/Strings/ru-RU/Main.resw +++ b/FoxTube/Strings/ru-RU/Main.resw @@ -126,6 +126,9 @@ Канал + + Открыть в FoxTube + Закрыть приложение diff --git a/FoxTube/Strings/ru-RU/Translate.resw b/FoxTube/Strings/ru-RU/Translate.resw new file mode 100644 index 0000000..1cae7e2 --- /dev/null +++ b/FoxTube/Strings/ru-RU/Translate.resw @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Спасибо за ваш вклад в развитие моего приложения. Это очень важно для меня. Обработка пакета, исправление технических ошибок и подготовка пакета к интеграции займет некоторое время. Я пришлю вам письмо, когда локализация будет готова. +Всего лучшего, +XFox + +Это автоматический ответ. Пожалуйста, не отвечайте на это письмо. Ладно, только если очень хочется) + + + Результат сертификации пакета + + + Выбрать другой файл + + + Вы можете помочь нам сделать приложение еще лучше, помогая перевести его на новые языки + + + Экспортировать на ПК (.zip) + + + Сохранить + + + Провал + + + Ошибка чтения файла. Структура данных повреждена + + + Не удалось отправить ваш пакет из-за проблем с соединением или внутренней ошибкой сервера. Пожалуйста, попробуйте позже + + + Ошибка при отправке пакета + + + Файл + + + Это достаточно просто: + + + 1. Выберите язык на который вы хотите перевести + + + Выберите язык... + + + 2. Сохраните языковой пакет на свой ПК + + + 3. Откройте файлы в архиве любым текстовым редактором на ваш выбор (Блокнот, Wordpad, Notepad++, VS Code, и т.д.) + + + 4. Переведите необходимые слова и предложения + + + 5. Загрузите финальный пакет на наши сервера + + + Помогите нам перевести это приложение + + + Обработка пакета займет 2-3 недели. Новая локализация будет доступна в ближайших обновлениях +Спасибо за вашу помощь 😉 + +С наилучшими пожеланиями, + + + В процессе... + + + Схема языкового пакета + + + Посмотреть лог + + + не найден + + + Пройдена + + + Помощь в локализации приложения FoxTube + + + Загрузить + + + Ваш языковой пакт отправлен! + + + Спасибо! Это очень важно для нас. Вы помогаете сделать приложение лучше! + + + Выберите файл для отправки + + + Автоответчик FoxTube + + \ No newline at end of file diff --git a/FoxTube/Strings/ru-RU/VideoPage.resw b/FoxTube/Strings/ru-RU/VideoPage.resw index 1392183..76c703f 100644 --- a/FoxTube/Strings/ru-RU/VideoPage.resw +++ b/FoxTube/Strings/ru-RU/VideoPage.resw @@ -303,4 +303,7 @@ Авто + + Скорость видео + \ No newline at end of file diff --git a/FoxTube/Themes/Generic.xaml b/FoxTube/Themes/Generic.xaml index 8435d59..413aabc 100644 --- a/FoxTube/Themes/Generic.xaml +++ b/FoxTube/Themes/Generic.xaml @@ -342,10 +342,13 @@ -