diff --git a/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs b/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs
index 3c8bcc9d21..34c3328792 100644
--- a/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs
+++ b/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs
@@ -16,6 +16,7 @@ public sealed class GeneralStationRecordConsoleBoundUserInterface : BoundUserInt
_window = new();
_window.OnKeySelected += OnKeySelected;
+ _window.OnFiltersChanged += OnFiltersChanged;
_window.OnClose += Close;
_window.OpenCentered();
@@ -26,6 +27,13 @@ public sealed class GeneralStationRecordConsoleBoundUserInterface : BoundUserInt
SendMessage(new SelectGeneralStationRecord(key));
}
+ private void OnFiltersChanged(
+ GeneralStationRecordFilterType type, string filterValue)
+ {
+ GeneralStationRecordsFilterMsg msg = new(type, filterValue);
+ SendMessage(msg);
+ }
+
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
diff --git a/Content.Client/StationRecords/GeneralStationRecordConsoleWindow.xaml b/Content.Client/StationRecords/GeneralStationRecordConsoleWindow.xaml
index 97df400c63..a915d329bc 100644
--- a/Content.Client/StationRecords/GeneralStationRecordConsoleWindow.xaml
+++ b/Content.Client/StationRecords/GeneralStationRecordConsoleWindow.xaml
@@ -1,17 +1,26 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/StationRecords/GeneralStationRecordConsoleWindow.xaml.cs b/Content.Client/StationRecords/GeneralStationRecordConsoleWindow.xaml.cs
index b5aa896aeb..89c5048f33 100644
--- a/Content.Client/StationRecords/GeneralStationRecordConsoleWindow.xaml.cs
+++ b/Content.Client/StationRecords/GeneralStationRecordConsoleWindow.xaml.cs
@@ -12,12 +12,24 @@ namespace Content.Client.StationRecords;
public sealed partial class GeneralStationRecordConsoleWindow : DefaultWindow
{
public Action? OnKeySelected;
+
+ public Action? OnFiltersChanged;
+
private bool _isPopulating;
+ private GeneralStationRecordFilterType _currentFilterType;
+
public GeneralStationRecordConsoleWindow()
{
RobustXamlLoader.Load(this);
+ _currentFilterType = GeneralStationRecordFilterType.Name;
+
+ foreach (var item in Enum.GetValues())
+ {
+ StationRecordsFilterType.AddItem(GetTypeFilterLocals(item), (int)item);
+ }
+
RecordListing.OnItemSelected += args =>
{
if (_isPopulating || RecordListing[args.ItemIndex].Metadata is not StationRecordKey cast)
@@ -33,20 +45,66 @@ public sealed partial class GeneralStationRecordConsoleWindow : DefaultWindow
if (!_isPopulating)
OnKeySelected?.Invoke(null);
};
+
+ StationRecordsFilterType.OnItemSelected += eventArgs =>
+ {
+ var type = (GeneralStationRecordFilterType)eventArgs.Id;
+
+ if (_currentFilterType != type)
+ {
+ _currentFilterType = type;
+ FilterListingOfRecords();
+ }
+ };
+
+ StationRecordsFiltersValue.OnTextEntered += args =>
+ {
+ FilterListingOfRecords(args.Text);
+ };
+
+ StationRecordsFilters.OnPressed += _ =>
+ {
+ FilterListingOfRecords(StationRecordsFiltersValue.Text);
+ };
+
+ StationRecordsFiltersReset.OnPressed += _ =>
+ {
+ StationRecordsFiltersValue.Text = "";
+ FilterListingOfRecords();
+ };
}
public void UpdateState(GeneralStationRecordConsoleState state)
{
+ if (state.Filter != null)
+ {
+ if (state.Filter.Type != _currentFilterType)
+ {
+ _currentFilterType = state.Filter.Type;
+ }
+
+ if (state.Filter.Value != StationRecordsFiltersValue.Text)
+ {
+ StationRecordsFiltersValue.Text = state.Filter.Value;
+ }
+ }
+
+ StationRecordsFilterType.SelectId((int)_currentFilterType);
+
if (state.RecordListing == null)
{
RecordListingStatus.Visible = true;
RecordListing.Visible = false;
RecordListingStatus.Text = Loc.GetString("general-station-record-console-empty-state");
+ RecordContainer.Visible = false;
+ RecordContainerStatus.Visible = false;
return;
}
RecordListingStatus.Visible = false;
RecordListing.Visible = true;
+ RecordContainer.Visible = true;
+
PopulateRecordListing(state.RecordListing!, state.SelectedKey);
RecordContainerStatus.Visible = state.Record == null;
@@ -65,18 +123,17 @@ public sealed partial class GeneralStationRecordConsoleWindow : DefaultWindow
RecordContainer.RemoveAllChildren();
}
}
-
private void PopulateRecordListing(Dictionary listing, StationRecordKey? selected)
{
RecordListing.Clear();
RecordListing.ClearSelected();
_isPopulating = true;
+
foreach (var (key, name) in listing)
{
var item = RecordListing.AddItem(name);
item.Metadata = key;
-
if (selected != null && key.ID == selected.Value.ID)
{
item.Selected = true;
@@ -131,4 +188,17 @@ public sealed partial class GeneralStationRecordConsoleWindow : DefaultWindow
RecordContainer.AddChild(control);
}
}
+
+ private void FilterListingOfRecords(string text = "")
+ {
+ if (!_isPopulating)
+ {
+ OnFiltersChanged?.Invoke(_currentFilterType, text);
+ }
+ }
+
+ private string GetTypeFilterLocals(GeneralStationRecordFilterType type)
+ {
+ return Loc.GetString($"general-station-record-{type.ToString().ToLower()}-filter");
+ }
}
diff --git a/Content.Server/StationRecords/Components/GeneralStationRecordConsoleComponent.cs b/Content.Server/StationRecords/Components/GeneralStationRecordConsoleComponent.cs
index 31b73acc27..8c79fa2dbe 100644
--- a/Content.Server/StationRecords/Components/GeneralStationRecordConsoleComponent.cs
+++ b/Content.Server/StationRecords/Components/GeneralStationRecordConsoleComponent.cs
@@ -6,4 +6,5 @@ namespace Content.Server.StationRecords;
public sealed class GeneralStationRecordConsoleComponent : Component
{
public StationRecordKey? ActiveKey { get; set; }
+ public GeneralStationRecordsFilter? Filter { get; set; }
}
diff --git a/Content.Server/StationRecords/Systems/GeneralStationRecordConsoleSystem.cs b/Content.Server/StationRecords/Systems/GeneralStationRecordConsoleSystem.cs
index 33ef0335f7..4dd5ec6f6e 100644
--- a/Content.Server/StationRecords/Systems/GeneralStationRecordConsoleSystem.cs
+++ b/Content.Server/StationRecords/Systems/GeneralStationRecordConsoleSystem.cs
@@ -1,6 +1,7 @@
using Content.Server.Station.Systems;
using Content.Shared.StationRecords;
using Robust.Server.GameObjects;
+using System.Linq;
namespace Content.Server.StationRecords.Systems;
@@ -14,6 +15,7 @@ public sealed class GeneralStationRecordConsoleSystem : EntitySystem
{
SubscribeLocalEvent(UpdateUserInterface);
SubscribeLocalEvent(OnKeySelected);
+ SubscribeLocalEvent(OnFiltersChanged);
SubscribeLocalEvent(UpdateUserInterface);
SubscribeLocalEvent(UpdateUserInterface);
}
@@ -30,7 +32,19 @@ public sealed class GeneralStationRecordConsoleSystem : EntitySystem
UpdateUserInterface(uid, component);
}
- private void UpdateUserInterface(EntityUid uid, GeneralStationRecordConsoleComponent? console = null)
+ private void OnFiltersChanged(EntityUid uid,
+ GeneralStationRecordConsoleComponent component, GeneralStationRecordsFilterMsg msg)
+ {
+ if (component.Filter == null ||
+ component.Filter.Type != msg.Type || component.Filter.Value != msg.Value)
+ {
+ component.Filter = new GeneralStationRecordsFilter(msg.Type, msg.Value);
+ UpdateUserInterface(uid, component);
+ }
+ }
+
+ private void UpdateUserInterface(EntityUid uid,
+ GeneralStationRecordConsoleComponent? console = null)
{
if (!Resolve(uid, ref console))
{
@@ -39,27 +53,39 @@ public sealed class GeneralStationRecordConsoleSystem : EntitySystem
var owningStation = _stationSystem.GetOwningStation(uid);
-
-
if (!TryComp(owningStation, out var stationRecordsComponent))
{
- _userInterface.GetUiOrNull(uid, GeneralStationRecordConsoleKey.Key)?.SetState(new GeneralStationRecordConsoleState(null, null, null));
+ GeneralStationRecordConsoleState state = new(null, null, null, null);
+ SetStateForInterface(uid, state);
return;
}
- var enumerator = _stationRecordsSystem.GetRecordsOfType(owningStation.Value, stationRecordsComponent);
+ var consoleRecords =
+ _stationRecordsSystem.GetRecordsOfType(owningStation.Value, stationRecordsComponent);
var listing = new Dictionary();
- foreach (var pair in enumerator)
+
+ foreach (var pair in consoleRecords)
{
+ if (console != null && console.Filter != null
+ && IsSkippedRecord(console.Filter, pair.Item2))
+ {
+ continue;
+ }
+
listing.Add(pair.Item1, pair.Item2.Name);
}
if (listing.Count == 0)
{
- _userInterface.GetUiOrNull(uid, GeneralStationRecordConsoleKey.Key)?.SetState(new GeneralStationRecordConsoleState(null, null, null));
+ GeneralStationRecordConsoleState state = new(null, null, null, console.Filter);
+ SetStateForInterface(uid, state);
return;
}
+ else if (listing.Count == 1)
+ {
+ console.ActiveKey = listing.Keys.First();
+ }
GeneralStationRecord? record = null;
if (console.ActiveKey != null)
@@ -68,8 +94,41 @@ public sealed class GeneralStationRecordConsoleSystem : EntitySystem
stationRecordsComponent);
}
+ GeneralStationRecordConsoleState newState = new(console.ActiveKey, record, listing, console.Filter);
+ SetStateForInterface(uid, newState);
+ }
+
+ private void SetStateForInterface(EntityUid uid, GeneralStationRecordConsoleState newState)
+ {
_userInterface
- .GetUiOrNull(uid, GeneralStationRecordConsoleKey.Key)?
- .SetState(new GeneralStationRecordConsoleState(console.ActiveKey, record, listing));
+ .GetUiOrNull(uid, GeneralStationRecordConsoleKey.Key)
+ ?.SetState(newState);
+ }
+
+ private bool IsSkippedRecord(GeneralStationRecordsFilter filter,
+ GeneralStationRecord someRecord)
+ {
+ bool isFilter = filter.Value.Length > 0;
+ string filterLowerCaseValue = "";
+
+ if (!isFilter)
+ return false;
+
+ filterLowerCaseValue = filter.Value.ToLower();
+
+ return filter.Type switch
+ {
+ GeneralStationRecordFilterType.Name =>
+ !someRecord.Name.ToLower().Contains(filterLowerCaseValue),
+ GeneralStationRecordFilterType.Prints => someRecord.Fingerprint != null
+ && IsFilterWithSomeCodeValue(someRecord.Fingerprint, filterLowerCaseValue),
+ GeneralStationRecordFilterType.DNA => someRecord.DNA != null
+ && IsFilterWithSomeCodeValue(someRecord.DNA, filterLowerCaseValue),
+ };
+ }
+
+ private bool IsFilterWithSomeCodeValue(string value, string filter)
+ {
+ return !value.ToLower().StartsWith(filter);
}
}
diff --git a/Content.Shared/StationRecords/GeneralStationRecordsFilter.cs b/Content.Shared/StationRecords/GeneralStationRecordsFilter.cs
new file mode 100644
index 0000000000..f032242011
--- /dev/null
+++ b/Content.Shared/StationRecords/GeneralStationRecordsFilter.cs
@@ -0,0 +1,38 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.StationRecords;
+
+[Serializable, NetSerializable]
+public sealed class GeneralStationRecordsFilter
+{
+ public GeneralStationRecordFilterType Type { get; set; }
+ = GeneralStationRecordFilterType.Name;
+ public string Value { get; set; } = "";
+ public GeneralStationRecordsFilter(GeneralStationRecordFilterType filterType, string newValue = "")
+ {
+ Type = filterType;
+ Value = newValue;
+ }
+}
+
+[Serializable, NetSerializable]
+public sealed class GeneralStationRecordsFilterMsg : BoundUserInterfaceMessage
+{
+ public string Value { get; }
+ public GeneralStationRecordFilterType Type { get; }
+
+ public GeneralStationRecordsFilterMsg(GeneralStationRecordFilterType filterType,
+ string filterValue)
+ {
+ Type = filterType;
+ Value = filterValue;
+ }
+}
+
+[Serializable, NetSerializable]
+public enum GeneralStationRecordFilterType : byte
+{
+ Name,
+ Prints,
+ DNA,
+}
diff --git a/Content.Shared/StationRecords/SharedGeneralStationRecordConsoleSystem.cs b/Content.Shared/StationRecords/SharedGeneralStationRecordConsoleSystem.cs
index 85cd6b3a15..6eb8f505ff 100644
--- a/Content.Shared/StationRecords/SharedGeneralStationRecordConsoleSystem.cs
+++ b/Content.Shared/StationRecords/SharedGeneralStationRecordConsoleSystem.cs
@@ -20,6 +20,10 @@ public enum GeneralStationRecordConsoleKey : byte
/// - SelectedKey non-null, Record non-null, RecordListing non-null
/// - The selected key has a record tied to it, and the record has been sent.
///
+/// - there is added new filters and so added new states
+/// -SelectedKey null, Record null, RecordListing null, filters non-null
+/// the station may have data, but they all did not pass through the filters
+///
/// Other states are erroneous.
///
[Serializable, NetSerializable]
@@ -31,15 +35,18 @@ public sealed class GeneralStationRecordConsoleState : BoundUserInterfaceState
public StationRecordKey? SelectedKey { get; }
public GeneralStationRecord? Record { get; }
public Dictionary? RecordListing { get; }
-
- public GeneralStationRecordConsoleState(StationRecordKey? key, GeneralStationRecord? record, Dictionary? recordListing)
+ public GeneralStationRecordsFilter? Filter { get; }
+ public GeneralStationRecordConsoleState(StationRecordKey? key, GeneralStationRecord? record,
+ Dictionary? recordListing, GeneralStationRecordsFilter? newFilter)
{
SelectedKey = key;
Record = record;
RecordListing = recordListing;
+ Filter = newFilter;
}
- public bool IsEmpty() => SelectedKey == null && Record == null && RecordListing == null;
+ public bool IsEmpty() => SelectedKey == null
+ && Record == null && RecordListing == null;
}
[Serializable, NetSerializable]
diff --git a/Resources/Locale/en-US/station-records/general-station-records.ftl b/Resources/Locale/en-US/station-records/general-station-records.ftl
index 7bbde02f74..89775a449e 100644
--- a/Resources/Locale/en-US/station-records/general-station-records.ftl
+++ b/Resources/Locale/en-US/station-records/general-station-records.ftl
@@ -9,3 +9,10 @@ general-station-record-console-record-species = Species: {$species}
general-station-record-console-record-gender = Gender: {$gender}
general-station-record-console-record-fingerprint = Fingerprint: {$fingerprint}
general-station-record-console-record-dna = DNA: {$dna}
+
+general-station-record-for-filter-line-placeholder = Input text and press "Enter"
+general-station-record-name-filter = Name of person
+general-station-record-prints-filter = Fingerprints
+general-station-record-dna-filter = DNA
+general-station-record-console-search-records = Search
+general-station-record-console-reset-filters = Reset
\ No newline at end of file