- tweak: server viewmodel cache
This commit is contained in:
@@ -16,19 +16,11 @@ public partial class ServerListViewModel
|
|||||||
[GenerateProperty] private ConfigurationService ConfigurationService { get; }
|
[GenerateProperty] private ConfigurationService ConfigurationService { get; }
|
||||||
[GenerateProperty] private RestService RestService { get; }
|
[GenerateProperty] private RestService RestService { get; }
|
||||||
|
|
||||||
public readonly List<(RobustUrl,ServerStatus)> RawFavoriteServers = new();
|
public ObservableCollection<ServerEntryModelView> FavoriteServers { get; } = new();
|
||||||
|
|
||||||
public ServerEntryModelView GetServerEntryModelView((RobustUrl, ServerStatus) server)
|
private async void UpdateFavoriteEntries()
|
||||||
{
|
{
|
||||||
var model = ViewHelperService.GetViewModel<ServerEntryModelView>().WithData(server.Item1, server.Item2);
|
FavoriteServers.Clear();
|
||||||
model.OnFavoriteToggle += ()=> RemoveFavorite(model);
|
|
||||||
model.IsFavorite = true;
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void FetchFavorite()
|
|
||||||
{
|
|
||||||
RawFavoriteServers.Clear();
|
|
||||||
|
|
||||||
var servers = ConfigurationService.GetConfigValue(CurrentConVar.Favorites);
|
var servers = ConfigurationService.GetConfigValue(CurrentConVar.Favorites);
|
||||||
if (servers is null || servers.Length == 0)
|
if (servers is null || servers.Length == 0)
|
||||||
@@ -38,21 +30,9 @@ public partial class ServerListViewModel
|
|||||||
|
|
||||||
foreach (var server in servers)
|
foreach (var server in servers)
|
||||||
{
|
{
|
||||||
var uri = server.ToRobustUrl();
|
var s = await ServerViewContainer.Get(server.ToRobustUrl());
|
||||||
try
|
s.IsFavorite = true;
|
||||||
{
|
FavoriteServers.Add(s);
|
||||||
var serverInfo = await RestService.GetAsync<ServerStatus>(uri.StatusUri, CancellationToken.None);
|
|
||||||
if (serverInfo.Value is null)
|
|
||||||
{
|
|
||||||
throw new Exception("Server info is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
RawFavoriteServers.Add((uri, serverInfo.Value));
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
RawFavoriteServers.Add((uri, new ServerStatus("ErrorLand",$"ERROR: {e.Message}",[],"",-1,-1,-1,false,DateTime.Now, -1)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +47,7 @@ public partial class ServerListViewModel
|
|||||||
var servers = (ConfigurationService.GetConfigValue(CurrentConVar.Favorites) ?? []).ToList();
|
var servers = (ConfigurationService.GetConfigValue(CurrentConVar.Favorites) ?? []).ToList();
|
||||||
servers.Add(robustUrl.ToString());
|
servers.Add(robustUrl.ToString());
|
||||||
ConfigurationService.SetConfigValue(CurrentConVar.Favorites, servers.ToArray());
|
ConfigurationService.SetConfigValue(CurrentConVar.Favorites, servers.ToArray());
|
||||||
FetchFavorite();
|
UpdateFavoriteEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveFavorite(ServerEntryModelView entryModelView)
|
public void RemoveFavorite(ServerEntryModelView entryModelView)
|
||||||
@@ -76,6 +56,6 @@ public partial class ServerListViewModel
|
|||||||
servers.Remove(entryModelView.Address.ToString());
|
servers.Remove(entryModelView.Address.ToString());
|
||||||
ConfigurationService.SetConfigValue(CurrentConVar.Favorites, servers.ToArray());
|
ConfigurationService.SetConfigValue(CurrentConVar.Favorites, servers.ToArray());
|
||||||
entryModelView.IsFavorite = false;
|
entryModelView.IsFavorite = false;
|
||||||
FetchFavorite();
|
UpdateFavoriteEntries();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,27 +22,30 @@ public partial class ServerListViewModel : ViewModelBase, IViewModelPage
|
|||||||
[ObservableProperty] private string _searchText = string.Empty;
|
[ObservableProperty] private string _searchText = string.Empty;
|
||||||
|
|
||||||
[ObservableProperty] private bool _isFavoriteMode;
|
[ObservableProperty] private bool _isFavoriteMode;
|
||||||
public SortedList<float, ServerEntryModelView> Servers { get; } = new(Comparer<float>.Create((x,y)=>y.CompareTo(x)));
|
|
||||||
|
|
||||||
private ServerViewContainer ServerViewContainer;
|
public ObservableCollection<ServerEntryModelView> Servers { get; }= new();
|
||||||
|
|
||||||
public Action? OnSearchChange;
|
public Action? OnSearchChange;
|
||||||
[GenerateProperty] private HubService HubService { get; } = default!;
|
[GenerateProperty] private HubService HubService { get; }
|
||||||
[GenerateProperty] private PopupMessageService PopupMessageService { get; }
|
[GenerateProperty] private PopupMessageService PopupMessageService { get; }
|
||||||
[GenerateProperty, DesignConstruct] private ViewHelperService ViewHelperService { get; } = default!;
|
[GenerateProperty] private CancellationService CancellationService { get; }
|
||||||
|
[GenerateProperty] private DebugService DebugService { get; }
|
||||||
|
[GenerateProperty, DesignConstruct] private ViewHelperService ViewHelperService { get; }
|
||||||
|
|
||||||
|
private ServerViewContainer ServerViewContainer { get; set; }
|
||||||
|
|
||||||
private List<ServerHubInfo> UnsortedServers { get; } = new();
|
private List<ServerHubInfo> UnsortedServers { get; } = new();
|
||||||
|
|
||||||
//Design think
|
//Design think
|
||||||
protected override void InitialiseInDesignMode()
|
protected override void InitialiseInDesignMode()
|
||||||
{
|
{
|
||||||
ServerViewContainer = new ServerViewContainer(this);
|
ServerViewContainer = new ServerViewContainer(this, RestService, CancellationService, DebugService, ViewHelperService);
|
||||||
}
|
}
|
||||||
|
|
||||||
//real think
|
//real think
|
||||||
protected override void Initialise()
|
protected override void Initialise()
|
||||||
{
|
{
|
||||||
ServerViewContainer = new ServerViewContainer(this);
|
ServerViewContainer = new ServerViewContainer(this, RestService, CancellationService, DebugService, ViewHelperService);
|
||||||
|
|
||||||
foreach (var info in HubService.ServerList) UnsortedServers.Add(info);
|
foreach (var info in HubService.ServerList) UnsortedServers.Add(info);
|
||||||
|
|
||||||
@@ -51,40 +54,35 @@ public partial class ServerListViewModel : ViewModelBase, IViewModelPage
|
|||||||
OnSearchChange += OnChangeSearch;
|
OnSearchChange += OnChangeSearch;
|
||||||
|
|
||||||
if (!HubService.IsUpdating) UpdateServerEntries();
|
if (!HubService.IsUpdating) UpdateServerEntries();
|
||||||
//FetchFavorite();
|
UpdateFavoriteEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateServerEntries()
|
private void UpdateServerEntries()
|
||||||
{
|
{
|
||||||
Servers.Clear();
|
Servers.Clear();
|
||||||
OnPropertyChanged(nameof(Servers));
|
Task.Run(async () =>
|
||||||
foreach (var info in UnsortedServers.Where(a=>CheckServerThink(a.StatusData)))
|
|
||||||
{
|
{
|
||||||
var view = ServerViewContainer.Get(info.Address.ToRobustUrl(), info.StatusData);
|
UnsortedServers.Sort(new ServerComparer());
|
||||||
float players = info.StatusData.Players;
|
foreach (var info in UnsortedServers.Where(a => CheckServerThink(a.StatusData)))
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
try
|
var view = await ServerViewContainer.Get(info.Address.ToRobustUrl(), info.StatusData);
|
||||||
{
|
Servers.Add(view);
|
||||||
Servers.Add(players,view);
|
|
||||||
OnPropertyChanged(nameof(Servers));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Console.WriteLine(e);
|
|
||||||
players += 0.01f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnChangeSearch()
|
private void OnChangeSearch()
|
||||||
{
|
{
|
||||||
if(string.IsNullOrEmpty(SearchText)) return;
|
if(string.IsNullOrEmpty(SearchText)) return;
|
||||||
|
|
||||||
UpdateServerEntries();
|
if(IsFavoriteMode)
|
||||||
|
{
|
||||||
|
UpdateFavoriteEntries();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UpdateServerEntries();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HubServerChangedEventArgs(HubServerChangedEventArgs obj)
|
private void HubServerChangedEventArgs(HubServerChangedEventArgs obj)
|
||||||
@@ -95,7 +93,13 @@ public partial class ServerListViewModel : ViewModelBase, IViewModelPage
|
|||||||
if (obj.Action == HubServerChangeAction.Remove)
|
if (obj.Action == HubServerChangeAction.Remove)
|
||||||
foreach (var info in obj.Items)
|
foreach (var info in obj.Items)
|
||||||
UnsortedServers.Remove(info);
|
UnsortedServers.Remove(info);
|
||||||
if (obj.Action == HubServerChangeAction.Clear) UnsortedServers.Clear();
|
if (obj.Action == HubServerChangeAction.Clear)
|
||||||
|
{
|
||||||
|
UnsortedServers.Clear();
|
||||||
|
ServerViewContainer.Clear();
|
||||||
|
Servers.Clear();
|
||||||
|
UpdateFavoriteEntries();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckServerThink(ServerStatus hubInfo)
|
private bool CheckServerThink(ServerStatus hubInfo)
|
||||||
@@ -128,18 +132,45 @@ public partial class ServerListViewModel : ViewModelBase, IViewModelPage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ServerViewContainer(ServerListViewModel serverListViewModel)
|
public class ServerViewContainer(
|
||||||
|
ServerListViewModel serverListViewModel,
|
||||||
|
RestService restService,
|
||||||
|
CancellationService cancellationService,
|
||||||
|
DebugService debugService,
|
||||||
|
ViewHelperService viewHelperService
|
||||||
|
)
|
||||||
{
|
{
|
||||||
private readonly Dictionary<RobustUrl, ServerEntryModelView> _entries = new();
|
private readonly Dictionary<RobustUrl, ServerEntryModelView> _entries = new();
|
||||||
|
|
||||||
public ServerEntryModelView Get(RobustUrl url, ServerStatus serverStatus)
|
public void Clear()
|
||||||
|
{
|
||||||
|
_entries.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServerEntryModelView> Get(RobustUrl url, ServerStatus? serverStatus = null)
|
||||||
{
|
{
|
||||||
if (_entries.TryGetValue(url, out var entry))
|
if (_entries.TryGetValue(url, out var entry))
|
||||||
{
|
{
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = serverListViewModel.GetServerEntryModelView((url, serverStatus));
|
try
|
||||||
|
{
|
||||||
|
serverStatus ??= await restService.GetAsync<ServerStatus>(url.StatusUri, cancellationService.Token);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
debugService.Error(e);
|
||||||
|
serverStatus = new ServerStatus("ErrorLand", $"ERROR: {e.Message}", [], "", -1, -1, -1, false, DateTime.Now,
|
||||||
|
-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = viewHelperService.GetViewModel<ServerEntryModelView>().WithData(url, serverStatus);
|
||||||
|
entry.OnFavoriteToggle += () =>
|
||||||
|
{
|
||||||
|
if (entry.IsFavorite) serverListViewModel.RemoveFavorite(entry);
|
||||||
|
else serverListViewModel.AddFavorite(entry);
|
||||||
|
};
|
||||||
_entries.Add(url, entry);
|
_entries.Add(url, entry);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
|
|||||||
@@ -54,10 +54,7 @@ public partial class ServerEntryModelView : ViewModelBase
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result =
|
_serverInfo = await RestService.GetAsync<ServerInfo>(Address.InfoUri, CancellationService.Token);
|
||||||
await RestService.GetAsync<ServerInfo>(Address.InfoUri, CancellationService.Token);
|
|
||||||
if (result.Value == null) return null;
|
|
||||||
_serverInfo = result.Value;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -100,23 +97,6 @@ public partial class ServerEntryModelView : ViewModelBase
|
|||||||
CurrLog = ViewHelperService.GetViewModel<LogPopupModelView>();
|
CurrLog = ViewHelperService.GetViewModel<LogPopupModelView>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerEntryModelView WithData(ServerHubInfo value)
|
|
||||||
{
|
|
||||||
Status = value.StatusData;
|
|
||||||
Address = value.Address.ToRobustUrl();
|
|
||||||
Tags.Clear();
|
|
||||||
foreach (var tag in Status.Tags)
|
|
||||||
{
|
|
||||||
Tags.Add(tag);
|
|
||||||
}
|
|
||||||
foreach (var tag in value.InferredTags)
|
|
||||||
{
|
|
||||||
Tags.Add(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ServerEntryModelView WithData(RobustUrl url, ServerStatus serverStatus)
|
public ServerEntryModelView WithData(RobustUrl url, ServerStatus serverStatus)
|
||||||
{
|
{
|
||||||
Status = serverStatus;
|
Status = serverStatus;
|
||||||
|
|||||||
@@ -25,11 +25,11 @@
|
|||||||
<Panel>
|
<Panel>
|
||||||
<ItemsControl
|
<ItemsControl
|
||||||
IsVisible="{Binding IsFavoriteMode}"
|
IsVisible="{Binding IsFavoriteMode}"
|
||||||
ItemsSource="{Binding Servers.Values}"
|
ItemsSource="{Binding FavoriteServers}"
|
||||||
Padding="0" />
|
Padding="0" />
|
||||||
<ItemsControl
|
<ItemsControl
|
||||||
IsVisible="{Binding !IsFavoriteMode}"
|
IsVisible="{Binding !IsFavoriteMode}"
|
||||||
ItemsSource="{Binding Servers.Values}"
|
ItemsSource="{Binding Servers}"
|
||||||
Padding="0" />
|
Padding="0" />
|
||||||
</Panel>
|
</Panel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class RestService
|
|||||||
_debug = debug;
|
_debug = debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RestResult<T>> GetAsync<T>(Uri uri, CancellationToken cancellationToken)
|
public async Task<RestResult<T>> GetAsync<T>(Uri uri, CancellationToken cancellationToken) where T : notnull
|
||||||
{
|
{
|
||||||
var response = await _client.GetAsync(uri, cancellationToken);
|
var response = await _client.GetAsync(uri, cancellationToken);
|
||||||
return await ReadResult<T>(response, cancellationToken);
|
return await ReadResult<T>(response, cancellationToken);
|
||||||
@@ -35,7 +35,7 @@ public class RestService
|
|||||||
return result.Value ?? defaultValue;
|
return result.Value ?? defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RestResult<K>> PostAsync<K, T>(T information, Uri uri, CancellationToken cancellationToken)
|
public async Task<RestResult<K>> PostAsync<K, T>(T information, Uri uri, CancellationToken cancellationToken) where K : notnull
|
||||||
{
|
{
|
||||||
var json = JsonSerializer.Serialize(information, _serializerOptions);
|
var json = JsonSerializer.Serialize(information, _serializerOptions);
|
||||||
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||||
@@ -43,7 +43,7 @@ public class RestService
|
|||||||
return await ReadResult<K>(response, cancellationToken);
|
return await ReadResult<K>(response, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RestResult<T>> PostAsync<T>(Stream stream, Uri uri, CancellationToken cancellationToken)
|
public async Task<RestResult<T>> PostAsync<T>(Stream stream, Uri uri, CancellationToken cancellationToken) where T : notnull
|
||||||
{
|
{
|
||||||
using var multipartFormContent =
|
using var multipartFormContent =
|
||||||
new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture));
|
new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture));
|
||||||
@@ -52,7 +52,7 @@ public class RestService
|
|||||||
return await ReadResult<T>(response, cancellationToken);
|
return await ReadResult<T>(response, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RestResult<T>> DeleteAsync<T>(Uri uri, CancellationToken cancellationToken)
|
public async Task<RestResult<T>> DeleteAsync<T>(Uri uri, CancellationToken cancellationToken) where T : notnull
|
||||||
{
|
{
|
||||||
var response = await _client.DeleteAsync(uri, cancellationToken);
|
var response = await _client.DeleteAsync(uri, cancellationToken);
|
||||||
return await ReadResult<T>(response, cancellationToken);
|
return await ReadResult<T>(response, cancellationToken);
|
||||||
@@ -61,19 +61,19 @@ public class RestService
|
|||||||
private async Task<RestResult<T>> ReadResult<T>(HttpResponseMessage response, CancellationToken cancellationToken) where T : notnull
|
private async Task<RestResult<T>> ReadResult<T>(HttpResponseMessage response, CancellationToken cancellationToken) where T : notnull
|
||||||
{
|
{
|
||||||
var content = await response.Content.ReadAsStringAsync(cancellationToken);
|
var content = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||||
|
|
||||||
|
if (typeof(T) == typeof(RawResult))
|
||||||
|
return (new RestResult<RawResult>(new RawResult(content), null, response.StatusCode) as RestResult<T>)!;
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
_debug.Debug($"SUCCESSFUL GET CONTENT {typeof(T)}");
|
_debug.Debug($"SUCCESSFUL GET CONTENT {typeof(T)}");
|
||||||
if (typeof(T) == typeof(RawResult))
|
|
||||||
return (new RestResult<RawResult>(new RawResult(content), null, response.StatusCode) as RestResult<T>)!;
|
|
||||||
|
|
||||||
return new RestResult<T>(await response.Content.AsJson<T>(), null,
|
return new RestResult<T>(await response.Content.AsJson<T>(), null,
|
||||||
response.StatusCode);
|
response.StatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
_debug.Error("ERROR " + response.StatusCode + " " + content);
|
throw new HttpRequestException();
|
||||||
return new RestResult<T>(default, "response code:" + response.StatusCode, response.StatusCode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,16 +81,16 @@ public class RestResult<T>
|
|||||||
{
|
{
|
||||||
public string Message = "Ok";
|
public string Message = "Ok";
|
||||||
public HttpStatusCode StatusCode;
|
public HttpStatusCode StatusCode;
|
||||||
public T? Value;
|
public T Value;
|
||||||
|
|
||||||
public RestResult(T? value, string? message, HttpStatusCode statusCode)
|
public RestResult(T value, string? message, HttpStatusCode statusCode)
|
||||||
{
|
{
|
||||||
Value = value;
|
Value = value;
|
||||||
if (message != null) Message = message;
|
if (message != null) Message = message;
|
||||||
StatusCode = statusCode;
|
StatusCode = statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator T?(RestResult<T> result)
|
public static implicit operator T(RestResult<T> result)
|
||||||
{
|
{
|
||||||
return result.Value;
|
return result.Value;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user