From 9b61e1d3894d7fa2efc3054e6748cf30ddc51c54 Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Wed, 24 Apr 2024 05:03:17 +0200 Subject: [PATCH] Port fancy typing indicators --- .../TypingIndicator/TypingIndicatorSystem.cs | 53 +++++++++++++++---- .../TypingIndicatorVisualizerSystem.cs | 17 +++++- .../Systems/Chat/ChatUIController.cs | 7 +++ .../Systems/Chat/Widgets/ChatBox.xaml.cs | 16 ++++++ .../TypingIndicator/TypingIndicatorSystem.cs | 14 ++--- .../TypingIndicator/TypingChangedEvent.cs | 8 +-- .../TypingIndicatorPrototype.cs | 5 ++ .../TypingIndicator/TypingIndicatorVisuals.cs | 2 +- .../TypingIndicator/TypingIndicatorState.cs | 11 ++++ Resources/Prototypes/typing_indicator.yml | 11 ++++ 10 files changed, 122 insertions(+), 22 deletions(-) create mode 100644 Content.Shared/Corvax/TypingIndicator/TypingIndicatorState.cs diff --git a/Content.Client/Chat/TypingIndicator/TypingIndicatorSystem.cs b/Content.Client/Chat/TypingIndicator/TypingIndicatorSystem.cs index 844f793fc49..c668bf2602c 100644 --- a/Content.Client/Chat/TypingIndicator/TypingIndicatorSystem.cs +++ b/Content.Client/Chat/TypingIndicator/TypingIndicatorSystem.cs @@ -16,6 +16,7 @@ public sealed class TypingIndicatorSystem : SharedTypingIndicatorSystem private readonly TimeSpan _typingTimeout = TimeSpan.FromSeconds(2); private TimeSpan _lastTextChange; private bool _isClientTyping; + private bool _isClientChatFocused; // Corvax-TypingIndicator public override void Initialize() { @@ -31,7 +32,10 @@ public void ClientChangedChatText() return; // client typed something - show typing indicator - ClientUpdateTyping(true); + // Corvax-TypingIndicator-Start + _isClientTyping = true; + ClientUpdateTyping(); + // Corvax-TypingIndicator-End _lastTextChange = _time.CurTime; } @@ -42,9 +46,26 @@ public void ClientSubmittedChatText() return; // client submitted text - hide typing indicator - ClientUpdateTyping(false); + // Corvax-TypingIndicator-Start + _isClientTyping = false; + _isClientChatFocused = false; + ClientUpdateTyping(); + // Corvax-TypingIndicator-End } + // Corvax-TypingIndicator-Start + public void ClientChangedChatFocus(bool isFocused) + { + // don't update it if player don't want to show typing + if (!_cfg.GetCVar(CCVars.ChatShowTypingIndicator)) + return; + + // client submitted text - hide typing indicator + _isClientChatFocused = isFocused; + ClientUpdateTyping(); + } + // Corvax-TypingIndicator-End + public override void Update(float frameTime) { base.Update(frameTime); @@ -56,23 +77,34 @@ public override void Update(float frameTime) if (dif > _typingTimeout) { // client didn't typed anything for a long time - hide indicator - ClientUpdateTyping(false); + // Corvax-TypingIndicator-Start + _isClientTyping = false; + ClientUpdateTyping(); + // Corvax-TypingIndicator-End } } } - private void ClientUpdateTyping(bool isClientTyping) + private void ClientUpdateTyping() // Corvax-TypingIndicator { - if (_isClientTyping == isClientTyping) - return; - _isClientTyping = isClientTyping; + // Corvax-TypingIndicator-Start + // if (_isClientTyping == isClientTyping) + // return; + // _isClientTyping = isClientTyping; + // Corvax-TypingIndicator-End // check if player controls any pawn if (_playerManager.LocalEntity == null) return; + // Corvax-TypingIndicator-Start + var state = TypingIndicatorState.None; + if (_isClientChatFocused) + state = _isClientTyping ? TypingIndicatorState.Typing : TypingIndicatorState.Idle; + // Corvax-TypingIndicator-End + // send a networked event to server - RaiseNetworkEvent(new TypingChangedEvent(isClientTyping)); + RaiseNetworkEvent(new TypingChangedEvent(state)); // Corvax-TypingIndicator } private void OnShowTypingChanged(bool showTyping) @@ -80,7 +112,10 @@ private void OnShowTypingChanged(bool showTyping) // hide typing indicator immediately if player don't want to show it anymore if (!showTyping) { - ClientUpdateTyping(false); + // Corvax-TypingIndicator-Start + _isClientTyping = false; + ClientUpdateTyping(); + // Corvax-TypingIndicator-End } } } diff --git a/Content.Client/Chat/TypingIndicator/TypingIndicatorVisualizerSystem.cs b/Content.Client/Chat/TypingIndicator/TypingIndicatorVisualizerSystem.cs index d04c9d661dd..182ddd74b64 100644 --- a/Content.Client/Chat/TypingIndicator/TypingIndicatorVisualizerSystem.cs +++ b/Content.Client/Chat/TypingIndicator/TypingIndicatorVisualizerSystem.cs @@ -20,7 +20,7 @@ protected override void OnAppearanceChange(EntityUid uid, TypingIndicatorCompone return; } - AppearanceSystem.TryGetData(uid, TypingIndicatorVisuals.IsTyping, out var isTyping, args.Component); + //AppearanceSystem.TryGetData(uid, TypingIndicatorVisuals.IsTyping, out var isTyping, args.Component); // Corvax-TypingIndicator var layerExists = args.Sprite.LayerMapTryGet(TypingIndicatorLayers.Base, out var layer); if (!layerExists) layer = args.Sprite.LayerMapReserveBlank(TypingIndicatorLayers.Base); @@ -29,6 +29,19 @@ protected override void OnAppearanceChange(EntityUid uid, TypingIndicatorCompone args.Sprite.LayerSetState(layer, proto.TypingState); args.Sprite.LayerSetShader(layer, proto.Shader); args.Sprite.LayerSetOffset(layer, proto.Offset); - args.Sprite.LayerSetVisible(layer, isTyping); + // args.Sprite.LayerSetVisible(layer, isTyping); // Corvax-TypingIndicator + // Corvax-TypingIndicator-Start + AppearanceSystem.TryGetData(uid, TypingIndicatorVisuals.State, out var state); + args.Sprite.LayerSetVisible(layer, state != TypingIndicatorState.None); + switch (state) + { + case TypingIndicatorState.Idle: + args.Sprite.LayerSetState(layer, proto.IdleState); + break; + case TypingIndicatorState.Typing: + args.Sprite.LayerSetState(layer, proto.TypingState); + break; + } + // Corvax-TypingIndicator-End } } diff --git a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs index 1adf9ae59bd..4160109a311 100644 --- a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs +++ b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs @@ -865,6 +865,13 @@ public void NotifyChatTextChange() _typingIndicator?.ClientChangedChatText(); } + // Corvax-TypingIndicator-Start + public void NotifyChatFocus(bool isFocused) + { + _typingIndicator?.ClientChangedChatFocus(isFocused); + } + // Corvax-TypingIndicator-End + public void Repopulate() { foreach (var chat in _chats) diff --git a/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs b/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs index a33bee20f9f..284e7461ff7 100644 --- a/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs +++ b/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs @@ -35,6 +35,8 @@ public ChatBox() ChatInput.Input.OnTextEntered += OnTextEntered; ChatInput.Input.OnKeyBindDown += OnInputKeyBindDown; ChatInput.Input.OnTextChanged += OnTextChanged; + ChatInput.Input.OnFocusEnter += OnFocusEnter; // Corvax-TypingIndicator + ChatInput.Input.OnFocusExit += OnFocusExit; // Corvax-TypingIndicator ChatInput.ChannelSelector.OnChannelSelect += OnChannelSelect; ChatInput.FilterButton.Popup.OnChannelFilter += OnChannelFilter; @@ -175,6 +177,20 @@ private void OnTextChanged(LineEditEventArgs args) _controller.NotifyChatTextChange(); } + // Corvax-TypingIndicator-Start + private void OnFocusEnter(LineEditEventArgs args) + { + // Warn typing indicator about focus + _controller.NotifyChatFocus(true); + } + + private void OnFocusExit(LineEditEventArgs args) + { + // Warn typing indicator about focus + _controller.NotifyChatFocus(false); + } + // Corvax-TypingIndicator-End + protected override void Dispose(bool disposing) { base.Dispose(disposing); diff --git a/Content.Server/Chat/TypingIndicator/TypingIndicatorSystem.cs b/Content.Server/Chat/TypingIndicator/TypingIndicatorSystem.cs index 761e9456bcd..f3f7dc13c90 100644 --- a/Content.Server/Chat/TypingIndicator/TypingIndicatorSystem.cs +++ b/Content.Server/Chat/TypingIndicator/TypingIndicatorSystem.cs @@ -31,7 +31,7 @@ private void OnPlayerAttached(PlayerAttachedEvent ev) private void OnPlayerDetached(EntityUid uid, TypingIndicatorComponent component, PlayerDetachedEvent args) { // player left entity body - hide typing indicator - SetTypingIndicatorEnabled(uid, false); + SetTypingIndicatorState(uid, TypingIndicatorState.None); // Corvax-TypingIndicator } private void OnClientTypingChanged(TypingChangedEvent ev, EntitySessionEventArgs args) @@ -47,18 +47,18 @@ private void OnClientTypingChanged(TypingChangedEvent ev, EntitySessionEventArgs if (!_actionBlocker.CanEmote(uid.Value) && !_actionBlocker.CanSpeak(uid.Value)) { // nah, make sure that typing indicator is disabled - SetTypingIndicatorEnabled(uid.Value, false); + SetTypingIndicatorState(uid.Value, TypingIndicatorState.None); // Corvax-TypingIndicator return; } - SetTypingIndicatorEnabled(uid.Value, ev.IsTyping); + SetTypingIndicatorState(uid.Value, ev.State); // Corvax-TypingIndicator } - private void SetTypingIndicatorEnabled(EntityUid uid, bool isEnabled, AppearanceComponent? appearance = null) + private void SetTypingIndicatorState(EntityUid uid, TypingIndicatorState state, AppearanceComponent? appearance = null) // Corvax-TypingIndicator { - if (!Resolve(uid, ref appearance, false)) - return; + // if (!Resolve(uid, ref appearance, false)) // Corvax-TypingIndicator + // return; - _appearance.SetData(uid, TypingIndicatorVisuals.IsTyping, isEnabled, appearance); + _appearance.SetData(uid, TypingIndicatorVisuals.State, state); // Corvax-TypingIndicator } } diff --git a/Content.Shared/Chat/TypingIndicator/TypingChangedEvent.cs b/Content.Shared/Chat/TypingIndicator/TypingChangedEvent.cs index 6245f19b5d4..c5526bc8f34 100644 --- a/Content.Shared/Chat/TypingIndicator/TypingChangedEvent.cs +++ b/Content.Shared/Chat/TypingIndicator/TypingChangedEvent.cs @@ -9,10 +9,12 @@ namespace Content.Shared.Chat.TypingIndicator; [Serializable, NetSerializable] public sealed class TypingChangedEvent : EntityEventArgs { - public readonly bool IsTyping; + // Corvax-TypingIndicator-Start + public readonly TypingIndicatorState State; - public TypingChangedEvent(bool isTyping) + public TypingChangedEvent(TypingIndicatorState state) { - IsTyping = isTyping; + State = state; } + // Corvax-TypingIndicator-End } diff --git a/Content.Shared/Chat/TypingIndicator/TypingIndicatorPrototype.cs b/Content.Shared/Chat/TypingIndicator/TypingIndicatorPrototype.cs index 8cbfe7bb2e4..d1c9cc184ae 100644 --- a/Content.Shared/Chat/TypingIndicator/TypingIndicatorPrototype.cs +++ b/Content.Shared/Chat/TypingIndicator/TypingIndicatorPrototype.cs @@ -19,6 +19,11 @@ public sealed partial class TypingIndicatorPrototype : IPrototype [DataField("typingState", required: true)] public string TypingState = default!; + // Corvax-TypingIndicator-Start + [DataField("idleState", required: true)] + public string IdleState = default!; + // Corvax-TypingIndicator-End + [DataField("offset")] public Vector2 Offset = new(0, 0); diff --git a/Content.Shared/Chat/TypingIndicator/TypingIndicatorVisuals.cs b/Content.Shared/Chat/TypingIndicator/TypingIndicatorVisuals.cs index 0368819eff2..e59dff9dc8b 100644 --- a/Content.Shared/Chat/TypingIndicator/TypingIndicatorVisuals.cs +++ b/Content.Shared/Chat/TypingIndicator/TypingIndicatorVisuals.cs @@ -5,7 +5,7 @@ namespace Content.Shared.Chat.TypingIndicator; [Serializable, NetSerializable] public enum TypingIndicatorVisuals : byte { - IsTyping + State, // Corvax-TypingIndicator } [Serializable] diff --git a/Content.Shared/Corvax/TypingIndicator/TypingIndicatorState.cs b/Content.Shared/Corvax/TypingIndicator/TypingIndicatorState.cs new file mode 100644 index 00000000000..b8c2729e626 --- /dev/null +++ b/Content.Shared/Corvax/TypingIndicator/TypingIndicatorState.cs @@ -0,0 +1,11 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.Chat.TypingIndicator; + +[Serializable, NetSerializable] +public enum TypingIndicatorState +{ + None = 0, + Idle = 1, + Typing = 2, +} diff --git a/Resources/Prototypes/typing_indicator.yml b/Resources/Prototypes/typing_indicator.yml index 7271770ef50..553769dd69e 100644 --- a/Resources/Prototypes/typing_indicator.yml +++ b/Resources/Prototypes/typing_indicator.yml @@ -1,50 +1,61 @@ - type: typingIndicator id: default typingState: default0 + idleState: default3 # Corvax-TypingIndicator - type: typingIndicator id: robot typingState: robot0 + idleState: robot3 # Corvax-TypingIndicator - type: typingIndicator id: alien typingState: alien0 + idleState: alien3 # Corvax-TypingIndicator - type: typingIndicator id: guardian typingState: guardian0 + idleState: guardian3 # Corvax-TypingIndicator - type: typingIndicator id: holo typingState: holo0 + idleState: holo3 # Corvax-TypingIndicator offset: 0, 0.0625 - type: typingIndicator id: lawyer typingState: lawyer0 + idleState: lawyer3 # Corvax-TypingIndicator offset: 0, 0.125 - type: typingIndicator id: moth typingState: moth0 + idleState: moth3 # Corvax-TypingIndicator offset: 0, 0.125 - type: typingIndicator id: spider typingState: spider0 + idleState: spider3 # Corvax-TypingIndicator offset: 0, 0.125 - type: typingIndicator id: vox typingState: vox0 + idleState: vox3 # Corvax-TypingIndicator offset: -0.125, 0.125 - type: typingIndicator id: lizard typingState: lizard0 + idleState: lizard3 # Corvax-TypingIndicator offset: 0, 0.0625 - type: typingIndicator id: slime typingState: slime0 + idleState: slime3 # Corvax-TypingIndicator offset: 0, 0.125