🎉 增加是否置于顶层开关
This commit is contained in:
@@ -111,6 +111,16 @@
|
|||||||
<hc:Divider LineStrokeDashArray="3,3" Margin="0,0,0,0" Height="20" LineStroke="Black" Grid.ColumnSpan="1"/>
|
<hc:Divider LineStrokeDashArray="3,3" Margin="0,0,0,0" Height="20" LineStroke="Black" Grid.ColumnSpan="1"/>
|
||||||
|
|
||||||
<hc:UniformSpacingPanel Spacing="10" Margin="5,-10,0,0" Grid.ColumnSpan="4">
|
<hc:UniformSpacingPanel Spacing="10" Margin="5,-10,0,0" Grid.ColumnSpan="4">
|
||||||
|
<CheckBox Content="置于顶层" IsChecked="{Binding AlwaysTopmost}">
|
||||||
|
<CheckBox.Background>
|
||||||
|
<LinearGradientBrush EndPoint="1,0" StartPoint="0,0">
|
||||||
|
<GradientStop Color="#FF9EA3A6"/>
|
||||||
|
</LinearGradientBrush>
|
||||||
|
</CheckBox.Background>
|
||||||
|
</CheckBox>
|
||||||
|
</hc:UniformSpacingPanel>
|
||||||
|
|
||||||
|
<hc:UniformSpacingPanel Spacing="10" Margin="5,10,0,0" Grid.ColumnSpan="4">
|
||||||
<CheckBox Content="主窗口动画" IsChecked="{Binding AppAnimation}" Click="Animation_Checked">
|
<CheckBox Content="主窗口动画" IsChecked="{Binding AppAnimation}" Click="Animation_Checked">
|
||||||
<CheckBox.Background>
|
<CheckBox.Background>
|
||||||
<LinearGradientBrush EndPoint="1,0" StartPoint="0,0">
|
<LinearGradientBrush EndPoint="1,0" StartPoint="0,0">
|
||||||
|
|||||||
@@ -1051,10 +1051,10 @@ namespace GeekDesk.Control.UserControls.PannelCard
|
|||||||
|
|
||||||
private void VerticalCard_ScrollChanged(object sender, ScrollChangedEventArgs e)
|
private void VerticalCard_ScrollChanged(object sender, ScrollChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (appData.AppConfig.EnableEveryThing == true && EveryThingUtil.hasNext())
|
if (appData.AppConfig.EnableEveryThing == true && EveryThingUtil.HasNext())
|
||||||
{
|
{
|
||||||
HandyControl.Controls.ScrollViewer sv = sender as HandyControl.Controls.ScrollViewer;
|
HandyControl.Controls.ScrollViewer sv = sender as HandyControl.Controls.ScrollViewer;
|
||||||
if (sv.ExtentHeight - (sv.ActualHeight + sv.VerticalOffset) < 200 && EveryThingUtil.hasNext())
|
if (sv.ExtentHeight - (sv.ActualHeight + sv.VerticalOffset) < 200 && EveryThingUtil.HasNext())
|
||||||
{
|
{
|
||||||
string[] split = MainWindow.mainWindow.TotalMsgBtn.Content.ToString().Split(' ');
|
string[] split = MainWindow.mainWindow.TotalMsgBtn.Content.ToString().Split(' ');
|
||||||
long count = Convert.ToInt64(split[0]);
|
long count = Convert.ToInt64(split[0]);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||||
xmlns:xf="clr-namespace:XamlFlair;assembly=XamlFlair.WPF"
|
xmlns:xf="clr-namespace:XamlFlair;assembly=XamlFlair.WPF"
|
||||||
xmlns:local="clr-namespace:GeekDesk"
|
xmlns:local="clr-namespace:GeekDesk" xmlns:viewmodel="clr-namespace:GeekDesk.ViewModel" d:DataContext="{d:DesignInstance Type=viewmodel:AppConfig}"
|
||||||
Title="Setting"
|
Title="Setting"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
|
|||||||
@@ -294,8 +294,6 @@
|
|||||||
<Compile Include="Util\BlurGlassUtil.cs" />
|
<Compile Include="Util\BlurGlassUtil.cs" />
|
||||||
<Compile Include="Util\ColorUtil.cs" />
|
<Compile Include="Util\ColorUtil.cs" />
|
||||||
<Compile Include="Util\DefaultIcons.cs" />
|
<Compile Include="Util\DefaultIcons.cs" />
|
||||||
<Compile Include="Util\DelayHelper.cs" />
|
|
||||||
<Compile Include="Util\DelayHelperFlyoutMenuItem.cs" />
|
|
||||||
<Compile Include="Util\DragAdorner.cs" />
|
<Compile Include="Util\DragAdorner.cs" />
|
||||||
<Compile Include="Util\FileWatcher.cs" />
|
<Compile Include="Util\FileWatcher.cs" />
|
||||||
<Compile Include="Util\GlobalHotKey.cs" />
|
<Compile Include="Util\GlobalHotKey.cs" />
|
||||||
@@ -327,6 +325,7 @@
|
|||||||
<Compile Include="Util\SvgToGeometry.cs" />
|
<Compile Include="Util\SvgToGeometry.cs" />
|
||||||
<Compile Include="Util\UserActivityHook.cs" />
|
<Compile Include="Util\UserActivityHook.cs" />
|
||||||
<Compile Include="Util\WindowsThumbnailProvider.cs" />
|
<Compile Include="Util\WindowsThumbnailProvider.cs" />
|
||||||
|
<Compile Include="Util\WindowUtil.cs" />
|
||||||
<Compile Include="ViewModel\AppConfig.cs" />
|
<Compile Include="ViewModel\AppConfig.cs" />
|
||||||
<Compile Include="ViewModel\AppData.cs" />
|
<Compile Include="ViewModel\AppData.cs" />
|
||||||
<Compile Include="ViewModel\GradientBGParam.cs" />
|
<Compile Include="ViewModel\GradientBGParam.cs" />
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
MouseEnter="MainWindow_MouseEnter"
|
MouseEnter="MainWindow_MouseEnter"
|
||||||
GotFocus="Window_GotFocus"
|
GotFocus="Window_GotFocus"
|
||||||
Loaded="Window_Loaded"
|
Loaded="Window_Loaded"
|
||||||
|
Topmost="{Binding AppConfig.AlwaysTopmost}"
|
||||||
>
|
>
|
||||||
|
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ namespace GeekDesk
|
|||||||
public static int toDoHotKeyId = -1;
|
public static int toDoHotKeyId = -1;
|
||||||
public static int colorPickerHotKeyId = -1;
|
public static int colorPickerHotKeyId = -1;
|
||||||
public static MainWindow mainWindow;
|
public static MainWindow mainWindow;
|
||||||
DelayHelper searchDelayHelper = new DelayHelper(300);
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
//加载数据
|
//加载数据
|
||||||
@@ -54,9 +53,6 @@ namespace GeekDesk
|
|||||||
//用于其他类访问
|
//用于其他类访问
|
||||||
mainWindow = this;
|
mainWindow = this;
|
||||||
|
|
||||||
//置于顶层
|
|
||||||
this.Topmost = true;
|
|
||||||
|
|
||||||
//执行待办提醒
|
//执行待办提醒
|
||||||
ToDoTask.BackLogCheck();
|
ToDoTask.BackLogCheck();
|
||||||
|
|
||||||
@@ -354,9 +350,7 @@ namespace GeekDesk
|
|||||||
//毛玻璃 暂时未解决阴影问题
|
//毛玻璃 暂时未解决阴影问题
|
||||||
//BlurGlassUtil.EnableBlur(this);
|
//BlurGlassUtil.EnableBlur(this);
|
||||||
|
|
||||||
//开启延迟搜索 优化搜索功能
|
WindowUtil.SetOwner(this, WindowUtil.GetDesktopHandle(this, DesktopLayer.Progman));
|
||||||
searchDelayHelper.Idled += SearchDelay;
|
|
||||||
|
|
||||||
|
|
||||||
if (appData.AppConfig.EnableEveryThing == true)
|
if (appData.AppConfig.EnableEveryThing == true)
|
||||||
{
|
{
|
||||||
@@ -364,7 +358,6 @@ namespace GeekDesk
|
|||||||
EveryThingUtil.EnableEveryThing();
|
EveryThingUtil.EnableEveryThing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Keyboard.Focus(SearchBox);
|
Keyboard.Focus(SearchBox);
|
||||||
|
|
||||||
MessageUtil.ChangeWindowMessageFilter(MessageUtil.WM_COPYDATA, 1);
|
MessageUtil.ChangeWindowMessageFilter(MessageUtil.WM_COPYDATA, 1);
|
||||||
@@ -383,7 +376,7 @@ namespace GeekDesk
|
|||||||
{
|
{
|
||||||
if (MotionControl.hotkeyFinished)
|
if (MotionControl.hotkeyFinished)
|
||||||
{
|
{
|
||||||
if (mainWindow.Visibility == Visibility.Collapsed || mainWindow.Opacity == 0 || MarginHide.IS_HIDE)
|
if (CheckSholeShowApp())
|
||||||
{
|
{
|
||||||
ShowApp();
|
ShowApp();
|
||||||
}
|
}
|
||||||
@@ -587,6 +580,7 @@ namespace GeekDesk
|
|||||||
ShowWindowFollowMouse.Show(mainWindow, MousePosition.CENTER, 0, 0);
|
ShowWindowFollowMouse.Show(mainWindow, MousePosition.CENTER, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MainWindow.mainWindow.Activate();
|
MainWindow.mainWindow.Activate();
|
||||||
mainWindow.Show();
|
mainWindow.Show();
|
||||||
//mainWindow.Visibility = Visibility.Visible;
|
//mainWindow.Visibility = Visibility.Visible;
|
||||||
@@ -705,7 +699,7 @@ namespace GeekDesk
|
|||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
private void NotifyIcon_Click(object sender, RoutedEventArgs e)
|
private void NotifyIcon_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (this.Visibility == Visibility.Collapsed || this.Opacity == 0)
|
if (CheckSholeShowApp())
|
||||||
{
|
{
|
||||||
ShowApp();
|
ShowApp();
|
||||||
}
|
}
|
||||||
@@ -715,6 +709,14 @@ namespace GeekDesk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool CheckSholeShowApp()
|
||||||
|
{
|
||||||
|
return mainWindow.Visibility == Visibility.Collapsed
|
||||||
|
|| mainWindow.Opacity == 0
|
||||||
|
|| MarginHide.IS_HIDE
|
||||||
|
|| !WindowUtil.WindowIsTop(mainWindow);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 右键任务栏图标 设置
|
/// 右键任务栏图标 设置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ namespace GeekDesk.Plugins.EveryThing
|
|||||||
|
|
||||||
new Thread(() =>
|
new Thread(() =>
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
Thread.Sleep(2000);
|
Thread.Sleep(2000);
|
||||||
|
|
||||||
//判断EveryThing服务是否已启动
|
//判断EveryThing服务是否已启动
|
||||||
@@ -64,7 +65,6 @@ namespace GeekDesk.Plugins.EveryThing
|
|||||||
Thread.Sleep(2000);
|
Thread.Sleep(2000);
|
||||||
processList = Process.GetProcesses();
|
processList = Process.GetProcesses();
|
||||||
|
|
||||||
|
|
||||||
//启动程序
|
//启动程序
|
||||||
using (Process p = new Process())
|
using (Process p = new Process())
|
||||||
{
|
{
|
||||||
@@ -79,6 +79,11 @@ namespace GeekDesk.Plugins.EveryThing
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}).Start();
|
}).Start();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -101,7 +106,7 @@ namespace GeekDesk.Plugins.EveryThing
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static bool hasNext()
|
public static bool HasNext()
|
||||||
{
|
{
|
||||||
return ui < Everything_GetNumResults();
|
return ui < Everything_GetNumResults();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace GeekDesk.Util
|
|
||||||
{
|
|
||||||
public class DelayHelper
|
|
||||||
{
|
|
||||||
public event EventHandler Idled = delegate { };
|
|
||||||
public int WaitingMilliSeconds { get; set; }
|
|
||||||
|
|
||||||
public object Source { get; set; }
|
|
||||||
|
|
||||||
readonly System.Threading.Timer waitingTimer;
|
|
||||||
|
|
||||||
public DelayHelper(int waitingMilliSeconds = 600)
|
|
||||||
{
|
|
||||||
WaitingMilliSeconds = waitingMilliSeconds;
|
|
||||||
waitingTimer = new System.Threading.Timer(p =>
|
|
||||||
{
|
|
||||||
Idled(this, EventArgs.Empty);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void DelayExecute(object source)
|
|
||||||
{
|
|
||||||
this.Source = source;
|
|
||||||
waitingTimer.Change(WaitingMilliSeconds, System.Threading.Timeout.Infinite);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace GeekDesk.Util
|
|
||||||
{
|
|
||||||
public class DelayHelperFlyoutMenuItem
|
|
||||||
{
|
|
||||||
public DelayHelperFlyoutMenuItem()
|
|
||||||
{
|
|
||||||
TargetType = typeof(DelayHelperFlyoutMenuItem);
|
|
||||||
}
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string Title { get; set; }
|
|
||||||
|
|
||||||
public Type TargetType { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
141
Util/WindowUtil.cs
Normal file
141
Util/WindowUtil.cs
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Windows.Interop;
|
||||||
|
|
||||||
|
namespace GeekDesk.Util
|
||||||
|
{
|
||||||
|
public class WindowUtil
|
||||||
|
{
|
||||||
|
|
||||||
|
public enum GetWindowCmd : uint
|
||||||
|
{
|
||||||
|
GW_HWNDFIRST = 0,
|
||||||
|
GW_HWNDLAST = 1,
|
||||||
|
GW_HWNDNEXT = 2,
|
||||||
|
GW_HWNDPREV = 3,
|
||||||
|
GW_OWNER = 4,
|
||||||
|
GW_CHILD = 5,
|
||||||
|
GW_ENABLEDPOPUP = 6
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum SetWindowPosFlags
|
||||||
|
{
|
||||||
|
SWP_NOSIZE = 0x0001,
|
||||||
|
SWP_NOMOVE = 0x0002,
|
||||||
|
SWP_NOZORDER = 0x0004,
|
||||||
|
SWP_NOREDRAW = 0x0008,
|
||||||
|
SWP_NOACTIVATE = 0x0010,
|
||||||
|
SWP_FRAMECHANGED = 0x0020,
|
||||||
|
SWP_SHOWWINDOW = 0x0040,
|
||||||
|
SWP_HIDEWINDOW = 0x0080,
|
||||||
|
SWP_NOCOPYBITS = 0x0100,
|
||||||
|
SWP_NOOWNERZORDER = 0x0200,
|
||||||
|
SWP_NOSENDCHANGING = 0x0400
|
||||||
|
}
|
||||||
|
|
||||||
|
//取得前台窗口句柄函数
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
private static extern IntPtr GetForegroundWindow();
|
||||||
|
//取得桌面窗口句柄函数
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
private static extern IntPtr GetDesktopWindow();
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||||
|
private static extern IntPtr FindWindow(string className, string windowName);
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
|
||||||
|
private static extern IntPtr GetWindow(HandleRef hWnd, int nCmd);
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
private static extern IntPtr SetParent(IntPtr child, IntPtr parent);
|
||||||
|
[DllImport("user32.dll", EntryPoint = "GetDCEx", CharSet = CharSet.Auto, ExactSpelling = true)]
|
||||||
|
private static extern IntPtr GetDCEx(IntPtr hWnd, IntPtr hrgnClip, int flags);
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
|
||||||
|
private static extern bool SetWindowPos(HandleRef hWnd, HandleRef hWndInsertAfter, int x, int y, int cx, int cy, int flags);
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
private static extern int ReleaseDC(IntPtr window, IntPtr handle);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void SetOwner(Window source, IntPtr parentHandle)
|
||||||
|
{
|
||||||
|
WindowInteropHelper helper = new WindowInteropHelper(source);
|
||||||
|
helper.Owner = parentHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="window"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool WindowIsTop(Window window)
|
||||||
|
{
|
||||||
|
IntPtr handle = new WindowInteropHelper(window).Handle;
|
||||||
|
IntPtr deskHandle = GetDesktopHandle(window, DesktopLayer.Progman);
|
||||||
|
IntPtr deskHandle2 = GetDesktopHandle(window, DesktopLayer.FolderView);
|
||||||
|
IntPtr deskHandle3 = GetDesktopHandle(window, DesktopLayer.SHELLDLL);
|
||||||
|
IntPtr topHandle = GetForegroundWindow();
|
||||||
|
return (topHandle.Equals(handle) || topHandle.Equals(deskHandle));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public const int GW_CHILD = 5;
|
||||||
|
|
||||||
|
public static IntPtr GetDesktopHandle(Window window, DesktopLayer layer)
|
||||||
|
{
|
||||||
|
HandleRef hWnd;
|
||||||
|
IntPtr hDesktop = new IntPtr();
|
||||||
|
switch (layer)
|
||||||
|
{
|
||||||
|
case DesktopLayer.Progman:
|
||||||
|
hDesktop = FindWindow("Progman", null);//第一层桌面
|
||||||
|
break;
|
||||||
|
case DesktopLayer.SHELLDLL:
|
||||||
|
hDesktop = FindWindow("Progman", null);//第一层桌面
|
||||||
|
hWnd = new HandleRef(window, hDesktop);
|
||||||
|
hDesktop = GetWindow(hWnd, GW_CHILD);//第2层桌面
|
||||||
|
break;
|
||||||
|
case DesktopLayer.FolderView:
|
||||||
|
hDesktop = FindWindow("Progman", null);//第一层桌面
|
||||||
|
hWnd = new HandleRef(window, hDesktop);
|
||||||
|
hDesktop = GetWindow(hWnd, GW_CHILD);//第2层桌面
|
||||||
|
hWnd = new HandleRef(window, hDesktop);
|
||||||
|
hDesktop = GetWindow(hWnd, GW_CHILD);//第3层桌面
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return hDesktop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EmbedDesktop(Object embeddedWindow, IntPtr childWindow, IntPtr parentWindow)
|
||||||
|
{
|
||||||
|
Form window = (Form)embeddedWindow;
|
||||||
|
HandleRef HWND_BOTTOM = new HandleRef(embeddedWindow, new IntPtr(1));
|
||||||
|
const int SWP_FRAMECHANGED = 0x0020;//发送窗口大小改变消息
|
||||||
|
SetParent(childWindow, parentWindow);
|
||||||
|
SetWindowPos(new HandleRef(window, childWindow), HWND_BOTTOM, 300, 300, window.Width, window.Height, SWP_FRAMECHANGED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DesktopLayer
|
||||||
|
{
|
||||||
|
Progman = 0,
|
||||||
|
SHELLDLL = 1,
|
||||||
|
FolderView = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -107,6 +107,22 @@ namespace GeekDesk.ViewModel
|
|||||||
|
|
||||||
private bool? enableEveryThing;
|
private bool? enableEveryThing;
|
||||||
|
|
||||||
|
private bool? alwaysTopmost;
|
||||||
|
|
||||||
|
|
||||||
|
public bool? AlwaysTopmost
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (alwaysTopmost == null) alwaysTopmost = false;
|
||||||
|
return alwaysTopmost;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
alwaysTopmost = value;
|
||||||
|
OnPropertyChanged("AlwaysTopmost");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool? EnableEveryThing
|
public bool? EnableEveryThing
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user