mirror of
https://github.com/Stone-Red-Code/Decho.git
synced 2026-09-04 08:56:14 +02:00
Code cleanup
This commit is contained in:
@@ -35,86 +35,6 @@ public sealed class ConnectionService : IDisposable
|
|||||||
private readonly Dictionary<string, ServerConnection> _connections = new(StringComparer.OrdinalIgnoreCase);
|
private readonly Dictionary<string, ServerConnection> _connections = new(StringComparer.OrdinalIgnoreCase);
|
||||||
internal IReadOnlyDictionary<string, ServerConnection> Connections => _connections;
|
internal IReadOnlyDictionary<string, ServerConnection> Connections => _connections;
|
||||||
|
|
||||||
private async Task<ServerModel> ConnectCoreAsync(ConnectDialogResult dialogResult)
|
|
||||||
{
|
|
||||||
ConnectionManager conn = new ConnectionManager();
|
|
||||||
|
|
||||||
ConnectResult result;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result = await conn.ConnectAsync(dialogResult, _ => { });
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
await conn.DisposeAsync();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
LoginResponse login = result.Login;
|
|
||||||
UserModel userModel = new UserModel(login.Username, login.DisplayName ?? login.Username, login.NicknameColor);
|
|
||||||
|
|
||||||
ObservableCollection<ChannelModel> channels = [];
|
|
||||||
ServerModel serverModel = new ServerModel(
|
|
||||||
Guid.NewGuid().ToString("N"),
|
|
||||||
new Uri(dialogResult.ServerUrl).Host,
|
|
||||||
channels,
|
|
||||||
dialogResult.ServerUrl,
|
|
||||||
isConnected: true,
|
|
||||||
connectedUser: login.Username);
|
|
||||||
|
|
||||||
ServerConnection serverEntry = new ServerConnection(conn, conn.Api!, serverModel, userModel);
|
|
||||||
|
|
||||||
foreach (ChannelDto ch in result.Channels)
|
|
||||||
{
|
|
||||||
ChannelModel channelModel = ChannelModelFromDto(ch);
|
|
||||||
channels.Add(channelModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
WireConnectionEvents(serverEntry, conn);
|
|
||||||
|
|
||||||
_connections[dialogResult.ServerUrl] = serverEntry;
|
|
||||||
SaveRefreshToken(dialogResult.ServerUrl, dialogResult.RememberMe);
|
|
||||||
ServerAdded?.Invoke(serverModel);
|
|
||||||
|
|
||||||
AutoJoinRemainingChannels(dialogResult.ServerUrl, result.Channels);
|
|
||||||
|
|
||||||
return serverModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void AutoJoinRemainingChannels(string serverUrl, List<ChannelDto> channels)
|
|
||||||
{
|
|
||||||
ClientConfig config = ConfigManager.Load();
|
|
||||||
List<string> leftChannels = config.SavedServers
|
|
||||||
.FirstOrDefault(s => string.Equals(s.Url, serverUrl, StringComparison.OrdinalIgnoreCase))
|
|
||||||
?.LeftChannels ?? [];
|
|
||||||
|
|
||||||
foreach (ChannelDto ch in channels)
|
|
||||||
{
|
|
||||||
if (string.Equals(ch.Name, HubConstants.DefaultChannel, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leftChannels.Contains(ch.Name, StringComparer.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_ = await JoinChannelAsync(serverUrl, ch.Name);
|
|
||||||
}
|
|
||||||
catch (EchoHub.Client.Services.ChannelPasswordRequiredException)
|
|
||||||
{
|
|
||||||
// protected channel — join stays manual
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// skip channels we can't join
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<ServerModel> ConnectAsync(string serverUrl, string username, string password, bool isRegister, bool rememberMe)
|
public async Task<ServerModel> ConnectAsync(string serverUrl, string username, string password, bool isRegister, bool rememberMe)
|
||||||
{
|
{
|
||||||
ConnectDialogResult dialogResult = new ConnectDialogResult(
|
ConnectDialogResult dialogResult = new ConnectDialogResult(
|
||||||
@@ -129,24 +49,6 @@ public sealed class ConnectionService : IDisposable
|
|||||||
_ = await ConnectCoreAsync(dialogResult);
|
_ = await ConnectCoreAsync(dialogResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<ServerConnection?> CleanupConnectionAsync(string serverUrl)
|
|
||||||
{
|
|
||||||
if (!_connections.TryGetValue(serverUrl, out ServerConnection? entry))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry.Server.IsConnected = false;
|
|
||||||
entry.Server.IsConnecting = false;
|
|
||||||
|
|
||||||
await entry.Manager.CleanupAsync();
|
|
||||||
entry.ApiClient.Dispose();
|
|
||||||
await entry.Manager.DisposeAsync();
|
|
||||||
|
|
||||||
_ = _connections.Remove(serverUrl);
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DisconnectAsync(string serverUrl)
|
public async Task DisconnectAsync(string serverUrl)
|
||||||
{
|
{
|
||||||
ServerConnection? entry = await CleanupConnectionAsync(serverUrl);
|
ServerConnection? entry = await CleanupConnectionAsync(serverUrl);
|
||||||
@@ -163,26 +65,6 @@ public sealed class ConnectionService : IDisposable
|
|||||||
ServerRemoved?.Invoke(serverUrl);
|
ServerRemoved?.Invoke(serverUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ModifyConfig(string serverUrl, Action<ClientConfig, SavedServer?> action)
|
|
||||||
{
|
|
||||||
ClientConfig config = ConfigManager.Load();
|
|
||||||
SavedServer? saved = config.SavedServers.FirstOrDefault(s =>
|
|
||||||
string.Equals(s.Url, serverUrl, StringComparison.OrdinalIgnoreCase));
|
|
||||||
action(config, saved);
|
|
||||||
ConfigManager.Save(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RemoveServerFromConfig(string serverUrl)
|
|
||||||
{
|
|
||||||
ModifyConfig(serverUrl, (config, saved) =>
|
|
||||||
{
|
|
||||||
if (saved is not null)
|
|
||||||
{
|
|
||||||
_ = config.SavedServers.Remove(saved);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SendMessageAsync(string serverUrl, string channelName, string content)
|
public async Task SendMessageAsync(string serverUrl, string channelName, string content)
|
||||||
{
|
{
|
||||||
if (!_connections.TryGetValue(serverUrl, out ServerConnection? entry))
|
if (!_connections.TryGetValue(serverUrl, out ServerConnection? entry))
|
||||||
@@ -256,17 +138,6 @@ public sealed class ConnectionService : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RemoveFromLeftChannels(string serverUrl, string channelName)
|
|
||||||
{
|
|
||||||
ClientConfig config = ConfigManager.Load();
|
|
||||||
SavedServer? saved = config.SavedServers
|
|
||||||
.FirstOrDefault(s => string.Equals(s.Url, serverUrl, StringComparison.OrdinalIgnoreCase));
|
|
||||||
if (saved is not null && saved.LeftChannels.Remove(channelName))
|
|
||||||
{
|
|
||||||
ConfigManager.Save(config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<MessageModel>> GetHistoryAsync(string serverUrl, string channelName, int count = HubConstants.DefaultHistoryCount, int offset = 0)
|
public async Task<List<MessageModel>> GetHistoryAsync(string serverUrl, string channelName, int count = HubConstants.DefaultHistoryCount, int offset = 0)
|
||||||
{
|
{
|
||||||
if (!_connections.TryGetValue(serverUrl, out ServerConnection? entry))
|
if (!_connections.TryGetValue(serverUrl, out ServerConnection? entry))
|
||||||
@@ -591,6 +462,135 @@ public sealed class ConnectionService : IDisposable
|
|||||||
return _connections.TryGetValue(serverUrl, out ServerConnection? conn) ? conn : null;
|
return _connections.TryGetValue(serverUrl, out ServerConnection? conn) ? conn : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ModifyConfig(string serverUrl, Action<ClientConfig, SavedServer?> action)
|
||||||
|
{
|
||||||
|
ClientConfig config = ConfigManager.Load();
|
||||||
|
SavedServer? saved = config.SavedServers.FirstOrDefault(s =>
|
||||||
|
string.Equals(s.Url, serverUrl, StringComparison.OrdinalIgnoreCase));
|
||||||
|
action(config, saved);
|
||||||
|
ConfigManager.Save(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RemoveServerFromConfig(string serverUrl)
|
||||||
|
{
|
||||||
|
ModifyConfig(serverUrl, (config, saved) =>
|
||||||
|
{
|
||||||
|
if (saved is not null)
|
||||||
|
{
|
||||||
|
_ = config.SavedServers.Remove(saved);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RemoveFromLeftChannels(string serverUrl, string channelName)
|
||||||
|
{
|
||||||
|
ClientConfig config = ConfigManager.Load();
|
||||||
|
SavedServer? saved = config.SavedServers
|
||||||
|
.FirstOrDefault(s => string.Equals(s.Url, serverUrl, StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (saved is not null && saved.LeftChannels.Remove(channelName))
|
||||||
|
{
|
||||||
|
ConfigManager.Save(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<ServerModel> ConnectCoreAsync(ConnectDialogResult dialogResult)
|
||||||
|
{
|
||||||
|
ConnectionManager conn = new ConnectionManager();
|
||||||
|
|
||||||
|
ConnectResult result;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = await conn.ConnectAsync(dialogResult, _ => { });
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
await conn.DisposeAsync();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoginResponse login = result.Login;
|
||||||
|
UserModel userModel = new UserModel(login.Username, login.DisplayName ?? login.Username, login.NicknameColor);
|
||||||
|
|
||||||
|
ObservableCollection<ChannelModel> channels = [];
|
||||||
|
ServerModel serverModel = new ServerModel(
|
||||||
|
Guid.NewGuid().ToString("N"),
|
||||||
|
new Uri(dialogResult.ServerUrl).Host,
|
||||||
|
channels,
|
||||||
|
dialogResult.ServerUrl,
|
||||||
|
isConnected: true,
|
||||||
|
connectedUser: login.Username);
|
||||||
|
|
||||||
|
ServerConnection serverEntry = new ServerConnection(conn, conn.Api!, serverModel, userModel);
|
||||||
|
|
||||||
|
foreach (ChannelDto ch in result.Channels)
|
||||||
|
{
|
||||||
|
ChannelModel channelModel = ChannelModelFromDto(ch);
|
||||||
|
channels.Add(channelModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
WireConnectionEvents(serverEntry, conn);
|
||||||
|
|
||||||
|
_connections[dialogResult.ServerUrl] = serverEntry;
|
||||||
|
SaveRefreshToken(dialogResult.ServerUrl, dialogResult.RememberMe);
|
||||||
|
ServerAdded?.Invoke(serverModel);
|
||||||
|
|
||||||
|
AutoJoinRemainingChannels(dialogResult.ServerUrl, result.Channels);
|
||||||
|
|
||||||
|
return serverModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void AutoJoinRemainingChannels(string serverUrl, List<ChannelDto> channels)
|
||||||
|
{
|
||||||
|
ClientConfig config = ConfigManager.Load();
|
||||||
|
List<string> leftChannels = config.SavedServers
|
||||||
|
.FirstOrDefault(s => string.Equals(s.Url, serverUrl, StringComparison.OrdinalIgnoreCase))
|
||||||
|
?.LeftChannels ?? [];
|
||||||
|
|
||||||
|
foreach (ChannelDto ch in channels)
|
||||||
|
{
|
||||||
|
if (string.Equals(ch.Name, HubConstants.DefaultChannel, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftChannels.Contains(ch.Name, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_ = await JoinChannelAsync(serverUrl, ch.Name);
|
||||||
|
}
|
||||||
|
catch (EchoHub.Client.Services.ChannelPasswordRequiredException)
|
||||||
|
{
|
||||||
|
// protected channel — join stays manual
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// skip channels we can't join
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<ServerConnection?> CleanupConnectionAsync(string serverUrl)
|
||||||
|
{
|
||||||
|
if (!_connections.TryGetValue(serverUrl, out ServerConnection? entry))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.Server.IsConnected = false;
|
||||||
|
entry.Server.IsConnecting = false;
|
||||||
|
|
||||||
|
await entry.Manager.CleanupAsync();
|
||||||
|
entry.ApiClient.Dispose();
|
||||||
|
await entry.Manager.DisposeAsync();
|
||||||
|
|
||||||
|
_ = _connections.Remove(serverUrl);
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
private void SaveRefreshToken(string serverUrl, bool rememberMe)
|
private void SaveRefreshToken(string serverUrl, bool rememberMe)
|
||||||
{
|
{
|
||||||
if (!rememberMe)
|
if (!rememberMe)
|
||||||
|
|||||||
@@ -3,29 +3,27 @@ using System.Text.RegularExpressions;
|
|||||||
|
|
||||||
namespace Decho.ViewModels;
|
namespace Decho.ViewModels;
|
||||||
|
|
||||||
public sealed class AutocompleteController : ViewModelBase
|
public sealed class AutocompleteController(IEnumerable<AutocompleteProvider> providers) : ViewModelBase
|
||||||
{
|
{
|
||||||
private readonly List<AutocompleteProvider> _providers;
|
|
||||||
|
|
||||||
private static readonly Regex TriggerPattern = new(@"([@#])(\w*)$", RegexOptions.Compiled);
|
private static readonly Regex TriggerPattern = new(@"([@#])(\w*)$", RegexOptions.Compiled);
|
||||||
|
private readonly List<AutocompleteProvider> _providers = providers.ToList();
|
||||||
public ObservableCollection<string> FilteredItems { get; } = [];
|
public ObservableCollection<string> FilteredItems { get; } = [];
|
||||||
|
|
||||||
public bool ShowPopup
|
public bool ShowPopup
|
||||||
{
|
{
|
||||||
get => field;
|
get;
|
||||||
set => this.RaiseAndSetIfChanged(ref field, value);
|
set => this.RaiseAndSetIfChanged(ref field, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int SelectedIndex
|
public int SelectedIndex
|
||||||
{
|
{
|
||||||
get => field;
|
get;
|
||||||
set => this.RaiseAndSetIfChanged(ref field, value);
|
set => this.RaiseAndSetIfChanged(ref field, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string FilterText
|
public string FilterText
|
||||||
{
|
{
|
||||||
get => field;
|
get;
|
||||||
set => this.RaiseAndSetIfChanged(ref field, value);
|
set => this.RaiseAndSetIfChanged(ref field, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,11 +31,6 @@ public sealed class AutocompleteController : ViewModelBase
|
|||||||
|
|
||||||
public int TriggerCharIndex { get; private set; }
|
public int TriggerCharIndex { get; private set; }
|
||||||
|
|
||||||
public AutocompleteController(IEnumerable<AutocompleteProvider> providers)
|
|
||||||
{
|
|
||||||
_providers = providers.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update(string text)
|
public void Update(string text)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(text) || _providers.Count == 0)
|
if (string.IsNullOrEmpty(text) || _providers.Count == 0)
|
||||||
|
|||||||
@@ -1,23 +1,10 @@
|
|||||||
namespace Decho.ViewModels;
|
namespace Decho.ViewModels;
|
||||||
|
|
||||||
public sealed class AutocompleteProvider
|
public sealed class AutocompleteProvider(char trigger, Func<IEnumerable<string>> itemsSource, string insertPrefix, int maxResults = 10)
|
||||||
{
|
{
|
||||||
public char Trigger { get; }
|
public char Trigger { get; } = trigger;
|
||||||
public Func<IEnumerable<string>> ItemsSource { get; }
|
public Func<IEnumerable<string>> ItemsSource { get; } = itemsSource;
|
||||||
public Func<string, string, bool> Filter { get; }
|
public Func<string, string, bool> Filter { get; } = (item, filter) => item.StartsWith(filter, StringComparison.OrdinalIgnoreCase);
|
||||||
public Func<string, string> FormatInsertion { get; }
|
public Func<string, string> FormatInsertion { get; } = item => $"{insertPrefix}{item} ";
|
||||||
public int MaxResults { get; }
|
public int MaxResults { get; } = maxResults;
|
||||||
|
|
||||||
public AutocompleteProvider(
|
|
||||||
char trigger,
|
|
||||||
Func<IEnumerable<string>> itemsSource,
|
|
||||||
string insertPrefix,
|
|
||||||
int maxResults = 10)
|
|
||||||
{
|
|
||||||
Trigger = trigger;
|
|
||||||
ItemsSource = itemsSource;
|
|
||||||
Filter = (item, filter) => item.StartsWith(filter, StringComparison.OrdinalIgnoreCase);
|
|
||||||
FormatInsertion = item => $"{insertPrefix}{item} ";
|
|
||||||
MaxResults = maxResults;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -34,13 +34,13 @@ public sealed class ChannelViewModel(ChannelModel model) : ViewModelBase
|
|||||||
|
|
||||||
public bool IsLocked
|
public bool IsLocked
|
||||||
{
|
{
|
||||||
get => field;
|
get;
|
||||||
set => this.RaiseAndSetIfChanged(ref field, value);
|
set => this.RaiseAndSetIfChanged(ref field, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int UnreadCount
|
public int UnreadCount
|
||||||
{
|
{
|
||||||
get => field;
|
get;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (field == value)
|
if (field == value)
|
||||||
@@ -60,7 +60,7 @@ public sealed class ChannelViewModel(ChannelModel model) : ViewModelBase
|
|||||||
|
|
||||||
public int MentionCount
|
public int MentionCount
|
||||||
{
|
{
|
||||||
get => field;
|
get;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (field == value)
|
if (field == value)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public sealed class ChatViewModel : ViewModelBase
|
|||||||
|
|
||||||
public bool ShowOnlineUsers
|
public bool ShowOnlineUsers
|
||||||
{
|
{
|
||||||
get => field;
|
get;
|
||||||
set => this.RaiseAndSetIfChanged(ref field, value);
|
set => this.RaiseAndSetIfChanged(ref field, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ public sealed class ChatViewModel : ViewModelBase
|
|||||||
|
|
||||||
public string OnlineUserCount
|
public string OnlineUserCount
|
||||||
{
|
{
|
||||||
get => field;
|
get;
|
||||||
set => this.RaiseAndSetIfChanged(ref field, value);
|
set => this.RaiseAndSetIfChanged(ref field, value);
|
||||||
} = string.Empty;
|
} = string.Empty;
|
||||||
|
|
||||||
@@ -63,11 +63,6 @@ public sealed class ChatViewModel : ViewModelBase
|
|||||||
ToggleUsersPanelCommand = ReactiveCommand.Create(ToggleUsersPanel);
|
ToggleUsersPanelCommand = ReactiveCommand.Create(ToggleUsersPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ToggleUsersPanel()
|
|
||||||
{
|
|
||||||
ShowOnlineUsers = !ShowOnlineUsers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetChannel(ChannelViewModel? channel, string serverUrl = "", bool isServerConnected = true)
|
public void SetChannel(ChannelViewModel? channel, string serverUrl = "", bool isServerConnected = true)
|
||||||
{
|
{
|
||||||
if (channel is null)
|
if (channel is null)
|
||||||
@@ -145,4 +140,9 @@ public sealed class ChatViewModel : ViewModelBase
|
|||||||
OnlineUsers.Clear();
|
OnlineUsers.Clear();
|
||||||
OnlineUserCount = string.Empty;
|
OnlineUserCount = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ToggleUsersPanel()
|
||||||
|
{
|
||||||
|
ShowOnlineUsers = !ShowOnlineUsers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1060,4 +1060,3 @@ public sealed class MainWindowViewModel : ViewModelBase
|
|||||||
return Chat.CurrentServerUrl;
|
return Chat.CurrentServerUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,10 +13,9 @@ public sealed class MessageComposerViewModel : ViewModelBase
|
|||||||
|
|
||||||
public event Action<string, string>? FileUploadRequested;
|
public event Action<string, string>? FileUploadRequested;
|
||||||
|
|
||||||
private CommandHandler? _commandHandler;
|
|
||||||
|
|
||||||
private readonly ObservableCollection<UserViewModel> _onlineUsers = [];
|
private readonly ObservableCollection<UserViewModel> _onlineUsers = [];
|
||||||
private readonly ObservableCollection<string> _channelNames = [];
|
private readonly ObservableCollection<string> _channelNames = [];
|
||||||
|
private CommandHandler? _commandHandler;
|
||||||
|
|
||||||
public string Draft
|
public string Draft
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,13 +5,14 @@ using EchoHub.Core.Models;
|
|||||||
|
|
||||||
namespace Decho.ViewModels;
|
namespace Decho.ViewModels;
|
||||||
|
|
||||||
public sealed class UserViewModel : ViewModelBase
|
public sealed class UserViewModel(UserPresenceDto dto) : ViewModelBase
|
||||||
{
|
{
|
||||||
public string Username { get; }
|
private UserStatus _status = dto.Status;
|
||||||
public string DisplayName { get; }
|
public string Username { get; } = dto.Username;
|
||||||
public string? NicknameColor { get; }
|
public string DisplayName { get; } = dto.DisplayName ?? dto.Username;
|
||||||
public string? StatusMessage { get; }
|
public string? NicknameColor { get; } = dto.NicknameColor;
|
||||||
public ServerRole Role { get; }
|
public string? StatusMessage { get; } = dto.StatusMessage;
|
||||||
|
public ServerRole Role { get; } = dto.Role;
|
||||||
|
|
||||||
public UserStatus Status
|
public UserStatus Status
|
||||||
{
|
{
|
||||||
@@ -30,8 +31,6 @@ public sealed class UserViewModel : ViewModelBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserStatus _status;
|
|
||||||
|
|
||||||
public string FullName => DisplayName ?? Username;
|
public string FullName => DisplayName ?? Username;
|
||||||
|
|
||||||
public IBrush? DisplayColor
|
public IBrush? DisplayColor
|
||||||
@@ -71,14 +70,4 @@ public sealed class UserViewModel : ViewModelBase
|
|||||||
UserStatus.Invisible => "Invisible",
|
UserStatus.Invisible => "Invisible",
|
||||||
_ => "Offline",
|
_ => "Offline",
|
||||||
};
|
};
|
||||||
|
|
||||||
public UserViewModel(UserPresenceDto dto)
|
|
||||||
{
|
|
||||||
Username = dto.Username;
|
|
||||||
DisplayName = dto.DisplayName ?? dto.Username;
|
|
||||||
NicknameColor = dto.NicknameColor;
|
|
||||||
StatusMessage = dto.StatusMessage;
|
|
||||||
Role = dto.Role;
|
|
||||||
_status = dto.Status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -16,6 +16,7 @@ namespace Decho.Views;
|
|||||||
|
|
||||||
public partial class MessageItemView : UserControl
|
public partial class MessageItemView : UserControl
|
||||||
{
|
{
|
||||||
|
private static readonly Regex MentionRegex = new(@"@(\w+)", RegexOptions.Compiled);
|
||||||
private CancellationTokenSource? _loadCts;
|
private CancellationTokenSource? _loadCts;
|
||||||
private string? _loadedMessageId;
|
private string? _loadedMessageId;
|
||||||
|
|
||||||
@@ -25,8 +26,6 @@ public partial class MessageItemView : UserControl
|
|||||||
DataContextChanged += OnDataContextChanged;
|
DataContextChanged += OnDataContextChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Regex MentionRegex = new(@"@(\w+)", RegexOptions.Compiled);
|
|
||||||
|
|
||||||
private void OnDataContextChanged(object? sender, EventArgs args)
|
private void OnDataContextChanged(object? sender, EventArgs args)
|
||||||
{
|
{
|
||||||
if (DataContext is MessageViewModel newMsg && newMsg.Model.Id == _loadedMessageId)
|
if (DataContext is MessageViewModel newMsg && newMsg.Model.Id == _loadedMessageId)
|
||||||
|
|||||||
@@ -51,11 +51,6 @@ public sealed partial class ProfileWindow : Window
|
|||||||
LastSeenText.Text = profile.LastSeenAt.ToString("g");
|
LastSeenText.Text = profile.LastSeenAt.ToString("g");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCloseClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FormatStatus(UserStatus status)
|
private static string FormatStatus(UserStatus status)
|
||||||
{
|
{
|
||||||
return status switch
|
return status switch
|
||||||
@@ -90,4 +85,9 @@ public sealed partial class ProfileWindow : Window
|
|||||||
_ => role.ToString(),
|
_ => role.ToString(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnCloseClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user