mirror of
https://github.com/gwdevhub/Daybreak.git
synced 2026-09-17 13:55:02 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91bac0d50b | ||
|
|
0bf03e0fb5 | ||
|
|
81401178a5 | ||
|
|
882357a8e5 | ||
|
|
abf629c5c6 | ||
|
|
758f9004cd | ||
|
|
f174f8cbb3 | ||
|
|
f2f6bde25d | ||
|
|
85f378b303 | ||
|
|
71ab3fdefb | ||
|
|
2f83d6c860 | ||
|
|
3db4975b48 | ||
|
|
6a6eea5d02 | ||
|
|
8fe9eeb32f |
+134
@@ -0,0 +1,134 @@
|
||||
[*.cs]
|
||||
|
||||
# CA2254: Template should be a static expression
|
||||
dotnet_diagnostic.CA2254.severity = none
|
||||
csharp_indent_labels = one_less_than_current
|
||||
csharp_using_directive_placement = outside_namespace:error
|
||||
csharp_prefer_simple_using_statement = true:error
|
||||
csharp_prefer_braces = true:silent
|
||||
csharp_style_namespace_declarations = block_scoped:silent
|
||||
csharp_style_prefer_method_group_conversion = true:silent
|
||||
csharp_style_expression_bodied_methods = false:silent
|
||||
csharp_style_expression_bodied_constructors = false:silent
|
||||
csharp_style_expression_bodied_operators = false:silent
|
||||
csharp_style_expression_bodied_properties = true:silent
|
||||
csharp_style_expression_bodied_indexers = true:silent
|
||||
csharp_style_expression_bodied_accessors = true:silent
|
||||
csharp_style_expression_bodied_lambdas = true:silent
|
||||
csharp_style_expression_bodied_local_functions = false:silent
|
||||
csharp_indent_braces = false
|
||||
insert_final_newline = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_style_throw_expression = true:suggestion
|
||||
csharp_style_prefer_null_check_over_type_check = true:suggestion
|
||||
csharp_prefer_simple_default_expression = true:suggestion
|
||||
csharp_style_prefer_local_over_anonymous_function = true:error
|
||||
csharp_style_prefer_index_operator = true:suggestion
|
||||
csharp_style_prefer_range_operator = true:suggestion
|
||||
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
|
||||
csharp_style_prefer_tuple_swap = true:suggestion
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
csharp_style_deconstructed_variable_declaration = true:error
|
||||
csharp_style_unused_value_assignment_preference = discard_variable:error
|
||||
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
|
||||
csharp_prefer_static_local_function = true:suggestion
|
||||
csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent
|
||||
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent
|
||||
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:suggestion
|
||||
csharp_style_conditional_delegate_call = true:suggestion
|
||||
csharp_style_prefer_parameter_null_checking = true:suggestion
|
||||
csharp_style_prefer_switch_expression = true:suggestion
|
||||
csharp_style_prefer_pattern_matching = true:silent
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||
csharp_style_prefer_not_pattern = true:suggestion
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
csharp_style_prefer_extended_property_pattern = true:suggestion
|
||||
csharp_style_var_for_built_in_types = false:silent
|
||||
csharp_style_var_when_type_is_apparent = false:silent
|
||||
csharp_style_var_elsewhere = false:silent
|
||||
|
||||
[*.{cs,vb}]
|
||||
#### Naming styles ####
|
||||
|
||||
# Naming rules
|
||||
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.severity = error
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
|
||||
|
||||
dotnet_naming_rule.types_should_be_pascal_case.severity = error
|
||||
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
|
||||
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
|
||||
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = error
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
|
||||
|
||||
# Symbol specifications
|
||||
|
||||
dotnet_naming_symbols.interface.applicable_kinds = interface
|
||||
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.interface.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
|
||||
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.types.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
|
||||
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.non_field_members.required_modifiers =
|
||||
|
||||
# Naming styles
|
||||
|
||||
dotnet_naming_style.begins_with_i.required_prefix = I
|
||||
dotnet_naming_style.begins_with_i.required_suffix =
|
||||
dotnet_naming_style.begins_with_i.word_separator =
|
||||
dotnet_naming_style.begins_with_i.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.pascal_case.required_prefix =
|
||||
dotnet_naming_style.pascal_case.required_suffix =
|
||||
dotnet_naming_style.pascal_case.word_separator =
|
||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.pascal_case.required_prefix =
|
||||
dotnet_naming_style.pascal_case.required_suffix =
|
||||
dotnet_naming_style.pascal_case.word_separator =
|
||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||
tab_width = 4
|
||||
indent_size = 4
|
||||
end_of_line = crlf
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:error
|
||||
dotnet_style_prefer_auto_properties = true:error
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
|
||||
dotnet_style_prefer_conditional_expression_over_return = true:silent
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||
dotnet_style_prefer_compound_assignment = true:suggestion
|
||||
dotnet_style_prefer_simplified_interpolation = true:suggestion
|
||||
dotnet_style_namespace_match_folder = true:suggestion
|
||||
dotnet_style_readonly_field = true:suggestion
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
|
||||
dotnet_style_predefined_type_for_member_access = true:silent
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
|
||||
dotnet_style_allow_multiple_blank_lines_experimental = true:silent
|
||||
dotnet_style_allow_statement_immediately_after_block_experimental = false:suggestion
|
||||
dotnet_code_quality_unused_parameters = all:error
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:suggestion
|
||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggestion
|
||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:suggestion
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
|
||||
dotnet_style_qualification_for_field = true:error
|
||||
dotnet_style_qualification_for_property = true:error
|
||||
dotnet_style_qualification_for_method = true:error
|
||||
dotnet_style_qualification_for_event = true:error
|
||||
dotnet_diagnostic.CA1000.severity = error
|
||||
|
||||
[*.vb]
|
||||
dotnet_diagnostic.CA1047.severity = error
|
||||
@@ -0,0 +1 @@
|
||||
* amacocian@yahoo.com
|
||||
@@ -0,0 +1,16 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
- package-ecosystem: "nuget"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
echo "${{ env.Changelog }}"
|
||||
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v1
|
||||
uses: actions/setup-dotnet@v2
|
||||
with:
|
||||
dotnet-version: '6.x'
|
||||
|
||||
@@ -87,7 +87,7 @@ jobs:
|
||||
shell: pwsh
|
||||
|
||||
- name: Publish release
|
||||
uses: Xotl/cool-github-releases@v1.1.2
|
||||
uses: Xotl/cool-github-releases@v1.1.7
|
||||
with:
|
||||
mode: update
|
||||
tag_name: v${{ env.Version }}
|
||||
|
||||
@@ -31,12 +31,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v1
|
||||
uses: actions/setup-dotnet@v2
|
||||
with:
|
||||
dotnet-version: '6.x'
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "master" ]
|
||||
schedule:
|
||||
- cron: '41 12 * * 6'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'csharp' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v2
|
||||
with:
|
||||
dotnet-version: '6.x'
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
@@ -4,10 +4,13 @@ on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- "Daybreak/**"
|
||||
- "Daybreak.Installer/**"
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
check_version:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -22,7 +25,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
@@ -25,6 +25,11 @@ catch
|
||||
}
|
||||
Console.WriteLine("Deleting package");
|
||||
File.Delete(tempFile);
|
||||
|
||||
Console.WriteLine("Deleting browser caches");
|
||||
Directory.Delete("BrowserData", true);
|
||||
Directory.Delete("Daybreak.exe.WebView2", true);
|
||||
|
||||
Console.WriteLine("Launching application");
|
||||
var process = new Process
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.7.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0-preview-20220707-01" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0-preview-20220726-02" />
|
||||
<PackageReference Include="Moq" Version="4.18.2" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Daybreak.Tests.Services
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
buildTemplateManager = new BuildTemplateManager(new Mock<ILogger<BuildTemplateManager>>().Object);
|
||||
this.buildTemplateManager = new BuildTemplateManager(new Mock<ILogger<BuildTemplateManager>>().Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
||||
+9
-1
@@ -11,6 +11,8 @@ 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\codeql-analysis.yml = .github\workflows\codeql-analysis.yml
|
||||
.github\dependabot.yml = .github\dependabot.yml
|
||||
.github\workflows\version_check.yaml = .github\workflows\version_check.yaml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
@@ -19,8 +21,14 @@ 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
|
||||
Scripts\GetBuildVersion.ps1 = Scripts\GetBuildVersion.ps1
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0E30DDA0-2111-4E6C-851E-01DC34124FC2}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
.github\CODEOWNERS = .github\CODEOWNERS
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Daybreak.Behaviors
|
||||
protected override void OnAttached()
|
||||
{
|
||||
base.OnAttached();
|
||||
this.AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
|
||||
this.AssociatedObject.SelectionChanged += this.AssociatedObject_SelectionChanged;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -48,7 +48,7 @@ namespace Daybreak.Behaviors
|
||||
{
|
||||
base.OnDetaching();
|
||||
this.AssociatedObject.SelectionChanged -=
|
||||
AssociatedObject_SelectionChanged;
|
||||
this.AssociatedObject_SelectionChanged;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ using Daybreak.Services.Options;
|
||||
using Daybreak.Models;
|
||||
using Microsoft.CorrelationVector;
|
||||
using System.Logging;
|
||||
using Daybreak.Services.Updater.PostUpdate;
|
||||
using System.Core.Extensions;
|
||||
using Daybreak.Services.Updater.PostUpdate.Actions;
|
||||
|
||||
namespace Daybreak.Configuration
|
||||
{
|
||||
@@ -30,7 +33,7 @@ namespace Daybreak.Configuration
|
||||
{
|
||||
public static void RegisterResolvers(IServiceManager serviceManager)
|
||||
{
|
||||
serviceManager.ThrowIfNull(nameof(serviceManager));
|
||||
serviceManager.ThrowIfNull();
|
||||
|
||||
serviceManager.RegisterHttpFactory((serviceProvider, categoryType) =>
|
||||
{
|
||||
@@ -44,7 +47,7 @@ namespace Daybreak.Configuration
|
||||
|
||||
public static void RegisterServices(IServiceProducer serviceProducer)
|
||||
{
|
||||
serviceProducer.ThrowIfNull(nameof(serviceProducer));
|
||||
serviceProducer.ThrowIfNull();
|
||||
|
||||
serviceProducer.RegisterSingleton<ILogsManager, JsonLogsManager>();
|
||||
serviceProducer.RegisterSingleton<IDebugLogsWriter, Services.Logging.DebugLogsWriter>();
|
||||
@@ -60,6 +63,7 @@ namespace Daybreak.Configuration
|
||||
|
||||
serviceProducer.RegisterScoped((sp) => new ScopeMetadata(new CorrelationVector()));
|
||||
serviceProducer.RegisterSingleton<ViewManager>(registerAllInterfaces: true);
|
||||
serviceProducer.RegisterSingleton<PostUpdateActionManager>(registerAllInterfaces: true);
|
||||
serviceProducer.RegisterSingleton<IConfigurationManager, ConfigurationManager>();
|
||||
serviceProducer.RegisterSingleton<ILiteDatabase, LiteDatabase>(sp => new LiteDatabase("Daybreak.db"));
|
||||
serviceProducer.RegisterSingleton<IMutexHandler, MutexHandler>();
|
||||
@@ -79,7 +83,7 @@ namespace Daybreak.Configuration
|
||||
|
||||
public static void RegisterViews(IViewProducer viewProducer)
|
||||
{
|
||||
viewProducer.ThrowIfNull(nameof(viewProducer));
|
||||
viewProducer.ThrowIfNull();
|
||||
|
||||
viewProducer.RegisterView<MainView>();
|
||||
viewProducer.RegisterView<SettingsView>();
|
||||
@@ -97,5 +101,12 @@ namespace Daybreak.Configuration
|
||||
viewProducer.RegisterView<LogsView>();
|
||||
viewProducer.RegisterView<IconDownloadView>();
|
||||
}
|
||||
|
||||
public static void RegisterPostUpdateActions(IPostUpdateActionProducer postUpdateActionProducer)
|
||||
{
|
||||
postUpdateActionProducer.ThrowIfNull();
|
||||
|
||||
postUpdateActionProducer.AddPostUpdateAction<RenameInstallerAction>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Daybreak.Controls
|
||||
|
||||
public AddButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Daybreak.Controls
|
||||
|
||||
public BackButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Daybreak.Controls
|
||||
public event EventHandler Clicked;
|
||||
public BinButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Daybreak.Controls
|
||||
|
||||
public CancelButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Daybreak.Controls
|
||||
|
||||
public HelpButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
|
||||
@@ -13,17 +13,17 @@ namespace Daybreak.Controls
|
||||
|
||||
public MaximizeButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
BackgroundEllipse.Visibility = System.Windows.Visibility.Visible;
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Visible;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
BackgroundEllipse.Visibility = System.Windows.Visibility.Hidden;
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Hidden;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Daybreak.Controls
|
||||
|
||||
public MinusButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace Daybreak.Controls
|
||||
|
||||
public OpaqueButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void Rectangle_MouseEnter(object sender, MouseEventArgs e)
|
||||
|
||||
@@ -13,17 +13,17 @@ namespace Daybreak.Controls
|
||||
|
||||
public SaveButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
BackgroundEllipse.Visibility = System.Windows.Visibility.Visible;
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Visible;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
BackgroundEllipse.Visibility = System.Windows.Visibility.Hidden;
|
||||
this.BackgroundEllipse.Visibility = System.Windows.Visibility.Hidden;
|
||||
}
|
||||
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<ContentPresenter x:Name="Content" Margin="5"
|
||||
Content="{Binding ElementName=_this, Path=InnerContent}"></ContentPresenter>
|
||||
<ContentPresenter Margin="5"
|
||||
Content="{Binding ElementName=_this, Path=InnerContent}"></ContentPresenter>
|
||||
<Border BorderBrush="{Binding ElementName=_this, Path=BorderBrush}"
|
||||
BorderThickness="{Binding ElementName=_this, Path=BorderThickness}"
|
||||
Opacity="{Binding ElementName=_this, Path=Highlighted, Converter={StaticResource HighlightConverter}}"
|
||||
|
||||
@@ -44,8 +44,8 @@ namespace Daybreak.Controls
|
||||
private bool canNavigate;
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool controlsEnabled;
|
||||
[GenerateDependencyProperty]
|
||||
private bool browserSupported;
|
||||
[GenerateDependencyProperty(InitialValue = null)]
|
||||
private bool? browserSupported;
|
||||
[GenerateDependencyProperty]
|
||||
private bool addressBarReadonly;
|
||||
[GenerateDependencyProperty]
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Daybreak.Controls
|
||||
{
|
||||
public CircularLoadingWidget()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Daybreak.Controls
|
||||
{
|
||||
public AvatarGlyph()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Daybreak.Controls
|
||||
{
|
||||
public ExperimentGlyph()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Daybreak.Controls
|
||||
{
|
||||
public FileGlyph()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Daybreak.Controls
|
||||
{
|
||||
public FireballGlyph()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Daybreak.Controls
|
||||
{
|
||||
public GoldenArrowGlyph()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Daybreak.Controls
|
||||
{
|
||||
public LogsGlyph()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Daybreak.Controls
|
||||
|
||||
public StarGlyph()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Daybreak.Controls
|
||||
|
||||
public ImageViewer()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
this.Image1.Visibility = Visibility.Visible;
|
||||
this.Image1.Opacity = 1;
|
||||
this.Image2.Visibility = Visibility.Hidden;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<UserControl x:Class="Daybreak.Controls.SearchTextBox"
|
||||
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:local="clr-namespace:Daybreak.Controls"
|
||||
x:Name="_this"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"></BooleanToVisibilityConverter>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<TextBox Foreground="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=Foreground, Mode=OneWay}"
|
||||
FontSize="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontSize, Mode=OneWay}"
|
||||
FontFamily="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontFamily, Mode=OneWay}"
|
||||
FontStretch="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontStretch, Mode=OneWay}"
|
||||
FontWeight="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontWeight, Mode=OneWay}"
|
||||
FontStyle="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontStyle, Mode=OneWay}"
|
||||
TextChanged="TextBox_TextChanged"
|
||||
Background="Transparent"/>
|
||||
<TextBlock Margin="5, 0, 0, 0"
|
||||
Text="Search"
|
||||
Background="Transparent"
|
||||
Opacity="0.5"
|
||||
IsHitTestVisible="False"
|
||||
FontSize="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontSize, Mode=OneWay}"
|
||||
FontFamily="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontFamily, Mode=OneWay}"
|
||||
FontStretch="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontStretch, Mode=OneWay}"
|
||||
FontWeight="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontWeight, Mode=OneWay}"
|
||||
FontStyle="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=FontStyle, Mode=OneWay}"
|
||||
Foreground="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=Foreground, Mode=OneWay}"
|
||||
Visibility="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=PlaceholderVisibility, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Extensions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for SearchTextBox.xaml
|
||||
/// </summary>
|
||||
public partial class SearchTextBox : UserControl
|
||||
{
|
||||
public event EventHandler<string> TextChanged;
|
||||
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool placeholderVisibility;
|
||||
[GenerateDependencyProperty]
|
||||
private string searchText;
|
||||
|
||||
public SearchTextBox()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
var searchText = e.Source.As<TextBox>().Text;
|
||||
if (searchText.IsNullOrWhiteSpace())
|
||||
{
|
||||
this.PlaceholderVisibility = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.PlaceholderVisibility = false;
|
||||
}
|
||||
|
||||
this.SearchText = searchText;
|
||||
this.TextChanged?.Invoke(this, searchText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ namespace Daybreak.Controls
|
||||
public AccountTemplate()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += AccountTemplate_DataContextChanged;
|
||||
this.DataContextChanged += this.AccountTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
private void AccountTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Daybreak.Controls
|
||||
public AttributeTemplate()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += AttributeTemplate_DataContextChanged;
|
||||
this.DataContextChanged += this.AttributeTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
private void AttributeTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Daybreak.Controls
|
||||
|
||||
public BuildEntryTemplate()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void BinButton_Clicked(object sender, EventArgs e)
|
||||
|
||||
@@ -157,14 +157,36 @@
|
||||
<local:ChromiumBrowserWrapper x:Name="SkillBrowser" ControlsEnabled="False" Width="0" AddressBarReadonly="True" CanNavigate="True"></local:ChromiumBrowserWrapper>
|
||||
</Grid>
|
||||
<Grid Grid.Column="1" Grid.RowSpan="6">
|
||||
<ListView x:Name="SkillsListView" Background="Transparent" Width="0"
|
||||
ItemsSource="{Binding ElementName=_this, Path=AvailableSkills, Mode=OneWay}" MouseDoubleClick="ListView_MouseDoubleClick">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock FontSize="16" Foreground="White" TextWrapping="Wrap" Text="{Binding Name}"></TextBlock>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
<Grid x:Name="SkillListContainer">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<local:SearchTextBox FontSize="20"
|
||||
Foreground="White"
|
||||
Background="Transparent"
|
||||
SearchText="{Binding ElementName=_this, Path=SkillSearchText, Mode=TwoWay}"
|
||||
TextChanged="SearchTextBox_TextChanged"></local:SearchTextBox>
|
||||
<ListView x:Name="SkillsListView"
|
||||
Grid.Row="1"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Hidden"
|
||||
Background="Transparent"
|
||||
ItemsSource="{Binding ElementName=_this, Path=AvailableSkills, Mode=OneWay}"
|
||||
MouseDoubleClick="ListView_MouseDoubleClick">
|
||||
<ListView.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel>
|
||||
</VirtualizingStackPanel>
|
||||
</ItemsPanelTemplate>
|
||||
</ListView.ItemsPanel>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock FontSize="16" Foreground="White" TextWrapping="Wrap" Text="{Binding Name}"></TextBlock>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -11,9 +11,11 @@ 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;
|
||||
using Utils;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
{
|
||||
@@ -36,6 +38,8 @@ namespace Daybreak.Controls
|
||||
|
||||
public event EventHandler BuildChanged;
|
||||
|
||||
[GenerateDependencyProperty]
|
||||
private string skillSearchText;
|
||||
[GenerateDependencyProperty]
|
||||
private Profession primaryProfession;
|
||||
[GenerateDependencyProperty]
|
||||
@@ -84,6 +88,9 @@ namespace Daybreak.Controls
|
||||
this.SkillTemplate5.InitializeSkillTemplate(iconRetriever);
|
||||
this.SkillTemplate6.InitializeSkillTemplate(iconRetriever);
|
||||
this.SkillTemplate7.InitializeSkillTemplate(iconRetriever);
|
||||
|
||||
this.HideSkillListView();
|
||||
this.HideInfoBrowser();
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
@@ -202,14 +209,8 @@ namespace Daybreak.Controls
|
||||
this.loadedBuild.Build.Attributes = this.Attributes.ToList();
|
||||
}
|
||||
|
||||
private void LoadSkills()
|
||||
private async void LoadSkills()
|
||||
{
|
||||
var possibleSkills = Skill.Skills
|
||||
.Where(s => s.Profession == this.PrimaryProfession || s.Profession == this.SecondaryProfession || s.Profession == Profession.None)
|
||||
.Where(s => s != Skill.NoSkill)
|
||||
.OrderBy(s => s.Name);
|
||||
this.AvailableSkills.ClearAnd().AddRange(possibleSkills);
|
||||
|
||||
if (this.Skill0.Profession != this.PrimaryProfession &&
|
||||
this.Skill0.Profession != this.SecondaryProfession &&
|
||||
this.Skill0.Profession != Profession.None)
|
||||
@@ -265,8 +266,12 @@ namespace Daybreak.Controls
|
||||
{
|
||||
this.Skill7 = Skill.NoSkill;
|
||||
}
|
||||
|
||||
var filteredSkills = await this.FilterSkills(this.SkillSearchText).ToListAsync().ConfigureAwait(true);
|
||||
this.AvailableSkills.ClearAnd().AddRange(filteredSkills);
|
||||
}
|
||||
|
||||
|
||||
private void LoadBuild()
|
||||
{
|
||||
this.suppressBuildChanged = true;
|
||||
@@ -297,7 +302,7 @@ namespace Daybreak.Controls
|
||||
if (this.SkillBrowser.BrowserSupported is true)
|
||||
{
|
||||
this.SkillBrowser.Width = 400;
|
||||
this.SkillsListView.Width = 0;
|
||||
this.SkillListContainer.Width = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,12 +317,12 @@ namespace Daybreak.Controls
|
||||
private void ShowSkillListView()
|
||||
{
|
||||
this.SkillBrowser.Width = 0;
|
||||
this.SkillsListView.Width = 400;
|
||||
this.SkillListContainer.Width = 400;
|
||||
}
|
||||
|
||||
private void HideSkillListView()
|
||||
{
|
||||
this.SkillsListView.Width = 0;
|
||||
this.SkillListContainer.Width = 0;
|
||||
}
|
||||
|
||||
private void HelpButtonPrimary_Clicked(object sender, System.EventArgs e)
|
||||
@@ -348,13 +353,14 @@ namespace Daybreak.Controls
|
||||
}
|
||||
}
|
||||
|
||||
private void AttributeTemplate_HelpClicked(object sender, AttributeEntry e)
|
||||
private void AttributeTemplate_HelpClicked(object _, AttributeEntry e)
|
||||
{
|
||||
this.BrowseToInfo(e.Attribute.Name);
|
||||
}
|
||||
|
||||
private void AttributeTemplate_AttributeChanged(object sender, AttributeEntry e)
|
||||
private void AttributeTemplate_AttributeChanged(object _, AttributeEntry e)
|
||||
{
|
||||
e.ThrowIfNull();
|
||||
this.BuildChanged?.Invoke(this, new EventArgs());
|
||||
}
|
||||
|
||||
@@ -363,6 +369,7 @@ namespace Daybreak.Controls
|
||||
var skill = sender.As<SkillTemplate>().DataContext.As<Skill>();
|
||||
if (skill == Skill.NoSkill)
|
||||
{
|
||||
this.SkillSearchText = string.Empty;
|
||||
this.ShowSkillListView();
|
||||
this.selectingSkillTemplate = sender.As<SkillTemplate>();
|
||||
}
|
||||
@@ -374,6 +381,12 @@ namespace Daybreak.Controls
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void SearchTextBox_TextChanged(object _, string e)
|
||||
{
|
||||
e.ThrowIfNull();
|
||||
this.LoadSkills();
|
||||
}
|
||||
|
||||
private void SkillTemplate_RemoveClicked(object sender, System.EventArgs e)
|
||||
{
|
||||
sender.As<SkillTemplate>().DataContext = Skill.NoSkill;
|
||||
@@ -415,5 +428,50 @@ namespace Daybreak.Controls
|
||||
sender.As<ListView>().Items.Count;
|
||||
}
|
||||
}
|
||||
|
||||
private void ScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
|
||||
{
|
||||
if (sender is not ScrollViewer scrollViewer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - e.Delta);
|
||||
}
|
||||
|
||||
private async IAsyncEnumerable<Skill> FilterSkills(string searchTerm)
|
||||
{
|
||||
// Replace symbols to ease search
|
||||
searchTerm = searchTerm?.Replace("\"", "").Replace("!", "");
|
||||
|
||||
foreach (var skill in Skill.Skills)
|
||||
{
|
||||
if (skill == Skill.NoSkill)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skill.Profession != this.PrimaryProfession &&
|
||||
skill.Profession != this.SecondaryProfession &&
|
||||
skill.Profession != Profession.None)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (searchTerm.IsNullOrWhiteSpace())
|
||||
{
|
||||
yield return skill;
|
||||
continue;
|
||||
}
|
||||
|
||||
var matchesName = await Task.Run(() => StringUtils.MatchesSearchString(skill.Name.Replace("\"", "").Replace("!", ""), searchTerm));
|
||||
if (matchesName)
|
||||
{
|
||||
yield return skill;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Daybreak.Controls
|
||||
public GuildwarsPathTemplate()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += GuildwarsPathTemplate_DataContextChanged;
|
||||
this.DataContextChanged += this.GuildwarsPathTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
private void GuildwarsPathTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Daybreak.Controls.Templates
|
||||
public ScreenTemplate()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += ScreenTemplate_DataContextChanged;
|
||||
this.DataContextChanged += this.ScreenTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Daybreak.Controls
|
||||
public SkillTemplate()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.DataContextChanged += SkillTemplate_DataContextChanged;
|
||||
this.DataContextChanged += this.SkillTemplate_DataContextChanged;
|
||||
}
|
||||
|
||||
public void InitializeSkillTemplate(IIconCache iconRetriever)
|
||||
|
||||
@@ -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 ((objValue && TriggerValue && IsHidden) || (!objValue && !TriggerValue && IsHidden))
|
||||
if (value is not bool)
|
||||
{
|
||||
return this.IsHidden ?
|
||||
Visibility.Hidden :
|
||||
Visibility.Collapsed;
|
||||
}
|
||||
|
||||
var objValue = value.Cast<bool>();
|
||||
if ((objValue && this.TriggerValue && this.IsHidden) || (!objValue && !this.TriggerValue && this.IsHidden))
|
||||
{
|
||||
return Visibility.Hidden;
|
||||
}
|
||||
if ((objValue && TriggerValue && !IsHidden) || (!objValue && !TriggerValue && !IsHidden))
|
||||
|
||||
if ((objValue && this.TriggerValue && !this.IsHidden) || (!objValue && !this.TriggerValue && !this.IsHidden))
|
||||
{
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
|
||||
return Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Daybreak.Converters
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return GetVerticalAlignment(value);
|
||||
return this.GetVerticalAlignment(value);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
|
||||
@@ -10,20 +10,26 @@
|
||||
<LangVersion>preview</LangVersion>
|
||||
<ApplicationIcon>Daybreak.ico</ApplicationIcon>
|
||||
<IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation>
|
||||
<Version>0.9.3.6</Version>
|
||||
<Version>0.9.5.2</Version>
|
||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\.editorconfig" Link=".editorconfig" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LiteDB" Version="5.0.12" />
|
||||
<PackageReference Include="Microsoft.CorrelationVector" Version="1.0.42" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.1264.42" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.1293.44" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="NReco.Logging.File" Version="1.1.5" />
|
||||
<PackageReference Include="securifybv.ShellLink" Version="0.1.0" />
|
||||
<PackageReference Include="Slim" Version="1.7.3" />
|
||||
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||
<PackageReference Include="SystemExtensions.NetCore" Version="1.0.1" />
|
||||
<PackageReference Include="SystemExtensions.NetStandard" Version="1.5.0" />
|
||||
<PackageReference Include="WCL" Version="1.0.2" />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Exceptions;
|
||||
using Daybreak.Services.Updater.PostUpdate;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Slim;
|
||||
@@ -31,8 +32,9 @@ namespace Daybreak.Launch
|
||||
protected override void RegisterServices(IServiceProducer serviceProducer)
|
||||
{
|
||||
ProjectConfiguration.RegisterServices(this.ServiceManager);
|
||||
ServiceManager.BuildSingletons();
|
||||
this.ServiceManager.BuildSingletons();
|
||||
ProjectConfiguration.RegisterViews(this.ServiceManager.GetService<IViewManager>());
|
||||
ProjectConfiguration.RegisterPostUpdateActions(this.ServiceManager.GetService<IPostUpdateActionProducer>());
|
||||
}
|
||||
protected override bool HandleException(Exception e)
|
||||
{
|
||||
|
||||
@@ -104,8 +104,8 @@
|
||||
</Grid>
|
||||
<wcl:Border OnResize="Border_OnResize" Grid.RowSpan="2" Active="True"></wcl:Border>
|
||||
<webview:WebView2 x:Name="BackgroundWebView"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Visibility="Collapsed"
|
||||
Grid.Row="1"></webview:WebView2>
|
||||
</Grid>
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Daybreak.Models.Builds
|
||||
set
|
||||
{
|
||||
this.attribute = value;
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Attribute)));
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Attribute)));
|
||||
}
|
||||
}
|
||||
public int Points
|
||||
@@ -22,7 +22,7 @@ namespace Daybreak.Models.Builds
|
||||
set
|
||||
{
|
||||
this.points = value;
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Points)));
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Points)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Daybreak.Models.Builds
|
||||
set
|
||||
{
|
||||
this.name = value;
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Name)));
|
||||
}
|
||||
}
|
||||
public Build Build
|
||||
@@ -24,7 +24,7 @@ namespace Daybreak.Models.Builds
|
||||
set
|
||||
{
|
||||
this.build = value;
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Build)));
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Build)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2978,7 +2978,7 @@ namespace Daybreak.Models.Builds
|
||||
WeaponsofThreeForges,
|
||||
VowofRevolution,
|
||||
HeroicRefrain,
|
||||
};
|
||||
}.OrderBy(s => s.Name).ToList();
|
||||
|
||||
public static bool TryParse(int id, out Skill skill)
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Daybreak.Models
|
||||
/// <summary>
|
||||
/// The VirtualCode converted to typeof(Keys) for higher usability.
|
||||
/// </summary>
|
||||
public Keys Key { get { return (Keys)VirtualCode; } }
|
||||
public Keys Key { get { return (Keys)this.VirtualCode; } }
|
||||
|
||||
/// <summary>
|
||||
/// A hardware scan code for the key.
|
||||
|
||||
@@ -17,11 +17,11 @@ namespace Daybreak.Models.Progress
|
||||
|
||||
public IconDownloadStep CurrentStep
|
||||
{
|
||||
get => currentStep;
|
||||
get => this.currentStep;
|
||||
set
|
||||
{
|
||||
currentStep = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentStep)));
|
||||
this.currentStep = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.CurrentStep)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@ namespace Daybreak.Models.Progress
|
||||
|
||||
public UpdateStep CurrentStep
|
||||
{
|
||||
get => currentStep;
|
||||
get => this.currentStep;
|
||||
set
|
||||
{
|
||||
currentStep = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentStep)));
|
||||
this.currentStep = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.CurrentStep)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Daybreak.Models.Progress
|
||||
{
|
||||
internal DownloadUpdateStep(string name, double progress) : base(name)
|
||||
{
|
||||
Progress = progress;
|
||||
this.Progress = progress;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,33 +16,33 @@ namespace Daybreak.Models
|
||||
|
||||
private byte[] DecryptedValue
|
||||
{
|
||||
get => this.encryptedBytes.DecryptBytes(key);
|
||||
set => this.encryptedBytes = value.EncryptBytes(key);
|
||||
get => this.encryptedBytes.DecryptBytes(this.key);
|
||||
set => this.encryptedBytes = value.EncryptBytes(this.key);
|
||||
}
|
||||
[JsonProperty("value")]
|
||||
public string Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.encryptedBytes.DecryptBytes(key).AsString();
|
||||
return this.encryptedBytes.DecryptBytes(this.key).AsString();
|
||||
}
|
||||
set
|
||||
{
|
||||
this.encryptedBytes = value.AsBytes().EncryptBytes(key);
|
||||
this.encryptedBytes = value.AsBytes().EncryptBytes(this.key);
|
||||
}
|
||||
}
|
||||
private SecureString(byte[] value)
|
||||
{
|
||||
this.key = new byte[32];
|
||||
using var crypto = RandomNumberGenerator.Create();
|
||||
crypto.GetBytes(key);
|
||||
crypto.GetBytes(this.key);
|
||||
this.DecryptedValue = value;
|
||||
}
|
||||
public SecureString(string value)
|
||||
{
|
||||
this.key = new byte[32];
|
||||
using var crypto = RandomNumberGenerator.Create();
|
||||
crypto.GetBytes(key);
|
||||
crypto.GetBytes(this.key);
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,10 +30,10 @@ namespace Daybreak.Models.Versioning
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var version = string.Join('.', parts.OfType<VersionNumberToken>());
|
||||
if (parts.Last() is VersionStringToken)
|
||||
var version = string.Join('.', this.parts.OfType<VersionNumberToken>());
|
||||
if (this.parts.Last() is VersionStringToken)
|
||||
{
|
||||
version += "-" + parts.Last();
|
||||
version += "-" + this.parts.Last();
|
||||
}
|
||||
|
||||
if (this.HasPrefix)
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Daybreak.Services.Bloogum
|
||||
this.logger.LogInformation($"Retrieving image from {BaseAddress}/{url}");
|
||||
try
|
||||
{
|
||||
var response = await httpClient.GetAsync($"{BaseAddress}/{url}").ConfigureAwait(false);
|
||||
var response = await this.httpClient.GetAsync($"{BaseAddress}/{url}").ConfigureAwait(false);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
this.logger.LogInformation("Received success status code");
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Extensions;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Daybreak.Services.BuildTemplates
|
||||
{
|
||||
@@ -41,16 +42,7 @@ namespace Daybreak.Services.BuildTemplates
|
||||
public BuildEntry CreateBuild()
|
||||
{
|
||||
var emptyBuild = new Build();
|
||||
var builds = GetBuilds();
|
||||
var baseName = "New build";
|
||||
var name = baseName;
|
||||
int count = 0;
|
||||
while(builds.Where(b => b.Name.Equals(name, StringComparison.OrdinalIgnoreCase)).Any())
|
||||
{
|
||||
name = baseName + count;
|
||||
count++;
|
||||
}
|
||||
|
||||
var name = Guid.NewGuid().ToString();
|
||||
var entry = new BuildEntry { Build = emptyBuild, Name = name, PreviousName = string.Empty };
|
||||
this.SaveBuild(entry);
|
||||
return entry;
|
||||
@@ -88,19 +80,18 @@ namespace Daybreak.Services.BuildTemplates
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<BuildEntry> GetBuilds()
|
||||
public async IAsyncEnumerable<BuildEntry> GetBuilds()
|
||||
{
|
||||
foreach (var file in Directory.GetFiles(BuildsPath))
|
||||
{
|
||||
Build build = default;
|
||||
try
|
||||
{
|
||||
build = this.DecodeTemplate(File.ReadAllText(file));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
this.logger.LogError($"Failed to decode template from file {file}. Details: {e}");
|
||||
}
|
||||
var maybeBuild = this.DecodeTemplateInner(await File.ReadAllTextAsync(file));
|
||||
var build = maybeBuild.Switch(
|
||||
onSuccess: build => build,
|
||||
onFailure: exception =>
|
||||
{
|
||||
this.logger.LogError(exception, "Failed to parse build");
|
||||
return default;
|
||||
});
|
||||
|
||||
if (build is not null)
|
||||
{
|
||||
@@ -111,7 +102,21 @@ namespace Daybreak.Services.BuildTemplates
|
||||
|
||||
public Build DecodeTemplate(string template)
|
||||
{
|
||||
return this.DecodeTemplateInner(template);
|
||||
var maybeTemplate = this.DecodeTemplateInner(template);
|
||||
return maybeTemplate.Switch(
|
||||
onSuccess: build => build,
|
||||
onFailure: exception => throw exception);
|
||||
}
|
||||
|
||||
public bool TryDecodeTemplate(string template, out Build build)
|
||||
{
|
||||
var maybeBuild = this.DecodeTemplateInner(template);
|
||||
(var result, var parsedBuild) = maybeBuild.Switch(
|
||||
onSuccess: parsedBuild => (true, parsedBuild),
|
||||
onFailure: _ => (false, null));
|
||||
|
||||
build = parsedBuild;
|
||||
return result;
|
||||
}
|
||||
|
||||
public string EncodeTemplate(Build build)
|
||||
@@ -119,7 +124,7 @@ namespace Daybreak.Services.BuildTemplates
|
||||
return this.EncodeTemplateInner(build);
|
||||
}
|
||||
|
||||
private Build DecodeTemplateInner(string template)
|
||||
private Result<Build, Exception> DecodeTemplateInner(string template)
|
||||
{
|
||||
this.logger.LogInformation("Attempting to decode template");
|
||||
var buildMetadata = ParseEncodedTemplate(template);
|
||||
@@ -127,7 +132,7 @@ namespace Daybreak.Services.BuildTemplates
|
||||
if (buildMetadata.VersionNumber != 0)
|
||||
{
|
||||
this.logger.LogError($"Expected version number to be 0 but found {buildMetadata.VersionNumber}");
|
||||
throw new InvalidOperationException($"Failed to parse template");
|
||||
return new InvalidOperationException($"Failed to parse template");
|
||||
}
|
||||
|
||||
var build = new Build()
|
||||
@@ -139,14 +144,14 @@ namespace Daybreak.Services.BuildTemplates
|
||||
if (Profession.TryParse(buildMetadata.PrimaryProfessionId, out var primaryProfession) is false)
|
||||
{
|
||||
this.logger.LogError($"Failed to parse profession with id {buildMetadata.PrimaryProfessionId}");
|
||||
throw new InvalidOperationException($"Failed to parse template");
|
||||
return new InvalidOperationException($"Failed to parse template");
|
||||
}
|
||||
|
||||
build.Primary = primaryProfession;
|
||||
if (Profession.TryParse(buildMetadata.SecondaryProfessionId, out var secondaryProfession) is false)
|
||||
{
|
||||
this.logger.LogError($"Failed to parse profession with id {buildMetadata.SecondaryProfessionId}");
|
||||
throw new InvalidOperationException($"Failed to parse template");
|
||||
return new InvalidOperationException($"Failed to parse template");
|
||||
}
|
||||
|
||||
build.Secondary = secondaryProfession;
|
||||
@@ -155,7 +160,7 @@ namespace Daybreak.Services.BuildTemplates
|
||||
if (Daybreak.Models.Builds.Attribute.TryParse(buildMetadata.AttributesIds[i], out var attribute) is false)
|
||||
{
|
||||
this.logger.LogError($"Failed to parse attribute with id {buildMetadata.AttributesIds[i]}");
|
||||
throw new InvalidOperationException($"Failed to parse template");
|
||||
return new InvalidOperationException($"Failed to parse template");
|
||||
}
|
||||
|
||||
build.Attributes.Add(new AttributeEntry { Attribute = attribute, Points = buildMetadata.AttributePoints[i] });
|
||||
@@ -166,7 +171,7 @@ namespace Daybreak.Services.BuildTemplates
|
||||
if (Skill.TryParse(buildMetadata.SkillIds[i], out var skill) is false)
|
||||
{
|
||||
this.logger.LogError($"Failed to parse skill with id {buildMetadata.SkillIds[i]}");
|
||||
throw new InvalidOperationException($"Failed to parse template");
|
||||
return new InvalidOperationException($"Failed to parse template");
|
||||
}
|
||||
|
||||
build.Skills.Add(skill);
|
||||
|
||||
@@ -10,8 +10,9 @@ namespace Daybreak.Services.BuildTemplates
|
||||
BuildEntry CreateBuild(string name);
|
||||
void SaveBuild(BuildEntry buildEntry);
|
||||
void RemoveBuild(BuildEntry buildEntry);
|
||||
IEnumerable<BuildEntry> GetBuilds();
|
||||
IAsyncEnumerable<BuildEntry> GetBuilds();
|
||||
Build DecodeTemplate(string template);
|
||||
bool TryDecodeTemplate(string template, out Build build);
|
||||
string EncodeTemplate(Build build);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Daybreak.Services.BuildTemplates.Models
|
||||
|
||||
public string GetEncodedString()
|
||||
{
|
||||
return innerStringBuilder.ToString();
|
||||
return this.innerStringBuilder.ToString();
|
||||
}
|
||||
|
||||
private void EncodeToBinary(int value, int count)
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace Daybreak.Services.IconRetrieve
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
||||
this.logger.LogError(e, "Encountered error when initializing browser");
|
||||
}
|
||||
|
||||
var curedSkillName = request.Skill.AlternativeName.IsNullOrWhiteSpace() ?
|
||||
|
||||
@@ -8,6 +8,7 @@ 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;
|
||||
@@ -77,7 +78,7 @@ namespace Daybreak.Services.IconRetrieve
|
||||
|
||||
this.cancellationTokenSource = new();
|
||||
this.iconDownloadStatus = new IconDownloadStatus();
|
||||
Task.Run(this.DownloadIcons);
|
||||
_ = Task.Run(this.DownloadIcons);
|
||||
return this.iconDownloadStatus;
|
||||
}
|
||||
|
||||
@@ -98,11 +99,40 @@ namespace Daybreak.Services.IconRetrieve
|
||||
return;
|
||||
}
|
||||
|
||||
this.iconBrowser.InitializeWebView(this.browserWrapper, this.cancellationTokenSource.Token);
|
||||
var progressIncrement = 100d / Skill.Skills.Count();
|
||||
var incomplete = false;
|
||||
var progressValue = 0d;
|
||||
foreach (var skill in Skill.Skills.OrderBy(s => s.Name))
|
||||
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)
|
||||
{
|
||||
@@ -116,17 +146,7 @@ namespace Daybreak.Services.IconRetrieve
|
||||
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)
|
||||
{
|
||||
logger.LogInformation("Icon exists");
|
||||
progressValue += progressIncrement;
|
||||
continue;
|
||||
}
|
||||
|
||||
logger.LogInformation("Downloading icon");
|
||||
this.logger.LogInformation("Downloading icon");
|
||||
this.iconDownloadStatus.CurrentStep = IconDownloadStatus.Downloading(skill.Name, progressValue);
|
||||
var request = new IconRequest { Skill = skill };
|
||||
this.iconBrowser.QueueIconRequest(request);
|
||||
@@ -138,12 +158,12 @@ namespace Daybreak.Services.IconRetrieve
|
||||
|
||||
if (request.IconBase64.IsNullOrWhiteSpace())
|
||||
{
|
||||
logger.LogWarning("Failed to download icon");
|
||||
this.logger.LogWarning("Failed to download icon");
|
||||
incomplete = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInformation("Downloaded icon");
|
||||
this.logger.LogInformation("Downloaded icon");
|
||||
}
|
||||
|
||||
progressValue += progressIncrement;
|
||||
@@ -156,6 +176,12 @@ namespace Daybreak.Services.IconRetrieve
|
||||
}
|
||||
else
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
this.browserWrapper.IsEnabled = false;
|
||||
this.browserWrapper.Dispose();
|
||||
});
|
||||
this.iconDownloadStatus.CurrentStep = IconDownloadStatus.Finished;
|
||||
this.DownloadComplete = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace Daybreak.Services.KeyboardHook
|
||||
}
|
||||
|
||||
this.windowsHookHandle = IntPtr.Zero;
|
||||
this.hookProc -= LowLevelKeyboardProc;
|
||||
this.hookProc -= this.LowLevelKeyboardProc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,12 +104,12 @@ namespace Daybreak.Services.KeyboardHook
|
||||
|
||||
~KeyboardHookService()
|
||||
{
|
||||
Dispose(false);
|
||||
this.Dispose(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
this.Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Daybreak.Exceptions;
|
||||
using Daybreak.Models.Github;
|
||||
using Daybreak.Models.Progress;
|
||||
using Daybreak.Services.Updater.PostUpdate;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Views;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -9,6 +10,7 @@ using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Core.Extensions;
|
||||
using System.Diagnostics;
|
||||
using System.Extensions;
|
||||
using System.IO;
|
||||
@@ -24,6 +26,7 @@ namespace Daybreak.Services.Updater
|
||||
{
|
||||
public sealed class ApplicationUpdater : IApplicationUpdater
|
||||
{
|
||||
private const string TemporaryInstallerFileName = "Daybreak.Installer.Temp.exe";
|
||||
private const string InstallerFileName = "Daybreak.Installer.exe";
|
||||
private const string UpdatedKey = "Updating";
|
||||
private const string RegistryKey = "Daybreak";
|
||||
@@ -35,24 +38,29 @@ namespace Daybreak.Services.Updater
|
||||
private const string DownloadUrl = $"https://github.com/AlexMacocian/Daybreak/releases/download/{VersionTag}/Daybreak{VersionTag}.zip";
|
||||
|
||||
private readonly CancellationTokenSource updateCancellationTokenSource = new();
|
||||
private readonly ILogger<ApplicationUpdater> logger;
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly IPostUpdateActionProvider postUpdateActionProvider;
|
||||
private readonly ILiveOptions<ApplicationConfiguration> liveOptions;
|
||||
private readonly IHttpClient<ApplicationUpdater> httpClient;
|
||||
private readonly ILogger<ApplicationUpdater> logger;
|
||||
|
||||
public Version CurrentVersion { get; }
|
||||
|
||||
public ApplicationUpdater(
|
||||
ILogger<ApplicationUpdater> logger,
|
||||
ILiveOptions<ApplicationConfiguration> liveOptions,
|
||||
IViewManager viewManager,
|
||||
IHttpClient<ApplicationUpdater> httpClient)
|
||||
IPostUpdateActionProvider postUpdateActionProvider,
|
||||
ILiveOptions<ApplicationConfiguration> liveOptions,
|
||||
IHttpClient<ApplicationUpdater> httpClient,
|
||||
ILogger<ApplicationUpdater> logger)
|
||||
{
|
||||
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
|
||||
this.liveOptions = liveOptions.ThrowIfNull(nameof(liveOptions));
|
||||
this.logger = logger.ThrowIfNull(nameof(logger));
|
||||
this.httpClient = httpClient.ThrowIfNull(nameof(httpClient));
|
||||
this.viewManager = viewManager.ThrowIfNull();
|
||||
this.postUpdateActionProvider = postUpdateActionProvider.ThrowIfNull();
|
||||
this.liveOptions = liveOptions.ThrowIfNull();
|
||||
this.httpClient = httpClient.ThrowIfNull();
|
||||
this.logger = logger.ThrowIfNull();
|
||||
|
||||
this.httpClient.DefaultRequestHeaders.Add("user-agent", "Daybreak Client");
|
||||
|
||||
if (Version.TryParse(Assembly.GetExecutingAssembly().GetName().Version.ToString(), out var currentVersion))
|
||||
{
|
||||
if (currentVersion.HasPrefix is false)
|
||||
@@ -178,6 +186,7 @@ namespace Daybreak.Services.Updater
|
||||
if (UpdateMarkedInRegistry())
|
||||
{
|
||||
UnmarkUpdateInRegistry();
|
||||
this.ExecutePostUpdateActions();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,6 +222,18 @@ namespace Daybreak.Services.Updater
|
||||
}
|
||||
}
|
||||
|
||||
private async void ExecutePostUpdateActions()
|
||||
{
|
||||
this.logger.LogInformation("Executing post-update actions");
|
||||
foreach(var action in this.postUpdateActionProvider.GetPostUpdateActions())
|
||||
{
|
||||
this.logger.LogInformation($"Starting [{action.GetType().Name}]");
|
||||
action.DoPostUpdateAction();
|
||||
await action.DoPostUpdateActionAsync();
|
||||
this.logger.LogInformation($"Finished [{action.GetType().Name}]");
|
||||
}
|
||||
}
|
||||
|
||||
private static void MarkUpdateInRegistry()
|
||||
{
|
||||
var homeRegistryKey = GetOrCreateHomeKey();
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Core.Extensions;
|
||||
using System.IO;
|
||||
|
||||
namespace Daybreak.Services.Updater.PostUpdate.Actions
|
||||
{
|
||||
public sealed class RenameInstallerAction : PostUpdateActionBase
|
||||
{
|
||||
private const string TemporaryInstallerFileName = "Daybreak.Installer.Temp.exe";
|
||||
private const string InstallerFileName = "Daybreak.Installer.exe";
|
||||
|
||||
private readonly ILogger<RenameInstallerAction> logger;
|
||||
|
||||
public RenameInstallerAction(
|
||||
ILogger<RenameInstallerAction> logger)
|
||||
{
|
||||
this.logger = logger.ThrowIfNull();
|
||||
}
|
||||
|
||||
public override void DoPostUpdateAction()
|
||||
{
|
||||
if (File.Exists(TemporaryInstallerFileName))
|
||||
{
|
||||
this.logger.LogInformation("Detected new installer version. Overwriting old installer with new one");
|
||||
File.Copy(TemporaryInstallerFileName, InstallerFileName, true);
|
||||
|
||||
this.logger.LogInformation("Deleting new installer temporary file");
|
||||
File.Delete(TemporaryInstallerFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Daybreak.Services.Updater.PostUpdate
|
||||
{
|
||||
public interface IPostUpdateActionManager : IPostUpdateActionProducer, IPostUpdateActionProvider
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Daybreak.Services.Updater.PostUpdate
|
||||
{
|
||||
public interface IPostUpdateActionProducer
|
||||
{
|
||||
void AddPostUpdateAction<T>()
|
||||
where T : PostUpdateActionBase;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Daybreak.Services.Updater.PostUpdate
|
||||
{
|
||||
public interface IPostUpdateActionProvider
|
||||
{
|
||||
IEnumerable<PostUpdateActionBase> GetPostUpdateActions();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Daybreak.Services.Updater.PostUpdate
|
||||
{
|
||||
public abstract class PostUpdateActionBase
|
||||
{
|
||||
public virtual void DoPostUpdateAction()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual Task DoPostUpdateActionAsync()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Slim;
|
||||
using System.Collections.Generic;
|
||||
using System.Core.Extensions;
|
||||
|
||||
namespace Daybreak.Services.Updater.PostUpdate
|
||||
{
|
||||
public sealed class PostUpdateActionManager : IPostUpdateActionManager
|
||||
{
|
||||
private readonly IServiceManager serviceManager;
|
||||
private readonly ILogger<PostUpdateActionManager> logger;
|
||||
|
||||
public PostUpdateActionManager(
|
||||
IServiceManager serviceManager,
|
||||
ILogger<PostUpdateActionManager> logger)
|
||||
{
|
||||
this.serviceManager = serviceManager.ThrowIfNull();
|
||||
this.logger = logger.ThrowIfNull();
|
||||
}
|
||||
|
||||
public void AddPostUpdateAction<T>()
|
||||
where T : PostUpdateActionBase
|
||||
{
|
||||
this.serviceManager.RegisterSingleton<T>();
|
||||
this.logger.LogDebug($"Added post update action {typeof(T).Name}");
|
||||
}
|
||||
|
||||
public IEnumerable<PostUpdateActionBase> GetPostUpdateActions()
|
||||
{
|
||||
return this.serviceManager.GetServicesOfType<PostUpdateActionBase>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
public static class StringUtils
|
||||
{
|
||||
public static int DamerauLevenshteinDistance(string s, string t)
|
||||
{
|
||||
var (height, width) = (s.Length + 1, t.Length + 1);
|
||||
|
||||
var matrix = new int[height, width];
|
||||
|
||||
for (var j = 0; j < height; j++) { matrix[j, 0] = j; };
|
||||
for (var i = 0; i < width; i++) { matrix[0, i] = i; };
|
||||
|
||||
for (var j = 1; j < height; j++)
|
||||
{
|
||||
for (var i = 1; i < width; i++)
|
||||
{
|
||||
var cost = (s[j - 1] == t[i - 1]) ? 0 : 1;
|
||||
var insertion = matrix[j, i - 1] + 1;
|
||||
var deletion = matrix[j - 1, i] + 1;
|
||||
var substitution = matrix[j - 1, i - 1] + cost;
|
||||
|
||||
var distance = Math.Min(insertion, Math.Min(deletion, substitution));
|
||||
|
||||
if (j > 1 && i > 1 && s[j - 1] == t[i - 2] && s[j - 2] == t[i - 1])
|
||||
{
|
||||
distance = Math.Min(distance, matrix[j - 2, i - 2] + cost);
|
||||
}
|
||||
|
||||
matrix[j, i] = distance;
|
||||
}
|
||||
}
|
||||
|
||||
return matrix[height - 1, width - 1];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if stringToSearch is somewhat close to searchString.
|
||||
/// </summary>
|
||||
/// <param name="stringToSearch"></param>
|
||||
/// <param name="searchString"></param>
|
||||
/// <returns>True if strings match.</returns>
|
||||
public static bool MatchesSearchString(string stringToSearch, string searchString)
|
||||
{
|
||||
// Return true if either the distance between the entire text and the searchstring is small enough, or if any of the words are close to the search string.
|
||||
return DamerauLevenshteinDistance(stringToSearch.ToLower()[..Math.Min(stringToSearch.Length, searchString.Length)], searchString.ToLower()) < 3 ||
|
||||
stringToSearch.Split(' ').Any(word => DamerauLevenshteinDistance(word.ToLower()[..Math.Min(word.Length, searchString.Length)], searchString.ToLower()) < 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ namespace Daybreak.Views
|
||||
Build = this.buildTemplateManager.DecodeTemplate(this.CurrentBuildCode)
|
||||
};
|
||||
|
||||
this.logger.LogInformation($"Template {CurrentBuildCode} decoded");
|
||||
this.logger.LogInformation($"Template {this.CurrentBuildCode} decoded");
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid Background="#A0202020">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
@@ -17,7 +18,11 @@
|
||||
Clicked="BackButton_Clicked"></controls:BackButton>
|
||||
<controls:AddButton Foreground="White" Height="30" Width="30" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="5"
|
||||
Clicked="AddButton_Clicked"></controls:AddButton>
|
||||
<ListView Grid.Row="1" Background="Transparent" ItemsSource="{Binding ElementName=_this, Path=BuildEntries, Mode=OneWay}"
|
||||
<controls:SearchTextBox Grid.Row="1"
|
||||
FontSize="24"
|
||||
Foreground="White"
|
||||
TextChanged="SearchTextBox_TextChanged"></controls:SearchTextBox>
|
||||
<ListView Grid.Row="2" Background="Transparent" ItemsSource="{Binding ElementName=_this, Path=BuildEntries, Mode=OneWay}"
|
||||
MouseDoubleClick="ListView_MouseDoubleClick" HorizontalContentAlignment="Stretch">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Extensions;
|
||||
using System.Linq;
|
||||
using System.Windows.Controls;
|
||||
using Utils;
|
||||
|
||||
namespace Daybreak.Views
|
||||
{
|
||||
@@ -16,6 +19,8 @@ namespace Daybreak.Views
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly IBuildTemplateManager buildTemplateManager;
|
||||
|
||||
private IEnumerable<BuildEntry> buildEntries;
|
||||
|
||||
public ObservableCollection<BuildEntry> BuildEntries { get; } = new ObservableCollection<BuildEntry>();
|
||||
|
||||
public BuildsListView(
|
||||
@@ -28,9 +33,10 @@ namespace Daybreak.Views
|
||||
this.LoadBuilds();
|
||||
}
|
||||
|
||||
private void LoadBuilds()
|
||||
private async void LoadBuilds()
|
||||
{
|
||||
this.BuildEntries.ClearAnd().AddRange(this.buildTemplateManager.GetBuilds());
|
||||
this.buildEntries = await this.buildTemplateManager.GetBuilds().ToListAsync();
|
||||
this.BuildEntries.ClearAnd().AddRange(this.buildEntries);
|
||||
}
|
||||
|
||||
private void ListView_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
@@ -49,10 +55,17 @@ namespace Daybreak.Views
|
||||
this.viewManager.ShowView<BuildTemplateView>(build);
|
||||
}
|
||||
|
||||
private void BuildEntryTemplate_RemoveClicked(object sender, BuildEntry e)
|
||||
private void BuildEntryTemplate_RemoveClicked(object _, BuildEntry e)
|
||||
{
|
||||
this.buildTemplateManager.RemoveBuild(e);
|
||||
this.LoadBuilds();
|
||||
}
|
||||
|
||||
private void SearchTextBox_TextChanged(object _, string e)
|
||||
{
|
||||
this.BuildEntries.Clear();
|
||||
this.BuildEntries.AddRange(
|
||||
this.buildEntries.Where(b => StringUtils.MatchesSearchString(b.Name, e)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,19 +184,19 @@ namespace Daybreak.Views
|
||||
}
|
||||
}
|
||||
|
||||
private void ChromiumBrowserWrapper_BuildDecoded(object sender, Build e)
|
||||
private void ChromiumBrowserWrapper_BuildDecoded(object _, Build e)
|
||||
{
|
||||
this.viewManager.ShowView<BuildTemplateView>(new BuildEntry { Build = e, Name = string.Empty });
|
||||
}
|
||||
|
||||
private void LeftBrowser_FavoriteUriChanged(object sender, string e)
|
||||
private void LeftBrowser_FavoriteUriChanged(object _, string e)
|
||||
{
|
||||
var config = this.liveOptions.Value;
|
||||
config.LeftBrowserDefault = e;
|
||||
this.liveOptions.UpdateOption();
|
||||
}
|
||||
|
||||
private void RightBrowser_FavoriteUriChanged(object sender, string e)
|
||||
private void RightBrowser_FavoriteUriChanged(object _, string e)
|
||||
{
|
||||
var config = this.liveOptions.Value;
|
||||
config.RightBrowserDefault = e;
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Daybreak.Views
|
||||
{
|
||||
this.liveOptions = liveOptions.ThrowIfNull();
|
||||
this.viewManager = viewManager.ThrowIfNull();
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void AccountButton_Clicked(object sender, System.EventArgs e)
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Daybreak.Views
|
||||
this.applicationUpdater = applicationUpdater;
|
||||
this.logger = logger;
|
||||
this.viewManager = viewManager;
|
||||
this.updateStatus.PropertyChanged += UpdateStatus_PropertyChanged;
|
||||
this.updateStatus.PropertyChanged += this.UpdateStatus_PropertyChanged;
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace Daybreak.Views
|
||||
}
|
||||
|
||||
this.logger.LogInformation("Starting update procedure");
|
||||
var success = await applicationUpdater.DownloadUpdate(version, updateStatus).ConfigureAwait(true);
|
||||
var success = await this.applicationUpdater.DownloadUpdate(version, this.updateStatus).ConfigureAwait(true);
|
||||
if (success is false)
|
||||
{
|
||||
this.logger.LogError("Update procedure failed");
|
||||
|
||||
@@ -6,6 +6,7 @@ Param(
|
||||
Write-Output "Deleting pdb file"
|
||||
Remove-item .\Publish\Daybreak.pdb
|
||||
Remove-item .\Publish\Daybreak.Installer.pdb
|
||||
Move-Item -Path .\Publish\Daybreak.Installer.exe -Destination .\Publish\Daybreak.Installer.Temp.exe
|
||||
$zipPath = "Publish\daybreakv$version.zip"
|
||||
Write-Output "Compressing binaries to $zipPath"
|
||||
Compress-Archive .\Publish\* $zipPath -Force
|
||||
|
||||
Reference in New Issue
Block a user