mirror of
https://github.com/gwdevhub/Daybreak.git
synced 2026-09-16 05:19:23 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fe9eeb32f | ||
|
|
4c1025243b | ||
|
|
f24eb02ca1 |
@@ -0,0 +1,45 @@
|
||||
name: Daybreak Version Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
targetplatform: [x64]
|
||||
|
||||
runs-on: windows-latest
|
||||
|
||||
env:
|
||||
Configuration: Release
|
||||
Solution_Path: Daybreak.sln
|
||||
Actions_Allow_Unsecure_Commands: true
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get Latest Tag
|
||||
id: getLatestTag
|
||||
uses: WyriHaximus/github-action-get-previous-tag@v1
|
||||
|
||||
- name: Build Daybreak project
|
||||
run: dotnet build Daybreak -c $env:Configuration
|
||||
|
||||
- name: Set version variable
|
||||
run: |
|
||||
$version = .\Scripts\GetBuildVersion.ps1
|
||||
echo "::set-env name=Version::$version"
|
||||
|
||||
- name: Check version difference
|
||||
run: |
|
||||
.\Scripts\CompareVersions -currentVersion ${{ env.Version }} -lastVersion ${{ env.LatestReleaseTag }}
|
||||
env:
|
||||
LatestReleaseTag: ${{ steps.getLatestTag.outputs.tag }}
|
||||
+9
-1
@@ -11,9 +11,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Pipelines", "Pipelines", "{
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.github\workflows\cd.yaml = .github\workflows\cd.yaml
|
||||
.github\workflows\ci.yaml = .github\workflows\ci.yaml
|
||||
.github\workflows\version_check.yaml = .github\workflows\version_check.yaml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Daybreak.Installer", "Daybreak.Installer\Daybreak.Installer.csproj", "{4E2BB805-135D-4F02-8C53-3D8B6876D323}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Daybreak.Installer", "Daybreak.Installer\Daybreak.Installer.csproj", "{4E2BB805-135D-4F02-8C53-3D8B6876D323}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{41AE8C5D-25E1-4B08-8D65-868552421A63}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
Scripts\BuildRelease.ps1 = Scripts\BuildRelease.ps1
|
||||
Scripts\GetBuildVersion.ps1 = Scripts\GetBuildVersion.ps1
|
||||
Scripts\CompareVersions.ps1 = Scripts\CompareVersions.ps1
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
||||
@@ -46,21 +46,6 @@ namespace Daybreak.Configuration
|
||||
{
|
||||
serviceProducer.ThrowIfNull(nameof(serviceProducer));
|
||||
|
||||
serviceProducer.RegisterSingleton<ViewManager>(registerAllInterfaces: true);
|
||||
serviceProducer.RegisterSingleton<IConfigurationManager, ConfigurationManager>();
|
||||
serviceProducer.RegisterSingleton<ILiteDatabase, LiteDatabase>(sp => new LiteDatabase("Daybreak.db"));
|
||||
serviceProducer.RegisterSingleton<IMutexHandler, MutexHandler>();
|
||||
serviceProducer.RegisterSingleton<IShortcutManager, ShortcutManager>();
|
||||
serviceProducer.RegisterSingleton<IIconBrowser, IconBrowser>();
|
||||
serviceProducer.RegisterScoped<ICredentialManager, CredentialManager>();
|
||||
serviceProducer.RegisterScoped<IApplicationLauncher, ApplicationLauncher>();
|
||||
serviceProducer.RegisterScoped<IScreenshotProvider, ScreenshotProvider>();
|
||||
serviceProducer.RegisterScoped<IBloogumClient, BloogumClient>();
|
||||
serviceProducer.RegisterScoped<IApplicationUpdater, ApplicationUpdater>();
|
||||
serviceProducer.RegisterScoped<IBuildTemplateManager, BuildTemplateManager>();
|
||||
serviceProducer.RegisterScoped<IIconRetriever, IconRetriever>();
|
||||
serviceProducer.RegisterScoped<IPrivilegeManager, PrivilegeManager>();
|
||||
serviceProducer.RegisterScoped<IScreenManager, ScreenManager>();
|
||||
serviceProducer.RegisterSingleton<ILogsManager, JsonLogsManager>();
|
||||
serviceProducer.RegisterSingleton<IDebugLogsWriter, Services.Logging.DebugLogsWriter>();
|
||||
serviceProducer.RegisterSingleton<ILoggerFactory, LoggerFactory>(sp =>
|
||||
@@ -72,8 +57,24 @@ namespace Daybreak.Configuration
|
||||
serviceProducer.RegisterSingleton<ILogsWriter, CompositeLogsWriter>(sp => new CompositeLogsWriter(
|
||||
sp.GetService<ILogsManager>(),
|
||||
sp.GetService<IDebugLogsWriter>()));
|
||||
|
||||
|
||||
serviceProducer.RegisterScoped((sp) => new ScopeMetadata(new CorrelationVector()));
|
||||
serviceProducer.RegisterSingleton<ViewManager>(registerAllInterfaces: true);
|
||||
serviceProducer.RegisterSingleton<IConfigurationManager, ConfigurationManager>();
|
||||
serviceProducer.RegisterSingleton<ILiteDatabase, LiteDatabase>(sp => new LiteDatabase("Daybreak.db"));
|
||||
serviceProducer.RegisterSingleton<IMutexHandler, MutexHandler>();
|
||||
serviceProducer.RegisterSingleton<IShortcutManager, ShortcutManager>();
|
||||
serviceProducer.RegisterSingleton<IIconBrowser, IconBrowser>();
|
||||
serviceProducer.RegisterSingleton<IIconDownloader, IconDownloader>();
|
||||
serviceProducer.RegisterScoped<ICredentialManager, CredentialManager>();
|
||||
serviceProducer.RegisterScoped<IApplicationLauncher, ApplicationLauncher>();
|
||||
serviceProducer.RegisterScoped<IScreenshotProvider, ScreenshotProvider>();
|
||||
serviceProducer.RegisterScoped<IBloogumClient, BloogumClient>();
|
||||
serviceProducer.RegisterScoped<IApplicationUpdater, ApplicationUpdater>();
|
||||
serviceProducer.RegisterScoped<IBuildTemplateManager, BuildTemplateManager>();
|
||||
serviceProducer.RegisterScoped<IIconCache, IconCache>();
|
||||
serviceProducer.RegisterScoped<IPrivilegeManager, PrivilegeManager>();
|
||||
serviceProducer.RegisterScoped<IScreenManager, ScreenManager>();
|
||||
}
|
||||
|
||||
public static void RegisterViews(IViewProducer viewProducer)
|
||||
|
||||
@@ -28,6 +28,8 @@ namespace Daybreak.Controls
|
||||
|
||||
private const string BrowserDownloadLink = "https://developer.microsoft.com/en-us/microsoft-edge/webview2/";
|
||||
|
||||
private static CoreWebView2Environment coreWebView2Environment;
|
||||
|
||||
public event EventHandler<string> FavoriteUriChanged;
|
||||
public event EventHandler MaximizeClicked;
|
||||
public event EventHandler<Build> BuildDecoded;
|
||||
@@ -35,16 +37,15 @@ namespace Daybreak.Controls
|
||||
private ILiveOptions<ApplicationConfiguration> liveOptions;
|
||||
private ILogger<ChromiumBrowserWrapper> logger;
|
||||
private IBuildTemplateManager buildTemplateManager;
|
||||
private CoreWebView2Environment coreWebView2Environment;
|
||||
|
||||
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool canDownloadBuild;
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool canNavigate;
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool controlsEnabled;
|
||||
[GenerateDependencyProperty]
|
||||
private bool browserSupported;
|
||||
[GenerateDependencyProperty(InitialValue = null)]
|
||||
private bool? browserSupported;
|
||||
[GenerateDependencyProperty]
|
||||
private bool addressBarReadonly;
|
||||
[GenerateDependencyProperty]
|
||||
@@ -80,7 +81,7 @@ namespace Daybreak.Controls
|
||||
}
|
||||
}
|
||||
|
||||
public async void InitializeBrowser(
|
||||
public async Task InitializeBrowser(
|
||||
ILiveOptions<ApplicationConfiguration> liveOptions,
|
||||
IBuildTemplateManager buildTemplateManager,
|
||||
ILogger<ChromiumBrowserWrapper> logger)
|
||||
@@ -107,7 +108,11 @@ namespace Daybreak.Controls
|
||||
|
||||
try
|
||||
{
|
||||
this.coreWebView2Environment = System.Extensions.TaskExtensions.RunSync(() => CoreWebView2Environment.CreateAsync(null, "BrowserData", null));
|
||||
if (coreWebView2Environment is null)
|
||||
{
|
||||
coreWebView2Environment = System.Extensions.TaskExtensions.RunSync(() => CoreWebView2Environment.CreateAsync(null, "BrowserData", null));
|
||||
}
|
||||
|
||||
this.BrowserSupported = true;
|
||||
}
|
||||
catch(Exception e)
|
||||
@@ -122,7 +127,8 @@ namespace Daybreak.Controls
|
||||
if (this.BrowserSupported is true)
|
||||
{
|
||||
this.WebBrowser.IsEnabled = true;
|
||||
await this.WebBrowser.EnsureCoreWebView2Async(this.coreWebView2Environment);
|
||||
this.BrowserEnabled = true;
|
||||
await this.WebBrowser.EnsureCoreWebView2Async(coreWebView2Environment);
|
||||
this.AddressBarReadonly = this.liveOptions.Value.AddressBarReadonly;
|
||||
this.CanDownloadBuild = this.liveOptions.Value.ExperimentalFeatures.DynamicBuildLoading;
|
||||
this.WebBrowser.CoreWebView2.NewWindowRequested += (browser, args) => args.Handled = true;
|
||||
@@ -207,6 +213,11 @@ namespace Daybreak.Controls
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.buildTemplateManager is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.buildTemplateManager.IsTemplate(maybeTemplate) is false)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -67,16 +67,15 @@ namespace Daybreak.Controls
|
||||
this.DataContextChanged += this.BuildTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
public void InitializeTemplate(
|
||||
IIconRetriever iconRetriever,
|
||||
public async void InitializeTemplate(
|
||||
IIconCache iconRetriever,
|
||||
IIconBrowser iconBrowser,
|
||||
ILiveOptions<ApplicationConfiguration> liveOptions,
|
||||
IBuildTemplateManager buildTemplateManager,
|
||||
ILogger<ChromiumBrowserWrapper> logger)
|
||||
{
|
||||
this.iconBrowser = iconBrowser.ThrowIfNull();
|
||||
this.SkillBrowser.InitializeBrowser(liveOptions, buildTemplateManager, logger);
|
||||
this.iconBrowser.InitializeWebView(this.SkillBrowser.WebBrowser, this.cancellationTokenSource.Token);
|
||||
await this.SkillBrowser.InitializeBrowser(liveOptions, buildTemplateManager, logger);
|
||||
this.SkillTemplate0.InitializeSkillTemplate(iconRetriever);
|
||||
this.SkillTemplate1.InitializeSkillTemplate(iconRetriever);
|
||||
this.SkillTemplate2.InitializeSkillTemplate(iconRetriever);
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Daybreak.Controls
|
||||
public event EventHandler<RoutedEventArgs> Clicked;
|
||||
public event EventHandler RemoveClicked;
|
||||
|
||||
private IIconRetriever iconRetriever;
|
||||
private IIconCache iconRetriever;
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private ImageSource imageSource;
|
||||
@@ -32,13 +32,19 @@ namespace Daybreak.Controls
|
||||
this.DataContextChanged += SkillTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
public void InitializeSkillTemplate(IIconRetriever iconRetriever)
|
||||
public void InitializeSkillTemplate(IIconCache iconRetriever)
|
||||
{
|
||||
this.iconRetriever = iconRetriever;
|
||||
this.SkillTemplate_DataContextChanged(this, new DependencyPropertyChangedEventArgs(UserControl.DataContextProperty, null, this.DataContext));
|
||||
}
|
||||
|
||||
private async void SkillTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (this.iconRetriever is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.NewValue is Skill skill)
|
||||
{
|
||||
if (skill != Skill.NoSkill)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Extensions;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
@@ -19,7 +20,7 @@ namespace Daybreak.Converters
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return GetVisibility(value);
|
||||
return this.GetVisibility(value);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
@@ -29,17 +30,24 @@ namespace Daybreak.Converters
|
||||
|
||||
private object GetVisibility(object value)
|
||||
{
|
||||
if (!(value is bool))
|
||||
return DependencyProperty.UnsetValue;
|
||||
bool objValue = (bool)value;
|
||||
if (value is not bool)
|
||||
{
|
||||
return this.IsHidden ?
|
||||
Visibility.Hidden :
|
||||
Visibility.Collapsed;
|
||||
}
|
||||
|
||||
var objValue = value.Cast<bool>();
|
||||
if ((objValue && TriggerValue && IsHidden) || (!objValue && !TriggerValue && IsHidden))
|
||||
{
|
||||
return Visibility.Hidden;
|
||||
}
|
||||
|
||||
if ((objValue && TriggerValue && !IsHidden) || (!objValue && !TriggerValue && !IsHidden))
|
||||
{
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
|
||||
return Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<LangVersion>preview</LangVersion>
|
||||
<ApplicationIcon>Daybreak.ico</ApplicationIcon>
|
||||
<IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation>
|
||||
<Version>0.9.3.4</Version>
|
||||
<Version>0.9.3.7</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:webview="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
|
||||
xmlns:local="clr-namespace:Daybreak.Launch"
|
||||
xmlns:wcl="clr-namespace:WCL;assembly=WCL"
|
||||
mc:Ignorable="d"
|
||||
@@ -102,5 +103,10 @@
|
||||
<Grid x:Name="Container" Grid.Row="1">
|
||||
</Grid>
|
||||
<wcl:Border OnResize="Border_OnResize" Grid.RowSpan="2" Active="True"></wcl:Border>
|
||||
<webview:WebView2 x:Name="BackgroundWebView"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Visibility="Collapsed"
|
||||
Grid.Row="1"></webview:WebView2>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Services.Bloogum;
|
||||
using Daybreak.Services.IconRetrieve;
|
||||
using Daybreak.Services.Privilege;
|
||||
using Daybreak.Services.Screenshots;
|
||||
using Daybreak.Services.Updater;
|
||||
@@ -8,6 +9,7 @@ using Daybreak.Views;
|
||||
using Pepa.Wpf.Utilities;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Core.Extensions;
|
||||
using System.Diagnostics;
|
||||
using System.Extensions;
|
||||
using System.Threading;
|
||||
@@ -32,6 +34,7 @@ namespace Daybreak.Launch
|
||||
private readonly IBloogumClient bloogumClient;
|
||||
private readonly IApplicationUpdater applicationUpdater;
|
||||
private readonly IPrivilegeManager privilegeManager;
|
||||
private readonly IIconDownloader iconDownloader;
|
||||
private readonly ILiveOptions<ApplicationConfiguration> liveOptions;
|
||||
private readonly CancellationTokenSource cancellationToken = new();
|
||||
|
||||
@@ -48,14 +51,16 @@ namespace Daybreak.Launch
|
||||
IBloogumClient bloogumClient,
|
||||
IApplicationUpdater applicationUpdater,
|
||||
IPrivilegeManager privilegeManager,
|
||||
IIconDownloader iconDownloader,
|
||||
ILiveOptions<ApplicationConfiguration> liveOptions)
|
||||
{
|
||||
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
|
||||
this.screenshotProvider = screenshotProvider.ThrowIfNull(nameof(screenshotProvider));
|
||||
this.bloogumClient = bloogumClient.ThrowIfNull(nameof(bloogumClient));
|
||||
this.applicationUpdater = applicationUpdater.ThrowIfNull(nameof(applicationUpdater));
|
||||
this.privilegeManager = privilegeManager.ThrowIfNull(nameof(privilegeManager));
|
||||
this.liveOptions = liveOptions.ThrowIfNull(nameof(liveOptions));
|
||||
this.viewManager = viewManager.ThrowIfNull();
|
||||
this.screenshotProvider = screenshotProvider.ThrowIfNull();
|
||||
this.bloogumClient = bloogumClient.ThrowIfNull();
|
||||
this.applicationUpdater = applicationUpdater.ThrowIfNull();
|
||||
this.privilegeManager = privilegeManager.ThrowIfNull();
|
||||
this.iconDownloader = iconDownloader.ThrowIfNull();
|
||||
this.liveOptions = liveOptions.ThrowIfNull();
|
||||
this.InitializeComponent();
|
||||
this.CurrentVersionText = this.applicationUpdater.CurrentVersion.ToString();
|
||||
this.IsRunningAsAdmin = this.privilegeManager.AdminPrivileges;
|
||||
@@ -66,6 +71,7 @@ namespace Daybreak.Launch
|
||||
{
|
||||
this.SetupImageCycle();
|
||||
this.CheckForUpdates();
|
||||
this.SetupBackgroundBrowser();
|
||||
}
|
||||
|
||||
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
@@ -101,6 +107,11 @@ namespace Daybreak.Launch
|
||||
NativeMethods.SendMessage(new WindowInteropHelper(this).Handle, NativeMethods.WM_SYSCOMMAND, (IntPtr)e, IntPtr.Zero);
|
||||
}
|
||||
|
||||
private void SetupBackgroundBrowser()
|
||||
{
|
||||
this.iconDownloader.SetBrowser(this.BackgroundWebView);
|
||||
}
|
||||
|
||||
private void SetupImageCycle()
|
||||
{
|
||||
TaskExtensions.RunPeriodicAsync(() => this.Dispatcher.Invoke(() => this.UpdateRandomImage()), TimeSpan.Zero, TimeSpan.FromSeconds(15), this.cancellationToken.Token);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Models
|
||||
namespace Daybreak.Models
|
||||
{
|
||||
public sealed class IconPayload
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Daybreak.Models.Builds;
|
||||
|
||||
namespace Models
|
||||
namespace Daybreak.Models
|
||||
{
|
||||
public sealed class IconRequest
|
||||
{
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Daybreak.Models.Progress
|
||||
{
|
||||
public sealed class IconDownloadStatus : INotifyPropertyChanged
|
||||
{
|
||||
public static readonly IconDownloadStep StartingStep = new StartingIconDownloadStep();
|
||||
public static readonly IconDownloadStep Finished = new FinishedIconDownloadStep();
|
||||
public static readonly IconDownloadStep BrowserNotSupported = new NotSupportedIconDownloadStep();
|
||||
public static IconDownloadStep Checking(string iconName, double progress) => new CheckingIconDownloadStep(iconName, progress);
|
||||
public static IconDownloadStep Downloading(string iconName, double progress) => new DownloadingIconDownloadStep(iconName, progress);
|
||||
public static IconDownloadStep Stopped(double progress) => new StoppedIconDownloadStep(progress);
|
||||
|
||||
private IconDownloadStep currentStep = StartingStep;
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public IconDownloadStep CurrentStep
|
||||
{
|
||||
get => currentStep;
|
||||
set
|
||||
{
|
||||
currentStep = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentStep)));
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class IconDownloadStep : LoadStatus
|
||||
{
|
||||
public IconDownloadStep(string name, double progress) : base(name)
|
||||
{
|
||||
this.Progress = progress;
|
||||
}
|
||||
}
|
||||
|
||||
public class StoppedIconDownloadStep : IconDownloadStep
|
||||
{
|
||||
public StoppedIconDownloadStep(double progress) : base("Download stopped", progress)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class DownloadingIconDownloadStep : IconDownloadStep
|
||||
{
|
||||
public DownloadingIconDownloadStep(string skillName, double progress) : base($"Downloading [{skillName}] icon", progress)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class CheckingIconDownloadStep : IconDownloadStep
|
||||
{
|
||||
public CheckingIconDownloadStep(string skillName, double progress) : base($"Checking [{skillName}] icon", progress)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class NotSupportedIconDownloadStep : IconDownloadStep
|
||||
{
|
||||
public NotSupportedIconDownloadStep() : base("Cannot download icons. The WebView2 browser is not supported", 0d)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class FinishedIconDownloadStep : IconDownloadStep
|
||||
{
|
||||
public FinishedIconDownloadStep() : base("Download finished", 100d)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class StartingIconDownloadStep : IconDownloadStep
|
||||
{
|
||||
public StartingIconDownloadStep() : base("Download starting", 0d)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Daybreak.Models.Progress
|
||||
{
|
||||
public abstract class LoadStatus
|
||||
{
|
||||
public string Description { get; set; }
|
||||
public double Progress { get; set; }
|
||||
public LoadStatus(string description)
|
||||
{
|
||||
this.Description = description;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Daybreak.Models
|
||||
namespace Daybreak.Models.Progress
|
||||
{
|
||||
public sealed class UpdateStatus : INotifyPropertyChanged
|
||||
{
|
||||
@@ -17,30 +17,26 @@ namespace Daybreak.Models
|
||||
|
||||
public UpdateStep CurrentStep
|
||||
{
|
||||
get => this.currentStep;
|
||||
get => currentStep;
|
||||
set
|
||||
{
|
||||
this.currentStep = value;
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentStep)));
|
||||
currentStep = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentStep)));
|
||||
}
|
||||
}
|
||||
|
||||
public class UpdateStep
|
||||
public class UpdateStep : LoadStatus
|
||||
{
|
||||
public string Name { get; }
|
||||
internal UpdateStep(string name)
|
||||
public UpdateStep(string name) : base(name)
|
||||
{
|
||||
this.Name = name;
|
||||
}
|
||||
}
|
||||
public class DownloadUpdateStep : UpdateStep
|
||||
{
|
||||
internal DownloadUpdateStep(string name, double progress) : base(name)
|
||||
{
|
||||
this.Progress = progress;
|
||||
Progress = progress;
|
||||
}
|
||||
|
||||
public double Progress { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.Web.WebView2.Wpf;
|
||||
using Models;
|
||||
using Daybreak.Controls;
|
||||
using Daybreak.Models;
|
||||
using Microsoft.Web.WebView2.Wpf;
|
||||
using System.Threading;
|
||||
|
||||
namespace Daybreak.Services.IconRetrieve
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Daybreak.Services.IconRetrieve
|
||||
{
|
||||
public interface IIconRetriever
|
||||
public interface IIconCache
|
||||
{
|
||||
Task<Optional<Uri>> GetIconUri(Skill skill);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Daybreak.Controls;
|
||||
using Daybreak.Models.Progress;
|
||||
using Microsoft.Web.WebView2.Wpf;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Daybreak.Services.IconRetrieve
|
||||
{
|
||||
public interface IIconDownloader
|
||||
{
|
||||
void SetBrowser(WebView2 chromiumBrowserWrapper);
|
||||
|
||||
bool DownloadComplete { get; }
|
||||
Task<IconDownloadStatus> StartIconDownload();
|
||||
void CancelIconDownload();
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Controls;
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using Microsoft.Web.WebView2.Wpf;
|
||||
using Models;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
@@ -13,7 +15,6 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace Daybreak.Services.IconRetrieve
|
||||
{
|
||||
@@ -30,7 +31,7 @@ namespace Daybreak.Services.IconRetrieve
|
||||
|
||||
private readonly ConcurrentQueue<IconRequest> iconRequests = new();
|
||||
private readonly ILogger<IconBrowser> logger;
|
||||
private WebView2 webView2;
|
||||
private WebView2 browserWrapper;
|
||||
private CancellationToken cancellationToken;
|
||||
|
||||
public IconBrowser(
|
||||
@@ -41,7 +42,7 @@ namespace Daybreak.Services.IconRetrieve
|
||||
|
||||
public void InitializeWebView(WebView2 webView2, CancellationToken cancellationToken)
|
||||
{
|
||||
this.webView2 = webView2.ThrowIfNull();
|
||||
this.browserWrapper = webView2.ThrowIfNull();
|
||||
this.cancellationToken = cancellationToken;
|
||||
Task.Run(this.PeriodicallyServeRequests, cancellationToken);
|
||||
}
|
||||
@@ -53,102 +54,116 @@ namespace Daybreak.Services.IconRetrieve
|
||||
|
||||
private async Task PeriodicallyServeRequests()
|
||||
{
|
||||
while(true)
|
||||
while(this.cancellationToken.IsCancellationRequested is false)
|
||||
{
|
||||
await Application.Current.Dispatcher.InvokeAsync(async () =>
|
||||
{
|
||||
await this.ServeRequest();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ServeRequest()
|
||||
{
|
||||
if (this.cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.iconRequests.TryDequeue(out var request) is false)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
return;
|
||||
}
|
||||
|
||||
var logger = this.logger.CreateScopedLogger(nameof(this.PeriodicallyServeRequests), request.Skill?.Name);
|
||||
logger.LogInformation($"Retrieving icon");
|
||||
while (this.browserWrapper is null)
|
||||
{
|
||||
if (this.cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.iconRequests.TryDequeue(out var request) is false)
|
||||
logger.LogInformation($"Browser is not yet initialized. Waiting");
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await this.browserWrapper.EnsureCoreWebView2Async();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
var curedSkillName = request.Skill.AlternativeName.IsNullOrWhiteSpace() ?
|
||||
request.Skill.Name.Replace(" ", "_") :
|
||||
request.Skill.AlternativeName.Replace(" ", "_");
|
||||
var skillIconUrl = $"{BaseUrl}/{QueryUrl.Replace(NamePlaceholder, curedSkillName)}";
|
||||
logger.LogInformation($"Looking for icon at {skillIconUrl}");
|
||||
|
||||
this.browserWrapper.CoreWebView2.Navigate(skillIconUrl);
|
||||
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
if (this.cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogInformation("Executing extraction script");
|
||||
var responseTask = await Application.Current.Dispatcher.InvokeAsync(async () =>
|
||||
{
|
||||
return await this.browserWrapper.ExecuteScriptAsync(Scripts.GetHrefFromSkillPage);
|
||||
});
|
||||
var response = await responseTask;
|
||||
logger.LogInformation("Parsing response");
|
||||
var iconPayload = JsonConvert.DeserializeObject<IconPayload>(response);
|
||||
if (iconPayload is null)
|
||||
{
|
||||
logger.LogInformation("Bad response");
|
||||
await Task.Delay(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
var logger = this.logger.CreateScopedLogger(nameof(this.PeriodicallyServeRequests), request.Skill?.Name);
|
||||
logger.LogInformation($"Retrieving icon");
|
||||
while(this.webView2 is null)
|
||||
if (iconPayload.SkillUrl != skillIconUrl.Replace("\"", "%22"))
|
||||
{
|
||||
if (this.cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogInformation($"Browser is not yet initialized. Waiting");
|
||||
logger.LogInformation("Retrieved icon doesn't match");
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
|
||||
var curedSkillName = request.Skill.AlternativeName.IsNullOrWhiteSpace() ?
|
||||
request.Skill.Name.Replace(" ", "_") :
|
||||
request.Skill.AlternativeName.Replace(" ", "_");
|
||||
var skillIconUrl = $"{BaseUrl}/{QueryUrl.Replace(NamePlaceholder, curedSkillName)}";
|
||||
logger.LogInformation($"Looking for icon at {skillIconUrl}");
|
||||
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
this.webView2.Source = new Uri(skillIconUrl);
|
||||
});
|
||||
|
||||
for(var i = 0; i < 5; i++)
|
||||
{
|
||||
if (this.cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogInformation("Executing extraction script");
|
||||
var responseTask = await Application.Current.Dispatcher.InvokeAsync(async () =>
|
||||
{
|
||||
return await this.webView2.ExecuteScriptAsync(Scripts.GetHrefFromSkillPage);
|
||||
});
|
||||
var response = await responseTask;
|
||||
logger.LogInformation("Parsing response");
|
||||
var iconPayload = JsonConvert.DeserializeObject<IconPayload>(response);
|
||||
if (iconPayload is null)
|
||||
{
|
||||
logger.LogInformation("Bad response");
|
||||
await Task.Delay(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (iconPayload.SkillUrl != skillIconUrl.Replace("\"", "%22"))
|
||||
{
|
||||
logger.LogInformation("Retrieved icon doesn't match");
|
||||
await Task.Delay(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
var potentialBase64 = iconPayload.SkillImage.Split(',').Skip(1).FirstOrDefault();
|
||||
if (potentialBase64 == FaultyBase64 ||
|
||||
potentialBase64 == LargeFaultyBase64)
|
||||
{
|
||||
logger.LogInformation("Faulty base64 retrieved");
|
||||
await Task.Delay(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
byte[] bytes;
|
||||
try
|
||||
{
|
||||
bytes = Convert.FromBase64String(potentialBase64);
|
||||
}
|
||||
catch
|
||||
{
|
||||
logger.LogError("Failed to parse base64");
|
||||
await Task.Delay(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
await SaveIconLocally(request.Skill, bytes);
|
||||
request.IconBase64 = potentialBase64;
|
||||
request.Finished = true;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
logger.LogError($"Failed to retrieve icon");
|
||||
var potentialBase64 = iconPayload.SkillImage.Split(',').Skip(1).FirstOrDefault();
|
||||
if (potentialBase64 == FaultyBase64 ||
|
||||
potentialBase64 == LargeFaultyBase64)
|
||||
{
|
||||
logger.LogInformation("Faulty base64 retrieved");
|
||||
await Task.Delay(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
byte[] bytes;
|
||||
try
|
||||
{
|
||||
bytes = Convert.FromBase64String(potentialBase64);
|
||||
}
|
||||
catch
|
||||
{
|
||||
logger.LogError("Failed to parse base64");
|
||||
await Task.Delay(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
await SaveIconLocally(request.Skill, bytes);
|
||||
request.IconBase64 = potentialBase64;
|
||||
request.Finished = true;
|
||||
break;
|
||||
}
|
||||
|
||||
logger.LogError($"Failed to retrieve icon");
|
||||
request.Finished = true;
|
||||
}
|
||||
|
||||
private static async Task<string> SaveIconLocally(Skill skill, byte[] data)
|
||||
|
||||
+5
-8
@@ -1,9 +1,6 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Models.Builds;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Models;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Core.Extensions;
|
||||
using System.Extensions;
|
||||
using System.IO;
|
||||
@@ -11,16 +8,16 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Daybreak.Services.IconRetrieve
|
||||
{
|
||||
public sealed class IconRetriever : IIconRetriever
|
||||
public sealed class IconCache : IIconCache
|
||||
{
|
||||
private const string NamePlaceholder = "[SKILLNAME]";
|
||||
private const string IconsDirectoryName = "Icons";
|
||||
private const string IconsLocation = $"{IconsDirectoryName}/{NamePlaceholder}.jpg";
|
||||
|
||||
private readonly ILogger<IconRetriever> logger;
|
||||
private readonly ILogger<IconCache> logger;
|
||||
|
||||
public IconRetriever(
|
||||
ILogger<IconRetriever> logger)
|
||||
public IconCache(
|
||||
ILogger<IconCache> logger)
|
||||
{
|
||||
this.logger = logger.ThrowIfNull();
|
||||
if (Directory.Exists(IconsDirectoryName) is false)
|
||||
@@ -0,0 +1,239 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Controls;
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Models.Progress;
|
||||
using Daybreak.Services.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using Microsoft.Web.WebView2.Wpf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Core.Extensions;
|
||||
using System.Extensions;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Extensions.Services;
|
||||
|
||||
namespace Daybreak.Services.IconRetrieve
|
||||
{
|
||||
public sealed class IconDownloader : IIconDownloader, IApplicationLifetimeService
|
||||
{
|
||||
private readonly IIconBrowser iconBrowser;
|
||||
private readonly IIconCache iconCache;
|
||||
private readonly IConfigurationManager configurationManager;
|
||||
private readonly ILogger<IconDownloader> logger;
|
||||
private readonly ILiveOptions<ApplicationConfiguration> liveOptions;
|
||||
private readonly ILogger<ChromiumBrowserWrapper> browserLogger;
|
||||
private WebView2 browserWrapper;
|
||||
private CancellationTokenSource cancellationTokenSource;
|
||||
private IconDownloadStatus iconDownloadStatus;
|
||||
|
||||
public bool DownloadComplete { get; private set; }
|
||||
public bool Downloading => this.cancellationTokenSource is not null;
|
||||
|
||||
public IconDownloader(
|
||||
IIconBrowser iconBrowser,
|
||||
IIconCache iconCache,
|
||||
IConfigurationManager configurationManager,
|
||||
ILogger<IconDownloader> logger,
|
||||
ILiveOptions<ApplicationConfiguration> liveOptions,
|
||||
ILogger<ChromiumBrowserWrapper> browserLogger)
|
||||
{
|
||||
this.iconBrowser = iconBrowser.ThrowIfNull();
|
||||
this.iconCache = iconCache.ThrowIfNull();
|
||||
this.configurationManager = configurationManager.ThrowIfNull();
|
||||
this.logger = logger.ThrowIfNull();
|
||||
this.liveOptions = liveOptions.ThrowIfNull();
|
||||
this.browserLogger = browserLogger.ThrowIfNull();
|
||||
this.HookIntoConfigurationChanges();
|
||||
}
|
||||
|
||||
public void SetBrowser(WebView2 chromiumBrowserWrapper)
|
||||
{
|
||||
if (this.browserWrapper is not null)
|
||||
{
|
||||
throw new InvalidOperationException("Browser is already set");
|
||||
}
|
||||
|
||||
this.browserWrapper = chromiumBrowserWrapper;
|
||||
}
|
||||
|
||||
public async Task<IconDownloadStatus> StartIconDownload()
|
||||
{
|
||||
while(this.browserWrapper is null)
|
||||
{
|
||||
await Task.Delay(100);
|
||||
}
|
||||
|
||||
this.logger.LogInformation("Starting download");
|
||||
if (this.Downloading)
|
||||
{
|
||||
this.logger.LogInformation("Download already running");
|
||||
return this.iconDownloadStatus;
|
||||
}
|
||||
|
||||
this.cancellationTokenSource = new();
|
||||
this.iconDownloadStatus = new IconDownloadStatus();
|
||||
Task.Run(this.DownloadIcons);
|
||||
return this.iconDownloadStatus;
|
||||
}
|
||||
|
||||
public void CancelIconDownload()
|
||||
{
|
||||
this.cancellationTokenSource?.Cancel();
|
||||
this.cancellationTokenSource?.Dispose();
|
||||
this.cancellationTokenSource = null;
|
||||
}
|
||||
|
||||
private async Task DownloadIcons()
|
||||
{
|
||||
this.logger.LogInformation("Beginning icon download");
|
||||
if (await TestBrowserSupported() is false)
|
||||
{
|
||||
this.logger.LogError("Browser not supported. Icon downloading stopped");
|
||||
this.iconDownloadStatus.CurrentStep = IconDownloadStatus.BrowserNotSupported;
|
||||
return;
|
||||
}
|
||||
|
||||
var progressIncrement = 100d / Skill.Skills.Count();
|
||||
var progressValue = 0d;
|
||||
var skillsToDownload = new List<Skill>();
|
||||
foreach(var skill in Skill.Skills.OrderBy(s => s.Name))
|
||||
{
|
||||
if (skill == Skill.NoSkill)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var logger = this.logger.CreateScopedLogger(nameof(this.DownloadIcons), skill.Name);
|
||||
logger.LogInformation("Verifying if icon exists");
|
||||
this.iconDownloadStatus.CurrentStep = IconDownloadStatus.Checking(skill.Name, progressValue);
|
||||
if ((await this.iconCache.GetIconUri(skill)).ExtractValue() is not null)
|
||||
{
|
||||
progressValue += progressIncrement;
|
||||
await Task.Delay(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
skillsToDownload.Add(skill);
|
||||
}
|
||||
|
||||
if (skillsToDownload.Count == 0)
|
||||
{
|
||||
this.logger.LogInformation("No icons missing. Stopping download");
|
||||
this.iconDownloadStatus.CurrentStep = IconDownloadStatus.Finished;
|
||||
return;
|
||||
}
|
||||
|
||||
this.iconBrowser.InitializeWebView(this.browserWrapper, this.cancellationTokenSource.Token);
|
||||
|
||||
var incomplete = false;
|
||||
foreach (var skill in skillsToDownload)
|
||||
{
|
||||
if (this.cancellationTokenSource?.IsCancellationRequested is null or true)
|
||||
{
|
||||
this.iconDownloadStatus.CurrentStep = IconDownloadStatus.Stopped(progressValue);
|
||||
return;
|
||||
}
|
||||
|
||||
if (skill == Skill.NoSkill)
|
||||
{
|
||||
progressValue += progressIncrement;
|
||||
continue;
|
||||
}
|
||||
|
||||
logger.LogInformation("Downloading icon");
|
||||
this.iconDownloadStatus.CurrentStep = IconDownloadStatus.Downloading(skill.Name, progressValue);
|
||||
var request = new IconRequest { Skill = skill };
|
||||
this.iconBrowser.QueueIconRequest(request);
|
||||
|
||||
while (request.Finished is false)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
|
||||
if (request.IconBase64.IsNullOrWhiteSpace())
|
||||
{
|
||||
logger.LogWarning("Failed to download icon");
|
||||
incomplete = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInformation("Downloaded icon");
|
||||
}
|
||||
|
||||
progressValue += progressIncrement;
|
||||
}
|
||||
|
||||
if (incomplete)
|
||||
{
|
||||
this.logger.LogError("Failed to download all icons. Retrying");
|
||||
await this.DownloadIcons();
|
||||
}
|
||||
else
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
this.browserWrapper.IsEnabled = false;
|
||||
this.browserWrapper.Dispose();
|
||||
});
|
||||
this.iconDownloadStatus.CurrentStep = IconDownloadStatus.Finished;
|
||||
this.DownloadComplete = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<bool> TestBrowserSupported()
|
||||
{
|
||||
CoreWebView2Environment coreWebView2Environment;
|
||||
try
|
||||
{
|
||||
var task = await Application.Current.Dispatcher.InvokeAsync(async () =>
|
||||
{
|
||||
return await CoreWebView2Environment.CreateAsync().ConfigureAwait(true);
|
||||
});
|
||||
|
||||
coreWebView2Environment = await task;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return coreWebView2Environment is not null;
|
||||
}
|
||||
|
||||
private void HookIntoConfigurationChanges()
|
||||
{
|
||||
this.configurationManager.ConfigurationChanged += async (_, _) =>
|
||||
{
|
||||
var configuration = this.configurationManager.GetConfiguration();
|
||||
if (configuration.ExperimentalFeatures.DownloadIcons)
|
||||
{
|
||||
await this.StartIconDownload();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.CancelIconDownload();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public async void OnStartup()
|
||||
{
|
||||
var configuration = this.configurationManager.GetConfiguration();
|
||||
if (configuration.ExperimentalFeatures.DownloadIcons)
|
||||
{
|
||||
await this.StartIconDownload();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnClosing()
|
||||
{
|
||||
this.cancellationTokenSource?.Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Exceptions;
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Models.Github;
|
||||
using Daybreak.Models.Progress;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Views;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Models.Progress;
|
||||
using Daybreak.Models.Versioning;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Daybreak.Views
|
||||
public BuildTemplateView(
|
||||
IViewManager viewManager,
|
||||
IBuildTemplateManager buildTemplateManager,
|
||||
IIconRetriever iconRetriever,
|
||||
IIconCache iconRetriever,
|
||||
IIconBrowser iconBrowser,
|
||||
ILiveOptions<ApplicationConfiguration> liveOptions,
|
||||
ILogger<ChromiumBrowserWrapper> chromiumLogger,
|
||||
|
||||
@@ -7,28 +7,17 @@
|
||||
xmlns:controls="clr-namespace:Daybreak.Controls"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
Unloaded="IconDownloadView_Unloaded"
|
||||
Loaded="IconDownloadView_Loaded"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></BooleanToVisibilityConverter>
|
||||
</UserControl.Resources>
|
||||
<Grid VerticalAlignment="Center" HorizontalAlignment="Center" Background="White" MinHeight="200" MinWidth="400">
|
||||
<controls:ChromiumBrowserWrapper x:Name="WebView"
|
||||
ControlsEnabled="False"
|
||||
AddressBarReadonly="True"
|
||||
CanNavigate="False"
|
||||
CanDownloadBuild="False"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Visibility="Visible"
|
||||
Width="0"
|
||||
Height="0"></controls:ChromiumBrowserWrapper>
|
||||
<StackPanel VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding ElementName=_this, Path=Description, Mode=OneWay}" Margin="10, 0, 10, 0" Foreground="Black"
|
||||
TextWrapping="Wrap" HorizontalAlignment="Center" FontSize="16"></TextBlock>
|
||||
<ProgressBar Minimum="0" Maximum="100" Value="{Binding ElementName=_this, Path=ProgressValue, Mode=OneWay}" Width="300" Height="20"></ProgressBar>
|
||||
<controls:OpaqueButton Text="Cancel" BackgroundOpacity="0.2" TransparentBackground="Gray" HorizontalAlignment="Center" Margin="10" Width="50" Height="25"
|
||||
<controls:OpaqueButton Text="Continue" BackgroundOpacity="0.2" TransparentBackground="Gray" HorizontalAlignment="Center" Margin="10" Width="80" Height="25"
|
||||
Clicked="OpaqueButton_Clicked" Foreground="Black" FontSize="16"></controls:OpaqueButton>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Models.Progress;
|
||||
using Daybreak.Services.IconRetrieve;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Models;
|
||||
using System;
|
||||
using System.Core.Extensions;
|
||||
using System.Extensions;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
|
||||
@@ -20,11 +18,7 @@ namespace Daybreak.Views
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
|
||||
public partial class IconDownloadView : UserControl
|
||||
{
|
||||
private static bool CompleteIcons = false;
|
||||
|
||||
private readonly CancellationTokenSource cancellationTokenSource = new();
|
||||
private readonly IIconRetriever iconRetriever;
|
||||
private readonly IIconBrowser iconBrowser;
|
||||
private readonly IIconDownloader iconDownloader;
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly ILogger<IconDownloadView> logger;
|
||||
|
||||
@@ -34,92 +28,41 @@ namespace Daybreak.Views
|
||||
private double progressValue;
|
||||
|
||||
public IconDownloadView(
|
||||
IIconRetriever iconRetriever,
|
||||
IIconBrowser iconBrowser,
|
||||
IIconDownloader iconDownloader,
|
||||
IViewManager viewManager,
|
||||
ILogger<IconDownloadView> logger)
|
||||
{
|
||||
this.iconRetriever = iconRetriever.ThrowIfNull();
|
||||
this.iconBrowser = iconBrowser.ThrowIfNull();
|
||||
this.iconDownloader = iconDownloader.ThrowIfNull();
|
||||
this.viewManager = viewManager.ThrowIfNull();
|
||||
this.logger = logger.ThrowIfNull();
|
||||
this.InitializeComponent();
|
||||
this.Description = "Verifying icons";
|
||||
}
|
||||
|
||||
private async void IconDownloadView_Loaded(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
await this.WebView.WebBrowser.EnsureCoreWebView2Async();
|
||||
this.DownloadSkills();
|
||||
}
|
||||
|
||||
private void IconDownloadView_Unloaded(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
this.cancellationTokenSource.Cancel();
|
||||
}
|
||||
|
||||
private void OpaqueButton_Clicked(object sender, System.EventArgs e)
|
||||
private void OpaqueButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<BuildsListView>();
|
||||
}
|
||||
|
||||
private async void DownloadSkills()
|
||||
private async void IconDownloadView_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (CompleteIcons)
|
||||
var iconDownloadStatus = await this.iconDownloader.StartIconDownload().ConfigureAwait(true);
|
||||
if (iconDownloadStatus.CurrentStep is IconDownloadStatus.FinishedIconDownloadStep or
|
||||
IconDownloadStatus.StoppedIconDownloadStep)
|
||||
{
|
||||
this.logger.LogInformation("All icons were detected. Skipping check");
|
||||
this.viewManager.ShowView<BuildsListView>();
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.LogInformation("Beginning icon download");
|
||||
this.iconBrowser.InitializeWebView(this.WebView.WebBrowser, this.cancellationTokenSource.Token);
|
||||
var progressIncrement = 100d / Skill.Skills.Count();
|
||||
var incomplete = false;
|
||||
foreach(var skill in Skill.Skills.OrderBy(s => s.Name))
|
||||
iconDownloadStatus.PropertyChanged += (_, _) =>
|
||||
{
|
||||
if (skill == Skill.NoSkill)
|
||||
this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
this.ProgressValue += progressIncrement;
|
||||
continue;
|
||||
}
|
||||
this.Description = iconDownloadStatus.CurrentStep.Description;
|
||||
this.ProgressValue = iconDownloadStatus.CurrentStep.Progress;
|
||||
});
|
||||
};
|
||||
|
||||
var logger = this.logger.CreateScopedLogger(nameof(this.DownloadSkills), skill.Name);
|
||||
logger.LogInformation("Verifying if icon exists");
|
||||
this.Description = $"Checking [{skill.Name}] icon";
|
||||
if ((await this.iconRetriever.GetIconUri(skill)).ExtractValue() is not null)
|
||||
{
|
||||
logger.LogInformation("Icon exists");
|
||||
this.ProgressValue += progressIncrement;
|
||||
await Task.Delay(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.Description = $"Downloading [{skill.Name}] icon";
|
||||
logger.LogInformation("Downloading icon");
|
||||
var request = new IconRequest { Skill = skill };
|
||||
this.iconBrowser.QueueIconRequest(request);
|
||||
|
||||
while(request.Finished is false)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
|
||||
if (request.IconBase64.IsNullOrWhiteSpace())
|
||||
{
|
||||
logger.LogWarning("Failed to download icon");
|
||||
incomplete = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInformation("Downloaded icon");
|
||||
}
|
||||
|
||||
this.ProgressValue += progressIncrement;
|
||||
}
|
||||
|
||||
CompleteIcons = !incomplete;
|
||||
this.viewManager.ShowView<BuildsListView>();
|
||||
this.Description = iconDownloadStatus.CurrentStep.Description;
|
||||
this.ProgressValue = iconDownloadStatus.CurrentStep.Progress;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,13 +73,13 @@ namespace Daybreak.Views
|
||||
this.InitializeComponent();
|
||||
this.PeriodicallyCheckGameState();
|
||||
this.InitializeBrowsers();
|
||||
this.NavigateToDefaults();
|
||||
}
|
||||
|
||||
private void InitializeBrowsers()
|
||||
private async void InitializeBrowsers()
|
||||
{
|
||||
this.LeftWebBrowser.InitializeBrowser(this.liveOptions, this.buildTemplateManager, this.browserLogger);
|
||||
this.RightWebBrowser.InitializeBrowser(this.liveOptions, this.buildTemplateManager, this.browserLogger);
|
||||
await this.LeftWebBrowser.InitializeBrowser(this.liveOptions, this.buildTemplateManager, this.browserLogger);
|
||||
await this.RightWebBrowser.InitializeBrowser(this.liveOptions, this.buildTemplateManager, this.browserLogger);
|
||||
this.NavigateToDefaults();
|
||||
}
|
||||
|
||||
private void NavigateToDefaults()
|
||||
@@ -91,6 +91,8 @@ namespace Daybreak.Views
|
||||
this.RightBrowserFavoriteAddress = applicationConfiguration.RightBrowserDefault;
|
||||
this.LeftBrowserAddress = applicationConfiguration.LeftBrowserDefault;
|
||||
this.RightBrowserAddress = applicationConfiguration.RightBrowserDefault;
|
||||
this.LeftWebBrowser.WebBrowser.CoreWebView2.Navigate(applicationConfiguration.LeftBrowserDefault);
|
||||
this.RightWebBrowser.WebBrowser.CoreWebView2.Navigate(applicationConfiguration.RightBrowserDefault);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Models.Progress;
|
||||
using Daybreak.Services.Updater;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -51,7 +51,7 @@ namespace Daybreak.Views
|
||||
this.ProgressValue = downloadUpdateStep.Progress * 100;
|
||||
}
|
||||
|
||||
this.Description = this.updateStatus.CurrentStep.Name;
|
||||
this.Description = this.updateStatus.CurrentStep.Description;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$currentVersion,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$lastVersion
|
||||
)
|
||||
|
||||
if ($currentVersion.StartsWith("v")){
|
||||
$currentVersion = $currentVersion.Substring(1)
|
||||
}
|
||||
|
||||
if ($lastVersion.StartsWith("v")){
|
||||
$lastVersion = $lastVersion.Substring(1)
|
||||
}
|
||||
|
||||
$isNewer = $currentVersion.CompareTo($lastVersion) -eq 1
|
||||
if ($isNewer -eq $false){
|
||||
throw "Version is not incremented. Current version " + $currentVersion + ". Last version " + $lastVersion
|
||||
}
|
||||
else{
|
||||
Write-Host "Version has been incremented"
|
||||
}
|
||||
Reference in New Issue
Block a user