Skip to content

Commit

Permalink
Merge branch 'main' into update-mnemonicdb
Browse files Browse the repository at this point in the history
  • Loading branch information
Al12rs committed Sep 24, 2024
2 parents 3ffe0f7 + a6d121f commit 1397ed3
Show file tree
Hide file tree
Showing 23 changed files with 395 additions and 220 deletions.
12 changes: 12 additions & 0 deletions docs/users/games/BaldursGate3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
!!! tip "Coming Soon"
Baldur's Gate 3 is not supported yet, but will be one of the next games we add to the app. Keep an eye on the [roadmap](https://trello.com/b/gPzMuIr3/nexus-mods-app-roadmap) for updates!

## Compatibility
This game can be managed via the app on the following operating systems and platforms. The application will automatically detect valid installations from supported game stores if possible.

|| :fontawesome-brands-windows: Windows | :fontawesome-brands-linux: Linux | :fontawesome-brands-apple: macOS |
|---|---|---|---|
| :fontawesome-brands-steam: [Steam](https://store.steampowered.com/app/1086940/Baldurs_Gate_3/) | :material-check-circle: | :material-check-circle: | :material-close-thick: |
| <img src="../../images/GOG.com_logo_white.svg" alt="GOG" width="14"/> [GOG](https://www.gog.com/en/game/baldurs_gate_iii) | :material-check-circle:[^1] | :material-close-thick:[^1] | :material-close-thick: |

[^1]: Offline backup installs from GOG.com cannot be detected automatically.
3 changes: 1 addition & 2 deletions docs/users/games/Cyberpunk2077.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Get information on potential issues in your loadout(s). [Learn more about Health

Diagnostics are shown in the following situations:

- A mod requires the REDmod DLC ([Steam](https://store.steampowered.com/app/2060310/Cyberpunk_2077_REDmod/)/[GOG](https://www.gog.com/game/cyberpunk_2077_redmod)/[Epic](https://store.epicgames.com/p/cyberpunk-2077)) but it is not installed.
- A mod is installed and requires any of the following dependencies by they are not installed or enabled:
- [Codeware](https://www.nexusmods.com/cyberpunk2077/mods/7780) - Detected by `.reds` files or Lua scripts with the `Codeware` global.
- [Virtual Atelier](https://www.nexusmods.com/cyberpunk2077/mods/2987) - Detected by `.reds` files uses hooks for this mod.
Expand All @@ -24,8 +25,6 @@ Diagnostics are shown in the following situations:

### Automated deployment for REDmods

!!! warning "This feature currently isn't available on Linux."

When mods using the official REDmod system are installed, it may be necessary to run the the REDmod tool. The app will detect when this is necessary and run it automatically before starting the game.

### Selective Game Backup
Expand Down
5 changes: 4 additions & 1 deletion docs/users/games/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ The following games are currently supported. Click on the game icon to learn mor
<img src="https://github.com/Nexus-Mods/NexusMods.App/blob/main/src/Games/NexusMods.Games.StardewValley/Resources/icon.png?raw=true" style="max-width:150px" title="Stardew Valley" alt="Stardew Valley">
</a>
<a href="./Cyberpunk2077">
<img src="https://github.com/Nexus-Mods/NexusMods.App/blob/main/src/Games/NexusMods.Games.RedEngine/Resources/Cyberpunk2077/icon.png?raw=true" style="max-width:150px" title="Stardew Valley" alt="Stardew Valley">
<img src="https://github.com/Nexus-Mods/NexusMods.App/blob/main/src/Games/NexusMods.Games.RedEngine/Resources/Cyberpunk2077/icon.png?raw=true" style="max-width:150px" title="Cyberpunk 2077" alt="Cyberpunk 2077">
</a>
<a href="./BaldursGate3">
<img src="https://github.com/Nexus-Mods/NexusMods.App/blob/main/src/Games/NexusMods.Games.Larian/BaldursGate3/Resources/icon.png?raw=true" style="max-width:150px" title="Baldur's Gate 3" alt="Baldur's Gate 3">
</a>


Expand Down
4 changes: 2 additions & 2 deletions docs/users/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

- This alpha software, meaning it is still very early in development and may have bugs or issues that could break your mod setup. We've done our best to patch up any major problems, but there will always be a few "gotchas" we haven't accounted for.
- The app only works on Windows (10+) or Linux. MacOS support is coming later!
- The current build only supports Stardew Valley on Steam or GOG.com - more games are planned to be added soon, so don't worry if you don't see your favourites yet!
- Please only use the app on a clean installation of Stardew Valley. This means removing SMAPI and any mods you have installed before managing it with the app. This is important as the state of the game folder will be the state the app will roll back to when mods are removed.
- The current build only supports a [limited number of games](./games/index.md) - more games are planned to be added soon, so don't worry if you don't see your favourites yet!
- Please only use the app on a clean, un-modded instance of any game installation. This means removing any mods you have installed before managing it with the app. The state of the game folder when you start modding the game will be the state the app will roll back to when mods are removed.
- As we release new versions you may be required to reset your loadout and start over. We'll do our best to avoid this though and it won't be a requirement in the final release!
- The app will work on Steam Deck but the experience isn't optimised yet, let us know how you get on!

1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ nav:
- users/games/index.md
- Stardew Valley: users/games/StardewValley.md
- Cyberpunk 2077: users/games/Cyberpunk2077.md
- Baldur's Gate 3: users/games/BaldursGate3.md
- Frequently Asked Questions:
- users/faq/index.md
- How to find the log files: users/faq/LogFiles.md
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,16 @@
<value>Wybierz pliki do zainstalowania z archiwum moda po lewej stronie.</value>
</data>
<data name="SelectLocationHeaderText_SELECT_INSTALL_LOCATION" xml:space="preserve">
<value>Wybierz ścieżkę instalacji</value>
<value>WYBIERZ ŚCIEŻKĘ INSTALACJI</value>
</data>
<data name="SelectLocationSubHeadingText_Select_where_to" xml:space="preserve">
<value>Wybierz scieżkę instalacji pliku/folderu moda.</value>
</data>
<data name="SuggestedHeaderText_SUGGESTED" xml:space="preserve">
<value>Sugerowane</value>
<value>SUGEROWANE</value>
</data>
<data name="AllFoldersAreaHeaderText_ALL_FOLDERS" xml:space="preserve">
<value>Wszystkie foldery</value>
<value>WSZYSTKIE FOLDERY</value>
</data>
<data name="AllFoldersAreaSubHeaderText_Select_from_full" xml:space="preserve">
<value>Wybierz z pełnej struktury folderów</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class CollectionCardDesignViewModel : AViewModel<ICollectionCardViewModel
public string Name => "Vanilla+ [Quality of Life]";
public Bitmap Image => new(AssetLoader.Open(new Uri("avares://NexusMods.App.UI/Assets/DesignTime/collection_tile_image.png")));
public string Summary => "1.6.8 This visual mod collection is designed to create a witchy medieval cottage aethetic experience for Stardew Valley, and Stardew Valley Expanded.";
public string Category => "Themed";
public string Category => "All-in-One \u2022 Fair and Balanced \u2022 Gameplay \u2022 Lore-friendly";
public int ModCount => 9;
public ulong EndorsementCount => 248;
public ulong DownloadCount => 30000;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<reactiveUi:ReactiveUserControl
<reactiveUi:ReactiveUserControl
x:TypeArguments="collections:ICollectionCardViewModel"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Expand All @@ -11,64 +11,87 @@
mc:Ignorable="d" d:DesignWidth="508" d:DesignHeight="288"
x:Class="NexusMods.App.UI.Pages.LibraryPage.Collections.CollectionCardView">
<Design.DataContext>
<collections:CollectionCardDesignViewModel/>
<collections:CollectionCardDesignViewModel />
</Design.DataContext>
<Border>
<Border x:Name="CardCollectionBorder">
<panels:FlexPanel x:Name="CardCollection">
<panels:FlexPanel x:Name="Container">
<Border x:Name="TileImageBorder">
<Image x:Name="TileImage"/>
</Border>
<panels:FlexPanel x:Name="TitleContainer">
<TextBlock x:Name="TitleText" Classes="BodyLGBold"/>
<panels:FlexPanel x:Name="CategoryTextWrapper">

<Border x:Name="ContainerBorder">
<panels:FlexPanel x:Name="Container">

<Border x:Name="TileImageBorder">
<Image x:Name="TileImage" />
</Border>

<panels:FlexPanel x:Name="TitleContainer">
<TextBlock x:Name="TitleText" />
<Border x:Name="CategoryTextBorder">
<TextBlock x:Name="CategoryText" Classes="BodySMNormal"/>
<TextBlock x:Name="CategoryText" />
</Border>
<panels:FlexPanel x:Name="SummaryTextFlexPanel">
<TextBlock x:Name="SummaryText" />
</panels:FlexPanel>
</panels:FlexPanel>
<TextBlock x:Name="SummaryText" Classes="BodyMDNormal" />
</panels:FlexPanel>
</panels:FlexPanel>
<panels:FlexPanel x:Name="Stats" Height="44" IsVisible="True">
<panels:FlexPanel x:Name="ModsPanel">
<icons:UnifiedIcon Classes="Mods" />
<TextBlock x:Name="ModCount" />
</panels:FlexPanel>
<panels:FlexPanel x:Name="EndorsementsPanel">
<icons:UnifiedIcon Classes="Check" />
<TextBlock x:Name="Endorsements" />
</panels:FlexPanel>
<panels:FlexPanel x:Name="DownloadsPanel">
<icons:UnifiedIcon Classes="Download"/>
<TextBlock x:Name="Downloads" />
</panels:FlexPanel>
<panels:FlexPanel x:Name="TotalSizePanel">
<icons:UnifiedIcon Classes="Disk" />
<TextBlock x:Name="TotalSize" />

</panels:FlexPanel>
<panels:FlexPanel x:Name="OverallRatingPanel">
<icons:UnifiedIcon Classes="Checkmark" />
<TextBlock x:Name="OverallRating" />
</Border>


<Border x:Name="StatsBorder">
<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 x:Name="ActionFooter">
<Border x:Name="ActionFooterBorder">
<panels:FlexPanel x:Name="ActionFooterPanel">
<Button x:Name="DownloadButton" Classes="Standard Secondary FooterButton">
</Border>


<Border x:Name="ActionFooterBorder">
<panels:FlexPanel x:Name="ActionFooter">

<panels:FlexPanel x:Name="ActionGroup">
<Button x:Name="DownloadButton" Classes="Standard Secondary" Height="28">
<panels:FlexPanel>
<icons:UnifiedIcon Classes="Download" />
<TextBlock Text="Continue Download" Classes="BodyMDNormal" />
<icons:UnifiedIcon Classes="ArrowRight" />
<icons:UnifiedIcon Value="{x:Static icons:IconValues.Download}" />
<TextBlock Text="Continue Download" />
<icons:UnifiedIcon Value="{x:Static icons:IconValues.ChevronRight}" />
</panels:FlexPanel>
</Button>
<Border x:Name="AvatarImageBorder">
<Image x:Name="AuthorAvatarImage" />
</Border>
<TextBlock x:Name="AuthorName" Classes="BodySMNormal" />
</panels:FlexPanel>
</Border>
</panels:FlexPanel>

<panels:FlexPanel x:Name="FooterLabels">
<panels:FlexPanel x:Name="UserLabel">
<Border x:Name="AvatarImageBorder">
<Image x:Name="AuthorAvatarImage" />
</Border>
<TextBlock x:Name="AuthorName" />
</panels:FlexPanel>
<panels:FlexPanel x:Name="ListingLabel">
<TextBlock x:Name="ListingLabelText" />
</panels:FlexPanel>
</panels:FlexPanel>

</panels:FlexPanel>
</Border>

</panels:FlexPanel>

</Border>
</reactiveUi:ReactiveUserControl>

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public CollectionCardViewModel(IConnection connection, RevisionId revision)
public string Name => _collection.Name;
public Bitmap Image => new(new MemoryStream(_collection.TileImage.ToArray()));
public string Summary => _collection.Summary;
public string Category => string.Join(" ", _collection.Tags.Select(t => t.Name));
public string Category => string.Join(" \u2022 ", _collection.Tags.Select(t => t.Name));
public int ModCount => (int)_revision.ModCount;
public ulong EndorsementCount => _collection.Endorsements;
public ulong DownloadCount => _revision.Downloads;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
<reactiveUi:ViewModelViewHost ViewModel="{CompiledBinding .}"
Margin="12"
Width="508"
Height="288"/>
Height="288"
ClipToBounds="False"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,23 @@ namespace NexusMods.App.UI.Pages.LibraryPage;
public class FakeParentLibraryItemModel : LibraryItemModel
{
public required IObservable<int> NumInstalledObservable { get; init; }
public required IObservable<IChangeSet<LibraryItem.ReadOnly, EntityId>> LibraryItemsObservable { get; init; }
public IObservable<IChangeSet<LibraryItem.ReadOnly, EntityId>> LibraryItemsObservable { get; }
protected ObservableHashSet<LibraryItem.ReadOnly> LibraryItems { get; set; } = [];

public override IReadOnlyCollection<LibraryItemId> GetLoadoutItemIds() => LibraryItems.Select(static item => item.LibraryItemId).ToArray();

private readonly IDisposable _modelActivationDisposable;
private readonly SerialDisposable _libraryItemsDisposable = new();
private readonly IDisposable _libraryItemsDisposable;

public FakeParentLibraryItemModel(LibraryItemId libraryItemId) : base(libraryItemId)
public FakeParentLibraryItemModel(LibraryItemId libraryItemId, IObservable<IChangeSet<LibraryItem.ReadOnly, EntityId>> libraryItemsObservable) : base(libraryItemId)
{
LibraryItemsObservable = libraryItemsObservable;

// NOTE(Al12rs): This needs to be set up even if model is never activated,
// as it is possible for items to get selected and interacted with without their model being activated
// (e.g. by quick scrolling to bottom with scrollbar and shift-selecting all items)
_libraryItemsDisposable = LibraryItemsObservable.OnUI().SubscribeWithErrorLogging(changeSet => LibraryItems.ApplyChanges(changeSet));

_modelActivationDisposable = WhenModelActivated(this, static (model, disposables) =>
{
model.NumInstalledObservable
Expand Down Expand Up @@ -54,11 +61,6 @@ public FakeParentLibraryItemModel(LibraryItemId libraryItemId) : base(libraryIte
}
})
.AddTo(disposables);

if (model._libraryItemsDisposable.Disposable is null)
{
model._libraryItemsDisposable.Disposable = model.LibraryItemsObservable.OnUI().SubscribeWithErrorLogging(changeSet => model.LibraryItems.ApplyChanges(changeSet));
}
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/NexusMods.App.UI/Pages/LibraryPage/LibraryView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
Classes.Tertiary="{Binding IsInstalledInLoadout.Value}"
>
<StackPanel Orientation="Horizontal">
<icons:UnifiedIcon Value="{x:Static icons:IconValues.Done}" IsVisible="{CompiledBinding IsInstalledInLoadout.Value}" />
<icons:UnifiedIcon Value="{x:Static icons:IconValues.Check}" IsVisible="{CompiledBinding IsInstalledInLoadout.Value}" />
<TextBlock Text="{CompiledBinding InstallText.Value}" />
</StackPanel>
</Button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using DynamicData;
using NexusMods.Abstractions.Library.Models;
using NexusMods.Abstractions.MnemonicDB.Attributes.Extensions;
using NexusMods.MnemonicDB.Abstractions;
using NexusMods.Paths;
using ObservableCollections;
using R3;
Expand All @@ -9,7 +11,8 @@ namespace NexusMods.App.UI.Pages.LibraryPage;
public class NexusModsModPageLibraryItemModel : FakeParentLibraryItemModel
{
private readonly IDisposable _modelActivationDisposable;
public NexusModsModPageLibraryItemModel() : base(default(LibraryItemId))
public NexusModsModPageLibraryItemModel(IObservable<IChangeSet<LibraryItem.ReadOnly, EntityId>> libraryItemsObservable)
: base(default(LibraryItemId), libraryItemsObservable)
{
_modelActivationDisposable = WhenModelActivated(this, static (model, disposables) =>
{
Expand Down
5 changes: 3 additions & 2 deletions src/NexusMods.App.UI/Pages/LocalFileDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,15 @@ public IObservable<IChangeSet<LibraryItemModel, EntityId>> ObserveNestedLibraryI
// NOTE(erri120): LocalFiles have only one child, this can only be 0 or 1.
var numInstalledObservable = linkedLoadoutItemsObservable.IsEmpty().Select(isEmpty => isEmpty ? 0 : 1);

var model = new FakeParentLibraryItemModel(libraryFile.Id)
var model = new FakeParentLibraryItemModel(
libraryFile.Id,
libraryItemsObservable: UIObservableExtensions.ReturnFactory(() => new ChangeSet<LibraryItem.ReadOnly, EntityId>([new Change<LibraryItem.ReadOnly, EntityId>(ChangeReason.Add, entityId, LibraryItem.Load(_connection.Db, entityId))])))
{
Name = libraryFile.AsLibraryItem().Name,
HasChildrenObservable = hasChildrenObservable,
ChildrenObservable = childrenObservable,
LinkedLoadoutItemsObservable = linkedLoadoutItemsObservable,
NumInstalledObservable = numInstalledObservable,
LibraryItemsObservable = UIObservableExtensions.ReturnFactory(() => new ChangeSet<LibraryItem.ReadOnly, EntityId>([new Change<LibraryItem.ReadOnly, EntityId>(ChangeReason.Add, entityId, LibraryItem.Load(_connection.Db, entityId))])),
};

model.CreatedAtDate.Value = libraryFile.GetCreatedAt();
Expand Down
Loading

0 comments on commit 1397ed3

Please sign in to comment.