Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various Improvements to NanoChat #2922

Merged
merged 15 commits into from
Feb 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Content.Client/Input/ContentContexts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ public static void SetupContexts(IInputContextContainer contexts)
common.AddFunction(ContentKeyFunctions.ResetZoom);
common.AddFunction(ContentKeyFunctions.InspectEntity);
common.AddFunction(ContentKeyFunctions.ToggleRoundEndSummaryWindow);
// DeltaV - Begin NanoChat keybinds
common.AddFunction(ContentKeyFunctions.NanoChatNavigateUp);
common.AddFunction(ContentKeyFunctions.NanoChatNavigateDown);
common.AddFunction(ContentKeyFunctions.NanoChatNavigateUpUnread);
common.AddFunction(ContentKeyFunctions.NanoChatNavigateDownUnread);
// DeltaV - End NanoChat keybinds

// Not in engine, because engine cannot check for sanbox/admin status before starting placement.
common.AddFunction(ContentKeyFunctions.EditorCopyObject);
Expand Down
8 changes: 8 additions & 0 deletions Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,14 @@ void AddCheckBox(string checkBoxName, bool currentState, Action<BaseButton.Butto
AddButton(EngineKeyFunctions.EscapeMenu);
AddButton(ContentKeyFunctions.EscapeContext);

// DeltaV - Begin NanoChat keybinds
AddHeader("ui-options-header-nano-chat");
AddButton(ContentKeyFunctions.NanoChatNavigateUp);
AddButton(ContentKeyFunctions.NanoChatNavigateDown);
AddButton(ContentKeyFunctions.NanoChatNavigateUpUnread);
AddButton(ContentKeyFunctions.NanoChatNavigateDownUnread);
// DeltaV - End NanoChat keybinds

// Shitmed Change Start - TODO: Add hands, feet and groin targeting.
AddHeader("ui-options-header-targeting");
AddButton(ContentKeyFunctions.TargetHead);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<DefaultWindow xmlns="https://spacestation14.io"
Title="{Loc nano-chat-edit-title}"
MinSize="300 200">
<PanelContainer StyleClasses="AngleRect">
<BoxContainer Orientation="Vertical" Margin="4">
<!-- Number input -->
<BoxContainer Orientation="Vertical" Margin="0 4">
<Label Text="{Loc nano-chat-number-label}"
StyleClasses="LabelHeading" />
<PanelContainer StyleClasses="ButtonSquare">
<LineEdit Name="NumberInput"
PlaceHolder="{Loc nano-chat-number-placeholder}"
Editable="False" />
</PanelContainer>
</BoxContainer>

<!-- Name input -->
<BoxContainer Orientation="Vertical" Margin="0 4">
<Label Text="{Loc nano-chat-name-label}"
StyleClasses="LabelHeading" />
<PanelContainer StyleClasses="ButtonSquare">
<LineEdit Name="NameInput"
PlaceHolder="{Loc nano-chat-name-placeholder}" />
</PanelContainer>
</BoxContainer>

<!-- Job input (optional) -->
<BoxContainer Orientation="Vertical" Margin="0 4">
<Label Text="{Loc nano-chat-job-label}"
StyleClasses="LabelHeading" />
<PanelContainer StyleClasses="ButtonSquare">
<LineEdit Name="JobInput"
PlaceHolder="{Loc nano-chat-job-placeholder}" />
</PanelContainer>
</BoxContainer>

<!-- Action buttons -->
<BoxContainer Orientation="Horizontal"
HorizontalAlignment="Right"
Margin="0 8 0 0">
<Button Name="CancelButton"
Text="{Loc nano-chat-cancel}"
StyleClasses="OpenRight"
MinSize="80 0" />
<Button Name="ConfirmButton"
Text="{Loc nano-chat-confirm}"
StyleClasses="OpenLeft"
MinSize="80 0"
Disabled="True" />
</BoxContainer>
</BoxContainer>
</PanelContainer>
</DefaultWindow>
104 changes: 104 additions & 0 deletions Content.Client/_DV/CartridgeLoader/Cartridges/EditChatPopup.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using Content.Shared.Access.Components;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;

namespace Content.Client._DV.CartridgeLoader.Cartridges;

[GenerateTypedNameReferences]
public sealed partial class EditChatPopup : DefaultWindow
{
private const int MaxNumberLength = 4;

// Used to see if the user input is different from the original data
// to check if the user can submit
private string _originalNumber = "";
private string _originalName = "";
private string _originalJob = "";

public event Action<uint, string, string?>? OnContactEdited;

public EditChatPopup()
{
RobustXamlLoader.Load(this);

// margins trolling
ContentsContainer.Margin = new Thickness(3);

// Button handlers
CancelButton.OnPressed += _ => Close();
ConfirmButton.OnPressed += _ => EditChat();

NameInput.OnTabComplete += _ => JobInput.GrabKeyboardFocus();
NameInput.OnTextEntered += _ => EditChat();

JobInput.OnTabComplete += _ => NameInput.GrabKeyboardFocus();
JobInput.OnTextEntered += _ => EditChat();

// Input validation
NameInput.OnTextChanged += args =>
{
if (args.Text.Length > IdCardConsoleComponent.MaxFullNameLength)
NameInput.Text = args.Text[..IdCardConsoleComponent.MaxFullNameLength];
ValidateInputs();
};

JobInput.OnTextChanged += args =>
{
if (args.Text.Length > IdCardConsoleComponent.MaxJobTitleLength)
JobInput.Text = args.Text[..IdCardConsoleComponent.MaxJobTitleLength];
ValidateInputs();
};
}

private void ValidateInputs()
{
var isValid = !string.IsNullOrWhiteSpace(NumberInput.Text) &&
!string.IsNullOrWhiteSpace(NameInput.Text) &&
NumberInput.Text.Length == MaxNumberLength &&
uint.TryParse(NumberInput.Text, out _) &&
// Only valid if there are any changes
(NumberInput.Text != _originalNumber ||
NameInput.Text != _originalName ||
JobInput.Text != _originalJob);

ConfirmButton.Disabled = !isValid;
}

private void EditChat()
{
if (!uint.TryParse(NumberInput.Text, out var number))
return;

var name = NameInput.Text.Trim();
var job = string.IsNullOrWhiteSpace(JobInput.Text) ? null : JobInput.Text.Trim();

OnContactEdited?.Invoke(number, name, job);
Close();
}

public void ClearInputs()
{
NameInput.Text = string.Empty;
JobInput.Text = string.Empty;
ValidateInputs();
}

public void SetNumberInput(string newNumber)
{
NumberInput.Text = newNumber.PadLeft(MaxNumberLength, '0');
_originalNumber = newNumber;
}

public void SetNameInput(string newName)
{
NameInput.Text = newName;
_originalName = newName;
}

public void SetJobInput(string newJob)
{
JobInput.Text = newJob;
_originalJob = newJob;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Content.Shared._DV.CartridgeLoader.Cartridges;
using Content.Shared._DV.NanoChat;
using Content.Shared.Access.Components;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
Expand Down Expand Up @@ -29,8 +31,8 @@ public void SetRecipient(NanoChatRecipient recipient, uint number, bool isSelect
_pressHandler = _ => OnPressed?.Invoke(_number);
ChatButton.OnPressed += _pressHandler;

NameLabel.Text = recipient.Name;
JobLabel.Text = recipient.JobTitle ?? "";
NameLabel.Text = SharedNanoChatSystem.Truncate(recipient.Name, IdCardConsoleComponent.MaxFullNameLength);
JobLabel.Text = SharedNanoChatSystem.Truncate(recipient.JobTitle ?? "", IdCardConsoleComponent.MaxJobTitleLength);
JobLabel.Visible = !string.IsNullOrEmpty(recipient.JobTitle);
UnreadIndicator.Visible = recipient.HasUnread;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Numerics;
using Content.Shared._DV.CartridgeLoader.Cartridges;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;

Expand Down Expand Up @@ -28,6 +29,19 @@ public void UpdateContactList(NanoChatUiState state)
for (var idx = 0; idx < contacts.Count; idx++)
{
var contact = contacts[idx];
var isEvenRow = idx % 2 == 0;
var contactControl = new ContactContainer(contact, state, isEvenRow, OnStartChat);
ContactsList.AddChild(contactControl);
}
}

public sealed class ContactContainer : PanelContainer
{
public ContactContainer(NanoChatRecipient contact, NanoChatUiState state, bool isEvenRow, Action<NanoChatRecipient>? onStartChat)
{
HorizontalExpand = true;
StyleClasses.Add(isEvenRow ? "PanelBackgroundBaseDark" : "PanelBackgroundLight");

var nameLabel = new Label()
{
Text = contact.Name,
Expand All @@ -36,7 +50,7 @@ public void UpdateContactList(NanoChatUiState state)
};
var numberLabel = new Label()
{
Text = $"#{contacts[idx].Number:D4}",
Text = $"#{contact.Number:D4}",
HorizontalAlignment = HAlignment.Right,
Margin = new Thickness(0, 0, 36, 0),
};
Expand All @@ -49,25 +63,17 @@ public void UpdateContactList(NanoChatUiState state)
ToolTip = Loc.GetString("nano-chat-new-chat"),
};
startChatButton.AddStyleClass("OpenBoth");

if (contact.Number == state.OwnNumber || state.Recipients.ContainsKey(contact.Number) || state.MaxRecipients <= state.Recipients.Count)
{
startChatButton.Disabled = true;
}
startChatButton.OnPressed += _ => OnStartChat?.Invoke(contact);

var panel = new PanelContainer()
{
HorizontalExpand = true,
};

panel.AddChild(nameLabel);
panel.AddChild(numberLabel);
panel.AddChild(startChatButton);

var styleClass = idx % 2 == 0 ? "PanelBackgroundBaseDark" : "PanelBackgroundLight";
panel.StyleClasses.Add(styleClass);
startChatButton.OnPressed += _ => onStartChat?.Invoke(contact);

ContactsList.AddChild(panel);
AddChild(nameLabel);
AddChild(numberLabel);
AddChild(startChatButton);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,6 @@
StyleClasses="LabelSubText"
VerticalAlignment="Center"
Margin="0 0 8 0" />
<Button Name="DeleteChatButton"
MaxSize="32 32"
Visible="False"
StyleClasses="OpenBoth"
Margin="0 0 4 0"
ToolTip="{Loc nano-chat-delete}">
<TextureRect StyleClasses="ButtonSquare"
TexturePath="/Textures/Interface/VerbIcons/delete_transparent.svg.192dpi.png"
Stretch="KeepAspectCentered"
MinSize="18 18" />
</Button>
<Button Name="MuteButton"
MaxSize="32 32"
StyleClasses="OpenBoth"
Expand Down Expand Up @@ -155,18 +144,59 @@
</ScrollContainer>
</BoxContainer>

<!-- Character count -->
<Label Name="CharacterCount"
HorizontalAlignment="Center"
StyleClasses="LabelSubText"
Margin="0 0 4 2"
Visible="False" />
<!-- Message input -->
<BoxContainer Name="MessageInputContainer"
Orientation="Horizontal"
HorizontalExpand="True"
Margin="0 4 0 0"
Visible="False">
<!-- Character count -->
<Label Name="CharacterCount"
HorizontalAlignment="Right"
StyleClasses="LabelSubText"
Margin="0 0 4 2"
Visible="False" />
<Button Name="EditChatButton"
MaxSize="32 32"
Visible="False"
StyleClasses="OpenBoth"
Margin="0 0 4 0"
ToolTip="{Loc nano-chat-edit}">
<TextureRect StyleClasses="ButtonSquare"
TexturePath="/Textures/_DV/Interface/VerbIcons/edit.svg.png"
Stretch="KeepAspectCentered"
MinSize="18 18" />
</Button>
<Button Name="DeleteChatButton"
MaxSize="32 32"
Visible="False"
StyleClasses="OpenBoth"
Margin="0 0 4 0"
ToolTip="{Loc nano-chat-delete}">
<TextureRect StyleClasses="ButtonSquare"
TexturePath="/Textures/Interface/VerbIcons/delete_transparent.svg.192dpi.png"
Stretch="KeepAspectCentered"
MinSize="18 18" />
</Button>
<Button Name="MuteChatButton"
MaxSize="32 32"
StyleClasses="OpenBoth"
Margin="0 0 4 0"
ToolTip="{Loc nano-chat-toggle-mute-chat}">
<Control HorizontalExpand="True" VerticalExpand="True">
<TextureRect Name="BellIconContact"
StyleClasses="ButtonSquare"
TexturePath="/Textures/_DV/Interface/VerbIcons/bell.svg.png"
Stretch="KeepAspectCentered"
MinSize="18 18" />
<TextureRect Name="BellMutedIconContact"
StyleClasses="ButtonSquare"
TexturePath="/Textures/_DV/Interface/VerbIcons/bell_muted.png"
Stretch="KeepAspectCentered"
Visible="False"
MinSize="18 18" />
</Control>
</Button>
<!-- Input row -->
<LineEdit Name="MessageInput"
PlaceHolder="{Loc nano-chat-message-placeholder}"
Expand Down
Loading
Loading