feat: enhance profile editing with avatar support and UI adjustments

- Added AvatarPath to ProfileEditResult for user profile updates.
- Updated ProfileEditDialog to include avatar selection with a browse button.
- Increased dialog height to accommodate new avatar input fields.
- Implemented avatar file path handling in the profile edit dialog.

feat: introduce moderation features and user roles

- Added ServerRole enum to define user roles (Member, Mod, Admin, Owner).
- Extended User model to include role, mute, and ban status.
- Created ModerationController for user role assignment, kicking, banning, and muting.
- Implemented methods in IChatBroadcaster and SignalRBroadcaster for user moderation actions.
- Updated database schema with new columns for user roles and moderation states.

fix: ensure muted users cannot send messages

- Added mute status checks in ChatService to prevent message sending for muted users.
- Updated user presence and status handling to reflect role changes and moderation actions.

chore: update constants for ASCII art rendering

- Introduced AsciiArtHeightHalfBlock constant for improved ASCII art rendering.
This commit is contained in:
HueByte
2026-02-19 17:47:10 +01:00
parent 257ac34224
commit b4c3ebd254
28 changed files with 1457 additions and 73 deletions
+55 -6
View File
@@ -9,7 +9,7 @@ namespace EchoHub.Client.UI;
/// <summary>
/// Result returned from the profile edit dialog.
/// </summary>
public record ProfileEditResult(string? DisplayName, string? Bio, string? NicknameColor);
public record ProfileEditResult(string? DisplayName, string? Bio, string? NicknameColor, string? AvatarPath);
/// <summary>
/// A Terminal.Gui dialog for editing the user's profile (display name, bio, nickname color).
@@ -23,7 +23,7 @@ public sealed class ProfileEditDialog
{
ProfileEditResult? result = null;
var dialog = new Dialog { Title = "Edit Profile", Width = 60, Height = 18 };
var dialog = new Dialog { Title = "Edit Profile", Width = 60, Height = 22 };
// Display Name
var nameLabel = new Label
@@ -102,20 +102,66 @@ public sealed class ProfileEditDialog
UpdateColorPreview(colorPreview, colorField.Text);
};
// Avatar
var avatarLabel = new Label
{
Text = "Avatar:",
X = 1,
Y = 10
};
var avatarField = new TextField
{
Text = "",
X = 17,
Y = 10,
Width = Dim.Fill(12)
};
var browseButton = new Button
{
Text = "Browse",
X = Pos.AnchorEnd(10),
Y = 10
};
var avatarHintLabel = new Label
{
Text = "(file path or URL)",
X = 17,
Y = 11
};
avatarHintLabel.SetScheme(new Scheme
{
Normal = new Attribute(Color.DarkGray, Color.Blue)
});
browseButton.Accepting += (s, e) =>
{
e.Handled = true;
var openDialog = new OpenDialog
{
Title = "Select Avatar Image",
OpenMode = OpenMode.File,
};
app.Run(openDialog);
if (openDialog.FilePaths.Count > 0)
{
avatarField.Text = openDialog.FilePaths[0];
}
};
// Buttons
var saveButton = new Button
{
Text = "Save",
IsDefault = true,
X = Pos.Center() - 10,
Y = 10
Y = 14
};
var cancelButton = new Button
{
Text = "Cancel",
X = Pos.Center() + 5,
Y = 10
Y = 14
};
saveButton.Accepting += (s, e) =>
@@ -123,8 +169,9 @@ public sealed class ProfileEditDialog
var displayName = NullIfEmpty(nameField.Text?.Trim());
var bio = NullIfEmpty(bioField.Text?.Trim());
var nicknameColor = NullIfEmpty(colorField.Text?.Trim());
var avatarPath = NullIfEmpty(avatarField.Text?.Trim());
result = new ProfileEditResult(displayName, bio, nicknameColor);
result = new ProfileEditResult(displayName, bio, nicknameColor, avatarPath);
e.Handled = true;
app.RequestStop();
};
@@ -137,7 +184,9 @@ public sealed class ProfileEditDialog
};
dialog.Add(nameLabel, nameField, bioLabel, bioField, colorLabel, colorField,
colorHintLabel, previewLabel, colorPreview, saveButton, cancelButton);
colorHintLabel, previewLabel, colorPreview,
avatarLabel, avatarField, browseButton, avatarHintLabel,
saveButton, cancelButton);
nameField.SetFocus();
app.Run(dialog);