mirror of
https://github.com/gwdevhub/Daybreak.git
synced 2026-09-16 21:35:20 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c99bb8d074 | ||
|
|
a98e54ebc6 | ||
|
|
a832aa1925 | ||
|
|
c7eb5debcb | ||
|
|
91f0cb4e31 | ||
|
|
5e8407a6ab | ||
|
|
243c2c1536 | ||
|
|
930aca4ffe | ||
|
|
1639cabe8e | ||
|
|
5961a57c5b | ||
|
|
75d9bc6dec | ||
|
|
4ccca32881 | ||
|
|
a7f5d9dd96 | ||
|
|
c8ba125abc |
@@ -24,11 +24,32 @@ catch
|
||||
|
||||
}
|
||||
Console.WriteLine("Deleting package");
|
||||
File.Delete(tempFile);
|
||||
try
|
||||
{
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.WriteLine($"Failed to delete {tempFile}.\n{e}");
|
||||
}
|
||||
|
||||
Console.WriteLine("Deleting browser caches");
|
||||
Directory.Delete("BrowserData", true);
|
||||
Directory.Delete("Daybreak.exe.WebView2", true);
|
||||
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
|
||||
@@ -43,4 +64,4 @@ if (process.Start() is false)
|
||||
{
|
||||
Console.WriteLine("Failed to launch application");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,5 +39,7 @@ namespace Daybreak.Configuration
|
||||
public bool AutoCheckUpdate { get; set; } = true;
|
||||
[JsonProperty("ProtectedGraphAccessToken")]
|
||||
public string ProtectedGraphAccessToken { get; set; }
|
||||
[JsonProperty("ProtectedGraphRefreshToken")]
|
||||
public string ProtectedGraphRefreshToken { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ 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;
|
||||
@@ -27,90 +26,111 @@ 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();
|
||||
|
||||
serviceManager.RegisterOptionsManager<ApplicationConfigurationOptionsManager>();
|
||||
serviceManager.RegisterResolver(new LoggerResolver());
|
||||
serviceManager
|
||||
.RegisterHttpClient<ApplicationUpdater>()
|
||||
.WithMessageHandler(sp =>
|
||||
{
|
||||
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(IServiceCollection services)
|
||||
{
|
||||
services.ThrowIfNull();
|
||||
|
||||
services.AddSingleton<ILogsManager, JsonLogsManager>();
|
||||
services.AddSingleton<IDebugLogsWriter, Services.Logging.DebugLogsWriter>();
|
||||
services.AddSingleton<ILoggerFactory, LoggerFactory>(sp =>
|
||||
{
|
||||
serviceManager.ThrowIfNull();
|
||||
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>()));
|
||||
|
||||
serviceManager.RegisterHttpFactory((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;
|
||||
});
|
||||
serviceManager.RegisterOptionsManager<ApplicationConfigurationOptionsManager>();
|
||||
}
|
||||
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>();
|
||||
}
|
||||
|
||||
public static void RegisterServices(IServiceProducer serviceProducer)
|
||||
{
|
||||
serviceProducer.ThrowIfNull();
|
||||
public static void RegisterViews(IViewProducer viewProducer)
|
||||
{
|
||||
viewProducer.ThrowIfNull();
|
||||
|
||||
serviceProducer.RegisterSingleton<ILogsManager, JsonLogsManager>();
|
||||
serviceProducer.RegisterSingleton<IDebugLogsWriter, Services.Logging.DebugLogsWriter>();
|
||||
serviceProducer.RegisterSingleton<ILoggerFactory, LoggerFactory>(sp =>
|
||||
{
|
||||
var factory = new LoggerFactory();
|
||||
factory.AddProvider(new CVLoggerProvider(sp.GetService<ILogsWriter>()));
|
||||
return factory;
|
||||
});
|
||||
serviceProducer.RegisterSingleton<ILogsWriter, CompositeLogsWriter>(sp => new CompositeLogsWriter(
|
||||
sp.GetService<ILogsManager>(),
|
||||
sp.GetService<IDebugLogsWriter>()));
|
||||
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>();
|
||||
}
|
||||
|
||||
serviceProducer.RegisterScoped((sp) => new ScopeMetadata(new CorrelationVector()));
|
||||
serviceProducer.RegisterSingleton<ViewManager>(registerAllInterfaces: true);
|
||||
serviceProducer.RegisterSingleton<PostUpdateActionManager>(registerAllInterfaces: true);
|
||||
serviceProducer.RegisterSingleton<IConfigurationManager, ConfigurationManager>();
|
||||
serviceProducer.RegisterSingleton<ILiteDatabase, LiteDatabase>(sp => new LiteDatabase("Daybreak.db"));
|
||||
serviceProducer.RegisterSingleton<IMutexHandler, MutexHandler>();
|
||||
serviceProducer.RegisterSingleton<IShortcutManager, ShortcutManager>();
|
||||
serviceProducer.RegisterSingleton<IIconBrowser, IconBrowser>();
|
||||
serviceProducer.RegisterSingleton<IIconDownloader, IconDownloader>();
|
||||
serviceProducer.RegisterScoped<ICredentialManager, CredentialManager>();
|
||||
serviceProducer.RegisterScoped<IApplicationLauncher, ApplicationLauncher>();
|
||||
serviceProducer.RegisterScoped<IScreenshotProvider, ScreenshotProvider>();
|
||||
serviceProducer.RegisterScoped<IBloogumClient, BloogumClient>();
|
||||
serviceProducer.RegisterScoped<IApplicationUpdater, ApplicationUpdater>();
|
||||
serviceProducer.RegisterScoped<IBuildTemplateManager, BuildTemplateManager>();
|
||||
serviceProducer.RegisterScoped<IIconCache, IconCache>();
|
||||
serviceProducer.RegisterScoped<IPrivilegeManager, PrivilegeManager>();
|
||||
serviceProducer.RegisterScoped<IScreenManager, ScreenManager>();
|
||||
serviceProducer.RegisterScoped<IGraphClient, GraphClient>();
|
||||
}
|
||||
public static void RegisterPostUpdateActions(IPostUpdateActionProducer postUpdateActionProducer)
|
||||
{
|
||||
postUpdateActionProducer.ThrowIfNull();
|
||||
|
||||
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.RegisterView<IconDownloadView>();
|
||||
viewProducer.RegisterView<GraphAuthorizationView>();
|
||||
viewProducer.RegisterView<BuildsSynchronizationView>();
|
||||
}
|
||||
|
||||
public static void RegisterPostUpdateActions(IPostUpdateActionProducer postUpdateActionProducer)
|
||||
{
|
||||
postUpdateActionProducer.ThrowIfNull();
|
||||
|
||||
postUpdateActionProducer.AddPostUpdateAction<RenameInstallerAction>();
|
||||
}
|
||||
postUpdateActionProducer.AddPostUpdateAction<RenameInstallerAction>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
[GenerateDependencyProperty]
|
||||
private FrameworkElement innerContent;
|
||||
[GenerateDependencyProperty]
|
||||
private string title;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -3,66 +3,65 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
public bool Highlighted
|
||||
{
|
||||
get => (bool)this.GetValue(HighlightedProperty);
|
||||
set => this.SetValue(HighlightedProperty, value);
|
||||
}
|
||||
|
||||
public TileButton()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
public string Title
|
||||
{
|
||||
get => this.GetValue(TitleProperty) as string;
|
||||
set => this.SetValue(TitleProperty, value);
|
||||
}
|
||||
|
||||
public bool Highlighted
|
||||
{
|
||||
get => (bool)this.GetValue(HighlightedProperty);
|
||||
set => this.SetValue(HighlightedProperty, value);
|
||||
}
|
||||
public FrameworkElement InnerContent
|
||||
{
|
||||
get => this.GetValue(InnerContentProperty) as FrameworkElement;
|
||||
set => this.SetValue(InnerContentProperty, value);
|
||||
}
|
||||
|
||||
public string Title
|
||||
{
|
||||
get => this.GetValue(TitleProperty) as string;
|
||||
set => this.SetValue(TitleProperty, value);
|
||||
}
|
||||
public Brush HighlightColor
|
||||
{
|
||||
get => this.GetValue(HighlightColorProperty) as Brush;
|
||||
set => this.SetValue(HighlightColorProperty, value);
|
||||
}
|
||||
|
||||
public FrameworkElement InnerContent
|
||||
{
|
||||
get => this.GetValue(InnerContentProperty) as FrameworkElement;
|
||||
set => this.SetValue(InnerContentProperty, value);
|
||||
}
|
||||
private void Grid_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.Highlighted = true;
|
||||
}
|
||||
|
||||
public Brush HighlightColor
|
||||
{
|
||||
get => this.GetValue(HighlightColorProperty) as Brush;
|
||||
set => this.SetValue(HighlightColorProperty, value);
|
||||
}
|
||||
private void Grid_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
this.Highlighted = false;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Daybreak.Models.Browser;
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using Daybreak.Utils;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using System;
|
||||
@@ -54,6 +55,8 @@ namespace Daybreak.Controls
|
||||
private bool navigating;
|
||||
[GenerateDependencyProperty]
|
||||
private string favoriteAddress;
|
||||
[GenerateDependencyProperty(InitialValue = false)]
|
||||
private bool preventDispose;
|
||||
public string Address
|
||||
{
|
||||
get => this.GetTypedValue<string>(AddressProperty);
|
||||
@@ -83,9 +86,9 @@ namespace Daybreak.Controls
|
||||
|
||||
public async Task InitializeDefaultBrowser()
|
||||
{
|
||||
var options = Launch.Launcher.Instance.ApplicationServiceManager.GetService<ILiveOptions<ApplicationConfiguration>>();
|
||||
var buildTemplateManager = Launch.Launcher.Instance.ApplicationServiceManager.GetService<IBuildTemplateManager>();
|
||||
var logger = Launch.Launcher.Instance.ApplicationServiceManager.GetService<ILogger<ChromiumBrowserWrapper>>();
|
||||
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);
|
||||
}
|
||||
@@ -260,6 +263,11 @@ namespace Daybreak.Controls
|
||||
|
||||
private void UserControl_Unloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (this.PreventDispose)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.WebBrowser?.Dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using Daybreak.Services.IconRetrieve;
|
||||
using Daybreak.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -15,7 +16,6 @@ using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
using Utils;
|
||||
|
||||
namespace Daybreak.Controls
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>Daybreak</RootNamespace>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
@@ -10,7 +11,7 @@
|
||||
<LangVersion>preview</LangVersion>
|
||||
<ApplicationIcon>Daybreak.ico</ApplicationIcon>
|
||||
<IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation>
|
||||
<Version>0.9.6.2</Version>
|
||||
<Version>0.9.7.2</Version>
|
||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||
<UserSecretsId>cfb2a489-db80-448d-a969-80270f314c46</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
@@ -38,20 +39,20 @@
|
||||
<PackageReference Include="Microsoft.CorrelationVector" Version="1.0.42" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.1293.44" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.1370.28" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="NReco.Logging.File" Version="1.1.5" />
|
||||
<PackageReference Include="securifybv.ShellLink" Version="0.1.0" />
|
||||
<PackageReference Include="Slim" Version="1.7.3" />
|
||||
<PackageReference Include="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.6.2" />
|
||||
<PackageReference Include="WpfExtended" Version="0.7.1" />
|
||||
<PackageReference Include="WpfExtended.SourceGeneration" Version="0.1.1" />
|
||||
<PackageReference Include="WpfScreenHelper" Version="2.0.0" />
|
||||
<PackageReference Include="WpfScreenHelper" Version="2.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -105,7 +106,7 @@
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<Exec Command="echo.>$(Version).version" />
|
||||
</Target>
|
||||
|
||||
+15
-11
@@ -1,9 +1,11 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Exceptions;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Services.Updater.PostUpdate;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Slim;
|
||||
using Slim.Integration.ServiceCollection;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -20,7 +22,7 @@ namespace Daybreak.Launch
|
||||
|
||||
private ILogger logger;
|
||||
|
||||
public IServiceManager ApplicationServiceManager => this.ServiceManager;
|
||||
public System.IServiceProvider ApplicationServiceProvider => this.ServiceProvider;
|
||||
|
||||
[STAThread]
|
||||
public static int Main()
|
||||
@@ -28,16 +30,15 @@ namespace Daybreak.Launch
|
||||
return LaunchMainWindow();
|
||||
}
|
||||
|
||||
protected override void SetupServiceManager(IServiceManager serviceManager)
|
||||
protected override System.IServiceProvider SetupServiceProvider(IServiceCollection services)
|
||||
{
|
||||
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);
|
||||
this.ServiceManager.BuildSingletons();
|
||||
ProjectConfiguration.RegisterViews(this.ServiceManager.GetService<IViewManager>());
|
||||
ProjectConfiguration.RegisterPostUpdateActions(this.ServiceManager.GetService<IPostUpdateActionProducer>());
|
||||
ProjectConfiguration.RegisterServices(services);
|
||||
}
|
||||
protected override bool HandleException(Exception e)
|
||||
{
|
||||
@@ -94,7 +95,10 @@ namespace Daybreak.Launch
|
||||
}
|
||||
protected override void ApplicationStarting()
|
||||
{
|
||||
this.logger = this.ServiceManager.GetService<ILogger<Launcher>>();
|
||||
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()
|
||||
@@ -103,8 +107,8 @@ namespace Daybreak.Launch
|
||||
|
||||
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()
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
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:webview="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
|
||||
xmlns:local="clr-namespace:Daybreak.Launch"
|
||||
xmlns:wcl="clr-namespace:WCL;assembly=WCL"
|
||||
mc:Ignorable="d"
|
||||
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"
|
||||
@@ -25,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>
|
||||
@@ -63,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}"
|
||||
@@ -100,9 +110,35 @@
|
||||
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"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Services.Bloogum;
|
||||
using Daybreak.Services.IconRetrieve;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Services.Privilege;
|
||||
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;
|
||||
@@ -14,10 +14,13 @@ 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
|
||||
@@ -44,6 +47,8 @@ namespace Daybreak.Launch
|
||||
private string currentVersionText;
|
||||
[GenerateDependencyProperty]
|
||||
private bool isRunningAsAdmin;
|
||||
[GenerateDependencyProperty]
|
||||
private bool isShowingDropdown;
|
||||
|
||||
public MainWindow(
|
||||
IViewManager viewManager,
|
||||
@@ -76,6 +81,12 @@ namespace Daybreak.Launch
|
||||
|
||||
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton is not MouseButton.Left &&
|
||||
e.LeftButton is not MouseButtonState.Pressed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.DragMove();
|
||||
}
|
||||
|
||||
@@ -144,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)
|
||||
@@ -187,7 +237,7 @@ namespace Daybreak.Launch
|
||||
}
|
||||
else
|
||||
{
|
||||
this.viewManager.ShowView<MainView>();
|
||||
this.viewManager.ShowView<CompanionView>();
|
||||
this.PeriodicallyCheckForUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,10 +3,10 @@ using Daybreak.Exceptions;
|
||||
using Daybreak.Services.Credentials;
|
||||
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;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
@@ -65,7 +65,7 @@ namespace Daybreak.Services.ApplicationLauncher
|
||||
{
|
||||
if (this.privilegeManager.AdminPrivileges is false)
|
||||
{
|
||||
this.privilegeManager.RequestAdminPrivileges<MainView>("You need administrator rights in order to start using multi-launch");
|
||||
this.privilegeManager.RequestAdminPrivileges<CompanionView>("You need administrator rights in order to start using multi-launch");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,22 @@ namespace Daybreak.Services.BuildTemplates
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Result<BuildEntry, Exception>> GetBuild(string name)
|
||||
{
|
||||
if (File.Exists($"{BuildsPath}/{name}.txt") is false)
|
||||
{
|
||||
return new InvalidOperationException("Unable to find build file");
|
||||
}
|
||||
|
||||
var content = await File.ReadAllTextAsync($"{BuildsPath}/{name}.txt");
|
||||
if (this.TryDecodeTemplate(content, out var build) is false)
|
||||
{
|
||||
return new InvalidOperationException("Unable to parse build file");
|
||||
}
|
||||
|
||||
return new BuildEntry { Build = build, Name = name, PreviousName = name };
|
||||
}
|
||||
|
||||
public void ClearBuilds()
|
||||
{
|
||||
foreach(var file in Directory.GetFiles(BuildsPath))
|
||||
@@ -260,7 +276,7 @@ namespace Daybreak.Services.BuildTemplates
|
||||
buildMetadata.NewTemplate = false;
|
||||
}
|
||||
|
||||
buildMetadata.ProfessionIdLength = stream.Read(2) * 2 + 4;
|
||||
buildMetadata.ProfessionIdLength = (stream.Read(2) * 2) + 4;
|
||||
buildMetadata.PrimaryProfessionId = stream.Read(buildMetadata.ProfessionIdLength);
|
||||
buildMetadata.SecondaryProfessionId = stream.Read(buildMetadata.ProfessionIdLength);
|
||||
buildMetadata.AttributeCount = stream.Read(4);
|
||||
@@ -297,7 +313,7 @@ namespace Daybreak.Services.BuildTemplates
|
||||
|
||||
var desiredProfessionIdLength = GetBitLength(new List<int> { buildMetadata.PrimaryProfessionId, buildMetadata.SecondaryProfessionId }.Max());
|
||||
var professionIdLength = Math.Max((desiredProfessionIdLength - 4) / 2, 0);
|
||||
var finalProfessionIdLength = professionIdLength * 2 + 4;
|
||||
var finalProfessionIdLength = (professionIdLength * 2) + 4;
|
||||
stream.Write(professionIdLength, 2);
|
||||
stream.Write(buildMetadata.PrimaryProfessionId, finalProfessionIdLength);
|
||||
stream.Write(buildMetadata.SecondaryProfessionId, finalProfessionIdLength);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using Daybreak.Models.Builds;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Extensions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Daybreak.Services.BuildTemplates
|
||||
{
|
||||
@@ -12,6 +15,7 @@ namespace Daybreak.Services.BuildTemplates
|
||||
void SaveBuild(BuildEntry buildEntry);
|
||||
void RemoveBuild(BuildEntry buildEntry);
|
||||
IAsyncEnumerable<BuildEntry> GetBuilds();
|
||||
Task<Result<BuildEntry, Exception>> GetBuild(string name);
|
||||
Build DecodeTemplate(string template);
|
||||
bool TryDecodeTemplate(string template, out Build build);
|
||||
string EncodeTemplate(Build build);
|
||||
|
||||
@@ -3,19 +3,19 @@ using Daybreak.Controls;
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using Daybreak.Services.Graph.Models;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Views;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration;
|
||||
using System.Core.Extensions;
|
||||
using System.Extensions;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
@@ -27,8 +27,8 @@ namespace Daybreak.Services.Graph;
|
||||
|
||||
public sealed class GraphClient : IGraphClient
|
||||
{
|
||||
private const string Scopes = "Files.Read Files.Read.All Files.ReadWrite Files.ReadWrite.All User.Read";
|
||||
private const string RedirectUri = "http://localhost";
|
||||
private const string Scopes = "Files.Read Files.Read.All Files.ReadWrite Files.ReadWrite.All User.Read offline_access";
|
||||
private const string RedirectUri = "http://localhost:42111";
|
||||
|
||||
private const string QueryStateKey = "state";
|
||||
private const string QueryCodeKey = "code";
|
||||
@@ -36,17 +36,17 @@ public sealed class GraphClient : IGraphClient
|
||||
private const string RedirectUriPlaceholder = "[RedirectUri]";
|
||||
private const string ScopesPlaceholder = "[Scopes]";
|
||||
private const string StatePlaceholder = "[State]";
|
||||
private const string RefreshTokenPlaceholder = "[RefreshToken]";
|
||||
private const string ProfileEndpoint = "me";
|
||||
private const string GraphBaseUrl = "https://graph.microsoft.com/v1.0/";
|
||||
private const string TokenUrlPlaceholder = $"https://login.microsoftonline.com/consumers/oauth2/v2.0/token";
|
||||
private const string RefreshTokenUrlPlaceholder = $"https://login.microsoftonline.com/consumers/oauth2/v2.0/token?client_id={ClientIdPlaceholder}&refresh_token={RefreshTokenPlaceholder}";
|
||||
private const string AuthorizationUrlPlaceholder = $"https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?client_id={ClientIdPlaceholder}&response_type=code&redirect_uri={RedirectUriPlaceholder}&response_mode=query&scope={ScopesPlaceholder}&state={StatePlaceholder}";
|
||||
private const string SyncFileUri = $"me/drive/root:/Daybreak/{BackupFileName}";
|
||||
private const string SyncFileUri = $"me/drive/root:/Daybreak/Builds/daybreak.json{ContentSuffix}";
|
||||
private const string ContentSuffix = ":/content";
|
||||
private const string BackupFileName = "daybreak_backup.json";
|
||||
|
||||
private static readonly byte[] Entropy = Convert.FromBase64String("R3VpbGR3YXJz");
|
||||
private static readonly string ApplicationId = SecretManager.GetSecret(SecretKeys.AadApplicationId);
|
||||
private static readonly string TenantId = SecretManager.GetSecret(SecretKeys.AadTenantId);
|
||||
|
||||
private readonly IBuildTemplateManager buildTemplateManager;
|
||||
private readonly IViewManager viewManager;
|
||||
@@ -54,6 +54,8 @@ public sealed class GraphClient : IGraphClient
|
||||
private readonly IHttpClient<GraphClient> httpClient;
|
||||
private readonly ILogger<GraphClient> logger;
|
||||
|
||||
private List<BuildFile> buildsCache;
|
||||
|
||||
public GraphClient(
|
||||
IBuildTemplateManager buildTemplateManager,
|
||||
IViewManager viewManager,
|
||||
@@ -75,7 +77,7 @@ public sealed class GraphClient : IGraphClient
|
||||
ChromiumBrowserWrapper chromiumBrowserWrapper,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var maybeAuthCode = await this.RetrieveAuthorizationCode(chromiumBrowserWrapper, cancellationToken);
|
||||
var maybeAuthCode = await RetrieveAuthorizationCode(chromiumBrowserWrapper, cancellationToken);
|
||||
if (maybeAuthCode.TryExtractSuccess(out var authCode) is false)
|
||||
{
|
||||
return maybeAuthCode.SwitchAny(onFailure: exception => exception);
|
||||
@@ -86,13 +88,22 @@ public sealed class GraphClient : IGraphClient
|
||||
return maybeAccessToken.Switch(
|
||||
onSuccess: token =>
|
||||
{
|
||||
var accessToken = AccessToken.FromTokenResponse(token);
|
||||
this.SaveAccessToken(accessToken);
|
||||
this.SaveTokenResponse(token);
|
||||
return true;
|
||||
},
|
||||
onFailure: exception => exception);
|
||||
}
|
||||
|
||||
public Task<Result<bool, Exception>> LogOut()
|
||||
{
|
||||
this.ResetAccessToken();
|
||||
this.ResetRefreshToken();
|
||||
this.ResetAuthorization();
|
||||
|
||||
//TODO: Currently revoking only one refresh token is not supported. Follow up when MS Graph implements refresh token revocation.
|
||||
return Task.FromResult(Result<bool, Exception>.Success(true));
|
||||
}
|
||||
|
||||
public async Task<Result<User, Exception>> GetUserProfile<TViewType>()
|
||||
where TViewType : UserControl
|
||||
{
|
||||
@@ -105,8 +116,15 @@ public sealed class GraphClient : IGraphClient
|
||||
|
||||
if (DateTime.Now > accessToken.ExpirationDate)
|
||||
{
|
||||
this.viewManager.ShowView<GraphAuthorizationView>(new ViewRedirectContext { CallingView = typeof(TViewType) });
|
||||
return new InvalidOperationException("Client authorization expired");
|
||||
var maybeToken = await this.RefreshAccessToken();
|
||||
if (maybeToken.ExtractValue() is not TokenResponse tokenResponse)
|
||||
{
|
||||
this.viewManager.ShowView<GraphAuthorizationView>(new ViewRedirectContext { CallingView = typeof(TViewType) });
|
||||
return new InvalidOperationException("Client authorization expired");
|
||||
}
|
||||
|
||||
(var newAccessToken, _) = this.SaveTokenResponse(tokenResponse);
|
||||
accessToken = newAccessToken;
|
||||
}
|
||||
|
||||
this.httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Token);
|
||||
@@ -130,22 +148,27 @@ public sealed class GraphClient : IGraphClient
|
||||
|
||||
public async Task<Result<bool, Exception>> UploadBuilds()
|
||||
{
|
||||
var compiledBuilds = await this.buildTemplateManager.GetBuilds().Select(b => new BuildFile { FileName = b.Name, TemplateCode = this.buildTemplateManager.EncodeTemplate(b.Build) }).ToListAsync();
|
||||
var serializedBuilds = JsonConvert.SerializeObject(compiledBuilds);
|
||||
await this.UploadBackupItem(serializedBuilds);
|
||||
return true;
|
||||
var builds = await this.buildTemplateManager.GetBuilds().ToListAsync();
|
||||
return await this.PutBuilds(builds);
|
||||
}
|
||||
|
||||
public async Task<Result<bool, Exception>> DownloadBuilds()
|
||||
{
|
||||
var maybeBuilds = await this.RetrieveBuildsList();
|
||||
if (maybeBuilds.TryExtractSuccess(out var builds) is false)
|
||||
var retrieveBuildsResponse = await this.RetrieveBuildsList();
|
||||
if (retrieveBuildsResponse.TryExtractFailure(out var failure))
|
||||
{
|
||||
return maybeBuilds.SwitchAny(onFailure: exception => exception);
|
||||
this.logger.LogError(failure, "Unable to download builds");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (retrieveBuildsResponse.TryExtractSuccess(out var builds) is false)
|
||||
{
|
||||
this.logger.LogError("Unexpected error occured");
|
||||
return false;
|
||||
}
|
||||
|
||||
this.buildTemplateManager.ClearBuilds();
|
||||
_ = builds.Select(buildFile =>
|
||||
var compiledBuilds = this.buildsCache.Select(buildFile =>
|
||||
{
|
||||
if (this.buildTemplateManager.TryDecodeTemplate(buildFile.TemplateCode, out var build) is false)
|
||||
{
|
||||
@@ -158,82 +181,171 @@ public sealed class GraphClient : IGraphClient
|
||||
Name = buildFile.FileName,
|
||||
PreviousName = buildFile.FileName
|
||||
};
|
||||
}).Where(entry => entry is not null)
|
||||
.Do(this.buildTemplateManager.SaveBuild).ToList();
|
||||
}).Where(entry => entry is not null).ToList();
|
||||
_ = compiledBuilds.Do(this.buildTemplateManager.SaveBuild).ToList();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<Result<List<BuildFile>, Exception>> RetrieveBuildsList()
|
||||
public async Task<Result<bool, Exception>> DownloadBuild(string buildName)
|
||||
{
|
||||
var maybeCompiledBuilds = await this.GetBackupItemContent();
|
||||
if (maybeCompiledBuilds.ExtractValue() is not string compiledBuilds)
|
||||
var retrieveBuildsResponse = await this.RetrieveBuildsList();
|
||||
if (retrieveBuildsResponse.TryExtractFailure(out var failure))
|
||||
{
|
||||
return new InvalidOperationException("No backup found");
|
||||
this.logger.LogError(failure, "Unable to download builds");
|
||||
return false;
|
||||
}
|
||||
|
||||
var builds = JsonConvert.DeserializeObject<List<BuildFile>>(compiledBuilds);
|
||||
return builds;
|
||||
if (retrieveBuildsResponse.TryExtractSuccess(out var builds) is false)
|
||||
{
|
||||
this.logger.LogError("Unexpected error occured");
|
||||
return false;
|
||||
}
|
||||
|
||||
var compiledBuilds = this.buildsCache
|
||||
.Where(b => b.FileName == buildName)
|
||||
.Select(buildFile =>
|
||||
{
|
||||
if (this.buildTemplateManager.TryDecodeTemplate(buildFile.TemplateCode, out var build) is false)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new BuildEntry
|
||||
{
|
||||
Build = build,
|
||||
Name = buildFile.FileName,
|
||||
PreviousName = buildFile.FileName
|
||||
};
|
||||
}).Where(entry => entry is not null).ToList();
|
||||
_ = compiledBuilds.Do(this.buildTemplateManager.SaveBuild).ToList();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<Result<DateTime, Exception>> GetLastUpdateTime()
|
||||
public async Task<Result<bool, Exception>> UploadBuild(string buildName)
|
||||
{
|
||||
var maybeDriveItem = await this.GetDriveItem();
|
||||
if (maybeDriveItem.ExtractValue() is not DriveItem driveItem)
|
||||
var getBuildResult = await this.buildTemplateManager.GetBuild(buildName);
|
||||
if (getBuildResult.TryExtractSuccess(out var buildEntry) is false)
|
||||
{
|
||||
return new InvalidOperationException("Unable to retrieve the drive file");
|
||||
return getBuildResult.SwitchAny(
|
||||
onFailure: exception => exception);
|
||||
}
|
||||
|
||||
return driveItem.LastModifiedDateTime;
|
||||
return await this.PutBuild(buildEntry);
|
||||
}
|
||||
|
||||
public async Task<Result<IEnumerable<BuildFile>, Exception>> RetrieveBuildsList()
|
||||
{
|
||||
var maybeBuildsBackup = await this.GetBuildsBackup();
|
||||
var buildsBackup = maybeBuildsBackup.ExtractValue();
|
||||
this.buildsCache = buildsBackup;
|
||||
return buildsBackup;
|
||||
}
|
||||
|
||||
public void ResetAuthorization()
|
||||
{
|
||||
this.ResetAccessToken();
|
||||
this.ResetRefreshToken();
|
||||
}
|
||||
|
||||
private async Task<Optional<string>> GetBackupItemContent()
|
||||
private async Task<Optional<TokenResponse>> RefreshAccessToken()
|
||||
{
|
||||
var maybeDriveItem = await this.GetDriveItem();
|
||||
if (maybeDriveItem.ExtractValue() is not DriveItem driveItem)
|
||||
var maybeRefreshToken = this.LoadRefreshToken();
|
||||
if (maybeRefreshToken.ExtractValue() is not RefreshToken refreshToken)
|
||||
{
|
||||
return Optional.None<string>();
|
||||
return Optional.None<TokenResponse>();
|
||||
}
|
||||
|
||||
if (driveItem.Name != BackupFileName)
|
||||
using var httpContent = new FormUrlEncodedContent(new Dictionary<string, string>
|
||||
{
|
||||
return Optional.None<string>();
|
||||
}
|
||||
|
||||
var response = await this.httpClient.GetAsync(driveItem.DownloadUrl);
|
||||
{ "client_id", ApplicationId },
|
||||
{ "refresh_token", refreshToken.Token },
|
||||
{ "grant_type", "refresh_token" }
|
||||
});
|
||||
using var response = await this.httpClient.PostAsync(TokenUrlPlaceholder, httpContent);
|
||||
if (response.IsSuccessStatusCode is false)
|
||||
{
|
||||
return Optional.None<string>();
|
||||
return Optional.None<TokenResponse>();
|
||||
}
|
||||
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
return JsonConvert.DeserializeObject<TokenResponse>(await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
private async Task<bool> UploadBackupItem(string serializedBuilds)
|
||||
private async Task<bool> PutBuild(BuildEntry buildEntry)
|
||||
{
|
||||
using var stringContent = new StringContent(serializedBuilds);
|
||||
var response = await this.httpClient.PutAsync(SyncFileUri + ContentSuffix, stringContent);
|
||||
return response.IsSuccessStatusCode;
|
||||
}
|
||||
if (this.buildsCache is null)
|
||||
{
|
||||
_ = await this.RetrieveBuildsList();
|
||||
}
|
||||
|
||||
private async Task<Optional<DriveItem>> GetDriveItem()
|
||||
{
|
||||
var response = await this.httpClient.GetAsync(SyncFileUri);
|
||||
var buildFile = new BuildFile
|
||||
{
|
||||
FileName = buildEntry.Name,
|
||||
TemplateCode = this.buildTemplateManager.EncodeTemplate(buildEntry.Build)
|
||||
};
|
||||
|
||||
var buildList = this.buildsCache ?? new List<BuildFile>();
|
||||
// Remove the previous version of the build
|
||||
buildList = buildList.Where(b => b.FileName != buildEntry.Name).ToList();
|
||||
// Add new version of the build
|
||||
buildList.Add(buildFile);
|
||||
// Order by name
|
||||
buildList = buildList.OrderBy(b => b.FileName).ToList();
|
||||
|
||||
using var stringContent = new StringContent(JsonConvert.SerializeObject(buildList));
|
||||
var response = await this.httpClient.PutAsync(SyncFileUri, stringContent);
|
||||
if (response.IsSuccessStatusCode is false)
|
||||
{
|
||||
return Optional.None<DriveItem>();
|
||||
return false;
|
||||
}
|
||||
|
||||
var driveItemContent = await response.Content.ReadAsStringAsync();
|
||||
return JsonConvert.DeserializeObject<DriveItem>(driveItemContent);
|
||||
this.buildsCache = buildList;
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<Result<string, Exception>> RetrieveAuthorizationCode(
|
||||
private async Task<bool> PutBuilds(List<BuildEntry> buildEntries)
|
||||
{
|
||||
var buildFiles = buildEntries.Select(buildEntry => new BuildFile
|
||||
{
|
||||
FileName = buildEntry.Name,
|
||||
TemplateCode = this.buildTemplateManager.EncodeTemplate(buildEntry.Build)
|
||||
});
|
||||
|
||||
var buildList = new List<BuildFile>();
|
||||
buildList.AddRange(buildFiles);
|
||||
buildList = buildList.OrderBy(b => b.FileName).ToList();
|
||||
|
||||
using var stringContent = new StringContent(JsonConvert.SerializeObject(buildList));
|
||||
var response = await this.httpClient.PutAsync(SyncFileUri, stringContent);
|
||||
if (response.IsSuccessStatusCode is false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this.buildsCache = buildList;
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<Optional<List<BuildFile>>> GetBuildsBackup()
|
||||
{
|
||||
var fileItemResponse = await this.httpClient.GetAsync(SyncFileUri);
|
||||
if (fileItemResponse.IsSuccessStatusCode is false)
|
||||
{
|
||||
return Optional.None<List<BuildFile>>();
|
||||
}
|
||||
|
||||
var driveItemContent = await fileItemResponse.Content.ReadAsStringAsync();
|
||||
var backup = JsonConvert.DeserializeObject<List<BuildFile>>(driveItemContent);
|
||||
if (backup is null)
|
||||
{
|
||||
return Optional.None<List<BuildFile>>();
|
||||
}
|
||||
|
||||
return backup;
|
||||
}
|
||||
|
||||
private static async Task<Result<string, Exception>> RetrieveAuthorizationCode(
|
||||
ChromiumBrowserWrapper chromiumBrowserWrapper,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -251,18 +363,29 @@ public sealed class GraphClient : IGraphClient
|
||||
.Replace(' ', '+'))
|
||||
.Replace(StatePlaceholder, state);
|
||||
|
||||
while (chromiumBrowserWrapper.Address.StartsWith(RedirectUri) is false)
|
||||
NameValueCollection query = null;
|
||||
bool finished = false;
|
||||
chromiumBrowserWrapper.WebBrowser.CoreWebView2.SourceChanged += (_, sourceArgs) =>
|
||||
{
|
||||
if (chromiumBrowserWrapper.Address.StartsWith(RedirectUri))
|
||||
{
|
||||
query = HttpUtility.ParseQueryString(chromiumBrowserWrapper.Address.Split('?').Skip(1).FirstOrDefault());
|
||||
finished = true;
|
||||
chromiumBrowserWrapper.WebBrowser.CoreWebView2.NavigateToString(string.Empty);
|
||||
}
|
||||
};
|
||||
|
||||
while (finished is false)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return new TaskCanceledException();
|
||||
}
|
||||
|
||||
await Task.Delay(1000).ConfigureAwait(true);
|
||||
await Task.Delay(1000, cancellationToken).ConfigureAwait(true);
|
||||
}
|
||||
|
||||
var query = HttpUtility.ParseQueryString(chromiumBrowserWrapper.Address.Split('?').Skip(1).FirstOrDefault());
|
||||
if (query.GetValues(QueryStateKey) is string[] states is false)
|
||||
if (query?.GetValues(QueryStateKey) is string[] states is false)
|
||||
{
|
||||
throw new InvalidOperationException("Response doesn't have state key in response");
|
||||
}
|
||||
@@ -319,6 +442,16 @@ public sealed class GraphClient : IGraphClient
|
||||
return JsonConvert.DeserializeObject<TokenResponse>(await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
private (AccessToken, RefreshToken) SaveTokenResponse(TokenResponse token)
|
||||
{
|
||||
var accessToken = AccessToken.FromTokenResponse(token);
|
||||
var refreshToken = RefreshToken.FromTokenResponse(token);
|
||||
this.SaveAccessToken(accessToken);
|
||||
this.SaveRefreshToken(refreshToken);
|
||||
|
||||
return (accessToken, refreshToken);
|
||||
}
|
||||
|
||||
private void ResetAccessToken()
|
||||
{
|
||||
this.liveUpdateableOptions.Value.ProtectedGraphAccessToken = null;
|
||||
@@ -332,6 +465,19 @@ public sealed class GraphClient : IGraphClient
|
||||
this.liveUpdateableOptions.UpdateOption();
|
||||
}
|
||||
|
||||
private void SaveRefreshToken(RefreshToken refreshToken)
|
||||
{
|
||||
var codeBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(refreshToken));
|
||||
this.liveUpdateableOptions.Value.ProtectedGraphRefreshToken = Convert.ToBase64String(ProtectedData.Protect(codeBytes, Entropy, DataProtectionScope.CurrentUser));
|
||||
this.liveUpdateableOptions.UpdateOption();
|
||||
}
|
||||
|
||||
private void ResetRefreshToken()
|
||||
{
|
||||
this.liveUpdateableOptions.Value.ProtectedGraphRefreshToken = null;
|
||||
this.liveUpdateableOptions.UpdateOption();
|
||||
}
|
||||
|
||||
private Optional<AccessToken> LoadAccessToken()
|
||||
{
|
||||
var protectedCode = this.liveUpdateableOptions.Value.ProtectedGraphAccessToken;
|
||||
@@ -353,6 +499,27 @@ public sealed class GraphClient : IGraphClient
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<RefreshToken> LoadRefreshToken()
|
||||
{
|
||||
var protectedCode = this.liveUpdateableOptions.Value.ProtectedGraphRefreshToken;
|
||||
if (protectedCode.IsNullOrWhiteSpace())
|
||||
{
|
||||
return Optional.None<RefreshToken>();
|
||||
}
|
||||
|
||||
var codeBytes = ProtectedData.Unprotect(Convert.FromBase64String(protectedCode), Entropy, DataProtectionScope.CurrentUser);
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<RefreshToken>(Encoding.UTF8.GetString(codeBytes));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.logger.LogError(e, "Failed to load refresh token. Resetting refresh token");
|
||||
this.ResetAccessToken();
|
||||
return Optional.None<RefreshToken>();
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetNewState()
|
||||
{
|
||||
return Guid.NewGuid().ToString();
|
||||
|
||||
@@ -14,9 +14,11 @@ public interface IGraphClient
|
||||
Task<Result<User, Exception>> GetUserProfile<TViewType>()
|
||||
where TViewType : UserControl;
|
||||
Task<Result<bool, Exception>> PerformAuthorizationFlow(ChromiumBrowserWrapper chromiumBrowserWrapper, CancellationToken cancellationToken = default);
|
||||
Task<Result<bool, Exception>> LogOut();
|
||||
Task<Result<bool, Exception>> UploadBuilds();
|
||||
Task<Result<bool, Exception>> DownloadBuilds();
|
||||
Task<Result<List<BuildFile>, Exception>> RetrieveBuildsList();
|
||||
Task<Result<DateTime, Exception>> GetLastUpdateTime();
|
||||
Task<Result<bool, Exception>> UploadBuild(string buildName);
|
||||
Task<Result<bool, Exception>> DownloadBuild(string buildName);
|
||||
Task<Result<IEnumerable<BuildFile>, Exception>> RetrieveBuildsList();
|
||||
void ResetAuthorization();
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ using System;
|
||||
|
||||
namespace Daybreak.Services.Graph.Models;
|
||||
|
||||
public sealed class DriveItem
|
||||
public sealed class FileItem
|
||||
{
|
||||
[JsonProperty("@microsoft.graph.downloadUrl")]
|
||||
public string DownloadUrl { get; set; }
|
||||
@@ -0,0 +1,10 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Daybreak.Services.Graph.Models;
|
||||
|
||||
public sealed class FolderItem
|
||||
{
|
||||
[JsonProperty("value")]
|
||||
public List<FileItem> Files { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Daybreak.Services.Graph.Models;
|
||||
|
||||
public sealed class RefreshToken
|
||||
{
|
||||
public string Token { get; set; }
|
||||
|
||||
public static RefreshToken FromTokenResponse(TokenResponse tokenResponse)
|
||||
{
|
||||
return new RefreshToken
|
||||
{
|
||||
Token = tokenResponse.RefreshToken,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Pepa.Wpf.Utilities;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Services.KeyboardHook;
|
||||
using Pepa.Wpf.Utilities;
|
||||
using Daybreak.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Pepa.Wpf.Utilities;
|
||||
using Daybreak.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Services.ViewManagement
|
||||
namespace Daybreak.Services.Navigation
|
||||
{
|
||||
public interface IViewManager : IViewProducer
|
||||
{
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Services.ViewManagement
|
||||
namespace Daybreak.Services.Navigation
|
||||
{
|
||||
public interface IViewProducer
|
||||
{
|
||||
void RegisterView<T>()
|
||||
where T : UserControl;
|
||||
void RegisterPermanentView<T>()
|
||||
where T : UserControl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
using Daybreak.Models;
|
||||
using Microsoft.CorrelationVector;
|
||||
using Slim;
|
||||
using Slim;
|
||||
using System;
|
||||
using System.Extensions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Services.ViewManagement
|
||||
namespace Daybreak.Services.Navigation
|
||||
{
|
||||
public sealed class ViewManager : IViewManager
|
||||
{
|
||||
@@ -28,11 +26,18 @@ namespace Daybreak.Services.ViewManagement
|
||||
this.container = panel;
|
||||
}
|
||||
|
||||
public void RegisterView<T>() where T : UserControl
|
||||
public void RegisterView<T>()
|
||||
where T : UserControl
|
||||
{
|
||||
this.serviceManager.RegisterTransient<T, T>();
|
||||
}
|
||||
|
||||
public void RegisterPermanentView<T>()
|
||||
where T : UserControl
|
||||
{
|
||||
this.serviceManager.RegisterSingleton<T, T>();
|
||||
}
|
||||
|
||||
public void ShowView<T>() where T : UserControl
|
||||
{
|
||||
this.ShowViewInner(typeof(T), null);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Views;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Extensions;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Pepa.Wpf.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
using Daybreak.Exceptions;
|
||||
using Daybreak.Models.Github;
|
||||
using Daybreak.Models.Progress;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Services.Updater.PostUpdate;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Views;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Win32;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Daybreak
|
||||
namespace Daybreak.Utils
|
||||
{
|
||||
internal static class EncryptionHelper
|
||||
{
|
||||
|
||||
@@ -3,9 +3,9 @@ using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using System.Text;
|
||||
|
||||
namespace Pepa.Wpf.Utilities
|
||||
namespace Daybreak.Utils
|
||||
{
|
||||
static class NativeMethods
|
||||
internal static class NativeMethods
|
||||
{
|
||||
public static uint WM_KEYDOWN = 0x0100;
|
||||
public static uint SWP_SHOWWINDOW = 0x0040;
|
||||
@@ -134,4 +134,4 @@ namespace Pepa.Wpf.Utilities
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetForegroundWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Utils
|
||||
namespace Daybreak.Utils
|
||||
{
|
||||
public static class StringUtils
|
||||
{
|
||||
@@ -18,7 +18,7 @@ namespace Utils
|
||||
{
|
||||
for (var i = 1; i < width; i++)
|
||||
{
|
||||
var cost = (s[j - 1] == t[i - 1]) ? 0 : 1;
|
||||
var cost = s[j - 1] == t[i - 1] ? 0 : 1;
|
||||
var insertion = matrix[j, i - 1] + 1;
|
||||
var deletion = matrix[j - 1, i] + 1;
|
||||
var substitution = matrix[j - 1, i - 1] + cost;
|
||||
|
||||
@@ -10,13 +10,12 @@
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid Background="#A0202020">
|
||||
<TextBlock HorizontalAlignment="Center" Text="Accounts settings" FontSize="22" Foreground="White"></TextBlock>
|
||||
<controls:BackButton Foreground="White" Height="30" Width="30" Grid.Column="0" HorizontalAlignment="Left" Margin="5"
|
||||
Clicked="BackButton_Clicked" VerticalAlignment="Top"></controls:BackButton>
|
||||
<controls:AddButton Foreground="White" Height="30" Width="30" Grid.Column="0" HorizontalAlignment="Right" Margin="5, 5, 45, 5"
|
||||
Clicked="AddButton_Clicked" VerticalAlignment="Top"></controls:AddButton>
|
||||
<controls:SaveButton Foreground="White" Height="30" Width="30" Grid.Column="0" HorizontalAlignment="Right" Margin="5"
|
||||
Clicked="SaveButton_Clicked" VerticalAlignment="Top"></controls:SaveButton>
|
||||
<ListView ItemsSource="{Binding ElementName=_this, Path=Accounts, Mode=OneWay}" Background="Transparent" Margin="0, 40, 0, 0">
|
||||
<ListView ItemsSource="{Binding ElementName=_this, Path=Accounts, Mode=OneWay}" Background="Transparent" Margin="0, 40, 0, 0"
|
||||
BorderThickness="0">
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Daybreak.Controls;
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Services.Credentials;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Extensions;
|
||||
@@ -17,16 +16,13 @@ namespace Daybreak.Views
|
||||
public partial class AccountsView : UserControl
|
||||
{
|
||||
private readonly ICredentialManager credentialManager;
|
||||
private readonly IViewManager viewManager;
|
||||
|
||||
public ObservableCollection<LoginCredentials> Accounts { get; } = new();
|
||||
|
||||
public AccountsView(
|
||||
ICredentialManager credentialManager,
|
||||
IViewManager viewManager)
|
||||
ICredentialManager credentialManager)
|
||||
{
|
||||
this.credentialManager = credentialManager.ThrowIfNull(nameof(credentialManager));
|
||||
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
|
||||
this.InitializeComponent();
|
||||
this.GetCredentials();
|
||||
}
|
||||
@@ -37,11 +33,6 @@ namespace Daybreak.Views
|
||||
this.Accounts.AddRange(creds);
|
||||
}
|
||||
|
||||
private void BackButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<SettingsCategoryView>();
|
||||
}
|
||||
|
||||
private void AddButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var newCredentials = new LoginCredentials();
|
||||
@@ -55,7 +46,6 @@ namespace Daybreak.Views
|
||||
private async void SaveButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
await this.credentialManager.StoreCredentials(this.Accounts.ToList()).ConfigureAwait(true);
|
||||
this.viewManager.ShowView<SettingsCategoryView>();
|
||||
}
|
||||
|
||||
private void AccountTemplate_RemoveClicked(object sender, EventArgs e)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Services.Privilege;
|
||||
using Daybreak.Services.Updater;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Configuration;
|
||||
using System.Extensions;
|
||||
@@ -41,7 +41,7 @@ namespace Daybreak.Views
|
||||
this.logger.LogInformation("User declined update");
|
||||
this.liveOptions.Value.AutoCheckUpdate = false;
|
||||
this.liveOptions.UpdateOption();
|
||||
this.viewManager.ShowView<MainView>();
|
||||
this.viewManager.ShowView<CompanionView>();
|
||||
}
|
||||
|
||||
private async void YesButton_Clicked(object sender, System.EventArgs e)
|
||||
|
||||
@@ -3,7 +3,7 @@ using Daybreak.Controls;
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using Daybreak.Services.IconRetrieve;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<controls:BackButton Foreground="White" Height="30" Width="30" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5"
|
||||
Clicked="BackButton_Clicked"></controls:BackButton>
|
||||
<controls:AddButton Foreground="White" Height="30" Width="30" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="5"
|
||||
Clicked="AddButton_Clicked"></controls:AddButton>
|
||||
<controls:SynchronizeButton Foreground="White" Height="30" Width="30" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="5, 5, 45, 5"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Extensions;
|
||||
using System.Linq;
|
||||
using System.Windows.Controls;
|
||||
using Utils;
|
||||
|
||||
namespace Daybreak.Views
|
||||
{
|
||||
@@ -44,11 +44,6 @@ namespace Daybreak.Views
|
||||
this.viewManager.ShowView<BuildTemplateView>(sender.As<ListView>().SelectedItem);
|
||||
}
|
||||
|
||||
private void BackButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<SettingsCategoryView>();
|
||||
}
|
||||
|
||||
private void AddButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var build = this.buildTemplateManager.CreateBuild();
|
||||
|
||||
@@ -5,14 +5,19 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Daybreak.Views"
|
||||
xmlns:controls="clr-namespace:Daybreak.Controls"
|
||||
xmlns:glyps="clr-namespace:Daybreak.Controls.Glyphs"
|
||||
xmlns:converters="clr-namespace:Daybreak.Converters"
|
||||
Loaded="UserControl_Loaded"
|
||||
mc:Ignorable="d"
|
||||
x:Name="_this"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" TriggerValue="False"></converters:BooleanToVisibilityConverter>
|
||||
<converters:BooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter" TriggerValue="True"></converters:BooleanToVisibilityConverter>
|
||||
</UserControl.Resources>
|
||||
<Grid
|
||||
Background="#A0202020">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
@@ -20,24 +25,32 @@
|
||||
<controls:BackButton Foreground="White" Height="30" Width="30" Grid.Column="0" HorizontalAlignment="Left" Margin="5"
|
||||
Clicked="BackButton_Clicked" VerticalAlignment="Top"
|
||||
IsEnabled="{Binding ElementName=_this, Path=ButtonsEnabled, Mode=OneWay}"></controls:BackButton>
|
||||
<controls:BackButton Foreground="White" Height="30" Width="30" HorizontalAlignment="Right" Margin="0, 5, 45, 5"
|
||||
Clicked="DownloadButton_Clicked"
|
||||
IsEnabled="{Binding ElementName=_this, Path=ButtonsEnabled, Mode=OneWay}">
|
||||
<controls:BackButton.RenderTransform>
|
||||
<RotateTransform Angle="270" CenterX="15" CenterY="15"></RotateTransform>
|
||||
</controls:BackButton.RenderTransform>
|
||||
</controls:BackButton>
|
||||
<controls:BackButton Foreground="White" Height="30" Width="30" HorizontalAlignment="Right" Margin="0, 5, 5, 5"
|
||||
Clicked="UploadButton_Clicked"
|
||||
IsEnabled="{Binding ElementName=_this, Path=ButtonsEnabled, Mode=OneWay}">
|
||||
<controls:BackButton.RenderTransform>
|
||||
<RotateTransform Angle="90" CenterX="15" CenterY="15"></RotateTransform>
|
||||
</controls:BackButton.RenderTransform>
|
||||
</controls:BackButton>
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
<controls:OpaqueButton Text="Log Out"
|
||||
Foreground="White"
|
||||
Background="DarkGray"
|
||||
HorizontalAlignment="Right"
|
||||
Padding="5"
|
||||
Margin="5"
|
||||
Clicked="LogOutButton_Clicked"
|
||||
Width="80"
|
||||
IsEnabled="{Binding ElementName=_this, Path=ButtonsEnabled, Mode=OneWay}"/>
|
||||
<WrapPanel HorizontalAlignment="Center">
|
||||
<TextBlock
|
||||
Text="Build templates synchronization"
|
||||
FontSize="24"
|
||||
Foreground="White" />
|
||||
<Grid Margin="5"
|
||||
VerticalAlignment="Center">
|
||||
<glyps:GoodGlyph Foreground="LimeGreen"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Visibility="{Binding ElementName=_this, Path=Synchronized, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
||||
<glyps:BadGlyph Foreground="OrangeRed"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Visibility="{Binding ElementName=_this, Path=Synchronized, Mode=OneWay, Converter={StaticResource InverseBooleanToVisibilityConverter}}"/>
|
||||
</Grid>
|
||||
</WrapPanel>
|
||||
<WrapPanel HorizontalAlignment="Center"
|
||||
Grid.Row="1">
|
||||
<TextBlock Text="Logged in as: "
|
||||
@@ -47,32 +60,45 @@
|
||||
FontSize="20"
|
||||
Foreground="White"></TextBlock>
|
||||
</WrapPanel>
|
||||
<WrapPanel HorizontalAlignment="Center"
|
||||
Grid.Row="2">
|
||||
<TextBlock Text="Last uploaded: "
|
||||
Foreground="White"
|
||||
FontSize="18"/>
|
||||
<TextBlock Text="{Binding ElementName=_this, Path=LastUploadDate, Mode=OneWay}"
|
||||
Foreground="White"
|
||||
FontSize="20"/>
|
||||
</WrapPanel>
|
||||
<Grid Grid.Row="3">
|
||||
<Grid Grid.Row="2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Text="Preview uploaded templates"
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="Local"
|
||||
FontSize="14"
|
||||
Foreground="White"
|
||||
HorizontalAlignment="Center"/>
|
||||
<ListView Grid.Row="1" Background="Transparent" ItemsSource="{Binding ElementName=_this, Path=BuildEntries, Mode=OneWay}"
|
||||
HorizontalContentAlignment="Stretch">
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
<controls:OpaqueButton Grid.Column="0"
|
||||
Text="Upload all"
|
||||
Foreground="White"
|
||||
Background="DarkGray"
|
||||
HorizontalAlignment="Right"
|
||||
Padding="5"
|
||||
Margin="5"
|
||||
Clicked="UploadAllButton_Clicked"
|
||||
Width="80"
|
||||
IsEnabled="{Binding ElementName=_this, Path=ButtonsEnabled, Mode=OneWay}"/>
|
||||
<ListView
|
||||
Grid.Column="0"
|
||||
Grid.Row="1"
|
||||
Background="Transparent"
|
||||
ItemsSource="{Binding ElementName=_this, Path=LocalBuildEntries, Mode=OneWay}"
|
||||
SelectedItem="{Binding ElementName=_this, Path=SelectedLocalBuild, Mode=TwoWay}"
|
||||
HorizontalContentAlignment="Stretch">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<TextBlock FontSize="14"
|
||||
Foreground="White"
|
||||
Text="{Binding FileName}"
|
||||
Text="{Binding Build.Name}"
|
||||
HorizontalAlignment="Left"></TextBlock>
|
||||
<TextBlock FontSize="14"
|
||||
Foreground="White"
|
||||
@@ -82,6 +108,69 @@
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
<TextBlock Grid.Column="2"
|
||||
Text="Remote"
|
||||
FontSize="14"
|
||||
Foreground="White"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
<controls:OpaqueButton Grid.Column="2"
|
||||
Text="Download all"
|
||||
Foreground="White"
|
||||
Background="DarkGray"
|
||||
HorizontalAlignment="Left"
|
||||
Padding="5"
|
||||
Margin="5"
|
||||
Clicked="DownloadAllButton_Clicked"
|
||||
Width="80"
|
||||
IsEnabled="{Binding ElementName=_this, Path=ButtonsEnabled, Mode=OneWay}"/>
|
||||
<ListView
|
||||
Grid.Column="2"
|
||||
Grid.Row="1"
|
||||
Background="Transparent"
|
||||
ItemsSource="{Binding ElementName=_this, Path=RemoteBuildEntries, Mode=OneWay}"
|
||||
SelectedItem="{Binding ElementName=_this, Path=SelectedRemoteBuild, Mode=TwoWay}"
|
||||
HorizontalContentAlignment="Stretch">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<TextBlock FontSize="14"
|
||||
Foreground="White"
|
||||
Text="{Binding TemplateCode}"
|
||||
HorizontalAlignment="Left"></TextBlock>
|
||||
<TextBlock FontSize="14"
|
||||
Foreground="White"
|
||||
Text="{Binding FileName}"
|
||||
HorizontalAlignment="Right"></TextBlock>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
<StackPanel Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center">
|
||||
<controls:OpaqueButton Text="Download Build"
|
||||
Foreground="White"
|
||||
Background="DarkGray"
|
||||
Margin="5"
|
||||
Padding="5"
|
||||
Clicked="DownloadButton_Clicked"
|
||||
IsEnabled="{Binding ElementName=_this, Path=ButtonsEnabled, Mode=OneWay}"></controls:OpaqueButton>
|
||||
<controls:OpaqueButton Text="Upload Build"
|
||||
Foreground="White"
|
||||
Background="DarkGray"
|
||||
Margin="5"
|
||||
Padding="5"
|
||||
Clicked="UploadButton_Clicked"
|
||||
IsEnabled="{Binding ElementName=_this, Path=ButtonsEnabled, Mode=OneWay}"></controls:OpaqueButton>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Grid Grid.RowSpan="3"
|
||||
Background="#A0202020"
|
||||
Visibility="{Binding ElementName=_this, Path=ShowLoading, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<controls:CircularLoadingWidget MaxWidth="200"
|
||||
MaxHeight="200"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -4,12 +4,16 @@ using System.Core.Extensions;
|
||||
using System.Windows;
|
||||
using System.Windows.Extensions;
|
||||
using System.Windows.Controls;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using System.Collections.ObjectModel;
|
||||
using Daybreak.Services.Graph.Models;
|
||||
using System.Extensions;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using System.Linq;
|
||||
using Daybreak.Models;
|
||||
using System.Collections.Generic;
|
||||
using Daybreak.Services.Navigation;
|
||||
|
||||
namespace Daybreak.Views;
|
||||
|
||||
@@ -18,11 +22,13 @@ namespace Daybreak.Views;
|
||||
/// </summary>
|
||||
public partial class BuildsSynchronizationView : UserControl
|
||||
{
|
||||
private readonly IBuildTemplateManager buildTemplateManager;
|
||||
private readonly IGraphClient graphClient;
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly ILogger<BuildsSynchronizationView> logger;
|
||||
|
||||
public ObservableCollection<BuildFile> BuildEntries { get; } = new();
|
||||
public ObservableCollection<BuildFile> RemoteBuildEntries { get; } = new();
|
||||
public ObservableCollection<BuildWithTemplateCode> LocalBuildEntries { get; } = new();
|
||||
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool buttonsEnabled;
|
||||
@@ -30,12 +36,22 @@ public partial class BuildsSynchronizationView : UserControl
|
||||
private string displayName;
|
||||
[GenerateDependencyProperty]
|
||||
private string lastUploadDate;
|
||||
[GenerateDependencyProperty]
|
||||
private BuildFile selectedRemoteBuild;
|
||||
[GenerateDependencyProperty]
|
||||
private BuildWithTemplateCode selectedLocalBuild;
|
||||
[GenerateDependencyProperty]
|
||||
private bool showLoading;
|
||||
[GenerateDependencyProperty]
|
||||
private bool synchronized;
|
||||
|
||||
public BuildsSynchronizationView(
|
||||
IBuildTemplateManager buildTemplateManager,
|
||||
IGraphClient graphClient,
|
||||
IViewManager viewManager,
|
||||
ILogger<BuildsSynchronizationView> logger)
|
||||
{
|
||||
this.buildTemplateManager = buildTemplateManager.ThrowIfNull();
|
||||
this.graphClient = graphClient.ThrowIfNull();
|
||||
this.viewManager = viewManager.ThrowIfNull();
|
||||
this.logger = logger.ThrowIfNull();
|
||||
@@ -45,6 +61,7 @@ public partial class BuildsSynchronizationView : UserControl
|
||||
private async void UserControl_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.ButtonsEnabled = false;
|
||||
this.ShowLoading = true;
|
||||
var profile = await this.graphClient.GetUserProfile<BuildsSynchronizationView>();
|
||||
if (profile.TryExtractSuccess(out var user) is false)
|
||||
{
|
||||
@@ -53,30 +70,32 @@ public partial class BuildsSynchronizationView : UserControl
|
||||
}
|
||||
|
||||
this.DisplayName = user.DisplayName;
|
||||
await this.PopulateLastUpdateTime();
|
||||
await this.PopulateBuilds();
|
||||
this.ButtonsEnabled = true;
|
||||
}
|
||||
|
||||
private async Task PopulateLastUpdateTime()
|
||||
{
|
||||
var maybeDateTime = await this.graphClient.GetLastUpdateTime();
|
||||
if (maybeDateTime.TryExtractSuccess(out var dateTime))
|
||||
{
|
||||
this.LastUploadDate = dateTime.ToString("G");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.LastUploadDate = "Never";
|
||||
}
|
||||
this.ShowLoading = false;
|
||||
}
|
||||
|
||||
private async Task PopulateBuilds()
|
||||
{
|
||||
var maybeBuilds = await this.graphClient.RetrieveBuildsList();
|
||||
if (maybeBuilds.TryExtractSuccess(out var builds))
|
||||
var getBuildsResponse = await this.graphClient.RetrieveBuildsList();
|
||||
if (getBuildsResponse.TryExtractSuccess(out var builds) is false)
|
||||
{
|
||||
this.BuildEntries.ClearAnd().AddRange(builds);
|
||||
builds = new List<BuildFile>();
|
||||
}
|
||||
|
||||
this.RemoteBuildEntries.ClearAnd().AddRange(builds);
|
||||
var localBuilds = await this.buildTemplateManager.GetBuilds().ToListAsync();
|
||||
this.LocalBuildEntries.ClearAnd().AddRange(localBuilds.Select(build => new BuildWithTemplateCode { Build = build, TemplateCode = this.buildTemplateManager.EncodeTemplate(build.Build) }));
|
||||
|
||||
if (this.LocalBuildEntries.Count == this.RemoteBuildEntries.Count &&
|
||||
this.LocalBuildEntries.Select(b => b.Build.Name).Except(this.RemoteBuildEntries.Select(b => b.FileName)).None() &&
|
||||
this.LocalBuildEntries.Select(b => b.TemplateCode).Except(this.RemoteBuildEntries.Select(b => b.TemplateCode)).None())
|
||||
{
|
||||
this.Synchronized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Synchronized = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,31 +106,85 @@ public partial class BuildsSynchronizationView : UserControl
|
||||
|
||||
private async void UploadButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.ButtonsEnabled = false;
|
||||
var result = await this.graphClient.UploadBuilds();
|
||||
result.DoAny(
|
||||
onFailure: (failure) =>
|
||||
{
|
||||
this.logger.LogError(failure, $"Failed to upload builds");
|
||||
});
|
||||
// TODO: Handle failures to upload
|
||||
if (this.SelectedLocalBuild is not BuildWithTemplateCode buildWithTemplateCode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await this.PopulateLastUpdateTime();
|
||||
this.ButtonsEnabled = false;
|
||||
this.ShowLoading = true;
|
||||
await this.graphClient.UploadBuild(buildWithTemplateCode.Build.Name);
|
||||
await this.PopulateBuilds();
|
||||
this.ButtonsEnabled = true;
|
||||
this.ShowLoading = false;
|
||||
}
|
||||
|
||||
private async void DownloadButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (this.SelectedRemoteBuild is not BuildFile buildFile)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.ButtonsEnabled = false;
|
||||
var result = await this.graphClient.DownloadBuilds();
|
||||
this.ShowLoading = true;
|
||||
await this.graphClient.DownloadBuild(buildFile.FileName);
|
||||
await this.PopulateBuilds();
|
||||
this.ButtonsEnabled = true;
|
||||
this.ShowLoading = false;
|
||||
}
|
||||
|
||||
private async void DownloadAllButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.ButtonsEnabled = false;
|
||||
this.ShowLoading = true;
|
||||
var result = await this.graphClient.DownloadBuilds().ConfigureAwait(true);
|
||||
result.DoAny(
|
||||
onFailure: (failure) =>
|
||||
{
|
||||
this.logger.LogError(failure, $"Failed to download builds");
|
||||
});
|
||||
|
||||
await this.PopulateLastUpdateTime();
|
||||
await this.PopulateBuilds();
|
||||
this.ButtonsEnabled = true;
|
||||
this.ShowLoading = false;
|
||||
}
|
||||
|
||||
private async void UploadAllButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.ButtonsEnabled = false;
|
||||
this.ShowLoading = true;
|
||||
var result = await this.graphClient.UploadBuilds().ConfigureAwait(true);
|
||||
result.DoAny(
|
||||
onFailure: (failure) =>
|
||||
{
|
||||
this.logger.LogError(failure, $"Failed to upload builds");
|
||||
});
|
||||
|
||||
await this.PopulateBuilds();
|
||||
this.ButtonsEnabled = true;
|
||||
this.ShowLoading = false;
|
||||
}
|
||||
|
||||
private async void LogOutButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.ButtonsEnabled = false;
|
||||
this.ShowLoading = true;
|
||||
var result = await this.graphClient.LogOut();
|
||||
result.Do(
|
||||
onSuccess: logOutSuccess =>
|
||||
{
|
||||
if (logOutSuccess)
|
||||
{
|
||||
this.viewManager.ShowView<BuildsListView>();
|
||||
}
|
||||
},
|
||||
onFailure: failure =>
|
||||
{
|
||||
this.logger.LogError(failure, "Failed to log out");
|
||||
});
|
||||
this.ButtonsEnabled = true;
|
||||
this.ShowLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<UserControl x:Class="Daybreak.Views.MainView"
|
||||
<UserControl x:Class="Daybreak.Views.CompanionView"
|
||||
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"
|
||||
@@ -46,7 +46,8 @@
|
||||
FavoriteAddress="{Binding ElementName=_this, Path=RightBrowserFavoriteAddress, Mode=OneWay}"
|
||||
MaximizeClicked="RightChromiumBrowserWrapper_MaximizeClicked"
|
||||
BuildDecoded="ChromiumBrowserWrapper_BuildDecoded"
|
||||
CanDownloadBuild="True"/>
|
||||
CanDownloadBuild="True"
|
||||
PreventDispose="True"/>
|
||||
</Grid>
|
||||
<Grid Grid.Column="0" Margin="10" Visibility="{Binding ElementName=_this, Path=BrowsersEnabled, Mode=OneWay, Converter={StaticResource BooleanToVisibility}}">
|
||||
<controls:ChromiumBrowserWrapper x:Name="LeftWebBrowser"
|
||||
@@ -55,7 +56,8 @@
|
||||
FavoriteAddress="{Binding ElementName=_this, Path=LeftBrowserFavoriteAddress, Mode=OneWay}"
|
||||
MaximizeClicked="LeftChromiumBrowserWrapper_MaximizeClicked"
|
||||
BuildDecoded="ChromiumBrowserWrapper_BuildDecoded"
|
||||
CanDownloadBuild="True"/>
|
||||
CanDownloadBuild="True"
|
||||
PreventDispose="True"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,12 +1,9 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Controls;
|
||||
using Daybreak.Exceptions;
|
||||
using Daybreak.Models.Builds;
|
||||
using Daybreak.Services.ApplicationLauncher;
|
||||
using Daybreak.Services.BuildTemplates;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Services.Screens;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Extensions;
|
||||
@@ -24,14 +21,14 @@ namespace Daybreak.Views
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification = "Fields used by source generator for DependencyProperty")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Used by source generators")]
|
||||
public partial class MainView : UserControl
|
||||
public partial class CompanionView : UserControl
|
||||
{
|
||||
private readonly IApplicationLauncher applicationDetector;
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly ILiveUpdateableOptions<ApplicationConfiguration> liveOptions;
|
||||
private readonly IScreenManager screenManager;
|
||||
private readonly CancellationTokenSource cancellationTokenSource = new();
|
||||
|
||||
private CancellationTokenSource cancellationTokenSource = new();
|
||||
private bool leftBrowserMaximized = false;
|
||||
private bool rightBrowserMaximized = false;
|
||||
|
||||
@@ -54,7 +51,7 @@ namespace Daybreak.Views
|
||||
[GenerateDependencyProperty(InitialValue = true)]
|
||||
private bool browsersEnabled;
|
||||
|
||||
public MainView(
|
||||
public CompanionView(
|
||||
IApplicationLauncher applicationDetector,
|
||||
IViewManager viewManager,
|
||||
ILiveUpdateableOptions<ApplicationConfiguration> liveOptions,
|
||||
@@ -65,7 +62,6 @@ namespace Daybreak.Views
|
||||
this.applicationDetector = applicationDetector.ThrowIfNull(nameof(applicationDetector));
|
||||
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
|
||||
this.InitializeComponent();
|
||||
this.PeriodicallyCheckGameState();
|
||||
this.InitializeBrowsers();
|
||||
}
|
||||
|
||||
@@ -96,6 +92,7 @@ namespace Daybreak.Views
|
||||
|
||||
private void PeriodicallyCheckGameState()
|
||||
{
|
||||
this.cancellationTokenSource = new CancellationTokenSource();
|
||||
System.Extensions.TaskExtensions.RunPeriodicAsync(() => this.Dispatcher.Invoke(this.CheckGameState), TimeSpan.Zero, TimeSpan.FromSeconds(1), this.cancellationTokenSource.Token);
|
||||
}
|
||||
|
||||
@@ -108,11 +105,12 @@ namespace Daybreak.Views
|
||||
|
||||
private void StartupView_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.PeriodicallyCheckGameState();
|
||||
}
|
||||
|
||||
private void StartupView_Unloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.cancellationTokenSource.Cancel();
|
||||
this.cancellationTokenSource?.Cancel();
|
||||
}
|
||||
|
||||
private async void LaunchButton_Clicked(object sender, EventArgs e)
|
||||
@@ -10,13 +10,12 @@
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid Background="#A0202020">
|
||||
<TextBlock HorizontalAlignment="Center" Text="Executables settings" FontSize="22" Foreground="White"></TextBlock>
|
||||
<controls:BackButton Foreground="White" Height="30" Width="30" Grid.Column="0" HorizontalAlignment="Left" Margin="5"
|
||||
Clicked="BackButton_Clicked" VerticalAlignment="Top"></controls:BackButton>
|
||||
<controls:AddButton Foreground="White" Height="30" Width="30" Grid.Column="0" HorizontalAlignment="Right" Margin="5, 5, 45, 5"
|
||||
Clicked="AddButton_Clicked" VerticalAlignment="Top"></controls:AddButton>
|
||||
<controls:SaveButton Foreground="White" Height="30" Width="30" Grid.Column="0" HorizontalAlignment="Right" Margin="5"
|
||||
Clicked="SaveButton_Clicked" VerticalAlignment="Top"></controls:SaveButton>
|
||||
<ListView ItemsSource="{Binding ElementName=_this, Path=Paths, Mode=OneWay}" Background="Transparent" Margin="0, 40, 0, 0">
|
||||
<ListView ItemsSource="{Binding ElementName=_this, Path=Paths, Mode=OneWay}" Background="Transparent" Margin="0, 40, 0, 0"
|
||||
BorderThickness="0">
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Controls;
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Configuration;
|
||||
@@ -18,15 +17,12 @@ namespace Daybreak.Views
|
||||
public partial class ExecutablesView : UserControl
|
||||
{
|
||||
private readonly ILiveUpdateableOptions<ApplicationConfiguration> liveUpdateableOptions;
|
||||
private readonly IViewManager viewManager;
|
||||
public ObservableCollection<GuildwarsPath> Paths { get; } = new();
|
||||
|
||||
public ExecutablesView(
|
||||
ILiveUpdateableOptions<ApplicationConfiguration> liveUpdateableOptions,
|
||||
IViewManager viewManager)
|
||||
ILiveUpdateableOptions<ApplicationConfiguration> liveUpdateableOptions)
|
||||
{
|
||||
this.liveUpdateableOptions = liveUpdateableOptions.ThrowIfNull(nameof(liveUpdateableOptions));
|
||||
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
|
||||
this.InitializeComponent();
|
||||
this.GetPaths();
|
||||
}
|
||||
@@ -36,11 +32,6 @@ namespace Daybreak.Views
|
||||
this.Paths.AddRange(this.liveUpdateableOptions.Value.GuildwarsPaths);
|
||||
}
|
||||
|
||||
private void BackButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<SettingsCategoryView>();
|
||||
}
|
||||
|
||||
private void AddButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
var newPath = new GuildwarsPath();
|
||||
@@ -55,7 +46,6 @@ namespace Daybreak.Views
|
||||
{
|
||||
this.liveUpdateableOptions.Value.GuildwarsPaths = this.Paths.ToList();
|
||||
this.liveUpdateableOptions.UpdateOption();
|
||||
this.viewManager.ShowView<SettingsCategoryView>();
|
||||
}
|
||||
|
||||
private void GuildwarsPathTemplate_DefaultClicked(object sender, EventArgs e)
|
||||
|
||||
@@ -71,8 +71,6 @@
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<controls:BackButton Foreground="White" Height="30" Width="30" Grid.Column="0" Margin="5"
|
||||
Clicked="BackButton_Clicked" VerticalAlignment="Top" HorizontalAlignment="Left"></controls:BackButton>
|
||||
<controls:SaveButton Foreground="White" Height="30" Width="30" Grid.Column="0" Margin="5"
|
||||
Clicked="SaveButton_Clicked" VerticalAlignment="Top" HorizontalAlignment="Right"></controls:SaveButton>
|
||||
<StackPanel Margin="50, 0, 50, 0" HorizontalAlignment="Center">
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Extensions;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Extensions;
|
||||
using System.Windows.Input;
|
||||
@@ -29,14 +27,11 @@ namespace Daybreak.Views
|
||||
[GenerateDependencyProperty]
|
||||
public bool downloadIcons;
|
||||
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly ILiveUpdateableOptions<ApplicationConfiguration> liveUpdateableOptions;
|
||||
|
||||
public ExperimentalSettingsView(
|
||||
IViewManager viewManager,
|
||||
ILiveUpdateableOptions<ApplicationConfiguration> liveUpdateableOptions)
|
||||
{
|
||||
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
|
||||
this.liveUpdateableOptions = liveUpdateableOptions.ThrowIfNull(nameof(liveUpdateableOptions));
|
||||
this.InitializeComponent();
|
||||
this.LoadExperimentalSettings();
|
||||
@@ -72,12 +67,6 @@ namespace Daybreak.Views
|
||||
private void SaveButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.SaveExperimentalSettings();
|
||||
this.viewManager.ShowView<SettingsCategoryView>();
|
||||
}
|
||||
|
||||
private void BackButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<SettingsCategoryView>();
|
||||
}
|
||||
|
||||
private void TextBox_AllowNumbersOnly(object sender, TextCompositionEventArgs e)
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using Daybreak.Services.Graph;
|
||||
using Daybreak.Services.Graph.Models;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Core.Extensions;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
@@ -38,14 +37,14 @@ public partial class GraphAuthorizationView : UserControl
|
||||
if (authorizationResult.TryExtractFailure(out var failure))
|
||||
{
|
||||
this.logger.LogError(failure, "Authorization failed");
|
||||
this.viewManager.ShowView<MainView>();
|
||||
this.viewManager.ShowView<CompanionView>();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.DataContext is not ViewRedirectContext redirectContext)
|
||||
{
|
||||
this.logger.LogError("Cannot redirect to proper view. No view set in context");
|
||||
this.viewManager.ShowView<MainView>();
|
||||
this.viewManager.ShowView<CompanionView>();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Daybreak.Models.Progress;
|
||||
using Daybreak.Services.IconRetrieve;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Core.Extensions;
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
<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"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Services.Logging;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
@@ -18,19 +16,16 @@ namespace Daybreak.Views
|
||||
/// </summary>
|
||||
public partial class LogsView : UserControl
|
||||
{
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly ILogsManager logManager;
|
||||
private readonly ILogger<LogsView> logger;
|
||||
|
||||
public ObservableCollection<Log> Logs { get; } = new ObservableCollection<Log>();
|
||||
|
||||
public LogsView(
|
||||
IViewManager viewManager,
|
||||
ILogsManager logManager,
|
||||
ILogger<LogsView> logger)
|
||||
{
|
||||
this.logManager = logManager.ThrowIfNull(nameof(logManager));
|
||||
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
|
||||
this.logger = logger.ThrowIfNull(nameof(logger));
|
||||
this.InitializeComponent();
|
||||
this.UpdateLogs();
|
||||
@@ -62,10 +57,6 @@ namespace Daybreak.Views
|
||||
this.logger.LogInformation("Exporting canceled");
|
||||
}
|
||||
}
|
||||
private void BackButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<SettingsCategoryView>();
|
||||
}
|
||||
private void BinButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.logManager.DeleteLogs();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Services.ApplicationLauncher;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Extensions;
|
||||
using System.Windows.Controls;
|
||||
@@ -42,7 +42,7 @@ namespace Daybreak.Views
|
||||
else
|
||||
{
|
||||
this.logger.LogWarning("Elevation request context is not set. Returning to home page");
|
||||
this.viewManager.ShowView<MainView>();
|
||||
this.viewManager.ShowView<CompanionView>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
using Daybreak.Controls.Templates;
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Services.ApplicationLauncher;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Services.Screens;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Extensions;
|
||||
@@ -87,7 +87,7 @@ namespace Daybreak.Views
|
||||
private void SaveButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.liveOptions.Value.DesiredGuildwarsScreen = this.selectedId;
|
||||
this.viewManager.ShowView<SettingsCategoryView>();
|
||||
this.viewManager.ShowView<SettingsView>();
|
||||
}
|
||||
|
||||
private void OpaqueButton_Clicked(object sender, EventArgs e)
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
<UserControl x:Class="Daybreak.Views.SettingsCategoryView"
|
||||
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"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid Background="#A0202020">
|
||||
<controls:BackButton Foreground="White" Height="30" Width="30" Grid.Column="0" Margin="5"
|
||||
Clicked="BackButton_Clicked" VerticalAlignment="Top" HorizontalAlignment="Left"></controls:BackButton>
|
||||
<WrapPanel Orientation="Vertical" VerticalAlignment="Bottom">
|
||||
<WrapPanel Orientation="Horizontal">
|
||||
<controls:TileButton Title="Account settings" Foreground="White" BorderBrush="White" BorderThickness="2"
|
||||
HighlightColor="White" Clicked="AccountButton_Clicked" Width="150" Height="150">
|
||||
<controls:TileButton.InnerContent>
|
||||
<controls:AvatarGlyph></controls:AvatarGlyph>
|
||||
</controls:TileButton.InnerContent>
|
||||
</controls:TileButton>
|
||||
<controls:TileButton Title="Guildwars settings" Foreground="White" BorderBrush="White" BorderThickness="2"
|
||||
HighlightColor="White" Clicked="FileButton_Clicked" Height="150" Width="150">
|
||||
<controls:TileButton.InnerContent>
|
||||
<controls:FileGlyph></controls:FileGlyph>
|
||||
</controls:TileButton.InnerContent>
|
||||
</controls:TileButton>
|
||||
<controls:TileButton Title="Launcher settings" Foreground="White" BorderBrush="White" BorderThickness="2"
|
||||
HighlightColor="White" Clicked="LauncherButton_Clicked" Width="150" Height="150">
|
||||
<controls:TileButton.InnerContent>
|
||||
<controls:GoldenArrowGlyph></controls:GoldenArrowGlyph>
|
||||
</controls:TileButton.InnerContent>
|
||||
</controls:TileButton>
|
||||
<controls:TileButton Title="Experimental settings" Foreground="White" BorderBrush="White" BorderThickness="2"
|
||||
HighlightColor="White" Clicked="ExperimentalButton_Clicked" Height="150" Width="150">
|
||||
<controls:TileButton.InnerContent>
|
||||
<controls:ExperimentGlyph></controls:ExperimentGlyph>
|
||||
</controls:TileButton.InnerContent>
|
||||
</controls:TileButton>
|
||||
<controls:TileButton Title="Builds" Foreground="White" BorderBrush="White" BorderThickness="2"
|
||||
HighlightColor="White" Clicked="BuildsButton_Clicked" Height="150" Width="150">
|
||||
<controls:TileButton.InnerContent>
|
||||
<controls:FireballGlyph></controls:FireballGlyph>
|
||||
</controls:TileButton.InnerContent>
|
||||
</controls:TileButton>
|
||||
<controls:TileButton Title="Version management" Foreground="White" BorderBrush="White" BorderThickness="2"
|
||||
HighlightColor="White" Clicked="VersionButton_Clicked" Height="150" Width="150">
|
||||
<controls:TileButton.InnerContent>
|
||||
<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>
|
||||
</UserControl>
|
||||
@@ -1,74 +0,0 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using System.Configuration;
|
||||
using System.Core.Extensions;
|
||||
using System.Extensions;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Daybreak.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for SettingsCategoryView.xaml
|
||||
/// </summary>
|
||||
public partial class SettingsCategoryView : UserControl
|
||||
{
|
||||
private readonly IViewManager viewManager;
|
||||
private readonly ILiveOptions<ApplicationConfiguration> liveOptions;
|
||||
|
||||
public SettingsCategoryView(
|
||||
ILiveOptions<ApplicationConfiguration> liveOptions,
|
||||
IViewManager viewManager)
|
||||
{
|
||||
this.liveOptions = liveOptions.ThrowIfNull();
|
||||
this.viewManager = viewManager.ThrowIfNull();
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void AccountButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<AccountsView>();
|
||||
}
|
||||
|
||||
private void LauncherButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<SettingsView>();
|
||||
}
|
||||
|
||||
private void ExperimentalButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<ExperimentalSettingsView>();
|
||||
}
|
||||
|
||||
private void BuildsButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.liveOptions.Value.ExperimentalFeatures.DownloadIcons)
|
||||
{
|
||||
this.viewManager.ShowView<IconDownloadView>();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.viewManager.ShowView<BuildsListView>();
|
||||
}
|
||||
}
|
||||
|
||||
private void VersionButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
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>();
|
||||
}
|
||||
|
||||
private void BackButton_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<MainView>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,8 +77,6 @@
|
||||
<ColumnDefinition Width="*"></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="Launcher settings" FontSize="22" Foreground="White" HorizontalAlignment="Center" Grid.ColumnSpan="2"></TextBlock>
|
||||
<controls:BackButton Foreground="White" Height="30" Width="30" Grid.Column="0" HorizontalAlignment="Left" Margin="5"
|
||||
Clicked="BackButton_Clicked"></controls:BackButton>
|
||||
<controls:SaveButton Foreground="White" Height="30" Width="30" Grid.Column="1" HorizontalAlignment="Right" Margin="5"
|
||||
Clicked="SaveButton_Clicked"></controls:SaveButton>
|
||||
<StackPanel Orientation="Vertical" Grid.Row="1">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Services.Navigation;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Extensions;
|
||||
@@ -86,7 +86,6 @@ namespace Daybreak.Views
|
||||
currentConfig.PlaceShortcut = this.ShortcutPlaced;
|
||||
currentConfig.AutoCheckUpdate = this.AutoCheckUpdate;
|
||||
this.liveUpdateableOptions.UpdateOption();
|
||||
this.viewManager.ShowView<SettingsCategoryView>();
|
||||
}
|
||||
|
||||
private void ToolboxFilePickerGlyph_Clicked(object sender, EventArgs e)
|
||||
@@ -139,11 +138,6 @@ namespace Daybreak.Views
|
||||
this.viewManager.ShowView<ScreenChoiceView>();
|
||||
}
|
||||
|
||||
private void BackButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
this.viewManager.ShowView<SettingsCategoryView>();
|
||||
}
|
||||
|
||||
private void TextBox_AllowOnlyNumbers(object sender, System.Windows.Input.TextCompositionEventArgs e)
|
||||
{
|
||||
if (int.TryParse(e.Text, out _) is false)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Daybreak.Models.Progress;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Services.Updater;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Windows;
|
||||
@@ -59,7 +59,7 @@ namespace Daybreak.Views
|
||||
{
|
||||
if (this.DataContext is not Version version)
|
||||
{
|
||||
this.viewManager.ShowView<MainView>();
|
||||
this.viewManager.ShowView<CompanionView>();
|
||||
throw new InvalidOperationException("No version specified for download");
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace Daybreak.Views
|
||||
}
|
||||
else
|
||||
{
|
||||
this.viewManager.ShowView<MainView>();
|
||||
this.viewManager.ShowView<CompanionView>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<controls:BackButton Foreground="White" Height="30" Width="30" Grid.Column="0" HorizontalAlignment="Left" Margin="5"
|
||||
Clicked="BackButton_Clicked"></controls:BackButton>
|
||||
<TextBlock Text="Manage application version" FontSize="18" Foreground="White" HorizontalAlignment="Center"></TextBlock>
|
||||
<WrapPanel Grid.Row="1" HorizontalAlignment="Center" Margin="10">
|
||||
<TextBlock Text="Current version: " Foreground="White" FontSize="16"></TextBlock>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Daybreak.Services.Updater;
|
||||
using Daybreak.Services.ViewManagement;
|
||||
using Daybreak.Services.Navigation;
|
||||
using Daybreak.Services.Updater;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
@@ -77,17 +77,5 @@ namespace Daybreak.Views
|
||||
|
||||
this.viewManager.ShowView<UpdateView>(desiredVersion);
|
||||
}
|
||||
|
||||
private void BackButton_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (this.DataContext is UserControl userControl)
|
||||
{
|
||||
this.viewManager.ShowView(userControl.GetType());
|
||||
}
|
||||
else
|
||||
{
|
||||
this.viewManager.ShowView<MainView>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user