mirror of
https://github.com/Pixeval/Pixeval.git
synced 2025-01-08 11:47:34 +08:00
Supports protocol activation for illustrations
This commit is contained in:
parent
69fefc84b6
commit
3f221021b7
@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31515.178
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31808.319
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pixeval", "src\Pixeval\Pixeval.csproj", "{97004D5A-21BE-4137-A529-A9E150AEB3CE}"
|
||||
EndProject
|
||||
|
26
src/Pixeval/Activation/ActivationRegistrar.cs
Normal file
26
src/Pixeval/Activation/ActivationRegistrar.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
using Microsoft.Windows.AppLifecycle;
|
||||
|
||||
namespace Pixeval.Activation
|
||||
{
|
||||
public static class ActivationRegistrar
|
||||
{
|
||||
static ActivationRegistrar()
|
||||
{
|
||||
FeatureHandlers[IllustrationActivationFragment] = new IllustrationAppActivationHandler();
|
||||
}
|
||||
|
||||
public static readonly Dictionary<string, IAppActivationHandler> FeatureHandlers = new();
|
||||
|
||||
public const string IllustrationActivationFragment = "illust";
|
||||
|
||||
public static void Dispatch(AppActivationArguments args)
|
||||
{
|
||||
if (args.Kind == ExtendedActivationKind.Protocol && args.Data is IProtocolActivatedEventArgs { Uri: var activationUri } && FeatureHandlers.TryGetValue(activationUri.Host, out var handler))
|
||||
{
|
||||
handler.Execute(activationUri.PathAndQuery[1..]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
src/Pixeval/Activation/IAppActivationHandler.cs
Normal file
9
src/Pixeval/Activation/IAppActivationHandler.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pixeval.Activation
|
||||
{
|
||||
public interface IAppActivationHandler
|
||||
{
|
||||
Task Execute(string id);
|
||||
}
|
||||
}
|
46
src/Pixeval/Activation/IllustrationAppActivationHandler.cs
Normal file
46
src/Pixeval/Activation/IllustrationAppActivationHandler.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Toolkit.Mvvm.Messaging;
|
||||
using Microsoft.UI.Xaml.Media.Animation;
|
||||
using Pixeval.Messages;
|
||||
using Pixeval.Pages.IllustrationViewer;
|
||||
using Pixeval.Util.UI;
|
||||
using Pixeval.Utilities;
|
||||
using Pixeval.ViewModel;
|
||||
|
||||
namespace Pixeval.Activation
|
||||
{
|
||||
public class IllustrationAppActivationHandler : IAppActivationHandler
|
||||
{
|
||||
public Task Execute(string id)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send(new MainPageFrameSetConnectedAnimationTargetMessage(App.AppViewModel.AppWindowRootFrame));
|
||||
|
||||
return App.AppViewModel.DispatchTaskAsync(async () =>
|
||||
{
|
||||
App.AppViewModel.PrepareForActivation();
|
||||
|
||||
try
|
||||
{
|
||||
var viewModels = new IllustrationViewModel(await App.AppViewModel.MakoClient.GetIllustrationFromIdAsync(id))
|
||||
.GetMangaIllustrationViewModels()
|
||||
.ToArray();
|
||||
|
||||
ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("ForwardConnectedAnimation", App.AppViewModel.AppWindowRootFrame);
|
||||
App.AppViewModel.RootFrameNavigate(typeof(IllustrationViewerPage), new IllustrationViewerPageViewModel(viewModels), new SuppressNavigationTransitionInfo());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UIHelper.ShowTextToastNotification(
|
||||
ActivationsResources.IllustrationActivationFailedTitle,
|
||||
ActivationsResources.IllustrationActivationFailedContentFormatted.Format(e.Message));
|
||||
}
|
||||
finally
|
||||
{
|
||||
App.AppViewModel.ActivationProcessed();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,13 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.Windows.AppLifecycle;
|
||||
using Pixeval.Activation;
|
||||
using Pixeval.Util.UI;
|
||||
using Pixeval.ViewModel;
|
||||
using ApplicationTheme = Pixeval.Options.ApplicationTheme;
|
||||
using LaunchActivatedEventArgs = Microsoft.UI.Xaml.LaunchActivatedEventArgs;
|
||||
|
||||
namespace Pixeval
|
||||
{
|
||||
@ -11,7 +16,7 @@ namespace Pixeval
|
||||
private const string ApplicationWideFontKey = "ContentControlThemeFontFamily";
|
||||
|
||||
public static AppViewModel AppViewModel { get; private set; } = null!;
|
||||
|
||||
|
||||
public App()
|
||||
{
|
||||
// The theme can only be changed in ctor
|
||||
@ -22,13 +27,24 @@ namespace Pixeval
|
||||
ApplicationTheme.Light => Microsoft.UI.Xaml.ApplicationTheme.Light,
|
||||
_ => RequestedTheme
|
||||
};
|
||||
AppInstance.GetCurrent().Activated += (_, arguments) => ActivationRegistrar.Dispatch(arguments);
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected override async void OnLaunched(LaunchActivatedEventArgs args)
|
||||
{
|
||||
var isProtocolActivated = AppInstance.GetCurrent().GetActivatedEventArgs() is { Kind: ExtendedActivationKind.Protocol };
|
||||
if (isProtocolActivated && AppInstance.GetInstances().Count > 1)
|
||||
{
|
||||
var notCurrent = AppInstance.GetInstances().First(ins => !ins.IsCurrent);
|
||||
await notCurrent.RedirectActivationToAsync(AppInstance.GetCurrent().GetActivatedEventArgs());
|
||||
return;
|
||||
}
|
||||
|
||||
Current.Resources[ApplicationWideFontKey] = new FontFamily(AppViewModel.AppSetting.AppFontFamilyName);
|
||||
await AppViewModel.InitializeAsync();
|
||||
await AppViewModel.InitializeAsync(isProtocolActivated);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -5,15 +5,31 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Closed="MainWindow_OnClosed"
|
||||
mc:Ignorable="d">
|
||||
<Frame x:Name="PixevalAppRootFrame"
|
||||
x:FieldModifier="public"
|
||||
Loaded="PixevalAppRootFrame_OnLoaded"
|
||||
Navigating="PixevalAppRootFrame_OnNavigating"
|
||||
NavigationFailed="PixevalAppRootFrame_OnNavigationFailed">
|
||||
<Frame.ContentTransitions>
|
||||
<TransitionCollection>
|
||||
<NavigationThemeTransition DefaultNavigationTransitionInfo="{x:Bind DefaultNavigationTransitionInfo}" />
|
||||
</TransitionCollection>
|
||||
</Frame.ContentTransitions>
|
||||
</Frame>
|
||||
<Grid>
|
||||
<Frame x:Name="PixevalAppRootFrame"
|
||||
x:FieldModifier="public"
|
||||
Loaded="PixevalAppRootFrame_OnLoaded"
|
||||
Navigating="PixevalAppRootFrame_OnNavigating"
|
||||
NavigationFailed="PixevalAppRootFrame_OnNavigationFailed">
|
||||
<Frame.ContentTransitions>
|
||||
<TransitionCollection>
|
||||
<NavigationThemeTransition DefaultNavigationTransitionInfo="{x:Bind DefaultNavigationTransitionInfo}" />
|
||||
</TransitionCollection>
|
||||
</Frame.ContentTransitions>
|
||||
</Frame>
|
||||
<Grid x:Name="ProcessingActivation"
|
||||
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"
|
||||
IsIndeterminate="True" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
@ -46,5 +46,15 @@ namespace Pixeval
|
||||
{
|
||||
NavigationMode = e.NavigationMode;
|
||||
}
|
||||
|
||||
public void ShowActivationProgressRing()
|
||||
{
|
||||
ProcessingActivation.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
public void HideActivationProgressRing()
|
||||
{
|
||||
ProcessingActivation.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,5 +9,5 @@ namespace Pixeval.Messages
|
||||
/// <see cref="MainPage"/>, the parameter contains the item that the <see cref="IllustrationViewerPage"/>
|
||||
/// is currently browsing
|
||||
/// </summary>
|
||||
public record NavigatingBackToMainPageMessage(IllustrationViewModel IllustrationViewModel);
|
||||
public record NavigatingBackToMainPageMessage(IllustrationViewModel? IllustrationViewModel);
|
||||
}
|
@ -49,6 +49,13 @@
|
||||
<uap:Rotation Preference="landscape"/>
|
||||
<uap:Rotation Preference="portrait"/></uap:InitialRotationPreference>
|
||||
</uap:VisualElements>
|
||||
<Extensions>
|
||||
<uap:Extension Category="windows.protocol">
|
||||
<uap:Protocol Name="pixeval">
|
||||
<uap:DisplayName>Pixeval App Protocol</uap:DisplayName>
|
||||
</uap:Protocol>
|
||||
</uap:Extension>
|
||||
</Extensions>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
|
@ -61,7 +61,7 @@ namespace Pixeval.Pages.IllustrationViewer
|
||||
|
||||
IllustrationImageShowcaseFrame.Navigate(typeof(ImageViewerPage), _viewModel.Current);
|
||||
|
||||
WeakReferenceMessenger.Default.Send(new MainPageFrameSetConnectedAnimationTargetMessage(_viewModel.IllustrationGrid.GetItemContainer(_viewModel.IllustrationViewModelInTheGridView)));
|
||||
WeakReferenceMessenger.Default.Send(new MainPageFrameSetConnectedAnimationTargetMessage(_viewModel.IllustrationGrid?.GetItemContainer(_viewModel.IllustrationViewModelInTheGridView!) ?? App.AppViewModel.AppWindowRootFrame));
|
||||
WeakReferenceMessenger.Default.Register<IllustrationViewerPage, CommentRepliesHyperlinkButtonTappedMessage>(this, CommentRepliesHyperlinkButtonTapped);
|
||||
}
|
||||
|
||||
@ -133,13 +133,13 @@ namespace Pixeval.Pages.IllustrationViewer
|
||||
Effect = SlideNavigationTransitionEffect.FromLeft
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void NextIllustration()
|
||||
{
|
||||
var illustrationViewModel = (IllustrationViewModel) _viewModel.ContainerGridViewModel.IllustrationsView[_viewModel.IllustrationIndex + 1];
|
||||
var illustrationViewModel = (IllustrationViewModel) _viewModel.ContainerGridViewModel!.IllustrationsView[_viewModel.IllustrationIndex!.Value + 1];
|
||||
var viewModel = illustrationViewModel.GetMangaIllustrationViewModels().ToArray();
|
||||
|
||||
App.AppViewModel.RootFrameNavigate(typeof(IllustrationViewerPage), new IllustrationViewerPageViewModel(_viewModel.IllustrationGrid, viewModel), new SlideNavigationTransitionInfo
|
||||
App.AppViewModel.RootFrameNavigate(typeof(IllustrationViewerPage), new IllustrationViewerPageViewModel(_viewModel.IllustrationGrid!, viewModel), new SlideNavigationTransitionInfo
|
||||
{
|
||||
Effect = SlideNavigationTransitionEffect.FromRight
|
||||
});
|
||||
@ -147,10 +147,10 @@ namespace Pixeval.Pages.IllustrationViewer
|
||||
|
||||
private void PrevIllustration()
|
||||
{
|
||||
var illustrationViewModel = (IllustrationViewModel)_viewModel.ContainerGridViewModel.IllustrationsView[_viewModel.IllustrationIndex - 1];
|
||||
var illustrationViewModel = (IllustrationViewModel) _viewModel.ContainerGridViewModel!.IllustrationsView[_viewModel.IllustrationIndex!.Value - 1];
|
||||
var viewModel = illustrationViewModel.GetMangaIllustrationViewModels().ToArray();
|
||||
|
||||
App.AppViewModel.RootFrameNavigate(typeof(IllustrationViewerPage), new IllustrationViewerPageViewModel(_viewModel.IllustrationGrid, viewModel), new SlideNavigationTransitionInfo
|
||||
App.AppViewModel.RootFrameNavigate(typeof(IllustrationViewerPage), new IllustrationViewerPageViewModel(_viewModel.IllustrationGrid!, viewModel), new SlideNavigationTransitionInfo
|
||||
{
|
||||
Effect = SlideNavigationTransitionEffect.FromLeft
|
||||
});
|
||||
|
@ -83,9 +83,11 @@
|
||||
Icon="{ui:FontIcon Glyph=SearchAndAppsE773}" />
|
||||
<NavigationViewItemHeader x:Uid="/MainPage/DownloadAndHistoriesTab" />
|
||||
<NavigationViewItem x:Uid="/MainPage/HistoriesTab"
|
||||
Icon="{ui:FontIcon Glyph=HistoryE81C}" />
|
||||
Icon="{ui:FontIcon Glyph=HistoryE81C}"
|
||||
Tag="{x:Bind _histories}" />
|
||||
<NavigationViewItem x:Uid="/MainPage/DownloadListTab"
|
||||
Icon="{ui:FontIcon Glyph=CheckListE9D5}" />
|
||||
Icon="{ui:FontIcon Glyph=CheckListE9D5}"
|
||||
Tag="{x:Bind _downloads}" />
|
||||
</NavigationView.MenuItems>
|
||||
<NavigationView.FooterMenuItems>
|
||||
<NavigationViewItem x:Uid="/MainPage/HelpTab"
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using System.Runtime;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
using Windows.Foundation;
|
||||
using Microsoft.Toolkit.Mvvm.Messaging;
|
||||
using Microsoft.UI.Xaml;
|
||||
@ -9,6 +10,8 @@ using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media.Animation;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
using Microsoft.Windows.AppLifecycle;
|
||||
using Pixeval.Activation;
|
||||
using Pixeval.CommunityToolkit;
|
||||
using Pixeval.CommunityToolkit.AdaptiveGridView;
|
||||
using Pixeval.CoreApi.Global.Enum;
|
||||
@ -36,6 +39,10 @@ namespace Pixeval.Pages
|
||||
|
||||
private readonly NavigationViewTag _settings = new(typeof(SettingsPage), App.AppViewModel.MakoClient.Configuration);
|
||||
|
||||
private readonly NavigationViewTag _downloads = new(typeof(DownloadListPage), null);
|
||||
|
||||
private readonly NavigationViewTag _histories = new(typeof(BrowsingHistoryPage), null);
|
||||
|
||||
private static UIElement? _connectedAnimationTarget;
|
||||
|
||||
// This field contains the view model that the illustration viewer is
|
||||
@ -58,6 +65,12 @@ namespace Pixeval.Pages
|
||||
// little dirty tricks
|
||||
((NavigationViewItem) MainPageRootNavigationView.MenuItems[(int) App.AppViewModel.AppSetting.DefaultSelectedTabItem]).IsSelected = true;
|
||||
|
||||
|
||||
if (App.AppViewModel.ConsumeProtocolActivation())
|
||||
{
|
||||
ActivationRegistrar.Dispatch(AppInstance.GetCurrent().GetActivatedEventArgs());
|
||||
}
|
||||
|
||||
WeakReferenceMessenger.Default.Register<MainPage, MainPageFrameSetConnectedAnimationTargetMessage>(this, (_, message) => _connectedAnimationTarget = message.Sender);
|
||||
WeakReferenceMessenger.Default.Register<MainPage, NavigatingBackToMainPageMessage>(this, (_, message) => _illustrationViewerContent = message.IllustrationViewModel);
|
||||
WeakReferenceMessenger.Default.Register<MainPage, IllustrationTagClickedMessage>(this, (_, message) => PerformSearch(message.Tag));
|
||||
|
14
src/Pixeval/Pages/Misc/BrowsingHistoryPage.xaml
Normal file
14
src/Pixeval/Pages/Misc/BrowsingHistoryPage.xaml
Normal file
@ -0,0 +1,14 @@
|
||||
<Page
|
||||
x:Class="Pixeval.Pages.Misc.BrowsingHistoryPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Pixeval.Pages.Misc"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
||||
<Grid>
|
||||
|
||||
</Grid>
|
||||
</Page>
|
31
src/Pixeval/Pages/Misc/BrowsingHistoryPage.xaml.cs
Normal file
31
src/Pixeval/Pages/Misc/BrowsingHistoryPage.xaml.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
|
||||
namespace Pixeval.Pages.Misc
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class BrowsingHistoryPage : Page
|
||||
{
|
||||
public BrowsingHistoryPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
<Page x:Class="Pixeval.Pages.Misc.DownloadAndHistoryListPage"
|
||||
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"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<NavigationView PaneDisplayMode="Top">
|
||||
<NavigationView.MenuItems>
|
||||
<NavigationViewItem x:Uid="/DownloadAndHistoryListPage/DownloadingItemsTab" />
|
||||
<NavigationViewItem x:Uid="/DownloadAndHistoryListPage/DownloadedItemsTab" />
|
||||
<NavigationViewItem x:Uid="/DownloadAndHistoryListPage/BrowsingHistoryTab" />
|
||||
</NavigationView.MenuItems>
|
||||
</NavigationView>
|
||||
</Page>
|
7
src/Pixeval/Pages/Misc/DownloadListPage.xaml
Normal file
7
src/Pixeval/Pages/Misc/DownloadListPage.xaml
Normal file
@ -0,0 +1,7 @@
|
||||
<Page x:Class="Pixeval.Pages.Misc.DownloadListPage"
|
||||
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"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
mc:Ignorable="d" />
|
@ -1,8 +1,8 @@
|
||||
namespace Pixeval.Pages.Misc
|
||||
{
|
||||
public sealed partial class DownloadAndHistoryListPage
|
||||
public sealed partial class DownloadListPage
|
||||
{
|
||||
public DownloadAndHistoryListPage()
|
||||
public DownloadListPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
@ -44,7 +44,6 @@
|
||||
<ItemGroup>
|
||||
<Content Remove="Assets\Images\logo-no-caption.png" />
|
||||
<Content Remove="Strings\zh-CN\BookmarksPage.resw" />
|
||||
<Content Remove="Strings\zh-CN\DownloadAndHistoryListPage.resw" />
|
||||
<Content Remove="Strings\zh-CN\IllustrationGridCommandBar.resw" />
|
||||
<Content Remove="Strings\zh-CN\IllustrationInfoPage.resw" />
|
||||
<Content Remove="Strings\zh-CN\IllustrationViewerPage.resw" />
|
||||
@ -80,12 +79,14 @@
|
||||
<None Remove="Pages\IllustrationViewer\CommentRepliesPage.xaml" />
|
||||
<None Remove="Pages\IllustrationViewer\PixivReplyEmojiListPage.xaml" />
|
||||
<None Remove="Pages\IllustrationViewer\PixivReplyStickerListPage.xaml" />
|
||||
<None Remove="Pages\Misc\BrowsingHistoryPage.xaml" />
|
||||
<None Remove="Popups\IllustrationResultFilterPopup.xaml" />
|
||||
<None Remove="Popups\IllustrationResultFilter\IllustrationResultFilterFunctionEntry.xaml" />
|
||||
<None Remove="Strings\zh-CN\Activations.resw" />
|
||||
<None Remove="Strings\zh-CN\BookmarksPage.resw" />
|
||||
<None Remove="Strings\zh-CN\CommentBlock.resw" />
|
||||
<None Remove="Strings\zh-CN\CommentRepliesBlock.resw" />
|
||||
<None Remove="Strings\zh-CN\DownloadAndHistoryListPage.resw" />
|
||||
<None Remove="Strings\zh-CN\DownloadListPage.resw" />
|
||||
<None Remove="Strings\zh-CN\IllustrationGridCommandBar.resw" />
|
||||
<None Remove="Strings\zh-CN\IllustrationInfoPage.resw" />
|
||||
<None Remove="Strings\zh-CN\IllustrationResultFilterPopupContent.resw" />
|
||||
@ -98,7 +99,6 @@
|
||||
<None Remove="Package.appxmanifest" />
|
||||
<None Remove="Pages\BookMarksPage.xaml" />
|
||||
<None Remove="Pages\Capability\NavigationPage.xaml" />
|
||||
<None Remove="Pages\DownloadAndHistoryListPage.xaml" />
|
||||
<None Remove="Pages\IllustrationGridPage.xaml" />
|
||||
<None Remove="Pages\IllustrationViewerPage.xaml" />
|
||||
<None Remove="Pages\IllustrationViewer\CommentsPage.xaml" />
|
||||
@ -186,7 +186,7 @@
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Pages\Misc\DownloadAndHistoryListPage.xaml">
|
||||
<Page Update="Pages\Misc\DownloadListPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
@ -232,10 +232,11 @@
|
||||
<Folder Include="CommunityToolkit\Markdown\Parsers\Markdown\Helpers\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PRIResource Include="Strings\zh-CN\Activations.resw" />
|
||||
<PRIResource Include="Strings\zh-CN\BookmarksPage.resw" />
|
||||
<PRIResource Include="Strings\zh-CN\CommentBlock.resw" />
|
||||
<PRIResource Include="Strings\zh-CN\CommentRepliesBlock.resw" />
|
||||
<PRIResource Include="Strings\zh-CN\DownloadAndHistoryListPage.resw" />
|
||||
<PRIResource Include="Strings\zh-CN\DownloadListPage.resw" />
|
||||
<PRIResource Include="Strings\zh-CN\IllustrationGridCommandBar.resw" />
|
||||
<PRIResource Include="Strings\zh-CN\IllustrationInfoPage.resw" />
|
||||
<PRIResource Include="Strings\zh-CN\IllustrationResultFilterPopupContent.resw" />
|
||||
@ -280,6 +281,9 @@
|
||||
<None Update="Pages\Capability\SearchResultsPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</None>
|
||||
<Page Update="Pages\Misc\BrowsingHistoryPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="UserControls\TokenInput\TokenInput.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
|
@ -2,7 +2,6 @@
|
||||
"profiles": {
|
||||
"Pixeval": {
|
||||
"commandName": "MsixPackage",
|
||||
"commandLineArgs": "",
|
||||
"alwaysReinstallApp": "false",
|
||||
"remoteDebugEnabled": false,
|
||||
"allowLocalNetworkLoopbackProperty": true,
|
||||
|
@ -117,13 +117,10 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="BrowsingHistoryTab.Content" xml:space="preserve">
|
||||
<value>历史记录</value>
|
||||
<data name="IllustrationActivationFailedContentFormatted" xml:space="preserve">
|
||||
<value>错误详情: {0}</value>
|
||||
</data>
|
||||
<data name="DownloadedItemsTab.Content" xml:space="preserve">
|
||||
<value>已下载</value>
|
||||
</data>
|
||||
<data name="DownloadingItemsTab.Content" xml:space="preserve">
|
||||
<value>下载中</value>
|
||||
<data name="IllustrationActivationFailedTitle" xml:space="preserve">
|
||||
<value>启动失败</value>
|
||||
</data>
|
||||
</root>
|
120
src/Pixeval/Strings/zh-CN/DownloadListPage.resw
Normal file
120
src/Pixeval/Strings/zh-CN/DownloadListPage.resw
Normal file
@ -0,0 +1,120 @@
|
||||
<?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>
|
||||
</root>
|
@ -68,12 +68,12 @@ namespace Pixeval.UserControls
|
||||
e.Handled = true;
|
||||
WeakReferenceMessenger.Default.Send(new MainPageFrameSetConnectedAnimationTargetMessage(sender as UIElement));
|
||||
|
||||
var viewModel = sender.GetDataContext<IllustrationViewModel>()
|
||||
var viewModels = sender.GetDataContext<IllustrationViewModel>()
|
||||
.GetMangaIllustrationViewModels()
|
||||
.ToArray();
|
||||
|
||||
ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("ForwardConnectedAnimation", (UIElement) sender);
|
||||
App.AppViewModel.RootFrameNavigate(typeof(IllustrationViewerPage), new IllustrationViewerPageViewModel(this, viewModel), new SuppressNavigationTransitionInfo());
|
||||
App.AppViewModel.RootFrameNavigate(typeof(IllustrationViewerPage), new IllustrationViewerPageViewModel(this, viewModels), new SuppressNavigationTransitionInfo());
|
||||
}
|
||||
|
||||
private void IllustrationThumbnailContainerItem_OnTapped(object sender, TappedRoutedEventArgs e)
|
||||
|
@ -5,6 +5,7 @@ using Windows.Foundation;
|
||||
using Windows.Graphics;
|
||||
using Microsoft.Toolkit.Mvvm.Messaging;
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
@ -30,6 +31,8 @@ namespace Pixeval.ViewModel
|
||||
App = app;
|
||||
}
|
||||
|
||||
private bool _activatedByProtocol;
|
||||
|
||||
public App App { get; }
|
||||
|
||||
public MainWindow Window = null!;
|
||||
@ -116,21 +119,31 @@ namespace Pixeval.ViewModel
|
||||
};
|
||||
|
||||
#if DEBUG
|
||||
// ReSharper disable once UnusedParameter.Local
|
||||
static Task UncaughtExceptionHandler(Exception e)
|
||||
{
|
||||
Debugger.Break();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
#elif RELEASE
|
||||
static async Task UncaughtExceptionHandler(Exception e)
|
||||
async Task UncaughtExceptionHandler(Exception e)
|
||||
{
|
||||
await MessageDialogBuilder.CreateAcknowledgement(Window, MiscResources.ExceptionEncountered, e.ToString()).ShowAsync();
|
||||
ExitWithPushedNotification();
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public void DispatchTask(DispatcherQueueHandler action)
|
||||
{
|
||||
Window.DispatcherQueue.TryEnqueue(action);
|
||||
}
|
||||
|
||||
public Task DispatchTaskAsync(Func<Task> action)
|
||||
{
|
||||
return Window.DispatcherQueue.EnqueueAsync(action);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Exit the notification after pushing an <see cref="ApplicationExitingMessage"/>
|
||||
@ -143,12 +156,13 @@ namespace Pixeval.ViewModel
|
||||
Application.Current.Exit();
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
public async Task InitializeAsync(bool activatedByProtocol)
|
||||
{
|
||||
_activatedByProtocol = activatedByProtocol;
|
||||
RegisterUnhandledExceptionHandler();
|
||||
await AppContext.WriteLogoIcoIfNotExist();
|
||||
Window = new MainWindow();
|
||||
|
||||
Window = new MainWindow();
|
||||
AppWindow = AppWindow.GetFromWindowId(Win32Interop.GetWindowIdFromWindow(GetMainWindowHandle()));
|
||||
AppWindow.Title = AppContext.AppIdentifier;
|
||||
AppWindow.Resize(new SizeInt32(AppSetting.WindowWidth, AppSetting.WindowHeight));
|
||||
@ -188,5 +202,26 @@ namespace Pixeval.ViewModel
|
||||
{
|
||||
AppContext.SaveContext();
|
||||
}
|
||||
|
||||
public void PrepareForActivation()
|
||||
{
|
||||
Window.ShowActivationProgressRing();
|
||||
}
|
||||
|
||||
public void ActivationProcessed()
|
||||
{
|
||||
Window.HideActivationProgressRing();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and resets the <see cref="_activatedByProtocol"/> field, used for one-time activation process
|
||||
/// during the app start
|
||||
/// </summary>
|
||||
public bool ConsumeProtocolActivation()
|
||||
{
|
||||
var original = _activatedByProtocol;
|
||||
_activatedByProtocol = false;
|
||||
return original;
|
||||
}
|
||||
}
|
||||
}
|
@ -25,12 +25,23 @@ namespace Pixeval.ViewModel
|
||||
/// <summary>
|
||||
/// The view model of the GridView that the <see cref="ImageViewerPageViewModels"/> comes from
|
||||
/// </summary>
|
||||
public IllustrationGridViewModel ContainerGridViewModel { get; }
|
||||
public IllustrationGridViewModel? ContainerGridViewModel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IllustrationGrid"/> that owns <see cref="ContainerGridViewModel"/>
|
||||
/// </summary>
|
||||
public IllustrationGrid IllustrationGrid { get; }
|
||||
public IllustrationGrid? IllustrationGrid { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IllustrationViewModelInTheGridView"/> in <see cref="IllustrationGrid"/> that corresponds to current
|
||||
/// <see cref="IllustrationViewerPageViewModel"/>
|
||||
/// </summary>
|
||||
public IllustrationViewModel? IllustrationViewModelInTheGridView { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The index of current illustration in <see cref="IllustrationGrid"/>
|
||||
/// </summary>
|
||||
public int? IllustrationIndex => ContainerGridViewModel?.IllustrationsView.IndexOf(IllustrationViewModelInTheGridView);
|
||||
|
||||
private ImageSource? _qrCodeSource;
|
||||
|
||||
@ -158,6 +169,14 @@ namespace Pixeval.ViewModel
|
||||
_ = LoadUserProfileImage();
|
||||
}
|
||||
|
||||
public IllustrationViewerPageViewModel(params IllustrationViewModel[] illustrations)
|
||||
{
|
||||
ImageViewerPageViewModels = illustrations.Select(i => new ImageViewerPageViewModel(this, i)).ToArray();
|
||||
Current = ImageViewerPageViewModels[CurrentIndex];
|
||||
InitializeCommands();
|
||||
_ = LoadUserProfileImage();
|
||||
}
|
||||
|
||||
public void UpdateCommandCanExecute()
|
||||
{
|
||||
PlayGifCommand.NotifyCanExecuteChanged();
|
||||
@ -379,17 +398,6 @@ namespace Pixeval.ViewModel
|
||||
|
||||
private ImageSource? _userProfileImageSource;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IllustrationViewModelInTheGridView"/> in <see cref="IllustrationGrid"/> that corresponds to current
|
||||
/// <see cref="IllustrationViewerPageViewModel"/>
|
||||
/// </summary>
|
||||
public IllustrationViewModel IllustrationViewModelInTheGridView { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The index of current illustration in <see cref="IllustrationGrid"/>
|
||||
/// </summary>
|
||||
public int IllustrationIndex => ContainerGridViewModel.IllustrationsView.IndexOf(IllustrationViewModelInTheGridView);
|
||||
|
||||
// Remarks:
|
||||
// The reason why we don't put UserProfileImageSource into IllustrationViewModel
|
||||
// is because the whole array of Illustrations is just representing the same
|
||||
@ -450,13 +458,21 @@ namespace Pixeval.ViewModel
|
||||
{
|
||||
// changes the IsBookmarked property of the item that of in the thumbnail list
|
||||
// so the thumbnail item will also receives state update
|
||||
IllustrationViewModelInTheGridView.IsBookmarked = true;
|
||||
if (IllustrationViewModelInTheGridView is not null)
|
||||
{
|
||||
IllustrationViewModelInTheGridView.IsBookmarked = true;
|
||||
}
|
||||
|
||||
return FirstIllustrationViewModel.PostPublicBookmarkAsync();
|
||||
}
|
||||
|
||||
public Task RemoveBookmarkAsync()
|
||||
{
|
||||
IllustrationViewModelInTheGridView.IsBookmarked = false;
|
||||
if (IllustrationViewModelInTheGridView is not null)
|
||||
{
|
||||
IllustrationViewModelInTheGridView.IsBookmarked = false;
|
||||
}
|
||||
|
||||
return FirstIllustrationViewModel.RemoveBookmarkAsync();
|
||||
}
|
||||
|
||||
@ -482,16 +498,28 @@ namespace Pixeval.ViewModel
|
||||
#region Helper Functions
|
||||
public Visibility CalculateNextImageButtonVisibility(int index)
|
||||
{
|
||||
if (IllustrationGrid is null)
|
||||
{
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
return index < ImageViewerPageViewModels.Length - 1 ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public Visibility CalculatePrevImageButtonVisibility(int index)
|
||||
{
|
||||
if (IllustrationGrid is null)
|
||||
{
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
return index > 0 ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public Visibility CalculateNextIllustrationButtonVisibility(int index)
|
||||
{
|
||||
if (ContainerGridViewModel is null)
|
||||
{
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
return ContainerGridViewModel.IllustrationsView.Count > IllustrationIndex + 1
|
||||
? CalculateNextImageButtonVisibility(index).Inverse()
|
||||
: Visibility.Collapsed;
|
||||
@ -499,6 +527,10 @@ namespace Pixeval.ViewModel
|
||||
|
||||
public Visibility CalculatePrevIllustrationButtonVisibility(int index)
|
||||
{
|
||||
if (ContainerGridViewModel is null)
|
||||
{
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
return IllustrationIndex > 0
|
||||
? CalculatePrevImageButtonVisibility(index).Inverse()
|
||||
: Visibility.Collapsed;
|
||||
|
Loading…
Reference in New Issue
Block a user