- tweak: Favorite button

This commit is contained in:
2025-01-29 12:32:42 +03:00
parent 730e2e5529
commit 37ff25ba70
18 changed files with 233 additions and 75 deletions

View File

@@ -15,6 +15,7 @@
<entry key="Nebula.Launcher/Views/MainWindow.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Pages/AccountInfoPage.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Pages/AccountInfoView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Pages/AddFavoriteView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Pages/ContentBrowserView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Pages/FavoriteServerListView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Pages/ServerListPage.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" id="star">
<path fill="none" fill-rule="evenodd" stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M10.2135354,0.441329894 L12.5301907,5.09668871 C12.6437709,5.3306716 12.8673229,5.49423715 13.1274534,5.53368599 L18.3127795,6.28282419 C18.5232013,6.31151358 18.713271,6.4218659 18.8407265,6.58934431 C18.9681821,6.75682272 19.0224584,6.9675444 18.9914871,7.17465538 C18.9654336,7.34490401 18.8826605,7.50177662 18.7562018,7.62057098 L15.0006864,11.2592422 C14.8108765,11.4385657 14.7257803,11.7002187 14.7744505,11.9548706 L15.679394,17.0828999 C15.7448774,17.5054355 15.4552147,17.9019154 15.0278347,17.9747311 C14.8516089,18.001936 14.6711642,17.9738576 14.5120169,17.8944663 L9.88775575,15.4776038 C9.65675721,15.3522485 9.37670064,15.3522485 9.1457021,15.4776038 L4.49429266,17.9123029 C4.1040442,18.1096521 3.62530757,17.962958 3.41740993,17.5823254 C3.33635184,17.4288523 3.30778438,17.2536748 3.33596502,17.0828999 L4.24090849,11.9548706 C4.28467865,11.7005405 4.20030563,11.441111 4.01467262,11.2592422 L0.23200891,7.62057098 C-0.0773363034,7.31150312 -0.0773363034,6.81484985 0.23200891,6.50578199 C0.358259148,6.3905834 0.515216648,6.31324177 0.684480646,6.28282419 L5.86980673,5.53368599 C6.12870837,5.49136141 6.35105151,5.32868032 6.46706943,5.09668871 L8.78372471,0.441329894 C8.87526213,0.25256864 9.04026912,0.108236628 9.24131794,0.0410719808 C9.44236677,-0.0260926667 9.66241783,-0.0103975019 9.85155801,0.0845974179 C10.0076083,0.16259069 10.1343954,0.287540724 10.2135354,0.441329894 Z" transform="translate(2.5 3)"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" id="star">
<path fill="white" fill-rule="evenodd" stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M10.2135354,0.441329894 L12.5301907,5.09668871 C12.6437709,5.3306716 12.8673229,5.49423715 13.1274534,5.53368599 L18.3127795,6.28282419 C18.5232013,6.31151358 18.713271,6.4218659 18.8407265,6.58934431 C18.9681821,6.75682272 19.0224584,6.9675444 18.9914871,7.17465538 C18.9654336,7.34490401 18.8826605,7.50177662 18.7562018,7.62057098 L15.0006864,11.2592422 C14.8108765,11.4385657 14.7257803,11.7002187 14.7744505,11.9548706 L15.679394,17.0828999 C15.7448774,17.5054355 15.4552147,17.9019154 15.0278347,17.9747311 C14.8516089,18.001936 14.6711642,17.9738576 14.5120169,17.8944663 L9.88775575,15.4776038 C9.65675721,15.3522485 9.37670064,15.3522485 9.1457021,15.4776038 L4.49429266,17.9123029 C4.1040442,18.1096521 3.62530757,17.962958 3.41740993,17.5823254 C3.33635184,17.4288523 3.30778438,17.2536748 3.33596502,17.0828999 L4.24090849,11.9548706 C4.28467865,11.7005405 4.20030563,11.441111 4.01467262,11.2592422 L0.23200891,7.62057098 C-0.0773363034,7.31150312 -0.0773363034,6.81484985 0.23200891,6.50578199 C0.358259148,6.3905834 0.515216648,6.31324177 0.684480646,6.28282419 L5.86980673,5.53368599 C6.12870837,5.49136141 6.35105151,5.32868032 6.46706943,5.09668871 L8.78372471,0.441329894 C8.87526213,0.25256864 9.04026912,0.108236628 9.24131794,0.0410719808 C9.44236677,-0.0260926667 9.66241783,-0.0103975019 9.85155801,0.0845974179 C10.0076083,0.16259069 10.1343954,0.287540724 10.2135354,0.441329894 Z" transform="translate(2.5 3)"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -36,6 +36,10 @@
<DependentUpon>ServerListTab.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Views\Popup\AddFavoriteView.axaml.cs">
<DependentUpon>AddFavoriteView.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<Target Name="BuildCheck" AfterTargets="AfterBuild">

View File

@@ -20,26 +20,21 @@ public partial class MainViewModel : ViewModelBase
{
private readonly List<ListItemTemplate> _templates =
[
new ListItemTemplate(typeof(AccountInfoViewModel), "user", "Account"),
new ListItemTemplate(typeof(ServerListViewModel), "file", "Servers"),
new ListItemTemplate(typeof(ContentBrowserViewModel), "folder", "Content")
new ListItemTemplate(typeof(AccountInfoViewModel), "user", "Account", null),
new ListItemTemplate(typeof(ServerListViewModel), "file", "Servers", false),
new ListItemTemplate(typeof(ServerListViewModel), "star", "Favorites", true),
new ListItemTemplate(typeof(ContentBrowserViewModel), "folder", "Content", null)
];
private readonly List<PopupViewModelBase> _viewQueue = new();
[ObservableProperty] private ViewModelBase _currentPage;
[ObservableProperty] private PopupViewModelBase? _currentPopup;
[ObservableProperty] private string _currentTitle = "Default";
[ObservableProperty] private bool _isEnabled = true;
[ObservableProperty] private bool _isPaneOpen;
[ObservableProperty] private bool _isPopupClosable = true;
[ObservableProperty] private bool _popup;
[ObservableProperty] private ListItemTemplate? _selectedListItem;
[GenerateProperty] private DebugService DebugService { get; } = default!;
@@ -57,22 +52,19 @@ public partial class MainViewModel : ViewModelBase
protected override void Initialise()
{
CurrentPage = ViewHelperService.GetViewModel<AccountInfoViewModel>();
Items = new ObservableCollection<ListItemTemplate>(_templates);
InitialiseInDesignMode();
PopupMessageService.OnPopupRequired += OnPopupRequired;
PopupMessageService.OnCloseRequired += OnPopupCloseRequired;
SelectedListItem = Items.First(vm => vm.ModelType == typeof(AccountInfoViewModel));
}
partial void OnSelectedListItemChanged(ListItemTemplate? value)
{
if (value is null) return;
if (!ViewHelperService.TryGetViewModel(value.ModelType, out var vmb)) return;
if (!ViewHelperService.TryGetViewModel(value.ModelType, out var vmb) || vmb is not IViewModelPage viewModelPage) return;
viewModelPage.OnPageOpen(value.args);
CurrentPage = vmb;
}

View File

@@ -16,7 +16,7 @@ namespace Nebula.Launcher.ViewModels.Pages;
[ViewModelRegister(typeof(AccountInfoView))]
[ConstructGenerator]
public partial class AccountInfoViewModel : ViewModelBase
public partial class AccountInfoViewModel : ViewModelBase, IViewModelPage
{
[ObservableProperty] private bool _authMenuExpand;
@@ -190,6 +190,11 @@ public partial class AccountInfoViewModel : ViewModelBase
ConfigurationService.SetConfigValue(CurrentConVar.AuthProfiles,
Accounts.Select(a => (AuthLoginPassword)a).ToArray());
}
public void OnPageOpen(object? args)
{
}
}
public record AuthLoginPasswordModel(

View File

@@ -22,7 +22,7 @@ namespace Nebula.Launcher.ViewModels.Pages;
[ViewModelRegister(typeof(ContentBrowserView))]
[ConstructGenerator]
public sealed partial class ContentBrowserViewModel : ViewModelBase
public sealed partial class ContentBrowserViewModel : ViewModelBase , IViewModelPage
{
private readonly List<ContentEntry> _root = new();
@@ -204,6 +204,10 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase
_history.RemoveAt(0);
return h;
}
public void OnPageOpen(object? args)
{
}
}
public class ContentEntry

View File

@@ -1,17 +0,0 @@
using System.Collections.ObjectModel;
using Nebula.Shared.Models;
namespace Nebula.Launcher.ViewModels.Pages;
public class FavoriteServerListViewModel : ViewModelBase
{
public ObservableCollection<ServerHubInfo> Servers = new();
protected override void Initialise()
{
}
protected override void InitialiseInDesignMode()
{
}
}

View File

@@ -0,0 +1,6 @@
namespace Nebula.Launcher.ViewModels.Pages;
public interface IViewModelPage
{
public void OnPageOpen(object? args);
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
@@ -32,6 +33,7 @@ public partial class ServerListViewModel
{
var model = ViewHelperService.GetViewModel<ServerEntryModelView>().WithData(server.Item1, server.Item2);
model.OnFavoriteToggle += ()=> RemoveFavorite(model);
model.IsFavorite = true;
return model;
}
@@ -51,23 +53,37 @@ public partial class ServerListViewModel
foreach (var server in servers)
{
var uri = server.ToRobustUrl();
var serverInfo = await RestService.GetAsync<ServerStatus>(uri.StatusUri, CancellationToken.None);
if (serverInfo.Value is null)
try
{
continue;
}
var serverInfo = await RestService.GetAsync<ServerStatus>(uri.StatusUri, CancellationToken.None);
if (serverInfo.Value is null)
{
throw new Exception("Server info is null");
}
FavoriteServers.Add((uri, serverInfo.Value));
FavoriteServers.Add((uri, serverInfo.Value));
}
catch (Exception e)
{
FavoriteServers.Add((uri, new ServerStatus("ErrorLand",$"ERROR: {e.Message}",[],"",-1,-1,-1,false,DateTime.Now, -1)));
}
}
SortFavorite();
}
public void AddFavorite(ServerEntryModelView entryModelView)
{
entryModelView.IsFavorite = true;
AddFavorite(entryModelView.Address);
}
public void AddFavorite(RobustUrl robustUrl)
{
var servers = (ConfigurationService.GetConfigValue(CurrentConVar.Favorites) ?? []).ToList();
servers.Add(entryModelView.Address.ToString());
servers.Add(robustUrl.ToString());
ConfigurationService.SetConfigValue(CurrentConVar.Favorites, servers.ToArray());
FetchFavorite();
}
public void RemoveFavorite(ServerEntryModelView entryModelView)
@@ -75,5 +91,7 @@ public partial class ServerListViewModel
var servers = (ConfigurationService.GetConfigValue(CurrentConVar.Favorites) ?? []).ToList();
servers.Remove(entryModelView.Address.ToString());
ConfigurationService.SetConfigValue(CurrentConVar.Favorites, servers.ToArray());
entryModelView.IsFavorite = false;
FetchFavorite();
}
}

View File

@@ -6,6 +6,7 @@ using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using Nebula.Launcher.Services;
using Nebula.Launcher.ViewModels.Popup;
using Nebula.Launcher.Views.Pages;
using Nebula.Shared.Models;
using Nebula.Shared.Services;
@@ -15,14 +16,17 @@ namespace Nebula.Launcher.ViewModels.Pages;
[ViewModelRegister(typeof(ServerListView))]
[ConstructGenerator]
public partial class ServerListViewModel : ViewModelBase
public partial class ServerListViewModel : ViewModelBase, IViewModelPage
{
[ObservableProperty] private string _searchText = string.Empty;
[ObservableProperty] private bool _isFavoriteMode;
public Action? OnSearchChange;
[GenerateProperty] private HubService HubService { get; } = default!;
[GenerateProperty] private PopupMessageService PopupMessageService { get; }
[GenerateProperty, DesignConstruct] private ViewHelperService ViewHelperService { get; } = default!;
public ObservableCollection<ServerEntryModelView> ServerInfos { get; } = new();
public ObservableCollection<ServerEntryModelView> SortedServers { get; } = new();
private List<ServerHubInfo> UnsortedServers { get; } = new();
//Design think
@@ -31,11 +35,11 @@ public partial class ServerListViewModel : ViewModelBase
FavoriteVisible = true;
SortedFavoriteServers.Add(GetServerEntryModelView(("ss14://localhost".ToRobustUrl(),
new ServerStatus("Nebula", "TestCraft", ["16+", "RU"], "super", 12, 55, 1, false, DateTime.Now, 20))));
ServerInfos.Add(CreateServerView(new ServerHubInfo("ss14://localhost",
SortedServers.Add(CreateServerView(new ServerHubInfo("ss14://localhost",
new ServerStatus("Nebula", "TestCraft", ["16+", "RU"], "super", 12, 55, 1, false, DateTime.Now, 20), [])));
ServerInfos.Add(CreateServerView(new ServerHubInfo("ss14://localhost",
SortedServers.Add(CreateServerView(new ServerHubInfo("ss14://localhost",
new ServerStatus("Nebula", "TestCraft", ["16+", "RU"], "super", 12, 55, 1, false, DateTime.Now, 20), [])));
ServerInfos.Add(CreateServerView(new ServerHubInfo("ss14://localhost",
SortedServers.Add(CreateServerView(new ServerHubInfo("ss14://localhost",
new ServerStatus("Nebula", "TestCraft", ["16+", "RU"], "super", 12, 55, 1, false, DateTime.Now, 20), [])));
}
@@ -74,9 +78,9 @@ public partial class ServerListViewModel : ViewModelBase
{
Task.Run(() =>
{
ServerInfos.Clear();
SortedServers.Clear();
UnsortedServers.Sort(new ServerComparer());
foreach (var server in UnsortedServers.Where(a => CheckServerThink(a.StatusData))) ServerInfos.Add(CreateServerView(server));
foreach (var server in UnsortedServers.Where(a => CheckServerThink(a.StatusData))) SortedServers.Add(CreateServerView(server));
});
}
@@ -97,10 +101,24 @@ public partial class ServerListViewModel : ViewModelBase
{
}
public void AddFavoriteRequired()
{
var p = ViewHelperService.GetViewModel<AddFavoriteViewModel>();
PopupMessageService.Popup(p);
}
public void UpdateRequired()
{
Task.Run(HubService.UpdateHub);
}
public void OnPageOpen(object? args)
{
if (args is bool fav)
{
IsFavoriteMode = fav;
}
}
}
public class ServerComparer : IComparer<ServerHubInfo>, IComparer<ServerStatus>, IComparer<(RobustUrl,ServerStatus)>

View File

@@ -0,0 +1,47 @@
using System;
using CommunityToolkit.Mvvm.ComponentModel;
using Nebula.Launcher.ViewModels.Pages;
using Nebula.Launcher.Views.Pages;
using Nebula.Shared.Services;
using Nebula.Shared.Utils;
using AddFavoriteView = Nebula.Launcher.Views.Popup.AddFavoriteView;
namespace Nebula.Launcher.ViewModels.Popup;
[ViewModelRegister(typeof(AddFavoriteView), false)]
[ConstructGenerator]
public partial class AddFavoriteViewModel : PopupViewModelBase
{
protected override void InitialiseInDesignMode()
{
}
protected override void Initialise()
{
}
[GenerateProperty]
public override PopupMessageService PopupMessageService { get; }
[GenerateProperty] private ServerListViewModel ServerListViewModel { get; }
[GenerateProperty] private DebugService DebugService { get; }
public override string Title => "Add to favorite";
public override bool IsClosable => true;
[ObservableProperty] private string _ipInput;
[ObservableProperty] private string _error = "";
public void OnEnter()
{
try
{
var uri = IpInput.ToRobustUrl();
ServerListViewModel.AddFavorite(uri);
Dispose();
}
catch (Exception e)
{
Error = e.Message;
DebugService.Error(e);
}
}
}

View File

@@ -38,6 +38,7 @@ public partial class ServerEntryModelView : ViewModelBase
[ObservableProperty] private string _description = "Fetching info...";
[ObservableProperty] private bool _expandInfo = false;
[ObservableProperty] private bool _tagDataVisible = false;
[ObservableProperty] private bool _isFavorite = false;
public ServerStatus Status { get; set; } =
new("", "", [], "", -1, -1, -1, false, DateTime.Now, -1);
@@ -51,10 +52,18 @@ public partial class ServerEntryModelView : ViewModelBase
{
if (_serverInfo == null)
{
var result =
await RestService.GetAsync<ServerInfo>(Address.InfoUri, CancellationService.Token);
if (result.Value == null) return null;
_serverInfo = result.Value;
try
{
var result =
await RestService.GetAsync<ServerInfo>(Address.InfoUri, CancellationService.Token);
if (result.Value == null) return null;
_serverInfo = result.Value;
}
catch (Exception e)
{
Description = e.Message;
DebugService.Error(e);
}
}
return _serverInfo;
@@ -248,7 +257,6 @@ public partial class ServerEntryModelView : ViewModelBase
var info = await GetServerInfo();
if (info == null)
{
Description = "Error think!";
return;
}

View File

@@ -22,24 +22,16 @@
Grid.RowSpan="2"
Margin="0,0,0,10"
Padding="0,0,10,0">
<StackPanel Spacing="5">
<Border
Background="{StaticResource DefaultSelected}"
BoxShadow="{StaticResource DefaultShadow}"
IsVisible="{Binding FavoriteVisible}"
Margin="5">
<StackPanel Margin="0,10,0,10" Spacing="5">
<Label
HorizontalAlignment="Center"
Margin="5"
VerticalAlignment="Center">
Favorites
</Label>
<ItemsControl ItemsSource="{Binding SortedFavoriteServers}" Padding="0" />
</StackPanel>
</Border>
<ItemsControl ItemsSource="{Binding ServerInfos}" Padding="0" />
</StackPanel>
<Panel>
<ItemsControl
IsVisible="{Binding IsFavoriteMode}"
ItemsSource="{Binding SortedFavoriteServers}"
Padding="0" />
<ItemsControl
IsVisible="{Binding !IsFavoriteMode}"
ItemsSource="{Binding SortedServers}"
Padding="0" />
</Panel>
</ScrollViewer>
<Border
@@ -49,7 +41,7 @@
Grid.Row="1" />
<Grid
ColumnDefinitions="*,40,40"
ColumnDefinitions="*,40,40,40"
Grid.Row="1"
Margin="5,0,0,0"
RowDefinitions="*">
@@ -60,14 +52,20 @@
VerticalAlignment="Center"
Watermark="Server name..." />
<Button
Command="{Binding FilterRequired}"
Command="{Binding AddFavoriteRequired}"
Grid.Column="1"
Padding="10">
<Svg IsVisible="{Binding IsFavoriteMode}" Path="/Assets/svg/star.svg" />
</Button>
<Button
Command="{Binding FilterRequired}"
Grid.Column="2"
Padding="10">
<Svg Path="/Assets/svg/filter.svg" />
</Button>
<Button
Command="{Binding UpdateRequired}"
Grid.Column="2"
Grid.Column="3"
Padding="10">
<Svg Path="/Assets/svg/refresh.svg" />
</Button>

View File

@@ -0,0 +1,28 @@
<UserControl
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d"
x:Class="Nebula.Launcher.Views.Popup.AddFavoriteView"
x:DataType="popup:AddFavoriteViewModel"
xmlns="https://github.com/avaloniaui"
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"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Design.DataContext>
<popup:AddFavoriteViewModel />
</Design.DataContext>
<StackPanel Margin="15" Spacing="10">
<Border BoxShadow="{StaticResource DefaultShadow}">
<TextBox Text="{Binding IpInput}" Watermark="ss14://localhost" />
</Border>
<Border Background="{StaticResource DefaultSelected}" BoxShadow="{StaticResource DefaultShadow}">
<Button Command="{Binding OnEnter}" HorizontalAlignment="Stretch">
<Label HorizontalAlignment="Center">Add</Label>
</Button>
</Border>
<Label>
<TextBlock Text="{Binding Error}" />
</Label>
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,18 @@
using Avalonia.Controls;
using Nebula.Launcher.ViewModels.Popup;
namespace Nebula.Launcher.Views.Popup;
public partial class AddFavoriteView : UserControl
{
public AddFavoriteView()
{
InitializeComponent();
}
public AddFavoriteView(AddFavoriteViewModel viewModel)
: this()
{
DataContext = viewModel;
}
}

View File

@@ -23,7 +23,7 @@
BoxShadow="-2 0 5 -1 #121212"
CornerRadius="10"
Margin="5">
<Grid ColumnDefinitions="*,80,50" RowDefinitions="35,*,*">
<Grid ColumnDefinitions="*,80,50,50" RowDefinitions="35,*,*">
<Border
Background="Transparent"
BoxShadow="0 3 3 -1 #121212"
@@ -70,6 +70,28 @@
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>
<Panel
Grid.Column="3"
Grid.Row="0"
Margin="5,0,0,0">
<Button
Command="{Binding RunInstance}"
CornerRadius="10,10,10,10"

View File

@@ -1,3 +1,3 @@
namespace Nebula.Shared.Models;
public record ListItemTemplate(Type ModelType, string IconKey, string Label);
public record ListItemTemplate(Type ModelType, string IconKey, string Label, object? args);