Better notes and bans (#14228)

Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com>
This commit is contained in:
Riggle
2023-07-21 13:38:52 +02:00
committed by GitHub
parent c6cb6ad928
commit 579913b617
84 changed files with 9820 additions and 886 deletions

View File

@@ -1,85 +1,172 @@
using Content.Shared.Administration.Notes;
using System.Text;
using Content.Client.Resources;
using Content.Shared.Administration.Notes;
using Content.Shared.Database;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Input;
using static Robust.Client.UserInterface.Controls.LineEdit;
using Robust.Shared.Utility;
namespace Content.Client.Administration.UI.Notes;
[GenerateTypedNameReferences]
public sealed partial class AdminNotesLine : BoxContainer
{
private RichTextLabel? _label;
private LineEdit? _edit;
private readonly SpriteSystem _sprites;
public AdminNotesLine(SharedAdminNote note)
private const string AdminNotesTextureBase = "/Textures/Interface/AdminNotes/";
private static readonly Dictionary<NoteSeverity, string> SeverityIcons = new()
{
{ NoteSeverity.None, AdminNotesTextureBase + "none_button.png" },
{ NoteSeverity.Minor, AdminNotesTextureBase + "minor_button.png" },
{ NoteSeverity.Medium, AdminNotesTextureBase + "medium_button.png" },
{ NoteSeverity.High, AdminNotesTextureBase + "high_button.png" },
};
private static readonly Dictionary<NoteType, string> NoteTypeIcons = new()
{
{ NoteType.Message, AdminNotesTextureBase + "message.png" },
{ NoteType.Watchlist, AdminNotesTextureBase + "watchlist.png" },
};
public AdminNotesLine(SpriteSystem sprites, SharedAdminNote note)
{
RobustXamlLoader.Load(this);
_sprites = sprites;
Note = note;
MouseFilter = MouseFilterMode.Pass;
AddLabel();
Separator.Visible = true;
Refresh();
}
public SharedAdminNote Note { get; private set; }
public int Id => Note.Id;
public string OriginalMessage => Note.Message;
public string EditText => _edit?.Text ?? OriginalMessage;
public event Action<AdminNotesLine>? OnSubmitted;
public event Func<AdminNotesLine, bool>? OnClicked;
private void AddLabel()
/// <summary>
/// Attempts to refresh the current note line with new data. The note it draws data on is stored in <see cref="Note"/>
/// </summary>
private void Refresh()
{
if (_edit != null)
{
_edit.OnTextEntered -= Submitted;
_edit.OnFocusExit -= Submitted;
string? iconPath;
if(Note.NoteSeverity is not null)
SeverityIcons.TryGetValue(Note.NoteSeverity.Value, out iconPath);
else
NoteTypeIcons.TryGetValue(Note.NoteType, out iconPath);
RemoveChild(_edit);
_edit = null;
if (iconPath is null)
{
SeverityRect.Visible = false;
Logger.WarningS("admin.notes", $"Could not find an icon for note ID {Note.Id}");
}
else
{
SeverityRect.Texture = _sprites.Frame0(new SpriteSpecifier.Texture(new ResPath(iconPath)));
}
_label = new RichTextLabel();
_label.SetMessage(Note.Message);
TimeLabel.Text = Note.CreatedAt.ToString("yyyy-MM-dd HH:mm:ss");
ServerLabel.Text = Note.ServerName ?? "Unknown";
RoundLabel.Text = Note.Round == null ? "Unknown round" : "Round " + Note.Round;
AdminLabel.Text = Note.CreatedByName;
PlaytimeLabel.Text = $"{Note.PlaytimeAtNote.TotalHours: 0.0}h";
AddChild(_label);
_label.SetPositionFirst();
Separator.Visible = true;
}
private void AddLineEdit()
{
if (_label != null)
if (Note.Secret)
{
RemoveChild(_label);
_label = null;
SecretSeparator.Visible = true;
SecretLabel.Visible = true;
}
_edit = new LineEdit {Text = Note.Message};
_edit.OnTextEntered += Submitted;
_edit.OnFocusExit += Submitted;
if (Note.UnbannedTime is not null)
{
ExtraLabel.Text = Loc.GetString("admin-notes-unbanned", ("admin", Note.UnbannedByName ?? "[error]"), ("date", Note.UnbannedTime));
ExtraLabel.Visible = true;
}
else if (Note.ExpiryTime is not null)
{
// Notes should never be visible when expired, bans should
if (Note.ExpiryTime.Value > DateTime.UtcNow)
{
ExpiresLabel.Text = Loc.GetString("admin-note-editor-expiry-label-params",
("date", Note.ExpiryTime.Value.ToString("yyyy-MM-dd HH:mm:ss")),
("expiresIn", (Note.ExpiryTime.Value - DateTime.UtcNow).ToString("d'd 'hh':'mm")));
ExpiresLabel.Modulate = Color.FromHex("#86DC3D");
}
else
{
ExpiresLabel.Text = Loc.GetString("admin-note-editor-expiry-label-expired");
}
ExpiresLabel.Visible = true;
}
AddChild(_edit);
_edit.SetPositionFirst();
_edit.GrabKeyboardFocus();
_edit.CursorPosition = _edit.Text.Length;
if (Note.LastEditedAt > Note.CreatedAt)
{
EditedLabel.Text = Loc.GetString("admin-notes-edited", ("author", Note.EditedByName), ("date", Note.LastEditedAt));
EditedLabel.Visible = true;
}
Separator.Visible = false;
switch (Note.NoteType)
{
case NoteType.ServerBan:
NoteLabel.SetMessage(FormatBanMessage());
break;
case NoteType.RoleBan:
NoteLabel.SetMessage(FormatRoleBanMessage());
break;
case NoteType.Note:
case NoteType.Watchlist:
case NoteType.Message:
default:
NoteLabel.SetMessage(Note.Message);
break;
}
if (Note.Seen == true)
{
ExtraLabel.Text = Loc.GetString("admin-notes-message-seen");
ExtraLabel.Visible = true;
}
}
private void Submitted(LineEditEventArgs args)
private string FormatBanMessage()
{
OnSubmitted?.Invoke(this);
var banMessage = new StringBuilder($"{Loc.GetString("admin-notes-banned-from")} {Loc.GetString("admin-notes-the-server")} ");
return FormatBanMessageCommon(banMessage);
}
AddLabel();
private string FormatRoleBanMessage()
{
var banMessage = new StringBuilder($"{Loc.GetString("admin-notes-banned-from")} {string.Join(", ", Note.BannedRoles ?? new []{"unknown"})} ");
return FormatBanMessageCommon(banMessage);
}
var note = Note with {Message = args.Text};
UpdateNote(note);
private string FormatBanMessageCommon(StringBuilder sb)
{
if (Note.ExpiryTime is null)
{
sb.Append(Loc.GetString("admin-notes-permanently"));
}
else
{
sb.Append("for ");
var banLength = Note.ExpiryTime.Value - Note.CreatedAt;
if (banLength.Days > 0)
sb.Append(Loc.GetString("admin-notes-days", ("days", banLength.TotalDays.ToString(".00"))));
else if (banLength.Hours > 0)
sb.Append(Loc.GetString("admin-notes-hours", ("hours", banLength.TotalHours.ToString(".00"))));
else
sb.Append(Loc.GetString("admin-notes-minutes", ("minutes", banLength.TotalMinutes.ToString(".00"))));
}
sb.Append(" - ");
sb.Append(Note.Message);
return sb.ToString();
}
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
@@ -101,24 +188,7 @@ public sealed partial class AdminNotesLine : BoxContainer
public void UpdateNote(SharedAdminNote note)
{
Note = note;
_label?.SetMessage(note.Message);
if (_edit != null && _edit.Text != note.Message)
{
_edit.Text = note.Message;
}
}
public void SetEditable(bool editable)
{
if (editable)
{
AddLineEdit();
}
else
{
AddLabel();
}
Refresh();
}
protected override void Dispose(bool disposing)
@@ -130,13 +200,6 @@ public sealed partial class AdminNotesLine : BoxContainer
return;
}
if (_edit != null)
{
_edit.OnTextEntered -= Submitted;
_edit.OnFocusExit -= Submitted;
}
OnSubmitted = null;
OnClicked = null;
}
}