Better notes and bans (#14228)
Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com>
This commit is contained in:
242
Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs
Normal file
242
Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs
Normal file
@@ -0,0 +1,242 @@
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Administration.Notes;
|
||||
using Content.Shared.Database;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Console;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Administration.UI.Notes;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class NoteEdit : FancyWindow
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly IClientConsoleHost _console = default!;
|
||||
|
||||
public event Action<int, NoteType, string, NoteSeverity?, bool, DateTime?>? SubmitPressed;
|
||||
|
||||
public NoteEdit(SharedAdminNote? note, string playerName, bool canCreate, bool canEdit)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
RobustXamlLoader.Load(this);
|
||||
PlayerName = playerName;
|
||||
Title = Loc.GetString("admin-note-editor-title-new", ("player", PlayerName));
|
||||
|
||||
ResetSubmitButton();
|
||||
|
||||
TypeOption.AddItem(Loc.GetString("admin-note-editor-type-note"), (int) NoteType.Note);
|
||||
TypeOption.AddItem(Loc.GetString("admin-note-editor-type-message"), (int) NoteType.Message);
|
||||
TypeOption.AddItem(Loc.GetString("admin-note-editor-type-watchlist"), (int) NoteType.Watchlist);
|
||||
TypeOption.OnItemSelected += OnTypeChanged;
|
||||
|
||||
|
||||
SeverityOption.AddItem(Loc.GetString("admin-note-editor-severity-none"), (int) Shared.Database.NoteSeverity.None);
|
||||
SeverityOption.AddItem(Loc.GetString("admin-note-editor-severity-low"), (int) Shared.Database.NoteSeverity.Minor);
|
||||
SeverityOption.AddItem(Loc.GetString("admin-note-editor-severity-medium"), (int) Shared.Database.NoteSeverity.Medium);
|
||||
SeverityOption.AddItem(Loc.GetString("admin-note-editor-severity-high"), (int) Shared.Database.NoteSeverity.High);
|
||||
SeverityOption.OnItemSelected += OnSeverityChanged;
|
||||
|
||||
PermanentCheckBox.OnPressed += OnPermanentPressed;
|
||||
SecretCheckBox.OnPressed += OnSecretPressed;
|
||||
SubmitButton.OnPressed += OnSubmitButtonPressed;
|
||||
|
||||
if (note is null && !canCreate)
|
||||
{
|
||||
SubmitButton.Disabled = true;
|
||||
TypeOption.Disabled = true;
|
||||
SeverityOption.Disabled = true;
|
||||
}
|
||||
|
||||
if (note is not null)
|
||||
{
|
||||
Title = Loc.GetString("admin-note-editor-title-existing", ("id", note.Id), ("player", PlayerName), ("author", note.CreatedByName));
|
||||
NoteId = note.Id;
|
||||
|
||||
NoteType = note.NoteType;
|
||||
TypeOption.AddItem(Loc.GetString("admin-note-editor-type-server-ban"), (int) NoteType.ServerBan);
|
||||
TypeOption.AddItem(Loc.GetString("admin-note-editor-type-role-ban"), (int) NoteType.RoleBan);
|
||||
TypeOption.SelectId((int)NoteType);
|
||||
TypeOption.Disabled = true;
|
||||
|
||||
NoteTextEdit.InsertAtCursor(note.Message);
|
||||
|
||||
NoteSeverity = note.NoteSeverity ?? Shared.Database.NoteSeverity.Minor;
|
||||
SeverityOption.SelectId((int)NoteSeverity);
|
||||
SeverityOption.Disabled = note.NoteType is not (NoteType.Note or NoteType.ServerBan or NoteType.RoleBan);
|
||||
|
||||
IsSecret = note.Secret;
|
||||
SecretCheckBox.Pressed = note.Secret;
|
||||
SecretCheckBox.Disabled = note.NoteType is not NoteType.Note;
|
||||
ExpiryTime = note.ExpiryTime;
|
||||
if (ExpiryTime is not null)
|
||||
{
|
||||
PermanentCheckBox.Pressed = false;
|
||||
UpdatePermanentCheckboxFields();
|
||||
ExpiryLineEdit.Text = ExpiryTime.Value.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
if (!canEdit)
|
||||
{
|
||||
SubmitButton.Disabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string PlayerName { get; }
|
||||
private int NoteId { get; }
|
||||
private bool IsSecret { get; set; }
|
||||
private NoteType NoteType { get; set; }
|
||||
private NoteSeverity? NoteSeverity { get; set; } = Shared.Database.NoteSeverity.None;
|
||||
private DateTime? ExpiryTime { get; set; }
|
||||
private TimeSpan? DeleteResetOn { get; set; }
|
||||
|
||||
private void OnTypeChanged(OptionButton.ItemSelectedEventArgs args)
|
||||
{
|
||||
// We should be resetting the underlying values too but the server handles that anyway
|
||||
switch (args.Id)
|
||||
{
|
||||
case (int) NoteType.Note: // Note: your standard note, does nothing special
|
||||
NoteType = NoteType.Note;
|
||||
SecretCheckBox.Disabled = false;
|
||||
SecretCheckBox.Pressed = false;
|
||||
SeverityOption.Disabled = false;
|
||||
PermanentCheckBox.Pressed = true;
|
||||
UpdatePermanentCheckboxFields();
|
||||
break;
|
||||
case (int) NoteType.Message: // Message: these are shown to the player when they log on
|
||||
NoteType = NoteType.Message;
|
||||
SecretCheckBox.Disabled = true;
|
||||
SecretCheckBox.Pressed = false;
|
||||
SeverityOption.Disabled = true;
|
||||
SeverityOption.SelectId((int) Shared.Database.NoteSeverity.None);
|
||||
NoteSeverity = null;
|
||||
PermanentCheckBox.Pressed = false;
|
||||
UpdatePermanentCheckboxFields();
|
||||
break;
|
||||
case (int) NoteType.Watchlist: // Watchlist: these are always secret and only shown to admins when the player logs on
|
||||
NoteType = NoteType.Watchlist;
|
||||
SecretCheckBox.Disabled = true;
|
||||
SecretCheckBox.Pressed = true;
|
||||
SeverityOption.Disabled = true;
|
||||
SeverityOption.SelectId((int) Shared.Database.NoteSeverity.None);
|
||||
NoteSeverity = null;
|
||||
PermanentCheckBox.Pressed = false;
|
||||
UpdatePermanentCheckboxFields();
|
||||
break;
|
||||
default: // Wuh oh
|
||||
throw new ArgumentOutOfRangeException(nameof(args.Id), args.Id, "Unknown note type");
|
||||
}
|
||||
|
||||
TypeOption.SelectId(args.Id);
|
||||
}
|
||||
|
||||
private void OnPermanentPressed(BaseButton.ButtonEventArgs _)
|
||||
{
|
||||
UpdatePermanentCheckboxFields();
|
||||
}
|
||||
|
||||
private void UpdatePermanentCheckboxFields()
|
||||
{
|
||||
ExpiryLabel.Visible = !PermanentCheckBox.Pressed;
|
||||
ExpiryLineEdit.Visible = !PermanentCheckBox.Pressed;
|
||||
|
||||
ExpiryLineEdit.Text = !PermanentCheckBox.Pressed ? DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") : string.Empty;
|
||||
}
|
||||
|
||||
private void OnSecretPressed(BaseButton.ButtonEventArgs _)
|
||||
{
|
||||
IsSecret = SecretCheckBox.Pressed;
|
||||
}
|
||||
|
||||
private void OnSeverityChanged(OptionButton.ItemSelectedEventArgs args)
|
||||
{
|
||||
NoteSeverity = (NoteSeverity) args.Id;
|
||||
SeverityOption.SelectId(args.Id);
|
||||
}
|
||||
|
||||
private void OnSubmitButtonPressed(BaseButton.ButtonEventArgs args)
|
||||
{
|
||||
if (!ParseExpiryTime())
|
||||
return;
|
||||
if (DeleteResetOn is null)
|
||||
{
|
||||
DeleteResetOn = _gameTiming.CurTime.Add(TimeSpan.FromSeconds(3));
|
||||
SubmitButton.Text = Loc.GetString("admin-note-editor-submit-confirm");
|
||||
SubmitButton.ModulateSelfOverride = Color.Red;
|
||||
// Task.Delay(3000).ContinueWith(_ => ResetSubmitButton()); // TODO: fix
|
||||
return;
|
||||
}
|
||||
|
||||
ResetSubmitButton();
|
||||
|
||||
SubmitPressed?.Invoke(NoteId, NoteType, Rope.Collapse(NoteTextEdit.TextRope), NoteSeverity, IsSecret, ExpiryTime);
|
||||
|
||||
if (Parent is null)
|
||||
{
|
||||
_console.ExecuteCommand($"adminnotes \"{PlayerName}\"");
|
||||
}
|
||||
Close();
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
// This checks for null for free, do not invert it as null always produces a false value
|
||||
if (DeleteResetOn > _gameTiming.CurTime)
|
||||
{
|
||||
ResetSubmitButton();
|
||||
DeleteResetOn = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetSubmitButton()
|
||||
{
|
||||
SubmitButton.Text = Loc.GetString("admin-note-editor-submit");
|
||||
SubmitButton.ModulateSelfOverride = null;
|
||||
UpdateDraw();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to parse the currently entered expiry time. As a side effect this function
|
||||
/// will colour its respective line edit to indicate an error
|
||||
/// </summary>
|
||||
/// <returns>True if parsing was successful, false if not</returns>
|
||||
private bool ParseExpiryTime()
|
||||
{
|
||||
// If the checkbox is pressed the note is permanent, so expiry is null
|
||||
if (PermanentCheckBox.Pressed)
|
||||
{
|
||||
ExpiryTime = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ExpiryLineEdit.Text) || !DateTime.TryParse(ExpiryLineEdit.Text, out var result) || DateTime.UtcNow > result)
|
||||
{
|
||||
ExpiryLineEdit.ModulateSelfOverride = Color.Red;
|
||||
return false;
|
||||
}
|
||||
|
||||
ExpiryTime = result;
|
||||
ExpiryLineEdit.ModulateSelfOverride = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (!disposing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PermanentCheckBox.OnPressed -= OnPermanentPressed;
|
||||
SecretCheckBox.OnPressed -= OnSecretPressed;
|
||||
SubmitButton.OnPressed -= OnSubmitButtonPressed;
|
||||
|
||||
SubmitPressed = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user