mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-07 09:28:03 +08:00
[ColorPicker] UX fixes (#10220)
* Added tooltip * Added edit icon * NumberBoxes * [spelling] add terms * Update ColorPickerControl.xaml * use variable to reduce casting Co-authored-by: Niels Laute <niels9001@hotmail.com> Co-authored-by: Enrico Giordani <enrico.giordani@gmail.com>
This commit is contained in:
parent
885c7c4e50
commit
6e14e86e4b
3
.github/actions/spell-check/expect.txt
vendored
3
.github/actions/spell-check/expect.txt
vendored
@ -169,6 +169,7 @@ BLURREGION
|
|||||||
bmi
|
bmi
|
||||||
bmp
|
bmp
|
||||||
bms
|
bms
|
||||||
|
BNumber
|
||||||
Bokm
|
Bokm
|
||||||
BOKMAL
|
BOKMAL
|
||||||
bootstrapper
|
bootstrapper
|
||||||
@ -794,6 +795,7 @@ githubusercontent
|
|||||||
gitignore
|
gitignore
|
||||||
globals
|
globals
|
||||||
gmx
|
gmx
|
||||||
|
GNumber
|
||||||
google
|
google
|
||||||
GPTR
|
GPTR
|
||||||
grayscale
|
grayscale
|
||||||
@ -1820,6 +1822,7 @@ riid
|
|||||||
riverar
|
riverar
|
||||||
RKey
|
RKey
|
||||||
RMENU
|
RMENU
|
||||||
|
RNumber
|
||||||
roadmap
|
roadmap
|
||||||
Roboto
|
Roboto
|
||||||
roslyn
|
roslyn
|
||||||
|
@ -32,7 +32,8 @@
|
|||||||
Background="LightPink"
|
Background="LightPink"
|
||||||
Click="ColorVariationButton_Click"
|
Click="ColorVariationButton_Click"
|
||||||
AutomationProperties.Name="Color shade 1"
|
AutomationProperties.Name="Color shade 1"
|
||||||
Style="{DynamicResource ColorShadeButtonStyle}"/>
|
Style="{DynamicResource ColorShadeButtonStyle}"
|
||||||
|
ToolTipService.ToolTip="{x:Static p:Resources.Select_color}"/>
|
||||||
<Button x:Name="colorVariation2Button"
|
<Button x:Name="colorVariation2Button"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
ui:ControlHelper.CornerRadius="0"
|
ui:ControlHelper.CornerRadius="0"
|
||||||
@ -40,7 +41,8 @@
|
|||||||
Background="LightPink"
|
Background="LightPink"
|
||||||
Click="ColorVariationButton_Click"
|
Click="ColorVariationButton_Click"
|
||||||
AutomationProperties.Name="Color shade 2"
|
AutomationProperties.Name="Color shade 2"
|
||||||
Style="{DynamicResource ColorShadeButtonStyle}"/>
|
Style="{DynamicResource ColorShadeButtonStyle}"
|
||||||
|
ToolTipService.ToolTip="{x:Static p:Resources.Select_color}"/>
|
||||||
<Button x:Name="colorVariation3Button"
|
<Button x:Name="colorVariation3Button"
|
||||||
Grid.Column="3"
|
Grid.Column="3"
|
||||||
TabIndex="7"
|
TabIndex="7"
|
||||||
@ -48,7 +50,8 @@
|
|||||||
Background="LightPink"
|
Background="LightPink"
|
||||||
Click="ColorVariationButton_Click"
|
Click="ColorVariationButton_Click"
|
||||||
AutomationProperties.Name="Color shade 3"
|
AutomationProperties.Name="Color shade 3"
|
||||||
Style="{DynamicResource ColorShadeButtonStyle}"/>
|
Style="{DynamicResource ColorShadeButtonStyle}"
|
||||||
|
ToolTipService.ToolTip="{x:Static p:Resources.Select_color}"/>
|
||||||
<Button x:Name="colorVariation4Button"
|
<Button x:Name="colorVariation4Button"
|
||||||
Grid.Column="4"
|
Grid.Column="4"
|
||||||
TabIndex="8"
|
TabIndex="8"
|
||||||
@ -56,7 +59,8 @@
|
|||||||
Background="LightPink"
|
Background="LightPink"
|
||||||
Click="ColorVariationButton_Click"
|
Click="ColorVariationButton_Click"
|
||||||
AutomationProperties.Name="Color shade 5"
|
AutomationProperties.Name="Color shade 5"
|
||||||
Style="{DynamicResource ColorShadeButtonStyle}"/>
|
Style="{DynamicResource ColorShadeButtonStyle}"
|
||||||
|
ToolTipService.ToolTip="{x:Static p:Resources.Select_color}"/>
|
||||||
<Button x:Name="CurrentColorButton"
|
<Button x:Name="CurrentColorButton"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
@ -72,7 +76,8 @@
|
|||||||
AutomationProperties.HelpText="{x:Static p:Resources.Selected_color_helptext}"
|
AutomationProperties.HelpText="{x:Static p:Resources.Selected_color_helptext}"
|
||||||
ToolTipService.ToolTip="{x:Static p:Resources.Selected_color_tooltip}"
|
ToolTipService.ToolTip="{x:Static p:Resources.Selected_color_tooltip}"
|
||||||
Click="CurrentColorButton_Click"
|
Click="CurrentColorButton_Click"
|
||||||
Style="{DynamicResource ColorShadeButtonStyle}"/>
|
Style="{DynamicResource ColorShadeButtonStyle}">
|
||||||
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<!--Details panel-->
|
<!--Details panel-->
|
||||||
@ -202,71 +207,73 @@
|
|||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid HorizontalAlignment="Stretch" Margin="12,16,12,8">
|
<Grid HorizontalAlignment="Stretch"
|
||||||
|
Margin="12,16,12,8">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="20"/>
|
<ColumnDefinition Width="20" />
|
||||||
<ColumnDefinition Width="68"/>
|
<ColumnDefinition Width="86" />
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="36"/>
|
<RowDefinition Height="36" />
|
||||||
<RowDefinition Height="36"/>
|
<RowDefinition Height="36" />
|
||||||
<RowDefinition Height="36"/>
|
<RowDefinition Height="36" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<TextBlock Text="R"
|
<TextBlock Text="R"
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Center" />
|
||||||
<TextBox x:Name="RTextBox"
|
<ui:NumberBox x:Name="RNumberBox"
|
||||||
Margin="0,0,0,0"
|
Grid.Column="1"
|
||||||
Grid.Column="1"
|
Height="32"
|
||||||
Height="32"
|
AutomationProperties.Name="{x:Static p:Resources.Red_value}"
|
||||||
AutomationProperties.Name="{x:Static p:Resources.Red_value}"
|
ValueChanged="RGBNumberBox_ValueChanged"
|
||||||
TextChanged="RGBTextBoxes_TextChanged"
|
Minimum="0"
|
||||||
TextWrapping="Wrap"/>
|
Maximum="255" />
|
||||||
|
|
||||||
<TextBlock Text="G"
|
<TextBlock Text="G"
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Center" />
|
||||||
|
|
||||||
<TextBox x:Name="GTextBox"
|
<ui:NumberBox x:Name="GNumberBox"
|
||||||
Width="68"
|
Height="32"
|
||||||
Height="32"
|
Grid.Row="1"
|
||||||
Grid.Row="1"
|
Grid.Column="1"
|
||||||
Grid.Column="1"
|
AutomationProperties.Name="{x:Static p:Resources.Green_value}"
|
||||||
AutomationProperties.Name="{x:Static p:Resources.Green_value}"
|
ValueChanged="RGBNumberBox_ValueChanged"
|
||||||
TextChanged="RGBTextBoxes_TextChanged"
|
Minimum="0"
|
||||||
TextWrapping="Wrap"/>
|
Maximum="255" />
|
||||||
|
|
||||||
<TextBlock Text="B"
|
<TextBlock Text="B"
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Center" />
|
||||||
|
|
||||||
<TextBox x:Name="BTextBox"
|
<ui:NumberBox x:Name="BNumberBox"
|
||||||
Width="68"
|
Height="32"
|
||||||
Height="32"
|
Grid.Column="1"
|
||||||
Grid.Column="1"
|
Grid.Row="2"
|
||||||
Grid.Row="2"
|
AutomationProperties.Name="{x:Static p:Resources.Blue_value}"
|
||||||
AutomationProperties.Name="{x:Static p:Resources.Blue_value}"
|
ValueChanged="RGBNumberBox_ValueChanged"
|
||||||
TextChanged="RGBTextBoxes_TextChanged"
|
Minimum="0"
|
||||||
TextWrapping="Wrap"/>
|
Maximum="255" />
|
||||||
|
|
||||||
<TextBlock Text="HEX"
|
<TextBlock Text="HEX"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Center" />
|
||||||
<TextBox x:Name="HexCode"
|
<TextBox x:Name="HexCode"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
Margin="8,0,0,0"
|
Margin="8,0,0,0"
|
||||||
Height="32"
|
Height="32"
|
||||||
Grid.Column="3"
|
Grid.Column="3"
|
||||||
AutomationProperties.Name="{x:Static p:Resources.Hex_value}"
|
AutomationProperties.Name="{x:Static p:Resources.Hex_value}"
|
||||||
|
GotKeyboardFocus="HexCode_GotKeyboardFocus"
|
||||||
TextChanged="HexCode_TextChanged"
|
TextChanged="HexCode_TextChanged"
|
||||||
TextWrapping="Wrap"/>
|
TextWrapping="Wrap" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<WrapPanel HorizontalAlignment="Right"
|
<WrapPanel HorizontalAlignment="Right"
|
||||||
Margin="0,0,0,0"
|
Margin="0,0,0,0"
|
||||||
|
@ -56,20 +56,24 @@ namespace ColorPicker.Controls
|
|||||||
|
|
||||||
private static void SelectedColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
private static void SelectedColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
|
var control = (ColorPickerControl)d;
|
||||||
var newColor = (Color)e.NewValue;
|
var newColor = (Color)e.NewValue;
|
||||||
((ColorPickerControl)d)._originalColor = ((ColorPickerControl)d)._currentColor = newColor;
|
|
||||||
var newColorBackground = new SolidColorBrush(newColor);
|
|
||||||
((ColorPickerControl)d).CurrentColorButton.Background = newColorBackground;
|
|
||||||
|
|
||||||
((ColorPickerControl)d)._ignoreHexChanges = true;
|
control._originalColor = control._currentColor = newColor;
|
||||||
((ColorPickerControl)d)._ignoreRGBChanges = true;
|
var newColorBackground = new SolidColorBrush(newColor);
|
||||||
((ColorPickerControl)d).HexCode.Text = ColorToHex(newColor);
|
control.CurrentColorButton.Background = newColorBackground;
|
||||||
((ColorPickerControl)d).RTextBox.Text = newColor.R.ToString(CultureInfo.InvariantCulture);
|
|
||||||
((ColorPickerControl)d).GTextBox.Text = newColor.G.ToString(CultureInfo.InvariantCulture);
|
control._ignoreHexChanges = true;
|
||||||
((ColorPickerControl)d).BTextBox.Text = newColor.B.ToString(CultureInfo.InvariantCulture);
|
control._ignoreRGBChanges = true;
|
||||||
((ColorPickerControl)d).SetColorFromTextBoxes(System.Drawing.Color.FromArgb(newColor.R, newColor.G, newColor.B));
|
|
||||||
((ColorPickerControl)d)._ignoreRGBChanges = false;
|
control.HexCode.Text = ColorToHex(newColor);
|
||||||
((ColorPickerControl)d)._ignoreHexChanges = false;
|
control.RNumberBox.Text = newColor.R.ToString(CultureInfo.InvariantCulture);
|
||||||
|
control.GNumberBox.Text = newColor.G.ToString(CultureInfo.InvariantCulture);
|
||||||
|
control.BNumberBox.Text = newColor.B.ToString(CultureInfo.InvariantCulture);
|
||||||
|
control.SetColorFromTextBoxes(System.Drawing.Color.FromArgb(newColor.R, newColor.G, newColor.B));
|
||||||
|
|
||||||
|
control._ignoreRGBChanges = false;
|
||||||
|
control._ignoreHexChanges = false;
|
||||||
|
|
||||||
var hsv = ColorHelper.ConvertToHSVColor(System.Drawing.Color.FromArgb(newColor.R, newColor.G, newColor.B));
|
var hsv = ColorHelper.ConvertToHSVColor(System.Drawing.Color.FromArgb(newColor.R, newColor.G, newColor.B));
|
||||||
|
|
||||||
@ -107,12 +111,13 @@ namespace ColorPicker.Controls
|
|||||||
}
|
}
|
||||||
|
|
||||||
var s = hsv.saturation;
|
var s = hsv.saturation;
|
||||||
|
var control = (ColorPickerControl)d;
|
||||||
|
|
||||||
((ColorPickerControl)d).colorVariation1Button.Background = new SolidColorBrush(HSVColor.RGBFromHSV(Math.Min(hsv.hue + (hueCoefficient * 8), 360), s, Math.Min(hsv.value + 0.3, 1)));
|
control.colorVariation1Button.Background = new SolidColorBrush(HSVColor.RGBFromHSV(Math.Min(hsv.hue + (hueCoefficient * 8), 360), s, Math.Min(hsv.value + 0.3, 1)));
|
||||||
((ColorPickerControl)d).colorVariation2Button.Background = new SolidColorBrush(HSVColor.RGBFromHSV(Math.Min(hsv.hue + (hueCoefficient * 4), 360), s, Math.Min(hsv.value + 0.15, 1)));
|
control.colorVariation2Button.Background = new SolidColorBrush(HSVColor.RGBFromHSV(Math.Min(hsv.hue + (hueCoefficient * 4), 360), s, Math.Min(hsv.value + 0.15, 1)));
|
||||||
|
|
||||||
((ColorPickerControl)d).colorVariation3Button.Background = new SolidColorBrush(HSVColor.RGBFromHSV(Math.Max(hsv.hue - (hueCoefficient2 * 4), 0), s, Math.Max(hsv.value - 0.2, 0)));
|
control.colorVariation3Button.Background = new SolidColorBrush(HSVColor.RGBFromHSV(Math.Max(hsv.hue - (hueCoefficient2 * 4), 0), s, Math.Max(hsv.value - 0.2, 0)));
|
||||||
((ColorPickerControl)d).colorVariation4Button.Background = new SolidColorBrush(HSVColor.RGBFromHSV(Math.Max(hsv.hue - (hueCoefficient2 * 8), 0), s, Math.Max(hsv.value - 0.3, 0)));
|
control.colorVariation4Button.Background = new SolidColorBrush(HSVColor.RGBFromHSV(Math.Max(hsv.hue - (hueCoefficient2 * 8), 0), s, Math.Max(hsv.value - 0.3, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateValueColorGradient(double posX)
|
private void UpdateValueColorGradient(double posX)
|
||||||
@ -161,9 +166,9 @@ namespace ColorPicker.Controls
|
|||||||
|
|
||||||
if (!_ignoreRGBChanges)
|
if (!_ignoreRGBChanges)
|
||||||
{
|
{
|
||||||
RTextBox.Text = currentColor.R.ToString(CultureInfo.InvariantCulture);
|
RNumberBox.Text = currentColor.R.ToString(CultureInfo.InvariantCulture);
|
||||||
GTextBox.Text = currentColor.G.ToString(CultureInfo.InvariantCulture);
|
GNumberBox.Text = currentColor.G.ToString(CultureInfo.InvariantCulture);
|
||||||
BTextBox.Text = currentColor.B.ToString(CultureInfo.InvariantCulture);
|
BNumberBox.Text = currentColor.B.ToString(CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
_currentColor = currentColor;
|
_currentColor = currentColor;
|
||||||
@ -357,19 +362,15 @@ namespace ColorPicker.Controls
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RGBTextBoxes_TextChanged(object sender, TextChangedEventArgs e)
|
#pragma warning disable CA1801 // Review unused parameters
|
||||||
|
private void RGBNumberBox_ValueChanged(ModernWpf.Controls.NumberBox sender, ModernWpf.Controls.NumberBoxValueChangedEventArgs args)
|
||||||
|
#pragma warning restore CA1801 // Review unused parameters
|
||||||
{
|
{
|
||||||
var validNumber = int.TryParse((sender as TextBox).Text, out int result);
|
|
||||||
if (!validNumber || result < 0 || result > 255)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_ignoreRGBChanges)
|
if (!_ignoreRGBChanges)
|
||||||
{
|
{
|
||||||
var r = byte.Parse(RTextBox.Text, CultureInfo.InvariantCulture);
|
var r = byte.Parse(RNumberBox.Text, CultureInfo.InvariantCulture);
|
||||||
var g = byte.Parse(GTextBox.Text, CultureInfo.InvariantCulture);
|
var g = byte.Parse(GNumberBox.Text, CultureInfo.InvariantCulture);
|
||||||
var b = byte.Parse(BTextBox.Text, CultureInfo.InvariantCulture);
|
var b = byte.Parse(BNumberBox.Text, CultureInfo.InvariantCulture);
|
||||||
_ignoreRGBChanges = true;
|
_ignoreRGBChanges = true;
|
||||||
SetColorFromTextBoxes(System.Drawing.Color.FromArgb(r, g, b));
|
SetColorFromTextBoxes(System.Drawing.Color.FromArgb(r, g, b));
|
||||||
_ignoreRGBChanges = false;
|
_ignoreRGBChanges = false;
|
||||||
@ -397,5 +398,10 @@ namespace ColorPicker.Controls
|
|||||||
{
|
{
|
||||||
return "#" + BitConverter.ToString(new byte[] { color.R, color.G, color.B }).Replace("-", string.Empty, StringComparison.InvariantCulture);
|
return "#" + BitConverter.ToString(new byte[] { color.R, color.G, color.B }).Replace("-", string.Empty, StringComparison.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HexCode_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
|
||||||
|
{
|
||||||
|
(sender as TextBox).SelectAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,6 +195,15 @@ namespace ColorPicker.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Select color.
|
||||||
|
/// </summary>
|
||||||
|
public static string Select_color {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Select_color", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Selected color.
|
/// Looks up a localized string similar to Selected color.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -361,4 +361,7 @@
|
|||||||
<value>Plum</value>
|
<value>Plum</value>
|
||||||
<comment>Plum color</comment>
|
<comment>Plum color</comment>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Select_color" xml:space="preserve">
|
||||||
|
<value>Select color</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -105,6 +105,7 @@
|
|||||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||||
Focusable="False"
|
Focusable="False"
|
||||||
|
Opacity="0"
|
||||||
RecognizesAccessKey="True"
|
RecognizesAccessKey="True"
|
||||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
|
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
|
||||||
</Border>
|
</Border>
|
||||||
@ -113,12 +114,12 @@
|
|||||||
<Trigger Property="IsMouseOver" Value="True">
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
<Setter TargetName="Background" Property="Opacity" Value="0.8" />
|
<Setter TargetName="Background" Property="Opacity" Value="0.8" />
|
||||||
<Setter TargetName="Border" Property="BorderBrush" Value="{DynamicResource ButtonBorderBrushPointerOver}" />
|
<Setter TargetName="Border" Property="BorderBrush" Value="{DynamicResource ButtonBorderBrushPointerOver}" />
|
||||||
<Setter TargetName="ContentPresenter" Property="TextElement.Foreground" Value="{DynamicResource ButtonForegroundPointerOver}" />
|
<Setter TargetName="ContentPresenter" Property="Opacity" Value="1" />
|
||||||
</Trigger>
|
</Trigger>
|
||||||
<Trigger Property="IsPressed" Value="True">
|
<Trigger Property="IsPressed" Value="True">
|
||||||
<Setter TargetName="Background" Property="Opacity" Value="0.9" />
|
<Setter TargetName="Background" Property="Opacity" Value="0.9" />
|
||||||
<Setter TargetName="Border" Property="BorderBrush" Value="{DynamicResource ButtonBorderBrushPressed}" />
|
<Setter TargetName="Border" Property="BorderBrush" Value="{DynamicResource ButtonBorderBrushPressed}" />
|
||||||
<Setter TargetName="ContentPresenter" Property="TextElement.Foreground" Value="{DynamicResource ButtonForegroundPressed}" />
|
<Setter TargetName="ContentPresenter" Property="Opacity" Value="1" />
|
||||||
</Trigger>
|
</Trigger>
|
||||||
</ControlTemplate.Triggers>
|
</ControlTemplate.Triggers>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
|
Loading…
Reference in New Issue
Block a user