From b875124c1a528b091166ade13e9aa244a80d6b38 Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Thu, 4 Apr 2019 22:10:47 +0300 Subject: [PATCH] Region settings fixed Channel page cover fixed Livestream toasts added --- FoxTube.Background/BackgroundProcessor.cs | 45 ++++++++++++------- FoxTube.Background/ResourceCreators.cs | 50 +++++++++++++++++++++ FoxTube/App.xaml | 6 +++ FoxTube/Assets/Data/Patchnotes.xml | 19 +++++++- FoxTube/Pages/ChannelPage.xaml | 4 +- FoxTube/Pages/ChannelPage.xaml.cs | 6 +++ FoxTube/Pages/MainPage.xaml | 1 + FoxTube/Pages/MainPage.xaml.cs | 5 --- FoxTube/Pages/SettingsPages/General.xaml | 8 ++-- FoxTube/Pages/SettingsPages/General.xaml.cs | 16 +++---- FoxTube/Pages/VideoPage.xaml | 39 +++++++++++++++- FoxTube/Pages/VideoPage.xaml.cs | 16 +++++++ 12 files changed, 175 insertions(+), 40 deletions(-) diff --git a/FoxTube.Background/BackgroundProcessor.cs b/FoxTube.Background/BackgroundProcessor.cs index 50ca6dc..706209d 100644 --- a/FoxTube.Background/BackgroundProcessor.cs +++ b/FoxTube.Background/BackgroundProcessor.cs @@ -1,4 +1,7 @@ -using Newtonsoft.Json; +using Google.Apis.Services; +using Google.Apis.YouTube.v3; +using Google.Apis.YouTube.v3.Data; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; @@ -17,6 +20,11 @@ namespace FoxTube.Background private DateTime lastCheck; private readonly ApplicationDataContainer settings = ApplicationData.Current.RoamingSettings; dynamic prefs; + private readonly YouTubeService Service = new YouTubeService(new BaseClientService.Initializer() + { + ApiKey = "AIzaSyBgHrCnrlzlVmk0cJKL8RqP9Y8x6XSuk_0", + ApplicationName = "FoxTube" + }); BackgroundTaskDeferral def; public async void Run(IBackgroundTaskInstance taskInstance) @@ -53,35 +61,40 @@ namespace FoxTube.Background { Dictionary subscriptions = JsonConvert.DeserializeObject>(settings.Values["subscriptions"] as string); - List results = new List(); + List results = new List(); foreach (var s in subscriptions) { - XmlDocument doc = new XmlDocument(); - doc.LoadXml(await new HttpClient().GetStringAsync($"https://www.youtube.com/feeds/videos.xml?channel_id={s.Key}")); + SearchResource.ListRequest request = Service.Search.List("snippet"); + request.PublishedAfter = lastCheck; + request.ChannelId = s.Key; + request.Type = "video"; + request.MaxResults = 5; + SearchListResponse response = await request.ExecuteAsync(); - List items = new List(); - - foreach (XmlElement i in doc["feed"].ChildNodes) - if (i.Name == "entry" && DateTime.Parse(i["published"].InnerText) > lastCheck) - items.Add(i); - - items.OrderByDescending(i => DateTime.Parse(i["published"].InnerText)); - - foreach(XmlElement i in items) + foreach (SearchResult i in response.Items) { results.Add(i); - ToastNotificationManager.CreateToastNotifier().Show( - Notification.GetVideoToast(i["yt:videoId"].InnerText, s.Key, i["title"].InnerText, i["author"]["name"].InnerText, (await new YoutubeExplode.YoutubeClient().GetVideoAsync(i["yt:videoId"].InnerText)).Thumbnails.MediumResUrl, DateTime.Parse(i["published"].InnerText), s.Value)); + if(i.Snippet.LiveBroadcastContent == "live") + ToastNotificationManager.CreateToastNotifier().Show( + Notification.GetStreamToast(i.Id.VideoId, i.Snippet.ChannelId, i.Snippet.Title, i.Snippet.ChannelTitle, i.Snippet.Thumbnails.Medium.Url, i.Snippet.PublishedAt.Value, s.Value)); + else if(i.Snippet.LiveBroadcastContent == "upcoming") + ToastNotificationManager.CreateToastNotifier().Show( + Notification.GetUpcomingToast(i.Id.VideoId, i.Snippet.ChannelId, i.Snippet.Title, i.Snippet.ChannelTitle, i.Snippet.Thumbnails.Medium.Url, i.Snippet.PublishedAt.Value, s.Value)); + else + ToastNotificationManager.CreateToastNotifier().Show( + Notification.GetVideoToast(i.Id.VideoId, i.Snippet.ChannelId, i.Snippet.Title, i.Snippet.ChannelTitle, i.Snippet.Thumbnails.Medium.Url, i.Snippet.PublishedAt.Value, s.Value)); } } + results.OrderBy(i => i.Snippet.PublishedAt); + TileUpdater updater = TileUpdateManager.CreateTileUpdaterForApplication(); updater.EnableNotificationQueue(true); updater.Clear(); for (int i = 0; i < 5 && i < results.Count; i++) - updater.Update(Tiles.GetTileLayout(System.Security.SecurityElement.Escape(results[i]["title"].InnerText), System.Security.SecurityElement.Escape(results[i]["author"]["name"].InnerText), (await new YoutubeExplode.YoutubeClient().GetVideoAsync(results[i]["yt:videoId"].InnerText)).Thumbnails.MediumResUrl.Replace("&", "%26"), subscriptions[results[i]["author"]["url"].InnerText.Split('/').Last()])); + updater.Update(Tiles.GetTileLayout(System.Security.SecurityElement.Escape(results[i].Snippet.Title), System.Security.SecurityElement.Escape(results[i].Snippet.ChannelTitle), results[i].Snippet.Thumbnails.Medium.Url.Replace("&", "%26"), subscriptions[results[i].Snippet.ChannelId])); } catch { } } diff --git a/FoxTube.Background/ResourceCreators.cs b/FoxTube.Background/ResourceCreators.cs index 50a29a0..254f1ff 100644 --- a/FoxTube.Background/ResourceCreators.cs +++ b/FoxTube.Background/ResourceCreators.cs @@ -23,6 +23,10 @@ namespace FoxTube.Background { "changelog", "Список изменений" }, { "changelogHeader", "Что нового в версии" }, { "videoContent", "загрузил новое видео" }, + { "live", "ПРЯМОЙ ЭФИР" }, + { "upcoming", "Запланирован" }, + { "liveContent", "начал прямой эфир" }, + { "upcomingContent", "запланировал прямой эфир" }, { "goChannel", "Открыть канал" } }; else @@ -32,6 +36,10 @@ namespace FoxTube.Background { "changelog", "Changelog" }, { "changelogHeader", "What's new in version" }, { "videoContent", "uploaded a new video" }, + { "live", "LIVE" }, + { "upcoming", "Upcoming" }, + { "liveContent", "started live broadcast" }, + { "upcomingContent", "planned live broadcast" }, { "goChannel", "Go to channel" } }; } @@ -76,6 +84,48 @@ namespace FoxTube.Background return new ToastNotification(template); } + public static ToastNotification GetStreamToast(string id, string channelId, string title, string channel, string thumbnail, DateTimeOffset timeStamp, string avatar) + { + XmlDocument template = new XmlDocument(); + string ts = $"{timeStamp.Year}-{timeStamp.Month:00}-{timeStamp.Day:00}T{timeStamp.Hour:00}:{timeStamp.Minute:00}:{timeStamp.Second:00}Z"; + template.LoadXml($@" + + + + + 🔴 [{languagePack["live"]}] {System.Security.SecurityElement.Escape(title)} + {System.Security.SecurityElement.Escape(channel)} {languagePack["liveContent"]} + + + + + + + "); + + return new ToastNotification(template); + } + public static ToastNotification GetUpcomingToast(string id, string channelId, string title, string channel, string thumbnail, DateTimeOffset timeStamp, string avatar) + { + XmlDocument template = new XmlDocument(); + string ts = $"{timeStamp.Year}-{timeStamp.Month:00}-{timeStamp.Day:00}T{timeStamp.Hour:00}:{timeStamp.Minute:00}:{timeStamp.Second:00}Z"; + template.LoadXml($@" + + + + + 🔴 [{languagePack["upcoming"]}] {System.Security.SecurityElement.Escape(title)} + {System.Security.SecurityElement.Escape(channel)} {languagePack["upcomingContent"]} + + + + + + + "); + + return new ToastNotification(template); + } public static ToastNotification GetInternalToast(string id, string header, string content, string thumbnail, string avatar) { diff --git a/FoxTube/App.xaml b/FoxTube/App.xaml index 573cf86..93d2f98 100644 --- a/FoxTube/App.xaml +++ b/FoxTube/App.xaml @@ -7,5 +7,11 @@ Red + diff --git a/FoxTube/Assets/Data/Patchnotes.xml b/FoxTube/Assets/Data/Patchnotes.xml index 5e117f4..54221b5 100644 --- a/FoxTube/Assets/Data/Patchnotes.xml +++ b/FoxTube/Assets/Data/Patchnotes.xml @@ -5,7 +5,7 @@ ### What's new: - Improved stability and speed of the app - Fixed a lot of bugs -- Fixed player +- Rebuilt player - Added animations and acrylic ### Following features awaits their implementation: @@ -17,8 +17,23 @@ ### Что нового: - Улучшена стабильность и скорость приложения - Исправлена куча багов -- Исправлен плеер +- Переработан плеер - Добавлены анимации и акрил +- Добавлена информация об аккаунте +- Добавлена история +- Добавлен плейлист "Посмотреть позже" +- Добавлены вкладки "Рекоммендованные" и "Подписки" на домашней странице +- Добавлена маленькая иконка канала при прокрутке вниз на странице канала +- Добавлена возможность удалять комментарии +- Переработано скачивание видео +- Добавлен прозрачный заголовок окна +- Добавлены всплывающие уведомления с просьбой оценить приложение и оставить отзыв (появляются после 12 и 24 часов активного использования) +- Переработана сетка карточек +- Добавлена информация о дате публикации видео на странице просмотра +- Обратный отсчет для стримов переработан и перенесен вверх страницы +- Список видео текущего плейлиста сразу перематывается на текущее +- Текст выделяется красным, а не текущим цветом системы +- Добавлены уведомления для прямых эфиров ### Следующие функции ждут своего внедрения: - История и плейлист 'Посмотреть позже' (прогресс есть, но нужно еще работать) diff --git a/FoxTube/Pages/ChannelPage.xaml b/FoxTube/Pages/ChannelPage.xaml index 8cc5b2b..655529d 100644 --- a/FoxTube/Pages/ChannelPage.xaml +++ b/FoxTube/Pages/ChannelPage.xaml @@ -11,7 +11,7 @@ xmlns:Windows10version1809="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract, 7)" mc:Ignorable="d"> - + @@ -30,7 +30,7 @@ - + diff --git a/FoxTube/Pages/ChannelPage.xaml.cs b/FoxTube/Pages/ChannelPage.xaml.cs index d1e65de..0758ee3 100644 --- a/FoxTube/Pages/ChannelPage.xaml.cs +++ b/FoxTube/Pages/ChannelPage.xaml.cs @@ -282,6 +282,12 @@ namespace FoxTube.Pages private void ChannelCover_ImageOpened(object sender, RoutedEventArgs e) { channelCover.Opacity = 1; + infoStack.Margin = new Thickness(0, channelCover.ActualHeight, 0, 0); + } + + private void Grid_SizeChanged(object sender, SizeChangedEventArgs e) + { + infoStack.Margin = new Thickness(0, channelCover.ActualHeight, 0, 0); } private void Share(DataTransferManager sender, DataRequestedEventArgs args) diff --git a/FoxTube/Pages/MainPage.xaml b/FoxTube/Pages/MainPage.xaml index a4f8f47..f1c3d7c 100644 --- a/FoxTube/Pages/MainPage.xaml +++ b/FoxTube/Pages/MainPage.xaml @@ -34,6 +34,7 @@ diff --git a/FoxTube/Pages/MainPage.xaml.cs b/FoxTube/Pages/MainPage.xaml.cs index 6759767..df129ed 100644 --- a/FoxTube/Pages/MainPage.xaml.cs +++ b/FoxTube/Pages/MainPage.xaml.cs @@ -131,12 +131,7 @@ namespace FoxTube public void SetTitleBar(CoreApplicationViewTitleBar coreTitleBar = null) { if (coreTitleBar != null) - { - bool full = ApplicationView.GetForCurrentView().IsFullScreenMode; - double left = 12 + (full ? 0 : coreTitleBar.SystemOverlayLeftInset); - AppTitle.Margin = new Thickness(left, 8, 0, 0); AppTitleBar.Height = coreTitleBar.Height; - } var titleBar = ApplicationView.GetForCurrentView().TitleBar; diff --git a/FoxTube/Pages/SettingsPages/General.xaml b/FoxTube/Pages/SettingsPages/General.xaml index fa41c91..0b44e9d 100644 --- a/FoxTube/Pages/SettingsPages/General.xaml +++ b/FoxTube/Pages/SettingsPages/General.xaml @@ -9,7 +9,7 @@ - + @@ -26,18 +26,18 @@ - + - + - + diff --git a/FoxTube/Pages/SettingsPages/General.xaml.cs b/FoxTube/Pages/SettingsPages/General.xaml.cs index 7b655b9..6b6c0af 100644 --- a/FoxTube/Pages/SettingsPages/General.xaml.cs +++ b/FoxTube/Pages/SettingsPages/General.xaml.cs @@ -51,19 +51,17 @@ namespace FoxTube.Pages.SettingsPages async void InitializeRegions() { I18nRegionsResource.ListRequest regRequest = SecretsVault.Service.I18nRegions.List("snippet"); + regRequest.Hl = SettingsStorage.Language; I18nRegionListResponse regResponse = await regRequest.ExecuteAsync(); - foreach(I18nRegion i in regResponse.Items) + regResponse.Items.ForEach(i => region.Items.Add(new ComboBoxItem { - region.Items.Add(new ComboBoxItem - { - Content = i.Snippet.Name, - Tag = i.Snippet.Gl - }); - if (SettingsStorage.Region == i.Snippet.Gl) - region.SelectedItem = region.Items.Last(); - } + Content = i.Snippet.Name, + Tag = i.Snippet.Gl + })); + region.SelectedItem = region.Items.Find(i => ((ComboBoxItem)i).Tag as string == SettingsStorage.Region) ?? region.Items.Find(i => ((ComboBoxItem)i).Tag as string == SettingsStorage.Language.Remove(0, 3)); I18nLanguagesResource.ListRequest langRequest = SecretsVault.Service.I18nLanguages.List("snippet"); + langRequest.Hl = SettingsStorage.Language; I18nLanguageListResponse langResponse = await langRequest.ExecuteAsync(); foreach(I18nLanguage i in langResponse.Items) { diff --git a/FoxTube/Pages/VideoPage.xaml b/FoxTube/Pages/VideoPage.xaml index f711e8b..f595f0d 100644 --- a/FoxTube/Pages/VideoPage.xaml +++ b/FoxTube/Pages/VideoPage.xaml @@ -112,7 +112,35 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -196,6 +224,13 @@ + + + + + + + diff --git a/FoxTube/Pages/VideoPage.xaml.cs b/FoxTube/Pages/VideoPage.xaml.cs index 4fa4ada..f9e5cbb 100644 --- a/FoxTube/Pages/VideoPage.xaml.cs +++ b/FoxTube/Pages/VideoPage.xaml.cs @@ -566,5 +566,21 @@ namespace FoxTube.Pages subscribe.Content = resources.GetString("/Cards/subscribe/Content"); } } + + private async void NewPlaylist_Click(object sender, RoutedEventArgs e) + { + //TODO: Localize strings + await playlistDialog.ShowAsync(); + } + + private void Wl_Click(object sender, RoutedEventArgs e) + { + + } + + private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) + { + + } } }