From 78343b2dbb4f4706c80245a0fb061f7b7c7a115d Mon Sep 17 00:00:00 2001 From: Perry Fraser Date: Fri, 9 Jan 2026 09:48:38 -0500 Subject: [PATCH] feat: allow removing empty smart fridge entries (#39195) * feat: allow removing empty smart fridge entries * review --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- .../SmartFridgeBoundUserInterface.cs | 3 ++- Content.Client/SmartFridge/SmartFridgeItem.xaml | 6 ++++++ .../SmartFridge/SmartFridgeItem.xaml.cs | 7 +++++++ .../SmartFridge/SmartFridgeMenu.xaml.cs | 5 ++++- .../SmartFridge/SharedSmartFridgeSystem.cs | 17 +++++++++++++++++ .../SmartFridge/SmartFridgeComponent.cs | 16 ++++++++++++++++ 6 files changed, 52 insertions(+), 2 deletions(-) diff --git a/Content.Client/SmartFridge/SmartFridgeBoundUserInterface.cs b/Content.Client/SmartFridge/SmartFridgeBoundUserInterface.cs index 60d8ea413a..a364c8e6b9 100644 --- a/Content.Client/SmartFridge/SmartFridgeBoundUserInterface.cs +++ b/Content.Client/SmartFridge/SmartFridgeBoundUserInterface.cs @@ -19,12 +19,13 @@ public sealed class SmartFridgeBoundUserInterface : BoundUserInterface _menu = this.CreateWindow(); _menu.OnItemSelected += OnItemSelected; + _menu.OnRemoveButtonPressed += data => SendPredictedMessage(new SmartFridgeRemoveEntryMessage(data.Entry)); Refresh(); } public void Refresh() { - if (_menu is not {} menu || !EntMan.TryGetComponent(Owner, out SmartFridgeComponent? fridge)) + if (_menu is not { } menu || !EntMan.TryGetComponent(Owner, out SmartFridgeComponent? fridge)) return; menu.SetFlavorText(Loc.GetString(fridge.FlavorText)); diff --git a/Content.Client/SmartFridge/SmartFridgeItem.xaml b/Content.Client/SmartFridge/SmartFridgeItem.xaml index 3960d7ce42..17eb89801e 100644 --- a/Content.Client/SmartFridge/SmartFridgeItem.xaml +++ b/Content.Client/SmartFridge/SmartFridgeItem.xaml @@ -13,4 +13,10 @@ SizeFlagsStretchRatio="3" HorizontalExpand="True" ClipText="True"/> + diff --git a/Content.Client/SmartFridge/SmartFridgeItem.xaml.cs b/Content.Client/SmartFridge/SmartFridgeItem.xaml.cs index c69d2e7de2..1d1403878d 100644 --- a/Content.Client/SmartFridge/SmartFridgeItem.xaml.cs +++ b/Content.Client/SmartFridge/SmartFridgeItem.xaml.cs @@ -8,11 +8,18 @@ namespace Content.Client.SmartFridge; [GenerateTypedNameReferences] public sealed partial class SmartFridgeItem : BoxContainer { + public Action? RemoveButtonPressed; + public SmartFridgeItem(EntityUid uid, string text) { RobustXamlLoader.Load(this); EntityView.SetEntity(uid); NameLabel.Text = text; + + RemoveButton.OnPressed += _ => RemoveButtonPressed?.Invoke(); + + if (uid.IsValid()) + RemoveButton.Visible = false; } } diff --git a/Content.Client/SmartFridge/SmartFridgeMenu.xaml.cs b/Content.Client/SmartFridge/SmartFridgeMenu.xaml.cs index c896e7fada..ee3b3a8e7a 100644 --- a/Content.Client/SmartFridge/SmartFridgeMenu.xaml.cs +++ b/Content.Client/SmartFridge/SmartFridgeMenu.xaml.cs @@ -17,6 +17,7 @@ public sealed partial class SmartFridgeMenu : FancyWindow [Dependency] private readonly IEntityManager _entityManager = default!; public event Action? OnItemSelected; + public event Action? OnRemoveButtonPressed; private readonly StyleBoxFlat _styleBox = new() { BackgroundColor = new Color(70, 73, 102) }; @@ -48,8 +49,10 @@ public sealed partial class SmartFridgeMenu : FancyWindow return; var label = Loc.GetString("smart-fridge-list-item", ("item", entry.Entry.Name), ("amount", entry.Amount)); - button.AddChild(new SmartFridgeItem(entry.Representative, label)); + var item = new SmartFridgeItem(entry.Representative, label); + item.RemoveButtonPressed += () => OnRemoveButtonPressed?.Invoke(entry); + button.AddChild(item); button.ToolTip = label; button.StyleBoxOverride = _styleBox; } diff --git a/Content.Shared/SmartFridge/SharedSmartFridgeSystem.cs b/Content.Shared/SmartFridge/SharedSmartFridgeSystem.cs index a331c3104d..7ad6cf9c28 100644 --- a/Content.Shared/SmartFridge/SharedSmartFridgeSystem.cs +++ b/Content.Shared/SmartFridge/SharedSmartFridgeSystem.cs @@ -41,6 +41,7 @@ public abstract class SharedSmartFridgeSystem : EntitySystem sub => { sub.Event(OnDispenseItem); + sub.Event(OnRemoveEntry); }); } @@ -168,6 +169,22 @@ public abstract class SharedSmartFridgeSystem : EntitySystem }); } + private void OnRemoveEntry(Entity ent, ref SmartFridgeRemoveEntryMessage args) + { + if (!Allowed(ent, args.Actor)) + return; + + if (!ent.Comp.ContainedEntries.TryGetValue(args.Entry, out var contained) + || contained.Count > 0 + || !ent.Comp.Entries.Contains(args.Entry)) + return; + + ent.Comp.Entries.Remove(args.Entry); + ent.Comp.ContainedEntries.Remove(args.Entry); + Dirty(ent); + UpdateUI(ent); + } + private void OnGetDumpableVerb(Entity ent, ref GetDumpableVerbEvent args) { if (_accessReader.IsAllowed(args.User, ent)) diff --git a/Content.Shared/SmartFridge/SmartFridgeComponent.cs b/Content.Shared/SmartFridge/SmartFridgeComponent.cs index 5bbd58b75d..552b50607b 100644 --- a/Content.Shared/SmartFridge/SmartFridgeComponent.cs +++ b/Content.Shared/SmartFridge/SmartFridgeComponent.cs @@ -75,6 +75,10 @@ public sealed partial class SmartFridgeComponent : Component public SoundSpecifier SoundDeny = new SoundCollectionSpecifier("VendingDeny"); } +/// +/// A single entry in the smart fridge UI. +/// May contain multiple items of the same type. +/// [Serializable, NetSerializable, DataRecord] public partial record struct SmartFridgeEntry { @@ -92,8 +96,20 @@ public enum SmartFridgeUiKey : byte Key, } +/// +/// Send by the client when trying to dispense an item inside the fridge. +/// [Serializable, NetSerializable] public sealed class SmartFridgeDispenseItemMessage(SmartFridgeEntry entry) : BoundUserInterfaceMessage { public SmartFridgeEntry Entry = entry; } + +/// +/// Send by the client when trying to remove an empty smart fridge entry from the list of items in the UI. +/// +[Serializable, NetSerializable] +public sealed class SmartFridgeRemoveEntryMessage(SmartFridgeEntry entry) : BoundUserInterfaceMessage +{ + public SmartFridgeEntry Entry = entry; +} -- 2.52.0