Skip to content

Commit 631bea9

Browse files
authored
Use factories to create ViewModels (#256)
1 parent 10e6998 commit 631bea9

File tree

14 files changed

+84
-39
lines changed

14 files changed

+84
-39
lines changed

src/Angor/Avalonia/AngorApp/Core/CompositionRoot.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,31 +27,33 @@ public static MainViewModel CreateMainViewModel(Control control)
2727
{
2828
var topLevel = TopLevel.GetTopLevel(control);
2929
var launcher = new LauncherService(topLevel!.Launcher);
30+
var activeWallet = new ActiveWallet();
31+
3032
var uiServices = new UIServices(
3133
launcher,
3234
new DesktopDialog(),
3335
new NotificationService(new WindowNotificationManager(topLevel)
3436
{
3537
Position = NotificationPosition.BottomRight
36-
}));
38+
}), new ActiveWallet());
3739

3840
var walletStoreDesign = new WalletProviderDesign();
3941
var walletFactory = new WalletFactory(new WalletBuilderDesign(), uiServices);
40-
42+
4143
MainViewModel mainViewModel = null!;
4244

4345
var projectService = RealProjectService();
4446

4547
IEnumerable<SectionBase> sections =
4648
[
47-
new Section("Home", new HomeSectionViewModel(walletStoreDesign, uiServices, () => mainViewModel), "svg:/Assets/angor-icon.svg"),
49+
new Section("Home", () => new HomeSectionViewModel(activeWallet, uiServices, () => mainViewModel), "svg:/Assets/angor-icon.svg"),
4850
new Separator(),
49-
new Section("Wallet", new WalletSectionViewModel(walletFactory, walletStoreDesign, uiServices), "fa-wallet"),
50-
new Section("Browse", new NavigationViewModel(navigator => new BrowseSectionViewModel(walletStoreDesign, projectService, navigator, uiServices)), "fa-magnifying-glass"),
51-
new Section("Portfolio", new PortfolioSectionViewModel(), "fa-hand-holding-dollar"),
52-
new Section("Founder", new FounderSectionViewModel(projectService), "fa-money-bills"),
51+
new Section("Wallet", () => new WalletSectionViewModel(walletFactory, walletStoreDesign, uiServices), "fa-wallet"),
52+
new Section("Browse", () => new NavigationViewModel(navigator => new BrowseSectionViewModel(walletStoreDesign, projectService, navigator, uiServices)), "fa-magnifying-glass"),
53+
new Section("Portfolio", () => new PortfolioSectionViewModel(), "fa-hand-holding-dollar"),
54+
new Section("Founder", () => new FounderSectionViewModel(projectService), "fa-money-bills"),
5355
new Separator(),
54-
new Section("Settings", null, "fa-gear"),
56+
new Section("Settings", () => null, "fa-gear"),
5557
new CommandSection("Angor Hub", ReactiveCommand.CreateFromTask(() => uiServices.LauncherService.LaunchUri(Constants.AngorHubUri)), "fa-magnifying-glass") { IsPrimary = false }
5658
];
5759

src/Angor/Avalonia/AngorApp/Sections/Home/HomeSectionViewModel.cs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,16 @@
66

77
namespace AngorApp.Sections.Home;
88

9-
public class HomeSectionViewModel : ReactiveObject, IHomeSectionViewModel
9+
public class HomeSectionViewModel(
10+
IActiveWallet activeWallet,
11+
UIServices uiServices,
12+
Func<IMainViewModel> getMainViewModel)
13+
: ReactiveObject, IHomeSectionViewModel
1014
{
11-
private readonly IWalletProvider provider;
15+
//GoToFounderSection = ReactiveCommand.Create(() => getMainViewModel().GoToSection("Founder"));
1216

13-
public HomeSectionViewModel(IWalletProvider provider, UIServices uiServices, Func<IMainViewModel> getMainViewModel)
14-
{
15-
this.provider = provider;
16-
provider.GetWallet();
17-
GoToWalletSection = ReactiveCommand.Create(() => getMainViewModel().GoToSection("Wallet"));
18-
OpenHub = ReactiveCommand.CreateFromTask(() => uiServices.LauncherService.LaunchUri(Constants.AngorHubUri));
19-
//GoToFounderSection = ReactiveCommand.Create(() => getMainViewModel().GoToSection("Founder"));
20-
}
21-
22-
public bool IsWalletSetup => provider.GetWallet().HasValue;
23-
public ICommand GoToWalletSection { get; }
17+
public bool IsWalletSetup => activeWallet.Current.HasValue;
18+
public ICommand GoToWalletSection { get; } = ReactiveCommand.Create(() => getMainViewModel().GoToSection("Wallet"), activeWallet.HasWallet);
2419
public ICommand GoToFounderSection { get; }
25-
public ICommand OpenHub { get; }
20+
public ICommand OpenHub { get; } = ReactiveCommand.CreateFromTask(() => uiServices.LauncherService.LaunchUri(Constants.AngorHubUri));
2621
}

src/Angor/Avalonia/AngorApp/Sections/Shell/MainView.axaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<Interaction.Behaviors>
2020
<behaviors:NestedScrollViewerBehavior />
2121
</Interaction.Behaviors>
22-
<ContentControl MinWidth="300" MinHeight="300" Margin="10 10 10 10" Content="{Binding SelectedSection.ViewModel}" ClipToBounds="False" />
22+
<ContentControl MinWidth="300" MinHeight="300" Margin="10 10 10 10" Content="{Binding CurrentContent^}" ClipToBounds="False" />
2323
</ScrollViewer>
2424
</DockPanel>
2525
</UserControl>

src/Angor/Avalonia/AngorApp/Sections/Shell/MainViewModel.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Linq;
2+
using System.Reactive.Linq;
23
using AngorApp.Core;
34
using AngorApp.Services;
45
using ReactiveUI.SourceGenerators;
@@ -12,13 +13,15 @@ public partial class MainViewModel : ReactiveObject, IMainViewModel
1213
public MainViewModel(IEnumerable<SectionBase> sections, UIServices uiServices)
1314
{
1415
Sections = sections;
15-
SelectedSection = Sections.OfType<Section>().Skip(0).First();
16+
SelectedSection = Sections.OfType<Section>().First();
1617
OpenHub = ReactiveCommand.CreateFromTask(() => uiServices.LauncherService.LaunchUri(Constants.AngorHubUri));
18+
CurrentContent = this.WhenAnyValue(x => x.SelectedSection).Select(section => section.GetViewModel());
1719
}
1820

1921
public ReactiveCommand<Unit,Unit> OpenHub { get; }
2022

2123
public IEnumerable<SectionBase> Sections { get; }
24+
public IObservable<object> CurrentContent { get; }
2225

2326
public void GoToSection(string sectionName)
2427
{

src/Angor/Avalonia/AngorApp/Sections/Shell/MainViewModelDesign.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
using AngorApp.Sections.Browse;
21
using AngorApp.Sections.Home;
3-
using AngorApp.Sections.Wallet;
4-
using AngorApp.Services;
5-
using CSharpFunctionalExtensions;
6-
using Zafiro.Avalonia.Controls.Navigation;
72

83
namespace AngorApp.Sections.Shell;
94

@@ -13,7 +8,7 @@ public MainViewModelDesign()
138
{
149
Sections =
1510
[
16-
new Section("Home", new HomeSectionViewModelDesign(), "svg:/Assets/angor-icon.svg"),
11+
new Section("Home", () => new HomeSectionViewModelDesign(), "svg:/Assets/angor-icon.svg"),
1712
new Separator(),
1813
new Section("Wallet", null, "fa-wallet"),
1914
new Section("Browse", null, "fa-magnifying-glass"),
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
namespace AngorApp.Sections.Shell;
22

3-
public class Section(string name, object viewModel, object? icon = null) : SectionBase
3+
public class Section(string name, Func<object> getViewModel, object? icon = null) : SectionBase
44
{
55
public string Name { get; } = name;
6-
public object ViewModel { get; } = viewModel;
6+
public Func<object> GetViewModel { get; } = getViewModel;
77
public object? Icon { get; } = icon;
88
}

src/Angor/Avalonia/AngorApp/Sections/Wallet/CreateAndRecover/Create.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public async Task<Maybe<Result<IWallet>>> Start()
3434
.Then(prev => new SeedWordsConfirmationViewModel(prev.Words.Value))
3535
.Then(prev => new PassphraseCreateViewModel(prev.SeedWords))
3636
.Then(prev => new EncryptionPasswordViewModel(prev.SeedWords, prev.Passphrase!))
37-
.Then(prev => new SummaryAndCreationViewModel(prev.Passphrase, prev.SeedWords, prev.Password!, walletBuilder)
37+
.Then(prev => new SummaryAndCreationViewModel(prev.Passphrase, prev.SeedWords, prev.Password!, walletBuilder, uiServices)
3838
{
3939
IsRecovery = false,
4040
})

src/Angor/Avalonia/AngorApp/Sections/Wallet/CreateAndRecover/Recover.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public async Task<Maybe<Result<IWallet>>> Start()
3333
.Then(_ => new RecoverySeedWordsViewModel())
3434
.Then(seedwords => new PassphraseRecoverViewModel(seedwords.SeedWords))
3535
.Then(passphrase => new EncryptionPasswordViewModel(passphrase.SeedWords, passphrase.Passphrase!))
36-
.Then(passphrase => new SummaryAndCreationViewModel(passphrase.Passphrase, passphrase.SeedWords, passphrase.Password!, walletBuilder)
36+
.Then(passphrase => new SummaryAndCreationViewModel(passphrase.Passphrase, passphrase.SeedWords, passphrase.Password!, walletBuilder, uiServices)
3737
{
3838
IsRecovery = true
3939
})

src/Angor/Avalonia/AngorApp/Sections/Wallet/CreateAndRecover/Steps/SeedWordsGeneration/SeedWordsView.axaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
<Panel>
1515
<seedWordsGeneration:Empty IsVisible="{Binding Words.HasNoValue}" />
16-
<seedWordsGeneration:GeneratedWords IsVisible="{Binding Words.HasValue}" />
16+
<!-- <seedWordsGeneration:GeneratedWords IsVisible="{Binding Words.HasValue}" /> -->
1717
</Panel>
1818

1919
</UserControl>

src/Angor/Avalonia/AngorApp/Sections/Wallet/CreateAndRecover/Steps/SummaryAndCreation/SummaryAndCreationViewModel.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
using System.Threading.Tasks;
12
using Angor.UI.Model;
3+
using AngorApp.Services;
24
using CSharpFunctionalExtensions;
35
using ReactiveUI.SourceGenerators;
46
using ReactiveUI.Validation.Helpers;
@@ -10,14 +12,24 @@ namespace AngorApp.Sections.Wallet.CreateAndRecover.Steps.SummaryAndCreation;
1012

1113
public partial class SummaryAndCreationViewModel : ReactiveValidationObject, IStep, ISummaryAndCreationViewModel
1214
{
15+
private readonly IWalletBuilder walletBuilder;
16+
private readonly UIServices uiServices;
1317
[ObservableAsProperty] private IWallet? wallet;
1418

15-
public SummaryAndCreationViewModel(Maybe<string> passphrase, SeedWords seedwords, string encryptionKey, IWalletBuilder walletBuilder)
19+
public SummaryAndCreationViewModel(Maybe<string> passphrase, SeedWords seedwords, string encryptionKey, IWalletBuilder walletBuilder, UIServices uiServices)
1620
{
21+
this.walletBuilder = walletBuilder;
22+
this.uiServices = uiServices;
1723
Passphrase = passphrase;
18-
CreateWallet = ReactiveCommand.CreateFromTask(() => walletBuilder.Create(seedwords, passphrase, encryptionKey));
24+
CreateWallet = ReactiveCommand.CreateFromTask(() => CreateAndSet(seedwords, encryptionKey, encryptionKey));
1925
walletHelper = CreateWallet.Successes().ToProperty(this, x => x.Wallet);
2026
}
27+
28+
private Task<Result<IWallet>> CreateAndSet(SeedWords seedwords, Maybe<string> passphrase, string encryptionKey)
29+
{
30+
return walletBuilder.Create(seedwords, passphrase, encryptionKey)
31+
.Tap(w => uiServices.ActiveWallet.Current = w.AsMaybe());
32+
}
2133

2234
public string CreateWalletText => IsRecovery ? "Recover Wallet" : "Create Wallet";
2335
public string CreatingWalletText => IsRecovery ? "Recovering Wallet..." : "Creating Wallet...";

0 commit comments

Comments
 (0)