Skip to content

Commit

Permalink
Complete Browse section (#225)
Browse files Browse the repository at this point in the history
* Refine the invest flow

* Wip

* Add Invest wizard

* Added Nostr part

* Add gauges

* Fix header

* Completed invest wizard

* Refine use of IProject

* Complete Browse flow

* Add Launcher Service

* Improve more

* Polish

* More polish

* Use projects + polishing
  • Loading branch information
SuperJMN authored Dec 18, 2024
1 parent 4b967c4 commit 7690592
Show file tree
Hide file tree
Showing 59 changed files with 1,087 additions and 239 deletions.
48 changes: 26 additions & 22 deletions src/Angor/Avalonia/AngorApp.Desktop/AngorApp.Desktop.csproj
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<!--If you are willing to use Windows/MacOS native APIs you will need to create 3 projects.
One for Windows with net9.0-windows TFM, one for MacOS with net9.0-macos and one with net9.0 TFM for Linux.-->
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
</PropertyGroup>
<PropertyGroup>
<OutputType>WinExe</OutputType>
<!--If you are willing to use Windows/MacOS native APIs you will need to create 3 projects.
One for Windows with net9.0-windows TFM, one for MacOS with net9.0-macos and one with net9.0 TFM for Linux.-->
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<Company>Angor</Company>
<Product>Angor</Product>
<AssemblyName>Angor</AssemblyName>
<RootNamespace>Angor</RootNamespace>
</PropertyGroup>

<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Avalonia.Desktop" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Include="Avalonia.Diagnostics" >
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia.Desktop"/>
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Include="Avalonia.Diagnostics">
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\AngorApp\AngorApp.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AngorApp\AngorApp.csproj"/>
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion src/Angor/Avalonia/AngorApp.Desktop/app.manifest
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<!-- This manifest is used on Windows only.
Don't remove it as it might cause problems with window transparency and embedded controls.
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
<assemblyIdentity version="1.0.0.0" name="AngorApp.Desktop"/>
<assemblyIdentity version="1.0.0.0" name="Angor"/>

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
Expand Down
9 changes: 5 additions & 4 deletions src/Angor/Avalonia/AngorApp/AngorApp.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
Expand All @@ -23,15 +23,16 @@
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference>
<PackageReference Include="Avalonia.Xaml.Behaviors"/>
<PackageReference Include="Humanizer.Core" />
<PackageReference Include="Deadpikle.AvaloniaProgressRing"/>
<PackageReference Include="Humanizer.Core"/>
<PackageReference Include="Projektanker.Icons.Avalonia.FontAwesome"/>
<PackageReference Include="ReactiveUI"/>
<PackageReference Include="ReactiveUI.SourceGenerators">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Zafiro.Avalonia" />
<PackageReference Include="Zafiro.Avalonia"/>
<PackageReference Include="Zafiro.Avalonia.Dialogs"/>

</ItemGroup>

</Project>
10 changes: 7 additions & 3 deletions src/Angor/Avalonia/AngorApp/App.axaml
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AngorApp"
xmlns:misc="clr-namespace:Zafiro.Avalonia.Misc;assembly=Zafiro.Avalonia"
x:Class="AngorApp.App"
RequestedThemeVariant="Light">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->

<Application.DataTemplates>

<local:ViewLocator />
<misc:NamingConventionViewLocator />
<misc:DataTemplateInclude Source="avares://Zafiro.Avalonia/Controls/Wizards/WizardTemplate.axaml" />

</Application.DataTemplates>

<Application.Styles>
<FluentTheme />
<StyleInclude Source="avares://Zafiro.Avalonia/Styles.axaml" />
<StyleInclude Source="avares://Zafiro.Avalonia.Dialogs/Styles.axaml" />
<StyleInclude Source="Styles.axaml" />
<StyleInclude Source="avares://AsyncImageLoader.Avalonia/AdvancedImage.axaml" />
<StyleInclude Source="Controls/Pane.axaml" />

<StyleInclude Source="Controls/Dialog.axaml" />
<StyleInclude Source="avares://AvaloniaProgressRing/Styles/ProgressRing.xaml" />
</Application.Styles>

<Application.Resources>
Expand All @@ -28,6 +31,7 @@
<MergeResourceInclude Source="Controls/Header.axaml" />
<MergeResourceInclude Source="Controls/Frame.axaml" />
<MergeResourceInclude Source="Controls/SectionItem.axaml" />
<MergeResourceInclude Source="Icons.axaml" />
</ResourceDictionary.MergedDictionaries>

</ResourceDictionary>
Expand Down
Binary file not shown.
14 changes: 14 additions & 0 deletions src/Angor/Avalonia/AngorApp/Common/SuccessView.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<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"
xmlns:avalonia="https://github.com/projektanker/icons.avalonia"
xmlns:details="clr-namespace:AngorApp.Sections.Browse.Details"
xmlns:common="clr-namespace:AngorApp.Common"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AngorApp.Common.SuccessView" x:DataType="common:SuccessViewModel">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<avalonia:Icon Value="fa-solid fa-check" Foreground="Green" FontSize="20" Margin="10" />
<TextBlock Text="{Binding Message}" VerticalAlignment="Center" />
</StackPanel>
</UserControl>
13 changes: 13 additions & 0 deletions src/Angor/Avalonia/AngorApp/Common/SuccessView.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;

namespace AngorApp.Common;

public partial class SuccessView : UserControl
{
public SuccessView()
{
InitializeComponent();
}
}
18 changes: 18 additions & 0 deletions src/Angor/Avalonia/AngorApp/Common/SuccessViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Reactive.Linq;
using Zafiro.Avalonia.Controls.Wizards.Builder;

namespace AngorApp.Common;

public class SuccessViewModel : IStep
{
public string Message { get; }

public SuccessViewModel(string message)
{
Message = message;
}

public IObservable<bool> IsValid => Observable.Return(false);
public IObservable<bool> IsBusy => Observable.Return(false);
public bool AutoAdvance => false;
}
21 changes: 16 additions & 5 deletions src/Angor/Avalonia/AngorApp/CompositionRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
using AngorApp.Sections.Shell;
using AngorApp.Sections.Wallet;
using AngorApp.Services;
using Avalonia.Controls.Notifications;
using Zafiro.Avalonia.Dialogs;
using Zafiro.Avalonia.Dialogs.SizingAlgorithms;
using Zafiro.Avalonia.Notifications;
using Zafiro.Avalonia.Services;
using Separator = AngorApp.Sections.Shell.Separator;

namespace AngorApp;
Expand All @@ -16,21 +21,27 @@ public static MainViewModel CreateMainViewModel(Control control)
{
var topLevel = TopLevel.GetTopLevel(control);
var launcher = new LauncherService(topLevel!.Launcher);
var uiServices = new UIServices(launcher);

var uiServices = new UIServices(
launcher,
new DesktopDialog(algorithm: new AlternateSizingAlgorithm()),
new NotificationService(new WindowNotificationManager(topLevel)
{
Position = NotificationPosition.BottomRight,
}));

IEnumerable<SectionBase> sections =
[
new Section("Home", new HomeViewModel(), "svg:/Assets/angor-icon.svg"),
new Separator(),
new Section("Wallet", new WalletViewModel(), "fa-wallet"),
new Section("Browse", new NavigationViewModel(navigator => new BrowseViewModel(navigator, uiServices)), "fa-magnifying-glass"),
new Section("Browse", new NavigationViewModel(navigator => new BrowseViewModel(() => new WalletDesign(), navigator, uiServices)), "fa-magnifying-glass"),
new Section("Portfolio", new PortfolioViewModel(), "fa-hand-holding-dollar"),
new Section("Founder", new FounderViewModel(), "fa-money-bills"),
new Separator(),
new Section("Settings", new WalletViewModel(), "fa-gear"),
new CommandSection("Angor Hub", ReactiveCommand.CreateFromTask(() => uiServices.LauncherService.Launch(new Uri("https://www.angor.io"))) , "fa-magnifying-glass") { IsPrimary = false }
new CommandSection("Angor Hub", ReactiveCommand.CreateFromTask(() => uiServices.LauncherService.LaunchUri(new Uri("https://www.angor.io"))), "fa-magnifying-glass") { IsPrimary = false }
];

return new MainViewModel(sections, uiServices);
}
}
74 changes: 74 additions & 0 deletions src/Angor/Avalonia/AngorApp/Controls/Dialog.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:z="clr-namespace:Zafiro.Avalonia.Dialogs;assembly=Zafiro.Avalonia.Dialogs"
xmlns:views="clr-namespace:Zafiro.Avalonia.Dialogs.Views;assembly=Zafiro.Avalonia.Dialogs"
xmlns:generic="clr-namespace:System.Collections.Generic;assembly=System.Collections"
xmlns:angorApp="clr-namespace:AngorApp"
xmlns:amount="clr-namespace:AngorApp.Sections.Browse.Details.Invest.Amount"
xmlns:controls="clr-namespace:AngorApp.Controls">
<Design.PreviewWith>
<z:DialogView Width="600" Height="500">
<z:DialogView.Content>
<amount:AmountView VerticalAlignment="Center" />
</z:DialogView.Content>
<z:DialogView.Options>
<generic:List x:TypeArguments="z:IOption">
<controls:OptionDesign Title="Next" />
<controls:OptionDesign Title="Cancel" />
</generic:List>
</z:DialogView.Options>
</z:DialogView>
</Design.PreviewWith>

<Style Selector="z|DialogViewContainer.Desktop">
<Setter Property="Template">
<ControlTemplate>
<Border Background="{StaticResource Level1}" Padding="20">
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
</ControlTemplate>
</Setter>
</Style>

<Style Selector="z|DialogView">
<Setter Property="OptionsPanelHeight" Value="30" />
<Setter Property="Template">
<ControlTemplate TargetType="z:DialogView">
<Border Background="{StaticResource Level1}">
<DockPanel x:DataType="z:DialogViewModel" x:CompileBindings="True">
<DockPanel.DataTemplates>
<DataTemplate DataType="z:MessageDialogViewModel">
<views:MessageDialogView />
</DataTemplate>
</DockPanel.DataTemplates>
<ItemsControl Margin="0 10 0 0" HorizontalAlignment="Right" ItemsSource="{TemplateBinding Options}"
DockPanel.Dock="Bottom">
<ItemsControl.ItemContainerTheme>
<ControlTheme TargetType="ContentPresenter">
<Setter x:DataType="z:IOption" Property="IsVisible" Value="{Binding IsVisible^}" />
</ControlTheme>
</ItemsControl.ItemContainerTheme>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Spacing="8" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="z:IOption">
<Button HorizontalContentAlignment="Center"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Command="{Binding Command}"
IsDefault="{Binding IsDefault}"
IsCancel="{Binding IsCancel}"
Content="{Binding Title}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ContentControl Margin="0 4" Content="{TemplateBinding Content}" />
</DockPanel>
</Border>
</ControlTemplate>
</Setter>
</Style>
</Styles>
12 changes: 7 additions & 5 deletions src/Angor/Avalonia/AngorApp/Controls/Frame.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,26 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:navigation="clr-namespace:Zafiro.Avalonia.Controls.Navigation;assembly=Zafiro.Avalonia"
xmlns:avalonia="https://github.com/projektanker/icons.avalonia">

<Design.PreviewWith>
<navigation:Frame Width="200" Height="200" />
</Design.PreviewWith>

<ControlTheme TargetType="navigation:Frame" x:Key="{x:Type navigation:Frame}">
<Setter Property="ClipToBounds" Value="False" />
<Setter Property="Template">
<ControlTemplate>
<Panel>
<ScrollViewer>
<ContentControl ClipToBounds="False" Content="{Binding $parent[navigation:Frame].Navigator.Content}" />
</ScrollViewer>
<Button Background="Transparent" VerticalAlignment="Top" HorizontalAlignment="Left"
Command="{Binding $parent[navigation:Frame].Navigator.Back}"
DockPanel.Dock="Top">
IsVisible="{Binding $self.IsEffectivelyEnabled}">
<avalonia:Icon FontSize="28" Value="fa-solid fa-arrow-left" />
</Button>
<ContentControl ClipToBounds="False" Content="{Binding $parent[navigation:Frame].Navigator.Content}" />
</Panel>
</ControlTemplate>
</Setter>
</ControlTheme>
</ResourceDictionary>
</ResourceDictionary>
2 changes: 1 addition & 1 deletion src/Angor/Avalonia/AngorApp/Controls/Header.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</Design.PreviewWith>

<ControlTheme TargetType="c:Header" x:Key="{x:Type c:Header}">
<Setter Property="IconMargin" Value="10, 20" />
<Setter Property="IconMargin" Value="20, 20" />
<Setter Property="Template">
<ControlTemplate>
<Panel>
Expand Down
14 changes: 13 additions & 1 deletion src/Angor/Avalonia/AngorApp/Controls/MiscConverters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,21 @@ public static class MiscConverters
public static readonly FuncValueConverter<SectionBase, bool> IsActivatable = new(sectionBase => sectionBase is not Separator);

public static readonly FuncValueConverter<bool, Dock> IsPrimaryToDock = new(isPrimary => isPrimary ? Dock.Top : Dock.Bottom);

public static readonly FuncValueConverter<DateTimeOffset, string> TimeLeft = new(offset =>
{
Humanizer.Configuration.Configurator.DateTimeHumanizeStrategy = new DefaultDateTimeHumanizeStrategy();
return offset.Humanize(dateToCompareAgainst: DateTimeOffset.Now);
});

public static readonly FuncValueConverter<TimeSpan, string> HumanizeTimeSpan = new(offset => offset.Humanize());

public static readonly FuncValueConverter<bool, double> BoolToOpacity = new(b => b ? 1 : 0);

public static FuncValueConverter<string, string> HubProfile = new((value) =>
{
return "https://hub.angor.io/profile/" + value;
});

public static string BigBtcFormat = "{0} BTC";
public static string AmountBtcFormat = "0.0000 0000 BTC";
}
14 changes: 14 additions & 0 deletions src/Angor/Avalonia/AngorApp/Controls/OptionDesign.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Reactive.Linq;
using Zafiro.Avalonia.Commands;
using Zafiro.Avalonia.Dialogs;

namespace AngorApp.Controls;

public class OptionDesign : IOption
{
public string Title { get; set; }
public IEnhancedCommand Command { get; }
public bool IsDefault { get; set; }
public bool IsCancel { get; set; }
public IObservable<bool> IsVisible { get; } = Observable.Return(true);
}
Loading

0 comments on commit 7690592

Please sign in to comment.