- tweak: Rework loading status
This commit is contained in:
1
.idea/.idea.Nebula/.idea/avalonia.xml
generated
1
.idea/.idea.Nebula/.idea/avalonia.xml
generated
@@ -35,6 +35,7 @@
|
||||
<entry key="Nebula.Launcher/Views/Popup/LogPopupView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
<entry key="Nebula.Launcher/Views/Popup/MessagePopupView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
<entry key="Nebula.Launcher/Views/Popup/TfaView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
<entry key="Nebula.Launcher/Views/ServerCompoundEntryView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
<entry key="Nebula.Launcher/Views/ServerContainer.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
<entry key="Nebula.Launcher/Views/ServerEntryView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
<entry key="Nebula.Launcher/Views/ServerList.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||
|
||||
@@ -49,7 +49,7 @@ public partial class ServerListView : UserControl
|
||||
{
|
||||
if (rawView is ServerEntryModelView serverEntryModelView)
|
||||
{
|
||||
serverEntryModelView.UpdateStatusIfNecessary();
|
||||
//serverEntryModelView.UpdateStatusIfNecessary();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,9 +61,10 @@ public partial class ServerListView : UserControl
|
||||
if(IsLoading)
|
||||
return;
|
||||
|
||||
foreach (IFilterConsumer? serverView in ServerList.Items)
|
||||
foreach (var serverView in ServerList.Items)
|
||||
{
|
||||
serverView?.ProcessFilter(filter);
|
||||
if(serverView is IFilterConsumer filterConsumer)
|
||||
filterConsumer.ProcessFilter(filter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +84,8 @@ public partial class ServerListView : UserControl
|
||||
foreach (var serverEntry in _provider.GetServers())
|
||||
{
|
||||
ServerList.Items.Add(serverEntry);
|
||||
serverEntry.ProcessFilter(_currentFilter);
|
||||
if(serverEntry is IFilterConsumer serverFilter)
|
||||
serverFilter.ProcessFilter(_currentFilter);
|
||||
}
|
||||
|
||||
foreach (var error in _provider.GetErrors())
|
||||
|
||||
@@ -23,13 +23,13 @@ public sealed partial class FavoriteServerListProvider : IServerListProvider, IS
|
||||
[GenerateProperty] private IServiceProvider ServiceProvider { get; }
|
||||
[GenerateProperty] private ServerViewContainer ServerViewContainer { get; }
|
||||
|
||||
private List<IFilterConsumer> _serverLists = [];
|
||||
private List<IListEntryModelView> _serverLists = [];
|
||||
private string[] rawServerLists = [];
|
||||
|
||||
public bool IsLoaded { get; private set; }
|
||||
public Action? OnLoaded { get; set; }
|
||||
public Action? Dirty { get; set; }
|
||||
public IEnumerable<IFilterConsumer> GetServers()
|
||||
public IEnumerable<IListEntryModelView> GetServers()
|
||||
{
|
||||
return _serverLists;
|
||||
}
|
||||
@@ -45,12 +45,12 @@ public sealed partial class FavoriteServerListProvider : IServerListProvider, IS
|
||||
_serverLists.Clear();
|
||||
var servers = GetFavoriteEntries();
|
||||
|
||||
_serverLists.AddRange(
|
||||
servers.Select(s =>
|
||||
var serverEntries = servers.Select(s =>
|
||||
ServerViewContainer.Get(s.ToRobustUrl())
|
||||
)
|
||||
);
|
||||
|
||||
_serverLists.AddRange(serverEntries);
|
||||
|
||||
_serverLists.Add(new AddFavoriteButton(ServiceProvider));
|
||||
|
||||
IsLoaded = true;
|
||||
@@ -67,7 +67,7 @@ public sealed partial class FavoriteServerListProvider : IServerListProvider, IS
|
||||
var servers = GetFavoriteEntries();
|
||||
servers.Add(robustUrl.ToString());
|
||||
ConfigurationService.SetConfigValue(LauncherConVar.Favorites, servers.ToArray());
|
||||
ServerViewContainer.Get(robustUrl).IsFavorite = true;
|
||||
if(ServerViewContainer.Get(robustUrl) is IFavoriteEntryModelView favoriteView) favoriteView.IsFavorite = true;
|
||||
}
|
||||
|
||||
public void RemoveFavorite(ServerEntryModelView entryModelView)
|
||||
@@ -77,6 +77,13 @@ public sealed partial class FavoriteServerListProvider : IServerListProvider, IS
|
||||
ConfigurationService.SetConfigValue(LauncherConVar.Favorites, servers.ToArray());
|
||||
}
|
||||
|
||||
public void RemoveFavorite(RobustUrl url)
|
||||
{
|
||||
var servers = GetFavoriteEntries();
|
||||
servers.Remove(url.ToString());
|
||||
ConfigurationService.SetConfigValue(LauncherConVar.Favorites, servers.ToArray());
|
||||
}
|
||||
|
||||
private List<string> GetFavoriteEntries()
|
||||
{
|
||||
return rawServerLists.ToList();
|
||||
@@ -103,7 +110,7 @@ public sealed partial class FavoriteServerListProvider : IServerListProvider, IS
|
||||
private void InitialiseInDesignMode(){}
|
||||
}
|
||||
|
||||
public class AddFavoriteButton: Border, IFilterConsumer{
|
||||
public class AddFavoriteButton: Border, IListEntryModelView{
|
||||
|
||||
private Button _addFavoriteButton = new Button();
|
||||
public AddFavoriteButton(IServiceProvider serviceProvider)
|
||||
@@ -120,8 +127,5 @@ public class AddFavoriteButton: Border, IFilterConsumer{
|
||||
_addFavoriteButton.Content = "Add Favorite";
|
||||
Child = _addFavoriteButton;
|
||||
}
|
||||
|
||||
public void ProcessFilter(ServerFilter? serverFilter)
|
||||
{
|
||||
}
|
||||
public bool IsFavorite { get; set; }
|
||||
}
|
||||
@@ -24,7 +24,7 @@ public sealed partial class HubServerListProvider : IServerListProvider
|
||||
public Action? OnLoaded { get; set; }
|
||||
|
||||
private CancellationTokenSource? _cts;
|
||||
private readonly List<ServerEntryModelView> _servers = [];
|
||||
private readonly List<IListEntryModelView> _servers = [];
|
||||
private readonly List<Exception> _errors = [];
|
||||
|
||||
public HubServerListProvider With(string hubUrl)
|
||||
@@ -33,7 +33,7 @@ public sealed partial class HubServerListProvider : IServerListProvider
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEnumerable<IFilterConsumer> GetServers()
|
||||
public IEnumerable<IListEntryModelView> GetServers()
|
||||
{
|
||||
return _servers;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Nebula.Launcher.ViewModels;
|
||||
using Nebula.Launcher.ViewModels.Pages;
|
||||
|
||||
namespace Nebula.Launcher.ServerListProviders;
|
||||
|
||||
@@ -9,7 +10,7 @@ public interface IServerListProvider
|
||||
public bool IsLoaded { get; }
|
||||
public Action? OnLoaded { get; set; }
|
||||
|
||||
public IEnumerable<IFilterConsumer> GetServers();
|
||||
public IEnumerable<IListEntryModelView> GetServers();
|
||||
public IEnumerable<Exception> GetErrors();
|
||||
|
||||
public void LoadServerList();
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Nebula.Launcher.Controls;
|
||||
using Nebula.Launcher.ViewModels;
|
||||
using Nebula.Launcher.ViewModels.Pages;
|
||||
|
||||
namespace Nebula.Launcher.ServerListProviders;
|
||||
|
||||
@@ -9,7 +10,7 @@ public sealed class TestServerList : IServerListProvider
|
||||
{
|
||||
public bool IsLoaded => true;
|
||||
public Action? OnLoaded { get; set; }
|
||||
public IEnumerable<IFilterConsumer> GetServers()
|
||||
public IEnumerable<IListEntryModelView> GetServers()
|
||||
{
|
||||
return [new ServerEntryModelView(),new ServerEntryModelView()];
|
||||
}
|
||||
|
||||
@@ -125,12 +125,6 @@ public static class ConfigControlHelper{
|
||||
|
||||
public static object? CreateDefaultValue(Type type)
|
||||
{
|
||||
if (type == typeof(string))
|
||||
return string.Empty;
|
||||
if (type == typeof(int))
|
||||
return 0;
|
||||
if (type == typeof(float))
|
||||
return 0f;
|
||||
if(type.IsValueType)
|
||||
return Activator.CreateInstance(type);
|
||||
|
||||
|
||||
@@ -29,9 +29,7 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase, IContentHol
|
||||
[ObservableProperty] private string _serverText = "";
|
||||
[ObservableProperty] private string _searchText = "";
|
||||
[GenerateProperty] private ContentService ContentService { get; } = default!;
|
||||
[GenerateProperty] private CancellationService CancellationService { get; } = default!;
|
||||
[GenerateProperty] private FileService FileService { get; } = default!;
|
||||
[GenerateProperty] private DebugService DebugService { get; } = default!;
|
||||
[GenerateProperty] private PopupMessageService PopupService { get; } = default!;
|
||||
[GenerateProperty] private IServiceProvider ServiceProvider { get; }
|
||||
[GenerateProperty, DesignConstruct] private ViewHelperService ViewHelperService { get; } = default!;
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Nebula.Launcher.Controls;
|
||||
@@ -89,7 +90,8 @@ public partial class ServerOverviewModel : ViewModelBase
|
||||
{
|
||||
foreach (var entry in ServerViewContainer.Items)
|
||||
{
|
||||
entry.ProcessFilter(CurrentFilter);
|
||||
if(entry is IFilterConsumer filterConsumer)
|
||||
filterConsumer.ProcessFilter(CurrentFilter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +111,7 @@ public partial class ServerOverviewModel : ViewModelBase
|
||||
|
||||
public void UpdateRequired()
|
||||
{
|
||||
ServerViewContainer.Clear();
|
||||
CurrentServerList.RefreshFromProvider();
|
||||
CurrentServerList.RequireStatusUpdate();
|
||||
CurrentServerList.ApplyFilter(CurrentFilter);
|
||||
@@ -150,25 +153,25 @@ public class ServerViewContainer
|
||||
|
||||
foreach (var favorite in favorites)
|
||||
{
|
||||
if (_entries.TryGetValue(favorite, out var entry))
|
||||
if (_entries.TryGetValue(favorite, out var entry) && entry is IFavoriteEntryModelView favoriteView)
|
||||
{
|
||||
entry.IsFavorite = true;
|
||||
favoriteView.IsFavorite = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, ServerEntryModelView> _entries = new();
|
||||
private readonly Dictionary<string, IListEntryModelView> _entries = new();
|
||||
|
||||
public ICollection<ServerEntryModelView> Items => _entries.Values;
|
||||
public ICollection<IListEntryModelView> Items => _entries.Values;
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_entries.Clear();
|
||||
}
|
||||
|
||||
public ServerEntryModelView Get(RobustUrl url, ServerStatus? serverStatus = null)
|
||||
public IListEntryModelView Get(RobustUrl url, ServerStatus? serverStatus = null)
|
||||
{
|
||||
ServerEntryModelView? entry;
|
||||
IListEntryModelView? entry;
|
||||
|
||||
lock (_entries)
|
||||
{
|
||||
@@ -177,9 +180,13 @@ public class ServerViewContainer
|
||||
return entry;
|
||||
}
|
||||
|
||||
if (serverStatus is not null)
|
||||
entry = _viewHelperService.GetViewModel<ServerEntryModelView>().WithData(url, serverStatus);
|
||||
else
|
||||
entry = _viewHelperService.GetViewModel<ServerCompoundEntryViewModel>().LoadServerEntry(url, CancellationToken.None);
|
||||
|
||||
if(favorites.Contains(url.ToString())) entry.IsFavorite = true;
|
||||
if(favorites.Contains(url.ToString()) && entry is IFavoriteEntryModelView favoriteEntryModelView)
|
||||
favoriteEntryModelView.IsFavorite = true;
|
||||
|
||||
_entries.Add(url.ToString(), entry);
|
||||
}
|
||||
@@ -188,6 +195,16 @@ public class ServerViewContainer
|
||||
}
|
||||
}
|
||||
|
||||
public interface IListEntryModelView
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public interface IFavoriteEntryModelView
|
||||
{
|
||||
public bool IsFavorite { get; set; }
|
||||
}
|
||||
|
||||
public class ServerComparer : IComparer<ServerHubInfo>, IComparer<ServerStatus>, IComparer<(RobustUrl,ServerStatus)>
|
||||
{
|
||||
public int Compare(ServerHubInfo? x, ServerHubInfo? y)
|
||||
|
||||
89
Nebula.Launcher/ViewModels/ServerCompoundEntryModelView.cs
Normal file
89
Nebula.Launcher/ViewModels/ServerCompoundEntryModelView.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Threading;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Nebula.Launcher.ServerListProviders;
|
||||
using Nebula.Launcher.ViewModels.Pages;
|
||||
using Nebula.Launcher.Views;
|
||||
using Nebula.Shared.Models;
|
||||
using Nebula.Shared.Services;
|
||||
using BindingFlags = System.Reflection.BindingFlags;
|
||||
|
||||
namespace Nebula.Launcher.ViewModels;
|
||||
|
||||
[ViewModelRegister(typeof(ServerCompoundEntryView), false)]
|
||||
[ConstructGenerator]
|
||||
public sealed partial class ServerCompoundEntryViewModel :
|
||||
ViewModelBase, IFavoriteEntryModelView, IFilterConsumer, IListEntryModelView
|
||||
{
|
||||
[ObservableProperty] private ServerEntryModelView _currentEntry;
|
||||
[ObservableProperty] private Control? _entryControl;
|
||||
[ObservableProperty] private string _name = "Loading...";
|
||||
[ObservableProperty] private bool _isFavorite;
|
||||
[ObservableProperty] private bool _loading = true;
|
||||
|
||||
[GenerateProperty] private RestService RestService { get; }
|
||||
[GenerateProperty] private IServiceProvider ServiceProvider{ get; }
|
||||
[GenerateProperty] private FavoriteServerListProvider FavoriteServerListProvider { get; }
|
||||
|
||||
private RobustUrl? _url;
|
||||
|
||||
|
||||
protected override void InitialiseInDesignMode()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Initialise()
|
||||
{
|
||||
}
|
||||
|
||||
public ServerCompoundEntryViewModel LoadServerEntry(RobustUrl url, CancellationToken cancellationToken)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
_url = url;
|
||||
Name = $"Loading {url}...";
|
||||
var status = await RestService.GetAsync<ServerStatus>(url.StatusUri, cancellationToken);
|
||||
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
CurrentEntry = ServiceProvider.GetService<ServerEntryModelView>()!.WithData(url, status);
|
||||
CurrentEntry.IsFavorite = IsFavorite;
|
||||
CurrentEntry.Loading = false;
|
||||
Loading = false;
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var error = new Exception("Unable to load server entry", e);
|
||||
Name = e.Message;
|
||||
}
|
||||
}, cancellationToken);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void ToggleFavorites()
|
||||
{
|
||||
if (_url == null)
|
||||
return;
|
||||
IsFavorite = !IsFavorite;
|
||||
if(IsFavorite)
|
||||
FavoriteServerListProvider.AddFavorite(_url);
|
||||
else
|
||||
FavoriteServerListProvider.RemoveFavorite(_url);
|
||||
}
|
||||
|
||||
|
||||
public void ProcessFilter(ServerFilter? serverFilter)
|
||||
{
|
||||
if(CurrentEntry is IFilterConsumer filterConsumer)
|
||||
filterConsumer.ProcessFilter(serverFilter);
|
||||
}
|
||||
}
|
||||
@@ -21,22 +21,21 @@ namespace Nebula.Launcher.ViewModels;
|
||||
|
||||
[ViewModelRegister(typeof(ServerEntryView), false)]
|
||||
[ConstructGenerator]
|
||||
public partial class ServerEntryModelView : ViewModelBase, IFilterConsumer
|
||||
public partial class ServerEntryModelView : ViewModelBase, IFilterConsumer, IListEntryModelView, IFavoriteEntryModelView
|
||||
{
|
||||
[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 bool _tagDataVisible;
|
||||
[ObservableProperty] private bool _loading;
|
||||
|
||||
private ILogger _logger;
|
||||
private bool _isStatusFromHub;
|
||||
private ServerInfo? _serverInfo;
|
||||
private ContentLogConsumer _currentContentLogConsumer;
|
||||
private ProcessRunHandler<GameProcessStartInfoProvider>? _currentInstance;
|
||||
|
||||
[ObservableProperty] private bool _tagDataVisible;
|
||||
|
||||
public LogPopupModelView CurrLog;
|
||||
public RobustUrl Address { get; private set; }
|
||||
[GenerateProperty] private ConfigurationService ConfigurationService { get; } = default!;
|
||||
@@ -120,39 +119,14 @@ public partial class ServerEntryModelView : ViewModelBase, IFilterConsumer
|
||||
OnPropertyChanged(nameof(Status));
|
||||
}
|
||||
|
||||
public void UpdateStatusIfNecessary()
|
||||
{
|
||||
if(_isStatusFromHub) return;
|
||||
FetchStatus();
|
||||
}
|
||||
|
||||
public ServerEntryModelView WithData(RobustUrl url, ServerStatus? serverStatus)
|
||||
public ServerEntryModelView WithData(RobustUrl url, ServerStatus serverStatus)
|
||||
{
|
||||
Address = url;
|
||||
_isStatusFromHub = serverStatus is not null;
|
||||
if (_isStatusFromHub)
|
||||
SetStatus(serverStatus!);
|
||||
else
|
||||
FetchStatus();
|
||||
|
||||
SetStatus(serverStatus);
|
||||
return this;
|
||||
}
|
||||
|
||||
private async void FetchStatus()
|
||||
{
|
||||
try
|
||||
{
|
||||
SetStatus(await RestService.GetAsync<ServerStatus>(Address.StatusUri, CancellationService.Token));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(e);
|
||||
Status = new ServerStatus("ErrorLand", $"ERROR: {e.Message}", [], "", -1, -1, -1, false,
|
||||
DateTime.Now,
|
||||
-1);
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenContentViewer()
|
||||
{
|
||||
MainViewModel.RequirePage<ContentBrowserViewModel>().Go(Address, ContentPath.Empty);
|
||||
|
||||
73
Nebula.Launcher/Views/ServerCompoundEntryView.axaml
Normal file
73
Nebula.Launcher/Views/ServerCompoundEntryView.axaml
Normal file
@@ -0,0 +1,73 @@
|
||||
<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:viewModels="clr-namespace:Nebula.Launcher.ViewModels"
|
||||
xmlns:views="clr-namespace:Nebula.Launcher.Views"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Nebula.Launcher.Views.ServerCompoundEntryView"
|
||||
x:DataType="viewModels:ServerCompoundEntryViewModel">
|
||||
<Design.DataContext>
|
||||
<viewModels:ServerCompoundEntryViewModel />
|
||||
</Design.DataContext>
|
||||
|
||||
<Panel>
|
||||
<Border IsVisible="{Binding Loading}"
|
||||
Background="{StaticResource DefaultGrad}"
|
||||
BoxShadow="-2 0 5 -1 #121212"
|
||||
CornerRadius="10"
|
||||
Margin="5">
|
||||
|
||||
<Grid ColumnDefinitions="*,80,50,50" RowDefinitions="35,*,*">
|
||||
<Border
|
||||
Background="Transparent"
|
||||
BoxShadow="0 3 3 -2 #121212"
|
||||
CornerRadius="10"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Grid.Row="0"/>
|
||||
|
||||
<ScrollViewer
|
||||
Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalScrollBarVisibility="Hidden"
|
||||
Margin="10,0,0,0"
|
||||
VerticalScrollBarVisibility="Disabled"
|
||||
x:Name="AutoScrollViewer">
|
||||
<Label VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding Name}" />
|
||||
</Label>
|
||||
</ScrollViewer>
|
||||
|
||||
<Panel
|
||||
Grid.Column="2"
|
||||
Grid.Row="0"
|
||||
Margin="5,0,0,0">
|
||||
<Button
|
||||
Command="{Binding ToggleFavorites}"
|
||||
CornerRadius="10,10,10,10"
|
||||
HorizontalAlignment="Stretch"
|
||||
IsVisible="{Binding !IsFavorite}"
|
||||
VerticalAlignment="Stretch">
|
||||
<Svg Margin="4" Path="/Assets/svg/star.svg" />
|
||||
</Button>
|
||||
<Button
|
||||
Command="{Binding ToggleFavorites}"
|
||||
CornerRadius="10,10,10,10"
|
||||
HorizontalAlignment="Stretch"
|
||||
IsVisible="{Binding IsFavorite}"
|
||||
VerticalAlignment="Stretch">
|
||||
<Svg Margin="4" Path="/Assets/svg/starfull.svg" />
|
||||
</Button>
|
||||
</Panel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Panel IsVisible="{Binding !Loading}">
|
||||
<views:ServerEntryView IsVisible="{Binding !Loading}" DataContext="{Binding CurrentEntry}"/>
|
||||
</Panel>
|
||||
|
||||
</Panel>
|
||||
</UserControl>
|
||||
17
Nebula.Launcher/Views/ServerCompoundEntryView.axaml.cs
Normal file
17
Nebula.Launcher/Views/ServerCompoundEntryView.axaml.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Avalonia.Controls;
|
||||
using Nebula.Launcher.ViewModels;
|
||||
|
||||
namespace Nebula.Launcher.Views;
|
||||
|
||||
public partial class ServerCompoundEntryView : UserControl
|
||||
{
|
||||
public ServerCompoundEntryView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public ServerCompoundEntryView(ServerCompoundEntryViewModel viewModel) : this()
|
||||
{
|
||||
DataContext = viewModel;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
@@ -24,12 +25,14 @@ public class RestService
|
||||
_logger = debug.GetLogger(this);
|
||||
}
|
||||
|
||||
[Pure]
|
||||
public async Task<T> GetAsync<T>(Uri uri, CancellationToken cancellationToken) where T : notnull
|
||||
{
|
||||
var response = await _client.GetAsync(uri, cancellationToken);
|
||||
return await ReadResult<T>(response, cancellationToken, uri);
|
||||
}
|
||||
|
||||
[Pure]
|
||||
public async Task<T> GetAsyncDefault<T>(Uri uri, T defaultValue, CancellationToken cancellationToken) where T : notnull
|
||||
{
|
||||
try
|
||||
@@ -43,6 +46,7 @@ public class RestService
|
||||
}
|
||||
}
|
||||
|
||||
[Pure]
|
||||
public async Task<K> PostAsync<K, T>(T information, Uri uri, CancellationToken cancellationToken) where K : notnull
|
||||
{
|
||||
var json = JsonSerializer.Serialize(information, _serializerOptions);
|
||||
@@ -51,6 +55,7 @@ public class RestService
|
||||
return await ReadResult<K>(response, cancellationToken, uri);
|
||||
}
|
||||
|
||||
[Pure]
|
||||
public async Task<T> PostAsync<T>(Stream stream, Uri uri, CancellationToken cancellationToken) where T : notnull
|
||||
{
|
||||
using var multipartFormContent =
|
||||
@@ -60,12 +65,14 @@ public class RestService
|
||||
return await ReadResult<T>(response, cancellationToken, uri);
|
||||
}
|
||||
|
||||
[Pure]
|
||||
public async Task<T> DeleteAsync<T>(Uri uri, CancellationToken cancellationToken) where T : notnull
|
||||
{
|
||||
var response = await _client.DeleteAsync(uri, cancellationToken);
|
||||
return await ReadResult<T>(response, cancellationToken, uri);
|
||||
}
|
||||
|
||||
[Pure]
|
||||
private async Task<T> ReadResult<T>(HttpResponseMessage response, CancellationToken cancellationToken, Uri uri) where T : notnull
|
||||
{
|
||||
var content = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AConsole_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Ffd57398b7dc3a8ce7da2786f2c67289c3d974658a9e90d0c1e84db3d965fbf1_003FConsole_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AControl_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F57361bc4e5442f644ff63ec7e745da2eb4bbb6c769d1fb683bab5f6f952b1ab_003FControl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADecorator_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Feecfe7fcb95caaf3978fdce4ae36e346b34986d1d844b0dce2fcb67e5952c_003FDecorator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADesign_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F9a2912aa19f1b0ab2229159cec21d718356660fc49cd8e5257a66b584b69b_003FDesign_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADispatcher_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fe6d04341b5ca8c55e2be617e1b6fc5a12cc8647f7272d94f614ae7fb1c0e8d_003FDispatcher_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADrawingContext_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F7f67edd2b798d6c80b015913cde68b729bfe416b62cf075ea3953ffeff639c_003FDrawingContext_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnumerable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fcae7ff14a5884c649c9045d4ef4f987ea0928_003Fa6_003F6011c781_003FEnumerable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFileShare_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa6b7f037ba7b44df80b8d3aa7e58eeb2e8e938_003F54_003Fc3f4f140_003FFileShare_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
@@ -18,6 +20,7 @@
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpClient_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fc439425da351c75ac7d966a1cc8324b51a9c471865af79d2f2f3fcb65e392_003FHttpClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpContent_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F9657cc383c70851dc2bdcf91eff27f21196844abfe552fc9c3243ff36974cd_003FHttpContent_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpResponseMessage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F4cfeb8b377bc81e1fbb5f7d7a02492cb6ac23e88c8c9d7155944f0716f3d4b_003FHttpResponseMessage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIDispatcherImpl_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F22d92db124764b1ab49745245c66f01b1e1a00_003F0f_003F01061787_003FIDispatcherImpl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIDisposable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa6b7f037ba7b44df80b8d3aa7e58eeb2e8e938_003F98_003Fd1b23281_003FIDisposable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIndex_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F2a1a813823579c69832f1304f97761e7be433bd6aa928f351d138050b56a38_003FIndex_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInt32_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fa882d183338544fdbcbdfc7b6d3dcb78916630765551644a221b5be9c45a121b_003FInt32_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
|
||||
Reference in New Issue
Block a user