Compare commits

..
9 Commits
Author SHA1 Message Date
amacocianandGitHub 3c0877c1a0 Ability to keep a local cache of icons (#16) 2021-06-03 21:12:31 +02:00
967b57b9a8 Fix build code encoding/decoding view (#15)
Co-authored-by: Alexandru Macocian <almacoci@microsoft.com>
2021-06-03 20:40:56 +02:00
amacocianandGitHub f47cc319b5 Build template code field 2021-06-03 19:57:29 +02:00
amacocianandGitHub 26da84c4e7 Update to new version of wpfextended
Fix a bug where version parsing would ignore all 0s before the first digit
Remove LoggerFactory and LoggerProviders duplicated in WpfExtended
2021-06-03 14:48:35 +02:00
a39e8dc5c6 Separate CV from message (#12)
Co-authored-by: Alexandru Macocian <almacoci@microsoft.com>
2021-06-01 21:57:27 +02:00
1bb4669135 Introduce correlated logs (#11)
Co-authored-by: Alexandru Macocian <almacoci@microsoft.com>
2021-06-01 20:43:55 +02:00
amacocianandGitHub 0203eef006 Rework logging (#10)
* Rework log storing into a litedb.
LogView implementation to view logs.
Create crash.log on crash.

* Rename Logs namespace to Logging.
2021-05-18 19:49:51 +02:00
amacocianandGitHub 4ab50ee191 Use Microsoft.Logging.Abstractions
Typed ILogger.
2021-05-14 14:31:33 +02:00
amacocianandGitHub 06c1ec1ac2 Add scoped http client. (#8)
* Introduce scoped http client.
* Uts for scoped httpclient
2021-05-10 12:46:01 +02:00
54 changed files with 686 additions and 456 deletions
+1
View File
@@ -13,6 +13,7 @@
<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" />
</ItemGroup>
<ItemGroup>
+2
View File
@@ -10,6 +10,8 @@ namespace Daybreak.Tests.Models
[TestClass]
public class VersionTests
{
[DataRow("v0.1.0.0.1", "v0.1.0.0.1")]
[DataRow("v0.1.0.0.1.0.0.0.0", "v0.1.0.0.1")]
[DataRow("v0.1.0", "v0.1")]
[DataRow("0.1.0", "0.1")]
[DataRow("v0.1.0.0.0", "v0.1")]
@@ -1,7 +1,7 @@
using Daybreak.Models.Builds;
using Daybreak.Services.BuildTemplates;
using Daybreak.Services.Logging;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System.Collections.Generic;
@@ -17,7 +17,7 @@ namespace Daybreak.Tests.Services
[TestInitialize]
public void Initialize()
{
buildTemplateManager = new BuildTemplateManager(new Mock<ILogger>().Object);
buildTemplateManager = new BuildTemplateManager(new Mock<ILogger<BuildTemplateManager>>().Object);
}
[TestMethod]
@@ -0,0 +1,61 @@
using Daybreak.Services.Logging;
using FluentAssertions;
using LiteDB;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using WpfExtended.Logging;
namespace Daybreak.Tests.Services
{
[TestClass]
public class JsonLoggerProviderTests
{
private ILogsManager logsManager;
private ILoggerProvider loggerProvider;
private ILiteDatabase liteDatabase;
[TestInitialize]
public void InitializeProvider()
{
File.Delete("Daybreak.db");
this.liteDatabase = new LiteDatabase("Daybreak.db");
this.logsManager = new JsonLogsManager(this.liteDatabase);
this.loggerProvider = new CVLoggerProvider(this.logsManager);
}
[TestCleanup]
public void TestCleanup()
{
this.liteDatabase.Dispose();
}
[TestMethod]
public void CreateLoggerReturnsLogger()
{
var logger = this.loggerProvider.CreateLogger("SomeCategory");
logger.Should().NotBeNull();
}
[TestMethod]
public void LoggerLogsAndReaderReads()
{
var logger = this.loggerProvider.CreateLogger("SomeCategory");
logger.LogInformation("Logging some stuff");
logger.LogError("Logging some error");
this.logsManager.GetLogs().Should().HaveCount(2);
}
[TestMethod]
public void DeletingLogsShouldDeleteLogs()
{
var logger = this.loggerProvider.CreateLogger("SomeCategory");
logger.LogInformation("Logging some stuff");
logger.LogError("Logging some error");
this.logsManager.GetLogs().Should().HaveCount(2);
this.logsManager.DeleteLogs();
this.logsManager.GetLogs().Should().HaveCount(0);
}
}
}
+5 -5
View File
@@ -5,7 +5,7 @@ VisualStudioVersion = 16.0.31005.135
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Daybreak", "Daybreak\Daybreak.csproj", "{AA45C2B1-8BD0-466C-9271-699F168905AF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Daybreak.Tests", "Daybreak.Tests\Daybreak.Tests.csproj", "{C911C1C2-6566-419C-89C7-F802EB3FE709}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Daybreak.Tests", "Daybreak.Tests\Daybreak.Tests.csproj", "{C911C1C2-6566-419C-89C7-F802EB3FE709}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -17,12 +17,12 @@ Global
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Debug|x64.ActiveCfg = Debug|x64
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Debug|x64.Build.0 = Debug|x64
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Debug|x64.ActiveCfg = Debug|Any CPU
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Debug|x64.Build.0 = Debug|Any CPU
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Release|Any CPU.Build.0 = Release|Any CPU
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Release|x64.ActiveCfg = Release|x64
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Release|x64.Build.0 = Release|x64
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Release|x64.ActiveCfg = Release|Any CPU
{AA45C2B1-8BD0-466C-9271-699F168905AF}.Release|x64.Build.0 = Release|Any CPU
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C911C1C2-6566-419C-89C7-F802EB3FE709}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -37,5 +37,7 @@ namespace Daybreak.Configuration
public bool PlaceShortcut { get; set; }
[JsonProperty("AutoCheckUpdate")]
public bool AutoCheckUpdate { get; set; } = true;
[JsonProperty("KeepLocalIconCache")]
public bool KeepLocalIconCache { get; set; } = true;
}
}
+34 -13
View File
@@ -15,40 +15,60 @@ 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;
namespace Daybreak.Configuration
{
public static class ProjectConfiguration
{
public static void RegisterResolvers(IServiceManager serviceManager)
{
serviceManager.ThrowIfNull(nameof(serviceManager));
serviceManager.RegisterResolver(
new HttpClientResolver()
.WithHttpMessageHandlerFactory((serviceProvider, categoryType) =>
{
var loggerType = typeof(ILogger<>).MakeGenericType(categoryType);
var logger = serviceProvider.GetService(loggerType).As<ILogger>();
var handler = new LoggingHttpMessageHandler(logger) { InnerHandler = new HttpClientHandler() };
return handler;
}));
}
public static void RegisterServices(IServiceProducer serviceProducer)
{
serviceProducer.ThrowIfNull(nameof(serviceProducer));
serviceProducer.RegisterSingleton<ICredentialManager, CredentialManager>();
serviceProducer.RegisterSingleton<ILoggingDatabase, FlatLoggingDatabase>();
serviceProducer.RegisterSingleton<ILogger, Logger>();
serviceProducer.RegisterSingleton<ApplicationLifetimeManager>();
serviceProducer.RegisterSingleton<ViewManager>();
serviceProducer.RegisterSingleton<IApplicationLauncher, ApplicationLauncher>();
serviceProducer.RegisterSingleton<IScreenshotProvider, ScreenshotProvider>();
serviceProducer.RegisterSingleton<IConfigurationManager, ConfigurationManager>();
serviceProducer.RegisterSingleton<IBloogumClient, BloogumClient>();
serviceProducer.RegisterSingleton<IApplicationUpdater, ApplicationUpdater>();
serviceProducer.RegisterSingleton<IMutexHandler, MutexHandler>();
serviceProducer.RegisterSingleton<ILiteDatabase, LiteDatabase>(sp => new LiteDatabase("Daybreak.db"));
serviceProducer.RegisterSingleton<IRuntimeStore, RuntimeStore>();
serviceProducer.RegisterSingleton<IBuildTemplateManager, BuildTemplateManager>();
serviceProducer.RegisterSingleton<IIconRetriever, IconRetriever>();
serviceProducer.RegisterSingleton<IPrivilegeManager, PrivilegeManager>();
serviceProducer.RegisterSingleton<IScreenManager, ScreenManager>();
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));
applicationLifetimeProducer.RegisterService<ILoggingDatabase>();
applicationLifetimeProducer.RegisterService<IScreenshotProvider>();
applicationLifetimeProducer.RegisterService<IApplicationUpdater>();
applicationLifetimeProducer.RegisterService<IShortcutManager>();
@@ -70,6 +90,7 @@ namespace Daybreak.Configuration
viewProducer.RegisterView<RequestElevationView>();
viewProducer.RegisterView<ScreenChoiceView>();
viewProducer.RegisterView<VersionManagementView>();
viewProducer.RegisterView<LogsView>();
}
}
}
@@ -1,10 +1,9 @@
using Daybreak.Launch;
using Daybreak.Models.Browser;
using Daybreak.Models.Browser;
using Daybreak.Models.Builds;
using Daybreak.Services.BuildTemplates;
using Daybreak.Services.Configuration;
using Daybreak.Services.Logging;
using Daybreak.Utils;
using Microsoft.Extensions.Logging;
using Microsoft.Web.WebView2.Core;
using System;
using System.Diagnostics;
@@ -29,9 +28,9 @@ namespace Daybreak.Controls
public event EventHandler MaximizeClicked;
public event EventHandler<Build> BuildDecoded;
private readonly IConfigurationManager configurationManager;
private readonly ILogger logger;
private readonly IBuildTemplateManager buildTemplateManager;
private IConfigurationManager configurationManager;
private ILogger<ChromiumBrowserWrapper> logger;
private IBuildTemplateManager buildTemplateManager;
private CoreWebView2Environment coreWebView2Environment;
[GenerateDependencyProperty(InitialValue = true)]
@@ -40,7 +39,7 @@ namespace Daybreak.Controls
private bool canNavigate;
[GenerateDependencyProperty(InitialValue = true)]
private bool controlsEnabled;
[GenerateDependencyProperty(InitialValue = true)]
[GenerateDependencyProperty]
private bool browserSupported;
[GenerateDependencyProperty]
private bool addressBarReadonly;
@@ -55,12 +54,8 @@ namespace Daybreak.Controls
public ChromiumBrowserWrapper()
{
this.configurationManager = Launcher.ApplicationServiceManager.GetService<IConfigurationManager>();
this.logger = Launcher.ApplicationServiceManager.GetService<ILogger>();
this.buildTemplateManager = Launcher.ApplicationServiceManager.GetService<IBuildTemplateManager>();
this.InitializeComponent();
this.InitializeEnvironment();
this.InitializeBrowser();
this.WebBrowser.IsEnabled = false;
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
@@ -72,6 +67,18 @@ namespace Daybreak.Controls
}
}
public async void InitializeBrowser(
IConfigurationManager configurationManager,
IBuildTemplateManager buildTemplateManager,
ILogger<ChromiumBrowserWrapper> logger)
{
this.configurationManager = configurationManager;
this.buildTemplateManager = buildTemplateManager;
this.logger = logger;
this.InitializeEnvironment();
await this.InitializeBrowser();
}
public async void ReinitializeBrowser()
{
await this.InitializeBrowser();
@@ -101,6 +108,7 @@ 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;
@@ -174,7 +182,7 @@ namespace Daybreak.Controls
}
catch(Exception e)
{
this.logger.LogError(e);
this.logger.LogError(e, $"Exception encountered when deserializing {nameof(BrowserPayload)}");
}
if (payload?.Key == BrowserPayload.PayloadKeys.ContextMenu)
{
+14
View File
@@ -0,0 +1,14 @@
<UserControl x:Class="Daybreak.Controls.LogsGlyph"
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>
<Path Fill="{Binding ElementName=_this, Path=Foreground, Mode=OneWay}"
Data="m7,3l0,-1.00209c0,-1.09965 0.89762,-1.99791 2.00488,-1.99791l0.99024,0c1.11098,0 2.00488,0.8945 2.00488,1.99791l0,1.00209l2.00442,0c0.55074,0 0.99558,0.44725 0.99558,0.99896l0,1.00208c0,0.5563 -0.44574,0.99896 -0.99558,0.99896l-9.00884,0c-0.55074,0 -0.99558,-0.44725 -0.99558,-0.99896l0,-1.00208c0,-0.5563 0.44574,-0.99896 0.99558,-0.99896l2.00442,0l0,0zm8.99999,1l1.00259,0c1.10649,0 1.99742,0.89704 1.99742,2.00359l0,20.99282c0,1.11383 -0.89428,2.00359 -1.99742,2.00359l-15.00516,0c-1.10649,0 -1.99742,-0.89704 -1.99742,-2.00359l0,-20.99282c0,-1.11383 0.89428,-2.00359 1.99742,-2.00359l1.00259,0c-0.00001,0.00163 -0.00001,0.00325 -0.00001,0.00488l0,0.99024c0,1.10726 0.89354,2.00488 2.00276,2.00488l8.99448,0c1.10609,0 2.00276,-0.8939 2.00276,-2.00488l0,-0.99024c0,-0.00163 0,-0.00325 -0.00001,-0.00488l0,0l0,0zm-6.49999,-1c0.27614,0 0.5,-0.22386 0.5,-0.5c0,-0.27614 -0.22386,-0.5 -0.5,-0.5c-0.27614,0 -0.5,0.22386 -0.5,0.5c0,0.27614 0.22386,0.5 0.5,0.5l0,0zm-6.5,8l0,1l13,0l0,-1l-13,0l0,0zm0,3l0,1l13,0l0,-1l-13,0l0,0zm0,3l0,1l13,0l0,-1l-13,0l0,0zm0,3l0,1l13,0l0,-1l-13,0l0,0zm0,3l0,1l13,0l0,-1l-13,0l0,0z"></Path>
</Viewbox>
</UserControl>
@@ -0,0 +1,15 @@
using System.Windows.Controls;
namespace Daybreak.Controls
{
/// <summary>
/// Interaction logic for LogsGlyph.xaml
/// </summary>
public partial class LogsGlyph : UserControl
{
public LogsGlyph()
{
InitializeComponent();
}
}
}
@@ -15,6 +15,7 @@ namespace Daybreak.Controls
public partial class AttributeTemplate : UserControl
{
public event EventHandler<AttributeEntry> HelpClicked;
public event EventHandler<AttributeEntry> AttributeChanged;
[GenerateDependencyProperty(InitialValue = false)]
private bool canAdd;
@@ -50,6 +51,7 @@ namespace Daybreak.Controls
this.DataContext.As<AttributeEntry>().Points--;
this.CanSubtract = this.DataContext.As<AttributeEntry>().Points > 0;
this.CanAdd = true;
this.AttributeChanged?.Invoke(this, this.DataContext.As<AttributeEntry>());
}
}
@@ -60,6 +62,7 @@ namespace Daybreak.Controls
this.DataContext.As<AttributeEntry>().Points++;
this.CanAdd = this.DataContext.As<AttributeEntry>().Points < 12;
this.CanSubtract = true;
this.AttributeChanged?.Invoke(this, this.DataContext.As<AttributeEntry>());
}
}
@@ -75,7 +75,7 @@
HorizontalContentAlignment="Stretch" BorderThickness="0">
<ListBox.ItemTemplate>
<DataTemplate>
<local:AttributeTemplate HelpClicked="AttributeTemplate_HelpClicked"></local:AttributeTemplate>
<local:AttributeTemplate HelpClicked="AttributeTemplate_HelpClicked" AttributeChanged="AttributeTemplate_AttributeChanged"></local:AttributeTemplate>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
@@ -95,42 +95,42 @@
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<local:SkillTemplate Grid.Column="0"
<local:SkillTemplate Grid.Column="0" x:Name="SkillTemplate0"
Foreground="White" Cursor="Hand"
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill0, Mode=TwoWay}"
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
<local:SkillTemplate Grid.Column="1"
<local:SkillTemplate Grid.Column="1" x:Name="SkillTemplate1"
Foreground="White" Cursor="Hand"
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill1, Mode=TwoWay}"
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
<local:SkillTemplate Grid.Column="2"
<local:SkillTemplate Grid.Column="2" x:Name="SkillTemplate2"
Foreground="White" Cursor="Hand"
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill2, Mode=TwoWay}"
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
<local:SkillTemplate Grid.Column="3"
<local:SkillTemplate Grid.Column="3" x:Name="SkillTemplate3"
Foreground="White" Cursor="Hand"
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill3, Mode=TwoWay}"
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
<local:SkillTemplate Grid.Column="4"
<local:SkillTemplate Grid.Column="4" x:Name="SkillTemplate4"
Foreground="White" Cursor="Hand"
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill4, Mode=TwoWay}"
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
<local:SkillTemplate Grid.Column="5"
<local:SkillTemplate Grid.Column="5" x:Name="SkillTemplate5"
Foreground="White" Cursor="Hand"
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill5, Mode=TwoWay}"
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
<local:SkillTemplate Grid.Column="6"
<local:SkillTemplate Grid.Column="6" x:Name="SkillTemplate6"
Foreground="White" Cursor="Hand"
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill6, Mode=TwoWay}"
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
RemoveClicked="SkillTemplate_RemoveClicked"></local:SkillTemplate>
<local:SkillTemplate Grid.Column="7"
<local:SkillTemplate Grid.Column="7" x:Name="SkillTemplate7"
Foreground="White" Cursor="Hand"
FontSize="22" DataContext="{Binding ElementName=_this, Path=Skill7, Mode=TwoWay}"
VerticalAlignment="Stretch" Clicked="SkillTemplate_Clicked"
@@ -1,4 +1,9 @@
using Daybreak.Models.Builds;
using Daybreak.Services.BuildTemplates;
using Daybreak.Services.Configuration;
using Daybreak.Services.IconRetrieve;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Extensions;
@@ -19,10 +24,13 @@ namespace Daybreak.Controls
private const string InfoNamePlaceholder = "[NAME]";
private const string BaseAddress = $"https://wiki.guildwars.com/wiki/{InfoNamePlaceholder}";
private bool suppressBuildChanged = false;
private bool loadedProperties = false;
private BuildEntry loadedBuild;
private SkillTemplate selectingSkillTemplate;
public event EventHandler BuildChanged;
[GenerateDependencyProperty]
private Profession primaryProfession;
[GenerateDependencyProperty]
@@ -54,6 +62,23 @@ namespace Daybreak.Controls
this.DataContextChanged += BuildTemplate_DataContextChanged;
}
public void InitializeTemplate(
IIconRetriever iconRetriever,
IConfigurationManager configurationManager,
IBuildTemplateManager buildTemplateManager,
ILogger<ChromiumBrowserWrapper> logger)
{
this.SkillBrowser.InitializeBrowser(configurationManager, buildTemplateManager, logger);
this.SkillTemplate0.InitializeSkillTemplate(iconRetriever);
this.SkillTemplate1.InitializeSkillTemplate(iconRetriever);
this.SkillTemplate2.InitializeSkillTemplate(iconRetriever);
this.SkillTemplate3.InitializeSkillTemplate(iconRetriever);
this.SkillTemplate4.InitializeSkillTemplate(iconRetriever);
this.SkillTemplate5.InitializeSkillTemplate(iconRetriever);
this.SkillTemplate6.InitializeSkillTemplate(iconRetriever);
this.SkillTemplate7.InitializeSkillTemplate(iconRetriever);
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
@@ -74,6 +99,33 @@ namespace Daybreak.Controls
}
this.LoadSkills();
this.LoadAttributes();
if (this.suppressBuildChanged is false)
{
this.BuildChanged?.Invoke(this, new EventArgs());
}
}
if (e.Property == Skill0Property ||
e.Property == Skill1Property ||
e.Property == Skill2Property ||
e.Property == Skill3Property ||
e.Property == Skill4Property ||
e.Property == Skill5Property ||
e.Property == Skill6Property ||
e.Property == Skill7Property)
{
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.BuildChanged?.Invoke(this, new EventArgs());
}
}
}
@@ -197,6 +249,7 @@ namespace Daybreak.Controls
private void LoadBuild()
{
this.suppressBuildChanged = true;
var build = this.DataContext.As<BuildEntry>();
this.loadedBuild = build;
this.PrimaryProfession = build.Build.Primary;
@@ -209,6 +262,7 @@ namespace Daybreak.Controls
this.Skill5 = build.Build.Skills[5];
this.Skill6 = build.Build.Skills[6];
this.Skill7 = build.Build.Skills[7];
this.suppressBuildChanged = false;
}
private void BrowseToInfo(string infoName)
@@ -273,6 +327,11 @@ namespace Daybreak.Controls
this.BrowseToInfo(e.Attribute.Name);
}
private void AttributeTemplate_AttributeChanged(object sender, AttributeEntry e)
{
this.BuildChanged?.Invoke(this, new EventArgs());
}
private void SkillTemplate_Clicked(object sender, RoutedEventArgs e)
{
var skill = sender.As<SkillTemplate>().DataContext.As<Skill>();
@@ -23,7 +23,7 @@ namespace Daybreak.Controls
public event EventHandler<RoutedEventArgs> Clicked;
public event EventHandler RemoveClicked;
private readonly IIconRetriever iconRetriever;
private IIconRetriever iconRetriever;
[GenerateDependencyProperty]
private ImageSource imageSource;
@@ -32,22 +32,26 @@ namespace Daybreak.Controls
public SkillTemplate()
{
this.iconRetriever = Launcher.ApplicationServiceManager.GetService<IIconRetriever>();
this.InitializeComponent();
this.DataContextChanged += SkillTemplate_DataContextChanged;
}
public void InitializeSkillTemplate(IIconRetriever iconRetriever)
{
this.iconRetriever = iconRetriever;
}
private void SkillTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is Skill skill)
{
if (skill != Skill.NoSkill)
{
Task.Run(() => GetImageStream(skill)).ContinueWith((previousTask) =>
Task.Run(() => this.GetImageStream(skill)).ContinueWith((previousTask) =>
{
this.Dispatcher.Invoke(() =>
{
this.ImageSource = GetImageSource(previousTask.Result);
this.ImageSource = this.GetImageSource(previousTask.Result);
});
});
}
@@ -88,6 +92,11 @@ namespace Daybreak.Controls
}
private async Task<Stream> GetImageStream(Skill skill)
{
if (this.iconRetriever is null)
{
return null;
}
var maybeStream = await this.iconRetriever.GetIcon(skill);
return maybeStream.ExtractValue();
}
+10 -5
View File
@@ -10,19 +10,24 @@
<LangVersion>preview</LangVersion>
<ApplicationIcon>Daybreak.ico</ApplicationIcon>
<IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation>
<Version>0.8.9</Version>
<Version>0.9.2</Version>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.32" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.818.41" />
<PackageReference Include="LiteDB" Version="5.0.10" />
<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="securifybv.ShellLink" Version="0.1.0" />
<PackageReference Include="Slim" Version="1.2.2" />
<PackageReference Include="Slim" Version="1.4.3" />
<PackageReference Include="System.Windows.Interactivity.WPF" Version="2.0.20525" />
<PackageReference Include="SystemExtensions.NetStandard" Version="1.1.4" />
<PackageReference Include="SystemExtensions.NetStandard" Version="1.3.0" />
<PackageReference Include="WCL" Version="1.0.2" />
<PackageReference Include="WpfExtended" Version="0.2.1" />
<PackageReference Include="WpfExtended" Version="0.4.1" />
<PackageReference Include="WpfExtended.SourceGeneration" Version="0.1.1" />
<PackageReference Include="WpfScreenHelper" Version="1.0.0" />
</ItemGroup>
+18 -7
View File
@@ -1,17 +1,14 @@
using Daybreak.Configuration;
using Daybreak.Exceptions;
using Daybreak.Services.ApplicationLifetime;
using Daybreak.Services.Logging;
using Daybreak.Services.ViewManagement;
using Daybreak.Utils;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
using Microsoft.Extensions.Logging;
using Slim;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Extensions;
@@ -28,9 +25,15 @@ namespace Daybreak.Launch
return LaunchMainWindow();
}
protected override void SetupServiceManager(IServiceManager serviceManager)
{
ApplicationServiceManager = this.ServiceManager;
ProjectConfiguration.RegisterResolvers(serviceManager);
}
protected override void RegisterServices(IServiceProducer serviceProducer)
{
ProjectConfiguration.RegisterServices(this.ServiceManager);
ServiceManager.BuildSingletons();
ProjectConfiguration.RegisterLifetimeServices(this.ServiceManager.GetService<IApplicationLifetimeManager>());
ProjectConfiguration.RegisterViews(this.ServiceManager.GetService<IViewManager>());
}
@@ -41,10 +44,19 @@ namespace Daybreak.Launch
return false;
}
this.ServiceManager.GetService<ILogger>().LogCritical(e);
this.ServiceManager.GetService<ILogger>().LogCritical(e, $"Unhandled exception");
if (e is FatalException fatalException)
{
this.ServiceManager.GetService<ILogger>().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.");
MessageBox.Show(innerFatalException.ToString());
File.WriteAllText("crash.log", e.ToString());
return false;
}
else if (e is AggregateException aggregateException)
@@ -65,7 +77,6 @@ namespace Daybreak.Launch
}
protected override void ApplicationStarting()
{
ApplicationServiceManager = this.ServiceManager;
this.ServiceManager.GetService<IApplicationLifetimeManager>().OnStartup();
this.RegisterViewContainer();
}
-12
View File
@@ -1,12 +0,0 @@
using System;
namespace Daybreak.Models
{
public class Log
{
public LogLevel LogLevel { get; set; }
public string Message { get; set; }
public string StackTrace { get; set; }
public DateTime Timestamp { get; set; }
}
}
-10
View File
@@ -1,10 +0,0 @@
namespace Daybreak.Models
{
public enum LogLevel
{
Information,
Warning,
Error,
Critical
}
}
+14
View File
@@ -0,0 +1,14 @@
using Microsoft.CorrelationVector;
namespace Daybreak.Models
{
public class ScopeMetadata
{
public CorrelationVector CorrelationVector { get; set; }
public ScopeMetadata(CorrelationVector correlationVector)
{
this.CorrelationVector = correlationVector;
}
}
}
+4
View File
@@ -68,6 +68,10 @@ namespace Daybreak.Models.Versioning
{
parts.RemoveAt(i);
}
else
{
break;
}
}
parsedVersion = new Version
@@ -1,11 +1,10 @@
using Daybreak.Exceptions;
using Daybreak.Services.Configuration;
using Daybreak.Services.Credentials;
using Daybreak.Services.Logging;
using Daybreak.Services.Mutex;
using Daybreak.Services.Privilege;
using Daybreak.Utils;
using Daybreak.Views;
using Microsoft.Extensions.Logging;
using Microsoft.Win32;
using Pepa.Wpf.Utilities;
using System;
@@ -33,7 +32,7 @@ namespace Daybreak.Services.ApplicationLauncher
private readonly IConfigurationManager configurationManager;
private readonly ICredentialManager credentialManager;
private readonly IMutexHandler mutexHandler;
private readonly ILogger logger;
private readonly ILogger<ApplicationLauncher> logger;
private readonly IPrivilegeManager privilegeManager;
public bool IsTexmodRunning => TexModProcessDetected();
@@ -44,7 +43,7 @@ namespace Daybreak.Services.ApplicationLauncher
IConfigurationManager configurationManager,
ICredentialManager credentialManager,
IMutexHandler mutexHandler,
ILogger logger,
ILogger<ApplicationLauncher> logger,
IPrivilegeManager privilegeManager)
{
this.logger = logger.ThrowIfNull(nameof(logger));
+8 -8
View File
@@ -1,10 +1,9 @@
using Daybreak.Services.Bloogum.Models;
using Daybreak.Services.Logging;
using Daybreak.Utils;
using Microsoft.Extensions.Logging;
using System;
using System.Extensions;
using System.Http;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
namespace Daybreak.Services.Bloogum
@@ -12,15 +11,16 @@ namespace Daybreak.Services.Bloogum
public sealed class BloogumClient : IBloogumClient
{
private const string BaseAddress = "http://bloogum.net/guildwars";
private readonly HttpClient httpClient;
private readonly IHttpClient<BloogumClient> httpClient;
private readonly ILogger logger;
private readonly Random random = new();
public BloogumClient(ILogger logger)
public BloogumClient(
ILogger<BloogumClient> logger,
IHttpClient<BloogumClient> httpClient)
{
this.logger = logger.ThrowIfNull(nameof(logger));
this.httpClient = new HttpClient();
this.httpClient = httpClient.ThrowIfNull(nameof(httpClient));
}
public async Task<Optional<Stream>> GetRandomScreenShot()
@@ -53,7 +53,7 @@ namespace Daybreak.Services.Bloogum
}
catch(Exception e)
{
this.logger.LogError(e);
this.logger.LogError(e.ToString());
return Optional.None<Stream>();
}
}
+2 -2
View File
@@ -81,13 +81,13 @@ namespace Daybreak.Services.Bloogum.Models
new Category("stingraystrand", 15),
new Category("fishermenshaven", 4),
new Category("riversideprovince", 31),
new Category("sanctumcay", 21)
new Category("sanctumcay", 21),
new Category("majestysrest", 14)
});
public static readonly Location MaguumaJungle = new(
"maguuma",
new List<Category>
{
new Category("majestysrest", 14),
new Category("druidsoverlook", 1),
new Category("sagelands", 27),
new Category("thewilds", 19),
@@ -1,7 +1,6 @@
using Daybreak.Models.Builds;
using Daybreak.Services.BuildTemplates.Models;
using Daybreak.Services.Logging;
using Daybreak.Utils;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Extensions;
@@ -16,10 +15,10 @@ namespace Daybreak.Services.BuildTemplates
private const string DecodingLookupTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
private readonly static string BuildsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\Guild Wars\\Templates\\Skills";
private readonly ILogger logger;
private readonly ILogger<BuildTemplateManager> logger;
public BuildTemplateManager(
ILogger logger)
ILogger<BuildTemplateManager> logger)
{
this.logger = logger.ThrowIfNull(nameof(logger));
}
@@ -229,8 +228,10 @@ namespace Daybreak.Services.BuildTemplates
{
var curedTemplate = template.Trim();
var buildMetadata = new BuildMetadata();
buildMetadata.Base64Decoded = template.Select(c => DecodingLookupTable.IndexOf(c)).ToList();
var buildMetadata = new BuildMetadata
{
Base64Decoded = template.Select(c => DecodingLookupTable.IndexOf(c)).ToList(),
};
buildMetadata.BinaryDecoded = buildMetadata.Base64Decoded.Select(b => ToBitString(b)).ToList();
var stream = new DecodeCharStream(buildMetadata.BinaryDecoded.ToArray());
@@ -1,6 +1,6 @@
using Daybreak.Configuration;
using Daybreak.Services.Logging;
using Daybreak.Utils;
using Microsoft.Extensions.Logging;
using System;
using System.Extensions;
using System.IO;
@@ -12,11 +12,11 @@ namespace Daybreak.Services.Configuration
private const string ConfigName = "Daybreak.config.json";
private ApplicationConfiguration applicationConfiguration;
private readonly ILogger logger;
private readonly ILogger<ConfigurationManager> logger;
public event EventHandler ConfigurationChanged;
public ConfigurationManager(ILogger logger)
public ConfigurationManager(ILogger<ConfigurationManager> logger)
{
this.logger = logger.ThrowIfNull(nameof(logger));
try
@@ -1,7 +1,6 @@
using Daybreak.Models;
using Daybreak.Services.Configuration;
using Daybreak.Services.Logging;
using Daybreak.Utils;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Extensions;
@@ -15,11 +14,11 @@ namespace Daybreak.Services.Credentials
public sealed class CredentialManager : ICredentialManager
{
private static readonly byte[] Entropy = Convert.FromBase64String("R3VpbGR3YXJz");
private readonly ILogger logger;
private readonly ILogger<CredentialManager> logger;
private readonly IConfigurationManager configurationManager;
public CredentialManager(
ILogger logger,
ILogger<CredentialManager> logger,
IConfigurationManager configurationManager)
{
this.configurationManager = configurationManager.ThrowIfNull(nameof(configurationManager));
@@ -1,12 +1,12 @@
using Daybreak.Models.Builds;
using Daybreak.Services.Logging;
using Daybreak.Utils;
using Daybreak.Services.Configuration;
using HtmlAgilityPack;
using Microsoft.Extensions.Logging;
using System;
using System.Extensions;
using System.Http;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace Daybreak.Services.IconRetrieve
@@ -16,18 +16,48 @@ namespace Daybreak.Services.IconRetrieve
private const string NamePlaceholder = "[SKILLNAME]";
private const string BaseUrl = "https://wiki.guildwars.com";
private const string QueryUrl = $"wiki/File:{NamePlaceholder}.jpg";
private const string IconsDirectoryName = "Icons";
private const string IconsLocation = $"{IconsDirectoryName}/{NamePlaceholder}.jpg";
private readonly HttpClient httpClient = new();
private readonly ILogger logger;
private readonly IHttpClient<IconRetriever> httpClient;
private readonly ILogger<IconRetriever> logger;
private readonly IConfigurationManager configurationManager;
public IconRetriever(
ILogger logger)
ILogger<IconRetriever> logger,
IHttpClient<IconRetriever> httpClient,
IConfigurationManager configurationManager)
{
this.logger = logger.ThrowIfNull(nameof(logger));
this.httpClient = httpClient.ThrowIfNull(nameof(httpClient));
this.configurationManager = configurationManager.ThrowIfNull(nameof(configurationManager));
this.httpClient.BaseAddress = new Uri(BaseUrl);
if (Directory.Exists(IconsDirectoryName) is false)
{
Directory.CreateDirectory(IconsDirectoryName);
}
}
public async Task<Optional<Stream>> GetIcon(Skill skill)
{
if (this.configurationManager.GetConfiguration().KeepLocalIconCache)
{
this.logger.LogInformation($"{nameof(IconRetriever)} configured to look first in cache before downloading icons");
var maybeIcon = await this.GetLocalIcon(skill);
if (maybeIcon.ExtractValue() is Stream stream)
{
return stream;
}
}
else
{
this.logger.LogInformation($"{nameof(IconRetriever)} configured to skip local cache. Downloading icon");
}
return await this.DownloadIcon(skill);
}
private async Task<Optional<Stream>> DownloadIcon(Skill skill)
{
var curedSkillName = skill.Name
.Replace(" ", "_");
@@ -55,13 +85,42 @@ namespace Daybreak.Services.IconRetrieve
if (response.IsSuccessStatusCode)
{
this.logger.LogInformation("Retrieved latest icon stream");
return new MemoryStream(await iconResponse.Content.ReadAsByteArrayAsync());
var iconData = await iconResponse.Content.ReadAsByteArrayAsync();
if (this.configurationManager.GetConfiguration().KeepLocalIconCache)
{
await this.SaveIconLocally(skill, iconData);
}
return new MemoryStream(iconData);
}
this.logger.LogError($"Failed to retrieve icon from {BaseUrl + "/" + url}");
return Optional.None<Stream>();
}
private async Task<Optional<Stream>> GetLocalIcon(Skill skill)
{
var curedSkillName = skill.Name
.Replace(" ", "_")
.Replace("\"", "");
this.logger.LogInformation("Checking local icon cache");
if (File.Exists(IconsLocation.Replace(NamePlaceholder, curedSkillName)))
{
this.logger.LogInformation("Local icon cache found. Retrieving icon");
return new MemoryStream(await File.ReadAllBytesAsync(IconsLocation.Replace(NamePlaceholder, curedSkillName)));
}
this.logger.LogWarning("No local icon cache found");
return Optional.None<Stream>();
}
private async Task SaveIconLocally(Skill skill, byte[] data)
{
var curedSkillName = skill.Name
.Replace(" ", "_")
.Replace("\"", "");
await File.WriteAllBytesAsync(IconsLocation.Replace(NamePlaceholder, curedSkillName), data);
}
private static string GetHref(HtmlDocument doc)
{
foreach (var child in doc.DocumentNode.Descendants("a"))
@@ -1,6 +1,5 @@
using Daybreak.Models;
using Daybreak.Services.Logging;
using Daybreak.Utils;
using Microsoft.Extensions.Logging;
using Pepa.Wpf.Utilities;
using System;
using System.ComponentModel;
@@ -15,7 +14,7 @@ namespace Daybreak.Services.KeyboardHook
// https://stackoverflow.com/questions/604410/global-keyboard-capture-in-c-sharp-application
public sealed class KeyboardHookService : IKeyboardHookService, IDisposable
{
private readonly ILogger logger;
private readonly ILogger<KeyboardHookService> logger;
private IntPtr windowsHookHandle;
private IntPtr user32LibraryHandle;
private NativeMethods.HookProc hookProc;
@@ -23,7 +22,7 @@ namespace Daybreak.Services.KeyboardHook
public event EventHandler<KeyboardHookEventArgs> KeyboardPressed;
public KeyboardHookService(
ILogger logger)
ILogger<KeyboardHookService> logger)
{
this.logger = logger.ThrowIfNull(nameof(logger));
this.Setup();
@@ -1,7 +1,7 @@
using Daybreak.Models;
using Daybreak.Services.Configuration;
using Daybreak.Services.KeyboardHook;
using Daybreak.Services.Logging;
using Microsoft.Extensions.Logging;
using Pepa.Wpf.Utilities;
using System;
using System.Collections.Generic;
@@ -16,7 +16,6 @@ namespace Daybreak.Services.KeyboardMacros
public sealed class MacroService : IMacroService
{
private readonly CancellationTokenSource cancellationTokenSource = new();
private readonly ILogger logger;
private readonly IKeyboardHookService keyboardHookService;
private readonly IConfigurationManager configurationManager;
private readonly HashSet<Keys> KeysDown = new();
@@ -26,11 +25,9 @@ namespace Daybreak.Services.KeyboardMacros
private IntPtr gwWindowHwnd;
public MacroService(
ILogger logger,
IKeyboardHookService keyboardHookService,
IConfigurationManager configurationManager)
{
this.logger = logger.ThrowIfNull(nameof(logger));
this.keyboardHookService = keyboardHookService.ThrowIfNull(nameof(keyboardHookService));
this.configurationManager = configurationManager.ThrowIfNull(nameof(configurationManager));
@@ -1,143 +0,0 @@
using Daybreak.Exceptions;
using Daybreak.Models;
using Daybreak.Utils;
using System;
using System.Collections.Generic;
using System.Extensions;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Daybreak.Services.Logging
{
public class FlatLoggingDatabase : ILoggingDatabase
{
private const string Path = "logs.db";
private const int bufferSize = 10;
private const char separator = '§';
private readonly string filePath = Path;
private readonly List<string> buffer = new List<string>();
public FlatLoggingDatabase()
{
}
public Task<IEnumerable<Log>> GetLogs()
{
return Task.Run(() =>
{
lock (this.buffer)
{
if (this.buffer.Count > 0)
{
this.WriteBufferToFile();
}
}
return this.GetSerializedLogs().Select(s => s.Deserialize<Log>());
});
}
public Task<IEnumerable<Log>> GetLogsByDate(DateTime startTime, DateTime endTime)
{
return Task.Run(() =>
{
lock (this.buffer)
{
if (this.buffer.Count > 0)
{
this.WriteBufferToFile();
}
}
return this.GetSerializedLogs()
.Select(s => s.Deserialize<Log>())
.Where(l => l.Timestamp > startTime && l.Timestamp < endTime);
});
}
public Task<bool> InsertLog(Log log)
{
return Task.Run(() =>
{
lock (this.buffer)
{
this.buffer.Add(log.Serialize());
if (this.buffer.Count > bufferSize)
{
this.WriteBufferToFile();
}
}
return true;
});
}
public Task<bool> ClearDatabase()
{
return Task.Run(() =>
{
lock (this.buffer)
{
this.buffer.Clear();
}
lock (this.filePath)
{
File.WriteAllText(this.filePath, string.Empty);
}
return true;
});
}
public void OnClosing()
{
this.WriteBufferToFile();
}
public void OnStartup()
{
if (!File.Exists(filePath))
{
try
{
using var fs = File.Create(filePath);
}
catch (Exception ex)
{
throw new FatalException("Could not initialize logging. See inner exception for details.", ex);
}
}
}
private void WriteBufferToFile()
{
lock (this.filePath)
{
File.AppendAllLines(this.filePath, this.buffer.Select(s => s + separator), Encoding.UTF8);
}
this.buffer.Clear();
}
private IEnumerable<string> GetSerializedLogs()
{
lock (this.filePath)
{
var stringBuilder = new StringBuilder();
using var fileStream = File.OpenRead(this.filePath);
using var streamReader = new StreamReader(fileStream, Encoding.UTF8);
string serializedLog = null;
while ((serializedLog = streamReader.ReadUntil(separator.ToString())) != null
&& serializedLog != string.Empty
&& serializedLog != "\r"
&& serializedLog != "\n"
&& serializedLog != "\r\n")
{
yield return serializedLog;
}
}
}
}
}
-11
View File
@@ -1,11 +0,0 @@
using Daybreak.Models;
using System;
namespace Daybreak.Services.Logging
{
public interface ILogger
{
void Log(LogLevel logLevel, Exception exception);
void Log(LogLevel logLevel, string message);
}
}
@@ -1,16 +0,0 @@
using Daybreak.Models;
using Daybreak.Services.ApplicationLifetime;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Daybreak.Services.Logging
{
public interface ILoggingDatabase : IApplicationLifetimeService
{
Task<bool> ClearDatabase();
Task<IEnumerable<Log>> GetLogsByDate(DateTime startTime, DateTime endTime);
Task<IEnumerable<Log>> GetLogs();
Task<bool> InsertLog(Log log);
}
}
+12
View File
@@ -0,0 +1,12 @@
using System.Collections.Generic;
using WpfExtended.Logging;
using WpfExtended.Models;
namespace Daybreak.Services.Logging
{
public interface ILogsManager : ILogsWriter
{
IEnumerable<Log> GetLogs();
int DeleteLogs();
}
}
@@ -0,0 +1,30 @@
using LiteDB;
using System.Collections.Generic;
using System.Extensions;
using WpfExtended.Models;
namespace Daybreak.Services.Logging
{
public sealed class JsonLogsManager : ILogsManager
{
private readonly ILiteDatabase liteDatabase;
public JsonLogsManager(ILiteDatabase liteDatabase)
{
this.liteDatabase = liteDatabase.ThrowIfNull(nameof(liteDatabase));
}
public IEnumerable<Log> GetLogs()
{
return this.liteDatabase.GetCollection<Log>().FindAll();
}
public void WriteLog(Log log)
{
this.liteDatabase.GetCollection<Log>().Insert(log);
}
public int DeleteLogs()
{
return this.liteDatabase.GetCollection<Log>().DeleteAll();
}
}
}
-42
View File
@@ -1,42 +0,0 @@
using Daybreak.Models;
using System;
namespace Daybreak.Services.Logging
{
public class Logger : ILogger
{
private readonly ILoggingDatabase loggingDatabase;
public Logger(ILoggingDatabase loggingDatabase)
{
this.loggingDatabase = loggingDatabase;
}
public async void Log(LogLevel logLevel, Exception exception)
{
if (exception is null) throw new ArgumentNullException(nameof(exception));
await this.loggingDatabase.InsertLog(
new Log
{
LogLevel = logLevel,
Message = exception.Message,
StackTrace = exception.StackTrace,
Timestamp = DateTime.Now
}).ConfigureAwait(false);
}
public async void Log(LogLevel logLevel, string message)
{
if (message is null) throw new ArgumentNullException(nameof(message));
await this.loggingDatabase.InsertLog(
new Log
{
LogLevel = logLevel,
Message = message,
StackTrace = Environment.StackTrace,
Timestamp = DateTime.Now
}).ConfigureAwait(false);
}
}
}
+6 -2
View File
@@ -1,4 +1,6 @@
using Slim;
using Daybreak.Models;
using Microsoft.CorrelationVector;
using Slim;
using System;
using System.Extensions;
using System.Windows;
@@ -53,9 +55,11 @@ namespace Daybreak.Services.ViewManagement
private void ShowViewInner(Type viewType, object dataContext)
{
var scopedManager = this.serviceManager.CreateScope();
scopedManager.As<IServiceManager>().RegisterScoped<ScopeMetadata, ScopeMetadata>((sp) => new ScopeMetadata(new CorrelationVector()));
Application.Current.Dispatcher.Invoke(() =>
{
var view = this.serviceManager.GetService(viewType).As<UserControl>();
var view = scopedManager.GetService(viewType).As<UserControl>();
this.container.Children.Clear();
this.container.Children.Add(view);
view.DataContext = dataContext;
@@ -1,8 +1,7 @@
using Daybreak.Models;
using Daybreak.Services.Logging;
using Daybreak.Services.ViewManagement;
using Daybreak.Utils;
using Daybreak.Views;
using Microsoft.Extensions.Logging;
using System.Extensions;
using System.Security.Principal;
using System.Windows.Controls;
@@ -14,11 +13,11 @@ namespace Daybreak.Services.Privilege
public bool AdminPrivileges => new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
private readonly IViewManager viewManager;
private readonly ILogger logger;
private readonly ILogger<PrivilegeManager> logger;
public PrivilegeManager(
IViewManager viewManager,
ILogger logger)
ILogger<PrivilegeManager> logger)
{
this.logger = logger.ThrowIfNull(nameof(logger));
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
+3 -4
View File
@@ -1,6 +1,5 @@
using Daybreak.Models;
using Daybreak.Services.Logging;
using Daybreak.Utils;
using Microsoft.Extensions.Logging;
using Pepa.Wpf.Utilities;
using System;
using System.Collections.Generic;
@@ -12,13 +11,13 @@ namespace Daybreak.Services.Screens
{
public sealed class ScreenManager : IScreenManager
{
private readonly ILogger logger;
private readonly ILogger<ScreenManager> logger;
public IEnumerable<Screen> Screens { get; } = WpfScreenHelper.Screen.AllScreens
.Select((screen, index) => new Screen { Id = index, Size = screen.Bounds });
public ScreenManager(
ILogger logger)
ILogger<ScreenManager> logger)
{
this.logger = logger.ThrowIfNull(nameof(logger));
}
@@ -1,5 +1,4 @@
using Daybreak.Services.Logging;
using Daybreak.Utils;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Extensions;
@@ -14,11 +13,11 @@ namespace Daybreak.Services.Screenshots
{
private const string ScreenshotsFolder = "Screenshots";
private readonly List<string> Screenshots = new List<string>();
private readonly ILogger logger;
private readonly List<string> Screenshots = new();
private readonly ILogger<ScreenshotProvider> logger;
private int innerCount = 0;
public ScreenshotProvider(ILogger logger)
public ScreenshotProvider(ILogger<ScreenshotProvider> logger)
{
this.logger = logger.ThrowIfNull(nameof(logger));
if (Directory.Exists(ScreenshotsFolder) is false)
@@ -1,16 +1,17 @@
using Daybreak.Exceptions;
using Daybreak.Models;
using Daybreak.Models.Github;
using Daybreak.Services.Logging;
using Daybreak.Services.Runtime;
using Daybreak.Services.ViewManagement;
using Daybreak.Utils;
using Daybreak.Views;
using Microsoft.Extensions.Logging;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Extensions;
using System.Http;
using System.IO;
using System.Linq;
using System.Net.Http;
@@ -56,21 +57,23 @@ namespace Daybreak.Services.Updater
private const string RemovePs1 = $"Remove-item {ExtractAndRunPs1}";
private readonly CancellationTokenSource updateCancellationTokenSource = new();
private readonly ILogger logger;
private readonly ILogger<ApplicationUpdater> logger;
private readonly IViewManager viewManager;
private readonly IRuntimeStore runtimeStore;
private readonly HttpClient httpClient = new();
private readonly IHttpClient<ApplicationUpdater> httpClient;
public Version CurrentVersion { get; }
public ApplicationUpdater(
ILogger logger,
ILogger<ApplicationUpdater> logger,
IRuntimeStore runtimeStore,
IViewManager viewManager)
IViewManager viewManager,
IHttpClient<ApplicationUpdater> httpClient)
{
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
this.runtimeStore = runtimeStore.ThrowIfNull(nameof(runtimeStore));
this.logger = logger.ThrowIfNull(nameof(logger));
this.httpClient = httpClient.ThrowIfNull(nameof(httpClient));
this.httpClient.DefaultRequestHeaders.Add("user-agent", "Daybreak Client");
if (Version.TryParse(Assembly.GetExecutingAssembly().GetName().Version.ToString(), out var currentVersion))
{
-65
View File
@@ -1,65 +0,0 @@
using Daybreak.Models;
using Daybreak.Services.Logging;
using System;
namespace Daybreak.Utils
{
public static class LoggingExtensions
{
public static void LogInformation(this ILogger logger, string message)
{
if (logger is null) throw new ArgumentNullException(nameof(logger));
logger.Log(LogLevel.Information, message);
}
public static void LogError(this ILogger logger, string message)
{
if (logger is null) throw new ArgumentNullException(nameof(logger));
logger.Log(LogLevel.Error, message);
}
public static void LogCritical(this ILogger logger, string message)
{
if (logger is null) throw new ArgumentNullException(nameof(logger));
logger.Log(LogLevel.Critical, message);
}
public static void LogWarning(this ILogger logger, string message)
{
if (logger is null) throw new ArgumentNullException(nameof(logger));
logger.Log(LogLevel.Warning, message);
}
public static void LogInformation(this ILogger logger, Exception e)
{
if (logger is null) throw new ArgumentNullException(nameof(logger));
logger.Log(LogLevel.Information, e);
}
public static void LogWarning(this ILogger logger, Exception e)
{
if (logger is null) throw new ArgumentNullException(nameof(logger));
logger.Log(LogLevel.Warning, e);
}
public static void LogError(this ILogger logger, Exception e)
{
if (logger is null) throw new ArgumentNullException(nameof(logger));
logger.Log(LogLevel.Error, e);
}
public static void LogCritical(this ILogger logger, Exception e)
{
if (logger is null) throw new ArgumentNullException(nameof(logger));
logger.Log(LogLevel.Critical, e);
}
}
}
+4 -5
View File
@@ -1,9 +1,8 @@
using Daybreak.Services.Logging;
using Daybreak.Services.Privilege;
using Daybreak.Services.Privilege;
using Daybreak.Services.Runtime;
using Daybreak.Services.Updater;
using Daybreak.Services.ViewManagement;
using Daybreak.Utils;
using Microsoft.Extensions.Logging;
using System.Extensions;
using System.Linq;
using System.Windows.Controls;
@@ -17,14 +16,14 @@ namespace Daybreak.Views
{
private const string UpdateDesiredKey = "UpdateDesired";
private readonly ILogger logger;
private readonly ILogger<AskUpdateView> logger;
private readonly IViewManager viewManager;
private readonly IRuntimeStore runtimeStore;
private readonly IPrivilegeManager privilegeManager;
private readonly IApplicationUpdater applicationUpdater;
public AskUpdateView(
ILogger logger,
ILogger<AskUpdateView> logger,
IViewManager viewManager,
IRuntimeStore runtimeStore,
IPrivilegeManager privilegeManager,
+12 -1
View File
@@ -11,6 +11,7 @@
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="#A0202020">
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
@@ -35,7 +36,17 @@
<controls:SaveButton Foreground="White" Height="30" Width="30" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5"
Clicked="SaveButton_Clicked" Grid.Column="2" IsEnabled="{Binding ElementName=_this, Path=SaveButtonEnabled, Mode=OneWay}"></controls:SaveButton>
</Grid>
<controls:BuildTemplate Grid.Row="1" DataContext="{Binding ElementName=_this, Path=CurrentBuild, Mode=OneWay}">
<Grid Grid.Row="1" Margin="10, 0, 10, 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="Code: " Foreground="White" Background="Transparent" FontSize="16"></TextBlock>
<TextBox Grid.Column="1" Foreground="White" Background="Transparent" FontSize="16"
Text="{Binding ElementName=_this, Path=CurrentBuildCode, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
</Grid>
<controls:BuildTemplate x:Name="BuildTemplate" Grid.Row="2" DataContext="{Binding ElementName=_this, Path=CurrentBuild, Mode=OneWay}"
BuildChanged="BuildTemplate_BuildChanged">
</controls:BuildTemplate>
</Grid>
</UserControl>
+65 -19
View File
@@ -1,12 +1,17 @@
using Daybreak.Models.Builds;
using Daybreak.Controls;
using Daybreak.Models.Builds;
using Daybreak.Services.BuildTemplates;
using Daybreak.Services.Configuration;
using Daybreak.Services.IconRetrieve;
using Daybreak.Services.ViewManagement;
using Microsoft.Extensions.Logging;
using System;
using System.Extensions;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Extensions;
using System.Windows.Input;
namespace Daybreak.Views
{
@@ -17,47 +22,89 @@ namespace Daybreak.Views
{
private const string DisallowedChars = "\r\n\\/.";
public readonly static DependencyProperty CurrentBuildProperty =
DependencyPropertyExtensions.Register<BuildTemplateView, BuildEntry>(nameof(CurrentBuild));
public readonly static DependencyProperty SaveButtonEnabledProperty =
DependencyPropertyExtensions.Register<BuildTemplateView, bool>(nameof(SaveButtonEnabled), new PropertyMetadata(false));
private bool supressDecode = false;
private readonly IViewManager viewManager;
private readonly IBuildTemplateManager buildTemplateManager;
private readonly ILogger<BuildTemplateView> logger;
public bool SaveButtonEnabled
{
get => this.GetTypedValue<bool>(SaveButtonEnabledProperty);
set => this.SetValue(SaveButtonEnabledProperty, value);
}
public BuildEntry CurrentBuild
{
get => this.GetTypedValue<BuildEntry>(CurrentBuildProperty);
set => this.SetValue(CurrentBuildProperty, value);
}
[GenerateDependencyProperty(InitialValue = false)]
private bool saveButtonEnabled;
[GenerateDependencyProperty]
private BuildEntry currentBuild;
[GenerateDependencyProperty]
private string currentBuildCode;
public BuildTemplateView(
IViewManager viewManager,
IBuildTemplateManager buildTemplateManager)
IBuildTemplateManager buildTemplateManager,
IIconRetriever iconRetriever,
IConfigurationManager configurationManager,
ILogger<ChromiumBrowserWrapper> chromiumLogger,
ILogger<BuildTemplateView> logger)
{
this.buildTemplateManager = buildTemplateManager.ThrowIfNull(nameof(buildTemplateManager));
this.logger = logger.ThrowIfNull(nameof(logger));
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
this.InitializeComponent();
this.BuildTemplate.InitializeTemplate(iconRetriever, configurationManager, buildTemplateManager, chromiumLogger);
this.DataContextChanged += (sender, contextArgs) =>
{
if (contextArgs.NewValue is BuildEntry)
{
this.logger.LogInformation("Received data context. Setting current build");
this.CurrentBuild = contextArgs.NewValue.As<BuildEntry>();
this.CurrentBuildCode = this.buildTemplateManager.EncodeTemplate(this.CurrentBuild.Build);
}
};
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == CurrentBuildCodeProperty && this.supressDecode is false)
{
this.logger.LogInformation($"Attempting to decode provided template {this.CurrentBuildCode}");
try
{
this.CurrentBuild = new BuildEntry
{
Name = this.CurrentBuild.Name,
PreviousName = this.CurrentBuild.PreviousName,
Build = this.buildTemplateManager.DecodeTemplate(this.CurrentBuildCode)
};
this.logger.LogInformation($"Template {CurrentBuildCode} decoded");
}
catch
{
this.logger.LogWarning($"Failed to decode {this.CurrentBuildCode}. Reverting to default build");
this.CurrentBuild = new BuildEntry
{
Name = this.CurrentBuild.Name,
PreviousName = this.CurrentBuild.PreviousName,
Build = new Build()
};
}
}
}
private void BuildTemplate_BuildChanged(object sender, EventArgs e)
{
try
{
this.supressDecode = true;
this.CurrentBuildCode = this.buildTemplateManager.EncodeTemplate(this.CurrentBuild.Build);
}
finally
{
this.supressDecode = false;
}
}
private void BackButton_Clicked(object sender, EventArgs e)
{
this.viewManager.ShowView<BuildsListView>();
}
private void SaveButton_Clicked(object sender, EventArgs e)
{
this.buildTemplateManager.SaveBuild(this.CurrentBuild);
@@ -71,7 +118,6 @@ namespace Daybreak.Views
e.Handled = true;
}
}
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (string.IsNullOrWhiteSpace(sender.As<TextBox>().Text))
+61
View File
@@ -0,0 +1,61 @@
<UserControl x:Class="Daybreak.Views.LogsView"
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.Views"
xmlns:controls="clr-namespace:Daybreak.Controls"
mc:Ignorable="d"
x:Name="_this"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<Style TargetType="{x:Type TextBlock}" x:Key="WrapText">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</UserControl.Resources>
<Grid Background="#A0202020">
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<controls:BackButton Foreground="White" Height="30" Width="30" HorizontalAlignment="Left" Margin="5"
Clicked="BackButton_Clicked"></controls:BackButton>
<controls:BinButton Foreground="White" Height="30" Width="30" HorizontalAlignment="Right" Margin="5"
Clicked="BinButton_Clicked"></controls:BinButton>
<controls:RefreshGlyph Foreground="White" Height="30" Width="30" HorizontalAlignment="Right" Margin="0, 5, 45, 5"
Clicked="RefreshGlyph_Clicked"></controls:RefreshGlyph>
<DataGrid IsReadOnly="True" Background="Transparent" Foreground="White" Grid.Row="1"
ItemsSource="{Binding ElementName=_this, Path=Logs, Mode=OneWay}" HorizontalScrollBarVisibility="Disabled"
AutoGenerateColumns="False" HeadersVisibility="Column" EnableColumnVirtualization="True"
EnableRowVirtualization="True">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="BorderBrush" Value="#80808080"></Setter>
<Setter Property="BorderThickness" Value="1"></Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="BorderBrush" Value="#80808080"></Setter>
<Setter Property="BorderThickness" Value="1"></Setter>
</Style>
</DataGrid.CellStyle>
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn IsReadOnly="True" Header="DateTime" Binding="{Binding LogTime}" ElementStyle="{StaticResource WrapText}" Width="auto"/>
<DataGridTextColumn IsReadOnly="True" Header="CV" Binding="{Binding CorrelationVector}" ElementStyle="{StaticResource WrapText}" Width="auto"/>
<DataGridTextColumn IsReadOnly="True" Header="Category" Binding="{Binding Category}" ElementStyle="{StaticResource WrapText}" Width="auto"/>
<DataGridTextColumn IsReadOnly="True" Header="LogLevel" Binding="{Binding LogLevel}" ElementStyle="{StaticResource WrapText}" Width="auto"/>
<DataGridTextColumn IsReadOnly="True" Header="EventId" Binding="{Binding EventId}" ElementStyle="{StaticResource WrapText}" Width="auto"/>
<DataGridTextColumn IsReadOnly="True" Header="Message" Binding="{Binding Message}" ElementStyle="{StaticResource WrapText}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</UserControl>
+49
View File
@@ -0,0 +1,49 @@
using Daybreak.Services.Logging;
using Daybreak.Services.ViewManagement;
using System;
using System.Collections.ObjectModel;
using System.Extensions;
using System.Windows.Controls;
using WpfExtended.Models;
namespace Daybreak.Views
{
/// <summary>
/// Interaction logic for LogsView.xaml
/// </summary>
public partial class LogsView : UserControl
{
private readonly IViewManager viewManager;
private readonly ILogsManager logManager;
public ObservableCollection<Log> Logs { get; } = new ObservableCollection<Log>();
public LogsView(
IViewManager viewManager,
ILogsManager logManager)
{
this.logManager = logManager.ThrowIfNull(nameof(logManager));
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
this.InitializeComponent();
this.UpdateLogs();
}
private void UpdateLogs()
{
this.Logs.ClearAnd().AddRange(this.logManager.GetLogs());
}
private void BackButton_Clicked(object sender, EventArgs e)
{
this.viewManager.ShowView<SettingsCategoryView>();
}
private void BinButton_Clicked(object sender, EventArgs e)
{
this.logManager.DeleteLogs();
this.UpdateLogs();
}
private void RefreshGlyph_Clicked(object sender, EventArgs e)
{
this.UpdateLogs();
}
}
}
+4 -2
View File
@@ -40,7 +40,8 @@
Clicked="LaunchTexmodButton_Clicked" Grid.Row="1" Grid.ColumnSpan="2" Grid.Column="1"
Visibility="{Binding ElementName=_this, Path=ButtonsVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibility}}"></controls:OpaqueButton>
<Grid Grid.Column="2" Margin="10" Visibility="{Binding ElementName=_this, Path=BrowsersEnabled, Mode=OneWay, Converter={StaticResource BooleanToVisibility}}">
<controls:ChromiumBrowserWrapper Address="{Binding ElementName=_this, Path=RightBrowserAddress, Mode=OneWay}"
<controls:ChromiumBrowserWrapper x:Name="RightWebBrowser"
Address="{Binding ElementName=_this, Path=RightBrowserAddress, Mode=OneWay}"
Foreground="White" FavoriteUriChanged="RightBrowser_FavoriteUriChanged"
FavoriteAddress="{Binding ElementName=_this, Path=RightBrowserFavoriteAddress, Mode=OneWay}"
MaximizeClicked="RightChromiumBrowserWrapper_MaximizeClicked"
@@ -48,7 +49,8 @@
CanDownloadBuild="True"/>
</Grid>
<Grid Grid.Column="0" Margin="10" Visibility="{Binding ElementName=_this, Path=BrowsersEnabled, Mode=OneWay, Converter={StaticResource BooleanToVisibility}}">
<controls:ChromiumBrowserWrapper Address="{Binding ElementName=_this, Path=LeftBrowserAddress, Mode=OneWay}"
<controls:ChromiumBrowserWrapper x:Name="LeftWebBrowser"
Address="{Binding ElementName=_this, Path=LeftBrowserAddress, Mode=OneWay}"
Foreground="White" FavoriteUriChanged="LeftBrowser_FavoriteUriChanged"
FavoriteAddress="{Binding ElementName=_this, Path=LeftBrowserFavoriteAddress, Mode=OneWay}"
MaximizeClicked="LeftChromiumBrowserWrapper_MaximizeClicked"
+18 -2
View File
@@ -1,9 +1,12 @@
using Daybreak.Exceptions;
using Daybreak.Controls;
using Daybreak.Exceptions;
using Daybreak.Models.Builds;
using Daybreak.Services.ApplicationLauncher;
using Daybreak.Services.BuildTemplates;
using Daybreak.Services.Configuration;
using Daybreak.Services.Screens;
using Daybreak.Services.ViewManagement;
using Microsoft.Extensions.Logging;
using System;
using System.Extensions;
using System.Linq;
@@ -26,6 +29,8 @@ namespace Daybreak.Views
private readonly IViewManager viewManager;
private readonly IConfigurationManager configurationManager;
private readonly IScreenManager screenManager;
private readonly IBuildTemplateManager buildTemplateManager;
private readonly ILogger<ChromiumBrowserWrapper> browserLogger;
private readonly CancellationTokenSource cancellationTokenSource = new();
private bool leftBrowserMaximized = false;
@@ -54,17 +59,28 @@ namespace Daybreak.Views
IApplicationLauncher applicationDetector,
IViewManager viewManager,
IConfigurationManager configurationManager,
IScreenManager screenManager)
IScreenManager screenManager,
IBuildTemplateManager buildTemplateManager,
ILogger<ChromiumBrowserWrapper> browserLogger)
{
this.browserLogger = browserLogger;
this.buildTemplateManager = buildTemplateManager.ThrowIfNull(nameof(buildTemplateManager));
this.screenManager = screenManager.ThrowIfNull(nameof(screenManager));
this.configurationManager = configurationManager.ThrowIfNull(nameof(configurationManager));
this.applicationDetector = applicationDetector.ThrowIfNull(nameof(applicationDetector));
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
this.InitializeComponent();
this.PeriodicallyCheckGameState();
this.InitializeBrowsers();
this.NavigateToDefaults();
}
private void InitializeBrowsers()
{
this.LeftWebBrowser.InitializeBrowser(this.configurationManager, this.buildTemplateManager, this.browserLogger);
this.RightWebBrowser.InitializeBrowser(this.configurationManager, this.buildTemplateManager, this.browserLogger);
}
private void NavigateToDefaults()
{
var applicationConfiguration = this.configurationManager.GetConfiguration();
+3 -4
View File
@@ -1,8 +1,7 @@
using Daybreak.Models;
using Daybreak.Services.ApplicationLauncher;
using Daybreak.Services.Logging;
using Daybreak.Services.ViewManagement;
using Daybreak.Utils;
using Microsoft.Extensions.Logging;
using System.Extensions;
using System.Windows.Controls;
@@ -15,12 +14,12 @@ namespace Daybreak.Views
{
private readonly IApplicationLauncher applicationLauncher;
private readonly IViewManager viewManager;
private readonly ILogger logger;
private readonly ILogger<RequestElevationView> logger;
public RequestElevationView(
IApplicationLauncher applicationLauncher,
IViewManager viewManager,
ILogger logger)
ILogger<RequestElevationView> logger)
{
this.applicationLauncher = applicationLauncher.ThrowIfNull(nameof(applicationLauncher));
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
+6
View File
@@ -48,6 +48,12 @@
<controls:StaticGlyph></controls:StaticGlyph>
</controls:TileButton.InnerContent>
</controls:TileButton>
<controls:TileButton Title="Logs" Foreground="White" BorderBrush="White" BorderThickness="2"
HighlightColor="White" Clicked="LogsButton_Clicked" Height="150" Width="150">
<controls:TileButton.InnerContent>
<controls:LogsGlyph></controls:LogsGlyph>
</controls:TileButton.InnerContent>
</controls:TileButton>
</WrapPanel>
</WrapPanel>
</Grid>
@@ -43,6 +43,11 @@ namespace Daybreak.Views
this.viewManager.ShowView<VersionManagementView>(this);
}
private void LogsButton_Clicked(object sender, System.EventArgs e)
{
this.viewManager.ShowView<LogsView>();
}
private void FileButton_Clicked(object sender, System.EventArgs e)
{
this.viewManager.ShowView<ExecutablesView>();
+3
View File
@@ -94,6 +94,7 @@
<TextBlock Text="Desired screen id: " FontSize="22" Foreground="White" Height="30"></TextBlock>
<TextBlock Text="Place Shortcut: " FontSize="22" Foreground="White" Height="30"></TextBlock>
<TextBlock Text="Shortcut folder: " FontSize="22" Foreground="White" Height="30"></TextBlock>
<TextBlock Text="Keep local cache of icons: " FontSize="22" Foreground="White" Height="30"></TextBlock>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Row="1" Grid.Column="1">
<ToggleButton HorizontalAlignment="Center" HorizontalContentAlignment="Stretch" Style="{StaticResource AnimatedSwitch}" Height="30" Width="40"
@@ -148,6 +149,8 @@
Foreground="White" BorderBrush="Gray" BorderThickness="0"
Clicked="ShortcutFolderPickerGlyph_Clicked"></controls:FilePickerGlyph>
</Grid>
<ToggleButton HorizontalAlignment="Center" HorizontalContentAlignment="Stretch" Style="{StaticResource AnimatedSwitch}" Height="30" Width="40"
FontSize="22" Foreground="White" IsChecked="{Binding ElementName=_this, Path=KeepLocalIconCache, Mode=TwoWay}"></ToggleButton>
</StackPanel>
</Grid>
</ScrollViewer>
+4
View File
@@ -45,6 +45,8 @@ namespace Daybreak.Views
private bool shortcutPlaced;
[GenerateDependencyProperty]
private bool autoCheckUpdate;
[GenerateDependencyProperty]
private bool keepLocalIconCache;
public SettingsView(
IConfigurationManager configurationManager,
@@ -71,6 +73,7 @@ namespace Daybreak.Views
this.ShortcutFolder = config.ShortcutLocation;
this.ShortcutPlaced = config.PlaceShortcut;
this.AutoCheckUpdate = config.AutoCheckUpdate;
this.KeepLocalIconCache = config.KeepLocalIconCache;
}
private void SaveButton_Clicked(object sender, EventArgs e)
@@ -88,6 +91,7 @@ namespace Daybreak.Views
currentConfig.ShortcutLocation = this.ShortcutFolder;
currentConfig.PlaceShortcut = this.ShortcutPlaced;
currentConfig.AutoCheckUpdate = this.AutoCheckUpdate;
currentConfig.KeepLocalIconCache = this.KeepLocalIconCache;
this.configurationManager.SaveConfiguration(currentConfig);
this.viewManager.ShowView<SettingsCategoryView>();
}
+3 -4
View File
@@ -1,8 +1,7 @@
using Daybreak.Models;
using Daybreak.Services.Logging;
using Daybreak.Services.Updater;
using Daybreak.Services.ViewManagement;
using Daybreak.Utils;
using Microsoft.Extensions.Logging;
using System;
using System.Windows;
using System.Windows.Controls;
@@ -18,7 +17,7 @@ namespace Daybreak.Views
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
public partial class UpdateView : UserControl
{
private readonly ILogger logger;
private readonly ILogger<UpdateView> logger;
private readonly IViewManager viewManager;
private readonly IApplicationUpdater applicationUpdater;
private readonly UpdateStatus updateStatus = new();
@@ -33,7 +32,7 @@ namespace Daybreak.Views
public UpdateView(
IApplicationUpdater applicationUpdater,
ILogger logger,
ILogger<UpdateView> logger,
IViewManager viewManager)
{
this.applicationUpdater = applicationUpdater;