mirror of
https://github.com/Pixeval/Pixeval.git
synced 2025-01-07 03:06:53 +08:00
parent
48c6c40b30
commit
e10ef1a357
@ -16,14 +16,14 @@
|
||||
HorizontalAlignment="Left"
|
||||
controls:DockPanel.Dock="Top"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{StaticResource TextSecondaryAccentColor}"
|
||||
Foreground="{StaticResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource BaseTextBlockStyle}"
|
||||
Text="{x:Bind Title, Mode=OneWay}" />
|
||||
<fluent:SymbolIcon
|
||||
VerticalAlignment="Center"
|
||||
controls:DockPanel.Dock="Left"
|
||||
FontSize="{StaticResource SmallIconFontSize}"
|
||||
Foreground="{StaticResource TextSecondaryAccentColor}"
|
||||
Foreground="{StaticResource TextFillColorSecondaryBrush}"
|
||||
Symbol="{x:Bind Symbol, Mode=OneWay}" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
|
@ -53,6 +53,8 @@ public static class C
|
||||
|
||||
public static bool IsNotZeroL(long value) => value is not 0;
|
||||
|
||||
public static Visibility IsNotZeroToVisibility(int value) => value is not 0 ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
public static Visibility IsNotZeroDToVisibility(double value) => value is not 0 ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
public static unsafe Color ToAlphaColor(uint color)
|
||||
|
19
src/Pixeval.Controls/DigitalSignalItem.xaml
Normal file
19
src/Pixeval.Controls/DigitalSignalItem.xaml
Normal file
@ -0,0 +1,19 @@
|
||||
<controls:DockPanel
|
||||
x:Class="Pixeval.Controls.DigitalSignalItem"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Pixeval.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
HorizontalSpacing="5"
|
||||
mc:Ignorable="d">
|
||||
<Ellipse
|
||||
Width="7"
|
||||
Height="7"
|
||||
Fill="{x:Bind Fill, Mode=OneWay}" />
|
||||
<TextBlock
|
||||
Foreground="{StaticResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind Text, Mode=OneWay}" />
|
||||
</controls:DockPanel>
|
11
src/Pixeval.Controls/DigitalSignalItem.xaml.cs
Normal file
11
src/Pixeval.Controls/DigitalSignalItem.xaml.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using WinUI3Utilities.Attributes;
|
||||
|
||||
namespace Pixeval.Controls;
|
||||
|
||||
[DependencyProperty<string>("Text")]
|
||||
[DependencyProperty<Brush>("Fill")]
|
||||
public sealed partial class DigitalSignalItem
|
||||
{
|
||||
public DigitalSignalItem() => InitializeComponent();
|
||||
}
|
@ -30,7 +30,7 @@
|
||||
Text="{x:Bind PersonNickname, Mode=OneWay}" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
Foreground="{ThemeResource PixevalTipTextForeground}"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind PersonName, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
|
@ -16,14 +16,14 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.Shimmer" Version="0.1.240517-build.1678" />
|
||||
<PackageReference Include="FluentIcons.WinUI" Version="1.1.244" />
|
||||
<PackageReference Include="FluentIcons.WinUI" Version="1.1.247" />
|
||||
<PackageReference Include="Microsoft.Graphics.Win2D" Version="1.2.0" />
|
||||
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.106">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.3233" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240607001" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240627000" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Triggers" Version="8.1.240606-rc" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Collections" Version="8.1.240606-rc" />
|
||||
@ -49,4 +49,16 @@
|
||||
<ItemGroup>
|
||||
<PRIResource Include="Strings\*\*.resjson" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<CustomAdditionalCompileInputs Remove="DigitalSignalItem.xaml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="DigitalSignalItem.xaml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Resource Remove="DigitalSignalItem.xaml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -12,7 +12,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||
<PackageReference Include="WebApiClientCore" Version="2.1.2" PrivateAssets="True" />
|
||||
<PackageReference Include="WebApiClientCore" Version="2.1.4" PrivateAssets="True" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -88,7 +88,7 @@ public partial record AppSettings() : IWindowSettings
|
||||
/// The max download tasks that are allowed to run concurrently
|
||||
/// </summary>
|
||||
[SettingsEntry(Symbol.DeveloperBoardLightning, nameof(MaxDownloadConcurrencyLevelEntryHeader), nameof(MaxDownloadConcurrencyLevelEntryDescription))]
|
||||
public int MaxDownloadTaskConcurrencyLevel { get; set; } = Environment.ProcessorCount / 2;
|
||||
public int MaxDownloadTaskConcurrencyLevel { get; set; } = Environment.ProcessorCount / 4;
|
||||
|
||||
[SettingsEntry(Symbol.SaveEdit, nameof(DownloadWhenBookmarkedEntryHeader), nameof(DownloadWhenBookmarkedEntryDescription))]
|
||||
public bool DownloadWhenBookmarked { get; set; }
|
||||
|
@ -69,7 +69,7 @@
|
||||
<!-- TipTextColor -->
|
||||
<TextBlock
|
||||
controls:DockPanel.Dock="Bottom"
|
||||
Foreground="{ThemeResource PixevalTipTextForeground}"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind local:C.CultureDateTimeOffsetDateFormatter(ViewModel.PostDate, pixeval:AppSettings.CurrentCulture), Mode=OneWay}" />
|
||||
</controls:DockPanel>
|
||||
|
@ -50,8 +50,25 @@
|
||||
ShowError="{x:Bind ViewModel.IsError(ViewModel.DownloadTask.CurrentState), Mode=OneWay}"
|
||||
ShowPaused="{x:Bind ViewModel.IsPaused(ViewModel.DownloadTask.CurrentState), Mode=OneWay}"
|
||||
Value="{x:Bind ViewModel.DownloadTask.ProgressPercentage, Mode=OneWay}" />
|
||||
<StackPanel
|
||||
Orientation="Horizontal"
|
||||
Spacing="5"
|
||||
Visibility="{x:Bind ViewModel.IsGroup(ViewModel.DownloadTask), Mode=OneWay}">
|
||||
<local:DigitalSignalItem
|
||||
Fill="{x:Bind ViewModel.CurrentStateBrush(ViewModel.DownloadTask.CurrentState), Mode=OneWay}"
|
||||
Text="{x:Bind ViewModel.DownloadTask.ActiveCount, Mode=OneWay}"
|
||||
Visibility="{x:Bind local:C.IsNotZeroToVisibility(ViewModel.DownloadTask.ActiveCount), Mode=OneWay}" />
|
||||
<local:DigitalSignalItem
|
||||
Fill="{StaticResource SystemFillColorSuccessBrush}"
|
||||
Text="{x:Bind ViewModel.DownloadTask.CompletedCount, Mode=OneWay}"
|
||||
Visibility="{x:Bind local:C.IsNotZeroToVisibility(ViewModel.DownloadTask.CompletedCount), Mode=OneWay}" />
|
||||
<local:DigitalSignalItem
|
||||
Fill="{StaticResource SystemFillColorCriticalBrush}"
|
||||
Text="{x:Bind ViewModel.DownloadTask.ErrorCount, Mode=OneWay}"
|
||||
Visibility="{x:Bind local:C.IsNotZeroToVisibility(ViewModel.DownloadTask.ErrorCount), Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource PixevalTipTextForeground}"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind ViewModel.ProgressMessage(ViewModel.DownloadTask.CurrentState, ViewModel.DownloadTask.ProgressPercentage, ViewModel.DownloadTask), Mode=OneWay}"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
|
@ -23,10 +23,12 @@ using System.IO;
|
||||
using Windows.Foundation;
|
||||
using Windows.System;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Pixeval.Download;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Documents;
|
||||
using Pixeval.Util.UI;
|
||||
using WinUI3Utilities;
|
||||
using WinUI3Utilities.Attributes;
|
||||
using Symbol = FluentIcons.Common.Symbol;
|
||||
|
||||
namespace Pixeval.Controls;
|
||||
|
||||
@ -47,24 +49,22 @@ public sealed partial class DownloadItem
|
||||
|
||||
private async void ActionButton_OnClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
switch (ViewModel.DownloadTask.CurrentState)
|
||||
switch (ViewModel.ActionButtonSymbol(ViewModel.DownloadTask.CurrentState))
|
||||
{
|
||||
case DownloadState.Queued:
|
||||
case DownloadState.Pending:
|
||||
case Symbol.Dismiss:
|
||||
ViewModel.DownloadTask.Cancel();
|
||||
break;
|
||||
case DownloadState.Running:
|
||||
case Symbol.Pause:
|
||||
ViewModel.DownloadTask.Pause();
|
||||
break;
|
||||
case DownloadState.Error:
|
||||
case DownloadState.Cancelled:
|
||||
case Symbol.ArrowRepeatAll:
|
||||
ViewModel.DownloadTask.TryReset();
|
||||
break;
|
||||
case DownloadState.Completed:
|
||||
case Symbol.Open:
|
||||
if (!await Launcher.LaunchUriAsync(new Uri(ViewModel.DownloadTask.OpenLocalDestination)))
|
||||
_ = await this.CreateAcknowledgementAsync(MiscResources.DownloadItemOpenFailed, MiscResources.DownloadItemMaybeDeleted);
|
||||
break;
|
||||
case DownloadState.Paused:
|
||||
case Symbol.Play:
|
||||
ViewModel.DownloadTask.TryResume();
|
||||
break;
|
||||
default:
|
||||
|
@ -23,6 +23,8 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentIcons.Common;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Pixeval.Database;
|
||||
using Pixeval.Download;
|
||||
using Pixeval.Download.Models;
|
||||
@ -87,20 +89,20 @@ public sealed partial class DownloadItemViewModel(IDownloadTaskGroup downloadTas
|
||||
_ => ThrowHelper.ArgumentOutOfRange<DownloadState, string>(state)
|
||||
};
|
||||
|
||||
public string ActionButtonContent(DownloadState state) => state switch
|
||||
public string ActionButtonContent(DownloadState state) => ActionButtonSymbol(state) switch
|
||||
{
|
||||
DownloadState.Queued or DownloadState.Pending => DownloadItemResources.ActionDownloadCancelled,
|
||||
DownloadState.Running => DownloadItemResources.ActionButtonContentPause,
|
||||
DownloadState.Cancelled or DownloadState.Error => DownloadItemResources.ActionButtonContentRetry,
|
||||
DownloadState.Completed => DownloadItemResources.ActionButtonContentOpen,
|
||||
DownloadState.Paused => DownloadItemResources.ActionButtonContentResume,
|
||||
Symbol.Dismiss => DownloadItemResources.ActionDownloadCancelled,
|
||||
Symbol.Pause => DownloadItemResources.ActionButtonContentPause,
|
||||
Symbol.ArrowRepeatAll => DownloadItemResources.ActionButtonContentRetry,
|
||||
Symbol.Open => DownloadItemResources.ActionButtonContentOpen,
|
||||
Symbol.Play => DownloadItemResources.ActionButtonContentResume,
|
||||
_ => ThrowHelper.ArgumentOutOfRange<DownloadState, string>(state)
|
||||
};
|
||||
|
||||
public Symbol ActionButtonSymbol(DownloadState state) => state switch
|
||||
{
|
||||
DownloadState.Queued or DownloadState.Pending => Symbol.Dismiss,
|
||||
DownloadState.Running => Symbol.Pause,
|
||||
DownloadState.Pending => Symbol.Dismiss,
|
||||
DownloadState.Queued or DownloadState.Running => Symbol.Pause,
|
||||
DownloadState.Cancelled or DownloadState.Error => Symbol.ArrowRepeatAll,
|
||||
DownloadState.Completed => Symbol.Open,
|
||||
DownloadState.Paused => Symbol.Play,
|
||||
@ -119,6 +121,15 @@ public sealed partial class DownloadItemViewModel(IDownloadTaskGroup downloadTas
|
||||
|
||||
public bool IsPaused(DownloadState state) => state is DownloadState.Paused;
|
||||
|
||||
public Visibility IsGroup(IDownloadTaskGroup group) => C.ToVisibility(group is DownloadTaskGroup);
|
||||
|
||||
public Brush CurrentStateBrush(DownloadState state) => Application.Current.GetResource<Brush>(state switch
|
||||
{
|
||||
DownloadState.Paused => "SystemFillColorCautionBrush",
|
||||
DownloadState.Cancelled => "SystemFillColorNeutralBrush",
|
||||
_ => "SystemFillColorAttentionBrush"
|
||||
});
|
||||
|
||||
#pragma warning restore CA1822
|
||||
|
||||
#region Not supported
|
||||
|
@ -45,10 +45,10 @@
|
||||
VerticalAlignment="Center"
|
||||
Content="{fluent:SymbolIcon Symbol=Guest,
|
||||
FontSize=12}"
|
||||
Foreground="{StaticResource TextSecondaryAccentColor}" />
|
||||
Foreground="{StaticResource TextFillColorSecondaryBrush}" />
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{StaticResource TextSecondaryAccentColor}"
|
||||
Foreground="{StaticResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionStrongTextBlockStyle}"
|
||||
Text="{x:Bind ViewModel.UserId, Mode=OneWay}" />
|
||||
<local:PixevalBadge
|
||||
|
@ -24,5 +24,5 @@
|
||||
<controls:ColorPickerButton
|
||||
ColorPickerStyle="{StaticResource ColorPickerStyle}"
|
||||
Loaded="ColorPicker_OnLoaded"
|
||||
SelectedColor="{x:Bind controls1:C.ToAlphaColor(Entry.Value), BindBack=controls1:C.ToAlphaUInt, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind controls1:C.ToAlphaColor(Entry.Value), BindBack=ColorBindBack, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
@ -1,3 +1,4 @@
|
||||
using Windows.UI;
|
||||
using CommunityToolkit.WinUI.Controls;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
@ -22,4 +23,6 @@ public sealed partial class ColorSettingsCard
|
||||
{
|
||||
Entry.ValueChanged?.Invoke(Entry.Value);
|
||||
}
|
||||
|
||||
private void ColorBindBack(Color color) => Entry.Value = C.ToAlphaUInt(color);
|
||||
}
|
||||
|
@ -28,16 +28,15 @@ using System.Threading.Tasks;
|
||||
using Pixeval.CoreApi.Net;
|
||||
using Pixeval.Download.Models;
|
||||
using Pixeval.Utilities.Threading;
|
||||
using WinUI3Utilities;
|
||||
|
||||
namespace Pixeval.Download;
|
||||
|
||||
public partial class DownloadManager : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 正在下载的任务队列,数量不超过<see cref="ConcurrencyDegree"/>
|
||||
/// 正在排队的任务队列
|
||||
/// </summary>
|
||||
private readonly Channel<IDownloadTaskBase> _downloadTaskChannel = Channel.CreateUnbounded<IDownloadTaskBase>();
|
||||
private readonly Channel<DownloadToken> _downloadTaskChannel = Channel.CreateUnbounded<DownloadToken>();
|
||||
|
||||
/// <summary>
|
||||
/// 使用<see cref="MakoApiKind.ImageApi"/>的<see cref="HttpClient"/>
|
||||
@ -53,7 +52,7 @@ public partial class DownloadManager : IDisposable
|
||||
private readonly ReenterableAwaiter<bool> _throttle = new(true, true);
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="_downloadTaskChannel"/>中的数量
|
||||
/// 正在下载中的数量
|
||||
/// </summary>
|
||||
private int _workingTasks;
|
||||
|
||||
@ -93,16 +92,17 @@ public partial class DownloadManager : IDisposable
|
||||
/// <remarks>
|
||||
/// intrinsic download task are not counted
|
||||
/// </remarks>
|
||||
public void QueueTask(IDownloadTaskGroup task)
|
||||
public void QueueTask(IDownloadTaskGroup taskGroup)
|
||||
{
|
||||
if (_taskQuerySet.TryGetValue(task.Destination, out var v) && v == task)
|
||||
if (_taskQuerySet.TryGetValue(taskGroup.Destination, out var v) && v == taskGroup)
|
||||
return;
|
||||
_taskQuerySet[task.Destination] = task;
|
||||
_taskQuerySet[taskGroup.Destination] = taskGroup;
|
||||
|
||||
if (v is not null)
|
||||
_ = QueuedTasks.Remove(v);
|
||||
QueuedTasks.Insert(0, task);
|
||||
_ = _downloadTaskChannel.Writer.TryWrite(task);
|
||||
QueuedTasks.Insert(0, taskGroup);
|
||||
taskGroup.SubscribeProgress(_downloadTaskChannel.Writer);
|
||||
_ = _downloadTaskChannel.Writer.TryWrite(taskGroup.GetToken());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -111,40 +111,30 @@ public partial class DownloadManager : IDisposable
|
||||
private async void PollTask()
|
||||
{
|
||||
while (await _downloadTaskChannel.Reader.WaitToReadAsync())
|
||||
while (await _throttle && _downloadTaskChannel.Reader.TryRead(out var queuedTask))
|
||||
switch (queuedTask)
|
||||
{
|
||||
case ImageDownloadTask imageTask:
|
||||
imageTask.DownloadTryResume += t => _downloadTaskChannel.Writer.TryWrite(t);
|
||||
imageTask.DownloadTryReset += t => _downloadTaskChannel.Writer.TryWrite(t);
|
||||
// 子任务入列时一定是处于Queued状态,需要直接运行的
|
||||
_ = DownloadAsync(imageTask);
|
||||
break;
|
||||
case IDownloadTaskGroup taskGroup:
|
||||
await taskGroup.InitializeTaskGroupAsync();
|
||||
foreach (var subTask in taskGroup)
|
||||
{
|
||||
subTask.DownloadTryResume += t => _downloadTaskChannel.Writer.TryWrite(t);
|
||||
subTask.DownloadTryReset += t => _downloadTaskChannel.Writer.TryWrite(t);
|
||||
// 任务组中的任务需要判断是否处于Queued状态才能运行
|
||||
if (subTask.CurrentState is DownloadState.Queued)
|
||||
{
|
||||
_ = DownloadAsync(subTask);
|
||||
_ = await _throttle;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
while (await _throttle
|
||||
&& _downloadTaskChannel.Reader.TryRead(out var taskToken)
|
||||
&& taskToken is { Token.IsCancellationRequested: false, Task: var taskGroup })
|
||||
{
|
||||
await taskGroup.InitializeTaskGroupAsync();
|
||||
foreach (var subTask in taskGroup)
|
||||
// 需要判断是否处于Queued状态才能运行
|
||||
if (subTask.CurrentState is DownloadState.Queued)
|
||||
{
|
||||
await DownloadAsync(subTask);
|
||||
_ = await _throttle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除指定任务
|
||||
/// </summary>
|
||||
/// <param name="task"></param>
|
||||
public void RemoveTask(IDownloadTaskGroup task)
|
||||
/// <param name="taskGroup"></param>
|
||||
public void RemoveTask(IDownloadTaskGroup taskGroup)
|
||||
{
|
||||
_ = _taskQuerySet.Remove(task.Destination);
|
||||
_ = QueuedTasks.Remove(task);
|
||||
taskGroup.Cancel();
|
||||
_ = _taskQuerySet.Remove(taskGroup.Destination);
|
||||
_ = QueuedTasks.Remove(taskGroup);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -152,9 +142,8 @@ public partial class DownloadManager : IDisposable
|
||||
/// </summary>
|
||||
public void ClearTasks()
|
||||
{
|
||||
// foreach (var task in QueuedTasks)
|
||||
// await task.CancelAsync();
|
||||
|
||||
foreach (var task in QueuedTasks)
|
||||
task.Cancel();
|
||||
QueuedTasks.Clear();
|
||||
_taskQuerySet.Clear();
|
||||
}
|
||||
@ -165,11 +154,12 @@ public partial class DownloadManager : IDisposable
|
||||
/// <remarks>
|
||||
/// Execute the task only if it's already queued
|
||||
/// </remarks>
|
||||
public bool TryExecuteTaskGroupInline(IDownloadTaskGroup task)
|
||||
public bool TryExecuteTaskGroupInline(IDownloadTaskGroup taskGroup)
|
||||
{
|
||||
if (QueuedTasks.Contains(task) && task.CurrentState is DownloadState.Queued)
|
||||
if (QueuedTasks.Contains(taskGroup) && taskGroup.CurrentState is DownloadState.Queued)
|
||||
{
|
||||
_ = _downloadTaskChannel.Writer.TryWrite(task);
|
||||
taskGroup.SubscribeProgress(_downloadTaskChannel.Writer);
|
||||
_ = _downloadTaskChannel.Writer.TryWrite(taskGroup.GetToken());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -179,8 +169,21 @@ public partial class DownloadManager : IDisposable
|
||||
private async Task DownloadAsync(ImageDownloadTask task)
|
||||
{
|
||||
await IncrementCounterAsync();
|
||||
await DownloadInternalAsync(task);
|
||||
await DecrementCounterAsync();
|
||||
_ = Download();
|
||||
|
||||
return;
|
||||
async Task Download()
|
||||
{
|
||||
try
|
||||
{
|
||||
await task.StartAsync(_httpClient);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
await DecrementCounterAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task IncrementCounterAsync()
|
||||
@ -194,21 +197,4 @@ public partial class DownloadManager : IDisposable
|
||||
_ = Interlocked.Decrement(ref _workingTasks);
|
||||
await _throttle.SetResultAsync(true);
|
||||
}
|
||||
|
||||
private async Task DownloadInternalAsync(ImageDownloadTask task)
|
||||
{
|
||||
try
|
||||
{
|
||||
await (task.CurrentState switch
|
||||
{
|
||||
DownloadState.Queued => task.StartAsync(_httpClient),
|
||||
DownloadState.Paused => task.ResumeAsync(_httpClient),
|
||||
_ => ThrowHelper.ArgumentOutOfRange<DownloadState, Task>(task.CurrentState)
|
||||
});
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@ -32,7 +33,6 @@ using Pixeval.Controls.Windowing;
|
||||
using Pixeval.CoreApi.Model;
|
||||
using Pixeval.Database;
|
||||
using Pixeval.Database.Managers;
|
||||
using Pixeval.Util.UI;
|
||||
using Pixeval.Utilities;
|
||||
using WinUI3Utilities;
|
||||
|
||||
@ -58,6 +58,10 @@ public abstract partial class DownloadTaskGroup(DownloadHistoryEntry entry) : Ob
|
||||
var g = sender.To<DownloadTaskGroup>();
|
||||
if (e.PropertyName is not nameof(CurrentState))
|
||||
return;
|
||||
// 子任务状态变化时,不一定需要任务组状态变化,也会进入此分支
|
||||
OnPropertyChanged(nameof(ActiveCount));
|
||||
OnPropertyChanged(nameof(CompletedCount));
|
||||
OnPropertyChanged(nameof(ErrorCount));
|
||||
if (g.CurrentState is DownloadState.Running or DownloadState.Paused or DownloadState.Pending)
|
||||
return;
|
||||
g.DatabaseEntry.State = g.CurrentState;
|
||||
@ -108,18 +112,23 @@ public abstract partial class DownloadTaskGroup(DownloadHistoryEntry entry) : Ob
|
||||
if (CurrentState is not (DownloadState.Completed or DownloadState.Error or DownloadState.Cancelled))
|
||||
return;
|
||||
IsProcessing = true;
|
||||
TasksSet.ForEach(t => t.TryReset());
|
||||
(CurrentState is DownloadState.Error
|
||||
? TasksSet.Where(t => t.CurrentState is DownloadState.Error)
|
||||
: TasksSet)
|
||||
.ForEach(t => t.TryReset());
|
||||
if (CancellationTokenSource.IsCancellationRequested)
|
||||
{
|
||||
CancellationTokenSource.Dispose();
|
||||
CancellationTokenSource = new();
|
||||
}
|
||||
DownloadTryReset?.Invoke(this);
|
||||
IsProcessing = false;
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
{
|
||||
IsProcessing = true;
|
||||
CancellationTokenSource.Cancel();
|
||||
TasksSet.ForEach(t => t.Pause());
|
||||
IsProcessing = false;
|
||||
}
|
||||
@ -127,7 +136,13 @@ public abstract partial class DownloadTaskGroup(DownloadHistoryEntry entry) : Ob
|
||||
public void TryResume()
|
||||
{
|
||||
IsProcessing = true;
|
||||
if (CancellationTokenSource.IsCancellationRequested)
|
||||
{
|
||||
CancellationTokenSource.Dispose();
|
||||
CancellationTokenSource = new();
|
||||
}
|
||||
TasksSet.ForEach(t => t.TryResume());
|
||||
DownloadTryResume?.Invoke(this);
|
||||
IsProcessing = false;
|
||||
}
|
||||
|
||||
@ -146,9 +161,8 @@ public abstract partial class DownloadTaskGroup(DownloadHistoryEntry entry) : Ob
|
||||
|
||||
public abstract void Delete();
|
||||
|
||||
/// <summary>
|
||||
/// 用于<see cref="DownloadState.Pending"/>的取消令牌
|
||||
/// </summary>
|
||||
public DownloadToken GetToken() => new(this, CancellationTokenSource.Token);
|
||||
|
||||
private CancellationTokenSource CancellationTokenSource { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
@ -219,6 +233,10 @@ public abstract partial class DownloadTaskGroup(DownloadHistoryEntry entry) : Ob
|
||||
|
||||
public event Func<DownloadTaskGroup, CancellationToken, Task>? AfterAllDownloadAsync;
|
||||
|
||||
private event Action<DownloadTaskGroup>? DownloadTryResume;
|
||||
|
||||
private event Action<DownloadTaskGroup>? DownloadTryReset;
|
||||
|
||||
protected void AddToTasksSet(ImageDownloadTask task)
|
||||
{
|
||||
_tasksSet.Add(task);
|
||||
@ -228,31 +246,24 @@ public abstract partial class DownloadTaskGroup(DownloadHistoryEntry entry) : Ob
|
||||
task.DownloadErrorAsync += x => ItemDownloadErrorAsync?.Invoke(x) ?? Task.CompletedTask;
|
||||
task.PropertyChanged += (_, e) =>
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
OnPropertyChanged(e.PropertyName switch
|
||||
{
|
||||
case nameof(ImageDownloadTask.ProgressPercentage):
|
||||
{
|
||||
var time = DateTime.Now;
|
||||
if (time - _lastReportedTime < TimeSpan.FromMilliseconds(500))
|
||||
return;
|
||||
_lastReportedTime = time;
|
||||
OnPropertyChanged(nameof(ProgressPercentage));
|
||||
break;
|
||||
}
|
||||
case nameof(ImageDownloadTask.CurrentState):
|
||||
OnPropertyChanged(nameof(CurrentState));
|
||||
break;
|
||||
case nameof(ImageDownloadTask.ErrorCause):
|
||||
OnPropertyChanged(nameof(ErrorCause));
|
||||
break;
|
||||
}
|
||||
nameof(ImageDownloadTask.ProgressPercentage) => nameof(ProgressPercentage),
|
||||
nameof(ImageDownloadTask.CurrentState) => nameof(CurrentState),
|
||||
nameof(ImageDownloadTask.ErrorCause) => nameof(ErrorCause),
|
||||
_ => ""
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 降低汇报频率
|
||||
/// </summary>
|
||||
private DateTime _lastReportedTime = DateTime.MinValue;
|
||||
public void SubscribeProgress(ChannelWriter<DownloadToken> writer)
|
||||
{
|
||||
DownloadTryResume += OnDownloadWrite;
|
||||
DownloadTryReset += OnDownloadWrite;
|
||||
|
||||
return;
|
||||
void OnDownloadWrite(DownloadTaskGroup o) => writer.TryWrite(o.GetToken());
|
||||
}
|
||||
|
||||
public Exception? ErrorCause => TasksSet.FirstOrDefault(t => t.ErrorCause is not null)?.ErrorCause;
|
||||
|
||||
@ -260,7 +271,20 @@ public abstract partial class DownloadTaskGroup(DownloadHistoryEntry entry) : Ob
|
||||
|
||||
public bool IsAnyError => TasksSet.Any(t => t.CurrentState is DownloadState.Error);
|
||||
|
||||
public double ProgressPercentage => TasksSet.Count is 0 ? 100 : TasksSet.Average(t => t.ProgressPercentage);
|
||||
public int ActiveCount => TasksSet.Count(t => t.CurrentState is DownloadState.Queued or DownloadState.Running or DownloadState.Pending or DownloadState.Paused or DownloadState.Cancelled);
|
||||
|
||||
public int CompletedCount => TasksSet.Count(t => t.CurrentState is DownloadState.Completed);
|
||||
|
||||
public int ErrorCount => TasksSet.Count(t => t.CurrentState is DownloadState.Error);
|
||||
|
||||
public double ProgressPercentage =>
|
||||
IsCreateFromEntry
|
||||
? DatabaseEntry.State is DownloadState.Queued
|
||||
? 0
|
||||
: 100
|
||||
: TasksSet.Count is 0
|
||||
? 100
|
||||
: TasksSet.Average(t => t.ProgressPercentage);
|
||||
|
||||
public IEnumerator<ImageDownloadTask> GetEnumerator() => TasksSet.GetEnumerator();
|
||||
|
||||
|
@ -23,6 +23,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
using Pixeval.CoreApi.Model;
|
||||
using Pixeval.Database;
|
||||
@ -34,4 +36,16 @@ public interface IDownloadTaskGroup : IDownloadTaskBase, IIdEntry, INotifyProper
|
||||
DownloadHistoryEntry DatabaseEntry { get; }
|
||||
|
||||
ValueTask InitializeTaskGroupAsync();
|
||||
|
||||
void SubscribeProgress(ChannelWriter<DownloadToken> writer);
|
||||
|
||||
DownloadToken GetToken();
|
||||
|
||||
int ActiveCount { get; }
|
||||
|
||||
int CompletedCount { get; }
|
||||
|
||||
int ErrorCount { get; }
|
||||
}
|
||||
|
||||
public readonly record struct DownloadToken(IDownloadTaskGroup Task, CancellationToken Token);
|
||||
|
@ -39,6 +39,8 @@ public partial class ImageDownloadTask : ObservableObject, IDownloadTaskBase, IP
|
||||
Uri = uri;
|
||||
Destination = destination;
|
||||
CurrentState = initState;
|
||||
if (initState is DownloadState.Completed or DownloadState.Cancelled or DownloadState.Error)
|
||||
ProgressPercentage = 100;
|
||||
DownloadStartedAsync += DownloadStartedAsyncOverride;
|
||||
DownloadStoppedAsync += DownloadStoppedAsyncOverride;
|
||||
DownloadErrorAsync += DownloadErrorAsyncOverride;
|
||||
@ -66,13 +68,13 @@ public partial class ImageDownloadTask : ObservableObject, IDownloadTaskBase, IP
|
||||
|
||||
[ObservableProperty] private DownloadState _currentState;
|
||||
|
||||
[ObservableProperty] private double _progressPercentage = 100;
|
||||
[ObservableProperty] private double _progressPercentage;
|
||||
|
||||
[ObservableProperty] private Exception? _errorCause;
|
||||
|
||||
[ObservableProperty] private bool _isProcessing;
|
||||
|
||||
private CancellationTokenSource CancellationTokenSource { get; set; } = new();
|
||||
protected CancellationTokenSource CancellationTokenSource { get; private set; } = new();
|
||||
|
||||
private bool _isRunning;
|
||||
|
||||
@ -199,11 +201,12 @@ public partial class ImageDownloadTask : ObservableObject, IDownloadTaskBase, IP
|
||||
|
||||
public void Pause()
|
||||
{
|
||||
if (CurrentState is not DownloadState.Running)
|
||||
if (CurrentState is not (DownloadState.Queued or DownloadState.Running))
|
||||
return;
|
||||
IsProcessing = true;
|
||||
CancellationTokenSource.Cancel();
|
||||
CurrentState = DownloadState.Paused;
|
||||
DownloadPaused?.Invoke(this);
|
||||
IsProcessing = false;
|
||||
}
|
||||
|
||||
@ -222,11 +225,6 @@ public partial class ImageDownloadTask : ObservableObject, IDownloadTaskBase, IP
|
||||
IsProcessing = false;
|
||||
}
|
||||
|
||||
public async Task ResumeAsync(HttpClient httpClient)
|
||||
{
|
||||
await StartAsync(httpClient, true);
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
if (CurrentState is not (DownloadState.Paused or DownloadState.Pending or DownloadState.Running or DownloadState.Queued))
|
||||
@ -234,6 +232,7 @@ public partial class ImageDownloadTask : ObservableObject, IDownloadTaskBase, IP
|
||||
IsProcessing = true;
|
||||
CancellationTokenSource.Cancel();
|
||||
CurrentState = DownloadState.Cancelled;
|
||||
DownloadCancelled?.Invoke(this);
|
||||
IsProcessing = false;
|
||||
}
|
||||
|
||||
@ -255,6 +254,10 @@ public partial class ImageDownloadTask : ObservableObject, IDownloadTaskBase, IP
|
||||
|
||||
public event Action<ImageDownloadTask>? DownloadTryReset;
|
||||
|
||||
public event Action<ImageDownloadTask>? DownloadPaused;
|
||||
|
||||
public event Action<ImageDownloadTask>? DownloadCancelled;
|
||||
|
||||
public event Func<ImageDownloadTask, CancellationToken, Task> AfterDownloadAsync;
|
||||
|
||||
void IProgress<double>.Report(double value) => ProgressPercentage = value;
|
||||
|
@ -85,7 +85,15 @@ public class MangaDownloadTaskGroup : DownloadTaskGroup, IImageDownloadTaskGroup
|
||||
|
||||
private IllustrationDownloadFormat IllustrationDownloadFormat { get; }
|
||||
|
||||
public override string OpenLocalDestination => Path.GetDirectoryName(TasksSet[0].Destination)!;
|
||||
public override string OpenLocalDestination
|
||||
{
|
||||
get
|
||||
{
|
||||
if (TasksSet.Count is 0)
|
||||
SetTasksSet();
|
||||
return Path.GetDirectoryName(TasksSet[0].Destination)!;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
|
@ -24,6 +24,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Pixeval.CoreApi.Model;
|
||||
@ -40,7 +41,11 @@ public class SingleImageDownloadTaskGroup : ImageDownloadTask, IImageDownloadTas
|
||||
{
|
||||
public DownloadHistoryEntry DatabaseEntry { get; }
|
||||
|
||||
public ValueTask InitializeTaskGroupAsync() => ValueTask.CompletedTask;
|
||||
public ValueTask InitializeTaskGroupAsync()
|
||||
{
|
||||
SetNotCreateFromEntry();
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
public Illustration Entry => DatabaseEntry.Entry.To<Illustration>();
|
||||
|
||||
@ -60,6 +65,8 @@ public class SingleImageDownloadTaskGroup : ImageDownloadTask, IImageDownloadTas
|
||||
{
|
||||
DatabaseEntry = entry;
|
||||
CurrentState = entry.State;
|
||||
if (entry.State is DownloadState.Completed or DownloadState.Cancelled or DownloadState.Error)
|
||||
ProgressPercentage = 100;
|
||||
IllustrationDownloadFormat = IoHelper.GetIllustrationFormat(Path.GetExtension(Destination));
|
||||
}
|
||||
|
||||
@ -92,6 +99,23 @@ public class SingleImageDownloadTaskGroup : ImageDownloadTask, IImageDownloadTas
|
||||
await TagsManager.SetTagsAsync(Destination, Entry, token);
|
||||
}
|
||||
|
||||
public DownloadToken GetToken() => new(this, CancellationTokenSource.Token);
|
||||
|
||||
public int ActiveCount => CurrentState is DownloadState.Queued or DownloadState.Running or DownloadState.Pending or DownloadState.Paused or DownloadState.Cancelled ? 1 : 0;
|
||||
|
||||
public int CompletedCount => CurrentState is DownloadState.Completed ? 1 : 0;
|
||||
|
||||
public int ErrorCount => CurrentState is DownloadState.Error ? 1 : 0;
|
||||
|
||||
public void SubscribeProgress(ChannelWriter<DownloadToken> writer)
|
||||
{
|
||||
DownloadTryResume += OnDownloadWrite;
|
||||
DownloadTryReset += OnDownloadWrite;
|
||||
|
||||
return;
|
||||
void OnDownloadWrite(ImageDownloadTask o) => writer.TryWrite(o.To<SingleImageDownloadTaskGroup>().GetToken());
|
||||
}
|
||||
|
||||
public int Count => 1;
|
||||
|
||||
public IEnumerator<ImageDownloadTask> GetEnumerator() => ((IReadOnlyList<ImageDownloadTask>)[this]).GetEnumerator();
|
||||
|
@ -30,7 +30,7 @@
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<TextBlock
|
||||
MaxHeight="15"
|
||||
Foreground="{ThemeResource PixevalTipTextForeground}"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind TranslatedName}"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
|
@ -37,25 +37,25 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.1.240606-rc" />
|
||||
<PackageReference Include="CommunityToolkit.Diagnostics" Version="8.2.2" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||
<PackageReference Include="FluentIcons.WinUI" Version="1.1.244" />
|
||||
<PackageReference Include="FluentIcons.WinUI" Version="1.1.247" />
|
||||
<PackageReference Include="GitVersion.MsBuild" Version="5.12.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="LiteDB" Version="5.0.20" />
|
||||
<PackageReference Include="LiteDB" Version="5.0.21" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
|
||||
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.3233" />
|
||||
<PackageReference Condition="'$(PublishAot)' == 'true'" Include="Microsoft.Windows.CsWinRT" Version="2.1.0-prerelease.240602.1" />
|
||||
<PackageReference Condition="'$(PublishAot)' == 'true'" Include="Microsoft.WindowsAppSDK" Version="1.6.240531000-experimental1" />
|
||||
<PackageReference Condition="'$(PublishAot)' == 'false'" Include="Microsoft.WindowsAppSDK" Version="1.5.240607001" />
|
||||
<PackageReference Condition="'$(PublishAot)' == 'false'" Include="Microsoft.WindowsAppSDK" Version="1.5.240627000" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
|
||||
<PackageReference Include="PininSharp" Version="1.2.0" />
|
||||
<!--<PackageReference Include="Pixeval.Bypass" Version="1.1.7" />-->
|
||||
<PackageReference Include="Pixeval.QRCoder" Version="1.4.5" />
|
||||
<PackageReference Include="QuestPDF" Version="2024.6.2" />
|
||||
<PackageReference Include="ReverseMarkdown" Version="4.5.0" />
|
||||
<PackageReference Include="QuestPDF" Version="2024.6.4" />
|
||||
<PackageReference Include="ReverseMarkdown" Version="4.6.0" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
|
||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.3" />
|
||||
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||
|
@ -12,12 +12,6 @@
|
||||
TintOpacity="0.3" />
|
||||
<SolidColorBrush x:Key="PixevalTranslucentBackgroundBrush" Color="#8FFFFFFF" />
|
||||
<SolidColorBrush x:Key="PixevalPanelBackgroundThemeBrush" Color="#F2F2F2" />
|
||||
<SolidColorBrush x:Key="PixevalBorderBrush" Color="#7C7B7B" />
|
||||
<SolidColorBrush x:Key="PixevalTipTextForeground" Color="#999AA1" />
|
||||
<SolidColorBrush x:Key="CardBackground" Color="#FAFCFD" />
|
||||
<SolidColorBrush x:Key="CardStrokeBrush" Color="#0F000000" />
|
||||
<SolidColorBrush x:Key="TextSecondaryAccentColor" Color="#404252" />
|
||||
<SolidColorBrush x:Key="SecondaryAccentBrush" Color="#FAFAFA" />
|
||||
<SolidColorBrush x:Key="SecondaryAccentBorderBrush" Color="#939393" />
|
||||
<ui:Color x:Key="SecondaryAccentColor">#FAFAFA</ui:Color>
|
||||
<ui:Color x:Key="ExpanderHeaderCardPointerOverBackgroundColor">#F6F6F6</ui:Color>
|
||||
@ -36,12 +30,6 @@
|
||||
TintOpacity="0.3" />
|
||||
<SolidColorBrush x:Key="PixevalTranslucentBackgroundBrush" Color="#8FFFFFFF" />
|
||||
<SolidColorBrush x:Key="PixevalPanelBackgroundThemeBrush" Color="#F2F2F2" />
|
||||
<SolidColorBrush x:Key="PixevalBorderBrush" Color="#7C7B7B" />
|
||||
<SolidColorBrush x:Key="PixevalTipTextForeground" Color="#999AA1" />
|
||||
<SolidColorBrush x:Key="CardBackground" Color="#FAFCFD" />
|
||||
<SolidColorBrush x:Key="CardStrokeBrush" Color="#0F000000" />
|
||||
<SolidColorBrush x:Key="TextSecondaryAccentColor" Color="#404252" />
|
||||
<SolidColorBrush x:Key="SecondaryAccentBrush" Color="#FAFAFA" />
|
||||
<SolidColorBrush x:Key="SecondaryAccentBorderBrush" Color="#939393" />
|
||||
<ui:Color x:Key="SecondaryAccentColor">#FAFAFA</ui:Color>
|
||||
<ui:Color x:Key="ExpanderHeaderCardPointerOverBackgroundColor">#F6F6F6</ui:Color>
|
||||
@ -60,13 +48,7 @@
|
||||
TintOpacity="0.3" />
|
||||
<SolidColorBrush x:Key="PixevalTranslucentBackgroundBrush" Color="#8F000000" />
|
||||
<SolidColorBrush x:Key="PixevalPanelBackgroundThemeBrush" Color="#232323" />
|
||||
<SolidColorBrush x:Key="PixevalBorderBrush" Color="#ACADAD" />
|
||||
<SolidColorBrush x:Key="PixevalTipTextForeground" Color="#828492" />
|
||||
<SolidColorBrush x:Key="CardBackground" Color="#2B2A2F" />
|
||||
<SolidColorBrush x:Key="CardStrokeBrush" Color="#19000000" />
|
||||
<SolidColorBrush x:Key="TextSecondaryAccentColor" Color="#D2D4DA" />
|
||||
<SolidColorBrush x:Key="SecondaryAccentBorderBrush" Color="#141414" />
|
||||
<SolidColorBrush x:Key="SecondaryAccentBrush" Color="#302C2D" />
|
||||
<ui:Color x:Key="SecondaryAccentColor">#302C2D</ui:Color>
|
||||
<ui:Color x:Key="ExpanderHeaderCardPointerOverBackgroundColor">#323232</ui:Color>
|
||||
<ui:Color x:Key="ActionableCardPointerOverBackgroundColor">#323232</ui:Color>
|
||||
@ -78,12 +60,6 @@
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<SolidColorBrush x:Key="PixevalAppAcrylicBrush" Color="{ThemeResource SystemColorWindowColor}" />
|
||||
<SolidColorBrush x:Key="PixevalPanelBackgroundThemeBrush" Color="#323232" />
|
||||
<SolidColorBrush x:Key="PixevalBorderBrush" Color="#ACADAD" />
|
||||
<SolidColorBrush x:Key="PixevalTipTextForeground" Color="#828492" />
|
||||
<SolidColorBrush x:Key="CardBackground" Color="{StaticResource SystemColorWindowColor}" />
|
||||
<SolidColorBrush x:Key="CardStrokeBrush" Color="Red" />
|
||||
<SolidColorBrush x:Key="TextSecondaryAccentColor" Color="#D2D4DA" />
|
||||
<SolidColorBrush x:Key="SecondaryAccentBrush" Color="Cyan" />
|
||||
<SolidColorBrush x:Key="SecondaryAccentBorderBrush" Color="Red" />
|
||||
<ui:Color x:Key="SecondaryAccentColor">Cyan</ui:Color>
|
||||
<ui:Color x:Key="ExpanderHeaderCardPointerOverBackgroundColor">#323232</ui:Color>
|
||||
|
Loading…
Reference in New Issue
Block a user