Skip to content

Commit

Permalink
Add Nanochat
Browse files Browse the repository at this point in the history
is nanochat (whatsapp)

TODO:
-delete all stock trading code (or add stock trading)
-figure out why nanochat won't work
-idk
  • Loading branch information
sypsesty committed Jan 7, 2025
1 parent ac42961 commit f098a7f
Show file tree
Hide file tree
Showing 51 changed files with 3,023 additions and 206 deletions.
34 changes: 16 additions & 18 deletions Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
using Content.Shared.Access.Systems;
using Content.Shared.StatusIcon;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Shared.Prototypes;
using Robust.Shared.Prototypes;

namespace Content.Client.Access.UI
{
Expand All @@ -18,16 +22,18 @@ protected override void Open()
{
base.Open();

_window?.Dispose();
_window = new AgentIDCardWindow(this);
if (State != null)
UpdateState(State);
_window = this.CreateWindow<AgentIDCardWindow>();

_window.OpenCentered();

_window.OnClose += Close;
_window.OnNameChanged += OnNameChanged;
_window.OnJobChanged += OnJobChanged;
_window.OnJobIconChanged += OnJobIconChanged;
_window.OnNumberChanged += OnNumberChanged; // DeltaV
}

// DeltaV - Add number change handler
private void OnNumberChanged(uint newNumber)
{
SendMessage(new AgentIDCardNumberChangedMessage(newNumber));
}

private void OnNameChanged(string newName)
Expand All @@ -40,7 +46,7 @@ private void OnJobChanged(string newJob)
SendMessage(new AgentIDCardJobChangedMessage(newJob));
}

public void OnJobIconChanged(string newJobIconId)
public void OnJobIconChanged(ProtoId<JobIconPrototype> newJobIconId)
{
SendMessage(new AgentIDCardJobIconChangedMessage(newJobIconId));
}
Expand All @@ -57,16 +63,8 @@ protected override void UpdateState(BoundUserInterfaceState state)

_window.SetCurrentName(cast.CurrentName);
_window.SetCurrentJob(cast.CurrentJob);
_window.SetAllowedIcons(cast.Icons, cast.CurrentJobIconId);
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;

_window?.Dispose();
_window.SetAllowedIcons(cast.CurrentJobIconId);
_window.SetCurrentNumber(cast.CurrentNumber); // DeltaV
}
}
}
15 changes: 8 additions & 7 deletions Content.Client/Access/UI/AgentIDCardWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
<LineEdit Name="NameLineEdit" />
<Label Name="CurrentJob" Text="{Loc 'agent-id-card-current-job'}" />
<LineEdit Name="JobLineEdit" />
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'agent-id-card-job-icon-label'}"/>
<Control HorizontalExpand="True" MinSize="50 0"/>
<GridContainer Name="IconGrid" Columns="10">
<!-- Job icon buttons are generated in the code -->
</GridContainer>
</BoxContainer>
<!-- DeltaV - Add NanoChat number field -->
<Label Name="CurrentNumber" Text="{Loc 'agent-id-card-current-number'}" />
<LineEdit Name="NumberLineEdit" PlaceHolder="#0000" />
<!-- DeltaV end -->
<Label Text="{Loc 'agent-id-card-job-icon-label'}"/>
<GridContainer Name="IconGrid" Columns="10">
<!-- Job icon buttons are generated in the code -->
</GridContainer>
</BoxContainer>
</DefaultWindow>
67 changes: 49 additions & 18 deletions Content.Client/Access/UI/AgentIDCardWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using System.Numerics;
using System.Linq;

namespace Content.Client.Access.UI
{
Expand All @@ -17,40 +18,72 @@ public sealed partial class AgentIDCardWindow : DefaultWindow
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
private readonly SpriteSystem _spriteSystem;
private readonly AgentIDCardBoundUserInterface _bui;

private const int JobIconColumnCount = 10;

private const int MaxNumberLength = 4; // DeltaV - Same as NewChatPopup

public event Action<string>? OnNameChanged;
public event Action<string>? OnJobChanged;

public AgentIDCardWindow(AgentIDCardBoundUserInterface bui)
public event Action<uint>? OnNumberChanged; // DeltaV - Add event for number changes

public event Action<ProtoId<JobIconPrototype>>? OnJobIconChanged;

public AgentIDCardWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_spriteSystem = _entitySystem.GetEntitySystem<SpriteSystem>();
_bui = bui;

NameLineEdit.OnTextEntered += e => OnNameChanged?.Invoke(e.Text);
NameLineEdit.OnFocusExit += e => OnNameChanged?.Invoke(e.Text);

JobLineEdit.OnTextEntered += e => OnJobChanged?.Invoke(e.Text);
JobLineEdit.OnFocusExit += e => OnJobChanged?.Invoke(e.Text);

// DeltaV - Add handlers for number changes
NumberLineEdit.OnTextEntered += OnNumberEntered;
NumberLineEdit.OnFocusExit += OnNumberEntered;

// DeltaV - Filter to only allow digits
NumberLineEdit.OnTextChanged += args =>
{
if (args.Text.Length > MaxNumberLength)
{
NumberLineEdit.Text = args.Text[..MaxNumberLength];
}

// Filter to digits only
var newText = string.Concat(args.Text.Where(char.IsDigit));
if (newText != args.Text)
NumberLineEdit.Text = newText;
};
}

public void SetAllowedIcons(HashSet<string> icons, string currentJobIconId)
// DeltaV - Add number validation and event
private void OnNumberEntered(LineEdit.LineEditEventArgs args)
{
if (uint.TryParse(args.Text, out var number) && number > 0)
OnNumberChanged?.Invoke(number);
}

// DeltaV - Add setter for current number
public void SetCurrentNumber(uint? number)
{
NumberLineEdit.Text = number?.ToString("D4") ?? "";
}

public void SetAllowedIcons(string currentJobIconId)
{
IconGrid.DisposeAllChildren();

var jobIconGroup = new ButtonGroup();
var jobIconButtonGroup = new ButtonGroup();
var i = 0;
foreach (var jobIconId in icons)
var icons = _prototypeManager.EnumeratePrototypes<JobIconPrototype>().Where(icon => icon.AllowSelection).ToList();
icons.Sort((x, y) => string.Compare(x.LocalizedJobName, y.LocalizedJobName, StringComparison.CurrentCulture));
foreach (var jobIcon in icons)
{
if (!_prototypeManager.TryIndex<StatusIconPrototype>(jobIconId, out var jobIcon))
{
continue;
}

String styleBase = StyleBase.ButtonOpenBoth;
var modulo = i % JobIconColumnCount;
if (modulo == 0)
Expand All @@ -64,25 +97,23 @@ public void SetAllowedIcons(HashSet<string> icons, string currentJobIconId)
Access = AccessLevel.Public,
StyleClasses = { styleBase },
MaxSize = new Vector2(42, 28),
Group = jobIconGroup,
Pressed = i == 0,
Group = jobIconButtonGroup,
Pressed = currentJobIconId == jobIcon.ID,
ToolTip = jobIcon.LocalizedJobName
};

// Generate buttons textures
TextureRect jobIconTexture = new TextureRect
var jobIconTexture = new TextureRect
{
Texture = _spriteSystem.Frame0(jobIcon.Icon),
TextureScale = new Vector2(2.5f, 2.5f),
Stretch = TextureRect.StretchMode.KeepCentered,
};

jobIconButton.AddChild(jobIconTexture);
jobIconButton.OnPressed += _ => _bui.OnJobIconChanged(jobIcon.ID);
jobIconButton.OnPressed += _ => OnJobIconChanged?.Invoke(jobIcon.ID);
IconGrid.AddChild(jobIconButton);

if (jobIconId.Equals(currentJobIconId))
jobIconButton.Pressed = true;

i++;
}
}
Expand Down
2 changes: 1 addition & 1 deletion Content.Client/CartridgeLoader/Cartridges/LogProbeUi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ public override void UpdateState(BoundUserInterfaceState state)
if (state is not LogProbeUiState logProbeUiState)
return;

_fragment?.UpdateState(logProbeUiState.PulledLogs);
_fragment?.UpdateState(logProbeUiState); // DeltaV - just take the state
}
}
28 changes: 24 additions & 4 deletions Content.Client/CartridgeLoader/Cartridges/LogProbeUiFragment.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,30 @@
BorderColor="#5a5a5a"
BorderThickness="0 0 0 1"/>
</PanelContainer.PanelOverride>
<BoxContainer Orientation="Horizontal" Margin="4 8">
<Label Align="Right" SetWidth="26" ClipText="True" Text="{Loc 'log-probe-label-number'}"/>
<Label Align="Center" SetWidth="100" ClipText="True" Text="{Loc 'log-probe-label-time'}"/>
<Label Align="Left" SetWidth="390" ClipText="True" Text="{Loc 'log-probe-label-accessor'}"/>
<BoxContainer Orientation="Vertical" Margin="4 8">
<!-- DeltaV begin - Add title label -->
<Label Name="TitleLabel"
Text="{Loc 'log-probe-header-access'}"
StyleClasses="LabelHeading"
HorizontalAlignment="Center"
Margin="0 0 0 8"/>
<!-- DeltaV end -->

<!-- DeltaV begin - Add card number display -->
<Label Name="CardNumberLabel"
StyleClasses="LabelSubText"
HorizontalAlignment="Center"
Margin="0 0 0 8"
Visible="False"/>
<!-- DeltaV end -->

<!-- DeltaV begin - Adjust column headers -->
<BoxContainer Orientation="Horizontal">
<Label Align="Right" SetWidth="26" ClipText="True" Text="{Loc 'log-probe-label-number'}"/>
<Label Align="Center" SetWidth="100" ClipText="True" Text="{Loc 'log-probe-label-time'}"/>
<Label Name="ContentLabel" Align="Left" SetWidth="390" ClipText="True" Text="{Loc 'log-probe-label-accessor'}"/>
</BoxContainer>
<!-- DeltaV end -->
</BoxContainer>
</PanelContainer>
<ScrollContainer VerticalExpand="True" HScrollEnabled="True">
Expand Down
109 changes: 107 additions & 2 deletions Content.Client/CartridgeLoader/Cartridges/LogProbeUiFragment.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Content.Shared.CartridgeLoader.Cartridges;
using System.Linq; // DeltaV
using Content.Client.DeltaV.CartridgeLoader.Cartridges; // DeltaV
using Content.Shared.CartridgeLoader.Cartridges;
using Content.Shared.DeltaV.CartridgeLoader.Cartridges; // DeltaV
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
Expand All @@ -13,10 +16,112 @@ public LogProbeUiFragment()
RobustXamlLoader.Load(this);
}

public void UpdateState(List<PulledAccessLog> logs)
// DeltaV begin - Update to handle both types of data
public void UpdateState(LogProbeUiState state)
{
ProbedDeviceContainer.RemoveAllChildren();

if (state.NanoChatData != null)
{
SetupNanoChatView(state.NanoChatData.Value);
DisplayNanoChatData(state.NanoChatData.Value);
}
else
{
SetupAccessLogView();
if (state.PulledLogs.Count > 0)
DisplayAccessLogs(state.PulledLogs);
}
}

private void SetupNanoChatView(NanoChatData data)
{
TitleLabel.Text = Loc.GetString("log-probe-header-nanochat");
ContentLabel.Text = Loc.GetString("log-probe-label-message");

// Show card info if available
var cardInfo = new List<string>();
if (data.CardNumber != null)
cardInfo.Add(Loc.GetString("log-probe-card-number", ("number", $"#{data.CardNumber:D4}")));

// Add recipient count
cardInfo.Add(Loc.GetString("log-probe-recipients", ("count", data.Recipients.Count)));

CardNumberLabel.Text = string.Join(" | ", cardInfo);
CardNumberLabel.Visible = true;
}

private void SetupAccessLogView()
{
TitleLabel.Text = Loc.GetString("log-probe-header-access");
ContentLabel.Text = Loc.GetString("log-probe-label-accessor");
CardNumberLabel.Visible = false;
}

private void DisplayNanoChatData(NanoChatData data)
{
// First add a recipient list entry
var recipientsList = Loc.GetString("log-probe-recipient-list") + "\n" + string.Join("\n",
data.Recipients.Values
.OrderBy(r => r.Name)
.Select(r => $" {r.Name}" +
(string.IsNullOrEmpty(r.JobTitle) ? "" : $" ({r.JobTitle})") +
$" | #{r.Number:D4}"));

var recipientsEntry = new LogProbeUiEntry(0, "---", recipientsList);
ProbedDeviceContainer.AddChild(recipientsEntry);

var count = 1;
foreach (var (partnerId, messages) in data.Messages)
{
// Show only successfully delivered incoming messages
var incomingMessages = messages
.Where(msg => msg.SenderId == partnerId && !msg.DeliveryFailed)
.OrderByDescending(msg => msg.Timestamp);

foreach (var msg in incomingMessages)
{
var messageText = Loc.GetString("log-probe-message-format",
("sender", $"#{msg.SenderId:D4}"),
("recipient", $"#{data.CardNumber:D4}"),
("content", msg.Content));

var entry = new NanoChatLogEntry(
count,
TimeSpan.FromSeconds(Math.Truncate(msg.Timestamp.TotalSeconds)).ToString(),
messageText);

ProbedDeviceContainer.AddChild(entry);
count++;
}

// Show only successfully delivered outgoing messages
var outgoingMessages = messages
.Where(msg => msg.SenderId == data.CardNumber && !msg.DeliveryFailed)
.OrderByDescending(msg => msg.Timestamp);

foreach (var msg in outgoingMessages)
{
var messageText = Loc.GetString("log-probe-message-format",
("sender", $"#{msg.SenderId:D4}"),
("recipient", $"#{partnerId:D4}"),
("content", msg.Content));

var entry = new NanoChatLogEntry(
count,
TimeSpan.FromSeconds(Math.Truncate(msg.Timestamp.TotalSeconds)).ToString(),
messageText);

ProbedDeviceContainer.AddChild(entry);
count++;
}
}
}
// DeltaV end

// DeltaV - Handle this in a separate method
private void DisplayAccessLogs(List<PulledAccessLog> logs)
{
//Reverse the list so the oldest entries appear at the bottom
logs.Reverse();

Expand Down
Loading

0 comments on commit f098a7f

Please sign in to comment.