- add: Custom names of servers
This commit is contained in:
2
.idea/.idea.Nebula/.idea/avalonia.xml
generated
2
.idea/.idea.Nebula/.idea/avalonia.xml
generated
@@ -28,6 +28,8 @@
|
|||||||
<entry key="Nebula.Launcher/Views/Pages/ServerListPage.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
<entry key="Nebula.Launcher/Views/Pages/ServerListPage.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||||
<entry key="Nebula.Launcher/Views/Pages/ServerListView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
<entry key="Nebula.Launcher/Views/Pages/ServerListView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||||
<entry key="Nebula.Launcher/Views/Pages/ServerOverviewView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
<entry key="Nebula.Launcher/Views/Pages/ServerOverviewView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||||
|
<entry key="Nebula.Launcher/Views/Popup/AddFavoriteView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||||
|
<entry key="Nebula.Launcher/Views/Popup/EditServerNameView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||||
<entry key="Nebula.Launcher/Views/Popup/ExceptionListView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
<entry key="Nebula.Launcher/Views/Popup/ExceptionListView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||||
<entry key="Nebula.Launcher/Views/Popup/ExceptionView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
<entry key="Nebula.Launcher/Views/Popup/ExceptionView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||||
<entry key="Nebula.Launcher/Views/Popup/InfoPopupView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
<entry key="Nebula.Launcher/Views/Popup/InfoPopupView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
|
||||||
|
|||||||
7
Nebula.Launcher/Assets/svg/pencil.svg
Normal file
7
Nebula.Launcher/Assets/svg/pencil.svg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<!-- License: Apache. Made by Remix Design: https://github.com/Remix-Design/remixicon -->
|
||||||
|
<svg width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g>
|
||||||
|
<path fill="none" d="M0 0h24v24H0z"/>
|
||||||
|
<path fill="white" d="M15.728 9.686l-1.414-1.414L5 17.586V19h1.414l9.314-9.314zm1.414-1.414l1.414-1.414-1.414-1.414-1.414 1.414 1.414 1.414zM7.242 21H3v-4.243L16.435 3.322a1 1 0 0 1 1.414 0l2.829 2.829a1 1 0 0 1 0 1.414L7.243 21z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 489 B |
@@ -18,7 +18,11 @@ public static class LauncherConVar
|
|||||||
public static readonly ConVar<string[]> Favorites =
|
public static readonly ConVar<string[]> Favorites =
|
||||||
ConVarBuilder.Build<string[]>("server.favorites", []);
|
ConVarBuilder.Build<string[]>("server.favorites", []);
|
||||||
|
|
||||||
public static readonly ConVar<AuthServerCredentials[]> AuthServers = ConVarBuilder.Build<AuthServerCredentials[]>("launcher.authServers", [
|
public static readonly ConVar<Dictionary<string,string>> ServerCustomNames =
|
||||||
|
ConVarBuilder.Build<Dictionary<string,string>>("server.names", []);
|
||||||
|
|
||||||
|
public static readonly ConVar<AuthServerCredentials[]> AuthServers =
|
||||||
|
ConVarBuilder.Build<AuthServerCredentials[]>("launcher.authServers", [
|
||||||
new AuthServerCredentials(
|
new AuthServerCredentials(
|
||||||
"WizDen",
|
"WizDen",
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Nebula.Launcher.Controls;
|
using Nebula.Launcher.Controls;
|
||||||
using Nebula.Launcher.Models;
|
using Nebula.Launcher.Models;
|
||||||
@@ -24,24 +25,18 @@ public partial class ServerOverviewModel : ViewModelBase
|
|||||||
|
|
||||||
[ObservableProperty] private bool _isFilterVisible;
|
[ObservableProperty] private bool _isFilterVisible;
|
||||||
|
|
||||||
[ObservableProperty] private ServerListView _currentServerList = new ServerListView();
|
[ObservableProperty] private ServerListView _currentServerList = new();
|
||||||
|
|
||||||
public readonly ServerFilter CurrentFilter = new ServerFilter();
|
public readonly ServerFilter CurrentFilter = new();
|
||||||
|
|
||||||
public Action? OnSearchChange;
|
public Action? OnSearchChange;
|
||||||
|
|
||||||
[GenerateProperty] private PopupMessageService PopupMessageService { get; }
|
|
||||||
[GenerateProperty] private CancellationService CancellationService { get; }
|
|
||||||
[GenerateProperty] private DebugService DebugService { get; }
|
|
||||||
[GenerateProperty] private IServiceProvider ServiceProvider { get; }
|
[GenerateProperty] private IServiceProvider ServiceProvider { get; }
|
||||||
[GenerateProperty] private ConfigurationService ConfigurationService { get; }
|
[GenerateProperty] private ConfigurationService ConfigurationService { get; }
|
||||||
[GenerateProperty] private FavoriteServerListProvider FavoriteServerListProvider { get; }
|
[GenerateProperty] private FavoriteServerListProvider FavoriteServerListProvider { get; }
|
||||||
[GenerateProperty, DesignConstruct] private ViewHelperService ViewHelperService { get; }
|
|
||||||
|
|
||||||
public ObservableCollection<ServerListTabTemplate> Items { get; private set; }
|
public ObservableCollection<ServerListTabTemplate> Items { get; private set; }
|
||||||
[ObservableProperty] private ServerListTabTemplate _selectedItem;
|
[ObservableProperty] private ServerListTabTemplate _selectedItem;
|
||||||
|
|
||||||
[GenerateProperty, DesignConstruct] private ServerViewContainer ServerViewContainer { get; set; }
|
[GenerateProperty, DesignConstruct] private ServerViewContainer ServerViewContainer { get; }
|
||||||
|
|
||||||
private Dictionary<string, ServerListView> _viewCache = [];
|
private Dictionary<string, ServerListView> _viewCache = [];
|
||||||
|
|
||||||
@@ -126,6 +121,7 @@ public partial class ServerOverviewModel : ViewModelBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
CurrentServerList = view;
|
CurrentServerList = view;
|
||||||
|
ApplyFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -134,25 +130,77 @@ public partial class ServerOverviewModel : ViewModelBase
|
|||||||
public class ServerViewContainer
|
public class ServerViewContainer
|
||||||
{
|
{
|
||||||
private readonly ViewHelperService _viewHelperService;
|
private readonly ViewHelperService _viewHelperService;
|
||||||
private List<string> favorites = [];
|
private readonly List<string> _favorites = [];
|
||||||
|
private readonly Dictionary<string, string> _customNames = [];
|
||||||
|
|
||||||
public ServerViewContainer()
|
public ServerViewContainer()
|
||||||
{
|
{
|
||||||
_viewHelperService = new ViewHelperService();
|
_viewHelperService = new ViewHelperService();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UsedImplicitly]
|
||||||
public ServerViewContainer(ViewHelperService viewHelperService, ConfigurationService configurationService)
|
public ServerViewContainer(ViewHelperService viewHelperService, ConfigurationService configurationService)
|
||||||
{
|
{
|
||||||
_viewHelperService = viewHelperService;
|
_viewHelperService = viewHelperService;
|
||||||
configurationService.SubscribeVarChanged(LauncherConVar.Favorites, OnFavoritesChange, true);
|
configurationService.SubscribeVarChanged(LauncherConVar.Favorites, OnFavoritesChange, true);
|
||||||
|
configurationService.SubscribeVarChanged(LauncherConVar.ServerCustomNames, OnCustomNamesChanged, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCustomNamesChanged(Dictionary<string,string>? value)
|
||||||
|
{
|
||||||
|
var oldNames =
|
||||||
|
_customNames.ToDictionary(k => k.Key, v => v.Value); //Clone think
|
||||||
|
|
||||||
|
_customNames.Clear();
|
||||||
|
|
||||||
|
if(value == null)
|
||||||
|
{
|
||||||
|
foreach (var (ip,_) in oldNames)
|
||||||
|
{
|
||||||
|
if(!_entries.TryGetValue(ip, out var listEntry) || listEntry is not IEntryNameHolder entryNameHolder)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
entryNameHolder.Name = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var (oldIp, oldName) in oldNames)
|
||||||
|
{
|
||||||
|
if(value.TryGetValue(oldIp, out var newName))
|
||||||
|
{
|
||||||
|
if (oldName == newName)
|
||||||
|
value.Remove(newName);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!_entries.TryGetValue(oldIp, out var listEntry) ||
|
||||||
|
listEntry is not IEntryNameHolder entryNameHolder)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
entryNameHolder.Name = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var (ip, name) in value)
|
||||||
|
{
|
||||||
|
_customNames.Add(ip, name);
|
||||||
|
if(!_entries.TryGetValue(ip, out var listEntry) || listEntry is not IEntryNameHolder entryNameHolder)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
entryNameHolder.Name = name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnFavoritesChange(string[]? value)
|
private void OnFavoritesChange(string[]? value)
|
||||||
{
|
{
|
||||||
favorites = new List<string>(value ?? []);
|
_favorites.Clear();
|
||||||
|
if(value == null) return;
|
||||||
|
|
||||||
foreach (var favorite in favorites)
|
foreach (var favorite in value)
|
||||||
{
|
{
|
||||||
|
_favorites.Add(favorite);
|
||||||
if (_entries.TryGetValue(favorite, out var entry) && entry is IFavoriteEntryModelView favoriteView)
|
if (_entries.TryGetValue(favorite, out var entry) && entry is IFavoriteEntryModelView favoriteView)
|
||||||
{
|
{
|
||||||
favoriteView.IsFavorite = true;
|
favoriteView.IsFavorite = true;
|
||||||
@@ -175,17 +223,20 @@ public class ServerViewContainer
|
|||||||
|
|
||||||
lock (_entries)
|
lock (_entries)
|
||||||
{
|
{
|
||||||
|
_customNames.TryGetValue(url.ToString(), out var customName);
|
||||||
|
|
||||||
if (_entries.TryGetValue(url.ToString(), out entry))
|
if (_entries.TryGetValue(url.ToString(), out entry))
|
||||||
{
|
{
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverStatus is not null)
|
if (serverStatus is not null)
|
||||||
entry = _viewHelperService.GetViewModel<ServerEntryModelView>().WithData(url, serverStatus);
|
entry = _viewHelperService.GetViewModel<ServerEntryModelView>().WithData(url, customName, serverStatus);
|
||||||
else
|
else
|
||||||
entry = _viewHelperService.GetViewModel<ServerCompoundEntryViewModel>().LoadServerEntry(url, CancellationToken.None);
|
entry = _viewHelperService.GetViewModel<ServerCompoundEntryViewModel>().LoadServerEntry(url, customName, CancellationToken.None);
|
||||||
|
|
||||||
if(favorites.Contains(url.ToString()) && entry is IFavoriteEntryModelView favoriteEntryModelView)
|
if(_favorites.Contains(url.ToString()) &&
|
||||||
|
entry is IFavoriteEntryModelView favoriteEntryModelView)
|
||||||
favoriteEntryModelView.IsFavorite = true;
|
favoriteEntryModelView.IsFavorite = true;
|
||||||
|
|
||||||
_entries.Add(url.ToString(), entry);
|
_entries.Add(url.ToString(), entry);
|
||||||
@@ -205,6 +256,11 @@ public interface IFavoriteEntryModelView
|
|||||||
public bool IsFavorite { get; set; }
|
public bool IsFavorite { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface IEntryNameHolder
|
||||||
|
{
|
||||||
|
public string? Name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class ServerComparer : IComparer<ServerHubInfo>, IComparer<ServerStatus>, IComparer<(RobustUrl,ServerStatus)>
|
public class ServerComparer : IComparer<ServerHubInfo>, IComparer<ServerStatus>, IComparer<(RobustUrl,ServerStatus)>
|
||||||
{
|
{
|
||||||
public int Compare(ServerHubInfo? x, ServerHubInfo? y)
|
public int Compare(ServerHubInfo? x, ServerHubInfo? y)
|
||||||
@@ -262,4 +318,6 @@ public sealed class ServerFilter
|
|||||||
{
|
{
|
||||||
return IsMatchByName(name) && IsMatchByTags(itemTags);
|
return IsMatchByName(name) && IsMatchByTags(itemTags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed record ServerCustomNameEntry(string Url, string Name);
|
||||||
56
Nebula.Launcher/ViewModels/Popup/EditServerNameViewModel.cs
Normal file
56
Nebula.Launcher/ViewModels/Popup/EditServerNameViewModel.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using Nebula.Launcher.Views.Popup;
|
||||||
|
using Nebula.Shared.Services;
|
||||||
|
|
||||||
|
namespace Nebula.Launcher.ViewModels.Popup;
|
||||||
|
|
||||||
|
[ViewModelRegister(typeof(EditServerNameView), false)]
|
||||||
|
[ConstructGenerator]
|
||||||
|
public sealed partial class EditServerNameViewModel : PopupViewModelBase
|
||||||
|
{
|
||||||
|
[GenerateProperty] public override PopupMessageService PopupMessageService { get; }
|
||||||
|
[GenerateProperty] public ConfigurationService ConfigurationService { get; }
|
||||||
|
public override string Title => "Edit server name";
|
||||||
|
public override bool IsClosable => true;
|
||||||
|
|
||||||
|
[ObservableProperty] private string _ipInput;
|
||||||
|
[ObservableProperty] private string _nameInput;
|
||||||
|
|
||||||
|
public void OnEnter()
|
||||||
|
{
|
||||||
|
if(string.IsNullOrWhiteSpace(IpInput))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(NameInput))
|
||||||
|
{
|
||||||
|
RemoveServerName();
|
||||||
|
Dispose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddServerName();
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddServerName()
|
||||||
|
{
|
||||||
|
var currentNames = ConfigurationService.GetConfigValue(LauncherConVar.ServerCustomNames)!;
|
||||||
|
currentNames.Add(IpInput, NameInput);
|
||||||
|
ConfigurationService.SetConfigValue(LauncherConVar.ServerCustomNames, currentNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveServerName()
|
||||||
|
{
|
||||||
|
var currentNames = ConfigurationService.GetConfigValue(LauncherConVar.ServerCustomNames)!;
|
||||||
|
currentNames.Remove(IpInput);
|
||||||
|
ConfigurationService.SetConfigValue(LauncherConVar.ServerCustomNames, currentNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void InitialiseInDesignMode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Initialise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,51 +18,59 @@ namespace Nebula.Launcher.ViewModels;
|
|||||||
[ViewModelRegister(typeof(ServerCompoundEntryView), false)]
|
[ViewModelRegister(typeof(ServerCompoundEntryView), false)]
|
||||||
[ConstructGenerator]
|
[ConstructGenerator]
|
||||||
public sealed partial class ServerCompoundEntryViewModel :
|
public sealed partial class ServerCompoundEntryViewModel :
|
||||||
ViewModelBase, IFavoriteEntryModelView, IFilterConsumer, IListEntryModelView
|
ViewModelBase, IFavoriteEntryModelView, IFilterConsumer, IListEntryModelView, IEntryNameHolder
|
||||||
{
|
{
|
||||||
[ObservableProperty] private ServerEntryModelView _currentEntry;
|
[ObservableProperty] private ServerEntryModelView? _currentEntry;
|
||||||
[ObservableProperty] private Control? _entryControl;
|
[ObservableProperty] private Control? _entryControl;
|
||||||
[ObservableProperty] private string _name = "Loading...";
|
[ObservableProperty] private string _message = "Loading server entry...";
|
||||||
[ObservableProperty] private bool _isFavorite;
|
[ObservableProperty] private bool _isFavorite;
|
||||||
[ObservableProperty] private bool _loading = true;
|
[ObservableProperty] private bool _loading = true;
|
||||||
|
|
||||||
|
private string? _name;
|
||||||
|
|
||||||
|
public string? Name
|
||||||
|
{
|
||||||
|
get => _name;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_name = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
|
||||||
|
if (CurrentEntry != null)
|
||||||
|
CurrentEntry.Name = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[GenerateProperty] private RestService RestService { get; }
|
[GenerateProperty] private RestService RestService { get; }
|
||||||
[GenerateProperty] private IServiceProvider ServiceProvider{ get; }
|
[GenerateProperty] private IServiceProvider ServiceProvider{ get; }
|
||||||
[GenerateProperty] private FavoriteServerListProvider FavoriteServerListProvider { get; }
|
[GenerateProperty] private FavoriteServerListProvider FavoriteServerListProvider { get; }
|
||||||
|
|
||||||
private RobustUrl? _url;
|
|
||||||
|
|
||||||
|
|
||||||
protected override void InitialiseInDesignMode()
|
protected override void InitialiseInDesignMode()
|
||||||
{
|
{
|
||||||
|
Name = "TEST.TEST";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Initialise()
|
protected override void Initialise()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerCompoundEntryViewModel LoadServerEntry(RobustUrl url, CancellationToken cancellationToken)
|
public ServerCompoundEntryViewModel LoadServerEntry(RobustUrl url,string? name, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_url = url;
|
Message = "Loading server entry...";
|
||||||
Name = $"Loading {url}...";
|
|
||||||
var status = await RestService.GetAsync<ServerStatus>(url.StatusUri, cancellationToken);
|
var status = await RestService.GetAsync<ServerStatus>(url.StatusUri, cancellationToken);
|
||||||
|
|
||||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
CurrentEntry = ServiceProvider.GetService<ServerEntryModelView>()!.WithData(url,name, status);
|
||||||
{
|
CurrentEntry.IsFavorite = IsFavorite;
|
||||||
CurrentEntry = ServiceProvider.GetService<ServerEntryModelView>()!.WithData(url, status);
|
CurrentEntry.Loading = false;
|
||||||
CurrentEntry.IsFavorite = IsFavorite;
|
Loading = false;
|
||||||
CurrentEntry.Loading = false;
|
|
||||||
Loading = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
var error = new Exception("Unable to load server entry", e);
|
Message = e.Message;
|
||||||
Name = e.Message;
|
|
||||||
}
|
}
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
|
|
||||||
@@ -71,13 +79,7 @@ public sealed partial class ServerCompoundEntryViewModel :
|
|||||||
|
|
||||||
public void ToggleFavorites()
|
public void ToggleFavorites()
|
||||||
{
|
{
|
||||||
if (_url == null)
|
CurrentEntry?.ToggleFavorites();
|
||||||
return;
|
|
||||||
IsFavorite = !IsFavorite;
|
|
||||||
if(IsFavorite)
|
|
||||||
FavoriteServerListProvider.AddFavorite(_url);
|
|
||||||
else
|
|
||||||
FavoriteServerListProvider.RemoveFavorite(_url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace Nebula.Launcher.ViewModels;
|
|||||||
|
|
||||||
[ViewModelRegister(typeof(ServerEntryView), false)]
|
[ViewModelRegister(typeof(ServerEntryView), false)]
|
||||||
[ConstructGenerator]
|
[ConstructGenerator]
|
||||||
public partial class ServerEntryModelView : ViewModelBase, IFilterConsumer, IListEntryModelView, IFavoriteEntryModelView
|
public partial class ServerEntryModelView : ViewModelBase, IFilterConsumer, IListEntryModelView, IFavoriteEntryModelView, IEntryNameHolder
|
||||||
{
|
{
|
||||||
[ObservableProperty] private string _description = "Fetching info...";
|
[ObservableProperty] private string _description = "Fetching info...";
|
||||||
[ObservableProperty] private bool _expandInfo;
|
[ObservableProperty] private bool _expandInfo;
|
||||||
@@ -30,6 +30,13 @@ public partial class ServerEntryModelView : ViewModelBase, IFilterConsumer, ILis
|
|||||||
[ObservableProperty] private bool _runVisible = true;
|
[ObservableProperty] private bool _runVisible = true;
|
||||||
[ObservableProperty] private bool _tagDataVisible;
|
[ObservableProperty] private bool _tagDataVisible;
|
||||||
[ObservableProperty] private bool _loading;
|
[ObservableProperty] private bool _loading;
|
||||||
|
[ObservableProperty] private string _realName;
|
||||||
|
|
||||||
|
public string? Name
|
||||||
|
{
|
||||||
|
get => RealName;
|
||||||
|
set => RealName = value ?? Status.Name;
|
||||||
|
}
|
||||||
|
|
||||||
private ILogger _logger;
|
private ILogger _logger;
|
||||||
private ServerInfo? _serverInfo;
|
private ServerInfo? _serverInfo;
|
||||||
@@ -83,6 +90,8 @@ public partial class ServerEntryModelView : ViewModelBase, IFilterConsumer, ILis
|
|||||||
|
|
||||||
protected override void InitialiseInDesignMode()
|
protected override void InitialiseInDesignMode()
|
||||||
{
|
{
|
||||||
|
IsVisible = true;
|
||||||
|
RealName = "TEST.TEST";
|
||||||
Description = "Server of meow girls! Nya~ \nNyaMeow\nOOOINK!!";
|
Description = "Server of meow girls! Nya~ \nNyaMeow\nOOOINK!!";
|
||||||
Links.Add(new ServerLink("Discord", "discord", "https://cinka.ru"));
|
Links.Add(new ServerLink("Discord", "discord", "https://cinka.ru"));
|
||||||
Status = new ServerStatus("Ameba",
|
Status = new ServerStatus("Ameba",
|
||||||
@@ -119,14 +128,22 @@ public partial class ServerEntryModelView : ViewModelBase, IFilterConsumer, ILis
|
|||||||
OnPropertyChanged(nameof(Status));
|
OnPropertyChanged(nameof(Status));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServerEntryModelView WithData(RobustUrl url, string? name,ServerStatus serverStatus)
|
||||||
public ServerEntryModelView WithData(RobustUrl url, ServerStatus serverStatus)
|
|
||||||
{
|
{
|
||||||
Address = url;
|
Address = url;
|
||||||
SetStatus(serverStatus);
|
SetStatus(serverStatus);
|
||||||
|
Name = name;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void EditName()
|
||||||
|
{
|
||||||
|
var popup = ViewHelperService.GetViewModel<EditServerNameViewModel>();
|
||||||
|
popup.IpInput = Address.ToString();
|
||||||
|
popup.NameInput = Name ?? string.Empty;
|
||||||
|
PopupMessageService.Popup(popup);
|
||||||
|
}
|
||||||
|
|
||||||
public void OpenContentViewer()
|
public void OpenContentViewer()
|
||||||
{
|
{
|
||||||
MainViewModel.RequirePage<ContentBrowserViewModel>().Go(Address, ContentPath.Empty);
|
MainViewModel.RequirePage<ContentBrowserViewModel>().Go(Address, ContentPath.Empty);
|
||||||
|
|||||||
26
Nebula.Launcher/Views/Popup/EditServerNameView.axaml
Normal file
26
Nebula.Launcher/Views/Popup/EditServerNameView.axaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<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:popup="clr-namespace:Nebula.Launcher.ViewModels.Popup"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Nebula.Launcher.Views.Popup.EditServerNameView"
|
||||||
|
x:DataType="popup:EditServerNameViewModel">
|
||||||
|
<Design.DataContext>
|
||||||
|
<popup:EditServerNameViewModel />
|
||||||
|
</Design.DataContext>
|
||||||
|
|
||||||
|
<StackPanel Margin="15" Spacing="10">
|
||||||
|
<Border BoxShadow="{StaticResource DefaultShadow}">
|
||||||
|
<TextBlock Text="{Binding IpInput}" Margin="10,8,10,8"/>
|
||||||
|
</Border>
|
||||||
|
<Border BoxShadow="{StaticResource DefaultShadow}">
|
||||||
|
<TextBox Text="{Binding NameInput}" Watermark="custom server name" />
|
||||||
|
</Border>
|
||||||
|
<Border Background="{StaticResource DefaultSelected}" BoxShadow="{StaticResource DefaultShadow}">
|
||||||
|
<Button Command="{Binding OnEnter}" HorizontalAlignment="Stretch">
|
||||||
|
<Label HorizontalAlignment="Center">Set name</Label>
|
||||||
|
</Button>
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
||||||
20
Nebula.Launcher/Views/Popup/EditServerNameView.axaml.cs
Normal file
20
Nebula.Launcher/Views/Popup/EditServerNameView.axaml.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Nebula.Launcher.ViewModels.Popup;
|
||||||
|
|
||||||
|
namespace Nebula.Launcher.Views.Popup;
|
||||||
|
|
||||||
|
public partial class EditServerNameView : UserControl
|
||||||
|
{
|
||||||
|
public EditServerNameView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EditServerNameView(EditServerNameViewModel viewModel)
|
||||||
|
: this()
|
||||||
|
{
|
||||||
|
DataContext = viewModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,9 +36,14 @@
|
|||||||
Margin="10,0,0,0"
|
Margin="10,0,0,0"
|
||||||
VerticalScrollBarVisibility="Disabled"
|
VerticalScrollBarVisibility="Disabled"
|
||||||
x:Name="AutoScrollViewer">
|
x:Name="AutoScrollViewer">
|
||||||
<Label VerticalAlignment="Center">
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock Text="{Binding Name}" />
|
<Label VerticalAlignment="Center">
|
||||||
</Label>
|
<TextBlock Text="{Binding Name}" />
|
||||||
|
</Label>
|
||||||
|
<Label VerticalAlignment="Center">
|
||||||
|
<TextBlock Text="{Binding Message}" />
|
||||||
|
</Label>
|
||||||
|
</StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|
||||||
<Panel
|
<Panel
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
CornerRadius="10"
|
CornerRadius="10"
|
||||||
Margin="5">
|
Margin="5">
|
||||||
|
|
||||||
<Grid ColumnDefinitions="*,80,50,50" RowDefinitions="35,*,*">
|
<Grid ColumnDefinitions="*,80,50,50,50" RowDefinitions="35,*,*">
|
||||||
<Border
|
<Border
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
BoxShadow="0 3 3 -2 #121212"
|
BoxShadow="0 3 3 -2 #121212"
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
VerticalScrollBarVisibility="Disabled"
|
VerticalScrollBarVisibility="Disabled"
|
||||||
x:Name="AutoScrollViewer">
|
x:Name="AutoScrollViewer">
|
||||||
<Label VerticalAlignment="Center">
|
<Label VerticalAlignment="Center">
|
||||||
<TextBlock Text="{Binding Status.Name}" />
|
<TextBlock Text="{Binding RealName}" />
|
||||||
</Label>
|
</Label>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -67,9 +67,19 @@
|
|||||||
</Label>
|
</Label>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<Panel
|
<Button
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
|
Command="{Binding EditName}"
|
||||||
|
CornerRadius="10,10,10,10"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch">
|
||||||
|
<Svg Margin="4" Path="/Assets/svg/pencil.svg" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Panel
|
||||||
|
Grid.Column="3"
|
||||||
|
Grid.Row="0"
|
||||||
Margin="5,0,0,0">
|
Margin="5,0,0,0">
|
||||||
<Button
|
<Button
|
||||||
Command="{Binding ToggleFavorites}"
|
Command="{Binding ToggleFavorites}"
|
||||||
@@ -90,7 +100,7 @@
|
|||||||
</Panel>
|
</Panel>
|
||||||
|
|
||||||
<Panel
|
<Panel
|
||||||
Grid.Column="3"
|
Grid.Column="4"
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Margin="5,0,0,0">
|
Margin="5,0,0,0">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASingle_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fe27543f11ad92fdb62cde92eebaa1afb3de86a016ad85f76d1554b0389cd3f3_003FSingle_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASingle_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fe27543f11ad92fdb62cde92eebaa1afb3de86a016ad85f76d1554b0389cd3f3_003FSingle_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AString_002EManipulation_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fe75a5575ba872c8ea754c015cb363850e6c661f39569712d5b74aaca67263c_003FString_002EManipulation_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AString_002EManipulation_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fe75a5575ba872c8ea754c015cb363850e6c661f39569712d5b74aaca67263c_003FString_002EManipulation_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AStyle_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fcfbd5689fdab68d1c02f6a9b3c5921abcc409b8743dcc958da77cc1cfcb8e_003FStyle_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AStyle_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fcfbd5689fdab68d1c02f6a9b3c5921abcc409b8743dcc958da77cc1cfcb8e_003FStyle_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATextBox_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F43273dba3ac6a4e11aefe78fbbccf5d36f07542ca37ecebffb25c95d1a1c16b_003FTextBox_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUri_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F6a1fb5a19c4883d19f63515be2d0cce5e0e9929bb30469a912a58ad2e1e6152_003FUri_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUri_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F6a1fb5a19c4883d19f63515be2d0cce5e0e9929bb30469a912a58ad2e1e6152_003FUri_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AValuePrinter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F80d1676fb411442983574149e0b6aebc72e00_003F2f_003F26a40f58_003FValuePrinter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AValuePrinter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F80d1676fb411442983574149e0b6aebc72e00_003F2f_003F26a40f58_003FValuePrinter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AZipFileExtensions_002EZipArchive_002ECreate_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F1dd11f63b66adf34b6a6d76e1e0c0fd1df69d78b5fbfdcdf31c67b6bb40e9e4_003FZipFileExtensions_002EZipArchive_002ECreate_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AZipFileExtensions_002EZipArchive_002ECreate_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F1dd11f63b66adf34b6a6d76e1e0c0fd1df69d78b5fbfdcdf31c67b6bb40e9e4_003FZipFileExtensions_002EZipArchive_002ECreate_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
|||||||
Reference in New Issue
Block a user