Archived
1
0

Added ability to report videos and comments

This commit is contained in:
Michael Gordeev
2019-06-23 14:31:24 +03:00
parent 2140ec0d5f
commit bb45734e2d
14 changed files with 451 additions and 3 deletions
+4
View File
@@ -6,11 +6,15 @@
- Fixed some cases when playlist cards aren't displayed
- Fixed some cases when the app crashes
- Fixed app crashes on trying to navigate to not existing channel/playlist/video
- You can now report comments as spam
- You can now report videos
</en-US>
<ru-RU>### Что нового:
- Исправлены некоторые случаи при которых карточки плейлистов не отображались
- Исправлены некоторые случай при которых приложение вылетало
- Исправлены вылеты приложения при попытке перейти на несуществующий канал/плейлист/видео
- Теперь вы можете помечать комментарии как спам
- Теперь вы можете отправлять жалобы на видео
</ru-RU>
</content>
</item>
+11 -3
View File
@@ -36,7 +36,7 @@
FontFamily="Segoe MDL2 Assets" Text="&#xE19F;" FontSize="20"/>
<TextBlock Name="rating" Foreground="Gray" VerticalAlignment="Center" Text="123"/>
<Button Click="showReplies_Click" Name="showReplies" Background="Transparent" Foreground="Gray" Padding="0" Margin="10,0,0,0"
<Button Click="showReplies_Click" Name="showReplies" Background="Transparent" Foreground="Gray" Padding="5,0" Margin="5,0"
VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
Height="35">
<StackPanel Orientation="Horizontal">
@@ -45,7 +45,7 @@
</StackPanel>
</Button>
<Button Click="replyBtn_Click" Name="replyBtn" Background="Transparent" Foreground="Gray" Padding="0" Margin="10,0,0,0"
<Button Click="replyBtn_Click" Name="replyBtn" Background="Transparent" Foreground="Gray" Padding="5,0" Margin="5,0"
VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
Height="35">
<StackPanel Orientation="Horizontal">
@@ -54,7 +54,7 @@
</StackPanel>
</Button>
<Button Click="editBtn_Click" Visibility="Collapsed" Name="editBtn" Background="Transparent" Foreground="Gray" Padding="0" Margin="10,0,0,0"
<Button Click="editBtn_Click" Visibility="Collapsed" Name="editBtn" Background="Transparent" Foreground="Gray" Padding="5,0" Margin="5,0"
VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
Height="35">
<StackPanel Orientation="Horizontal">
@@ -62,6 +62,14 @@
<TextBlock x:Uid="/CommentsPage/edit" Text="Edit"/>
</StackPanel>
</Button>
<Button x:Name="spam" Background="Transparent" Foreground="Gray" Padding="5,0" Margin="5,0" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Height="35" Content="&#x205D;">
<Button.Flyout>
<MenuFlyout>
<MenuFlyoutItem x:Uid="/CommentsPage/spam" Icon="Flag" Text="Report as spam" Click="MarkAsSpam_Click"/>
</MenuFlyout>
</Button.Flyout>
</Button>
</StackPanel>
<Grid Name="replyEditor" Visibility="Collapsed">
+14
View File
@@ -39,6 +39,7 @@ namespace FoxTube.Controls
thread = comment;
replyBtn.Visibility = comment.Snippet.CanReply.Value && SecretsVault.IsAuthorized ? Visibility.Visible : Visibility.Collapsed;
spam.Visibility = SecretsVault.IsAuthorized ? Visibility.Visible : Visibility.Collapsed;
if (!comment.Snippet.TotalReplyCount.HasValue || comment.Snippet.TotalReplyCount.Value == 0)
showReplies.Visibility = Visibility.Collapsed;
else
@@ -101,6 +102,7 @@ namespace FoxTube.Controls
replyBtn.Visibility = Visibility.Collapsed;
showReplies.Visibility = Visibility.Collapsed;
spam.Visibility = SecretsVault.IsAuthorized ? Visibility.Visible : Visibility.Collapsed;
if (comment.Snippet.CanRate == false)
{
@@ -327,5 +329,17 @@ namespace FoxTube.Controls
await dialog.ShowAsync();
}
private async void MarkAsSpam_Click(object sender, RoutedEventArgs e)
{
ResourceLoader resources = ResourceLoader.GetForCurrentView("Report");
try { await SecretsVault.Service.Comments.MarkAsSpam(item.Id).ExecuteAsync(); }
catch
{
await new MessageDialog(resources.GetString("/Report/err")).ShowAsync();
return;
}
await new MessageDialog(resources.GetString("/Report/submittedHeader"), resources.GetString("/Report/submittedBody")).ShowAsync();
}
}
}
+22
View File
@@ -0,0 +1,22 @@
<ContentDialog
x:Class="FoxTube.Controls.ReportVideo"
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"
Title="Report a video"
PrimaryButtonText="Report"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
IsPrimaryButtonEnabled="False"
CloseButtonText="Cancel"
DefaultButton="Primary"
x:Uid="/Report/report">
<StackPanel>
<ComboBox x:Uid="/Report/reason" x:Name="primaryReason" Header="Reason" PlaceholderText="Select a reason..." SelectionChanged="PrimaryReason_SelectionChanged" Width="300"/>
<ComboBox x:Uid="/Report/secondaryReason" x:Name="secondaryReason" PlaceholderText="Select a category..." Visibility="Collapsed" Width="300"/>
<TextBox x:Uid="/Report/comment" x:Name="comment" Header="Additional information (optional)" MinHeight="200" AcceptsReturn="True" Margin="0,10"/>
</StackPanel>
</ContentDialog>
+69
View File
@@ -0,0 +1,69 @@
using Windows.UI.Xaml.Controls;
using Google.Apis.YouTube.v3.Data;
using Google.Apis.YouTube.v3;
using Windows.UI.Xaml;
using System;
using Windows.UI.Popups;
using Windows.ApplicationModel.Resources;
namespace FoxTube.Controls
{
public sealed partial class ReportVideo : ContentDialog
{
string videoId;
public ReportVideo(string id)
{
InitializeComponent();
Initialize();
videoId = id;
}
async void Initialize()
{
VideoAbuseReportReasonsResource.ListRequest req = SecretsVault.Service.VideoAbuseReportReasons.List("id,snippet");
req.Hl = SettingsStorage.RelevanceLanguage;
VideoAbuseReportReasonListResponse reasons = await req.ExecuteAsync();
foreach (VideoAbuseReportReason i in reasons.Items)
primaryReason.Items.Add(new ComboBoxItem
{
Tag = i,
Content = i.Snippet.Label
});
}
private async void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
VideoAbuseReport report = new VideoAbuseReport
{
Comments = Methods.GuardFromNull(comment.Text),
VideoId = videoId,
ReasonId = ((primaryReason.SelectedItem as ComboBoxItem).Tag as VideoAbuseReportReason).Id,
SecondaryReasonId = secondaryReason.SelectedItem == null ? null : (secondaryReason.SelectedItem as ComboBoxItem).Tag as string
};
ResourceLoader resources = ResourceLoader.GetForCurrentView("Report");
try { await SecretsVault.Service.Videos.ReportAbuse(report).ExecuteAsync(); }
catch
{
await new MessageDialog(resources.GetString("/Report/err")).ShowAsync();
return;
}
await new MessageDialog(resources.GetString("/Report/submittedHeader"), resources.GetString("/Report/submittedBody")).ShowAsync();
}
private void PrimaryReason_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
IsPrimaryButtonEnabled = true;
secondaryReason.Items.Clear();
foreach (VideoAbuseReportSecondaryReason i in ((primaryReason.SelectedItem as ComboBoxItem).Tag as VideoAbuseReportReason).Snippet.SecondaryReasons)
secondaryReason.Items.Add(new ComboBoxItem
{
Tag = i.Id,
Content = i.Label
});
secondaryReason.Visibility = secondaryReason.Items.Count == 0 ? Visibility.Collapsed : Visibility.Visible;
}
}
}
+9
View File
@@ -145,6 +145,9 @@
<Compile Include="Controls\PlaylistCard.xaml.cs">
<DependentUpon>PlaylistCard.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\ReportVideo.xaml.cs">
<DependentUpon>ReportVideo.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\ShowMore.xaml.cs">
<DependentUpon>ShowMore.xaml</DependentUpon>
</Compile>
@@ -284,6 +287,8 @@
<Content Include="Assets\Square44x44Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
<PRIResource Include="Strings\ru-RU\Report.resw" />
<PRIResource Include="Strings\en-US\Report.resw" />
<PRIResource Include="Strings\ru-RU\Translate.resw" />
<PRIResource Include="Strings\en-US\Translate.resw" />
</ItemGroup>
@@ -336,6 +341,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\ReportVideo.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\ShowMore.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
+4
View File
@@ -128,6 +128,10 @@
<AppBarButton x:Uid="/VideoPage/refresh" Name="refresh" Click="refresh_Click" Icon="Refresh" Label="Refresh page"/>
<AppBarButton x:Uid="/VideoPage/share" Name="share" Click="share_Click" Icon="Share" Label="Share"/>
<AppBarButton x:Uid="/VideoPage/openWeb" Name="openBrowser" Click="openBrowser_Click" Icon="Globe" Label="Open in browser"/>
<classes:AdaptiveCommandBar.SecondaryCommands>
<AppBarButton x:Uid="/VideoPage/report" Icon="Flag" x:Name="report" Label="Report this video" Click="Report_Click"/>
</classes:AdaptiveCommandBar.SecondaryCommands>
</classes:AdaptiveCommandBar>
</Grid>
+6
View File
@@ -786,5 +786,11 @@ namespace FoxTube.Pages
{
Player.Player.Position = history.LeftOn;
}
private async void Report_Click(object sender, RoutedEventArgs e)
{
await new ReportVideo(item.Id).ShowAsync();
}
}
}
+3
View File
@@ -174,6 +174,9 @@
<data name="sortBy.Text" xml:space="preserve">
<value>Sort by: </value>
</data>
<data name="spam.Text" xml:space="preserve">
<value>Report as spam</value>
</data>
<data name="textbox.PlaceholderText" xml:space="preserve">
<value>Add a public comment</value>
</data>
+150
View File
@@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="comment.Header" xml:space="preserve">
<value>Additional information (optional)</value>
</data>
<data name="err" xml:space="preserve">
<value>We are unable to send your report right now. Please, try again later</value>
</data>
<data name="reason.Header" xml:space="preserve">
<value>Reason</value>
</data>
<data name="reason.PlaceholderText" xml:space="preserve">
<value>Select a reason...</value>
</data>
<data name="report.CloseButtonText" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="report.PrimaryButtonText" xml:space="preserve">
<value>Report</value>
</data>
<data name="report.Title" xml:space="preserve">
<value>Report a video</value>
</data>
<data name="secondaryReason.PlaceholderText" xml:space="preserve">
<value>Select a category...</value>
</data>
<data name="submittedBody" xml:space="preserve">
<value>Thanks for making YouTube community better</value>
</data>
<data name="submittedHeader" xml:space="preserve">
<value>Your report has been sent</value>
</data>
</root>
+3
View File
@@ -306,4 +306,7 @@
<data name="playbackSpeed.Header" xml:space="preserve">
<value>Playback speed</value>
</data>
<data name="report.Label" xml:space="preserve">
<value>Report this video</value>
</data>
</root>
+3
View File
@@ -174,6 +174,9 @@
<data name="sortBy.Text" xml:space="preserve">
<value>Сортировать по:</value>
</data>
<data name="spam.Text" xml:space="preserve">
<value>Отметить как спам</value>
</data>
<data name="textbox.PlaceholderText" xml:space="preserve">
<value>Оставить комментарий</value>
</data>
+150
View File
@@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="comment.Header" xml:space="preserve">
<value>Дополнительная информация (необязательно)</value>
</data>
<data name="err" xml:space="preserve">
<value>Нам не удалось отправить жалобу прямо сейчас. Пожалуйста, попробуйте позже</value>
</data>
<data name="reason.Header" xml:space="preserve">
<value>Причина</value>
</data>
<data name="reason.PlaceholderText" xml:space="preserve">
<value>Выберите причину...</value>
</data>
<data name="report.CloseButtonText" xml:space="preserve">
<value>Отмена</value>
</data>
<data name="report.PrimaryButtonText" xml:space="preserve">
<value>Пожаловаться</value>
</data>
<data name="report.Title" xml:space="preserve">
<value>Пожаловаться на видео</value>
</data>
<data name="secondaryReason.PlaceholderText" xml:space="preserve">
<value>Выберите категорию...</value>
</data>
<data name="submittedBody" xml:space="preserve">
<value>Спасибо что помогаете делать сообщество YouTube лучше</value>
</data>
<data name="submittedHeader" xml:space="preserve">
<value>Ваша жалоба отправлена</value>
</data>
</root>
+3
View File
@@ -306,4 +306,7 @@
<data name="playbackSpeed.Header" xml:space="preserve">
<value>Скорость видео</value>
</data>
<data name="report.Label" xml:space="preserve">
<value>Пожаловаться на видео</value>
</data>
</root>