Styling for the gallery, lots of other UI fixes

This commit is contained in:
Timothy Baldridge 2021-09-29 16:24:21 -06:00
parent 28417c39d3
commit a0b705e375
91 changed files with 8685 additions and 68 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
Branding/Github_Card.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
Branding/PNGs/Banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
Branding/PNGs/Letters.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
Branding/PNGs/Logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

BIN
Branding/PNGs/Wabba_Ded.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

158
Branding/SVGs/Banner.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 80 KiB

37
Branding/SVGs/Letters.svg Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 262 43" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,-128.835,-90.7199)">
<g transform="matrix(1.03627,0,0,1.1194,0,-120.896)">
<g id="Letter" transform="matrix(1,0,0,1,-6.85674e-14,5.36)">
<g transform="matrix(2.12799,0,0,1.96995,130.765,184)">
<path d="M0,18.744L-3.026,0L-1.821,0L0.991,17.084L3.722,0.08L5.034,0.08L7.658,17.03L10.363,0L11.46,0L8.462,18.744L6.855,18.744L4.338,3.401L1.714,18.744L0,18.744Z" style="fill:rgb(30,64,119);fill-rule:nonzero;"/>
</g>
<g transform="matrix(2.12799,0,0,1.96995,179.882,194.235)">
<path d="M0,8.327L-2.758,-3.803L-5.462,8.327L0,8.327ZM-6.587,13.549L-7.712,13.549L-3.615,-5.222L-1.821,-5.222L2.356,13.549L1.125,13.549L0.187,9.398L-5.65,9.398L-6.587,13.549Z" style="fill:rgb(30,64,119);fill-rule:nonzero;"/>
</g>
<g transform="matrix(2.12799,0,0,1.96995,207.774,187.823)">
<path d="M0,14.862C0.455,14.318 0.683,13.51 0.683,12.439L0.683,10.752C0.683,9.556 0.415,8.708 -0.121,8.208C-0.656,7.708 -1.495,7.458 -2.637,7.458L-4.967,7.458L-4.967,15.679L-2.182,15.679C-1.183,15.679 -0.455,15.407 0,14.862M-0.415,5.704C0.084,5.285 0.335,4.504 0.335,3.361L0.335,2.156C0.335,1.139 0.138,0.389 -0.254,-0.093C-0.647,-0.575 -1.326,-0.816 -2.29,-0.816L-4.967,-0.816L-4.967,6.334L-2.879,6.334C-1.736,6.334 -0.915,6.124 -0.415,5.704M0.683,-0.95C1.272,-0.289 1.566,0.71 1.566,2.049L1.566,3.12C1.566,4.191 1.383,5.026 1.017,5.624C0.651,6.222 0.013,6.619 -0.897,6.816C0.977,7.19 1.914,8.529 1.914,10.832L1.914,12.465C1.914,13.858 1.58,14.929 0.91,15.679C0.241,16.428 -0.79,16.803 -2.182,16.803L-6.199,16.803L-6.199,-1.941L-2.263,-1.941C-0.888,-1.941 0.094,-1.61 0.683,-0.95" style="fill:rgb(30,64,119);fill-rule:nonzero;"/>
</g>
<g transform="matrix(2.12799,0,0,1.96995,235.011,187.823)">
<path d="M0,14.862C0.455,14.318 0.683,13.51 0.683,12.439L0.683,10.752C0.683,9.556 0.415,8.708 -0.121,8.208C-0.656,7.708 -1.495,7.458 -2.638,7.458L-4.967,7.458L-4.967,15.679L-2.182,15.679C-1.183,15.679 -0.455,15.407 0,14.862M-0.415,5.704C0.085,5.285 0.335,4.504 0.335,3.361L0.335,2.156C0.335,1.139 0.138,0.389 -0.254,-0.093C-0.647,-0.575 -1.326,-0.816 -2.289,-0.816L-4.967,-0.816L-4.967,6.334L-2.879,6.334C-1.736,6.334 -0.915,6.124 -0.415,5.704M0.683,-0.95C1.272,-0.289 1.566,0.71 1.566,2.049L1.566,3.12C1.566,4.191 1.383,5.026 1.017,5.624C0.651,6.222 0.013,6.619 -0.897,6.816C0.977,7.19 1.914,8.529 1.914,10.832L1.914,12.465C1.914,13.858 1.58,14.929 0.91,15.679C0.241,16.428 -0.79,16.803 -2.182,16.803L-6.199,16.803L-6.199,-1.941L-2.263,-1.941C-0.888,-1.941 0.094,-1.61 0.683,-0.95" style="fill:rgb(30,64,119);fill-rule:nonzero;"/>
</g>
<g transform="matrix(2.12799,0,0,1.96995,264.897,194.235)">
<path d="M0,8.327L-2.758,-3.803L-5.463,8.327L0,8.327ZM-6.587,13.549L-7.712,13.549L-3.615,-5.222L-1.821,-5.222L2.356,13.549L1.125,13.549L0.187,9.398L-5.65,9.398L-6.587,13.549Z" style="fill:rgb(30,64,119);fill-rule:nonzero;"/>
</g>
<g transform="matrix(2.12799,0,0,1.96995,279.654,186.268)">
<path d="M0,16.468C0.357,16.468 0.616,16.459 0.777,16.441C1.687,16.37 2.356,16.071 2.785,15.544C3.213,15.018 3.427,14.192 3.427,13.067L3.427,-1.151L4.659,-1.151L4.659,12.987C4.659,14.558 4.338,15.705 3.695,16.428C3.053,17.151 2.124,17.539 0.91,17.593C0.785,17.61 0.58,17.619 0.295,17.619C0.027,17.619 -0.179,17.61 -0.321,17.593L-0.321,16.468L0,16.468Z" style="fill:rgb(30,64,119);fill-rule:nonzero;"/>
</g>
<g transform="matrix(2.12799,0,0,1.96995,315.552,194.235)">
<path d="M0,8.327L-2.758,-3.803L-5.463,8.327L0,8.327ZM-6.587,13.549L-7.712,13.549L-3.615,-5.222L-1.821,-5.222L2.356,13.549L1.125,13.549L0.187,9.398L-5.65,9.398L-6.587,13.549Z" style="fill:rgb(30,64,119);fill-rule:nonzero;"/>
</g>
<g transform="matrix(2.12799,0,0,1.96995,345.181,218.681)">
<path d="M0,-16.467C0.66,-15.601 0.991,-14.454 0.991,-13.026L0.991,-11.473L-0.187,-11.473L-0.187,-13.106C-0.187,-14.178 -0.415,-15.034 -0.87,-15.677C-1.325,-16.32 -2.044,-16.641 -3.026,-16.641C-4.008,-16.641 -4.726,-16.32 -5.181,-15.677C-5.637,-15.034 -5.864,-14.178 -5.864,-13.106L-5.864,-3.36C-5.864,-2.289 -5.637,-1.436 -5.181,-0.802C-4.726,-0.169 -4.008,0.148 -3.026,0.148C-2.044,0.148 -1.325,-0.169 -0.87,-0.802C-0.415,-1.436 -0.187,-2.289 -0.187,-3.36L-0.187,-5.582L0.991,-5.582L0.991,-3.44C0.991,-2.012 0.66,-0.865 0,0.001C-0.661,0.867 -1.678,1.299 -3.053,1.299C-4.427,1.299 -5.445,0.867 -6.105,0.001C-6.766,-0.865 -7.096,-2.012 -7.096,-3.44L-7.096,-13.026C-7.096,-14.454 -6.766,-15.601 -6.105,-16.467C-5.445,-17.333 -4.427,-17.766 -3.053,-17.766C-1.678,-17.766 -0.661,-17.333 0,-16.467" style="fill:rgb(30,64,119);fill-rule:nonzero;"/>
</g>
<g transform="matrix(2.12799,0,0,1.96995,359.882,197.347)">
<path d="M0,5.194L0,11.969L-1.232,11.969L-1.232,-6.775L0,-6.775L0,3.132L6.105,-6.775L7.39,-6.775L2.035,1.954L7.739,11.969L6.453,11.969L1.285,3.159L0,5.194Z" style="fill:rgb(30,64,119);fill-rule:nonzero;"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

130
Branding/SVGs/Logo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 76 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 1000 1000" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;"><rect id="Artboard1" x="0" y="0" width="1000" height="1000" style="fill:none;"/><g id="Artboard11" serif:id="Artboard1"><circle cx="500" cy="500" r="425" style="fill:#fff;fill-opacity:0;stroke:#fff;stroke-width:40px;"/><path d="M468.763,410.75l-58.013,0l89.25,-267.75l89.25,267.75l-58.013,0l0,178.5l58.013,0l-89.25,267.75l-89.25,-267.75l58.013,0l0,-178.5Z" style="fill:#fff;fill-opacity:0;stroke:#fff;stroke-width:40px;"/></g></svg>

After

Width:  |  Height:  |  Size: 899 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 782 KiB

BIN
Branding/wabbajack.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 KiB

BIN
Branding/wabbajack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

View File

@ -10,6 +10,7 @@
<Application.Styles>
<StyleInclude Source="avares://Material.Icons.Avalonia/App.xaml"></StyleInclude>
<FluentTheme Mode="Dark"/>
<StyleInclude Source="avares://Wabbajack.App/Assets/Wabbajack.axaml"></StyleInclude>
<Style Selector="Button:not(:pointerover) /template/ ContentPresenter">
<Setter Property="Background" Value="Transparent"></Setter>
</Style>

View File

@ -0,0 +1,42 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:Wabbajack.App.Controls">
<Design.PreviewWith>
<Border>
<TextBlock>Test</TextBlock>
</Border>
</Design.PreviewWith>
<Style Selector="controls|TagView Border">
<Setter Property="BorderThickness" Value="1"></Setter>
<Setter Property="BorderBrush" Value="#121212"></Setter>
<Setter Property="CornerRadius" Value="5"></Setter>
</Style>
<Style Selector="controls|TagView.ModList Border">
<Setter Property="Background" Value="#868CFC"></Setter>
</Style>
<Style Selector="controls|TagView.Game Border">
<Setter Property="Background" Value="#F686FC"></Setter>
</Style>
<Style Selector="controls|TagView.GameNotInstalled Border">
<Setter Property="Background" Value="#FCBB86"></Setter>
</Style>
<Style Selector="controls|TagView.GameNotInstalled Border">
<Setter Property="Background" Value="#FCBB86"></Setter>
</Style>
<Style Selector="controls|TagView TextBlock">
<Setter Property="Foreground" Value="#121212"></Setter>
</Style>
</Styles>

View File

@ -6,5 +6,7 @@ namespace Wabbajack.App
{
public AbsolutePath ModListsDownloadLocation { get; set; }
public AbsolutePath SavedSettingsLocation { get; set; }
public AbsolutePath EncryptedDataLocation { get; set; }
}
}

View File

@ -3,10 +3,11 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:controls="clr-namespace:Wabbajack.App.Controls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Wabbajack.App.Controls.BrowseItemView">
<Border BorderThickness="1" Margin="10, 10, 10, 10">
<Grid Width="570" Height="480" RowDefinitions="Auto, *, 40" ColumnDefinitions="*, Auto">
<Grid Width="540" Height="480" RowDefinitions="Auto, *, 40" ColumnDefinitions="*, Auto">
<Border Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" BorderThickness="0, 0, 0, 1">
<Grid ClipToBounds="True">
<Viewbox Height="340" HorizontalAlignment="Center" VerticalAlignment="Center"
@ -38,6 +39,18 @@
FontSize="14"
TextWrapping="Wrap" />
</ScrollViewer>
<ItemsControl Grid.Row="2" x:Name="TagsList">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:TagView></controls:TagView>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Grid Grid.Row="1" Grid.Column="1" Grid.RowSpan="2">
<Grid.RowDefinitions>

View File

@ -36,6 +36,9 @@ namespace Wabbajack.App.Controls
this.OneWayBind(ViewModel, vm => vm.Progress, view => view.DownloadProgressBar.Value,
s => s.Value * 1000)
.DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.Tags, view => view.TagsList.Items)
.DisposeWith(disposables);
});
}

View File

@ -1,5 +1,6 @@
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reactive;
using System.Reactive.Linq;
@ -16,6 +17,7 @@ using Wabbajack.App.ViewModels;
using Wabbajack.Common;
using Wabbajack.Downloaders;
using Wabbajack.DTOs;
using Wabbajack.Installer;
using Wabbajack.Paths;
using Wabbajack.Paths.IO;
using Wabbajack.RateLimiter;
@ -67,8 +69,12 @@ namespace Wabbajack.App.Controls
public bool IsUtilityList => _metadata.UtilityList;
public bool IsNSFW => _metadata.NSFW;
[Reactive]
public TagViewModel[] Tags { get; set; }
public BrowseItemViewModel(ModlistMetadata metadata, ModListSummary summary, HttpClient client, IResource<HttpClient> limiter,
FileHashCache hashCache, Configuration configuration, DownloadDispatcher dispatcher, IResource<DownloadDispatcher> downloadLimiter, ILogger logger)
FileHashCache hashCache, Configuration configuration, DownloadDispatcher dispatcher, IResource<DownloadDispatcher> downloadLimiter, GameLocator gameLocator,
ILogger logger)
{
Activator = new ViewModelActivator();
_metadata = metadata;
@ -80,6 +86,11 @@ namespace Wabbajack.App.Controls
_dispatcher = dispatcher;
_downloadLimiter = downloadLimiter;
_logger = logger;
var haveGame = gameLocator.IsInstalled(_metadata.Game);
Tags = metadata.tags
.Select(t => new TagViewModel(t, "ModList"))
.Prepend(new TagViewModel(_metadata.Game.MetaData().HumanFriendlyGameName, haveGame ? "Game" : "GameNotInstalled"))
.ToArray();
OpenWebsiteCommand = ReactiveCommand.Create(() =>
{

View File

@ -0,0 +1,18 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Wabbajack.App.Controls.TagView">
<Border x:Name = "Border"
Margin="5,5,0,5"
BorderThickness="1"
CornerRadius="7,7,7,7"
VerticalAlignment="Center"
Opacity="0.90">
<TextBlock
x:Name="Text"
Margin="5,5,5,5"
FontSize="10"/>
</Border>
</UserControl>

View File

@ -0,0 +1,26 @@
using System.Reactive.Disposables;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using DynamicData;
using ReactiveUI;
namespace Wabbajack.App.Controls
{
public partial class TagView : ReactiveUserControl<TagViewModel>
{
public TagView()
{
InitializeComponent();
this.WhenActivated(disposables =>
{
this.OneWayBind(ViewModel, vm => vm.Name, view => view.Text.Text)
.DisposeWith(disposables);
this.OneWayBind(ViewModel, vm => vm.Tag, view => view.Classes,
c => c == null ? new Classes() : new Classes(c))
.DisposeWith(disposables);
});
}
}
}

View File

@ -0,0 +1,23 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Wabbajack.App.ViewModels;
namespace Wabbajack.App.Controls
{
public class TagViewModel : ViewModelBase, IActivatableViewModel
{
[Reactive]
public string Name { get; set; }
[Reactive]
public string Tag { get; set; }
public TagViewModel(string name, string tag)
{
Activator = new ViewModelActivator();
Name = name;
Tag = tag;
}
}
}

View File

@ -68,5 +68,10 @@ namespace Wabbajack.App.Models
}
}
public async Task<InstallationConfigurationSetting?> Get(AbsolutePath modListPath)
{
return (await GetAll()).Settings.FirstOrDefault(f => f.ModList == modListPath);
}
}
}

View File

@ -198,7 +198,7 @@ namespace Wabbajack.App.Screens
summary = new ModListSummary();
}
return new BrowseItemViewModel(m, summary, _httpClient, _limiter, _hashCache, _configuration, _dispatcher, _dispatcherLimiter, _logger);
return new BrowseItemViewModel(m, summary, _httpClient, _limiter, _hashCache, _configuration, _dispatcher, _dispatcherLimiter, _gameLocator, _logger);
});
_modLists.Edit(lsts =>

View File

@ -3,30 +3,28 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Wabbajack.App.Views.SettingsView">
<WrapPanel>
x:Class="Wabbajack.App.Screens.SettingsView">
<WrapPanel Margin="40">
<Border x:Name="LoginBorder" Margin="5" BorderThickness="1">
<Grid RowDefinitions="Auto, Auto, Auto, Auto" ColumnDefinitions="20, *, Auto, Auto">
<TextBlock FontSize="20" Text="Logins" Grid.ColumnSpan="4"></TextBlock>
<Grid RowDefinitions="Auto, Auto, Auto, Auto" ColumnDefinitions="20, 100, Auto, Auto">
<TextBlock FontSize="20" Grid.ColumnSpan="4">Logins</TextBlock>
<Image Grid.Row="1" Grid.Column="0" Width="16" Height="16" Source="../Assets/Downloaders/nexus.ico" HorizontalAlignment="Right"></Image>
<Image Grid.Row="1" Grid.Column="0" Width="16" Height="16" Margin="4" Source="../Assets/Downloaders/nexus.ico" HorizontalAlignment="Right"></Image>
<TextBlock Grid.Row="1" Grid.Column="1" Text="Nexus" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBlock>
<Button Grid.Row="1" Grid.Column="2" x:Name="NexusLogIn">Log In</Button>
<Button Grid.Row="1" Grid.Column="3" x:Name="NexusLogOut">Log Out</Button>
<Image Grid.Row="2" Grid.Column="0" Width="16" Height="16" Source="../Assets/Downloaders/loverslab.ico" HorizontalAlignment="Right"></Image>
<Image Grid.Row="2" Grid.Column="0" Width="16" Height="16" Margin="4" Source="../Assets/Downloaders/loverslab.ico" HorizontalAlignment="Right"></Image>
<TextBlock Grid.Row="2" Grid.Column="1" Text="Lovers Lab" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBlock>
<Button Grid.Row="2" Grid.Column="2" x:Name="LoversLabLogIn">Log In</Button>
<Button Grid.Row="2" Grid.Column="3" x:Name="LoversLabLogOut">Log Out</Button>
<Image Grid.Row="3" Grid.Column="0" Width="16" Height="16" Source="../Assets/Downloaders/vectorplexus.ico" HorizontalAlignment="Right"></Image>
<Image Grid.Row="3" Grid.Column="0" Width="16" Height="16" Margin="4" Source="../Assets/Downloaders/vectorplexus.ico" HorizontalAlignment="Right"></Image>
<TextBlock Grid.Row="3" Grid.Column="1" Text="Vector Plexus" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBlock>
<Button Grid.Row="3" Grid.Column="2" x:Name="VectorPlexusLogIn">Log In</Button>
<Button Grid.Row="3" Grid.Column="3" x:Name="VectorPlexusLogOut">Log Out</Button>
</Grid>
</Border>
</WrapPanel>
</UserControl>

View File

@ -0,0 +1,24 @@
using System.Reactive.Disposables;
using ReactiveUI;
using Wabbajack.App.ViewModels;
using Wabbajack.App.Views;
namespace Wabbajack.App.Screens
{
public partial class SettingsView : ScreenBase<SettingsViewModel>
{
public SettingsView()
{
InitializeComponent();
this.WhenActivated(disposables =>
{
this.BindCommand(ViewModel, vm => vm.NexusLogin, view => view.NexusLogIn)
.DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.NexusLogout, view => view.NexusLogOut)
.DisposeWith(disposables);
});
}
}
}

View File

@ -0,0 +1,62 @@
using System.IO;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using Microsoft.Extensions.Logging;
using ReactiveUI;
using Wabbajack.App.Messages;
using Wabbajack.App.ViewModels;
using Wabbajack.Paths;
using Wabbajack.Services.OSIntegrated.TokenProviders;
namespace Wabbajack.App.Screens
{
public class SettingsViewModel : ViewModelBase, IReceiverMarker
{
private readonly ILogger<SettingsViewModel> _logger;
public ReactiveCommand<Unit, Unit> NexusLogin { get; set; }
public ReactiveCommand<Unit, Unit> NexusLogout { get; set; }
public FileSystemWatcher Watcher { get; set; }
private readonly Subject<AbsolutePath> _fileSystemEvents = new();
public SettingsViewModel(ILogger<SettingsViewModel> logger, Configuration configuration, NexusApiTokenProvider nexusProvider)
{
_logger = logger;
Activator = new ViewModelActivator();
this.WhenActivated(disposables =>
{
Watcher = new FileSystemWatcher(configuration.EncryptedDataLocation.ToString());
Watcher.DisposeWith(disposables);
Watcher.Created += Pulse;
Watcher.Deleted += Pulse;
Watcher.Renamed += Pulse;
Watcher.Changed += Pulse;
Watcher.EnableRaisingEvents = true;
var haveNexusToken = this._fileSystemEvents
.StartWith(AbsolutePath.Empty)
.Select(_ => nexusProvider.HaveToken());
NexusLogin = ReactiveCommand.Create(() =>
{
MessageBus.Instance.Send(new NavigateTo(typeof(NexusLoginViewModel)));
}, haveNexusToken.Select(x => !x));
NexusLogout = ReactiveCommand.Create(nexusProvider.DeleteToken, haveNexusToken.Select(x => x));
});
}
private void Pulse(object sender, FileSystemEventArgs e)
{
_fileSystemEvents.OnNext(e.Name?.ToAbsolutePath() ?? default);
}
}
}

View File

@ -23,6 +23,7 @@ using Wabbajack.Networking.NexusApi;
using Wabbajack.Paths;
using Wabbajack.Paths.IO;
using Wabbajack.Services.OSIntegrated;
using SettingsView = Wabbajack.App.Screens.SettingsView;
namespace Wabbajack.App
{
@ -32,7 +33,6 @@ namespace Wabbajack.App
{
services.AddSingleton<MessageBus>();
services.AddSingleton<MainWindow>();
services.AddSingleton<InstallConfigurationViewModel>();
services.AddSingleton<BrowseViewModel>();
services.AddTransient<BrowseItemViewModel>();
@ -50,6 +50,7 @@ namespace Wabbajack.App
services.AddSingleton<HttpClient>();
services.AddAllSingleton<IReceiverMarker, StandardInstallationViewModel>();
services.AddAllSingleton<IReceiverMarker, InstallConfigurationViewModel>();
services.AddAllSingleton<IReceiverMarker, MainWindowViewModel>();
services.AddAllSingleton<IReceiverMarker, SettingsViewModel>();
services.AddAllSingleton<IReceiverMarker, NexusLoginViewModel>();
@ -75,6 +76,7 @@ namespace Wabbajack.App
services.AddSingleton(s => new Configuration
{
EncryptedDataLocation = KnownFolders.WabbajackAppLocal.Combine("encrypted"),
ModListsDownloadLocation = KnownFolders.EntryPoint.Combine("downloaded_mod_lists"),
SavedSettingsLocation = KnownFolders.WabbajackAppLocal.Combine("saved_settings")
});

View File

@ -81,22 +81,22 @@ namespace Wabbajack.App.ViewModels
.BindTo(this, t => t.ModListImage)
.DisposeWith(disposables);
SetupDefaults().FireAndForget();
var settings = this.WhenAnyValue(t => t.ModListPath)
.SelectAsync(disposables, async v => await _stateManager.Get(v))
.Where(s => s != null);
settings.Select(s => s!.Install)
.BindTo(this, vm => vm.Install)
.DisposeWith(disposables);
settings.Select(s => s!.Downloads)
.BindTo(this, vm => vm.Download)
.DisposeWith(disposables);
});
}
private async Task SetupDefaults()
{
var lastState = await _stateManager.GetLastState();
if (!lastState.ModList.FileExists()) return;
await Task.Delay(250); // Ugly hack
ModListPath = lastState.ModList;
Install = lastState.Install;
Download = lastState.Downloads;
}
private void StartInstall()
{
_stateManager.SetLastState(new InstallationConfigurationSetting

View File

@ -14,6 +14,7 @@ using ReactiveUI.Fody.Helpers;
using ReactiveUI.Validation.Helpers;
using Wabbajack.App.Interfaces;
using Wabbajack.App.Messages;
using Wabbajack.App.Screens;
using Wabbajack.App.Views;
using Wabbajack.Common;
using Wabbajack.RateLimiter;

View File

@ -1,18 +0,0 @@
using Microsoft.Extensions.Logging;
using ReactiveUI;
using Wabbajack.App.Messages;
namespace Wabbajack.App.ViewModels
{
public class SettingsViewModel : ViewModelBase, IReceiverMarker
{
private readonly ILogger<SettingsViewModel> _logger;
public SettingsViewModel(ILogger<SettingsViewModel> logger)
{
_logger = logger;
Activator = new ViewModelActivator();
}
}
}

View File

@ -1,23 +0,0 @@
using System.Reactive.Disposables;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using ReactiveUI;
using Wabbajack.App.Messages;
using Wabbajack.App.ViewModels;
namespace Wabbajack.App.Views
{
public partial class SettingsView : ScreenBase<SettingsViewModel>
{
public SettingsView()
{
InitializeComponent();
this.WhenActivated(disposables =>
{
});
}
}
}

View File

@ -8,6 +8,8 @@
<ItemGroup>
<Folder Include="Models\" />
<AvaloniaResource Include="Assets\**" />
<AvaloniaXaml Remove="Assets\Wabbajack.axaml" />
<AvaloniaResource Include="Assets\Wabbajack.axaml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.7" />
@ -34,6 +36,12 @@
<ItemGroup>
<Reference Include="Microsoft.AspNetCore.Mvc.Core" />
</ItemGroup>
<ItemGroup>
<Compile Update="Screens\SettingsView.axaml.cs">
<DependentUpon>SettingsView.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<Target Name="AferBuild" AfterTargets="Build">
<Message Text="Downloading Cef" />

View File

@ -12,6 +12,7 @@ namespace Wabbajack.Paths
public readonly struct AbsolutePath : IPath, IComparable<AbsolutePath>, IEquatable<AbsolutePath>
{
public static readonly AbsolutePath Empty = "".ToAbsolutePath();
public PathFormat PathFormat { get; }