Skip to content
Open
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
18 changes: 18 additions & 0 deletions Content.Client/_DV/CartridgeLoader/Cartridges/MailMetricUi.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using Robust.Client.UserInterface;
using Content.Client.UserInterface.Fragments;
using Content.Shared.CartridgeLoader; // Frontier
using Content.Shared.CartridgeLoader.Cartridges;

namespace Content.Client._DV.CartridgeLoader.Cartridges;

public sealed partial class MailMetricUi : UIFragment
{
private MailMetricUiFragment? _fragment;
private BoundUserInterface _userInterface; // Frontier: Required to send messages to the server

public override Control GetUIFragmentRoot()
{
Expand All @@ -16,6 +18,9 @@ public override Control GetUIFragmentRoot()
public override void Setup(BoundUserInterface userInterface, EntityUid? fragmentOwner)
{
_fragment = new MailMetricUiFragment();
_userInterface = userInterface; // Frontier: Save the UI so we can send messages to the server
_fragment.OnToggleNotificationButtonPressed += OnNotificationToggled; // Frontier: Detect when the notification button is pressed

}

public override void UpdateState(BoundUserInterfaceState state)
Expand All @@ -25,4 +30,17 @@ public override void UpdateState(BoundUserInterfaceState state)
_fragment?.UpdateState(cast);
}
}

// Frontier: Add a method to toggle the visual notification button.
// Keep in mind that this is solely a visual toggle, as the data for this program is only stored server side
public void OnNotificationToggled()
{
if (_fragment == null)
return;
var newStatus = !_fragment.MailNotificationEnabledButtonStatus;
_fragment.SetNotificationButtonVisual(newStatus);
var message = new MailMetricsNotificationToggleMessage(newStatus);
_userInterface.SendMessage(new CartridgeUiMessage(message));
}
//End Frontier
}
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,19 @@
Align="Center"
StyleClasses="LabelBig" />
</BoxContainer>
<!-- Start frontier: Mail notification button-->
<PanelContainer HorizontalExpand="True" MinHeight="32">
<BoxContainer Orientation="Horizontal"
Margin="8,8,8,8"
HorizontalExpand="True">
<Button
Name="NotificationSwitch"
ToolTip="{Loc news-reader-ui-mute-tooltip}"
Text="{Loc news-read-ui-notification-on}"
MinWidth="20"
Margin="0,0,5,0"/>
</BoxContainer>
</PanelContainer>
<!-- End Frontier-->

</cartridges:MailMetricUiFragment>
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@ public sealed partial class MailMetricUiFragment : BoxContainer
{

private OpenedMailPercentGrade? _successGrade;
public Action? OnToggleNotificationButtonPressed; // Frontier: Mail notification
//This is the visual state of the button. Since the UI data is only saved server side, the client is just saying what it remembers.
public bool MailNotificationEnabledButtonStatus { get; private set; } = true; // Frontier: Mail notifications

public MailMetricUiFragment()
{
RobustXamlLoader.Load(this);
NotificationSwitch.OnPressed += _ => OnToggleNotificationButtonPressed?.Invoke(); // Frontier: Mail notification button

// This my way of adding multiple classes to a XAML control.
// Haha Batman I'm going to blow up Gotham City
Expand All @@ -32,6 +36,7 @@ public void UpdateState(MailMetricUiState state)
{
UpdateTextLabels(state);
UpdateSuccessGrade(state);
SetNotificationButtonVisual(state.NotificationsEnabled); // Frontier: Display notification status
}

public void UpdateTextLabels(MailMetricUiState state)
Expand Down Expand Up @@ -74,6 +79,16 @@ public void UpdateSuccessGrade(MailMetricUiState state)
SuccessRatePercent.StyleClasses.Add(GetClassForGrade(_successGrade));
}

// Frontier: Update the notification switch text
public void SetNotificationButtonVisual(bool notificationsEnabled)
{
//I'm just stealing the icon from the news system, yoink!
var locKey = notificationsEnabled ? "news-read-ui-notification-on" : "news-read-ui-notification-off";
NotificationSwitch.Text = Loc.GetString(locKey);
MailNotificationEnabledButtonStatus = notificationsEnabled;
}
// End Frontier

private static OpenedMailPercentGrade GetSuccessRateGrade(double successRate)
{
return successRate switch
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
namespace Content.Server._DV.CartridgeLoader.Cartridges;

// Frontier: removed the EntityUid of the station from the component
// Frontier: removed the EntityUid of the station from the component
[RegisterComponent, Access(typeof(MailMetricsCartridgeSystem))]
public sealed partial class MailMetricsCartridgeComponent : Component
{
public bool NotificationsEnabled = true; // Frontier: Allow toggling notifications
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,21 @@ public override void Initialize()
SubscribeLocalEvent<MailMetricsCartridgeComponent, CartridgeUiReadyEvent>(OnUiReady);
SubscribeLocalEvent<LogisticStatsUpdatedEvent>(OnLogisticsStatsUpdated);
SubscribeLocalEvent<MailComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<MailMetricsCartridgeComponent, CartridgeMessageEvent>(OnNotificationsUpdated);
}

private void OnUiReady(Entity<MailMetricsCartridgeComponent> ent, ref CartridgeUiReadyEvent args)
{
UpdateUI(args.Loader); // Frontier: remove station as first arg
UpdateUI(args.Loader, ent.Comp); // Frontier: remove station as first arg
}
// Frontier: Add an event listener for when the client wants to update its notification state
private void OnNotificationsUpdated(Entity<MailMetricsCartridgeComponent> program, ref CartridgeMessageEvent eventArgs )
{
if (eventArgs is MailMetricsNotificationToggleMessage toggleMessage)
program.Comp.NotificationsEnabled = toggleMessage.NotificationsEnabled;

}
// End Frontier

private void OnLogisticsStatsUpdated(LogisticStatsUpdatedEvent args)
{
Expand All @@ -44,11 +53,12 @@ private void UpdateAllCartridges() // Frontier: remove station
{
if (cartridge.LoaderUid is not { } loader)
continue;
UpdateUI(loader);
UpdateUI(loader, comp); // Frontier
}
}

private void UpdateUI(EntityUid loader)
// Frontier: Add parameter cartComp to allow us to get and send notification status
private void UpdateUI(EntityUid loader, MailMetricsCartridgeComponent cartComp)
{
//if (_station.GetOwningStation(loader) is { } station) // Frontier
// ent.Comp.Station = station; // Frontier
Expand All @@ -60,7 +70,7 @@ private void UpdateUI(EntityUid loader)
var unopenedMailCount = GetUnopenedMailCount(); // Frontier: no station arg

// Send logistic stats to cartridge client
var state = new MailMetricUiState(logiStats.Metrics, unopenedMailCount);
var state = new MailMetricUiState(logiStats.Metrics, unopenedMailCount, cartComp.NotificationsEnabled); // Frontier: Add cartComp.NotificationsEnabled
_cartridgeLoader.UpdateCartridgeUiState(loader, state);
}

Expand Down
26 changes: 26 additions & 0 deletions Content.Server/_DV/Mail/EntitySystems/MailSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,18 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using Content.Server._DV.CartridgeLoader.Cartridges; //Frontier
using Timer = Robust.Shared.Timing.Timer;
using Content.Server.Power.EntitySystems; // Frontier
using Content.Server._NF.Bank; // Frontier
using Content.Server._NF.Mail.Components; // Frontier
using Content.Server._NF.SectorServices; // Frontier
using Content.Server.CartridgeLoader; // Frontier
using Content.Shared.SSDIndicator; // Frontier
using Content.Shared.Station.Components; // Frontier
using Content.Shared._NF.Bank.BUI; // Frontier
using Content.Shared._NF.Bank.Components; // Frontier
using Content.Shared.CartridgeLoader; // Frontier
using Robust.Server.Player; // Frontier
using Robust.Shared.Enums; // Frontier

Expand Down Expand Up @@ -78,6 +81,7 @@ public sealed class MailSystem : EntitySystem
[Dependency] private readonly BankSystem _bank = default!; // Frontier
[Dependency] private readonly PowerReceiverSystem _powerReceiver = default!; // Frontier
[Dependency] private readonly IPlayerManager _player = default!; // Frontier
[Dependency] private readonly CartridgeLoaderSystem _cartLoader = default!; // Frontier

private ISawmill _sawmill = default!;
private static readonly ProtoId<TagPrototype> MailTag = "Mail"; // Frontier
Expand Down Expand Up @@ -799,6 +803,7 @@ private void SpawnMail(SectorMailComponent component)
if (validTeleporters[i].HadMail)
_audioSystem.PlayPvs(validTeleporters[i].Entity.Comp.TeleportSound, validTeleporters[i].Entity);
}
NotifyMailCarriers(deliveryCount); // Frontier; Mail carrier notifications
}
// End Frontier: sector-wide mail

Expand Down Expand Up @@ -849,6 +854,27 @@ private void ExecuteForEachLogisticsStats(Action<SectorLogisticStatsComponent> a
action(logisticStats);
// End Frontier
}

//Frontier: Send a PDA notification to all active mail carriers when new mail is teleported in.
/// <summary>
/// Notifies all in sector mail carriers that mail has arrived
/// </summary>
public void NotifyMailCarriers(int packageCount)
{
var pdaQuery = EntityQueryEnumerator<CartridgeLoaderComponent>();
while (pdaQuery.MoveNext(out var pdaUid, out var cartLoaderComp))
{
if (!_cartLoader.TryGetProgram<MailMetricsCartridgeComponent>(pdaUid, out var programUid, out var programComp))
continue;
if (programComp.NotificationsEnabled)
{
_cartLoader.SendNotification(pdaUid,
Loc.GetString("mail-notification-header"),
Loc.GetString("mail-notification-body", ("quantity", packageCount)));
}
}
}
// End Frontier
}

public struct MailRecipient(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Content.Shared.Preferences;
using Robust.Shared.Serialization;

namespace Content.Shared.CartridgeLoader.Cartridges;
Expand All @@ -9,13 +10,16 @@ public sealed class MailMetricUiState : BoundUserInterfaceState
public int UnopenedMailCount { get; }
public int TotalMail { get; }
public double SuccessRate { get; }
public bool NotificationsEnabled { get; } // Frontier: Mail notification toggle

public MailMetricUiState(MailStats metrics, int unopenedMailCount)
// Frontier: Add notifications enabled parameter
public MailMetricUiState(MailStats metrics, int unopenedMailCount, bool notificationsEnabled)
{
Metrics = metrics;
UnopenedMailCount = unopenedMailCount;
TotalMail = metrics.TotalMail(unopenedMailCount);
SuccessRate = metrics.SuccessRate(unopenedMailCount);
NotificationsEnabled = notificationsEnabled; // Frontier
}
}

Expand Down Expand Up @@ -47,3 +51,9 @@ public readonly double SuccessRate(int unopenedCount)
: 0;
}
}

[Serializable] [NetSerializable]
public sealed class MailMetricsNotificationToggleMessage(bool notificationsEnabled) : CartridgeMessageEvent
{
public readonly bool NotificationsEnabled = notificationsEnabled;
}
8 changes: 6 additions & 2 deletions Resources/Locale/en-US/_NF/mail/mail.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ ent-BaseMailLarge = package
mail-large-item-name-addressed = package ({$recipient})
mail-large-desc-far = A large package.
mail-large-desc-close = A large package addressed to {CAPITALIZE($name)}, {$job}. Last known location: {$station}.
mail-notification-title = Mail Delivery
mail-notification-body = {$quantity ->
[one] 1 package has arrived at the sector's mail teleporters.
*[other] {$quantity} packages have arrived at the sector's mail teleporters.
}



command-mailto-no-mailservice = Unable to get mail service.
command-mailto-no-mailservice = Unable to get mail service.
Loading