- tweak: Search think
This commit is contained in:
@@ -19,4 +19,7 @@ public static class CurrentConVar
|
|||||||
public static readonly ConVar AuthServers = ConVar.Build<string[]>("launcher.authServers", [
|
public static readonly ConVar AuthServers = ConVar.Build<string[]>("launcher.authServers", [
|
||||||
"https://auth.spacestation14.com/api/auth"
|
"https://auth.spacestation14.com/api/auth"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
public static readonly ConVar AuthProfiles = ConVar.Build<AuthLoginPassword[]>("auth.profiles", []);
|
||||||
|
public static readonly ConVar AuthCurrent = ConVar.Build<AuthLoginPassword>("auth.current");
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Nebula.Launcher.FileApis.Interfaces;
|
using Nebula.Launcher.FileApis.Interfaces;
|
||||||
|
|
||||||
@@ -34,6 +35,8 @@ public class FileApi : IReadWriteFileApi
|
|||||||
|
|
||||||
using var stream = File.OpenWrite(currPath);
|
using var stream = File.OpenWrite(currPath);
|
||||||
input.CopyTo(stream);
|
input.CopyTo(stream);
|
||||||
|
stream.Flush(true);
|
||||||
|
Console.WriteLine(input.Length + " " + stream.Length);
|
||||||
stream.Close();
|
stream.Close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization.Metadata;
|
||||||
|
|
||||||
namespace Nebula.Launcher.Services;
|
namespace Nebula.Launcher.Services;
|
||||||
|
|
||||||
@@ -25,38 +28,86 @@ public class ConVar
|
|||||||
[ServiceRegister]
|
[ServiceRegister]
|
||||||
public class ConfigurationService
|
public class ConfigurationService
|
||||||
{
|
{
|
||||||
public ConfigurationService()
|
private readonly FileService _fileService;
|
||||||
{
|
private readonly DebugService _debugService;
|
||||||
|
|
||||||
|
public ConfigurationService(FileService fileService, DebugService debugService)
|
||||||
|
{
|
||||||
|
_fileService = fileService;
|
||||||
|
_debugService = debugService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object? GetConfigValue(ConVar conVar)
|
public object? GetConfigValue(ConVar conVar)
|
||||||
{
|
{
|
||||||
return conVar.DefaultValue;
|
if(!_fileService.ConfigurationApi.TryOpen(conVar.Name, out var stream) ||
|
||||||
}
|
!ReadStream(stream, conVar.Type, out var obj))
|
||||||
|
return conVar.DefaultValue;
|
||||||
|
|
||||||
public T? GetConfigValue<T>(ConVar conVar)
|
_debugService.Log("Loading config file: " + conVar.Name);
|
||||||
{
|
|
||||||
var value = GetConfigValue(conVar);
|
|
||||||
if (value is not T tv) return default;
|
|
||||||
return tv;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryGetConfigValue(ConVar conVar,[NotNullWhen(true)] out object? value)
|
return obj;
|
||||||
{
|
|
||||||
value = GetConfigValue(conVar);
|
|
||||||
return value != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryGetConfigValue<T>(ConVar conVar, [NotNullWhen(true)] out T? value)
|
|
||||||
{
|
|
||||||
value = GetConfigValue<T>(conVar);
|
|
||||||
return value != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetConfigValue(ConVar conVar, object value)
|
public void SetConfigValue(ConVar conVar, object value)
|
||||||
{
|
{
|
||||||
if(conVar.Type != value.GetType())
|
if(conVar.Type != value.GetType())
|
||||||
|
{
|
||||||
|
_debugService.Error("Error config file " + conVar.Name + ": Type is not equals " + value.GetType() + " " + conVar.Type);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_debugService.Log("Saving config file: " + conVar.Name);
|
||||||
|
|
||||||
|
var stream = new MemoryStream();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var st = new StreamWriter(stream);
|
||||||
|
st.Write(JsonSerializer.Serialize(value));
|
||||||
|
st.Flush();
|
||||||
|
_fileService.ConfigurationApi.Save(conVar.Name, st.BaseStream);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_debugService.Error(e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ReadStream(Stream stream, Type type,[NotNullWhen(true)] out object? obj)
|
||||||
|
{
|
||||||
|
obj = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
obj = JsonSerializer.Deserialize(stream, JsonTypeInfo.CreateJsonTypeInfo(type, JsonSerializerOptions.Default));
|
||||||
|
return obj != null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_debugService.Error(e.Message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ConfigExt
|
||||||
|
{
|
||||||
|
public static T? GetConfigValue<T>(this ConfigurationService configurationService,ConVar conVar)
|
||||||
|
{
|
||||||
|
var value = configurationService.GetConfigValue(conVar);
|
||||||
|
if (value is not T tv) return default;
|
||||||
|
return tv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryGetConfigValue(this ConfigurationService configurationService,ConVar conVar,[NotNullWhen(true)] out object? value)
|
||||||
|
{
|
||||||
|
value = configurationService.GetConfigValue(conVar);
|
||||||
|
return value != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryGetConfigValue<T>(this ConfigurationService configurationService,ConVar conVar, [NotNullWhen(true)] out T? value)
|
||||||
|
{
|
||||||
|
value = configurationService.GetConfigValue<T>(conVar);
|
||||||
|
return value != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,16 +11,19 @@ using Robust.LoaderApi;
|
|||||||
|
|
||||||
namespace Nebula.Launcher.Services;
|
namespace Nebula.Launcher.Services;
|
||||||
|
|
||||||
|
[ServiceRegister]
|
||||||
public class FileService
|
public class FileService
|
||||||
{
|
{
|
||||||
public static string RootPath = Path.Join(Environment.GetFolderPath(
|
public static string RootPath = Path.Join(Environment.GetFolderPath(
|
||||||
Environment.SpecialFolder.ApplicationData), "./Datum/");
|
Environment.SpecialFolder.ApplicationData), "./Datum/");
|
||||||
|
|
||||||
private readonly DebugService _debugService;
|
private readonly DebugService _debugService;
|
||||||
public readonly IReadWriteFileApi ContentFileApi;
|
|
||||||
|
|
||||||
|
public readonly IReadWriteFileApi ContentFileApi;
|
||||||
public readonly IReadWriteFileApi EngineFileApi;
|
public readonly IReadWriteFileApi EngineFileApi;
|
||||||
public readonly IReadWriteFileApi ManifestFileApi;
|
public readonly IReadWriteFileApi ManifestFileApi;
|
||||||
|
public readonly IReadWriteFileApi ConfigurationApi;
|
||||||
|
|
||||||
private HashApi? _hashApi;
|
private HashApi? _hashApi;
|
||||||
|
|
||||||
public FileService(DebugService debugService)
|
public FileService(DebugService debugService)
|
||||||
@@ -29,6 +32,7 @@ public class FileService
|
|||||||
ContentFileApi = CreateFileApi("content/");
|
ContentFileApi = CreateFileApi("content/");
|
||||||
EngineFileApi = CreateFileApi("engine/");
|
EngineFileApi = CreateFileApi("engine/");
|
||||||
ManifestFileApi = CreateFileApi("manifest/");
|
ManifestFileApi = CreateFileApi("manifest/");
|
||||||
|
ConfigurationApi = CreateFileApi("config/");
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<RobustManifestItem> ManifestItems
|
public List<RobustManifestItem> ManifestItems
|
||||||
|
|||||||
36
Nebula.Launcher/Services/PopupMessageService.cs
Normal file
36
Nebula.Launcher/Services/PopupMessageService.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Nebula.Launcher.ViewModels;
|
||||||
|
|
||||||
|
namespace Nebula.Launcher.Services;
|
||||||
|
|
||||||
|
[ServiceRegister]
|
||||||
|
public class PopupMessageService
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
|
public Action<PopupViewModelBase?>? OnPopupRequired;
|
||||||
|
|
||||||
|
public PopupMessageService(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PopupInfo(string info)
|
||||||
|
{
|
||||||
|
var message = _serviceProvider.GetService<InfoPopupViewModel>();
|
||||||
|
message.InfoText = info;
|
||||||
|
PopupMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PopupMessage(PopupViewModelBase viewModelBase)
|
||||||
|
{
|
||||||
|
OnPopupRequired?.Invoke(viewModelBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClosePopup()
|
||||||
|
{
|
||||||
|
OnPopupRequired?.Invoke(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
28
Nebula.Launcher/Utils/DelegateCommand.cs
Normal file
28
Nebula.Launcher/Utils/DelegateCommand.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using Nebula.Launcher.ViewModels;
|
||||||
|
|
||||||
|
namespace Nebula.Launcher.Utils;
|
||||||
|
|
||||||
|
public class DelegateCommand<T> : ICommand
|
||||||
|
{
|
||||||
|
private readonly Action<T> _func;
|
||||||
|
public readonly Ref<T> TRef = new();
|
||||||
|
|
||||||
|
public DelegateCommand(Action<T> func)
|
||||||
|
{
|
||||||
|
_func = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanExecute(object? parameter)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute(object? parameter)
|
||||||
|
{
|
||||||
|
_func(TRef.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler? CanExecuteChanged;
|
||||||
|
}
|
||||||
6
Nebula.Launcher/Utils/Ref.cs
Normal file
6
Nebula.Launcher/Utils/Ref.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Nebula.Launcher.Utils;
|
||||||
|
|
||||||
|
public class Ref<T>
|
||||||
|
{
|
||||||
|
public T Value = default!;
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using Nebula.Launcher.Services;
|
using Nebula.Launcher.Services;
|
||||||
|
using Nebula.Launcher.Utils;
|
||||||
using Nebula.Launcher.ViewHelper;
|
using Nebula.Launcher.ViewHelper;
|
||||||
using Nebula.Launcher.Views.Pages;
|
using Nebula.Launcher.Views.Pages;
|
||||||
|
|
||||||
@@ -12,6 +14,8 @@ namespace Nebula.Launcher.ViewModels;
|
|||||||
[ViewRegister(typeof(AccountInfoView))]
|
[ViewRegister(typeof(AccountInfoView))]
|
||||||
public partial class AccountInfoViewModel : ViewModelBase
|
public partial class AccountInfoViewModel : ViewModelBase
|
||||||
{
|
{
|
||||||
|
private readonly PopupMessageService _popupMessageService;
|
||||||
|
private readonly ConfigurationService _configurationService;
|
||||||
private readonly AuthService _authService;
|
private readonly AuthService _authService;
|
||||||
|
|
||||||
public ObservableCollection<AuthLoginPasswordModel> Accounts { get; } = new();
|
public ObservableCollection<AuthLoginPasswordModel> Accounts { get; } = new();
|
||||||
@@ -25,20 +29,39 @@ public partial class AccountInfoViewModel : ViewModelBase
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _currentAuthServer = String.Empty;
|
private string _currentAuthServer = String.Empty;
|
||||||
|
|
||||||
|
public ObservableCollection<string> AuthUrls { get; } = new();
|
||||||
|
|
||||||
[ObservableProperty] private bool _pageEnabled = true;
|
[ObservableProperty] private bool _pageEnabled = true;
|
||||||
|
|
||||||
public AuthLoginPassword CurrentALP => new AuthLoginPassword(CurrentLogin, CurrentPassword, CurrentAuthServer);
|
private AuthLoginPassword CurrentAlp
|
||||||
|
{
|
||||||
|
get => new(CurrentLogin, CurrentPassword, CurrentAuthServer);
|
||||||
|
set
|
||||||
|
{
|
||||||
|
CurrentLogin = value.Login;
|
||||||
|
CurrentPassword = value.Password;
|
||||||
|
CurrentAuthServer = value.AuthServer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Design think
|
//Design think
|
||||||
public AccountInfoViewModel()
|
public AccountInfoViewModel()
|
||||||
{
|
{
|
||||||
AddAccount(new AuthLoginPassword("Binka","12341",""));
|
AddAccount(new AuthLoginPassword("Binka","12341",""));
|
||||||
|
AuthUrls.Add("https://cinka.ru");
|
||||||
|
AuthUrls.Add("https://cinka.ru");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Real think
|
//Real think
|
||||||
public AccountInfoViewModel(IServiceProvider serviceProvider, AuthService authService) : base(serviceProvider)
|
public AccountInfoViewModel(IServiceProvider serviceProvider, PopupMessageService popupMessageService,
|
||||||
|
ConfigurationService configurationService, AuthService authService) : base(serviceProvider)
|
||||||
{
|
{
|
||||||
|
//_popupMessageService = mainViewModel;
|
||||||
|
_popupMessageService = popupMessageService;
|
||||||
|
_configurationService = configurationService;
|
||||||
_authService = authService;
|
_authService = authService;
|
||||||
|
|
||||||
|
ReadAuthConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AuthByALP(AuthLoginPassword authLoginPassword)
|
public void AuthByALP(AuthLoginPassword authLoginPassword)
|
||||||
@@ -52,12 +75,18 @@ public partial class AccountInfoViewModel : ViewModelBase
|
|||||||
|
|
||||||
public async void DoAuth()
|
public async void DoAuth()
|
||||||
{
|
{
|
||||||
PageEnabled = false;
|
_popupMessageService.PopupInfo("Auth think, please wait...");
|
||||||
if(await _authService.Auth(CurrentALP))
|
|
||||||
Console.WriteLine("Hello, " + _authService.SelectedAuth!.Username);
|
if(await _authService.Auth(CurrentAlp))
|
||||||
|
{
|
||||||
|
_popupMessageService.ClosePopup();
|
||||||
|
_popupMessageService.PopupInfo("Hello, " + _authService.SelectedAuth!.Username);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Console.WriteLine("Shit!");
|
{
|
||||||
PageEnabled = true;
|
_popupMessageService.ClosePopup();
|
||||||
|
_popupMessageService.PopupInfo("Well, shit is happened");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddAccount(AuthLoginPassword authLoginPassword)
|
private void AddAccount(AuthLoginPassword authLoginPassword)
|
||||||
@@ -78,39 +107,41 @@ public partial class AccountInfoViewModel : ViewModelBase
|
|||||||
Accounts.Add(alpm);
|
Accounts.Add(alpm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ReadAuthConfig()
|
||||||
|
{
|
||||||
|
foreach (var profile in
|
||||||
|
_configurationService.GetConfigValue<AuthLoginPassword[]>(CurrentConVar.AuthProfiles)!)
|
||||||
|
{
|
||||||
|
AddAccount(profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
var currProfile = _configurationService.GetConfigValue<AuthLoginPassword>(CurrentConVar.AuthProfiles);
|
||||||
|
|
||||||
|
if (currProfile != null)
|
||||||
|
{
|
||||||
|
CurrentAlp = currProfile;
|
||||||
|
DoAuth();
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthUrls.Clear();
|
||||||
|
var authUrls = _configurationService.GetConfigValue<string[]>(CurrentConVar.AuthServers)!;
|
||||||
|
foreach (var url in authUrls)
|
||||||
|
{
|
||||||
|
AuthUrls.Add(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public void OnSaveProfile()
|
public void OnSaveProfile()
|
||||||
{
|
{
|
||||||
AddAccount(CurrentALP);
|
AddAccount(CurrentAlp);
|
||||||
|
_configurationService.SetConfigValue(CurrentConVar.AuthProfiles, Accounts.Select(a => (AuthLoginPassword) a).ToArray());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class Ref<T>
|
public string AuthItemSelect
|
||||||
{
|
|
||||||
public T Value = default!;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DelegateCommand<T> : ICommand
|
|
||||||
{
|
|
||||||
private readonly Action<T> _func;
|
|
||||||
public readonly Ref<T> TRef = new();
|
|
||||||
|
|
||||||
public DelegateCommand(Action<T> func)
|
|
||||||
{
|
{
|
||||||
_func = func;
|
set => CurrentAuthServer = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanExecute(object? parameter)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Execute(object? parameter)
|
|
||||||
{
|
|
||||||
_func(TRef.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public event EventHandler? CanExecuteChanged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public record AuthLoginPasswordModel(string Login, string Password, string AuthServer, ICommand OnSelect = default!, ICommand OnDelete = default!)
|
public record AuthLoginPasswordModel(string Login, string Password, string AuthServer, ICommand OnSelect = default!, ICommand OnDelete = default!)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ public partial class InfoPopupViewModel : PopupViewModelBase
|
|||||||
public InfoPopupViewModel(IServiceProvider serviceProvider) : base(serviceProvider)
|
public InfoPopupViewModel(IServiceProvider serviceProvider) : base(serviceProvider)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Title => "Info";
|
public override string Title => "Info";
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
|||||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Nebula.Launcher.Models;
|
using Nebula.Launcher.Models;
|
||||||
|
using Nebula.Launcher.Services;
|
||||||
using Nebula.Launcher.ViewHelper;
|
using Nebula.Launcher.ViewHelper;
|
||||||
using Nebula.Launcher.Views;
|
using Nebula.Launcher.Views;
|
||||||
using Nebula.Launcher.Views.Pages;
|
using Nebula.Launcher.Views.Pages;
|
||||||
@@ -21,38 +23,25 @@ public partial class MainViewModel : ViewModelBase
|
|||||||
{
|
{
|
||||||
TryGetViewModel(typeof(AccountInfoViewModel), out var model);
|
TryGetViewModel(typeof(AccountInfoViewModel), out var model);
|
||||||
_currentPage = model!;
|
_currentPage = model!;
|
||||||
TryGetViewModel(typeof(MessagePopupViewModel), out var viewModelBase);
|
|
||||||
_messagePopupViewModel = (MessagePopupViewModel)viewModelBase!;
|
|
||||||
|
|
||||||
Items = new ObservableCollection<ListItemTemplate>(_templates);
|
Items = new ObservableCollection<ListItemTemplate>(_templates);
|
||||||
|
|
||||||
SelectedListItem = Items.First(vm => vm.ModelType == typeof(AccountInfoViewModel));
|
SelectedListItem = Items.First(vm => vm.ModelType == typeof(AccountInfoViewModel));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MainViewModel(AccountInfoViewModel accountInfoViewModel, MessagePopupViewModel messagePopupViewModel,
|
public MainViewModel(AccountInfoViewModel accountInfoViewModel, PopupMessageService popupMessageService,
|
||||||
IServiceProvider serviceProvider): base(serviceProvider)
|
IServiceProvider serviceProvider): base(serviceProvider)
|
||||||
{
|
{
|
||||||
_currentPage = accountInfoViewModel;
|
_currentPage = accountInfoViewModel;
|
||||||
_messagePopupViewModel = messagePopupViewModel;
|
_popupMessageService = popupMessageService;
|
||||||
Items = new ObservableCollection<ListItemTemplate>(_templates);
|
Items = new ObservableCollection<ListItemTemplate>(_templates);
|
||||||
|
|
||||||
_messagePopupViewModel.OnOpenRequired += () => OnOpenRequired();
|
_popupMessageService.OnPopupRequired += OnPopupRequired;
|
||||||
_messagePopupViewModel.OnCloseRequired += () => OnCloseRequired();
|
|
||||||
|
|
||||||
SelectedListItem = Items.First(vm => vm.ModelType == typeof(AccountInfoViewModel));
|
SelectedListItem = Items.First(vm => vm.ModelType == typeof(AccountInfoViewModel));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCloseRequired()
|
private readonly Queue<PopupViewModelBase> _viewQueue = new();
|
||||||
{
|
|
||||||
IsEnabled = true;
|
|
||||||
Popup = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnOpenRequired()
|
|
||||||
{
|
|
||||||
IsEnabled = false;
|
|
||||||
Popup = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly List<ListItemTemplate> _templates =
|
private readonly List<ListItemTemplate> _templates =
|
||||||
[
|
[
|
||||||
@@ -66,10 +55,15 @@ public partial class MainViewModel : ViewModelBase
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private ViewModelBase _currentPage;
|
private ViewModelBase _currentPage;
|
||||||
|
|
||||||
|
private readonly PopupMessageService _popupMessageService;
|
||||||
|
|
||||||
[ObservableProperty] private bool _isEnabled = true;
|
[ObservableProperty] private bool _isEnabled = true;
|
||||||
[ObservableProperty] private bool _popup;
|
[ObservableProperty] private bool _popup;
|
||||||
|
|
||||||
private readonly MessagePopupViewModel _messagePopupViewModel;
|
[ObservableProperty]
|
||||||
|
private PopupViewModelBase? _currentPopup;
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _currentTitle = "Default";
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private ListItemTemplate? _selectedListItem;
|
private ListItemTemplate? _selectedListItem;
|
||||||
@@ -84,20 +78,63 @@ public partial class MainViewModel : ViewModelBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
CurrentPage = vmb;
|
CurrentPage = vmb;
|
||||||
|
|
||||||
var model = GetViewModel<InfoPopupViewModel>();
|
|
||||||
model.InfoText = "Переключили прикол!";
|
|
||||||
|
|
||||||
_messagePopupViewModel.PopupMessage(model);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableCollection<ListItemTemplate> Items { get; }
|
public ObservableCollection<ListItemTemplate> Items { get; }
|
||||||
|
|
||||||
|
public void PopupMessage(PopupViewModelBase viewModelBase)
|
||||||
|
{
|
||||||
|
if (CurrentPopup == null)
|
||||||
|
{
|
||||||
|
CurrentPopup = viewModelBase;
|
||||||
|
CurrentTitle = viewModelBase.Title;
|
||||||
|
OnOpenRequired();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_viewQueue.Enqueue(viewModelBase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCloseRequired()
|
||||||
|
{
|
||||||
|
IsEnabled = true;
|
||||||
|
Popup = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnOpenRequired()
|
||||||
|
{
|
||||||
|
IsEnabled = false;
|
||||||
|
Popup = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPopupRequired(PopupViewModelBase? viewModelBase)
|
||||||
|
{
|
||||||
|
if (viewModelBase is null)
|
||||||
|
{
|
||||||
|
ClosePopup();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PopupMessage(viewModelBase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private void TriggerPane()
|
private void TriggerPane()
|
||||||
{
|
{
|
||||||
IsPaneOpen = !IsPaneOpen;
|
IsPaneOpen = !IsPaneOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
public void ClosePopup()
|
||||||
|
{
|
||||||
|
if (!_viewQueue.TryDequeue(out var viewModelBase))
|
||||||
|
OnCloseRequired();
|
||||||
|
else
|
||||||
|
CurrentTitle = viewModelBase.Title;
|
||||||
|
|
||||||
|
CurrentPopup = viewModelBase;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Windows.Input;
|
|
||||||
using Avalonia.Logging;
|
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
using CommunityToolkit.Mvvm.Input;
|
|
||||||
using Nebula.Launcher.ViewHelper;
|
|
||||||
using Nebula.Launcher.Views.Popup;
|
|
||||||
|
|
||||||
namespace Nebula.Launcher.ViewModels;
|
|
||||||
|
|
||||||
[ViewRegister(typeof(MessagePopupView))]
|
|
||||||
public partial class MessagePopupViewModel : ViewModelBase
|
|
||||||
{
|
|
||||||
public MessagePopupViewModel() : base()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public MessagePopupViewModel(IServiceProvider serviceProvider) : base(serviceProvider)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action? OnCloseRequired;
|
|
||||||
public Action? OnOpenRequired;
|
|
||||||
|
|
||||||
public Queue<PopupViewModelBase> ViewQueue = new();
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private PopupViewModelBase? _currentPopup;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string _currentTitle = "Default";
|
|
||||||
|
|
||||||
public void PopupMessage(PopupViewModelBase viewModelBase)
|
|
||||||
{
|
|
||||||
Console.WriteLine(viewModelBase.Title);
|
|
||||||
if (CurrentPopup == null)
|
|
||||||
{
|
|
||||||
CurrentPopup = viewModelBase;
|
|
||||||
CurrentTitle = viewModelBase.Title;
|
|
||||||
OnOpenRequired?.Invoke();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ViewQueue.Enqueue(viewModelBase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
private void TriggerClose()
|
|
||||||
{
|
|
||||||
ClosePopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
private void ClosePopup()
|
|
||||||
{
|
|
||||||
Console.WriteLine("Gadeem");
|
|
||||||
if (!ViewQueue.TryDequeue(out var viewModelBase))
|
|
||||||
OnCloseRequired?.Invoke();
|
|
||||||
else
|
|
||||||
CurrentTitle = viewModelBase.Title;
|
|
||||||
|
|
||||||
CurrentPopup = viewModelBase;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Nebula.Launcher.Models;
|
using Nebula.Launcher.Models;
|
||||||
using Nebula.Launcher.Services;
|
using Nebula.Launcher.Services;
|
||||||
@@ -12,7 +13,11 @@ namespace Nebula.Launcher.ViewModels;
|
|||||||
[ViewRegister(typeof(ServerListView))]
|
[ViewRegister(typeof(ServerListView))]
|
||||||
public partial class ServerListViewModel : ViewModelBase
|
public partial class ServerListViewModel : ViewModelBase
|
||||||
{
|
{
|
||||||
public ObservableCollection<ServerHubInfo> ServerInfos { get; } = new ObservableCollection<ServerHubInfo>();
|
public ObservableCollection<ServerHubInfo> ServerInfos { get; } = new();
|
||||||
|
|
||||||
|
public Action? OnSearchChange;
|
||||||
|
|
||||||
|
[ObservableProperty] private string _searchText;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private ServerHubInfo? _selectedListItem;
|
private ServerHubInfo? _selectedListItem;
|
||||||
@@ -29,6 +34,12 @@ public partial class ServerListViewModel : ViewModelBase
|
|||||||
public ServerListViewModel(IServiceProvider serviceProvider, HubService hubService) : base(serviceProvider)
|
public ServerListViewModel(IServiceProvider serviceProvider, HubService hubService) : base(serviceProvider)
|
||||||
{
|
{
|
||||||
hubService.HubServerChangedEventArgs += HubServerChangedEventArgs;
|
hubService.HubServerChangedEventArgs += HubServerChangedEventArgs;
|
||||||
|
OnSearchChange += OnChangeSearch;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnChangeSearch()
|
||||||
|
{
|
||||||
|
SortServers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HubServerChangedEventArgs(HubServerChangedEventArgs obj)
|
private void HubServerChangedEventArgs(HubServerChangedEventArgs obj)
|
||||||
@@ -48,13 +59,24 @@ public partial class ServerListViewModel : ViewModelBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SortServers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SortServers()
|
||||||
|
{
|
||||||
ServerInfos.Clear();
|
ServerInfos.Clear();
|
||||||
UnsortedServers.Sort(new ServerComparer());
|
UnsortedServers.Sort(new ServerComparer());
|
||||||
foreach (var VARIABLE in UnsortedServers)
|
foreach (var server in UnsortedServers.Where(CheckServerThink))
|
||||||
{
|
{
|
||||||
ServerInfos.Add(VARIABLE);
|
ServerInfos.Add(server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool CheckServerThink(ServerHubInfo hubInfo)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(SearchText)) return true;
|
||||||
|
return hubInfo.StatusData.Name.ToLower().Contains(SearchText.ToLower());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ServerComparer : IComparer<ServerHubInfo>
|
public class ServerComparer : IComparer<ServerHubInfo>
|
||||||
|
|||||||
@@ -97,7 +97,44 @@
|
|||||||
CornerRadius="10"
|
CornerRadius="10"
|
||||||
Height="320"
|
Height="320"
|
||||||
Width="520">
|
Width="520">
|
||||||
<popup:MessagePopupView />
|
<Grid RowDefinitions="35,*,20">
|
||||||
|
<Border
|
||||||
|
BorderThickness="0,0,0,2"
|
||||||
|
CornerRadius="10,10,0,0"
|
||||||
|
Grid.Row="0">
|
||||||
|
<Panel Margin="12,0,0,0" VerticalAlignment="Center">
|
||||||
|
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Center">
|
||||||
|
<Label VerticalAlignment="Center" Content="{Binding CurrentTitle}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<Button
|
||||||
|
Content="X"
|
||||||
|
Margin="0"
|
||||||
|
CornerRadius="0,10,0,0"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Padding="10,8,10,8"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Command="{Binding ClosePopupCommand}"/>
|
||||||
|
</Panel>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<TransitioningContentControl Content="{Binding CurrentPopup}" Grid.Row="1" />
|
||||||
|
|
||||||
|
<Border
|
||||||
|
BorderThickness="0,2,0,2"
|
||||||
|
CornerRadius="0,0,10,10"
|
||||||
|
Grid.Row="2">
|
||||||
|
<Panel Margin="12,0,12,0" VerticalAlignment="Center">
|
||||||
|
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Center">
|
||||||
|
<Label
|
||||||
|
FontSize="8"
|
||||||
|
Foreground="#666666"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
Дальше бога нет...
|
||||||
|
</Label>
|
||||||
|
</StackPanel>
|
||||||
|
</Panel>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
</Panel>
|
</Panel>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<Window
|
<Window
|
||||||
Height="400"
|
Height="500"
|
||||||
Icon="/Assets/avalonia-logo.ico"
|
Icon="/Assets/avalonia-logo.ico"
|
||||||
MinHeight="400"
|
MinHeight="500"
|
||||||
MinWidth="600"
|
MinWidth="800"
|
||||||
Title="Nebula.Launcher"
|
Title="Nebula.Launcher"
|
||||||
Width="800"
|
Width="800"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
|
|||||||
@@ -12,34 +12,43 @@
|
|||||||
<Design.DataContext>
|
<Design.DataContext>
|
||||||
<viewModels:AccountInfoViewModel />
|
<viewModels:AccountInfoViewModel />
|
||||||
</Design.DataContext>
|
</Design.DataContext>
|
||||||
<Grid ColumnDefinitions="*,1.5*" RowDefinitions="*">
|
<Grid ColumnDefinitions="*,1.5*" RowDefinitions="*" Margin="15">
|
||||||
<StackPanel Grid.Column="0" Grid.Row="0">
|
<StackPanel Grid.Column="0" Grid.Row="0">
|
||||||
<Border
|
<Border
|
||||||
CornerRadius="10"
|
CornerRadius="10"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Padding="15">
|
Padding="15">
|
||||||
<StackPanel HorizontalAlignment="Center">
|
<StackPanel HorizontalAlignment="Center" Spacing="15">
|
||||||
<Image
|
<Image
|
||||||
Height="100"
|
Height="100"
|
||||||
Margin="0,0,0,20"
|
Margin="0,0,0,20"
|
||||||
Source="/Assets/account.png" />
|
Source="/Assets/account.png" />
|
||||||
<Grid ColumnDefinitions="120, 100" RowDefinitions="Auto, Auto, Auto">
|
<Grid ColumnDefinitions="100, 100" RowDefinitions="Auto, Auto, Auto, Auto" VerticalAlignment="Center">
|
||||||
<Label Grid.Column="0" Grid.Row="0">Login:</Label>
|
<Label Grid.Column="0" Grid.Row="0" VerticalAlignment="Center">Login:</Label>
|
||||||
<TextBox
|
<TextBox
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Text="{Binding CurrentLogin}"/>
|
Text="{Binding CurrentLogin}"/>
|
||||||
<Label Grid.Column="0" Grid.Row="1">Password:</Label>
|
<Label Grid.Column="0" Grid.Row="1" VerticalAlignment="Center">Password:</Label>
|
||||||
<TextBox
|
<TextBox
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
PasswordChar="#"
|
PasswordChar="#"
|
||||||
Text="{Binding CurrentPassword}" />
|
Text="{Binding CurrentPassword}" />
|
||||||
<Label Grid.Column="0" Grid.Row="2">Auth server:</Label>
|
<Label Grid.Column="0" Grid.Row="2" VerticalAlignment="Center">Auth server:</Label>
|
||||||
<TextBox
|
<TextBox
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Text="{Binding CurrentAuthServer}"/>
|
Text="{Binding CurrentAuthServer}"/>
|
||||||
|
<ScrollViewer Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" Height="80">
|
||||||
|
<ListBox Margin="15" Background="#00000000" ItemsSource="{Binding AuthUrls}" SelectedItem="{Binding AuthItemSelect}">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Label><TextBlock Text="{Binding}"/></Label>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
</ScrollViewer>
|
||||||
</Grid>
|
</Grid>
|
||||||
<StackPanel
|
<StackPanel
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
|
|||||||
@@ -147,7 +147,7 @@
|
|||||||
<TextBox
|
<TextBox
|
||||||
Margin="0"
|
Margin="0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Watermark="Server name..." />
|
Watermark="Server name..." Text="{Binding SearchText}" TextChanged="TextBox_OnTextChanged"/>
|
||||||
<Button Grid.Column="1" Padding="10">
|
<Button Grid.Column="1" Padding="10">
|
||||||
<Image Source="/Assets/filter.png" />
|
<Image Source="/Assets/filter.png" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -17,4 +17,10 @@ public partial class ServerListView : UserControl
|
|||||||
{
|
{
|
||||||
DataContext = viewModel;
|
DataContext = viewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TextBox_OnTextChanged(object? sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var context = (ServerListViewModel?)DataContext;
|
||||||
|
context?.OnSearchChange?.Invoke();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
<UserControl
|
|
||||||
d:DesignHeight="320"
|
|
||||||
d:DesignWidth="520"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
x:Class="Nebula.Launcher.Views.Popup.MessagePopupView"
|
|
||||||
x:DataType="viewModels:MessagePopupViewModel"
|
|
||||||
xmlns="https://github.com/avaloniaui"
|
|
||||||
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:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
|
||||||
|
|
||||||
<Design.DataContext>
|
|
||||||
<viewModels:MessagePopupViewModel />
|
|
||||||
</Design.DataContext>
|
|
||||||
|
|
||||||
<Grid RowDefinitions="35,*,20">
|
|
||||||
<Border
|
|
||||||
BorderThickness="0,0,0,2"
|
|
||||||
CornerRadius="10,10,0,0"
|
|
||||||
Grid.Row="0">
|
|
||||||
<Panel Margin="12,0,12,0" VerticalAlignment="Center">
|
|
||||||
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Center">
|
|
||||||
<Label VerticalAlignment="Center">Title</Label>
|
|
||||||
</StackPanel>
|
|
||||||
<Button
|
|
||||||
Content="Close"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Padding="15,0,15,0"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
x:Name="CloseButton" />
|
|
||||||
</Panel>
|
|
||||||
</Border>
|
|
||||||
|
|
||||||
<TransitioningContentControl Content="{Binding CurrentPopup}" Grid.Row="0" />
|
|
||||||
|
|
||||||
<Border
|
|
||||||
BorderThickness="0,2,0,2"
|
|
||||||
CornerRadius="0,0,10,10"
|
|
||||||
Grid.Row="2">
|
|
||||||
<Panel Margin="12,0,12,0" VerticalAlignment="Center">
|
|
||||||
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Center">
|
|
||||||
<Label
|
|
||||||
FontSize="8"
|
|
||||||
Foreground="#666666"
|
|
||||||
VerticalAlignment="Center">
|
|
||||||
Дальше бога нет...
|
|
||||||
</Label>
|
|
||||||
</StackPanel>
|
|
||||||
</Panel>
|
|
||||||
</Border>
|
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Avalonia;
|
|
||||||
using Avalonia.Controls;
|
|
||||||
using Avalonia.Markup.Xaml;
|
|
||||||
using Nebula.Launcher.ViewModels;
|
|
||||||
|
|
||||||
namespace Nebula.Launcher.Views.Popup;
|
|
||||||
|
|
||||||
public partial class MessagePopupView : UserControl
|
|
||||||
{
|
|
||||||
// This constructor is used when the view is created by the XAML Previewer
|
|
||||||
public MessagePopupView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
// This constructor is used when the view is created via dependency injection
|
|
||||||
public MessagePopupView(MessagePopupViewModel viewModel)
|
|
||||||
: this()
|
|
||||||
{
|
|
||||||
DataContext = viewModel;
|
|
||||||
Console.WriteLine("NO SOSAL");
|
|
||||||
CloseButton.KeyDown += (_,_) => Console.WriteLine("GGG11");
|
|
||||||
CloseButton.Click += (_,_) => Console.WriteLine("GGG");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user