Compare commits

...
59 Commits
Author SHA1 Message Date
amacocianandGitHub 78c8ae3e8f #127 - Introduce Nullable Support (#128) 2023-02-02 18:05:10 +00:00
amacocianandGitHub c64830c5b6 #123 #113 #105 Build Templates Improvements (#124) 2023-01-21 21:35:16 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
561c7cf7b1 Bump microsoft/setup-msbuild from 1.0.1 to 1.1.3 (#111)
Bumps [microsoft/setup-msbuild](https://github.com/microsoft/setup-msbuild) from 1.0.1 to 1.1.3.
- [Release notes](https://github.com/microsoft/setup-msbuild/releases)
- [Changelog](https://github.com/microsoft/setup-msbuild/blob/master/building-release.md)
- [Commits](https://github.com/microsoft/setup-msbuild/compare/v1.0.1...v1.1.3)

---
updated-dependencies:
- dependency-name: microsoft/setup-msbuild
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-09 15:22:44 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2c6862de41 Bump coverlet.collector from 3.1.2 to 3.2.0 (#112)
Bumps [coverlet.collector](https://github.com/coverlet-coverage/coverlet) from 3.1.2 to 3.2.0.
- [Release notes](https://github.com/coverlet-coverage/coverlet/releases)
- [Commits](https://github.com/coverlet-coverage/coverlet/commits/v3.2.0)

---
updated-dependencies:
- dependency-name: coverlet.collector
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-09 15:10:18 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
69842cbadf Bump Microsoft.NET.Test.Sdk from 17.4.0-preview-20221003-03 to 17.4.0 (#116)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.4.0-preview-20221003-03 to 17.4.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v17.4.0-preview-20221003-03...v17.4.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-09 14:24:26 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
c7327e7bb2 Bump Microsoft.NET.Test.Sdk (#108)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.4.0-preview-20220726-02 to 17.4.0-preview-20221003-03.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v17.4.0-preview-20220726-02...v17.4.0-preview-20221003-03)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 10:18:44 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
de33ed7fc4 Bump actions/setup-dotnet from 2 to 3 (#107)
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 2 to 3.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 10:09:29 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
c99bb8d074 Bump Microsoft.Web.WebView2 from 1.0.1343.22 to 1.0.1370.28 (#109)
* Bump Microsoft.Web.WebView2 from 1.0.1343.22 to 1.0.1370.28

Bumps Microsoft.Web.WebView2 from 1.0.1343.22 to 1.0.1370.28.

---
updated-dependencies:
- dependency-name: Microsoft.Web.WebView2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update daybreak version

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alexandru Macocian <amacocian@yahoo.com>
2022-10-11 10:02:33 +00:00
amacocianandGitHub a98e54ebc6 Sync namespaces (#104) 2022-09-23 09:56:47 +00:00
amacocianandGitHub a832aa1925 Minor fixes (#102) 2022-09-21 13:55:37 +00:00
amacocianandGitHub c7eb5debcb Refresh access token (#100) 2022-09-20 11:46:36 +00:00
amacocianandGitHub 91f0cb4e31 Implement expandable menu view (#95) 2022-09-19 19:08:34 +00:00
amacocianandGitHub 5e8407a6ab Make main view maintain its state (#94)
* Make main view maintain its state

* Stop checking game state when mainview is not loaded
2022-09-15 17:05:30 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
243c2c1536 Bump Microsoft.Extensions.Logging.Abstractions from 6.0.1 to 6.0.2 (#91)
* Bump Microsoft.Extensions.Logging.Abstractions from 6.0.1 to 6.0.2

Bumps [Microsoft.Extensions.Logging.Abstractions](https://github.com/dotnet/runtime) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](https://github.com/dotnet/runtime/compare/v6.0.1...v6.0.2)

---
updated-dependencies:
- dependency-name: Microsoft.Extensions.Logging.Abstractions
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump version

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alexandru Macocian <amacocian@yahoo.com>
2022-09-15 14:34:21 +00:00
amacocianandGitHub 930aca4ffe Bump dependencies (#90)
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2022-09-12 18:11:36 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1639cabe8e Bump Slim from 1.7.3 to 1.8.1 (#86)
Bumps [Slim](https://github.com/AlexMacocian/Slim) from 1.7.3 to 1.8.1.
- [Release notes](https://github.com/AlexMacocian/Slim/releases)
- [Commits](https://github.com/AlexMacocian/Slim/commits)

---
updated-dependencies:
- dependency-name: Slim
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-07 08:38:17 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
5961a57c5b Bump Microsoft.Web.WebView2 from 1.0.1293.44 to 1.0.1343.22 (#85)
Bumps Microsoft.Web.WebView2 from 1.0.1293.44 to 1.0.1343.22.

---
updated-dependencies:
- dependency-name: Microsoft.Web.WebView2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-07 10:29:18 +02:00
amacocianandGitHub 75d9bc6dec Add checkmark when builds are synchronized (#84) 2022-08-27 12:54:48 +00:00
amacocianandGitHub 4ccca32881 Build synchronization speedups (#82) 2022-08-27 12:15:21 +00:00
amacocianandGitHub a7f5d9dd96 Fix deletion error when installing (#80)
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2022-08-25 20:55:01 +00:00
amacocianandGitHub c8ba125abc Allow individual uploads/downloads for backed up builds (#77) 2022-08-25 20:44:20 +00:00
amacocianandGitHub 7d290031f1 Alexmacocian/fix secret build (#76)
* Fix pre-build secret building action

* Update version
2022-08-22 22:10:18 +00:00
amacocianandGitHub 5220a8c7ac Run fixed CD pipeline (#75) 2022-08-22 21:31:58 +00:00
amacocianandGitHub 33e221f60f Fix secret generation for CD pipeline (#74) 2022-08-22 21:05:13 +00:00
amacocianandGitHub 7f77547c50 Add support for build backups (#73) 2022-08-22 20:30:10 +00:00
amacocianandGitHub c5964e33ac Setup support for secrets (#72) 2022-08-22 12:55:29 +00:00
amacocianandGitHub 1c6f3ec797 Make all browsers use BrowserData folder (#70)
* Make all browsers use BrowserData folder

* Increment version
2022-08-21 14:09:26 +00:00
amacocianandGitHub 8601f61739 Run CD pipeline only on code changes (#67) 2022-08-20 15:24:45 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
91bac0d50b Bump actions/setup-dotnet from 1 to 2 (#64)
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 1 to 2.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v1...v2)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-20 15:22:41 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
0bf03e0fb5 Bump Xotl/cool-github-releases from 1.1.2 to 1.1.7 (#65)
Bumps [Xotl/cool-github-releases](https://github.com/Xotl/cool-github-releases) from 1.1.2 to 1.1.7.
- [Release notes](https://github.com/Xotl/cool-github-releases/releases)
- [Commits](https://github.com/Xotl/cool-github-releases/compare/v1.1.2...v1.1.7)

---
updated-dependencies:
- dependency-name: Xotl/cool-github-releases
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-20 15:22:24 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
81401178a5 Bump Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44 (#66)
* Bump Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44

Bumps Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44.

---
updated-dependencies:
- dependency-name: Microsoft.Web.WebView2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44

Bumps Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44.

---
updated-dependencies:
- dependency-name: Microsoft.Web.WebView2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Increment version

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alexandru Macocian <amacocian@yahoo.com>
2022-08-20 15:19:17 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
882357a8e5 Bump Microsoft.NET.Test.Sdk (#63)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.4.0-preview-20220707-01 to 17.4.0-preview-20220726-02.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v17.4.0-preview-20220707-01...v17.4.0-preview-20220726-02)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-20 13:18:22 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
abf629c5c6 Bump actions/checkout from 2 to 3 (#62)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-20 13:10:53 +00:00
amacocianandGitHub 758f9004cd Setup code owners (#61)
* Setup code owners

* Install .net6 on codeql pipeline

* Fix csproj

* Make version check only work when changing code files
2022-08-20 15:03:35 +02:00
amacocianandGitHub f174f8cbb3 Create dependabot.yml
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2022-08-20 14:42:07 +02:00
amacocianandGitHub f2f6bde25d Create codeql-analysis.yml
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2022-08-20 14:37:59 +02:00
amacocianandGitHub 85f378b303 Improve performance across builds and skills menus (#59)
Make buildtemplate load builds asynchronously
Make buildtemplateview load skills asynchronously
Improve search experience by making string matching be done asynchronously
Reduce memory footprint by virtualizing long skill list
2022-08-20 12:30:11 +00:00
amacocianandGitHub 71ab3fdefb Post-update actions (#57) 2022-08-19 12:45:07 +00:00
amacocianandGitHub 2f83d6c860 Delete browser cache on update (#56) 2022-08-18 20:17:36 +00:00
amacocianandGitHub 3db4975b48 Make launcher update the installer after an update (#55) 2022-08-18 19:59:08 +00:00
amacocianandGitHub 6a6eea5d02 Implement search bar for builds and skills (#50)
* Add search bars to builds and skills

* Fix search bar not appearing.
Improve search function.

* Increment version

* Rename version check so it can be added to status checks
2022-08-18 21:26:57 +02:00
amacocianandGitHub 8fe9eeb32f Icon downloader bugfixes (#47)
* Fix icon download to properly finish
2022-08-16 19:47:25 +02:00
amacocianandGitHub 4c1025243b Background Icon Downloader (#44)
* Download icons in the background

* Fix icon downloader browser setup
2022-08-16 17:51:35 +02:00
amacocianandGitHub f24eb02ca1 Pipeline to check that version is updated (#43)
* Pipeline to check that version is updated
2022-08-13 00:24:54 +02:00
amacocianandGitHub b01c09491f Download and check icons at startup (#41) 2022-08-12 23:41:22 +02:00
amacocianandGitHub 54ae742899 Increment version (#40) 2022-08-12 13:22:59 +02:00
amacocianandGitHub 4c862463d7 Fix IconRetriever (#38)
Use browser to bypass header issues with http client
2022-08-12 13:15:46 +02:00
amacocianandGitHub b455c89ddc Minor improvements (#36)
Deprecate Microsoft.Xaml.Behaviors.Wpf
Reverse version order in management view
2022-08-04 23:05:55 +02:00
amacocianandGitHub 782b76cd8e Remove admin mode when updating (#31) 2022-08-04 21:59:55 +02:00
amacocianandGitHub 230c2d9457 Setup executable installer (#29)
* Setup executable installer

* Increment update to 0.9.3

* Improve installer
2022-08-04 21:39:17 +02:00
amacocianandGitHub 63531e3b8c Hide console window (#25) 2022-08-04 19:52:54 +02:00
amacocianandGitHub ac430305f4 Update to .net 6 and update dependencies (#24)
* Update to .net 6 and update dependencies
2022-08-04 19:25:53 +02:00
amacocianandGitHub 3d830cfc16 Update dependencies (#23) 2021-07-10 13:39:00 +03:00
amacocianandGitHub b529aa8861 Fix logging on startup when ILogger is null (#22) 2021-07-10 12:45:44 +03:00
amacocianandGitHub 3798daa54e Update dependencies (#21)
* Update dependencies
* Minor nit fixes
* Fix UTs
2021-07-10 12:08:43 +03:00
amacocianandGitHub 624380ed86 Use IOptions instead of IConfigurationManager (#20)
* Use IOptions instead of dependency on IConfigurationManager
2021-06-22 15:48:37 +03:00
amacocianandGitHub 2b025e225b Updated wpfextended dependency 2021-06-11 13:50:58 +02:00
amacocianandGitHub 15a67ea28c Minor fixes
Stop showing browser when browser is disabled
Prevent setting address of browser when browser is disabled (should prevent browser from instantiating when disabled)
Ignore errors from browser caused by switching view before the browser could be initialized
Provide expression to filter logs
Button to export logs to json file
2021-06-07 14:33:54 +02:00
amacocianandGitHub c6b62fd5fd Logging improvements
Log uncaught exceptions
Logview expander
2021-06-07 00:34:43 +02:00
202 changed files with 4765 additions and 1919 deletions
+134
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
* amacocian@yahoo.com
+16
View File
@@ -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"
+20 -7
View File
@@ -9,6 +9,9 @@ on:
push:
branches:
- master
paths:
- "Daybreak/**"
- "Daybreak.Installer/**"
jobs:
@@ -24,12 +27,12 @@ jobs:
Configuration: Release
Solution_Path: Daybreak.sln
Test_Project_Path: Daybreak.Tests\Daybreak.Tests.csproj
Wpf_Project_Path: Daybreak\Daybreal.csproj
Wpf_Project_Path: Daybreak\Daybreak.csproj
Actions_Allow_Unsecure_Commands: true
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
@@ -50,12 +53,17 @@ jobs:
echo "${{ env.Changelog }}"
- name: Install .NET Core
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v3
with:
dotnet-version: '5.0.202'
dotnet-version: '6.x'
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.1
uses: microsoft/setup-msbuild@v1.1.3
- name: Setup project secrets
run: |
dotnet user-secrets --project Daybreak\Daybreak.csproj set AadApplicationId "${{ secrets.AadApplicationId }}"
dotnet user-secrets --project Daybreak\Daybreak.csproj set AadTenantId "${{ secrets.AadTenantId }}"
- name: Restore project
run: msbuild $env:Solution_Path /t:Restore /p:Configuration=$env:Configuration /p:RuntimeIdentifier=$env:RuntimeIdentifier
@@ -70,11 +78,16 @@ jobs:
$version = .\Scripts\GetBuildVersion.ps1
echo "::set-env name=Version::$version"
- name: Create publish files
- name: Create publish launcher files
run: dotnet publish .\Daybreak\Daybreak.csproj -c $env:Configuration -r $env:RuntimeIdentifier -p:PublishReadyToRun=true -p:PublishSingleFile=true --self-contained true -o .\Publish
env:
RuntimeIdentifier: win-${{ matrix.targetplatform }}
- name: Create publish installer files
run: dotnet publish .\Daybreak.Installer\Daybreak.Installer.csproj -c $env:Configuration -r $env:RuntimeIdentifier -p:PublishReadyToRun=true -p:PublishSingleFile=true --self-contained true -o .\Publish
env:
RuntimeIdentifier: win-${{ matrix.targetplatform }}
- name: Pack publish files
run: |
Write-Host $env
@@ -82,7 +95,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 }}
+4 -4
View File
@@ -31,17 +31,17 @@ 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@v3
with:
dotnet-version: '5.0.202'
dotnet-version: '6.x'
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.1
uses: microsoft/setup-msbuild@v1.1.3
- name: Execute Unit Tests
run: dotnet test $env:Test_Project_Path
+78
View File
@@ -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@v3
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
+48
View File
@@ -0,0 +1,48 @@
name: Daybreak Version Check
on:
pull_request:
branches:
- master
paths:
- "Daybreak/**"
- "Daybreak.Installer/**"
jobs:
check_version:
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@v3
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 }}
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
+67
View File
@@ -0,0 +1,67 @@
// See https://aka.ms/new-console-template for more information
using System.Diagnostics;
using System.IO.Compression;
const string tempFile = "tempfile.zip";
const string executableName = "Daybreak.exe";
Console.Title = "Daybreak Installer";
Console.WriteLine("Starting installation...");
if (File.Exists(tempFile) is false)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Unable to find launcher package. Aborting installation");
Console.ReadKey();
return;
}
Console.WriteLine("Unpacking files...");
try
{
ZipFile.ExtractToDirectory(tempFile, AppContext.BaseDirectory, true);
}
catch
{
}
Console.WriteLine("Deleting package");
try
{
File.Delete(tempFile);
}
catch(Exception e)
{
Console.WriteLine($"Failed to delete {tempFile}.\n{e}");
}
Console.WriteLine("Deleting browser caches");
try
{
Directory.Delete("BrowserData", true);
}
catch(Exception e)
{
Console.WriteLine($"Failed to delete BrowserData.\n{e}");
}
try
{
Directory.Delete("Daybreak.exe.WebView2", true);
}
catch(Exception e)
{
Console.WriteLine($"Failed to delete Daybreak.exe.WebView2.\n{e}");
}
Console.WriteLine("Launching application");
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = executableName
}
};
if (process.Start() is false)
{
Console.WriteLine("Failed to launch application");
Console.ReadKey();
}
+8 -9
View File
@@ -1,19 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<TargetFramework>net7.0-windows</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.0.0-alpha0002" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.1" />
<PackageReference Include="coverlet.collector" Version="1.3.0" />
<PackageReference Include="System.Linq.Async" Version="5.0.0" />
<PackageReference Include="FluentAssertions" Version="6.9.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="MSTest.TestAdapter" Version="3.0.2" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.2" />
<PackageReference Include="coverlet.collector" Version="3.2.0" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
</ItemGroup>
<ItemGroup>
@@ -0,0 +1,63 @@
using Daybreak.Configuration;
using Daybreak.Services.Configuration;
using Daybreak.Services.Options;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System;
namespace Daybreak.Tests.Services
{
[TestClass]
public class ApplicationConfigurationOptionsManagerTests
{
private ApplicationConfigurationOptionsManager applicationConfigurationOptionsManager;
[TestInitialize]
public void TestInitialize()
{
var configurationManagerMock = new Mock<IConfigurationManager>();
configurationManagerMock
.Setup(u => u.GetConfiguration())
.Returns(new ApplicationConfiguration());
this.applicationConfigurationOptionsManager = new ApplicationConfigurationOptionsManager(configurationManagerMock.Object);
}
[TestMethod]
public void GetApplicationConfiguration_ReturnsObject()
{
var config = this.applicationConfigurationOptionsManager.GetOptions<ApplicationConfiguration>();
config.Should().NotBeNull();
}
[TestMethod]
public void GetOtherOptions_ThrowsInvalidOperationException()
{
var action = new Action(() =>
{
this.applicationConfigurationOptionsManager.GetOptions<object>();
});
action.Should().Throw<InvalidOperationException>();
}
[TestMethod]
public void UpdateOptions_OnApplicationConfiguration_Succeeds()
{
this.applicationConfigurationOptionsManager.UpdateOptions(new ApplicationConfiguration());
}
[TestMethod]
public void UpdateOptions_OnOthers_ThrowsInvalidOperationException()
{
var action = new Action(() =>
{
this.applicationConfigurationOptionsManager.UpdateOptions(new object());
});
action.Should().Throw<InvalidOperationException>();
}
}
}
@@ -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]
@@ -4,7 +4,8 @@ using LiteDB;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using WpfExtended.Logging;
using System.Linq;
using System.Logging;
namespace Daybreak.Tests.Services
{
@@ -37,6 +38,18 @@ namespace Daybreak.Tests.Services
logger.Should().NotBeNull();
}
[TestMethod]
public void LoggerLogsAndReaderReadsFiltered()
{
var logger = this.loggerProvider.CreateLogger("SomeCategory");
logger.LogTrace("Logging some trace");
logger.LogInformation("Logging some stuff");
logger.LogError("Logging some error");
this.logsManager.GetLogs(l => l.LogLevel < LogLevel.Information).Should().HaveCount(1);
var log = this.logsManager.GetLogs(l => l.LogLevel < LogLevel.Information).First();
log.LogLevel.Should().Be(LogLevel.Error);
}
[TestMethod]
public void LoggerLogsAndReaderReads()
{
var logger = this.loggerProvider.CreateLogger("SomeCategory");
+34 -2
View File
@@ -1,12 +1,36 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31005.135
# Visual Studio Version 17
VisualStudioVersion = 17.2.32616.157
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Daybreak", "Daybreak\Daybreak.csproj", "{AA45C2B1-8BD0-466C-9271-699F168905AF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Daybreak.Tests", "Daybreak.Tests\Daybreak.Tests.csproj", "{C911C1C2-6566-419C-89C7-F802EB3FE709}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Pipelines", "Pipelines", "{067BF93F-E5B2-4E99-886E-039C04F35EAB}"
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
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\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
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -31,6 +55,14 @@ Global
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|Any CPU.Build.0 = Release|Any CPU
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|x64.ActiveCfg = Release|Any CPU
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Release|x64.Build.0 = Release|Any CPU
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|x64.ActiveCfg = Debug|Any CPU
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Debug|x64.Build.0 = Debug|Any CPU
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|Any CPU.Build.0 = Release|Any CPU
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|x64.ActiveCfg = Release|Any CPU
{4E2BB805-135D-4F02-8C53-3D8B6876D323}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+2 -2
View File
@@ -1,9 +1,9 @@
using System;
using Microsoft.Xaml.Behaviors;
using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using System.Windows.Media;
namespace Daybreak.Behaviors
+4 -4
View File
@@ -1,7 +1,7 @@
using System;
using Microsoft.Xaml.Behaviors;
using System;
using System.Extensions;
using System.Windows.Controls;
using System.Windows.Interactivity;
namespace Daybreak.Behaviors
{
@@ -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;
}
}
@@ -14,15 +14,15 @@ namespace Daybreak.Configuration
[JsonProperty("BrowsersEnabled")]
public bool BrowsersEnabled { get; set; } = true;
[JsonProperty("ToolboxPath")]
public string ToolboxPath { get; set; }
public string? ToolboxPath { get; set; }
[JsonProperty("TexmodPath")]
public string TexmodPath { get; set; }
public string? TexmodPath { get; set; }
[JsonProperty("ToolboxAutoLaunch")]
public bool ToolboxAutoLaunch { get; set; }
[JsonProperty("LeftBrowserDefault")]
public string LeftBrowserDefault { get; set; } = "https://gwpvx.fandom.com/wiki/PvX_wiki";
public string? LeftBrowserDefault { get; set; } = "https://gwpvx.fandom.com/wiki/PvX_wiki";
[JsonProperty("RightBrowserDefault")]
public string RightBrowserDefault { get; set; } = "https://wiki.guildwars.com/wiki/Quick_access_links";
public string? RightBrowserDefault { get; set; } = "https://wiki.guildwars.com/wiki/Quick_access_links";
[JsonProperty("GuildwarsPaths")]
public List<GuildwarsPath> GuildwarsPaths { get; set; } = new();
[JsonProperty("ProtectedLoginCredentials")]
@@ -32,12 +32,14 @@ namespace Daybreak.Configuration
[JsonProperty("ExperimentalFeatures")]
public ExperimentalFeatures ExperimentalFeatures { get; set; } = new();
[JsonProperty("ShortcutLocation")]
public string ShortcutLocation { get; set; } = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
public string? ShortcutLocation { get; set; } = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
[JsonProperty("PlaceShortcut")]
public bool PlaceShortcut { get; set; }
[JsonProperty("AutoCheckUpdate")]
public bool AutoCheckUpdate { get; set; } = true;
[JsonProperty("KeepLocalIconCache")]
public bool KeepLocalIconCache { get; set; } = true;
[JsonProperty("ProtectedGraphAccessToken")]
public string? ProtectedGraphAccessToken { get; set; }
[JsonProperty("ProtectedGraphRefreshToken")]
public string? ProtectedGraphRefreshToken { get; set; }
}
}
@@ -16,6 +16,8 @@ namespace Daybreak.Configuration
public bool LaunchGuildwarsAsCurrentUser { get; set; } = true;
[JsonProperty("CanInterceptKeys")]
public bool CanInterceptKeys { get; set; }
[JsonProperty("DownloadIcons")]
public bool DownloadIcons { get; set; }
[JsonProperty("Macros")]
public List<KeyMacro> Macros { get; set; } = new();
}
+104 -64
View File
@@ -1,5 +1,4 @@
using Daybreak.Services.ApplicationLauncher;
using Daybreak.Services.ApplicationLifetime;
using Daybreak.Services.Bloogum;
using Daybreak.Services.BuildTemplates;
using Daybreak.Services.Configuration;
@@ -8,89 +7,130 @@ using Daybreak.Services.IconRetrieve;
using Daybreak.Services.Logging;
using Daybreak.Services.Mutex;
using Daybreak.Services.Privilege;
using Daybreak.Services.Runtime;
using Daybreak.Services.Screens;
using Daybreak.Services.Screenshots;
using Daybreak.Services.Shortcuts;
using Daybreak.Services.Updater;
using Daybreak.Services.ViewManagement;
using Daybreak.Views;
using Microsoft.Extensions.Http.Logging;
using Microsoft.Extensions.Logging;
using Slim;
using System.Extensions;
using System.Net.Http;
using System.Windows.Extensions.Http;
using LiteDB;
using System.Windows.Extensions;
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;
using Daybreak.Services.Graph;
using Microsoft.Extensions.DependencyInjection;
using Daybreak.Services.Navigation;
namespace Daybreak.Configuration
namespace Daybreak.Configuration;
public static class ProjectConfiguration
{
public static class ProjectConfiguration
public static void RegisterResolvers(IServiceManager serviceManager)
{
public static void RegisterResolvers(IServiceManager serviceManager)
{
serviceManager.ThrowIfNull(nameof(serviceManager));
serviceManager.ThrowIfNull();
serviceManager.RegisterResolver(
new HttpClientResolver()
.WithHttpMessageHandlerFactory((serviceProvider, categoryType) =>
serviceManager.RegisterOptionsManager<ApplicationConfigurationOptionsManager>();
serviceManager.RegisterResolver(new LoggerResolver());
serviceManager
.RegisterHttpClient<ApplicationUpdater>()
.WithMessageHandler(sp =>
{
var loggerType = typeof(ILogger<>).MakeGenericType(categoryType);
var logger = serviceProvider.GetService(loggerType).As<ILogger>();
var handler = new LoggingHttpMessageHandler(logger) { InnerHandler = new HttpClientHandler() };
return handler;
}));
}
var logger = sp.GetService<ILogger<ApplicationUpdater>>();
return new LoggingHttpMessageHandler(logger!) { InnerHandler = new HttpClientHandler() };
})
.Build()
.RegisterHttpClient<BloogumClient>()
.WithMessageHandler(sp =>
{
var logger = sp.GetService<ILogger<BloogumClient>>();
return new LoggingHttpMessageHandler(logger!) { InnerHandler = new HttpClientHandler() };
})
.Build()
.RegisterHttpClient<GraphClient>()
.WithMessageHandler(sp =>
{
var logger = sp.GetService<ILogger<GraphClient>>();
return new LoggingHttpMessageHandler(logger!) { InnerHandler = new HttpClientHandler() };
})
.Build();
}
public static void RegisterServices(IServiceProducer serviceProducer)
public static void RegisterServices(IServiceCollection services)
{
services.ThrowIfNull();
services.AddSingleton<ILogsManager, JsonLogsManager>();
services.AddSingleton<IDebugLogsWriter, Services.Logging.DebugLogsWriter>();
services.AddSingleton<ILoggerFactory, LoggerFactory>(sp =>
{
serviceProducer.ThrowIfNull(nameof(serviceProducer));
var factory = new LoggerFactory();
factory.AddProvider(new CVLoggerProvider(sp.GetService<ILogsWriter>()));
return factory;
});
services.AddSingleton<ILogsWriter, CompositeLogsWriter>(sp => new CompositeLogsWriter(
sp.GetService<ILogsManager>()!,
sp.GetService<IDebugLogsWriter>()!));
serviceProducer.RegisterSingleton<ApplicationLifetimeManager>();
serviceProducer.RegisterSingleton<ViewManager>();
serviceProducer.RegisterSingleton<IConfigurationManager, ConfigurationManager>();
serviceProducer.RegisterSingleton<ILiteDatabase, LiteDatabase>(sp => new LiteDatabase("Daybreak.db"));
serviceProducer.RegisterSingleton<IRuntimeStore, RuntimeStore>();
serviceProducer.RegisterSingleton<IMutexHandler, MutexHandler>();
serviceProducer.RegisterSingleton<IShortcutManager, ShortcutManager>();
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.RegisterLogWriter<ILogsManager, JsonLogsManager>();
}
public static void RegisterLifetimeServices(IApplicationLifetimeProducer applicationLifetimeProducer)
{
applicationLifetimeProducer.ThrowIfNull(nameof(applicationLifetimeProducer));
services.AddScoped((sp) => new ScopeMetadata(new CorrelationVector()));
services.AddSingleton<ViewManager>();
services.AddSingleton<IViewManager, ViewManager>(sp => sp.GetRequiredService<ViewManager>());
services.AddSingleton<IViewProducer, ViewManager>(sp => sp.GetRequiredService<ViewManager>());
services.AddSingleton<PostUpdateActionManager>();
services.AddSingleton<IPostUpdateActionManager>(sp => sp.GetRequiredService<PostUpdateActionManager>());
services.AddSingleton<IPostUpdateActionProducer>(sp => sp.GetRequiredService<PostUpdateActionManager>());
services.AddSingleton<IPostUpdateActionProvider>(sp => sp.GetRequiredService<PostUpdateActionManager>());
services.AddSingleton<IConfigurationManager, ConfigurationManager>();
services.AddSingleton<ILiteDatabase, LiteDatabase>(sp => new LiteDatabase("Daybreak.db"));
services.AddSingleton<IMutexHandler, MutexHandler>();
services.AddSingleton<IShortcutManager, ShortcutManager>();
services.AddSingleton<IIconBrowser, IconBrowser>();
services.AddSingleton<IIconDownloader, IconDownloader>();
services.AddScoped<ICredentialManager, CredentialManager>();
services.AddScoped<IApplicationLauncher, ApplicationLauncher>();
services.AddScoped<IScreenshotProvider, ScreenshotProvider>();
services.AddScoped<IBloogumClient, BloogumClient>();
services.AddScoped<IApplicationUpdater, ApplicationUpdater>();
services.AddScoped<IBuildTemplateManager, BuildTemplateManager>();
services.AddScoped<IIconCache, IconCache>();
services.AddScoped<IPrivilegeManager, PrivilegeManager>();
services.AddScoped<IScreenManager, ScreenManager>();
services.AddScoped<IGraphClient, GraphClient>();
}
applicationLifetimeProducer.RegisterService<IScreenshotProvider>();
applicationLifetimeProducer.RegisterService<IApplicationUpdater>();
applicationLifetimeProducer.RegisterService<IShortcutManager>();
}
public static void RegisterViews(IViewProducer viewProducer)
{
viewProducer.ThrowIfNull(nameof(viewProducer));
public static void RegisterViews(IViewProducer viewProducer)
{
viewProducer.ThrowIfNull();
viewProducer.RegisterView<MainView>();
viewProducer.RegisterView<SettingsView>();
viewProducer.RegisterView<AskUpdateView>();
viewProducer.RegisterView<UpdateView>();
viewProducer.RegisterView<SettingsCategoryView>();
viewProducer.RegisterView<AccountsView>();
viewProducer.RegisterView<ExperimentalSettingsView>();
viewProducer.RegisterView<ExecutablesView>();
viewProducer.RegisterView<BuildTemplateView>();
viewProducer.RegisterView<BuildsListView>();
viewProducer.RegisterView<RequestElevationView>();
viewProducer.RegisterView<ScreenChoiceView>();
viewProducer.RegisterView<VersionManagementView>();
viewProducer.RegisterView<LogsView>();
}
viewProducer.RegisterPermanentView<CompanionView>();
viewProducer.RegisterView<SettingsView>();
viewProducer.RegisterView<AskUpdateView>();
viewProducer.RegisterView<UpdateView>();
viewProducer.RegisterView<AccountsView>();
viewProducer.RegisterView<ExperimentalSettingsView>();
viewProducer.RegisterView<ExecutablesView>();
viewProducer.RegisterView<BuildTemplateView>();
viewProducer.RegisterView<BuildsListView>();
viewProducer.RegisterView<RequestElevationView>();
viewProducer.RegisterView<ScreenChoiceView>();
viewProducer.RegisterView<VersionManagementView>();
viewProducer.RegisterView<LogsView>();
viewProducer.RegisterView<IconDownloadView>();
viewProducer.RegisterView<GraphAuthorizationView>();
viewProducer.RegisterView<BuildsSynchronizationView>();
}
public static void RegisterPostUpdateActions(IPostUpdateActionProducer postUpdateActionProducer)
{
postUpdateActionProducer.ThrowIfNull();
postUpdateActionProducer.AddPostUpdateAction<RenameInstallerAction>();
}
}
+12
View File
@@ -0,0 +1,12 @@
namespace Daybreak.Configuration;
public class SecretKeys
{
public static readonly SecretKeys AadApplicationId = new() { Key = "AadApplicationId" };
public static readonly SecretKeys AadTenantId = new() { Key = "AadTenantId" };
public string Key { get; private set; } = string.Empty;
private SecretKeys()
{
}
}
+49
View File
@@ -0,0 +1,49 @@
using Newtonsoft.Json.Linq;
using System.Extensions;
using System.Linq;
using System.Reflection;
namespace Daybreak.Configuration;
public static class SecretManager
{
private static JObject? SecretsHolder;
public static string GetSecret(SecretKeys secretKey)
{
if (SecretsHolder is null)
{
LoadSecrets();
}
return SecretsHolder!.Value<string>(secretKey.Key)!;
}
public static T GetSecret<T>(SecretKeys secretKey)
{
if (SecretsHolder is null)
{
LoadSecrets();
}
return SecretsHolder!.Value<T>(secretKey.Key)!;
}
private static void LoadSecrets()
{
var serializedSecrets = Assembly.GetExecutingAssembly().GetManifestResourceStream("Daybreak.secrets.json").ReadAllBytes().GetString();
serializedSecrets = TrimUnwantedCharacters(serializedSecrets);
SecretsHolder = JObject.Parse(serializedSecrets);
}
private static string TrimUnwantedCharacters(string s)
{
return new string(s.Where(c =>
char.IsWhiteSpace(c) ||
char.IsLetterOrDigit(c) ||
char.IsSymbol(c) ||
char.IsSeparator(c) ||
char.IsPunctuation(c))
.ToArray());
}
}
+2 -2
View File
@@ -9,11 +9,11 @@ namespace Daybreak.Controls
/// </summary>
public partial class AddButton : UserControl
{
public event EventHandler Clicked;
public event EventHandler? Clicked;
public AddButton()
{
InitializeComponent();
this.InitializeComponent();
}
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
+2 -2
View File
@@ -9,11 +9,11 @@ namespace Daybreak.Controls
/// </summary>
public partial class BackButton : UserControl
{
public event EventHandler Clicked;
public event EventHandler? Clicked;
public BackButton()
{
InitializeComponent();
this.InitializeComponent();
}
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
+2 -2
View File
@@ -9,10 +9,10 @@ namespace Daybreak.Controls
/// </summary>
public partial class BinButton : UserControl
{
public event EventHandler Clicked;
public event EventHandler? Clicked;
public BinButton()
{
InitializeComponent();
this.InitializeComponent();
}
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
@@ -9,11 +9,11 @@ namespace Daybreak.Controls
/// </summary>
public partial class CancelButton : UserControl
{
public event EventHandler Clicked;
public event EventHandler? Clicked;
public CancelButton()
{
InitializeComponent();
this.InitializeComponent();
}
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
@@ -12,11 +12,7 @@
<Viewbox Stretch="Fill">
<Grid>
<Ellipse Height="4" Width="4" StrokeThickness="0.2" Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></Ellipse>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Ellipse Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Height="1" Width="1"></Ellipse>
<Ellipse Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Height="1" Width="1"></Ellipse>
<Ellipse Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Height="1" Width="1"></Ellipse>
</StackPanel>
<local:ThreeDotsGlyph Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Padding="0.5"></local:ThreeDotsGlyph>
</Grid>
</Viewbox>
<Ellipse Fill="Transparent" MouseEnter="Ellipse_MouseEnter" MouseLeave="Ellipse_MouseLeave" MouseLeftButtonDown="Ellipse_MouseLeftButtonDown"></Ellipse>
@@ -9,7 +9,7 @@ namespace Daybreak.Controls
/// </summary>
public partial class FilePickerGlyph : UserControl
{
public event EventHandler Clicked;
public event EventHandler? Clicked;
public FilePickerGlyph()
{
+2 -2
View File
@@ -9,11 +9,11 @@ namespace Daybreak.Controls
/// </summary>
public partial class HelpButton : UserControl
{
public event EventHandler Clicked;
public event EventHandler? Clicked;
public HelpButton()
{
InitializeComponent();
this.InitializeComponent();
}
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
+1 -1
View File
@@ -9,7 +9,7 @@ namespace Daybreak.Controls
/// </summary>
public partial class HomeButton : UserControl
{
public event EventHandler Clicked;
public event EventHandler? Clicked;
public HomeButton()
{
@@ -9,21 +9,21 @@ namespace Daybreak.Controls
/// </summary>
public partial class MaximizeButton : UserControl
{
public event EventHandler Clicked;
public event EventHandler? Clicked;
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)
+41
View File
@@ -0,0 +1,41 @@
<UserControl x:Class="Daybreak.Controls.Buttons.MenuButton"
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.Buttons"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:behaviors="clr-namespace:Daybreak.Behaviors"
xmlns:converters="clr-namespace:Daybreak.Converters"
x:Name="_this"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<converters:MenuButtonHighlightConverter x:Key="HighlightConverter"></converters:MenuButtonHighlightConverter>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Rectangle
Fill="{Binding ElementName=_this, Path=HighlightColor, Mode=OneWay}"
Opacity="{Binding ElementName=_this, Path=Highlighted, Converter={StaticResource HighlightConverter}}"
Grid.ColumnSpan="2">
</Rectangle>
<ContentPresenter Margin="5"
Content="{Binding ElementName=_this, Path=InnerContent, Mode=OneWay}" />
<TextBlock Grid.Column="1"
Text="{Binding ElementName=_this, Path=Title, Mode=OneWay}"
FontSize="{Binding ElementName=_this, Path=FontSize, Mode=OneWay}"
FontFamily="{Binding ElementName=_this, Path=FontFamily, Mode=OneWay}"
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
VerticalAlignment="Center" HorizontalAlignment="Stretch" TextWrapping="Wrap"
TextAlignment="Left" />
<Rectangle Fill="Transparent"
MouseEnter="Grid_MouseEnter"
MouseLeave="Grid_MouseLeave"
MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"
Grid.ColumnSpan="2" />
</Grid>
</UserControl>
@@ -0,0 +1,44 @@
using System;
using System.Windows.Extensions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Daybreak.Controls.Buttons;
/// <summary>
/// Interaction logic for MenuButton.xaml
/// </summary>
public partial class MenuButton : UserControl
{
public event EventHandler? Clicked;
[GenerateDependencyProperty]
private bool highlighted;
[GenerateDependencyProperty]
private Brush highlightColor = default!;
[GenerateDependencyProperty]
private FrameworkElement innerContent = default!;
[GenerateDependencyProperty(InitialValue = "")]
private string title = string.Empty;
public MenuButton()
{
this.InitializeComponent();
}
private void Grid_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
this.Highlighted = true;
}
private void Grid_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
this.Highlighted = false;
}
private void Rectangle_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
this.Clicked?.Invoke(this, e);
}
}
@@ -9,11 +9,11 @@ namespace Daybreak.Controls
/// </summary>
public partial class MinusButton : UserControl
{
public event EventHandler Clicked;
public event EventHandler? Clicked;
public MinusButton()
{
InitializeComponent();
this.InitializeComponent();
}
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
+14 -55
View File
@@ -12,65 +12,24 @@ namespace Daybreak.Controls
/// </summary>
public partial class OpaqueButton : UserControl
{
public static readonly DependencyProperty TextProperty =
DependencyPropertyExtensions.Register<OpaqueButton, string>(nameof(Text));
public event EventHandler? Clicked;
public static readonly DependencyProperty TransparentBackgroundProperty =
DependencyPropertyExtensions.Register<OpaqueButton, Brush>(nameof(TransparentBackground));
public static readonly DependencyProperty HighlightProperty =
DependencyPropertyExtensions.Register<OpaqueButton, Brush>(nameof(Highlight));
public static readonly DependencyProperty BackgroundOpacityProperty =
DependencyPropertyExtensions.Register<OpaqueButton, double>(nameof(BackgroundOpacity));
public static readonly DependencyProperty HighlightOpacityProperty =
DependencyPropertyExtensions.Register<OpaqueButton, double>(nameof(HighlightOpacity));
public static readonly DependencyProperty HighlightVisibleProperty =
DependencyPropertyExtensions.Register<OpaqueButton, bool>(nameof(HighlightVisible));
public event EventHandler Clicked;
public string Text
{
get => this.GetTypedValue<string>(TextProperty);
set => this.SetTypedValue(TextProperty, value);
}
public Brush TransparentBackground
{
get => this.GetTypedValue<Brush>(TransparentBackgroundProperty);
set => this.SetTypedValue(TransparentBackgroundProperty, value);
}
public Brush Highlight
{
get => this.GetTypedValue<Brush>(HighlightProperty);
set => this.SetTypedValue(HighlightProperty, value);
}
public double BackgroundOpacity
{
get => this.GetTypedValue<double>(BackgroundOpacityProperty);
set => this.SetTypedValue(BackgroundOpacityProperty, value);
}
public double HighlightOpacity
{
get => this.GetTypedValue<double>(HighlightOpacityProperty);
set => this.SetTypedValue(HighlightOpacityProperty, value);
}
public bool HighlightVisible
{
get => this.GetTypedValue<bool>(HighlightVisibleProperty);
set => this.SetTypedValue(HighlightVisibleProperty, value);
}
[GenerateDependencyProperty(InitialValue = "")]
private string text = string.Empty;
[GenerateDependencyProperty]
private Brush transparentBackground = default!;
[GenerateDependencyProperty]
private Brush highlight = default!;
[GenerateDependencyProperty]
public double backgroundOpacity;
[GenerateDependencyProperty]
public double highlightOpacity;
[GenerateDependencyProperty]
public bool highlightVisible;
public OpaqueButton()
{
InitializeComponent();
this.InitializeComponent();
}
private void Rectangle_MouseEnter(object sender, MouseEventArgs e)
+4 -4
View File
@@ -9,21 +9,21 @@ namespace Daybreak.Controls
/// </summary>
public partial class SaveButton : UserControl
{
public event EventHandler Clicked;
public event EventHandler? Clicked;
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)
@@ -0,0 +1,36 @@
<UserControl x:Class="Daybreak.Controls.SynchronizeButton"
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"
mc:Ignorable="d"
x:Name="_this"
d:DesignHeight="450" d:DesignWidth="800">
<Viewbox>
<Grid>
<Ellipse x:Name="BackgroundEllipse" Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Visibility="Visible" Opacity="0.1" Width="35" Height="35" />
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
StrokeThickness="3"/>
<Grid VerticalAlignment="Center"
HorizontalAlignment="Center">
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
StrokeThickness="1.5"
Data="m19,15.6073c1.4937,-0.5852 3,-1.9184 3,-4.6073c0,-4 -3.3333,-5 -5,-5c0,-2 0,-6 -6,-6c-6,0 -6,4 -6,6c-1.66667,0 -5,1 -5,5c0,2.6889 1.50628,4.0221 3,4.6073" />
<Path StrokeThickness="1.5"
Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Data="m6,17l1.76777,1.7678c1.56214,1.5621 4.09474,1.5621 5.65684,0l0.3536,-0.3536" />
<Path StrokeThickness="1.5"
Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Data="m6.35355,19.4749l-0.35355,-2.4749l2.47482,0.3536l-2.12127,2.1213z" />
<Path StrokeThickness="1.5"
Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Data="m14.77821,14.93927l-1.7678,-1.7677c-1.5621,-1.5621 -4.0948,-1.5621 -5.65685,0l-0.35356,0.3535" />
<Path StrokeThickness="1.5"
Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Data="m14.1213,12l0.3536,2.4749l-2.4749,-0.3536l2.1213,-2.1213z" />
</Grid>
<Ellipse Fill="Transparent" MouseEnter="Ellipse_MouseEnter" MouseLeave="Ellipse_MouseLeave" MouseLeftButtonDown="Ellipse_MouseLeftButtonDown"></Ellipse>
</Grid>
</Viewbox>
</UserControl>
@@ -0,0 +1,36 @@
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for SynchronizeButton.xaml
/// </summary>
public partial class SynchronizeButton : UserControl
{
public event EventHandler? Clicked;
public SynchronizeButton()
{
this.InitializeComponent();
}
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
{
this.BackgroundEllipse.Opacity = 0.6;
}
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
{
this.BackgroundEllipse.Opacity = 0;
}
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
this.Clicked?.Invoke(this, e);
}
}
}
+3 -3
View File
@@ -4,7 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Daybreak.Controls"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:behaviors="clr-namespace:Daybreak.Behaviors"
xmlns:converters="clr-namespace:Daybreak.Converters"
x:Name="_this"
@@ -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}}"
+32 -56
View File
@@ -1,68 +1,44 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Extensions;
using System.Windows.Media;
namespace Daybreak.Controls
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for TileButton.xaml
/// </summary>
public partial class TileButton : UserControl
{
/// <summary>
/// Interaction logic for TileButton.xaml
/// </summary>
public partial class TileButton : UserControl
public event EventHandler? Clicked;
[GenerateDependencyProperty]
public bool highlighted;
[GenerateDependencyProperty(InitialValue = "")]
public string title = string.Empty;
[GenerateDependencyProperty]
public FrameworkElement InnerContent = default!;
[GenerateDependencyProperty]
public Brush HighlightColor = default!;
public TileButton()
{
public event EventHandler Clicked;
this.InitializeComponent();
}
public static readonly DependencyProperty HighlightedProperty =
DependencyProperty.Register("Highlighted", typeof(bool), typeof(TileButton), null);
public static readonly DependencyProperty HighlightColorProperty =
DependencyProperty.Register("HighlightColor", typeof(Brush), typeof(TileButton), null);
public static readonly DependencyProperty InnerContentProperty =
DependencyProperty.Register("InnerContent", typeof(FrameworkElement), typeof(TileButton), null);
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(TileButton), null);
private void Grid_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
this.Highlighted = true;
}
public TileButton()
{
this.InitializeComponent();
}
private void Grid_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
this.Highlighted = false;
}
public bool Highlighted
{
get => (bool)this.GetValue(HighlightedProperty);
set => this.SetValue(HighlightedProperty, value);
}
public string Title
{
get => this.GetValue(TitleProperty) as string;
set => this.SetValue(TitleProperty, value);
}
public FrameworkElement InnerContent
{
get => this.GetValue(InnerContentProperty) as FrameworkElement;
set => this.SetValue(InnerContentProperty, value);
}
public Brush HighlightColor
{
get => this.GetValue(HighlightColorProperty) as Brush;
set => this.SetValue(HighlightColorProperty, value);
}
private void Grid_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
this.Highlighted = true;
}
private void Grid_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
this.Highlighted = false;
}
private void Rectangle_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Clicked?.Invoke(this, e);
}
private void Rectangle_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
this.Clicked?.Invoke(this, e);
}
}
@@ -1,11 +1,13 @@
using Daybreak.Models.Browser;
using Daybreak.Configuration;
using Daybreak.Models.Browser;
using Daybreak.Models.Builds;
using Daybreak.Services.BuildTemplates;
using Daybreak.Services.Configuration;
using Daybreak.Utils;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Web.WebView2.Core;
using System;
using System.Configuration;
using System.Diagnostics;
using System.Extensions;
using System.Threading.Tasks;
@@ -22,25 +24,29 @@ namespace Daybreak.Controls
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
public partial class ChromiumBrowserWrapper : UserControl
{
public static readonly DependencyProperty AddressProperty =
DependencyPropertyExtensions.Register<ChromiumBrowserWrapper, string>(nameof(Address));
private const string BrowserDownloadLink = "https://developer.microsoft.com/en-us/microsoft-edge/webview2/";
public event EventHandler<string> FavoriteUriChanged;
public event EventHandler MaximizeClicked;
public event EventHandler<Build> BuildDecoded;
private static CoreWebView2Environment? coreWebView2Environment;
private IConfigurationManager configurationManager;
private ILogger<ChromiumBrowserWrapper> logger;
private IBuildTemplateManager buildTemplateManager;
private CoreWebView2Environment coreWebView2Environment;
public event EventHandler<string>? FavoriteUriChanged;
public event EventHandler? MaximizeClicked;
public event EventHandler<Build>? BuildDecoded;
private ILiveOptions<ApplicationConfiguration>? liveOptions;
private ILogger<ChromiumBrowserWrapper>? logger;
private IBuildTemplateManager? buildTemplateManager;
[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]
@@ -48,9 +54,20 @@ namespace Daybreak.Controls
[GenerateDependencyProperty]
private bool navigating;
[GenerateDependencyProperty]
private string favoriteAddress;
[GenerateDependencyProperty]
private string address;
private string favoriteAddress = string.Empty;
[GenerateDependencyProperty(InitialValue = false)]
private bool preventDispose;
public string Address
{
get => this.GetTypedValue<string>(AddressProperty);
set
{
if (this.BrowserSupported is true)
{
this.SetValue(AddressProperty, value);
}
}
}
public ChromiumBrowserWrapper()
{
@@ -67,12 +84,21 @@ namespace Daybreak.Controls
}
}
public async void InitializeBrowser(
IConfigurationManager configurationManager,
public async Task InitializeDefaultBrowser()
{
var options = Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<ILiveOptions<ApplicationConfiguration>>();
var buildTemplateManager = Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IBuildTemplateManager>();
var logger = Launch.Launcher.Instance.ApplicationServiceProvider.GetRequiredService<ILogger<ChromiumBrowserWrapper>>();
await this.InitializeDefaultBrowser(options, buildTemplateManager, logger);
}
public async Task InitializeDefaultBrowser(
ILiveOptions<ApplicationConfiguration> liveOptions,
IBuildTemplateManager buildTemplateManager,
ILogger<ChromiumBrowserWrapper> logger)
{
this.configurationManager = configurationManager;
this.liveOptions = liveOptions;
this.buildTemplateManager = buildTemplateManager;
this.logger = logger;
this.InitializeEnvironment();
@@ -86,7 +112,7 @@ namespace Daybreak.Controls
private void InitializeEnvironment()
{
if (this.configurationManager.GetConfiguration().BrowsersEnabled is false)
if (this.liveOptions!.Value.BrowsersEnabled is false)
{
this.BrowserSupported = false;
return;
@@ -94,12 +120,13 @@ namespace Daybreak.Controls
try
{
this.coreWebView2Environment = System.Extensions.TaskExtensions.RunSync(() => CoreWebView2Environment.CreateAsync(null, "BrowserData", null));
coreWebView2Environment ??= System.Extensions.TaskExtensions.RunSync(() => CoreWebView2Environment.CreateAsync(null, "BrowserData", null));
this.BrowserSupported = true;
}
catch(Exception e)
{
this.logger.LogWarning($"Browser initialization failed. Details: {e}");
this.logger!.LogWarning($"Browser initialization failed. Details: {e}");
this.BrowserSupported = false;
}
}
@@ -109,9 +136,10 @@ namespace Daybreak.Controls
if (this.BrowserSupported is true)
{
this.WebBrowser.IsEnabled = true;
await this.WebBrowser.EnsureCoreWebView2Async(this.coreWebView2Environment);
this.AddressBarReadonly = this.configurationManager.GetConfiguration().AddressBarReadonly;
this.CanDownloadBuild = this.configurationManager.GetConfiguration().ExperimentalFeatures.DynamicBuildLoading;
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;
this.WebBrowser.NavigationStarting += (browser, args) =>
{
@@ -125,7 +153,7 @@ namespace Daybreak.Controls
}
};
this.WebBrowser.NavigationCompleted += (browser, args) => this.Navigating = false;
this.WebBrowser.WebMessageReceived += this.CoreWebView2_WebMessageReceived;
this.WebBrowser.WebMessageReceived += this.CoreWebView2_WebMessageReceived!;
this.WebBrowser.CoreWebView2.Settings.AreDevToolsEnabled = false;
this.WebBrowser.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
if (this.CanDownloadBuild)
@@ -162,7 +190,7 @@ namespace Daybreak.Controls
{
var newAddress = sender.As<TextBox>().Text;
newAddress = SanitizeAddress(newAddress);
if (newAddress is null)
if (newAddress.IsNullOrWhiteSpace())
{
return;
}
@@ -175,24 +203,30 @@ namespace Daybreak.Controls
private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs args)
{
BrowserPayload payload = default;
BrowserPayload payload = default!;
try
{
payload = args.WebMessageAsJson.Deserialize<BrowserPayload>();
}
catch(Exception e)
{
this.logger.LogError(e, $"Exception encountered when deserializing {nameof(BrowserPayload)}");
this.logger!.LogError(e, $"Exception encountered when deserializing {nameof(BrowserPayload)}");
}
if (payload?.Key == BrowserPayload.PayloadKeys.ContextMenu)
{
var contextMenuPayload = args.WebMessageAsJson.Deserialize<BrowserPayload<OnContextMenuPayload>>();
var maybeTemplate = contextMenuPayload.Value.Selection;
var maybeTemplate = contextMenuPayload.Value!.Selection;
if (string.IsNullOrWhiteSpace(maybeTemplate))
{
return;
}
if (this.buildTemplateManager is null)
{
return;
}
if (this.buildTemplateManager.IsTemplate(maybeTemplate) is false)
{
return;
@@ -211,7 +245,7 @@ namespace Daybreak.Controls
}
catch(Exception e)
{
this.logger.LogWarning($"Exception when decoding template {maybeTemplate}. Details {e}");
this.logger!.LogWarning($"Exception when decoding template {maybeTemplate}. Details {e}");
}
});
}
@@ -226,6 +260,11 @@ namespace Daybreak.Controls
private void UserControl_Unloaded(object sender, RoutedEventArgs e)
{
if (this.PreventDispose)
{
return;
}
this.WebBrowser?.Dispose();
}
@@ -284,7 +323,7 @@ namespace Daybreak.Controls
{
if (string.IsNullOrWhiteSpace(address))
{
return null;
return default!;
}
if (address.StartsWith("www") is false &&
@@ -298,7 +337,7 @@ namespace Daybreak.Controls
}
Uri.TryCreate(address, UriKind.Absolute, out var uri);
return uri?.ToString();
return uri?.ToString() ?? string.Empty;
}
}
}
@@ -10,7 +10,7 @@ namespace Daybreak.Controls
{
public CircularLoadingWidget()
{
InitializeComponent();
this.InitializeComponent();
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
+2 -15
View File
@@ -1,17 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Controls;
namespace Daybreak.Controls
{
@@ -22,7 +9,7 @@ namespace Daybreak.Controls
{
public AvatarGlyph()
{
InitializeComponent();
this.InitializeComponent();
}
}
}
+22
View File
@@ -0,0 +1,22 @@
<UserControl x:Class="Daybreak.Controls.Glyphs.BadGlyph"
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.Glyphs"
mc:Ignorable="d"
x:Name="_this"
d:DesignHeight="450" d:DesignWidth="800">
<Viewbox>
<Grid>
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
StrokeThickness="1"
Width="32"
Height="32"/>
<Line X1="8" Y1="8" X2="24" Y2="24"
Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"/>
<Line X1="24" Y1="8" X2="8" Y2="24"
Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"/>
</Grid>
</Viewbox>
</UserControl>
+14
View File
@@ -0,0 +1,14 @@
using System.Windows.Controls;
namespace Daybreak.Controls.Glyphs;
/// <summary>
/// Interaction logic for BadGlyph.xaml
/// </summary>
public partial class BadGlyph : UserControl
{
public BadGlyph()
{
this.InitializeComponent();
}
}
+18
View File
@@ -0,0 +1,18 @@
<UserControl x:Class="Daybreak.Controls.CogGlyph"
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">
<Viewbox>
<Grid>
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" VerticalAlignment="Center" HorizontalAlignment="Center"
Data="m76.89,45.018c0,-1.587 -0.151,-3.138 -0.383,-4.66l11.227,-6.48l-11.639,-20.136l-11.616,6.47c-2.421,-1.931 -5.479,-3.506 -8.479,-4.664l0,-11.548l-22,0l0,11.548c-4,1.112 -5.649,2.617 -8.005,4.448l-11.251,-6.604l-11.914,20.006l11.12,6.604c-0.262,1.643 -0.45,3.308 -0.45,5.016c0,1.587 0.153,3.136 0.376,4.658l-11.228,6.484l11.634,20.135l11.424,-6.472c2.431,1.933 4.294,3.506 8.294,4.665l0,12.512l22,0l0,-12.512c3,-1.115 5.839,-2.618 8.19,-4.449l11.348,6.604l11.96,-20.006l-11.095,-6.603c0.258,-1.64 0.487,-3.304 0.487,-5.016zm-31.704,14.137c-7.799,0 -14.138,-6.332 -14.138,-14.138c0,-7.808 6.339,-14.136 14.138,-14.136c7.81,0 14.14,6.328 14.14,14.136c-0.001,7.806 -6.331,14.138 -14.14,14.138z"></Path>
<Path Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" VerticalAlignment="Center" HorizontalAlignment="Center"
Data="m56.5,89l-22,0c-1.381,0 -2.5,-1.119 -2.5,-2.5l0,-10.199c-2.612,-0.955 -4.464,-2.126 -6.274,-3.49l-10.229,5.671c-1.192,0.661 -2.694,0.244 -3.377,-0.936l-11.633,-20.135c-0.331,-0.574 -0.422,-1.257 -0.25,-1.897s0.591,-1.188 1.165,-1.519l9.794,-5.654c-0.121,-1.164 -0.181,-2.262 -0.181,-3.323c0,-1.317 0.112,-2.592 0.254,-3.721l-9.656,-5.75c-0.57,-0.34 -0.982,-0.893 -1.145,-1.537c-0.163,-0.644 -0.063,-1.326 0.279,-1.896l11.977,-20.006c0.702,-1.173 2.218,-1.564 3.399,-0.878l9.927,5.762c1.618,-1.213 3.362,-2.346 5.949,-3.273l0,-10.219c0.001,-1.381 1.12,-2.5 2.501,-2.5l22,0c1.381,0 2.5,1.119 2.5,2.5l0,10.377c2.124,0.938 4.104,2.059 5.919,3.35l9.939,-5.657c1.19,-0.677 2.713,-0.269 3.4,0.922l11.639,20.135c0.332,0.574 0.423,1.257 0.251,1.897s-0.591,1.188 -1.165,1.519l-9.781,5.646c0.126,1.165 0.188,2.266 0.188,3.329c0,1.327 -0.108,2.597 -0.246,3.717l9.692,5.752c0.571,0.339 0.983,0.891 1.147,1.533c0.163,0.644 0.065,1.325 -0.274,1.896l-11.897,20.005c-0.703,1.183 -2.234,1.573 -3.416,0.876l-9.798,-5.765c-1.782,1.25 -3.634,2.29 -5.598,3.144l0,10.324c0,1.381 -1.119,2.5 -2.5,2.5zm-19.5,-5l17,0l0,-9.512c0,-1.045 0.649,-1.979 1.629,-2.344c2.624,-0.975 5.004,-2.309 7.275,-4.078c0.809,-0.629 1.921,-0.702 2.804,-0.182l9.078,5.341l9.347,-15.716l-8.974,-5.325c-0.88,-0.522 -1.354,-1.528 -1.194,-2.538c0.198,-1.259 0.425,-2.923 0.425,-4.629c0,-1.314 -0.116,-2.716 -0.354,-4.284c-0.154,-1.018 0.33,-2.026 1.222,-2.541l9.061,-5.23l-9.145,-15.818l-9.208,5.241c-0.888,0.505 -1.995,0.42 -2.795,-0.219c-2.199,-1.754 -4.747,-3.196 -7.57,-4.286c-0.964,-0.372 -1.6,-1.299 -1.6,-2.332l0,-9.548l-17.001,0l0,9.548c0,1.123 -0.748,2.107 -1.83,2.408c-3.47,0.965 -5.073,2.212 -7.293,3.938l-0.098,0.076c-0.804,0.625 -1.909,0.7 -2.789,0.188l-9.243,-5.365l-9.423,15.739l8.937,5.321c0.879,0.524 1.351,1.531 1.189,2.542c-0.202,1.27 -0.435,2.943 -0.435,4.622c0,1.318 0.112,2.724 0.342,4.297c0.148,1.013 -0.337,2.015 -1.224,2.526l-9.065,5.234l9.151,15.842l9.525,-5.28c0.883,-0.49 1.976,-0.4 2.768,0.229c2.384,1.896 4.207,3.214 7.684,4.221c1.069,0.31 1.804,1.29 1.804,2.402l0,9.512zm8.186,-22.345c-9.174,0 -16.638,-7.464 -16.638,-16.638c0,-9.173 7.464,-16.636 16.638,-16.636c9.175,0 16.64,7.463 16.64,16.636c-0.001,9.174 -7.466,16.638 -16.64,16.638zm0,-28.273c-6.417,0 -11.638,5.22 -11.638,11.636c0,6.417 5.221,11.638 11.638,11.638c6.418,0 11.64,-5.221 11.64,-11.638c-0.001,-6.416 -5.222,-11.636 -11.64,-11.636z"></Path>
</Grid>
</Viewbox>
</UserControl>
+14
View File
@@ -0,0 +1,14 @@
using System.Windows.Controls;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for CogGlyph.xaml
/// </summary>
public partial class CogGlyph : UserControl
{
public CogGlyph()
{
this.InitializeComponent();
}
}
@@ -22,7 +22,7 @@ namespace Daybreak.Controls
{
public ExperimentGlyph()
{
InitializeComponent();
this.InitializeComponent();
}
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ namespace Daybreak.Controls
{
public FileGlyph()
{
InitializeComponent();
this.InitializeComponent();
}
}
}
+5 -2
View File
@@ -10,11 +10,14 @@
<Viewbox>
<Grid>
<Line Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
X1="15" X2="26" Y1="11" Y2="0"></Line>
X1="15" X2="26" Y1="11" Y2="0"
StrokeThickness="2"></Line>
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Width="4" Height="4"
Width="4" Height="4"
StrokeThickness="2"
Margin="8,13,13,8"></Ellipse>
<Path Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
StrokeThickness="2"
Data="m15.025,0l-12.7,11.3c-3.1,3.1 -3.1,8.2 0,11.3s8.2,3.1 11.3,0l12.4,-11.6"></Path>
</Grid>
</Viewbox>
@@ -22,7 +22,7 @@ namespace Daybreak.Controls
{
public FireballGlyph()
{
InitializeComponent();
this.InitializeComponent();
}
}
}
@@ -22,7 +22,7 @@ namespace Daybreak.Controls
{
public GoldenArrowGlyph()
{
InitializeComponent();
this.InitializeComponent();
}
}
}
+20
View File
@@ -0,0 +1,20 @@
<UserControl x:Class="Daybreak.Controls.Glyphs.GoodGlyph"
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.Glyphs"
mc:Ignorable="d"
x:Name="_this"
d:DesignHeight="450" d:DesignWidth="800">
<Viewbox>
<Grid>
<Ellipse Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
StrokeThickness="1"
Width="32"
Height="32"/>
<Polyline Stroke="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Points="26,8 13.625,22.714284896850586 8,16.02597427368164 "></Polyline>
</Grid>
</Viewbox>
</UserControl>
@@ -0,0 +1,14 @@
using System.Windows.Controls;
namespace Daybreak.Controls.Glyphs;
/// <summary>
/// Interaction logic for GoodGlyph.xaml
/// </summary>
public partial class GoodGlyph : UserControl
{
public GoodGlyph()
{
this.InitializeComponent();
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ namespace Daybreak.Controls
{
public LogsGlyph()
{
InitializeComponent();
this.InitializeComponent();
}
}
}
@@ -9,7 +9,7 @@ namespace Daybreak.Controls
/// </summary>
public partial class RefreshGlyph : UserControl
{
public event EventHandler Clicked;
public event EventHandler? Clicked;
public RefreshGlyph()
{
+2 -2
View File
@@ -9,11 +9,11 @@ namespace Daybreak.Controls
/// </summary>
public partial class StarGlyph : UserControl
{
public event EventHandler Clicked;
public event EventHandler? Clicked;
public StarGlyph()
{
InitializeComponent();
this.InitializeComponent();
}
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
@@ -0,0 +1,17 @@
<UserControl x:Class="Daybreak.Controls.ThreeDotsGlyph"
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"
mc:Ignorable="d"
x:Name="_this"
d:DesignHeight="450" d:DesignWidth="800">
<Viewbox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Ellipse Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Height="1" Width="1"></Ellipse>
<Ellipse Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Height="1" Width="1"></Ellipse>
<Ellipse Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Height="1" Width="1"></Ellipse>
</StackPanel>
</Viewbox>
</UserControl>
@@ -0,0 +1,14 @@
using System.Windows.Controls;
namespace Daybreak.Controls;
/// <summary>
/// Interaction logic for ThreeDotsGlyph.xaml
/// </summary>
public partial class ThreeDotsGlyph : UserControl
{
public ThreeDotsGlyph()
{
this.InitializeComponent();
}
}
+1 -1
View File
@@ -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;
+93
View File
@@ -0,0 +1,93 @@
<UserControl x:Class="Daybreak.Controls.MenuList"
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"
xmlns:buttons="clr-namespace:Daybreak.Controls.Buttons"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<StackPanel>
<buttons:MenuButton Title="Game companion"
Foreground="White"
HighlightColor="White"
Height="30"
Clicked="GameCompanionButton_Clicked">
<buttons:MenuButton.InnerContent>
<local:GoldenArrowGlyph Foreground="White"
Width="40"></local:GoldenArrowGlyph>
</buttons:MenuButton.InnerContent>
</buttons:MenuButton>
<buttons:MenuButton Title="Manage builds"
Foreground="White"
HighlightColor="White"
Height="30"
Clicked="ManageBuildsButton_Clicked">
<buttons:MenuButton.InnerContent>
<local:FireballGlyph Foreground="White"
Width="40"></local:FireballGlyph>
</buttons:MenuButton.InnerContent>
</buttons:MenuButton>
<buttons:MenuButton Title="Account settings"
Foreground="White"
HighlightColor="White"
Height="30"
Clicked="AccountSettingsButton_Clicked">
<buttons:MenuButton.InnerContent>
<local:AvatarGlyph Foreground="White"
Width="40"></local:AvatarGlyph>
</buttons:MenuButton.InnerContent>
</buttons:MenuButton>
<buttons:MenuButton Title="Guildwars settings"
Foreground="White"
HighlightColor="White"
Height="30"
Clicked="GuildwarsSettingsButton_Clicked">
<buttons:MenuButton.InnerContent>
<local:FileGlyph Foreground="White"
Width="40"></local:FileGlyph>
</buttons:MenuButton.InnerContent>
</buttons:MenuButton>
<buttons:MenuButton Title="Launcher settings"
Foreground="White"
HighlightColor="White"
Height="30"
Clicked="LauncherSettingsButton_Clicked">
<buttons:MenuButton.InnerContent>
<local:CogGlyph Foreground="White"
Width="40"
Height="20"></local:CogGlyph>
</buttons:MenuButton.InnerContent>
</buttons:MenuButton>
<buttons:MenuButton Title="Experimental settings"
Foreground="White"
HighlightColor="White"
Height="30"
Clicked="ExperimentalSettingsButton_Clicked">
<buttons:MenuButton.InnerContent>
<local:ExperimentGlyph Foreground="White"
Width="40"></local:ExperimentGlyph>
</buttons:MenuButton.InnerContent>
</buttons:MenuButton>
<buttons:MenuButton Title="Manage client version"
Foreground="White"
HighlightColor="White"
Height="30"
Clicked="VersionManagementButton_Clicked">
<buttons:MenuButton.InnerContent>
<local:StaticGlyph Foreground="White"
Width="40"></local:StaticGlyph>
</buttons:MenuButton.InnerContent>
</buttons:MenuButton>
<buttons:MenuButton Title="Logs"
Foreground="White"
HighlightColor="White"
Height="30"
Clicked="LogsButton_Clicked">
<buttons:MenuButton.InnerContent>
<local:LogsGlyph Foreground="White"
Width="40"></local:LogsGlyph>
</buttons:MenuButton.InnerContent>
</buttons:MenuButton>
</StackPanel>
</UserControl>
+78
View File
@@ -0,0 +1,78 @@
using Daybreak.Configuration;
using Daybreak.Launch;
using Daybreak.Services.Navigation;
using Daybreak.Views;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Configuration;
using System.Windows.Controls;
namespace Daybreak.Controls
{
/// <summary>
/// Interaction logic for MenuList.xaml
/// </summary>
public partial class MenuList : UserControl
{
public MenuList()
{
this.InitializeComponent();
}
private void GameCompanionButton_Clicked(object sender, EventArgs e)
{
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
viewManager.ShowView<CompanionView>();
}
private void AccountSettingsButton_Clicked(object sender, EventArgs e)
{
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
viewManager.ShowView<AccountsView>();
}
private void GuildwarsSettingsButton_Clicked(object sender, EventArgs e)
{
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
viewManager.ShowView<ExecutablesView>();
}
private void LauncherSettingsButton_Clicked(object sender, EventArgs e)
{
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
viewManager.ShowView<SettingsView>();
}
private void ExperimentalSettingsButton_Clicked(object sender, EventArgs e)
{
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
viewManager.ShowView<ExperimentalSettingsView>();
}
private void ManageBuildsButton_Clicked(object sender, EventArgs e)
{
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
var options = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<ILiveOptions<ApplicationConfiguration>>();
if (options.Value.ExperimentalFeatures.DownloadIcons)
{
viewManager.ShowView<IconDownloadView>();
}
else
{
viewManager.ShowView<BuildsListView>();
}
}
private void VersionManagementButton_Clicked(object sender, EventArgs e)
{
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
viewManager.ShowView<VersionManagementView>();
}
private void LogsButton_Clicked(object sender, EventArgs e)
{
var viewManager = Launcher.Instance.ApplicationServiceProvider.GetRequiredService<IViewManager>();
viewManager.ShowView<LogsView>();
}
}
}
+35
View File
@@ -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>
+42
View File
@@ -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 = default!;
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);
}
}
}
@@ -14,22 +14,22 @@ namespace Daybreak.Controls
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
public partial class AccountTemplate : UserControl
{
public event EventHandler RemoveClicked;
public event EventHandler DefaultClicked;
public event EventHandler? RemoveClicked;
public event EventHandler? DefaultClicked;
[GenerateDependencyProperty]
private string username;
private string username = string.Empty;
[GenerateDependencyProperty]
private string password;
private string password = string.Empty;
[GenerateDependencyProperty]
private string characterName;
private string characterName = string.Empty;
[GenerateDependencyProperty]
private bool isDefault;
public AccountTemplate()
{
this.InitializeComponent();
this.DataContextChanged += AccountTemplate_DataContextChanged;
this.DataContextChanged += this.AccountTemplate_DataContextChanged;
}
private void AccountTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
@@ -14,8 +14,8 @@ namespace Daybreak.Controls
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
public partial class AttributeTemplate : UserControl
{
public event EventHandler<AttributeEntry> HelpClicked;
public event EventHandler<AttributeEntry> AttributeChanged;
public event EventHandler<AttributeEntry>? HelpClicked;
public event EventHandler<AttributeEntry>? AttributeChanged;
[GenerateDependencyProperty(InitialValue = false)]
private bool canAdd;
@@ -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)
@@ -9,11 +9,11 @@ namespace Daybreak.Controls
/// </summary>
public partial class BuildEntryTemplate : UserControl
{
public event EventHandler<BuildEntry> RemoveClicked;
public event EventHandler<BuildEntry>? RemoveClicked;
public BuildEntryTemplate()
{
InitializeComponent();
this.InitializeComponent();
}
private void BinButton_Clicked(object sender, EventArgs e)
+32 -9
View File
@@ -4,11 +4,12 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Daybreak.Controls"
xmlns:interactivity="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:interactivity="http://schemas.microsoft.com/xaml/behaviors"
xmlns:behaviors="clr-namespace:Daybreak.Behaviors"
xmlns:converters="clr-namespace:Daybreak.Converters"
mc:Ignorable="d"
x:Name="_this"
Unloaded="BuildTemplate_Unloaded"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="Transparent" MouseLeftButtonDown="Grid_MouseLeftButtonDown">
<Grid.RowDefinitions>
@@ -156,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>
+162 -77
View File
@@ -1,13 +1,18 @@
using Daybreak.Models.Builds;
using Daybreak.Configuration;
using Daybreak.Models.Builds;
using Daybreak.Services.BuildTemplates;
using Daybreak.Services.Configuration;
using Daybreak.Services.IconRetrieve;
using Daybreak.Utils;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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.Controls;
using System.Windows.Extensions;
@@ -26,31 +31,35 @@ namespace Daybreak.Controls
private bool suppressBuildChanged = false;
private bool loadedProperties = false;
private BuildEntry loadedBuild;
private SkillTemplate selectingSkillTemplate;
private IIconBrowser? iconBrowser;
private BuildEntry? loadedBuild;
private SkillTemplate? selectingSkillTemplate;
private CancellationTokenSource? cancellationTokenSource = new();
public event EventHandler BuildChanged;
public event EventHandler? BuildChanged;
[GenerateDependencyProperty]
private Profession primaryProfession;
private string skillSearchText = string.Empty;
[GenerateDependencyProperty]
private Profession secondaryProfession;
private Profession primaryProfession = default!;
[GenerateDependencyProperty]
private Skill skill0;
private Profession secondaryProfession = default!;
[GenerateDependencyProperty]
private Skill skill1;
private Skill skill0 = default!;
[GenerateDependencyProperty]
private Skill skill2;
private Skill skill1 = default!;
[GenerateDependencyProperty]
private Skill skill3;
private Skill skill2 = default!;
[GenerateDependencyProperty]
private Skill skill4;
private Skill skill3 = default!;
[GenerateDependencyProperty]
private Skill skill5;
private Skill skill4 = default!;
[GenerateDependencyProperty]
private Skill skill6;
private Skill skill5 = default!;
[GenerateDependencyProperty]
private Skill skill7;
private Skill skill6 = default!;
[GenerateDependencyProperty]
private Skill skill7 = default!;
public ObservableCollection<Skill> AvailableSkills { get; } = new ObservableCollection<Skill>();
public ObservableCollection<AttributeEntry> Attributes { get; } = new ObservableCollection<AttributeEntry>();
public ObservableCollection<Profession> Professions { get; } = new ObservableCollection<Profession>(Profession.Professions);
@@ -59,16 +68,18 @@ namespace Daybreak.Controls
{
this.InitializeComponent();
this.InitializeProperties();
this.DataContextChanged += BuildTemplate_DataContextChanged;
this.DataContextChanged += this.BuildTemplate_DataContextChanged;
}
public void InitializeTemplate(
IIconRetriever iconRetriever,
IConfigurationManager configurationManager,
public async void InitializeTemplate(
IIconCache iconRetriever,
IIconBrowser iconBrowser,
ILiveOptions<ApplicationConfiguration> liveOptions,
IBuildTemplateManager buildTemplateManager,
ILogger<ChromiumBrowserWrapper> logger)
{
this.SkillBrowser.InitializeBrowser(configurationManager, buildTemplateManager, logger);
this.iconBrowser = iconBrowser.ThrowIfNull();
await this.SkillBrowser.InitializeDefaultBrowser(liveOptions, buildTemplateManager, logger);
this.SkillTemplate0.InitializeSkillTemplate(iconRetriever);
this.SkillTemplate1.InitializeSkillTemplate(iconRetriever);
this.SkillTemplate2.InitializeSkillTemplate(iconRetriever);
@@ -77,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)
@@ -91,12 +105,13 @@ namespace Daybreak.Controls
{
if (e.Property == PrimaryProfessionProperty)
{
this.loadedBuild.Build.Primary = this.PrimaryProfession;
this.loadedBuild!.Build!.Primary = this.PrimaryProfession;
}
else
{
this.loadedBuild.Build.Secondary = this.SecondaryProfession;
this.loadedBuild!.Build!.Secondary = this.SecondaryProfession;
}
this.LoadSkills();
this.LoadAttributes();
if (this.suppressBuildChanged is false)
@@ -116,19 +131,24 @@ namespace Daybreak.Controls
{
if (this.suppressBuildChanged is false)
{
this.loadedBuild.Build.Skills[0] = this.Skill0;
this.loadedBuild.Build.Skills[1] = this.Skill1;
this.loadedBuild.Build.Skills[2] = this.Skill2;
this.loadedBuild.Build.Skills[3] = this.Skill3;
this.loadedBuild.Build.Skills[4] = this.Skill4;
this.loadedBuild.Build.Skills[5] = this.Skill5;
this.loadedBuild.Build.Skills[6] = this.Skill6;
this.loadedBuild.Build.Skills[7] = this.Skill7;
this.loadedBuild!.Build!.Skills[0] = this.Skill0;
this.loadedBuild!.Build!.Skills[1] = this.Skill1;
this.loadedBuild!.Build!.Skills[2] = this.Skill2;
this.loadedBuild!.Build!.Skills[3] = this.Skill3;
this.loadedBuild!.Build!.Skills[4] = this.Skill4;
this.loadedBuild!.Build!.Skills[5] = this.Skill5;
this.loadedBuild!.Build!.Skills[6] = this.Skill6;
this.loadedBuild!.Build!.Skills[7] = this.Skill7;
this.BuildChanged?.Invoke(this, new EventArgs());
}
}
}
private void BuildTemplate_Unloaded(object sender, RoutedEventArgs e)
{
this.cancellationTokenSource?.Cancel();
}
private void InitializeProperties()
{
this.PrimaryProfession = Profession.None;
@@ -166,17 +186,17 @@ namespace Daybreak.Controls
if (this.PrimaryProfession != Profession.None)
{
possibleAttributes.Add(new AttributeEntry { Attribute = this.PrimaryProfession.PrimaryAttribute });
possibleAttributes.AddRange(this.PrimaryProfession.Attributes.Select(a => new AttributeEntry { Attribute = a }));
possibleAttributes.AddRange(this.PrimaryProfession.Attributes!.Select(a => new AttributeEntry { Attribute = a }));
}
if (this.SecondaryProfession != Profession.None && this.SecondaryProfession != this.PrimaryProfession)
{
possibleAttributes.AddRange(this.SecondaryProfession.Attributes.Select(a => new AttributeEntry { Attribute = a }));
possibleAttributes.AddRange(this.SecondaryProfession.Attributes!.Select(a => new AttributeEntry { Attribute = a }));
}
this.Attributes.ClearAnd().AddRange(possibleAttributes.Select(entry =>
{
var maybePresentAttribute = this.loadedBuild.Build.Attributes.Where(buildEntry => entry.Attribute == buildEntry.Attribute).FirstOrDefault();
var maybePresentAttribute = this.loadedBuild!.Build!.Attributes.Where(buildEntry => entry.Attribute == buildEntry.Attribute).FirstOrDefault();
if (maybePresentAttribute is null)
{
return entry;
@@ -186,73 +206,78 @@ namespace Daybreak.Controls
return entry;
}));
this.loadedBuild.Build.Attributes = this.Attributes.ToList();
this.loadedBuild!.Build!.Attributes = this.Attributes.ToList();
}
private void LoadSkills()
private async void LoadSkills()
{
var possibleSkills = Skill.Skills
.Where(s => s.Profession == PrimaryProfession || s.Profession == SecondaryProfession || s.Profession == Profession.None)
.Where(s => s != Skill.NoSkill)
.OrderBy(s => s.Name);
this.AvailableSkills.ClearAnd().AddRange(possibleSkills);
if (this.Skill0.Profession != PrimaryProfession &&
this.Skill0.Profession != SecondaryProfession &&
if (this.Skill0.Profession != this.PrimaryProfession &&
this.Skill0.Profession != this.SecondaryProfession &&
this.Skill0.Profession != Profession.None)
{
this.Skill0 = Skill.NoSkill;
}
if (this.Skill1.Profession != PrimaryProfession &&
this.Skill1.Profession != SecondaryProfession &&
if (this.Skill1.Profession != this.PrimaryProfession &&
this.Skill1.Profession != this.SecondaryProfession &&
this.Skill1.Profession != Profession.None)
{
this.Skill1 = Skill.NoSkill;
}
if (this.Skill2.Profession != PrimaryProfession &&
this.Skill2.Profession != SecondaryProfession &&
if (this.Skill2.Profession != this.PrimaryProfession &&
this.Skill2.Profession != this.SecondaryProfession &&
this.Skill2.Profession != Profession.None)
{
this.Skill2 = Skill.NoSkill;
}
if (this.Skill3.Profession != PrimaryProfession &&
this.Skill3.Profession != SecondaryProfession &&
if (this.Skill3.Profession != this.PrimaryProfession &&
this.Skill3.Profession != this.SecondaryProfession &&
this.Skill3.Profession != Profession.None)
{
this.Skill3 = Skill.NoSkill;
}
if (this.Skill4.Profession != PrimaryProfession &&
this.Skill4.Profession != SecondaryProfession &&
if (this.Skill4.Profession != this.PrimaryProfession &&
this.Skill4.Profession != this.SecondaryProfession &&
this.Skill4.Profession != Profession.None)
{
this.Skill4 = Skill.NoSkill;
}
if (this.Skill5.Profession != PrimaryProfession &&
this.Skill5.Profession != SecondaryProfession &&
if (this.Skill5.Profession != this.PrimaryProfession &&
this.Skill5.Profession != this.SecondaryProfession &&
this.Skill5.Profession != Profession.None)
{
this.Skill5 = Skill.NoSkill;
}
if (this.Skill6.Profession != PrimaryProfession &&
this.Skill6.Profession != SecondaryProfession &&
if (this.Skill6.Profession != this.PrimaryProfession &&
this.Skill6.Profession != this.SecondaryProfession &&
this.Skill6.Profession != Profession.None)
{
this.Skill6 = Skill.NoSkill;
}
if (this.Skill7.Profession != PrimaryProfession &&
this.Skill7.Profession != SecondaryProfession &&
if (this.Skill7.Profession != this.PrimaryProfession &&
this.Skill7.Profession != this.SecondaryProfession &&
this.Skill7.Profession != Profession.None)
{
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;
var build = this.DataContext.As<BuildEntry>();
this.loadedBuild = build;
this.PrimaryProfession = build.Build.Primary;
this.PrimaryProfession = build.Build!.Primary;
this.SecondaryProfession = build.Build.Secondary;
this.Skill0 = build.Build.Skills[0];
this.Skill1 = build.Build.Skills[1];
@@ -274,24 +299,30 @@ namespace Daybreak.Controls
private void ShowInfoBrowser()
{
this.SkillBrowser.Width = 400;
this.SkillsListView.Width = 0;
if (this.SkillBrowser.BrowserSupported is true)
{
this.SkillBrowser.Width = 400;
this.SkillListContainer.Width = 0;
}
}
private void HideInfoBrowser()
{
this.SkillBrowser.Width = 0;
if (this.SkillBrowser.BrowserSupported is true)
{
this.SkillBrowser.Width = 0;
}
}
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)
@@ -301,7 +332,7 @@ namespace Daybreak.Controls
return;
}
this.BrowseToInfo(PrimaryProfession.Name);
this.BrowseToInfo(this.PrimaryProfession.Name!);
if (e is RoutedEventArgs routedEventArgs)
{
routedEventArgs.Handled = true;
@@ -315,20 +346,21 @@ namespace Daybreak.Controls
return;
}
this.BrowseToInfo(this.SecondaryProfession.Name);
this.BrowseToInfo(this.SecondaryProfession.Name!);
if (e is RoutedEventArgs routedEventArgs)
{
routedEventArgs.Handled = true;
}
}
private void AttributeTemplate_HelpClicked(object sender, AttributeEntry e)
private void AttributeTemplate_HelpClicked(object _, AttributeEntry e)
{
this.BrowseToInfo(e.Attribute.Name);
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());
}
@@ -337,16 +369,24 @@ 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>();
}
else
{
this.BrowseToInfo(skill.Name);
this.BrowseToInfo(skill.Name!);
}
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;
@@ -362,14 +402,14 @@ namespace Daybreak.Controls
this.selectingSkillTemplate.DataContext = sender.As<ListView>().SelectedItem;
this.HideSkillListView();
this.loadedBuild.Build.Skills[0] = Skill0;
this.loadedBuild.Build.Skills[1] = Skill1;
this.loadedBuild.Build.Skills[2] = Skill2;
this.loadedBuild.Build.Skills[3] = Skill3;
this.loadedBuild.Build.Skills[4] = Skill4;
this.loadedBuild.Build.Skills[5] = Skill5;
this.loadedBuild.Build.Skills[6] = Skill6;
this.loadedBuild.Build.Skills[7] = Skill7;
this.loadedBuild!.Build!.Skills[0] = this.Skill0;
this.loadedBuild!.Build!.Skills[1] = this.Skill1;
this.loadedBuild!.Build!.Skills[2] = this.Skill2;
this.loadedBuild!.Build!.Skills[3] = this.Skill3;
this.loadedBuild!.Build!.Skills[4] = this.Skill4;
this.loadedBuild!.Build!.Skills[5] = this.Skill5;
this.loadedBuild!.Build!.Skills[6] = this.Skill6;
this.loadedBuild!.Build!.Skills[7] = this.Skill7;
}
private void ListView_NavigateWithMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
@@ -388,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;
}
}
}
}
}
@@ -15,18 +15,18 @@ namespace Daybreak.Controls
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
public partial class GuildwarsPathTemplate : UserControl
{
public event EventHandler RemoveClicked;
public event EventHandler DefaultClicked;
public event EventHandler? RemoveClicked;
public event EventHandler? DefaultClicked;
[GenerateDependencyProperty]
private string path;
private string path = string.Empty;
[GenerateDependencyProperty]
private bool isDefault;
public GuildwarsPathTemplate()
{
this.InitializeComponent();
this.DataContextChanged += GuildwarsPathTemplate_DataContextChanged;
this.DataContextChanged += this.GuildwarsPathTemplate_DataContextChanged;
}
private void GuildwarsPathTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
@@ -0,0 +1,18 @@
<UserControl x:Class="Daybreak.Controls.LogMessageTemplate"
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="BoolToVisibilityConverter"></BooleanToVisibilityConverter>
</UserControl.Resources>
<Grid HorizontalAlignment="Stretch">
<TextBlock Text="{Binding ElementName=_this, Path=Message, Mode=OneWay}" Background="Transparent"
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
MouseLeftButtonDown="TextBox_MouseLeftButtonDown" MaxHeight="18" TextWrapping="Wrap"></TextBlock>
</Grid>
</UserControl>
@@ -0,0 +1,36 @@
using System.Windows.Extensions;
using System.Windows.Controls;
using System.Windows.Input;
using System.Extensions;
namespace Daybreak.Controls
{
/// <summary>
/// Interaction logic for LogTemplate.xaml
/// </summary>
public partial class LogMessageTemplate : UserControl
{
private bool expanded;
[GenerateDependencyProperty]
private string message = string.Empty;
public LogMessageTemplate()
{
this.InitializeComponent();
}
private void TextBox_MouseLeftButtonDown(object sender, MouseButtonEventArgs eventArgs)
{
this.expanded = !this.expanded;
if (this.expanded)
{
sender.As<TextBlock>().MaxHeight = double.MaxValue;
}
else
{
sender.As<TextBlock>().MaxHeight = 18;
}
}
}
}
@@ -15,17 +15,17 @@ namespace Daybreak.Controls.Templates
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
public partial class ScreenTemplate : UserControl
{
public event EventHandler<Screen> Clicked;
public event EventHandler<Screen>? Clicked;
[GenerateDependencyProperty]
private string screenId;
private string screenId = string.Empty;
[GenerateDependencyProperty]
private Brush highlight;
private Brush highlight = default!;
public ScreenTemplate()
{
this.InitializeComponent();
this.DataContextChanged += ScreenTemplate_DataContextChanged;
this.DataContextChanged += this.ScreenTemplate_DataContextChanged;
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
@@ -1,8 +1,9 @@
<UserControl x:Class="Daybreak.Controls.SkillTemplate"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
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.Controls"
mc:Ignorable="d"
x:Name="_this"
@@ -1,10 +1,6 @@
using Daybreak.Launch;
using Daybreak.Models.Builds;
using Daybreak.Models.Builds;
using Daybreak.Services.IconRetrieve;
using System;
using System.Extensions;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Extensions;
@@ -20,40 +16,44 @@ namespace Daybreak.Controls
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
public partial class SkillTemplate : UserControl
{
public event EventHandler<RoutedEventArgs> Clicked;
public event EventHandler RemoveClicked;
public event EventHandler<RoutedEventArgs>? Clicked;
public event EventHandler? RemoveClicked;
private IIconRetriever iconRetriever;
private IIconCache? iconRetriever;
[GenerateDependencyProperty]
private ImageSource imageSource;
private ImageSource imageSource = default!;
[GenerateDependencyProperty]
private double borderOpacity;
public SkillTemplate()
{
this.InitializeComponent();
this.DataContextChanged += SkillTemplate_DataContextChanged;
this.DataContextChanged += this.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 void SkillTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
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)
{
Task.Run(() => this.GetImageStream(skill)).ContinueWith((previousTask) =>
var maybeUri = await this.iconRetriever.GetIconUri(skill).ConfigureAwait(true);
if (maybeUri.ExtractValue() is Uri uri)
{
this.Dispatcher.Invoke(() =>
{
this.ImageSource = this.GetImageSource(previousTask.Result);
});
});
this.ImageSource = new BitmapImage(uri);
}
}
else if (this.ImageSource is not null)
{
@@ -90,32 +90,5 @@ namespace Daybreak.Controls
return false;
}
private async Task<Stream> GetImageStream(Skill skill)
{
if (this.iconRetriever is null)
{
return null;
}
var maybeStream = await this.iconRetriever.GetIcon(skill);
return maybeStream.ExtractValue();
}
private ImageSource GetImageSource(Stream stream)
{
if (stream is null)
{
return null;
}
return this.Dispatcher.Invoke(() =>
{
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = stream;
bitmapImage.CacheOption = BitmapCacheOption.OnDemand;
bitmapImage.EndInit();
return bitmapImage;
});
}
}
}
@@ -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;
}
}
+1 -1
View File
@@ -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)
@@ -0,0 +1,35 @@
using System;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Converters
{
public class MenuButtonHighlightConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType == typeof(double) &&
value is bool boolean)
{
return boolean ? 0.4 : 0;
}
else
{
throw new NotImplementedException();
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType == typeof(bool) &&
value is double doubleValue)
{
return doubleValue == 0.4;
}
else
{
throw new NotImplementedException();
}
}
}
}
+63 -17
View File
@@ -1,38 +1,65 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<OutputType>WinExe</OutputType>
<RootNamespace>Daybreak</RootNamespace>
<TargetFramework>net7.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<Platforms>AnyCPU</Platforms>
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<LangVersion>preview</LangVersion>
<ApplicationIcon>Daybreak.ico</ApplicationIcon>
<IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation>
<Version>0.9.2</Version>
<Version>0.9.7.4</Version>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
<UserSecretsId>cfb2a489-db80-448d-a969-80270f314c46</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.32" />
<PackageReference Include="LiteDB" Version="5.0.10" />
<None Include="..\.editorconfig" Link=".editorconfig" />
</ItemGroup>
<Target Name="AddUserSecrets" BeforeTargets="PrepareForBuild" Condition=" '$(UserSecretsId)' != '' ">
<PropertyGroup>
<UserSecretsFilePath Condition=" '$(OS)' == 'Windows_NT' ">
$([System.Environment]::GetFolderPath(SpecialFolder.UserProfile))\AppData\Roaming\Microsoft\UserSecrets\$(UserSecretsId)\secrets.json
</UserSecretsFilePath>
<UserSecretsFilePath Condition=" '$(OS)' == 'Unix' ">
$([System.Environment]::GetFolderPath(SpecialFolder.UserProfile))/.microsoft/usersecrets/$(UserSecretsId)/secrets.json
</UserSecretsFilePath>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="$(UserSecretsFilePath)" Condition="Exists($(UserSecretsFilePath))" />
</ItemGroup>
</Target>
<ItemGroup>
<PackageReference Include="LiteDB" Version="5.0.15" />
<PackageReference Include="Microsoft.CorrelationVector" Version="1.0.42" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.864.35" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NReco.Logging.File" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.1518.46" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="NReco.Logging.File" Version="1.1.5" />
<PackageReference Include="securifybv.ShellLink" Version="0.1.0" />
<PackageReference Include="Slim" Version="1.4.3" />
<PackageReference Include="System.Windows.Interactivity.WPF" Version="2.0.20525" />
<PackageReference Include="SystemExtensions.NetStandard" Version="1.3.0" />
<PackageReference Include="Slim" Version="1.9.2" />
<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" />
<PackageReference Include="WpfExtended" Version="0.4.1" />
<PackageReference Include="WpfExtended" Version="0.7.1" />
<PackageReference Include="WpfExtended.SourceGeneration" Version="0.1.1" />
<PackageReference Include="WpfScreenHelper" Version="1.0.0" />
<PackageReference Include="WpfScreenHelper" Version="2.1.0" />
</ItemGroup>
<ItemGroup>
<Compile Update="Controls\Buttons\SynchronizeButton.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Controls\Buttons\HelpButton.xaml.cs">
<SubType>Code</SubType>
</Compile>
@@ -45,9 +72,16 @@
<Compile Update="Controls\Buttons\CancelButton.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Views\IconDownloadView.xaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Update="Controls\Buttons\SynchronizeButton.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
<Page Update="Controls\Buttons\HelpButton.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
@@ -68,10 +102,22 @@
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
<Page Update="Views\IconDownloadView.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
<Exec Command="echo.&gt;$(Version).version" />
</Target>
<Target Name="RemoveDuplicateAnalyzers" BeforeTargets="CoreCompile">
<!-- Work around https://github.com/dotnet/wpf/issues/6792 -->
<ItemGroup>
<FilteredAnalyzer Include="@(Analyzer-&gt;Distinct())" />
<Analyzer Remove="@(Analyzer)" />
<Analyzer Include="@(FilteredAnalyzer)" />
</ItemGroup>
</Target>
</Project>
+40 -20
View File
@@ -1,9 +1,11 @@
using Daybreak.Configuration;
using Daybreak.Exceptions;
using Daybreak.Services.ApplicationLifetime;
using Daybreak.Services.ViewManagement;
using Daybreak.Services.Navigation;
using Daybreak.Services.Updater.PostUpdate;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Slim;
using Slim.Integration.ServiceCollection;
using System;
using System.IO;
using System.Linq;
@@ -16,8 +18,11 @@ namespace Daybreak.Launch
{
public sealed class Launcher : ExtendedApplication<MainWindow>
{
public static IServiceManager ApplicationServiceManager { get; private set; }
private readonly static Launcher launcher = new();
public readonly static Launcher Instance = new();
private ILogger? logger;
public System.IServiceProvider ApplicationServiceProvider => this.ServiceProvider;
[STAThread]
public static int Main()
@@ -25,17 +30,15 @@ namespace Daybreak.Launch
return LaunchMainWindow();
}
protected override void SetupServiceManager(IServiceManager serviceManager)
protected override System.IServiceProvider SetupServiceProvider(IServiceCollection services)
{
ApplicationServiceManager = this.ServiceManager;
var serviceManager = new ServiceManager();
ProjectConfiguration.RegisterResolvers(serviceManager);
return services.BuildSlimServiceProvider(serviceManager);
}
protected override void RegisterServices(IServiceProducer serviceProducer)
protected override void RegisterServices(IServiceCollection services)
{
ProjectConfiguration.RegisterServices(this.ServiceManager);
ServiceManager.BuildSingletons();
ProjectConfiguration.RegisterLifetimeServices(this.ServiceManager.GetService<IApplicationLifetimeManager>());
ProjectConfiguration.RegisterViews(this.ServiceManager.GetService<IViewManager>());
ProjectConfiguration.RegisterServices(services);
}
protected override bool HandleException(Exception e)
{
@@ -44,17 +47,21 @@ namespace Daybreak.Launch
return false;
}
this.ServiceManager.GetService<ILogger>().LogCritical(e, $"Unhandled exception");
if (this.logger is null)
{
return false;
}
if (e is FatalException fatalException)
{
this.ServiceManager.GetService<ILogger>().LogCritical(e, $"{nameof(FatalException)} encountered. Closing application.");
this.logger.LogCritical(e, $"{nameof(FatalException)} encountered. Closing application");
MessageBox.Show(fatalException.ToString());
File.WriteAllText("crash.log", e.ToString());
return false;
}
else if (e is TargetInvocationException targetInvocationException && e.InnerException is FatalException innerFatalException)
{
this.ServiceManager.GetService<ILogger>().LogCritical(e, $"{nameof(FatalException)} encountered. Closing application.");
this.logger.LogCritical(e, $"{nameof(FatalException)} encountered. Closing application");
MessageBox.Show(innerFatalException.ToString());
File.WriteAllText("crash.log", e.ToString());
return false;
@@ -66,34 +73,47 @@ namespace Daybreak.Launch
{
/*
* Ignore exception caused by browser failing to initialize due to missing window.
* Likely caused by switching windows before browser was initialized.
* Likely caused by switching views before browser was initialized.
*/
this.logger.LogError(e, "Failed to initialize browser");
return true;
}
}
else if (e.Message.Contains("Invalid window handle.") && e.StackTrace?.Contains("CoreWebView2Environment.CreateCoreWebView2ControllerAsync") is true)
{
/*
* Ignore exception caused by browser failing to initialize due to missing window.
* Likely caused by switching views before the browser was initialized.
*/
this.logger.LogError(e, "Failed to initialize browser");
return true;
}
this.logger.LogError(e, $"Unhandled exception caught {e.GetType()}");
MessageBox.Show(e.ToString());
return true;
}
protected override void ApplicationStarting()
{
this.ServiceManager.GetService<IApplicationLifetimeManager>().OnStartup();
ProjectConfiguration.RegisterViews(this.ServiceProvider.GetService<IViewManager>()!);
ProjectConfiguration.RegisterPostUpdateActions(this.ServiceProvider.GetService<IPostUpdateActionProducer>()!);
this.logger = this.ServiceProvider.GetRequiredService<ILogger<Launcher>>();
this.RegisterViewContainer();
}
protected override void ApplicationClosing()
{
this.ServiceManager.GetService<IApplicationLifetimeManager>().OnClosing();
}
private void RegisterViewContainer()
{
var viewManager = this.ServiceManager.GetService<IViewManager>();
var mainWindow = this.ServiceManager.GetService<MainWindow>();
var viewManager = this.ServiceProvider.GetRequiredService<IViewManager>();
var mainWindow = this.ServiceProvider.GetRequiredService<MainWindow>();
viewManager.RegisterContainer(mainWindow.Container);
}
private static int LaunchMainWindow()
{
return launcher.Run();
return Instance.Run();
}
}
}
+64 -19
View File
@@ -2,11 +2,12 @@
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:local="clr-namespace:Daybreak.Launch"
xmlns:wcl="clr-namespace:WCL;assembly=WCL"
mc:Ignorable="d"
xmlns:controls="clr-namespace:Daybreak.Controls"
xmlns:converters="clr-namespace:Daybreak.Converters"
xmlns:effects="clr-namespace:System.Windows.Media.Extensions.Effects;assembly=WpfExtended"
WindowStyle="None"
ResizeMode="NoResize"
@@ -24,14 +25,7 @@
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid>
<Rectangle x:Name="OverlayRect" Fill="{TemplateBinding Background}" Opacity="0"></Rectangle>
<Viewbox Margin="5" Stretch="Uniform">
<Grid>
<Path Stroke="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"
Data="m76.89,45.018c0,-1.587 -0.151,-3.138 -0.383,-4.66l11.227,-6.48l-11.639,-20.136l-11.616,6.47c-2.421,-1.931 -5.479,-3.506 -8.479,-4.664l0,-11.548l-22,0l0,11.548c-4,1.112 -5.649,2.617 -8.005,4.448l-11.251,-6.604l-11.914,20.006l11.12,6.604c-0.262,1.643 -0.45,3.308 -0.45,5.016c0,1.587 0.153,3.136 0.376,4.658l-11.228,6.484l11.634,20.135l11.424,-6.472c2.431,1.933 4.294,3.506 8.294,4.665l0,12.512l22,0l0,-12.512c3,-1.115 5.839,-2.618 8.19,-4.449l11.348,6.604l11.96,-20.006l-11.095,-6.603c0.258,-1.64 0.487,-3.304 0.487,-5.016zm-31.704,14.137c-7.799,0 -14.138,-6.332 -14.138,-14.138c0,-7.808 6.339,-14.136 14.138,-14.136c7.81,0 14.14,6.328 14.14,14.136c-0.001,7.806 -6.331,14.138 -14.14,14.138z"></Path>
<Path Fill="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"
Data="m56.5,89l-22,0c-1.381,0 -2.5,-1.119 -2.5,-2.5l0,-10.199c-2.612,-0.955 -4.464,-2.126 -6.274,-3.49l-10.229,5.671c-1.192,0.661 -2.694,0.244 -3.377,-0.936l-11.633,-20.135c-0.331,-0.574 -0.422,-1.257 -0.25,-1.897s0.591,-1.188 1.165,-1.519l9.794,-5.654c-0.121,-1.164 -0.181,-2.262 -0.181,-3.323c0,-1.317 0.112,-2.592 0.254,-3.721l-9.656,-5.75c-0.57,-0.34 -0.982,-0.893 -1.145,-1.537c-0.163,-0.644 -0.063,-1.326 0.279,-1.896l11.977,-20.006c0.702,-1.173 2.218,-1.564 3.399,-0.878l9.927,5.762c1.618,-1.213 3.362,-2.346 5.949,-3.273l0,-10.219c0.001,-1.381 1.12,-2.5 2.501,-2.5l22,0c1.381,0 2.5,1.119 2.5,2.5l0,10.377c2.124,0.938 4.104,2.059 5.919,3.35l9.939,-5.657c1.19,-0.677 2.713,-0.269 3.4,0.922l11.639,20.135c0.332,0.574 0.423,1.257 0.251,1.897s-0.591,1.188 -1.165,1.519l-9.781,5.646c0.126,1.165 0.188,2.266 0.188,3.329c0,1.327 -0.108,2.597 -0.246,3.717l9.692,5.752c0.571,0.339 0.983,0.891 1.147,1.533c0.163,0.644 0.065,1.325 -0.274,1.896l-11.897,20.005c-0.703,1.183 -2.234,1.573 -3.416,0.876l-9.798,-5.765c-1.782,1.25 -3.634,2.29 -5.598,3.144l0,10.324c0,1.381 -1.119,2.5 -2.5,2.5zm-19.5,-5l17,0l0,-9.512c0,-1.045 0.649,-1.979 1.629,-2.344c2.624,-0.975 5.004,-2.309 7.275,-4.078c0.809,-0.629 1.921,-0.702 2.804,-0.182l9.078,5.341l9.347,-15.716l-8.974,-5.325c-0.88,-0.522 -1.354,-1.528 -1.194,-2.538c0.198,-1.259 0.425,-2.923 0.425,-4.629c0,-1.314 -0.116,-2.716 -0.354,-4.284c-0.154,-1.018 0.33,-2.026 1.222,-2.541l9.061,-5.23l-9.145,-15.818l-9.208,5.241c-0.888,0.505 -1.995,0.42 -2.795,-0.219c-2.199,-1.754 -4.747,-3.196 -7.57,-4.286c-0.964,-0.372 -1.6,-1.299 -1.6,-2.332l0,-9.548l-17.001,0l0,9.548c0,1.123 -0.748,2.107 -1.83,2.408c-3.47,0.965 -5.073,2.212 -7.293,3.938l-0.098,0.076c-0.804,0.625 -1.909,0.7 -2.789,0.188l-9.243,-5.365l-9.423,15.739l8.937,5.321c0.879,0.524 1.351,1.531 1.189,2.542c-0.202,1.27 -0.435,2.943 -0.435,4.622c0,1.318 0.112,2.724 0.342,4.297c0.148,1.013 -0.337,2.015 -1.224,2.526l-9.065,5.234l9.151,15.842l9.525,-5.28c0.883,-0.49 1.976,-0.4 2.768,0.229c2.384,1.896 4.207,3.214 7.684,4.221c1.069,0.31 1.804,1.29 1.804,2.402l0,9.512zm8.186,-22.345c-9.174,0 -16.638,-7.464 -16.638,-16.638c0,-9.173 7.464,-16.636 16.638,-16.636c9.175,0 16.64,7.463 16.64,16.636c-0.001,9.174 -7.466,16.638 -16.64,16.638zm0,-28.273c-6.417,0 -11.638,5.22 -11.638,11.636c0,6.417 5.221,11.638 11.638,11.638c6.418,0 11.64,-5.221 11.64,-11.638c-0.001,-6.416 -5.222,-11.636 -11.64,-11.636z"></Path>
</Grid>
</Viewbox>
<controls:ThreeDotsGlyph Margin="13"></controls:ThreeDotsGlyph>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
@@ -62,30 +56,47 @@
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Border BorderBrush="Transparent" BorderThickness="0" Grid.RowSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border BorderBrush="Transparent" BorderThickness="0" Grid.RowSpan="2" Grid.ColumnSpan="2">
<Border.Effect>
<BlurEffect Radius="5" KernelType="Gaussian" RenderingBias="Performance"></BlurEffect>
</Border.Effect>
<controls:ImageViewer x:Name="ImageViewer">
<controls:ImageViewer x:Name="ImageViewer"
MouseDown="TitleBar_MouseLeftButtonDown">
<controls:ImageViewer.Effect>
<effects:LightStreak Attenuation="0.4" BrightThreshold="0.9"></effects:LightStreak>
</controls:ImageViewer.Effect>
</controls:ImageViewer>
</Border>
<wcl:TitleBar x:Name="Titlebar"
Grid.ColumnSpan="2"
Background="Transparent" MouseLeftButtonDown="TitleBar_MouseLeftButtonDown"
WindowState="Normal" MinimizeButtonClicked="TitleBar_MinimizeButtonClicked"
MaximizeButtonClicked="TitleBar_MaximizeButtonClicked"
RestoreButtonClicked="TitleBar_RestoreButtonClicked"
CloseButtonClicked="TitleBar_CloseButtonClicked"
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"></wcl:TitleBar>
<ToggleButton Style="{StaticResource Window_SettingsButton}" Width="50" Height="30" HorizontalAlignment="Right"
Margin="0, 0, 150, 0" Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}" Click="SettingsButton_Clicked"></ToggleButton>
<controls:OpaqueButton Grid.Row="1" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Opacity="0.6"
Text="{Binding ElementName=_this, Path=CreditText, Mode=OneWay}" VerticalAlignment="Bottom"
HorizontalAlignment="Right" Margin="0, 0, 20, 30" FontSize="22" Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
<controls:OpaqueButton Grid.Row="1"
Grid.Column="1"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
Opacity="0.6"
Text="{Binding ElementName=_this, Path=CreditText, Mode=OneWay}"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"
Margin="0, 0, 20, 30"
FontSize="22"
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Clicked="CreditTextBox_MouseLeftButtonDown" Cursor="Hand"></controls:OpaqueButton>
<WrapPanel Grid.Row="1" Margin="0, 0, 20, 10" VerticalAlignment="Bottom" HorizontalAlignment="Right">
<WrapPanel Grid.Row="1"
Grid.Column="1"
Margin="0, 0, 20, 10"
VerticalAlignment="Bottom"
HorizontalAlignment="Right">
<controls:OpaqueButton Grid.Row="1" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Opacity="0.6"
Text="{Binding ElementName=_this, Path=CurrentVersionText, Mode=OneWay}" FontSize="10"
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
@@ -99,8 +110,42 @@
Visibility="{Binding ElementName=_this, Path=IsRunningAsAdmin, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"
Clicked="VersionText_Clicked"></controls:OpaqueButton>
</WrapPanel>
<Grid x:Name="Container" Grid.Row="1">
<Grid x:Name="Container"
Grid.Column="1"
Grid.Row="1"/>
<Grid x:Name="MenuContainer"
Width="0"
Grid.RowSpan="2"
VerticalAlignment="Stretch"
HorizontalAlignment="Left"
Background="#A0202020">
<controls:MenuList Margin="0, 30, 0, 0"/>
</Grid>
<wcl:Border OnResize="Border_OnResize" Grid.RowSpan="2" Active="True"></wcl:Border>
<ToggleButton Style="{StaticResource Window_SettingsButton}"
Width="50"
Height="30"
HorizontalAlignment="Left"
Margin="0, 0, 0, 0"
Grid.ColumnSpan="2"
Foreground="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Click="SettingsButton_Clicked"></ToggleButton>
<ToggleButton Style="{StaticResource Window_SettingsButton}"
Width="50"
Height="30"
HorizontalAlignment="Left"
Margin="0, 0, 0, 0"
Grid.ColumnSpan="2"
Foreground="White"
Visibility="{Binding ElementName=_this, Path=IsShowingDropdown, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"
Click="SettingsButton_Clicked"></ToggleButton>
<wcl:Border OnResize="Border_OnResize" Grid.RowSpan="2" Grid.ColumnSpan="2" Active="True"></wcl:Border>
<controls:ChromiumBrowserWrapper x:Name="BackgroundWebView"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Visibility="Visible"
ControlsEnabled="False"
CanNavigate="False"
CanDownloadBuild="False"
Grid.Row="1"></controls:ChromiumBrowserWrapper>
</Grid>
</Window>
+79 -27
View File
@@ -1,21 +1,26 @@
using Daybreak.Services.Bloogum;
using Daybreak.Services.Configuration;
using Daybreak.Configuration;
using Daybreak.Services.Bloogum;
using Daybreak.Services.IconRetrieve;
using Daybreak.Services.Navigation;
using Daybreak.Services.Privilege;
using Daybreak.Services.Runtime;
using Daybreak.Services.Screenshots;
using Daybreak.Services.Updater;
using Daybreak.Services.ViewManagement;
using Daybreak.Utils;
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;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Extensions;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
namespace Daybreak.Launch
@@ -32,17 +37,18 @@ namespace Daybreak.Launch
private readonly IBloogumClient bloogumClient;
private readonly IApplicationUpdater applicationUpdater;
private readonly IPrivilegeManager privilegeManager;
private readonly IConfigurationManager configurationManager;
private readonly IIconDownloader iconDownloader;
private readonly ILiveOptions<ApplicationConfiguration> liveOptions;
private readonly CancellationTokenSource cancellationToken = new();
private bool canCheckUpdate = false;
[GenerateDependencyProperty]
private string creditText;
private string creditText = string.Empty;
[GenerateDependencyProperty]
private string currentVersionText;
private string currentVersionText = string.Empty;
[GenerateDependencyProperty]
private bool isRunningAsAdmin;
[GenerateDependencyProperty]
private bool isShowingDropdown;
public MainWindow(
IViewManager viewManager,
@@ -50,35 +56,37 @@ namespace Daybreak.Launch
IBloogumClient bloogumClient,
IApplicationUpdater applicationUpdater,
IPrivilegeManager privilegeManager,
IConfigurationManager configurationManager)
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.configurationManager = configurationManager.ThrowIfNull(nameof(configurationManager));
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.LoadConfiguration();
this.configurationManager.ConfigurationChanged += (s, e) => this.LoadConfiguration();
this.CurrentVersionText = this.applicationUpdater.CurrentVersion.ToString();
this.IsRunningAsAdmin = this.privilegeManager.AdminPrivileges;
}
private void LoadConfiguration()
{
var configuration = this.configurationManager.GetConfiguration();
this.canCheckUpdate = configuration.AutoCheckUpdate;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.SetupImageCycle();
this.CheckForUpdates();
this.SetupBackgroundBrowser();
}
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton is not MouseButton.Left &&
e.LeftButton is not MouseButtonState.Pressed)
{
return;
}
this.DragMove();
}
@@ -110,6 +118,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);
@@ -142,7 +155,46 @@ namespace Daybreak.Launch
private void SettingsButton_Clicked(object sender, EventArgs e)
{
this.viewManager.ShowView<SettingsCategoryView>();
sender.As<ToggleButton>().IsEnabled = false;
var widthAnimation = new DoubleAnimation
{
From = this.IsShowingDropdown ?
this.MenuContainer.ActualWidth :
0,
To = this.IsShowingDropdown ?
0 :
300,
Duration = new Duration(TimeSpan.FromMilliseconds(200)),
DecelerationRatio = 0.7
};
var opacityAnimation = new DoubleAnimation
{
From = this.IsShowingDropdown ?
this.MenuContainer.Opacity :
0,
To = this.IsShowingDropdown ?
0 :
1,
Duration = new Duration(TimeSpan.FromMilliseconds(100)),
DecelerationRatio = 0.7
};
var storyBoard = new Storyboard();
storyBoard.Children.Add(widthAnimation);
Storyboard.SetTarget(widthAnimation, this.MenuContainer);
Storyboard.SetTargetProperty(widthAnimation, new PropertyPath(Grid.WidthProperty));
storyBoard.Children.Add(opacityAnimation);
Storyboard.SetTarget(opacityAnimation, this.MenuContainer);
Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(Grid.OpacityProperty));
storyBoard.Completed += (_, _) =>
{
sender.As<ToggleButton>().IsEnabled = true;
this.IsShowingDropdown = !this.IsShowingDropdown;
};
storyBoard.Begin();
}
private void CreditTextBox_MouseLeftButtonDown(object sender, EventArgs e)
@@ -178,14 +230,14 @@ namespace Daybreak.Launch
private async void CheckForUpdates()
{
var updateAvailable = this.canCheckUpdate is true && await this.applicationUpdater.UpdateAvailable().ConfigureAwait(true);
var updateAvailable = this.liveOptions.Value.AutoCheckUpdate is true && await this.applicationUpdater.UpdateAvailable().ConfigureAwait(true);
if (updateAvailable)
{
this.viewManager.ShowView<AskUpdateView>();
}
else
{
this.viewManager.ShowView<MainView>();
this.viewManager.ShowView<CompanionView>();
this.PeriodicallyCheckForUpdates();
}
}
+2 -1
View File
@@ -8,6 +8,7 @@ namespace Daybreak.Models.Browser
[JsonConverter(typeof(StringEnumConverter))]
public enum PayloadKeys
{
None,
ContextMenu
}
@@ -18,6 +19,6 @@ namespace Daybreak.Models.Browser
public sealed class BrowserPayload<T> : BrowserPayload
{
[JsonProperty("Value")]
public T Value { get; set; }
public T? Value { get; set; }
}
}
@@ -9,6 +9,6 @@ namespace Daybreak.Models.Browser
[JsonProperty("Y")]
public double Y { get; set; }
[JsonProperty("Selection")]
public string Selection { get; set; }
public string? Selection { get; set; }
}
}
+9
View File
@@ -0,0 +1,9 @@
using Daybreak.Models.Builds;
namespace Daybreak.Models;
public sealed class BuildWithTemplateCode
{
public BuildEntry? Build { get; set; }
public string? TemplateCode { get; set; }
}
+3 -3
View File
@@ -97,7 +97,7 @@ namespace Daybreak.Models.Builds
public static bool TryParse(int id, out Attribute attribute)
{
attribute = Attributes.Where(attr => attr.Id == id).FirstOrDefault();
attribute = Attributes.Where(attr => attr.Id == id).FirstOrDefault()!;
if (attribute is null)
{
return false;
@@ -107,7 +107,7 @@ namespace Daybreak.Models.Builds
}
public static bool TryParse(string name, out Attribute attribute)
{
attribute = Attributes.Where(attr => attr.Name == name).FirstOrDefault();
attribute = Attributes.Where(attr => attr.Name == name).FirstOrDefault()!;
if (attribute is null)
{
return false;
@@ -135,7 +135,7 @@ namespace Daybreak.Models.Builds
}
public int Id { get; private set; }
public string Name { get; private set; }
public string? Name { get; private set; }
private Attribute()
{
}
+5 -5
View File
@@ -4,16 +4,16 @@ namespace Daybreak.Models.Builds
{
public sealed class AttributeEntry : INotifyPropertyChanged
{
private Attribute attribute;
private Attribute? attribute;
private int points;
public Attribute Attribute
public Attribute? Attribute
{
get => this.attribute;
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,10 +22,10 @@ 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)));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangedEventHandler? PropertyChanged;
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Daybreak.Models.Builds
{
public sealed class Build
{
public BuildMetadata BuildMetadata { get; set; }
public BuildMetadata? BuildMetadata { get; set; }
public Profession Primary { get; set; } = Profession.None;
public Profession Secondary { get; set; } = Profession.None;
public List<AttributeEntry> Attributes { get; set; } = new();
+8 -8
View File
@@ -4,27 +4,27 @@ namespace Daybreak.Models.Builds
{
public sealed class BuildEntry : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string name;
private Build build;
public event PropertyChangedEventHandler? PropertyChanged;
private string? name;
private Build? build;
public string PreviousName { get; set; }
public string Name
public string? PreviousName { get; set; }
public string? Name
{
get => this.name;
set
{
this.name = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Name)));
}
}
public Build Build
public Build? Build
{
get => this.build;
set
{
this.build = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Build)));
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Build)));
}
}
}
+2 -2
View File
@@ -4,8 +4,8 @@ namespace Daybreak.Models.Builds
{
public sealed class BuildMetadata
{
public List<int> Base64Decoded { get; set; }
public List<string> BinaryDecoded { get; set; }
public List<int>? Base64Decoded { get; set; }
public List<string>? BinaryDecoded { get; set; }
public int Header { get; set; }
public int VersionNumber { get; set; }
public int ProfessionIdLength { get; set; }
+5 -5
View File
@@ -33,7 +33,7 @@ namespace Daybreak.Models.Builds
};
public static bool TryParse(int id, out Profession profession)
{
profession = Professions.Where(prof => prof.Id == id).FirstOrDefault();
profession = Professions.Where(prof => prof.Id == id).FirstOrDefault()!;
if (profession is null)
{
return false;
@@ -43,7 +43,7 @@ namespace Daybreak.Models.Builds
}
public static bool TryParse(string name, out Profession profession)
{
profession = Professions.Where(prof => prof.Name == name).FirstOrDefault();
profession = Professions.Where(prof => prof.Name == name).FirstOrDefault()!;
if (profession is null)
{
return false;
@@ -70,10 +70,10 @@ namespace Daybreak.Models.Builds
return profession;
}
public string Name { get; private set; }
public string? Name { get; private set; }
public int Id { get; set; }
public Attribute PrimaryAttribute { get; private set; }
public List<Attribute> Attributes { get; private set; }
public Attribute? PrimaryAttribute { get; private set; }
public List<Attribute>? Attributes { get; private set; }
private Profession()
{
}
+12 -11
View File
@@ -143,7 +143,7 @@ namespace Daybreak.Models.Builds
public static Skill Flurry { get; } = new() { Id = 344, Name = "Flurry", Profession = Profession.Warrior };
public static Skill Frenzy { get; } = new() { Id = 346, Name = "Frenzy", Profession = Profession.Warrior };
public static Skill Coward { get; } = new() { Id = 869, Name = "\"Coward!\"", Profession = Profession.Warrior };
public static Skill OnYourKnees { get; } = new() { Id = 906, Name = "On Your Knees!", Profession = Profession.Warrior };
public static Skill OnYourKnees { get; } = new() { Id = 906, Name = "\"On Your Knees!\"", Profession = Profession.Warrior };
public static Skill YoureAllAlone { get; } = new() { Id = 1412, Name = "\"You're All Alone!\"", Profession = Profession.Warrior };
public static Skill FrenziedDefense { get; } = new() { Id = 1700, Name = "Frenzied Defense", Profession = Profession.Warrior };
public static Skill Grapple { get; } = new() { Id = 2011, Name = "Grapple", Profession = Profession.Warrior };
@@ -702,7 +702,7 @@ namespace Daybreak.Models.Builds
public static Skill Echo { get; } = new() { Id = 74, Name = "Echo", Profession = Profession.Mesmer };
public static Skill ArcaneEcho { get; } = new() { Id = 75, Name = "Arcane Echo", Profession = Profession.Mesmer };
public static Skill Epidemic { get; } = new() { Id = 78, Name = "Epidemic", Profession = Profession.Mesmer };
public static Skill LyssasBalance { get; } = new() { Id = 877, Name = "Lyssa's Balance, Profession = Profession.Mesmer" };
public static Skill LyssasBalance { get; } = new() { Id = 877, Name = "Lyssa's Balance", Profession = Profession.Mesmer };
public static Skill SignetofDisenchantment { get; } = new() { Id = 882, Name = "Signet of Disenchantment", Profession = Profession.Mesmer };
public static Skill ShatterStorm { get; } = new() { Id = 933, Name = "Shatter Storm", Profession = Profession.Mesmer };
public static Skill ExpelHexes { get; } = new() { Id = 954, Name = "Expel Hexes", Profession = Profession.Mesmer };
@@ -1053,7 +1053,7 @@ namespace Daybreak.Models.Builds
public static Skill FeastofSouls { get; } = new() { Id = 980, Name = "Feast of Souls", Profession = Profession.Ritualist };
public static Skill RitualLord { get; } = new() { Id = 1217, Name = "Ritual Lord", Profession = Profession.Ritualist };
public static Skill AttunedWasSongkai { get; } = new() { Id = 1220, Name = "Attuned Was Songkai", Profession = Profession.Ritualist };
public static Skill AnguishedWasLingwah { get; } = new() { Id = 1223, Name = "Anguished Was Lingwah, Profession = Profession.Ritualist" };
public static Skill AnguishedWasLingwah { get; } = new() { Id = 1223, Name = "Anguished Was Lingwah", Profession = Profession.Ritualist };
public static Skill ExplosiveGrowth { get; } = new() { Id = 1229, Name = "Explosive Growth", Profession = Profession.Ritualist };
public static Skill BoonofCreation { get; } = new() { Id = 1230, Name = "Boon of Creation", Profession = Profession.Ritualist };
public static Skill SpiritChanneling { get; } = new() { Id = 1231, Name = "Spirit Channeling", Profession = Profession.Ritualist };
@@ -1483,8 +1483,8 @@ namespace Daybreak.Models.Builds
public static Skill VolfenBlessing { get; } = new() { Id = 2379, Name = "Volfen Blessing", Profession = Profession.None };
public static Skill TimeWard { get; } = new() { Id = 3422, Name = "Time Ward", Profession = Profession.Mesmer };
public static Skill SoulTaker { get; } = new() { Id = 3423, Name = "Soul Taker", Profession = Profession.Necromancer };
public static Skill OverTheLimit { get; } = new() { Id = 3424, Name = "Over The Limit", Profession = Profession.Elementalist };
public static Skill JudgementStrike { get; } = new() { Id = 3425, Name = "Judgement Strike", Profession = Profession.Monk };
public static Skill OverTheLimit { get; } = new() { Id = 3424, Name = "Over The Limit", AlternativeName = "Over the Limit", Profession = Profession.Elementalist };
public static Skill JudgementStrike { get; } = new() { Id = 3425, Name = "Judgement Strike", AlternativeName = "Judgment Strike", Profession = Profession.Monk };
public static Skill SevenWeaponsStance { get; } = new() { Id = 3426, Name = "Seven Weapons Stance", Profession = Profession.Warrior };
public static Skill Togetherasone { get; } = new() { Id = 3427, Name = "\"Together as one!\"", Profession = Profession.Ranger };
public static Skill ShadowTheft { get; } = new() { Id = 3428, Name = "Shadow Theft", Profession = Profession.Assassin };
@@ -2978,11 +2978,11 @@ namespace Daybreak.Models.Builds
WeaponsofThreeForges,
VowofRevolution,
HeroicRefrain,
};
}.OrderBy(s => s.Name).ToList();
public static bool TryParse(int id, out Skill skill)
{
skill = Skills.Where(skill => skill.Id == id).FirstOrDefault();
skill = Skills.Where(skill => skill.Id == id).FirstOrDefault()!;
if (skill is null)
{
return false;
@@ -2992,7 +2992,7 @@ namespace Daybreak.Models.Builds
}
public static bool TryParse(string name, out Skill skill)
{
skill = Skills.Where(skill => skill.Name == name).FirstOrDefault();
skill = Skills.Where(skill => skill.Name == name).FirstOrDefault()!;
if (skill is null)
{
return false;
@@ -3019,9 +3019,10 @@ namespace Daybreak.Models.Builds
return skill;
}
public Profession Profession { get; private set; }
public string Name { get; private set; }
public int Id { get; private set; }
public Profession? Profession { get; private set; }
public string? Name { get; private set; }
public int? Id { get; private set; }
public string? AlternativeName { get; private set; }
private Skill()
{
}
+3 -3
View File
@@ -4,8 +4,8 @@ namespace Daybreak.Models
{
public sealed class ElevationRequest
{
public object DataContext { get; set; }
public Type View { get; set; }
public string MessageToUser { get; set; }
public object? DataContext { get; set; }
public Type? View { get; set; }
public string? MessageToUser { get; set; }
}
}
+3 -3
View File
@@ -5,10 +5,10 @@ namespace Daybreak.Models.Github
public sealed class GithubRefTag
{
[JsonProperty("ref")]
public string Ref;
public string? Ref;
[JsonProperty("node_id")]
public string NodeId;
public string? NodeId;
[JsonProperty("url")]
public string Url;
public string? Url;
}
}
+1 -1
View File
@@ -5,7 +5,7 @@ namespace Daybreak.Models
public sealed class GuildwarsPath
{
[JsonProperty("path")]
public string Path { get; set; }
public string? Path { get; set; }
[JsonProperty("default")]
public bool Default { get; set; }
}
+8
View File
@@ -0,0 +1,8 @@
namespace Daybreak.Models
{
public sealed class IconPayload
{
public string? SkillUrl { get; set; }
public string? SkillImage { get; set; }
}
}
+11
View File
@@ -0,0 +1,11 @@
using Daybreak.Models.Builds;
namespace Daybreak.Models
{
public sealed class IconRequest
{
public Skill? Skill { get; set; }
public string? IconBase64 { get; set; }
public bool Finished { get; set; }
}
}
+1 -1
View File
@@ -5,7 +5,7 @@ namespace Daybreak.Models
{
public sealed class KeyMacro
{
public List<Keys> Keys { get; set; }
public List<Keys>? Keys { get; set; }
public Keys TargetKey { get; set; }
}
}
+1 -1
View File
@@ -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.
+15
View File
@@ -0,0 +1,15 @@
using Microsoft.Extensions.Logging;
using System;
namespace Daybreak.Models
{
public sealed class Log
{
public string? Message { get; set; }
public string? Category { get; set; }
public LogLevel LogLevel { get; set; }
public string? CorrelationVector { get; set; }
public string? EventId { get; set; }
public DateTime LogTime { get; set; }
}
}
+3 -3
View File
@@ -2,9 +2,9 @@
{
public sealed class LoginCredentials
{
public string Username { get; set; }
public string Password { get; set; }
public string CharacterName { get; set; }
public string? Username { get; set; }
public string? Password { get; set; }
public string? CharacterName { get; set; }
public bool Default { get; set; }
}
}

Some files were not shown because too many files have changed in this diff Show More