mirror of
https://github.com/Pixeval/Pixeval.git
synced 2025-01-07 03:06:53 +08:00
删除所有popup
This commit is contained in:
parent
e010984313
commit
79da476545
@ -20,7 +20,6 @@
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Graphics;
|
||||
using LiteDB;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
@ -38,9 +37,9 @@ using Pixeval.Util.Threading;
|
||||
using Pixeval.Util.UI;
|
||||
using WinUI3Utilities;
|
||||
using AppContext = Pixeval.AppManagement.AppContext;
|
||||
using ApplicationTheme = Pixeval.Options.ApplicationTheme;
|
||||
using IllustrationViewModel = Pixeval.UserControls.IllustrationView.IllustrationViewModel;
|
||||
using AppTheme = Pixeval.Options.ApplicationTheme;
|
||||
using Microsoft.UI;
|
||||
using Pixeval.UserControls.IllustrationView;
|
||||
|
||||
namespace Pixeval;
|
||||
|
||||
@ -102,27 +101,19 @@ public class AppViewModel : AutoActivateObservableRecipient,
|
||||
.AddSingleton(provider => new BrowseHistoryPersistentManager(provider.GetRequiredService<LiteDatabase>(), App.AppViewModel.AppSetting.MaximumBrowseHistoryRecords)));
|
||||
}
|
||||
|
||||
public void SwitchTheme(ApplicationTheme theme)
|
||||
public void SwitchTheme(AppTheme theme)
|
||||
{
|
||||
var selectedTheme = theme switch
|
||||
{
|
||||
ApplicationTheme.Dark => ElementTheme.Dark,
|
||||
ApplicationTheme.Light => ElementTheme.Light,
|
||||
ApplicationTheme.SystemDefault => ElementTheme.Default,
|
||||
AppTheme.Dark => ElementTheme.Dark,
|
||||
AppTheme.Light => ElementTheme.Light,
|
||||
AppTheme.SystemDefault => ElementTheme.Default,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(theme), theme, null)
|
||||
};
|
||||
|
||||
if (CurrentContext.Window.Content is FrameworkElement rootElement)
|
||||
rootElement.RequestedTheme = selectedTheme;
|
||||
|
||||
// TODO: 没反应
|
||||
Application.Current.Resources["WindowCaptionForeground"] =
|
||||
selectedTheme switch
|
||||
{
|
||||
ElementTheme.Dark => Colors.White,
|
||||
ElementTheme.Light => Colors.Black,
|
||||
_ => Application.Current.RequestedTheme is Microsoft.UI.Xaml.ApplicationTheme.Dark ? Colors.White : Colors.Black
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public async Task ShowExceptionDialogAsync(Exception e)
|
||||
@ -146,12 +137,12 @@ public class AppViewModel : AutoActivateObservableRecipient,
|
||||
|
||||
public void PrepareForActivation()
|
||||
{
|
||||
((MainWindow) CurrentContext.Window).ShowProgressRing();
|
||||
((MainWindow)CurrentContext.Window).ShowProgressRing();
|
||||
}
|
||||
|
||||
public void ActivationProcessed()
|
||||
{
|
||||
((MainWindow) CurrentContext.Window).HideProgressRing();
|
||||
((MainWindow)CurrentContext.Window).HideProgressRing();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -7,37 +7,34 @@
|
||||
Closed="MainWindow_OnClosed"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Grid>
|
||||
<Frame
|
||||
x:Name="PixevalAppRootFrame"
|
||||
x:FieldModifier="public"
|
||||
Loaded="PixevalAppRootFrame_OnLoaded"
|
||||
Navigated="PixevalAppRootFrame_OnNavigated"
|
||||
Navigating="PixevalAppRootFrame_OnNavigating"
|
||||
NavigationFailed="PixevalAppRootFrame_OnNavigationFailed">
|
||||
<Frame.ContentTransitions>
|
||||
<TransitionCollection>
|
||||
<NavigationThemeTransition DefaultNavigationTransitionInfo="{x:Bind DefaultNavigationTransitionInfo}" />
|
||||
</TransitionCollection>
|
||||
</Frame.ContentTransitions>
|
||||
</Frame>
|
||||
<Grid
|
||||
x:Name="Processing"
|
||||
Width="100"
|
||||
Height="100"
|
||||
<Frame
|
||||
x:Name="PixevalAppRootFrame"
|
||||
x:FieldModifier="public"
|
||||
Loaded="PixevalAppRootFrame_OnLoaded"
|
||||
Navigated="PixevalAppRootFrame_OnNavigated"
|
||||
Navigating="PixevalAppRootFrame_OnNavigating"
|
||||
NavigationFailed="PixevalAppRootFrame_OnNavigationFailed">
|
||||
<Frame.ContentTransitions>
|
||||
<TransitionCollection>
|
||||
<NavigationThemeTransition DefaultNavigationTransitionInfo="{x:Bind DefaultNavigationTransitionInfo}" />
|
||||
</TransitionCollection>
|
||||
</Frame.ContentTransitions>
|
||||
</Frame>
|
||||
<Grid
|
||||
x:Name="Processing"
|
||||
Width="100"
|
||||
Height="100"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
CornerRadius="15"
|
||||
Visibility="Collapsed">
|
||||
<Rectangle Fill="{ThemeResource PixevalAppAcrylicBrush}" />
|
||||
<ProgressRing
|
||||
Width="40"
|
||||
Height="40"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
CornerRadius="15"
|
||||
Visibility="Collapsed">
|
||||
<Rectangle Fill="{ThemeResource PixevalAppAcrylicBrush}" />
|
||||
<ProgressRing
|
||||
Width="40"
|
||||
Height="40"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
IsIndeterminate="True" />
|
||||
</Grid>
|
||||
<TeachingTip x:Name="PixevalAppSnackBar" x:FieldModifier="public" />
|
||||
IsIndeterminate="True" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
@ -1,26 +1,31 @@
|
||||
<controls:EnhancedPage x:Class="Pixeval.Pages.Login.LoginPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:Pixeval.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:login="using:Pixeval.Pages.Login"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:misc="using:Pixeval.Misc"
|
||||
xmlns:misc1="using:Pixeval.Pages.Misc"
|
||||
xmlns:attributes="using:Pixeval.Attributes"
|
||||
d:DataContext="{d:DesignInstance login:LoginPageViewModel}"
|
||||
Loaded="LoginPage_OnLoaded"
|
||||
mc:Ignorable="d">
|
||||
<controls:EnhancedPage
|
||||
x:Class="Pixeval.Pages.Login.LoginPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:attributes="using:Pixeval.Attributes"
|
||||
xmlns:controls="using:Pixeval.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:login="using:Pixeval.Pages.Login"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
d:DataContext="{d:DesignInstance login:LoginPageViewModel}"
|
||||
Loaded="LoginPage_OnLoaded"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Image Width="150"
|
||||
Height="150"
|
||||
Source="../../Assets/Images/logo.png" />
|
||||
<Image
|
||||
Width="150"
|
||||
Height="150"
|
||||
Source="../../Assets/Images/logo.png" />
|
||||
<ProgressRing Width="30" Height="30" />
|
||||
<TextBlock Margin="0,15,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
FontSize="10"
|
||||
Text="{x:Bind attributes:LocalizedResourceAttributeHelper.GetLocalizedResourceContent(_viewModel.LoginPhase), Mode=OneWay}" />
|
||||
<TextBlock
|
||||
Margin="0,15,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
FontSize="10"
|
||||
Text="{x:Bind attributes:LocalizedResourceAttributeHelper.GetLocalizedResourceContent(_viewModel.LoginPhase), Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<Border
|
||||
Margin="100"
|
||||
Child="{x:Bind _viewModel.WebView, Mode=OneWay}"
|
||||
CornerRadius="4" />
|
||||
</Grid>
|
||||
</controls:EnhancedPage>
|
||||
</controls:EnhancedPage>
|
||||
|
@ -77,6 +77,12 @@ public partial class LoginPageViewModel : AutoActivateObservableRecipient
|
||||
[ObservableProperty]
|
||||
private LoginPhaseEnum _loginPhase;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(IsWebViewVisible))]
|
||||
private LoginWebViewPopup? _webView;
|
||||
|
||||
public Visibility IsWebViewVisible => WebView is null ? Visibility.Collapsed : Visibility.Visible;
|
||||
|
||||
public void AdvancePhase(LoginPhaseEnum newPhase)
|
||||
{
|
||||
LoginPhase = newPhase;
|
||||
@ -176,24 +182,22 @@ public partial class LoginPageViewModel : AutoActivateObservableRecipient
|
||||
using var proxyServer = PixivAuthenticationProxyServer.Create(IPAddress.Loopback, port, await AppContext.GetFakeServerCertificateAsync());
|
||||
Environment.SetEnvironmentVariable("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", $"--proxy-server=127.0.0.1:{port} --ignore-certificate-errors");
|
||||
|
||||
var content = new LoginWebViewPopup();
|
||||
var webViewPopup = PopupManager.CreatePopup(content, widthMargin: 150, heightMargin: 100, minHeight: 400, minWidth: 600);
|
||||
WebView = new();
|
||||
|
||||
AdvancePhase(LoginPhaseEnum.ExecutingWebView2);
|
||||
PopupManager.ShowPopup(webViewPopup);
|
||||
|
||||
await content.LoginWebView.EnsureCoreWebView2Async();
|
||||
content.LoginWebView.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
|
||||
content.LoginWebView.CoreWebView2.WebResourceRequested += (_, args) =>
|
||||
await WebView.LoginWebView.EnsureCoreWebView2Async();
|
||||
WebView.LoginWebView.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
|
||||
WebView.LoginWebView.CoreWebView2.WebResourceRequested += (_, args) =>
|
||||
{
|
||||
args.Request.Headers.SetHeader("Accept-Language", args.Request.Uri.Contains("recaptcha") ? "zh-cn" : CultureInfo.CurrentUICulture.Name);
|
||||
};
|
||||
|
||||
var verifier = PixivAuthSignature.GetCodeVerify();
|
||||
content.LoginWebView.Source = new Uri(PixivAuthSignature.GenerateWebPageUrl(verifier));
|
||||
WebView.LoginWebView.Source = new Uri(PixivAuthSignature.GenerateWebPageUrl(verifier));
|
||||
|
||||
var (url, cookie) = await content.CookieCompletion.Task;
|
||||
PopupManager.ClosePopup(webViewPopup);
|
||||
var (url, cookie) = await WebView.CookieCompletion.Task;
|
||||
WebView = null;
|
||||
|
||||
var code = HttpUtility.ParseQueryString(new Uri(url).Query)["code"]!;
|
||||
|
||||
|
@ -1,264 +0,0 @@
|
||||
#region Copyright (c) Pixeval/Pixeval
|
||||
// GPL v3 License
|
||||
//
|
||||
// Pixeval/Pixeval
|
||||
// Copyright (c) 2022 Pixeval/AppPopup.cs
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using Windows.Foundation;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Media.Animation;
|
||||
using Pixeval.Util.UI;
|
||||
using WinUI3Utilities;
|
||||
|
||||
namespace Pixeval.Popups;
|
||||
|
||||
public static class PopupManager
|
||||
{
|
||||
private static readonly Dictionary<Guid, AppPopup> OpenPopupsInternal = new();
|
||||
|
||||
public static IReadOnlyDictionary<Guid, AppPopup> OpenPopups => OpenPopupsInternal;
|
||||
|
||||
public static AppPopup CreatePopup(
|
||||
IAppPopupContent content,
|
||||
double width = double.NaN,
|
||||
double height = double.NaN,
|
||||
double widthMargin = double.NaN,
|
||||
double heightMargin = double.NaN,
|
||||
double minWidth = 0,
|
||||
double maxWidth = double.MaxValue,
|
||||
double minHeight = 0,
|
||||
double maxHeight = double.MaxValue,
|
||||
bool lightDismiss = false,
|
||||
bool useAnimation = true,
|
||||
Action<IAppPopupContent>? opening = null,
|
||||
Action<IAppPopupContent, object?>? closing = null)
|
||||
{
|
||||
return new AppPopup(content, width, height, widthMargin, heightMargin, minWidth, maxWidth, minHeight, maxHeight, lightDismiss, useAnimation, opening, closing);
|
||||
}
|
||||
|
||||
public static void ShowPopup(AppPopup popup)
|
||||
{
|
||||
popup.Show();
|
||||
OpenPopupsInternal[popup.UniqueId] = popup;
|
||||
}
|
||||
|
||||
public static void ClosePopup(AppPopup popup)
|
||||
{
|
||||
popup.Close();
|
||||
OpenPopupsInternal.Remove(popup.UniqueId);
|
||||
}
|
||||
|
||||
public static void ClosePopup(Guid guid)
|
||||
{
|
||||
if (OpenPopupsInternal.TryGetValue(guid, out var popup))
|
||||
{
|
||||
popup.Close();
|
||||
OpenPopupsInternal.Remove(guid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AppPopup
|
||||
{
|
||||
private readonly Action<IAppPopupContent, object?>? _closing;
|
||||
private readonly IAppPopupContent _content;
|
||||
private readonly double _height;
|
||||
private readonly double _heightMargin;
|
||||
private readonly double _maxHeight;
|
||||
private readonly double _maxWidth;
|
||||
private readonly double _minHeight;
|
||||
private readonly double _minWidth;
|
||||
private readonly Action<IAppPopupContent>? _opening;
|
||||
private readonly bool _useAnimation;
|
||||
private readonly double _width;
|
||||
private readonly double _widthMargin;
|
||||
|
||||
public AppPopup(
|
||||
IAppPopupContent content,
|
||||
double width = double.NaN,
|
||||
double height = double.NaN,
|
||||
double widthMargin = double.NaN,
|
||||
double heightMargin = double.NaN,
|
||||
double minWidth = 0,
|
||||
double maxWidth = double.MaxValue,
|
||||
double minHeight = 0,
|
||||
double maxHeight = double.MaxValue,
|
||||
bool lightDismiss = false,
|
||||
bool useAnimation = true,
|
||||
Action<IAppPopupContent>? opening = null,
|
||||
Action<IAppPopupContent, object?>? closing = null)
|
||||
{
|
||||
_content = content;
|
||||
_width = width;
|
||||
_height = height;
|
||||
_opening = opening;
|
||||
_closing = closing;
|
||||
_maxWidth = maxWidth;
|
||||
_widthMargin = widthMargin;
|
||||
_heightMargin = heightMargin;
|
||||
_minWidth = minWidth;
|
||||
_maxWidth = maxWidth;
|
||||
_minHeight = minHeight;
|
||||
_maxHeight = maxHeight;
|
||||
_useAnimation = useAnimation;
|
||||
var (windowWidth, windowHeight) = UIHelper.GetAppWindowSizeTuple();
|
||||
UniqueId = content.UniqueId;
|
||||
content.UIContent.HorizontalAlignment = HorizontalAlignment.Stretch;
|
||||
content.UIContent.VerticalAlignment = VerticalAlignment.Stretch;
|
||||
|
||||
var themeShadow = new ThemeShadow();
|
||||
var shadowReceiver = new Grid
|
||||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Stretch,
|
||||
VerticalAlignment = VerticalAlignment.Stretch,
|
||||
Background = (Brush)Application.Current.Resources["ApplicationPageBackgroundThemeBrush"],
|
||||
Opacity = 0.4
|
||||
};
|
||||
var popupContentPresenter = new ContentPresenter
|
||||
{
|
||||
Shadow = themeShadow,
|
||||
Translation = new Vector3(0, 0, 40),
|
||||
BorderBrush = (Brush)Application.Current.Resources["PixevalBorderBrush"],
|
||||
Background = (Brush)Application.Current.Resources["PixevalPanelBackgroundThemeBrush"],
|
||||
CornerRadius = new CornerRadius(10),
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
Content = content
|
||||
};
|
||||
|
||||
themeShadow.Receivers.Add(shadowReceiver);
|
||||
|
||||
if (lightDismiss)
|
||||
{
|
||||
shadowReceiver.Tapped += OnShadowReceiverOnTapped;
|
||||
}
|
||||
else
|
||||
{
|
||||
shadowReceiver.Tapped -= OnShadowReceiverOnTapped;
|
||||
}
|
||||
|
||||
void OnShadowReceiverOnTapped(object sender, TappedRoutedEventArgs a)
|
||||
{
|
||||
PopupManager.ClosePopup(PopupManager.OpenPopups[UniqueId]);
|
||||
}
|
||||
|
||||
Popup = new Popup
|
||||
{
|
||||
RequestedTheme = App.AppViewModel.AppRootFrameTheme,
|
||||
Transitions = new TransitionCollection
|
||||
{
|
||||
new PopupThemeTransition()
|
||||
},
|
||||
XamlRoot = App.AppViewModel.AppWindowRootFrame.XamlRoot,
|
||||
Width = windowWidth,
|
||||
Height = windowHeight,
|
||||
Child = new Grid
|
||||
{
|
||||
Children =
|
||||
{
|
||||
shadowReceiver, popupContentPresenter
|
||||
}
|
||||
}
|
||||
};
|
||||
CurrentContext.Window.SizeChanged += WindowOnSizeChanged;
|
||||
}
|
||||
|
||||
public Popup Popup { get; }
|
||||
|
||||
public Guid UniqueId { get; }
|
||||
|
||||
private void WindowOnSizeChanged(object sender, WindowSizeChangedEventArgs args)
|
||||
{
|
||||
RearrangePopup(args.Size);
|
||||
}
|
||||
|
||||
private void RearrangePopup(Size desiredSize)
|
||||
{
|
||||
var (windowWidth, windowHeight) = (desiredSize.Width, desiredSize.Height);
|
||||
var child = (Grid)Popup.Child;
|
||||
var container = (ContentPresenter)((Grid)Popup.Child).Children[1];
|
||||
Popup.Width = windowWidth;
|
||||
Popup.Height = windowHeight;
|
||||
child.Width = windowWidth;
|
||||
child.Height = windowHeight;
|
||||
if (!double.IsNaN(_width))
|
||||
{
|
||||
container.Width = _width;
|
||||
}
|
||||
else if (!double.IsNaN(_widthMargin))
|
||||
{
|
||||
container.Width = Math.Clamp(windowWidth - _widthMargin * 2, _minWidth, _maxWidth);
|
||||
}
|
||||
|
||||
if (!double.IsNaN(_height))
|
||||
{
|
||||
container.Height = _height;
|
||||
}
|
||||
else if (!double.IsNaN(_heightMargin))
|
||||
{
|
||||
container.Height = Math.Clamp(windowHeight - _heightMargin * 2, _minHeight, _maxHeight);
|
||||
}
|
||||
}
|
||||
|
||||
public void Show()
|
||||
{
|
||||
if (_useAnimation)
|
||||
{
|
||||
var inAnimation = new PopInThemeAnimation();
|
||||
var storyboard = UIHelper.CreateStoryboard(inAnimation);
|
||||
Storyboard.SetTarget(inAnimation, Popup);
|
||||
storyboard.Begin();
|
||||
}
|
||||
|
||||
Popup.IsOpen = true;
|
||||
_opening?.Invoke(_content);
|
||||
RearrangePopup(UIHelper.GetDpiAwareAppWindowSize());
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (_useAnimation)
|
||||
{
|
||||
var inAnimation = new PopOutThemeAnimation();
|
||||
var storyboard = UIHelper.CreateStoryboard(inAnimation);
|
||||
Storyboard.SetTarget(inAnimation, Popup);
|
||||
storyboard.Completed += (_, _) =>
|
||||
{
|
||||
Popup.IsOpen = false;
|
||||
_closing?.Invoke(_content, _content is ICompletableAppPopupContent completable ? completable.GetCompletionResult() : null);
|
||||
};
|
||||
storyboard.Begin();
|
||||
}
|
||||
else
|
||||
{
|
||||
Popup.IsOpen = false;
|
||||
_closing?.Invoke(_content, _content is ICompletableAppPopupContent completable ? completable.GetCompletionResult() : null);
|
||||
}
|
||||
}
|
||||
|
||||
~AppPopup()
|
||||
{
|
||||
CurrentContext.Window.SizeChanged -= WindowOnSizeChanged;
|
||||
}
|
||||
}
|
@ -4,9 +4,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="using:Pixeval.Util.UI"
|
||||
xmlns:userControls="using:Pixeval.UserControls"
|
||||
ui:NavigationHelper.ClosePopupHotKey="Escape"
|
||||
mc:Ignorable="d">
|
||||
<StackPanel>
|
||||
<Grid>
|
||||
|
@ -1,31 +0,0 @@
|
||||
#region Copyright (c) Pixeval/Pixeval
|
||||
// GPL v3 License
|
||||
//
|
||||
// Pixeval/Pixeval
|
||||
// Copyright (c) 2022 Pixeval/IAppPopupContent.cs
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using Microsoft.UI.Xaml;
|
||||
|
||||
namespace Pixeval.Popups;
|
||||
|
||||
public interface IAppPopupContent
|
||||
{
|
||||
Guid UniqueId { get; }
|
||||
|
||||
FrameworkElement UIContent { get; }
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
#region Copyright (c) Pixeval/Pixeval
|
||||
// GPL v3 License
|
||||
//
|
||||
// Pixeval/Pixeval
|
||||
// Copyright (c) 2022 Pixeval/ICompletableAppPopupContent.cs
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
namespace Pixeval.Popups;
|
||||
|
||||
public interface ICompletableAppPopupContent : IAppPopupContent
|
||||
{
|
||||
object GetCompletionResult();
|
||||
}
|
@ -1,132 +1,87 @@
|
||||
<UserControl x:Class="Pixeval.Popups.IllustrationResultFilter.IllustrationResultFilterPopupContent"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:illustrationResultFilter="using:Pixeval.Popups.IllustrationResultFilter"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tokenInput="using:Pixeval.UserControls.TokenInput"
|
||||
xmlns:tokenInputTextBox="using:Pixeval.Controls.TokenInputTextBox"
|
||||
xmlns:ui="using:Pixeval.Util.UI"
|
||||
ui:NavigationHelper.ClosePopupHotKey="Escape"
|
||||
Loaded="IllustrationResultFilterPopupContent_OnLoaded"
|
||||
mc:Ignorable="d">
|
||||
<Grid Margin="20">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<TextBlock x:Uid="/IllustrationResultFilterPopupContent/TitleTextBlock"
|
||||
Margin="0,0,0,10"
|
||||
Style="{StaticResource TitleTextBlockStyle}" />
|
||||
<Button x:Name="CloseButton"
|
||||
Width="38"
|
||||
Height="38"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Content="{ui:FontIcon Glyph=ChromeCloseE8BB,
|
||||
FontSize={StaticResource PixevalButtonIconSize}}"
|
||||
CornerRadius="90"
|
||||
Tapped="CloseButton_OnTapped" />
|
||||
</Grid>
|
||||
<ScrollViewer Grid.Row="1">
|
||||
<StackPanel HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
Spacing="5">
|
||||
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
|
||||
x:Uid="/IllustrationResultFilterPopupContent/LeastBookmarkCountEntry">
|
||||
<NumberBox x:Uid="/IllustrationResultFilterPopupContent/LeastBookmarkCountNumberBox"
|
||||
Width="400"
|
||||
HorizontalAlignment="Left"
|
||||
Minimum="0"
|
||||
Style="{StaticResource SettingsNumberBoxStyle}"
|
||||
Value="{x:Bind _viewModel.LeastBookmark, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
|
||||
x:Uid="/IllustrationResultFilterPopupContent/MaximumBookmarkCountEntry">
|
||||
<NumberBox x:Uid="/IllustrationResultFilterPopupContent/MaximumBookmarkCountNumberBox"
|
||||
Width="400"
|
||||
HorizontalAlignment="Left"
|
||||
Minimum="0"
|
||||
Style="{StaticResource SettingsNumberBoxStyle}"
|
||||
Value="{x:Bind _viewModel.MaximumBookmark, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
|
||||
x:Uid="/IllustrationResultFilterPopupContent/IncludeTagsEntry">
|
||||
<tokenInput:TokenInput x:Uid="/IllustrationResultFilterPopupContent/IncludeTagTokenInput"
|
||||
TokenSource="{x:Bind _viewModel.IncludeTags, Mode=OneWay}" />
|
||||
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
|
||||
x:Uid="/IllustrationResultFilterPopupContent/ExcludeTagsEntry">
|
||||
<tokenInput:TokenInput x:Uid="/IllustrationResultFilterPopupContent/ExcludeTagTokenInput"
|
||||
TokenSource="{x:Bind _viewModel.ExcludeTags, Mode=OneWay}" />
|
||||
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
|
||||
x:Uid="/IllustrationResultFilterPopupContent/UserGroupNameEntry">
|
||||
<tokenInput:TokenInput x:Uid="/IllustrationResultFilterPopupContent/UserGroupNameInput"
|
||||
TokenSource="{x:Bind _viewModel.UserGroupName, Mode=OneWay}" />
|
||||
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
|
||||
x:Uid="/IllustrationResultFilterPopupContent/IllustratorNameEntry">
|
||||
<tokenInputTextBox:TokenInputTextBox
|
||||
x:Uid="/IllustrationResultFilterPopupContent/IllustratorNameInput"
|
||||
Token="{x:Bind _viewModel.IllustratorName, Mode=OneWay}" />
|
||||
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
|
||||
x:Uid="/IllustrationResultFilterPopupContent/IllustrationNameEntry">
|
||||
<tokenInputTextBox:TokenInputTextBox
|
||||
x:Uid="/IllustrationResultFilterPopupContent/IllustrationNameInput"
|
||||
Token="{x:Bind _viewModel.IllustrationName, Mode=OneWay}" />
|
||||
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
|
||||
x:Uid="/IllustrationResultFilterPopupContent/IllustratorIdEntry">
|
||||
<NumberBox x:Uid="/IllustrationResultFilterPopupContent/IllustratorIdInput"
|
||||
Width="400"
|
||||
HorizontalAlignment="Left"
|
||||
SpinButtonPlacementMode="Hidden"
|
||||
Style="{StaticResource SettingsNumberBoxStyle}"
|
||||
Text="{x:Bind _viewModel.IllustratorId, Mode=TwoWay}" />
|
||||
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
|
||||
x:Uid="/IllustrationResultFilterPopupContent/IllustrationIdEntry">
|
||||
<NumberBox x:Uid="/IllustrationResultFilterPopupContent/IllustrationIdInput"
|
||||
Width="400"
|
||||
HorizontalAlignment="Left"
|
||||
SpinButtonPlacementMode="Hidden"
|
||||
Style="{StaticResource SettingsNumberBoxStyle}"
|
||||
Text="{x:Bind _viewModel.IllustrationId, Mode=TwoWay}" />
|
||||
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
|
||||
x:Uid="/IllustrationResultFilterPopupContent/PublishDateStartEntry">
|
||||
<CalendarDatePicker x:Uid="/IllustrationResultFilterPopupContent/PublishDateStartPicker"
|
||||
Width="400"
|
||||
Date="{x:Bind _viewModel.PublishDateStart, Mode=TwoWay}" />
|
||||
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
|
||||
x:Uid="/IllustrationResultFilterPopupContent/PublishDateEndEntry">
|
||||
<CalendarDatePicker x:Uid="/IllustrationResultFilterPopupContent/PublishDateEndPicker"
|
||||
Width="400"
|
||||
Date="{x:Bind _viewModel.PublishDateEnd, Mode=TwoWay}" />
|
||||
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
<Button x:Uid="/IllustrationResultFilterPopupContent/ResetButton"
|
||||
Grid.Row="2"
|
||||
Margin="0,15,0,0"
|
||||
<UserControl
|
||||
x:Class="Pixeval.Popups.IllustrationResultFilter.IllustrationResultFilterPopupContent"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:filter="using:Pixeval.Popups.IllustrationResultFilter"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tokenInput="using:Pixeval.UserControls.TokenInput"
|
||||
xmlns:tokenInputTextBox="using:Pixeval.Controls.TokenInputTextBox"
|
||||
mc:Ignorable="d">
|
||||
<StackPanel Spacing="5">
|
||||
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/LeastBookmarkCountEntry">
|
||||
<NumberBox
|
||||
x:Uid="/IllustrationResultFilterPopupContent/LeastBookmarkCountNumberBox"
|
||||
Width="400"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Tapped="ResetButton_OnTapped" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
Minimum="0"
|
||||
Style="{StaticResource SettingsNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.LeastBookmark, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</filter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/MaximumBookmarkCountEntry">
|
||||
<NumberBox
|
||||
x:Uid="/IllustrationResultFilterPopupContent/MaximumBookmarkCountNumberBox"
|
||||
Width="400"
|
||||
HorizontalAlignment="Left"
|
||||
Minimum="0"
|
||||
Style="{StaticResource SettingsNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.MaximumBookmark, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</filter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/IncludeTagsEntry">
|
||||
<tokenInput:TokenInput x:Uid="/IllustrationResultFilterPopupContent/IncludeTagTokenInput" TokenSource="{x:Bind ViewModel.IncludeTags, Mode=OneWay}" />
|
||||
</filter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/ExcludeTagsEntry">
|
||||
<tokenInput:TokenInput x:Uid="/IllustrationResultFilterPopupContent/ExcludeTagTokenInput" TokenSource="{x:Bind ViewModel.ExcludeTags, Mode=OneWay}" />
|
||||
</filter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/UserGroupNameEntry">
|
||||
<tokenInput:TokenInput x:Uid="/IllustrationResultFilterPopupContent/UserGroupNameInput" TokenSource="{x:Bind ViewModel.UserGroupName, Mode=OneWay}" />
|
||||
</filter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/IllustratorNameEntry">
|
||||
<tokenInputTextBox:TokenInputTextBox x:Uid="/IllustrationResultFilterPopupContent/IllustratorNameInput" Token="{x:Bind ViewModel.IllustratorName, Mode=OneWay}" />
|
||||
</filter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/IllustrationNameEntry">
|
||||
<tokenInputTextBox:TokenInputTextBox x:Uid="/IllustrationResultFilterPopupContent/IllustrationNameInput" Token="{x:Bind ViewModel.IllustrationName, Mode=OneWay}" />
|
||||
</filter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/IllustratorIdEntry">
|
||||
<NumberBox
|
||||
x:Uid="/IllustrationResultFilterPopupContent/IllustratorIdInput"
|
||||
Width="400"
|
||||
HorizontalAlignment="Left"
|
||||
SpinButtonPlacementMode="Hidden"
|
||||
Style="{StaticResource SettingsNumberBoxStyle}"
|
||||
Text="{x:Bind ViewModel.IllustratorId, Mode=TwoWay}" />
|
||||
</filter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/IllustrationIdEntry">
|
||||
<NumberBox
|
||||
x:Uid="/IllustrationResultFilterPopupContent/IllustrationIdInput"
|
||||
Width="400"
|
||||
HorizontalAlignment="Left"
|
||||
SpinButtonPlacementMode="Hidden"
|
||||
Style="{StaticResource SettingsNumberBoxStyle}"
|
||||
Text="{x:Bind ViewModel.IllustrationId, Mode=TwoWay}" />
|
||||
</filter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/PublishDateStartEntry">
|
||||
<CalendarDatePicker
|
||||
x:Uid="/IllustrationResultFilterPopupContent/PublishDateStartPicker"
|
||||
Width="400"
|
||||
Date="{x:Bind ViewModel.PublishDateStart, Mode=TwoWay}" />
|
||||
</filter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/PublishDateEndEntry">
|
||||
<CalendarDatePicker
|
||||
x:Uid="/IllustrationResultFilterPopupContent/PublishDateEndPicker"
|
||||
Width="400"
|
||||
Date="{x:Bind ViewModel.PublishDateEnd, Mode=TwoWay}" />
|
||||
</filter:IllustrationResultFilterFunctionEntry>
|
||||
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
@ -1,4 +1,4 @@
|
||||
#region Copyright (c) Pixeval/Pixeval
|
||||
#region Copyright (c) Pixeval/Pixeval
|
||||
// GPL v3 License
|
||||
//
|
||||
// Pixeval/Pixeval
|
||||
@ -18,91 +18,39 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Pixeval.Attributes;
|
||||
|
||||
|
||||
namespace Pixeval.Popups.IllustrationResultFilter;
|
||||
|
||||
public sealed partial class IllustrationResultFilterPopupContent : ICompletableAppPopupContent
|
||||
public sealed partial class IllustrationResultFilterPopupContent
|
||||
{
|
||||
private readonly IllustrationResultFilterPopupViewModel _viewModel;
|
||||
public IllustrationResultFilterPopupViewModel ViewModel { get; set; } = new();
|
||||
|
||||
private EventHandler<TappedRoutedEventArgs>? _closeButtonTapped;
|
||||
|
||||
private EventHandler<TappedRoutedEventArgs>? _resetButtonTapped;
|
||||
|
||||
public IllustrationResultFilterPopupContent(IllustrationResultFilterPopupViewModel viewModel)
|
||||
public IllustrationResultFilterPopupContent()
|
||||
{
|
||||
_viewModel = viewModel;
|
||||
UniqueId = Guid.NewGuid();
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public bool IsReset { get; private set; }
|
||||
public FilterSettings GetFilterSettings =>
|
||||
new(ViewModel.IncludeTags,
|
||||
ViewModel.ExcludeTags,
|
||||
ViewModel.LeastBookmark,
|
||||
ViewModel.MaximumBookmark,
|
||||
ViewModel.UserGroupName,
|
||||
ViewModel.IllustratorName,
|
||||
ViewModel.IllustratorId,
|
||||
ViewModel.IllustrationName,
|
||||
ViewModel.IllustrationId,
|
||||
ViewModel.PublishDateStart,
|
||||
ViewModel.PublishDateEnd);
|
||||
|
||||
public Guid UniqueId { get; }
|
||||
|
||||
public FrameworkElement UIContent => this;
|
||||
|
||||
public object GetCompletionResult()
|
||||
public void Reset()
|
||||
{
|
||||
return new FilterSettings(
|
||||
_viewModel.IncludeTags,
|
||||
_viewModel.ExcludeTags,
|
||||
_viewModel.LeastBookmark,
|
||||
_viewModel.MaximumBookmark,
|
||||
_viewModel.UserGroupName,
|
||||
_viewModel.IllustratorName,
|
||||
_viewModel.IllustratorId,
|
||||
_viewModel.IllustrationName,
|
||||
_viewModel.IllustrationId,
|
||||
_viewModel.PublishDateStart,
|
||||
_viewModel.PublishDateEnd);
|
||||
}
|
||||
|
||||
public event EventHandler<TappedRoutedEventArgs> ResetButtonTapped
|
||||
{
|
||||
add => _resetButtonTapped += value;
|
||||
remove => _resetButtonTapped -= value;
|
||||
}
|
||||
|
||||
public event EventHandler<TappedRoutedEventArgs> CloseButtonTapped
|
||||
{
|
||||
add => _closeButtonTapped += value;
|
||||
remove => _closeButtonTapped -= value;
|
||||
}
|
||||
|
||||
private void CloseButton_OnTapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
_closeButtonTapped?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flush the bindings
|
||||
/// </summary>
|
||||
public void Cleanup()
|
||||
{
|
||||
Focus(FocusState.Programmatic);
|
||||
}
|
||||
|
||||
private void ResetButton_OnTapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
IsReset = true;
|
||||
foreach (var propertyInfo in typeof(IllustrationResultFilterPopupViewModel).GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
{
|
||||
propertyInfo.SetValue(_viewModel, propertyInfo.GetDefaultValue());
|
||||
propertyInfo.SetValue(ViewModel, propertyInfo.GetDefaultValue());
|
||||
}
|
||||
|
||||
_resetButtonTapped?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void IllustrationResultFilterPopupContent_OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Focus the popup content so that the hot key for closing can work properly
|
||||
CloseButton.Focus(FocusState.Programmatic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
<UserControl x:Class="Pixeval.Popups.LoginWebViewPopup"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<WebView2 x:Name="LoginWebView"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
x:FieldModifier="public"
|
||||
CoreWebView2Initialized="LoginWebView_OnCoreWebView2Initialized"
|
||||
NavigationStarting="LoginWebView_OnNavigationStarting" />
|
||||
<UserControl
|
||||
x:Class="Pixeval.Popups.LoginWebViewPopup"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<WebView2
|
||||
x:Name="LoginWebView"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
x:FieldModifier="public"
|
||||
CoreWebView2Initialized="LoginWebView_OnCoreWebView2Initialized"
|
||||
NavigationStarting="LoginWebView_OnNavigationStarting" />
|
||||
</UserControl>
|
||||
|
@ -1,4 +1,4 @@
|
||||
#region Copyright (c) Pixeval/Pixeval
|
||||
#region Copyright (c) Pixeval/Pixeval
|
||||
// GPL v3 License
|
||||
//
|
||||
// Pixeval/Pixeval
|
||||
@ -25,35 +25,26 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
|
||||
namespace Pixeval.Popups
|
||||
namespace Pixeval.Popups;
|
||||
|
||||
public sealed partial class LoginWebViewPopup
|
||||
{
|
||||
public sealed partial class LoginWebViewPopup : IAppPopupContent
|
||||
public LoginWebViewPopup() => InitializeComponent();
|
||||
|
||||
public readonly TaskCompletionSource<(string, string)> CookieCompletion = new();
|
||||
|
||||
private async void LoginWebView_OnNavigationStarting(WebView2 sender, CoreWebView2NavigationStartingEventArgs args)
|
||||
{
|
||||
public LoginWebViewPopup()
|
||||
if (args.Uri.StartsWith("pixiv://"))
|
||||
{
|
||||
InitializeComponent();
|
||||
UniqueId = Guid.NewGuid();
|
||||
}
|
||||
|
||||
public readonly TaskCompletionSource<(string, string)> CookieCompletion = new();
|
||||
|
||||
public Guid UniqueId { get; }
|
||||
|
||||
public FrameworkElement UIContent => this;
|
||||
|
||||
private async void LoginWebView_OnNavigationStarting(WebView2 sender, CoreWebView2NavigationStartingEventArgs args)
|
||||
{
|
||||
if (args.Uri.StartsWith("pixiv://"))
|
||||
{
|
||||
var cookies = await LoginWebView.CoreWebView2.CookieManager.GetCookiesAsync("https://pixiv.net");
|
||||
var cookieString = string.Join(';', cookies.Select(c => $"{c.Name}={c.Value}"));
|
||||
CookieCompletion.SetResult((args.Uri, cookieString));
|
||||
}
|
||||
}
|
||||
|
||||
private async void LoginWebView_OnCoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
|
||||
{
|
||||
await LoginWebView.CoreWebView2.CallDevToolsProtocolMethodAsync("Security.setIgnoreCertificateErrors", "{ \"ignore\": true }");
|
||||
var cookies = await LoginWebView.CoreWebView2.CookieManager.GetCookiesAsync("https://pixiv.net");
|
||||
var cookieString = string.Join(';', cookies.Select(c => $"{c.Name}={c.Value}"));
|
||||
CookieCompletion.SetResult((args.Uri, cookieString));
|
||||
}
|
||||
}
|
||||
|
||||
private async void LoginWebView_OnCoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
|
||||
{
|
||||
await LoginWebView.CoreWebView2.CallDevToolsProtocolMethodAsync("Security.setIgnoreCertificateErrors", "{ \"ignore\": true }");
|
||||
}
|
||||
}
|
||||
|
@ -177,12 +177,6 @@
|
||||
<data name="PublishDateStartPicker.PlaceholderText" xml:space="preserve">
|
||||
<value>只会包含该日期后发布的作品</value>
|
||||
</data>
|
||||
<data name="ResetButton.Content" xml:space="preserve">
|
||||
<value>清空过滤器</value>
|
||||
</data>
|
||||
<data name="TitleTextBlock.Text" xml:space="preserve">
|
||||
<value>过滤器设置</value>
|
||||
</data>
|
||||
<data name="UserGroupNameEntry.Header" xml:space="preserve">
|
||||
<value>自定义收藏夹的名称</value>
|
||||
</data>
|
||||
|
@ -168,4 +168,13 @@
|
||||
<data name="FastFilterAutoSuggestBox.PlaceholderText" xml:space="preserve">
|
||||
<value>输入ID/标签/作品名进行快速过滤</value>
|
||||
</data>
|
||||
<data name="FilterTeachingTip.ActionButtonContent" xml:space="preserve">
|
||||
<value>清空过滤器</value>
|
||||
</data>
|
||||
<data name="FilterTeachingTip.CloseButtonContent" xml:space="preserve">
|
||||
<value>应用</value>
|
||||
</data>
|
||||
<data name="FilterTeachingTip.Title" xml:space="preserve">
|
||||
<value>过滤器设置</value>
|
||||
</data>
|
||||
</root>
|
@ -123,7 +123,8 @@ public sealed partial class IllustrationView
|
||||
{
|
||||
TitleBarType = TitleBarHelper.TitleBarType.AppWindow,
|
||||
Size = new SizeInt32(width, height)
|
||||
});
|
||||
})
|
||||
.Activate();
|
||||
}
|
||||
|
||||
private static unsafe (int windowWidth, int windowHeight) DetermineWindowSize(int illustWidth, double illustRatio)
|
||||
|
@ -4,6 +4,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:illustrationResultFilter="using:Pixeval.Popups.IllustrationResultFilter"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="using:Pixeval.Util.UI"
|
||||
mc:Ignorable="d">
|
||||
@ -38,11 +39,11 @@
|
||||
Icon="{ui:FontIcon Glyph=CancelE711}"
|
||||
Label="{x:Bind ViewModel.SelectionLabel, Mode=OneWay}"
|
||||
Tapped="CancelSelectionButton_OnTapped" />
|
||||
<AppBarToggleButton
|
||||
<AppBarButton
|
||||
x:Name="OpenConditionDialogButton"
|
||||
x:Uid="/IllustrationViewCommandBar/OpenConditionDialogButton"
|
||||
Checked="OpenConditionDialogButton_OnChecked"
|
||||
Icon="{ui:FontIcon Glyph=FilterE71C}" />
|
||||
Icon="{ui:FontIcon Glyph=FilterE71C}"
|
||||
Tapped="OpenConditionDialogButton_OnTapped" />
|
||||
<AppBarButton
|
||||
x:Name="SelectAllButton"
|
||||
x:Uid="/IllustrationViewCommandBar/SelectAllButton"
|
||||
@ -66,6 +67,16 @@
|
||||
Icon="{ui:FontIcon Glyph=ShareE72D}"
|
||||
Tapped="ShareButton_OnTapped" />
|
||||
</CommandBar>
|
||||
<TeachingTip
|
||||
x:Name="FilterTeachingTip"
|
||||
x:Uid="/IllustrationViewCommandBar/FilterTeachingTip"
|
||||
Grid.Column="0"
|
||||
ActionButtonClick="FilterTeachingTip_OnActionButtonClick"
|
||||
CloseButtonClick="FilterTeachingTip_OnCloseButtonClick"
|
||||
IsLightDismissEnabled="True"
|
||||
Target="{x:Bind OpenConditionDialogButton}">
|
||||
<illustrationResultFilter:IllustrationResultFilterPopupContent x:Name="FilterContent" />
|
||||
</TeachingTip>
|
||||
<TeachingTip
|
||||
x:Name="CommandBarTeachingTip"
|
||||
Grid.Column="0"
|
||||
|
@ -55,8 +55,6 @@ public sealed partial class IllustrationViewCommandBar
|
||||
|
||||
private FilterSettings _lastFilterSettings = FilterSettings.Default;
|
||||
|
||||
private readonly IllustrationResultFilterPopupViewModel _filterPopupViewModel = new();
|
||||
|
||||
public IllustrationViewCommandBar()
|
||||
{
|
||||
InitializeComponent();
|
||||
@ -219,27 +217,19 @@ public sealed partial class IllustrationViewCommandBar
|
||||
ViewModel.DataProvider.IllustrationsSource.WhereNotNull().ForEach(i => i.IsSelected = false);
|
||||
}
|
||||
|
||||
private void OpenConditionDialogButton_OnChecked(object sender, RoutedEventArgs e)
|
||||
private void OpenConditionDialogButton_OnTapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
var content = new IllustrationResultFilterPopupContent(_filterPopupViewModel);
|
||||
var popup = PopupManager.CreatePopup(content, 550, heightMargin: 100, lightDismiss: false, closing: ConditionPopupClosing);
|
||||
content.ResetButtonTapped += (_, _) =>
|
||||
{
|
||||
content.Cleanup();
|
||||
PopupManager.ClosePopup(popup);
|
||||
};
|
||||
content.CloseButtonTapped += (_, _) =>
|
||||
{
|
||||
content.Cleanup();
|
||||
PopupManager.ClosePopup(popup);
|
||||
};
|
||||
PopupManager.ShowPopup(popup);
|
||||
FilterTeachingTip.IsOpen = true;
|
||||
}
|
||||
|
||||
private void ConditionPopupClosing(IAppPopupContent popup, object? arg)
|
||||
private void FilterTeachingTip_OnActionButtonClick(TeachingTip sender, object args)
|
||||
{
|
||||
OpenConditionDialogButton.IsChecked = false;
|
||||
if (arg is FilterSettings(
|
||||
FilterContent.Reset();
|
||||
}
|
||||
|
||||
private void FilterTeachingTip_OnCloseButtonClick(TeachingTip sender, object args)
|
||||
{
|
||||
if (FilterContent.GetFilterSettings is (
|
||||
var includeTags,
|
||||
var excludeTags,
|
||||
var leastBookmark,
|
||||
@ -258,11 +248,6 @@ public sealed partial class IllustrationViewCommandBar
|
||||
}
|
||||
|
||||
_lastFilterSettings = filterSettings;
|
||||
if (popup is IllustrationResultFilterPopupContent { IsReset: true })
|
||||
{
|
||||
ViewModel.DataProvider.Filter = null;
|
||||
return;
|
||||
}
|
||||
|
||||
ViewModel.DataProvider.Filter = null;
|
||||
ViewModel.DataProvider.Filter = o =>
|
||||
|
@ -1,4 +1,4 @@
|
||||
#region Copyright (c) Pixeval/Pixeval
|
||||
#region Copyright (c) Pixeval/Pixeval
|
||||
// GPL v3 License
|
||||
//
|
||||
// Pixeval/Pixeval
|
||||
@ -52,7 +52,7 @@ public static class ThreadingHelper
|
||||
|
||||
public static void CompareExchange(ref int location1, int value, int comparand)
|
||||
{
|
||||
do { } while (Interlocked.CompareExchange(ref location1, value, comparand) != comparand);
|
||||
while (Interlocked.CompareExchange(ref location1, value, comparand) != comparand);
|
||||
}
|
||||
|
||||
// fork a task from current context.
|
||||
@ -117,4 +117,4 @@ public static class ThreadingHelper
|
||||
}).Discard();
|
||||
return tcs.Task;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,108 +0,0 @@
|
||||
#region Copyright (c) Pixeval/Pixeval
|
||||
// GPL v3 License
|
||||
//
|
||||
// Pixeval/Pixeval
|
||||
// Copyright (c) 2022 Pixeval/NavigationHelper.cs
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using Windows.System;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Pixeval.Popups;
|
||||
|
||||
namespace Pixeval.Util.UI;
|
||||
|
||||
public static class NavigationHelper
|
||||
{
|
||||
public static readonly DependencyProperty BackHotKeyProperty = DependencyProperty.RegisterAttached(
|
||||
"BackHotKey",
|
||||
typeof(VirtualKey),
|
||||
typeof(NavigationHelper),
|
||||
new PropertyMetadata(DependencyProperty.UnsetValue, BackHotKeyChanged));
|
||||
|
||||
public static readonly DependencyProperty ClosePopupHotKeyProperty = DependencyProperty.RegisterAttached(
|
||||
"ClosePopupHotKey",
|
||||
typeof(VirtualKey),
|
||||
typeof(NavigationHelper),
|
||||
new PropertyMetadata(DependencyProperty.UnsetValue, ClosePopupHotKey));
|
||||
|
||||
public static void SetBackHotKey(DependencyObject element, VirtualKey value)
|
||||
{
|
||||
element.SetValue(BackHotKeyProperty, value);
|
||||
}
|
||||
|
||||
public static VirtualKey GetBackHotKey(DependencyObject element)
|
||||
{
|
||||
return (VirtualKey)element.GetValue(BackHotKeyProperty);
|
||||
}
|
||||
|
||||
private static void BackHotKeyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is Page and IGoBack)
|
||||
{
|
||||
if (e.NewValue is VirtualKey)
|
||||
{
|
||||
((Page)d).KeyDown += OnKeyDown;
|
||||
}
|
||||
else
|
||||
{
|
||||
((Page)d).KeyDown -= OnKeyDown;
|
||||
}
|
||||
|
||||
void OnKeyDown(object _, KeyRoutedEventArgs args)
|
||||
{
|
||||
if (args.Key == (VirtualKey)e.NewValue)
|
||||
{
|
||||
((IGoBack)d).GoBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetClosePopupHotKey(DependencyObject element, VirtualKey value)
|
||||
{
|
||||
element.SetValue(ClosePopupHotKeyProperty, value);
|
||||
}
|
||||
|
||||
public static VirtualKey GetClosePopupHotKey(DependencyObject element)
|
||||
{
|
||||
return (VirtualKey)element.GetValue(ClosePopupHotKeyProperty);
|
||||
}
|
||||
|
||||
private static void ClosePopupHotKey(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is IAppPopupContent content)
|
||||
{
|
||||
if (e.NewValue is VirtualKey)
|
||||
{
|
||||
content.UIContent.KeyDown += UIContentOnKeyDown;
|
||||
}
|
||||
else
|
||||
{
|
||||
content.UIContent.KeyDown -= UIContentOnKeyDown;
|
||||
}
|
||||
|
||||
void UIContentOnKeyDown(object sender, KeyRoutedEventArgs args)
|
||||
{
|
||||
if (args.Key == (VirtualKey)e.NewValue)
|
||||
{
|
||||
PopupManager.ClosePopup(content.UniqueId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -33,7 +33,11 @@ public static class WindowFactory
|
||||
public static CustomizableWindow Fork(this Window owner, out CustomizableWindow window)
|
||||
{
|
||||
var w = window = new(owner);
|
||||
window.Closed += (_, _) => ForkedWindowsInternal.Remove(w);
|
||||
window.Closed += (_, _) =>
|
||||
{
|
||||
w.Close();
|
||||
ForkedWindowsInternal.Remove(w);
|
||||
};
|
||||
ForkedWindowsInternal.Add(window);
|
||||
return window;
|
||||
}
|
||||
@ -44,8 +48,9 @@ public static class WindowFactory
|
||||
return window;
|
||||
}
|
||||
|
||||
public static void Initialize(this CustomizableWindow window, AppHelper.InitializeInfo provider)
|
||||
public static CustomizableWindow Initialize(this CustomizableWindow window, WindowHelper.InitializeInfo provider)
|
||||
{
|
||||
AppHelper.Initialize(provider, window);
|
||||
WindowHelper.Initialize(window, provider);
|
||||
return window;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user