Skip to content

Commit

Permalink
Merge pull request #44 from sahin-a/19-settings-tab-avalonia
Browse files Browse the repository at this point in the history
19 settings tab avalonia
  • Loading branch information
sahin-a committed Mar 11, 2023
2 parents 3b4138f + e06967b commit 53c840a
Show file tree
Hide file tree
Showing 24 changed files with 355 additions and 100 deletions.
2 changes: 1 addition & 1 deletion SteamAccountManager.AvaloniaUI/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow
desktop.MainWindow = new MainWindowView
{
DataContext = new MainWindowViewModel(),
};
Expand Down
35 changes: 35 additions & 0 deletions SteamAccountManager.AvaloniaUI/AppViewLocator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using ReactiveUI;
using SteamAccountManager.AvaloniaUI.ViewModels;
using SteamAccountManager.AvaloniaUI.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SteamAccountManager.AvaloniaUI
{
public class AppViewLocator : IViewLocator
{
public IViewFor? ResolveView<T>(T viewModel, string? contract = null)
{
string? viewPath = viewModel?.GetType().FullName?
.Replace("ViewModels", "Views")
.Replace("ViewModel", "View");

switch (viewPath)
{
case not null:
return createInstanceFromPath(viewPath);
default:
return null;
}
}

private IViewFor createInstanceFromPath(string path)
{
Type classType = Type.GetType(path, true) ?? throw new Exception("Couldn't resolve type from path");
return Activator.CreateInstance(classType) as IViewFor ?? throw new Exception("Type isn't of type IViewFor!");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace SteamAccountManager.AvaloniaUI.Common
{
internal class AdvancedObservableCollection<T> : ObservableCollection<T>
public class AdvancedObservableCollection<T> : ObservableCollection<T>
{
public AdvancedObservableCollection() : base()
{
Expand Down
33 changes: 33 additions & 0 deletions SteamAccountManager.AvaloniaUI/Common/ViewModelStore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Autofac;
using ReactiveUI;
using SteamAccountManager.Domain.Common.CodeExtensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SteamAccountManager.AvaloniaUI.Common
{
internal class ViewModelStore
{
private readonly Dictionary<Type, IRoutableViewModel> _viewModels = new Dictionary<Type, IRoutableViewModel>();

public IRoutableViewModel Get<T>(IScreen screen) where T : class, IRoutableViewModel
{
var viewModel = _viewModels.GetOrNull(typeof(T));
if (viewModel is null)
{
viewModel = CreateViewModel<T>(screen);
Register(viewModel);
}

return viewModel;
}

public void Register(IRoutableViewModel viewModel) => _viewModels.Add(viewModel.GetType(), viewModel);

private IRoutableViewModel CreateViewModel<T>(IScreen screen) where T : class, IRoutableViewModel
=> Dependencies.Container?.Resolve<T>(new TypedParameter(typeof(IScreen), screen)) ?? throw new Exception("Failed to resolve AccountSwitcherViewModel");
}
}
12 changes: 11 additions & 1 deletion SteamAccountManager.AvaloniaUI/Dependencies.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Autofac;
using Autofac.Core;
using DI;
using ReactiveUI;
using SteamAccountManager.Application.Steam.Service;
using SteamAccountManager.AvaloniaUI.Mappers;
using SteamAccountManager.AvaloniaUI.Notifications;
Expand Down Expand Up @@ -35,7 +37,15 @@ public static void RegisterAvaloniaModule(this ContainerBuilder builder)

public static void RegisterViewModels(this ContainerBuilder builder)
{
builder.RegisterType<AccountSwitcherViewModel>();

builder.RegisterViewModel<AccountSwitcherViewModel>();
builder.RegisterViewModel<SettingsViewModel>();
}

private static void RegisterViewModel<ViewModel>(this ContainerBuilder builder) where ViewModel : RoutableViewModel
{
builder.RegisterType<ViewModel>()
.WithParameter(new TypedParameter(typeof(IScreen), "screen"));
}
}
}
2 changes: 1 addition & 1 deletion SteamAccountManager.AvaloniaUI/Mappers/AccountMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace SteamAccountManager.AvaloniaUI.Mappers
{
internal class AccountMapper
public class AccountMapper
{
private AvatarService _avatarService;

Expand Down
2 changes: 1 addition & 1 deletion SteamAccountManager.AvaloniaUI/Models/Account.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace SteamAccountManager.AvaloniaUI.Models
{
internal class Account : INotifyPropertyChanged
public class Account : INotifyPropertyChanged
{
public IBitmap? ProfilePicture { get; set; }
public Uri? ProfilePictureUrl { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion SteamAccountManager.AvaloniaUI/Services/AvatarService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace SteamAccountManager.AvaloniaUI.Services
{
internal class AvatarService
public class AvatarService
{
private IAssetLoader _assetLoader;
private readonly IAvatarService _avatarService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
<None Remove="Assets\avatar_placeholder.jpg" />
<None Remove="Assets\github_mark_light.png" />
<None Remove="Assets\sam.ico" />
<None Remove="SteamAccountSwitcherStyles.xaml" />
</ItemGroup>
<ItemGroup>
<AvaloniaXaml Include="SteamAccountSwitcherStyles.xaml">
<Generator>MSBuild:Compile</Generator>
</AvaloniaXaml>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.16" />
Expand All @@ -42,8 +48,11 @@
<ProjectReference Include="..\SteamAccountManager.Application\SteamAccountManager.Application.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Views\AccountSwitcher.axaml.cs">
<DependentUpon>AccountSwitcher.axaml</DependentUpon>
<Compile Update="Views\AccountSwitcherView.axaml.cs">
<DependentUpon>AccountSwitcherView.axaml</DependentUpon>
</Compile>
<Compile Update="Views\MainWindowView.axaml.cs">
<DependentUpon>MainWindowView.axaml</DependentUpon>
</Compile>
</ItemGroup>
</Project>
35 changes: 35 additions & 0 deletions SteamAccountManager.AvaloniaUI/SteamAccountSwitcherStyles.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style Selector="Window">
<Setter Property="Background" Value="#1c1b1b" />
<Setter Property="Icon" Value="/Assets/sam.ico" />
<Setter Property="ExtendClientAreaToDecorationsHint" Value="True" />
</Style>

<Style Selector="Grid.NavBar">
<Setter Property="Background" Value="#1c1b1b" />
</Style>
<Style Selector="Button.NavTab">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Padding" Value="12" />
<Setter Property="Margin" Value="0" />
</Style>

<Style Selector="Grid.ButtonBar">
<Setter Property="Background" Value="#1c1b1b" />
</Style>
<Style Selector="Button.BarItem">
<Setter Property="FontSize" Value="25" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Padding" Value="12" />
<Setter Property="Margin" Value="0" />
</Style>
</Styles>
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
using System.Threading.Tasks;
using System.Windows.Input;
using SteamAccountManager.Application.Steam.Observables;
using ReactiveUI;

namespace SteamAccountManager.AvaloniaUI.ViewModels
{
// TODO: looks ridicilous, I should refactor all of this but I don't feel bored enough yet
internal class AccountSwitcherViewModel
// TOOD: switch to reactive commands etc.
public class AccountSwitcherViewModel : RoutableViewModel
{
private readonly IGetAccountsWithDetailsUseCase _getAccountsUseCase;
private readonly ISwitchAccountUseCase _switchAccountUseCase;
Expand All @@ -28,15 +30,15 @@ internal class AccountSwitcherViewModel
public ICommand AddAccountCommand { get; }
public Account? SelectedAccount { get; set; }


public AccountSwitcherViewModel
(
IScreen screen,
IGetAccountsWithDetailsUseCase getAccountsUseCase,
ISwitchAccountUseCase switchAccountUseCase,
AccountMapper accountMapper,
IAccountStorageObservable accountStorageObserver,
ILocalNotificationService notificationService
)
) : base(screen)
{
_getAccountsUseCase = getAccountsUseCase;
_switchAccountUseCase = switchAccountUseCase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace SteamAccountManager.AvaloniaUI.ViewModels.Commands
{
internal class QuickCommand : ICommand
public class QuickCommand : ICommand
{
private readonly Action _func;

Expand Down
69 changes: 66 additions & 3 deletions SteamAccountManager.AvaloniaUI/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,71 @@
namespace SteamAccountManager.AvaloniaUI.ViewModels
using ReactiveUI;
using SteamAccountManager.AvaloniaUI.Common;
using SteamAccountManager.AvaloniaUI.ViewModels.Commands;
using System.Reactive;

namespace SteamAccountManager.AvaloniaUI.ViewModels
{
public class MainWindowViewModel
public class NavigationTarget
{
public string Title { get; set; }
public string HintText { get; set; }
public QuickCommand NavigateCommand { get; set; }

public NavigationTarget(string title, string hintText, QuickCommand navigateCommand)
{
Title = title;
HintText = hintText;
NavigateCommand = navigateCommand;
}
}

public class MainWindowViewModel : ReactiveObject, IScreen
{
public string Greeting => "Welcome to Avalonia!";
// The Router associated with this Screen.
// Required by the IScreen interface.
public RoutingState Router { get; } = new RoutingState();

public AdvancedObservableCollection<NavigationTarget> NavigationTargets { get; } = new();

private readonly ViewModelStore _viewModelStore = new ViewModelStore();

public MainWindowViewModel()
{
// Manage the routing state. Use the Router.Navigate.Execute
// command to navigate to different view models.
//
// Note, that the Navigate.Execute method accepts an instance
// of a view model, this allows you to pass parameters to
// your view models, or to reuse existing view models.
//
NavigationTargets.Add(
new NavigationTarget
(
title: "Accounts",
hintText: "Show Accounts",
new QuickCommand(() => NavigateTo(_viewModelStore.Get<AccountSwitcherViewModel>(this)))
)
);
NavigationTargets.Add(
new NavigationTarget
(
title: "Settings",
hintText: "Show Settings",
new QuickCommand(() => NavigateTo(_viewModelStore.Get<SettingsViewModel>(this)))
)
);

NavigateTo(_viewModelStore.Get<AccountSwitcherViewModel>(this));
}

private void NavigateTo(IRoutableViewModel viewModel)
{
if (IsViewAlreadyVisible(viewModel))
return;

Router.Navigate.Execute(viewModel);
}

public bool IsViewAlreadyVisible(IRoutableViewModel viewModel) => viewModel == Router.GetCurrentViewModel();
}
}
18 changes: 18 additions & 0 deletions SteamAccountManager.AvaloniaUI/ViewModels/SettingsViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using ReactiveUI;
using SteamAccountManager.AvaloniaUI.ViewModels.Commands;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace SteamAccountManager.AvaloniaUI.ViewModels
{
public class SettingsViewModel : RoutableViewModel
{
public SettingsViewModel(IScreen screen) : base(screen)
{
}
}
}
23 changes: 22 additions & 1 deletion SteamAccountManager.AvaloniaUI/ViewModels/ViewModelBase.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
using ReactiveUI;
using System;
using System.Windows.Input;

namespace SteamAccountManager.AvaloniaUI.ViewModels
{
public class ViewModelBase : ReactiveObject
public abstract class ViewModelBase : ReactiveObject
{
}

public abstract class RoutableViewModel : ViewModelBase, IRoutableViewModel
{
public ICommand NavigateBackCommand { get; }

public string? UrlPathSegment => Guid.NewGuid().ToString().Substring(0, 5);
public IScreen HostScreen { get; }

public RoutableViewModel(IScreen screen)
{
NavigateBackCommand = ReactiveCommand.Create(NavigateBack);
HostScreen = screen;
}

protected void NavigateBack()
{
HostScreen.Router.NavigateBack.Execute();
}
}
}
Loading

0 comments on commit 53c840a

Please sign in to comment.