Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial UI design for the collection install page #2080

Merged
merged 3 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
6 changes: 6 additions & 0 deletions src/NexusMods.App.UI/NexusMods.App.UI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,12 @@
<Compile Update="Pages\LibraryPage\Collections\CollectionsDesignViewModel.cs">
<DependentUpon>ICollectionsViewModel.cs</DependentUpon>
</Compile>
<Compile Update="Pages\CollectionDownload\CollectionDownloadDesignViewModel.cs">
<DependentUpon>ICollectionDownloadViewModel.cs</DependentUpon>
</Compile>
<Compile Update="Pages\LibraryPage\Collections\CollectionCardViewModel.cs">
<DependentUpon>ICollectionCardViewModel.cs</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using NexusMods.Abstractions.Jobs;
using NexusMods.Abstractions.NexusWebApi.Types;
using NexusMods.Paths;

namespace NexusMods.App.UI.Pages.CollectionDownload;

public class CollectionDownloadDesignViewModel : AViewModel<ICollectionDownloadViewModel>, ICollectionDownloadViewModel
{
public string Name => "Vanilla+ [Quality of Life]";
public CollectionSlug Slug { get; } = CollectionSlug.From("tckf0m");
public RevisionNumber RevisionNumber { get; } = RevisionNumber.From(6);
public string AuthorName => "Lowtonotolerance";

public string Summary =>
"Aims to improves vanilla gameplay while adding minimal additional content. Aims to improves vanilla gameplay while adding minimal additional content. Aims to improves vanilla gameplay while adding minimal additional content. Aims to improves vanilla gameplay while adding minimal additional content.";

public int ModCount => 9;
public int RequiredModCount => 7;
public int OptionalModCount => 2;
public int EndorsementCount => 248;
public int DownloadCount => 35_123;
public Size TotalSize { get; } = Size.From(76_123_456);
public Percent OverallRating { get; } = Percent.CreateClamped(0.82);
public Bitmap TileImage { get; } = new(AssetLoader.Open(new Uri("avares://NexusMods.App.UI/Assets/DesignTime/collection_tile_image.png")));

public Bitmap BackgroundImage { get; } = new(AssetLoader.Open(new Uri("avares://NexusMods.App.UI/Assets/DesignTime/header-background.webp")));

public string CollectionStatusText { get; } = "0 of 9 mods downloaded";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<reactiveUi:ReactiveUserControl
x:TypeArguments="collectionDownload:ICollectionDownloadViewModel"
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:reactiveUi="http://reactiveui.net"
xmlns:collectionDownload="clr-namespace:NexusMods.App.UI.Pages.CollectionDownload"
xmlns:panels="clr-namespace:Avalonia.Labs.Panels;assembly=Avalonia.Labs.Panels"
xmlns:icons="clr-namespace:NexusMods.Icons;assembly=NexusMods.Icons"
mc:Ignorable="d" d:DesignWidth="1620" d:DesignHeight="600"
x:Class="NexusMods.App.UI.Pages.CollectionDownload.CollectionDownloadView">
<Design.DataContext>
<collectionDownload:CollectionDownloadDesignViewModel />
</Design.DataContext>

<reactiveUi:ReactiveUserControl.Resources>
<MenuFlyout x:Key="CollectionMenuFlyout">
<MenuItem>
<MenuItem.Header>
<panels:FlexPanel>
<TextBlock>View on Nexus Mods</TextBlock>
</panels:FlexPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem>
<MenuItem.Header>
<panels:FlexPanel>
<TextBlock>View in Library</TextBlock>
</panels:FlexPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem>
<MenuItem.Header>
<panels:FlexPanel>
<TextBlock>Delete all downloads</TextBlock>
</panels:FlexPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem>
<MenuItem.Header>
<panels:FlexPanel>
<TextBlock>Delete Collection</TextBlock>
</panels:FlexPanel>
</MenuItem.Header>
</MenuItem>
</MenuFlyout>
</reactiveUi:ReactiveUserControl.Resources>

<panels:FlexPanel x:Name="Body">
<panels:FlexPanel x:Name="Frame758">
<panels:FlexPanel x:Name="Frame1452">
<Border x:Name="ContainerBorder">
<panels:FlexPanel x:Name="Container">
<Border x:Name="Image38Border">
<Image x:Name="Image38" />
</Border>
<panels:FlexPanel x:Name="ContainerInner">
<TextBlock Classes="TitleSMSemi">COLLECTION DOWNLOAD</TextBlock>
<TextBlock x:Name="Title" Classes="HeadingSMSemi"/>
<panels:FlexPanel x:Name="TagsPanel">
<TextBlock x:Name="Revision" />
<Border x:Name="AuthorAvatarBorder">
<Image x:Name="AuthorAvatar" />
</Border>
</panels:FlexPanel>
<TextBlock x:Name="AuthorName" />
<TextBlock x:Name="Summary"></TextBlock>
</panels:FlexPanel>
</panels:FlexPanel>
</Border>
</panels:FlexPanel>
<panels:FlexPanel x:Name="Frame1449">
<panels:FlexPanel x:Name="Stats" IsVisible="True">
<panels:FlexPanel x:Name="ModsPanel">
<icons:UnifiedIcon Value="{x:Static icons:IconValues.Mods}" />
<TextBlock x:Name="ModCount" />
</panels:FlexPanel>
<panels:FlexPanel x:Name="EndorsementsPanel">
<icons:UnifiedIcon Value="{x:Static icons:IconValues.ThumbUp}" />
<TextBlock x:Name="Endorsements" />
</panels:FlexPanel>
<panels:FlexPanel x:Name="DownloadsPanel">
<icons:UnifiedIcon Value="{x:Static icons:IconValues.Download}" />
<TextBlock x:Name="Downloads" />
</panels:FlexPanel>
<panels:FlexPanel x:Name="TotalSizePanel">
<icons:UnifiedIcon Value="{x:Static icons:IconValues.Size}" />
<TextBlock x:Name="TotalSize" />
</panels:FlexPanel>
<panels:FlexPanel x:Name="OverallRatingPanel">
<icons:UnifiedIcon Value="{x:Static icons:IconValues.CheckCircle}" />
<TextBlock x:Name="OverallRating" />
</panels:FlexPanel>
</panels:FlexPanel>
</panels:FlexPanel>
</panels:FlexPanel>
<panels:FlexPanel x:Name="ListHeaderRow">
<TextBlock x:Name="CollectionStatusText"></TextBlock>
<Button x:Name="InstallButton">Install</Button>
<Button x:Name="DownloadAllButton">DownloadAll</Button>
<Button x:Name="FlyoutMenuButton" Flyout="{StaticResource CollectionMenuFlyout}">...</Button>
</panels:FlexPanel>
<Expander>
<Expander.Header>
<panels:FlexPanel>
<TextBlock>Required</TextBlock>
<TextBlock x:Name="RequiredModsCount" />
</panels:FlexPanel>
</Expander.Header>
<TextBlock>TODO: Grid of mods will appear here</TextBlock>
</Expander>
<Expander>
<Expander.Header>
<panels:FlexPanel>
<TextBlock>Optional</TextBlock>
<TextBlock x:Name="OptionalModsCount" />
</panels:FlexPanel>
</Expander.Header>
<TextBlock>TODO: Grid of mods will appear here</TextBlock>
</Expander>
</panels:FlexPanel>

</reactiveUi:ReactiveUserControl>

Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System.Reactive.Disposables;
using Avalonia.Media;
using Avalonia.ReactiveUI;
using ReactiveUI;

namespace NexusMods.App.UI.Pages.CollectionDownload;

public partial class CollectionDownloadView : ReactiveUserControl<ICollectionDownloadViewModel>
{
public CollectionDownloadView()
{
InitializeComponent();

this.WhenActivated(d =>
{

// Uncomment this to enable the background image
/*
this.WhenAnyValue(view => view.ViewModel!.BackgroundImage)
.WhereNotNull()
.SubscribeWithErrorLogging(image => Body.Background = new ImageBrush { Source = image })
.DisposeWith(d);
*/

this.WhenAnyValue(view => view.ViewModel!.TileImage)
.WhereNotNull()
.SubscribeWithErrorLogging(image => Image38.Source = image)
.DisposeWith(d);

this.OneWayBind(ViewModel, vm => vm.Name, view => view.Title.Text)
.DisposeWith(d);

this.OneWayBind(ViewModel, vm => vm.AuthorName, view => view.AuthorName.Text)
.DisposeWith(d);

this.OneWayBind(ViewModel, vm => vm.Summary, view => view.Summary.Text)
.DisposeWith(d);

this.OneWayBind(ViewModel, vm => vm.ModCount, view => view.ModCount.Text)
.DisposeWith(d);

this.OneWayBind(ViewModel, vm => vm.EndorsementCount, view => view.Endorsements.Text)
.DisposeWith(d);

this.OneWayBind(ViewModel, vm => vm.DownloadCount, view => view.Downloads.Text)
.DisposeWith(d);

this.OneWayBind(ViewModel, vm => vm.TotalSize, view => view.TotalSize.Text)
.DisposeWith(d);

this.OneWayBind(ViewModel, vm => vm.OverallRating, view => view.OverallRating.Text)
.DisposeWith(d);

this.OneWayBind(ViewModel, vm => vm.RequiredModCount, view => view.RequiredModsCount.Text)
.DisposeWith(d);

this.OneWayBind(ViewModel, vm => vm.OptionalModCount, view => view.OptionalModsCount.Text)
.DisposeWith(d);

this.OneWayBind(ViewModel, vm => vm.CollectionStatusText, view => view.CollectionStatusText.Text)
.DisposeWith(d);

}
);
}


}

Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using Avalonia.Media.Imaging;
using NexusMods.Abstractions.Jobs;
using NexusMods.Abstractions.NexusWebApi.Types;
using NexusMods.Paths;

namespace NexusMods.App.UI.Pages.CollectionDownload;

public interface ICollectionDownloadViewModel : IViewModelInterface
{
/// <summary>
/// Name of the collection
/// </summary>
public string Name { get; }

/// <summary>
/// The collection's slug
/// </summary>
public CollectionSlug Slug { get; }

/// <summary>
/// The collection's revision number
/// </summary>
public RevisionNumber RevisionNumber { get; }

/// <summary>
/// Name of the author of the collection
/// </summary>
public string AuthorName { get; }

/// <summary>
/// The summary (short description) of the collection
/// </summary>
public string Summary { get; }

/// <summary>
/// Total number of mods in the collection
/// </summary>
public int ModCount { get; }

/// <summary>
/// The number of required mods in the collection
/// </summary>
public int RequiredModCount { get; }

/// <summary>
/// The number of optional mods in the collection
/// </summary>
public int OptionalModCount { get; }

/// <summary>
/// The number of endorsements the collection has
/// </summary>
public int EndorsementCount { get; }

/// <summary>
/// The number of downloads the collection has
/// </summary>
public int DownloadCount { get; }

/// <summary>
/// The size of the collection including all downloads and the collection file iteself
/// </summary>
public Size TotalSize { get; }

/// <summary>
/// The overall approval rating of the collection
/// </summary>
public Percent OverallRating { get; }

/// <summary>
/// The small tileable image of the collection
/// </summary>
public Bitmap TileImage { get; }

/// <summary>
/// The background banner image of the collection
/// </summary>
public Bitmap BackgroundImage { get; }

/// <summary>
/// A text representation of the collection's status, such as "Downloading", "Installing", "Ready to Play", etc.
/// </summary>
public string CollectionStatusText { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<StyleInclude Source="/Styles/Controls/FlexPanel/FlexPanelStyles.axaml"/>

<StyleInclude Source="/Styles/UserControls/Banners/InfoBannerStyles.axaml"/>
<StyleInclude Source="/Styles/UserControls/CollectionDownloadPage/CollectionDownloadPage.axaml"/>
<StyleInclude Source="/Styles/UserControls/CollectionCards/CollectionCardStyles.axaml"/>
<StyleInclude Source="/Styles/UserControls/Diagnostics/DiagnosticEntryStyles.axaml"/>
<StyleInclude Source="/Styles/UserControls/EmptyState/EmptyStateStyles.axaml"/>
Expand Down
Loading
Loading