diff --git a/Nebula.Launcher/ServerListProviders/FavoriteServerListProvider.cs b/Nebula.Launcher/ServerListProviders/FavoriteServerListProvider.cs index 82dece3..81e0032 100644 --- a/Nebula.Launcher/ServerListProviders/FavoriteServerListProvider.cs +++ b/Nebula.Launcher/ServerListProviders/FavoriteServerListProvider.cs @@ -42,11 +42,6 @@ public sealed partial class FavoriteServerListProvider : IServerListProvider servers.Add(new AddFavoriteButton(ServiceProvider)); } - public void AddFavorite(ServerEntryViewModel entryViewModel) - { - AddFavorite(entryViewModel.Address); - } - public void AddFavorite(RobustUrl robustUrl) { var servers = GetFavoriteEntries(); diff --git a/Nebula.Launcher/ServerListProviders/HubServerListProvider.cs b/Nebula.Launcher/ServerListProviders/HubServerListProvider.cs index 50d9f25..be516a2 100644 --- a/Nebula.Launcher/ServerListProviders/HubServerListProvider.cs +++ b/Nebula.Launcher/ServerListProviders/HubServerListProvider.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using Avalonia.Collections; using Avalonia.Controls; +using Avalonia.Layout; using Avalonia.Threading; using Nebula.Launcher.Services; using Nebula.Launcher.ViewModels.Pages; @@ -116,6 +117,7 @@ public sealed class LoadingServerEntry : Label, IListEntryModelView { public LoadingServerEntry() { + HorizontalAlignment = HorizontalAlignment.Center; Content = LocalizationService.GetString("server-list-loading"); } public void Dispose() diff --git a/Nebula.Launcher/ServerListProviders/TestServerList.cs b/Nebula.Launcher/ServerListProviders/TestServerList.cs index a942fef..5e04f02 100644 --- a/Nebula.Launcher/ServerListProviders/TestServerList.cs +++ b/Nebula.Launcher/ServerListProviders/TestServerList.cs @@ -13,8 +13,8 @@ public sealed class TestServerList : IServerListProvider AvaloniaList exceptions) { - servers.Add(new ServerEntryViewModel()); - servers.Add(new ServerEntryViewModel()); + //servers.Add(new ServerEntryViewModel()); + //servers.Add(new ServerEntryViewModel()); exceptions.Add(new Exception("Oh no!")); } diff --git a/Nebula.Launcher/Services/GameRunnerService.cs b/Nebula.Launcher/Services/GameRunnerService.cs index 72d285e..74247a9 100644 --- a/Nebula.Launcher/Services/GameRunnerService.cs +++ b/Nebula.Launcher/Services/GameRunnerService.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using Nebula.Launcher.Models; using Nebula.Launcher.ProcessHelper; +using Nebula.Launcher.ServerListProviders; using Nebula.Launcher.ViewModels; using Nebula.Launcher.ViewModels.Pages; using Nebula.Launcher.ViewModels.Popup; @@ -23,6 +24,10 @@ public class GameRunnerService private readonly InstanceRunningContainer _instanceRunningContainer; private readonly AccountInfoViewModel _accountInfoViewModel; private readonly ServerViewContainer _container; + private readonly MainViewModel _mainViewModel; + private readonly FavoriteServerListProvider _favoriteServerListProvider; + private readonly RestService _restService; + private readonly CancellationService _cancellationService; private readonly ILogger _logger; private readonly Dictionary _robustUrls = new(); @@ -34,7 +39,11 @@ public class GameRunnerService GameRunnerPreparer gameRunnerPreparer, InstanceRunningContainer instanceRunningContainer, AccountInfoViewModel accountInfoViewModel, - ServerViewContainer container) + ServerViewContainer container, + MainViewModel mainViewModel, + FavoriteServerListProvider favoriteServerListProvider, + RestService restService, + CancellationService cancellationService) { _popupMessageService = popupMessageService; _viewHelperService = viewHelperService; @@ -42,6 +51,10 @@ public class GameRunnerService _instanceRunningContainer = instanceRunningContainer; _accountInfoViewModel = accountInfoViewModel; _container = container; + _mainViewModel = mainViewModel; + _favoriteServerListProvider = favoriteServerListProvider; + _restService = restService; + _cancellationService = cancellationService; _logger = debugService.GetLogger("GameRunnerService"); _instanceRunningContainer.IsRunningChanged += IsRunningChanged; @@ -65,21 +78,44 @@ public class GameRunnerService } } - public void StopInstance(ServerEntryViewModel serverEntryViewModel) + public void StopInstance(RobustUrl robustUrl) { - if (_robustKeys.TryGetValue(serverEntryViewModel.Address, out var instanceKey)) + if (_robustKeys.TryGetValue(robustUrl, out var instanceKey)) { _instanceRunningContainer.Stop(instanceKey); } } - public void ReadInstanceLog(ServerEntryViewModel serverEntryViewModel) + public void ReadInstanceLog(RobustUrl robustUrl) { - if (_robustKeys.TryGetValue(serverEntryViewModel.Address, out var instanceKey)) + if (_robustKeys.TryGetValue(robustUrl, out var instanceKey)) { _instanceRunningContainer.Popup(instanceKey); } } + + public void OpenContentViewer(RobustUrl robustUrl) + { + _mainViewModel.RequirePage().Go(robustUrl, ContentPath.Empty); + } + + public void AddFavorite(RobustUrl robustUrl) + { + _favoriteServerListProvider.AddFavorite(robustUrl); + } + + public void RemoveFavorite(RobustUrl robustUrl) + { + _favoriteServerListProvider.RemoveFavorite(robustUrl); + } + + public void EditName(RobustUrl robustUrl, string? oldName) + { + var popup = _viewHelperService.GetViewModel(); + popup.IpInput = robustUrl.ToString(); + popup.NameInput = oldName ?? string.Empty; + _popupMessageService.Popup(popup); + } public async Task RunInstanceAsync(ServerEntryViewModel serverEntryViewModel, CancellationToken cancellationToken, bool ignoreLoginCredentials = false) { @@ -117,4 +153,10 @@ public class GameRunnerService return null; } } + + public ServerEntryViewModel GetServerEntry(RobustUrl url, string customName, ServerStatus serverStatus) + { + return new ServerEntryViewModel(_restService, _cancellationService, this) + .WithData(url, customName, serverStatus); + } } \ No newline at end of file diff --git a/Nebula.Launcher/ViewModels/Pages/ServerOverviewModel.cs b/Nebula.Launcher/ViewModels/Pages/ServerOverviewModel.cs index 8451c59..2e9bf25 100644 --- a/Nebula.Launcher/ViewModels/Pages/ServerOverviewModel.cs +++ b/Nebula.Launcher/ViewModels/Pages/ServerOverviewModel.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using System.Runtime.InteropServices; using System.Threading; using Avalonia.Controls; using CommunityToolkit.Mvvm.ComponentModel; @@ -59,7 +60,7 @@ public partial class ServerOverviewModel : ViewModelBase { if(CurrentServerList.Provider is FavoriteServerListProvider favoriteServerListProvider) { - UpdateRequired(); + RefreshProvider(); } } @@ -107,6 +108,11 @@ public partial class ServerOverviewModel : ViewModelBase public void UpdateRequired() { ServerViewContainer.Clear(); + RefreshProvider(); + } + + private void RefreshProvider() + { CurrentServerList.ClearProvider(); CurrentServerList.RefreshFromProvider(); } @@ -152,8 +158,8 @@ public sealed class ServerViewContainer { foreach (var (_, weakRef) in _entries) { - if (weakRef.TryGetTarget(out var value)) - value.Dispose(); + if (weakRef.TryGetTarget(out var value) && value is IDisposable disposable) + disposable.Dispose(); } _entries.Clear(); @@ -191,7 +197,6 @@ public sealed class ServerViewContainer if (serverStatus is not null) { - //entry = new ExampleEntry(serverStatus.Name); entry = _viewHelperService .GetViewModel() .WithData(url, customName, serverStatus); @@ -296,7 +301,7 @@ public sealed class ServerViewContainer } } -public interface IListEntryModelView : IDisposable +public interface IListEntryModelView { } diff --git a/Nebula.Launcher/ViewModels/ServerCompoundEntryModelView.cs b/Nebula.Launcher/ViewModels/ServerCompoundEntryModelView.cs index 93be233..197d57b 100644 --- a/Nebula.Launcher/ViewModels/ServerCompoundEntryModelView.cs +++ b/Nebula.Launcher/ViewModels/ServerCompoundEntryModelView.cs @@ -130,9 +130,4 @@ public sealed partial class ServerCompoundEntryViewModel : if(CurrentEntry is IFilterConsumer filterConsumer) filterConsumer.ProcessFilter(serverFilter); } - - public void Dispose() - { - CurrentEntry?.Dispose(); - } } \ No newline at end of file diff --git a/Nebula.Launcher/ViewModels/ServerEntryViewModel.cs b/Nebula.Launcher/ViewModels/ServerEntryViewModel.cs index b66a10d..378dab6 100644 --- a/Nebula.Launcher/ViewModels/ServerEntryViewModel.cs +++ b/Nebula.Launcher/ViewModels/ServerEntryViewModel.cs @@ -18,16 +18,25 @@ using Nebula.Shared.ViewHelper; namespace Nebula.Launcher.ViewModels; [ViewModelRegister(typeof(ServerEntryView), false)] -[ConstructGenerator] -public sealed partial class ServerEntryViewModel : ViewModelBase, IFilterConsumer, IListEntryModelView, IFavoriteEntryModelView, IEntryNameHolder, IRunningSignalConsumer +public sealed partial class ServerEntryViewModel( + RestService restService, + CancellationService cancellationService, + GameRunnerService gameRunnerService + ) : + ViewModelBase, + IFilterConsumer, + IListEntryModelView, + IFavoriteEntryModelView, + IEntryNameHolder, + IRunningSignalConsumer { [ObservableProperty] private string _description = "Fetching info..."; [ObservableProperty] private bool _expandInfo; [ObservableProperty] private bool _isFavorite; [ObservableProperty] private bool _isVisible; [ObservableProperty] private bool _runVisible = true; - [ObservableProperty] private string _realName; - + [ObservableProperty] private string _realName = string.Empty; + public string? Name { get => RealName; @@ -37,13 +46,6 @@ public sealed partial class ServerEntryViewModel : ViewModelBase, IFilterConsume private ServerInfo? _serverInfo; public RobustUrl Address { get; private set; } - [GenerateProperty] private CancellationService CancellationService { get; } = default!; - [GenerateProperty] private PopupMessageService PopupMessageService { get; } = default!; - [GenerateProperty] private ViewHelperService ViewHelperService { get; } = default!; - [GenerateProperty] private RestService RestService { get; } = default!; - [GenerateProperty] private MainViewModel MainViewModel { get; } = default!; - [GenerateProperty] private FavoriteServerListProvider FavoriteServerListProvider { get; } = default!; - [GenerateProperty] private GameRunnerService GameRunnerService { get; } = default!; public ServerStatus Status { get; private set; } = new( @@ -69,7 +71,7 @@ public sealed partial class ServerEntryViewModel : ViewModelBase, IFilterConsume try { - _serverInfo = await RestService.GetAsync(Address.InfoUri, CancellationService.Token); + _serverInfo = await restService.GetAsync(Address.InfoUri, cancellationService.Token); } catch (Exception e) { @@ -124,46 +126,43 @@ public sealed partial class ServerEntryViewModel : ViewModelBase, IFilterConsume return this; } - public void EditName() - { - var popup = ViewHelperService.GetViewModel(); - popup.IpInput = Address.ToString(); - popup.NameInput = Name ?? string.Empty; - PopupMessageService.Popup(popup); - } - public void OpenContentViewer() { - MainViewModel.RequirePage().Go(Address, ContentPath.Empty); + gameRunnerService.OpenContentViewer(Address); } public void ToggleFavorites() { IsFavorite = !IsFavorite; if(IsFavorite) - FavoriteServerListProvider.AddFavorite(this); + gameRunnerService.AddFavorite(Address); else - FavoriteServerListProvider.RemoveFavorite(this); + gameRunnerService.RemoveFavorite(Address); } public void RunInstance() { - Task.Run(async ()=> await GameRunnerService.RunInstanceAsync(this, CancellationService.Token)); + Task.Run(async ()=> await gameRunnerService.RunInstanceAsync(this, cancellationService.Token)); } public void RunInstanceIgnoreAuth() { - Task.Run(async ()=> await GameRunnerService.RunInstanceAsync(this, CancellationService.Token, true)); + Task.Run(async ()=> await gameRunnerService.RunInstanceAsync(this, cancellationService.Token, true)); } public void StopInstance() { - GameRunnerService.StopInstance(this); + gameRunnerService.StopInstance(Address); } public void ReadLog() { - GameRunnerService.ReadInstanceLog(this); + gameRunnerService.ReadInstanceLog(Address); + } + + public void EditName() + { + gameRunnerService.EditName(Address, Name); } public async void ExpandInfoRequired() @@ -186,10 +185,6 @@ public sealed partial class ServerEntryViewModel : ViewModelBase, IFilterConsume { RunVisible = !isRunning; } - - public void Dispose() - { - } } public sealed class LinkGoCommand : ICommand