Skip to content

Commit

Permalink
Rework TypingIndicator
Browse files Browse the repository at this point in the history
  • Loading branch information
Mr0maks committed Mar 30, 2023
1 parent f91b18f commit bddb102
Show file tree
Hide file tree
Showing 64 changed files with 777 additions and 368 deletions.
61 changes: 51 additions & 10 deletions Content.Client/Chat/TypingIndicator/TypingIndicatorSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,62 @@ public sealed class TypingIndicatorSystem : SharedTypingIndicatorSystem

private readonly TimeSpan _typingTimeout = TimeSpan.FromSeconds(2);
private TimeSpan _lastTextChange;
private bool _isClientTyping;
private TypingIndicatorState State;

public override void Initialize()
{
base.Initialize();
_cfg.OnValueChanged(CCVars.ChatShowTypingIndicator, OnShowTypingChanged);
}

public void ClientFocusChat()
{
// don't update it if player don't want to show typing indicator
if (!_cfg.GetCVar(CCVars.ChatShowTypingIndicator))
return;

// client typed something - show typing indicator
ClientUpdateTyping(TypingIndicatorState.Thinking);
_lastTextChange = _time.CurTime;
}

public void ClientUnFocusChat()
{
// client typed something - show typing indicator
ClientUpdateTyping(TypingIndicatorState.None);
}


public void ClientChangedChatText()
{
// don't update it if player don't want to show typing indicator
if (!_cfg.GetCVar(CCVars.ChatShowTypingIndicator))
return;

// client typed something - show typing indicator
ClientUpdateTyping(true);
ClientUpdateTyping(TypingIndicatorState.Typing);
_lastTextChange = _time.CurTime;
}

public void ClientChangedChatTextQuestion()
{
// don't update it if player don't want to show typing indicator
if (!_cfg.GetCVar(CCVars.ChatShowTypingIndicator))
return;

// client typed something - show typing indicator
ClientUpdateTyping(TypingIndicatorState.TypingQuestion);
_lastTextChange = _time.CurTime;
}

public void ClientChangedChatTextAction()
{
// don't update it if player don't want to show typing indicator
if (!_cfg.GetCVar(CCVars.ChatShowTypingIndicator))
return;

// client typed something - show typing indicator
ClientUpdateTyping(TypingIndicatorState.TypingAction);
_lastTextChange = _time.CurTime;
}

Expand All @@ -41,45 +81,46 @@ public void ClientSubmittedChatText()
return;

// client submitted text - hide typing indicator
ClientUpdateTyping(false);
ClientUpdateTyping(TypingIndicatorState.None);
}

public override void Update(float frameTime)
{
base.Update(frameTime);

// check if client didn't changed chat text box for a long time
if (_isClientTyping)
if (State != TypingIndicatorState.None)
{
var dif = _time.CurTime - _lastTextChange;
if (dif > _typingTimeout)
{
// client didn't typed anything for a long time - hide indicator
ClientUpdateTyping(false);
ClientUpdateTyping(TypingIndicatorState.None);
}
}
}

private void ClientUpdateTyping(bool isClientTyping)
private void ClientUpdateTyping(TypingIndicatorState state)
{
if (_isClientTyping == isClientTyping)
if (State == state)
return;
_isClientTyping = isClientTyping;

State = state;

// check if player controls any pawn
if (_playerManager.LocalPlayer?.ControlledEntity == null)
return;

// send a networked event to server
RaiseNetworkEvent(new TypingChangedEvent(isClientTyping));
RaiseNetworkEvent(new TypingChangedEvent(state));
}

private void OnShowTypingChanged(bool showTyping)
{
// hide typing indicator immediately if player don't want to show it anymore
if (!showTyping)
{
ClientUpdateTyping(false);
ClientUpdateTyping(TypingIndicatorState.None);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,29 @@ protected override void OnAppearanceChange(EntityUid uid, TypingIndicatorCompone
return;
}

AppearanceSystem.TryGetData<bool>(uid, TypingIndicatorVisuals.IsTyping, out var isTyping, args.Component);
AppearanceSystem.TryGetData<TypingIndicatorState>(uid, TypingIndicatorVisuals.State, out var TypingState, args.Component);
var layerExists = args.Sprite.LayerMapTryGet(TypingIndicatorLayers.Base, out var layer);
if (!layerExists)
layer = args.Sprite.LayerMapReserveBlank(TypingIndicatorLayers.Base);

args.Sprite.LayerSetRSI(layer, proto.SpritePath);
args.Sprite.LayerSetState(layer, proto.TypingState);
switch (TypingState)
{
case TypingIndicatorState.Typing:
args.Sprite.LayerSetState(layer, proto.TypingState);
break;
case TypingIndicatorState.TypingQuestion:
args.Sprite.LayerSetState(layer, proto.QuestionState);
break;
case TypingIndicatorState.TypingAction:
args.Sprite.LayerSetState(layer, proto.ActionState);
break;
case TypingIndicatorState.Thinking:
args.Sprite.LayerSetState(layer, proto.ThinkState);
break;
}
args.Sprite.LayerSetShader(layer, proto.Shader);
args.Sprite.LayerSetOffset(layer, proto.Offset);
args.Sprite.LayerSetVisible(layer, isTyping);
args.Sprite.LayerSetVisible(layer, TypingState != TypingIndicatorState.None);
}
}
25 changes: 23 additions & 2 deletions Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -816,9 +816,30 @@ public ChatSelectChannel GetPreferredChannel()
return MapLocalIfGhost(PreferredChannel);
}

public void NotifyChatTextChange()
public void FocusEnter()
{
_typingIndicator?.ClientChangedChatText();
_typingIndicator?.ClientFocusChat();
}

public void FocusExit()
{
_typingIndicator?.ClientUnFocusChat();
}

public void NotifyChatTextChange(string text)
{
if(text.EndsWith('!'))
{
_typingIndicator?.ClientChangedChatTextAction();
}
else if(text.EndsWith('?'))
{
_typingIndicator?.ClientChangedChatTextQuestion();
}
else
{
_typingIndicator?.ClientChangedChatText();
}
}

public void Repopulate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ public ChatBox()
{
RobustXamlLoader.Load(this);


ChatInput.Input.OnFocusEnter += OnFocusEnter;
ChatInput.Input.OnFocusExit += OnFocusExit;
ChatInput.Input.OnTextEntered += OnTextEntered;
ChatInput.Input.OnKeyBindDown += OnKeyBindDown;
ChatInput.Input.OnTextChanged += OnTextChanged;
Expand All @@ -42,6 +45,16 @@ public ChatBox()
_controller.RegisterChat(this);
}

private void OnFocusEnter(LineEditEventArgs args)
{
_controller.FocusEnter();
}

private void OnFocusExit(LineEditEventArgs args)
{
_controller.FocusExit();
}

private void OnTextEntered(LineEditEventArgs args)
{
_controller.SendMessage(this, SelectedChannel);
Expand Down Expand Up @@ -173,7 +186,7 @@ private void OnTextChanged(LineEditEventArgs args)
_controller.UpdateSelectedChannel(this);

// Warn typing indicator about change
_controller.NotifyChatTextChange();
_controller.NotifyChatTextChange(args.Text);
}

protected override void Dispose(bool disposing)
Expand All @@ -182,6 +195,8 @@ protected override void Dispose(bool disposing)

if (!disposing) return;
_controller.UnregisterChat(this);
ChatInput.Input.OnFocusEnter -= OnFocusEnter;
ChatInput.Input.OnFocusExit -= OnFocusExit;
ChatInput.Input.OnTextEntered -= OnTextEntered;
ChatInput.Input.OnKeyBindDown -= OnKeyBindDown;
ChatInput.Input.OnTextChanged -= OnTextChanged;
Expand Down
10 changes: 5 additions & 5 deletions Content.Server/Chat/TypingIndicator/TypingIndicatorSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
SetTypingIndicatorEnabled(uid, TypingIndicatorState.None);
}

private void OnClientTypingChanged(TypingChangedEvent ev, EntitySessionEventArgs args)
Expand All @@ -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);
SetTypingIndicatorEnabled(uid.Value, TypingIndicatorState.None);
return;
}

SetTypingIndicatorEnabled(uid.Value, ev.IsTyping);
SetTypingIndicatorEnabled(uid.Value, ev.TypingState);
}

private void SetTypingIndicatorEnabled(EntityUid uid, bool isEnabled, AppearanceComponent? appearance = null)
private void SetTypingIndicatorEnabled(EntityUid uid, TypingIndicatorState state, AppearanceComponent? appearance = null)
{
if (!Resolve(uid, ref appearance, false))
return;

_appearance.SetData(uid, TypingIndicatorVisuals.IsTyping, isEnabled, appearance);
_appearance.SetData(uid, TypingIndicatorVisuals.State, state, appearance);
}
}
6 changes: 3 additions & 3 deletions Content.Shared/Chat/TypingIndicator/TypingChangedEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ namespace Content.Shared.Chat.TypingIndicator;
[Serializable, NetSerializable]
public sealed class TypingChangedEvent : EntityEventArgs
{
public readonly bool IsTyping;
public readonly TypingIndicatorState TypingState;

public TypingChangedEvent(bool isTyping)
public TypingChangedEvent(TypingIndicatorState typingState)
{
IsTyping = isTyping;
TypingState = typingState;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ public sealed class TypingIndicatorPrototype : IPrototype
[DataField("typingState", required: true)]
public string TypingState = default!;

[DataField("questionState", required: true)]
public string QuestionState = default!;

[DataField("actionState", required: true)]
public string ActionState = default!;

[DataField("thinkState", required: true)]
public string ThinkState = default!;

[DataField("offset")]
public Vector2 Offset = new(0.5f, 0.5f);

Expand Down
12 changes: 11 additions & 1 deletion Content.Shared/Chat/TypingIndicator/TypingIndicatorVisuals.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@

namespace Content.Shared.Chat.TypingIndicator;

[Serializable]
public enum TypingIndicatorState : byte
{
None = 0,
Typing,
TypingQuestion,
TypingAction,
Thinking
}

[Serializable, NetSerializable]
public enum TypingIndicatorVisuals : byte
{
IsTyping
State
}

[Serializable]
Expand Down
60 changes: 60 additions & 0 deletions Resources/Prototypes/typing_indicator.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,83 @@
- type: typingIndicator
id: default
typingState: default0
questionState: default1
actionState: default2
thinkState: default3

- type: typingIndicator
id: robot
typingState: robot0
questionState: robot1
actionState: robot2
thinkState: robot3

- type: typingIndicator
id: machine
typingState: machine0
questionState: machine1
actionState: machine2
thinkState: machine3

- type: typingIndicator
id: syndibot
typingState: syndibot0
questionState: syndibot1
actionState: syndibot2
thinkState: syndibot3

- type: typingIndicator
id: alien
typingState: alien0
questionState: alien1
actionState: alien2
thinkState: alien3

- type: typingIndicator
id: alienroyal
typingState: alienroyal0
questionState: alienroyal1
actionState: alienroyal2
thinkState: alienroyal3

- type: typingIndicator
id: guardian
typingState: guardian0
questionState: guardian1
actionState: guardian2
thinkState: guardian3

- type: typingIndicator
id: holo
typingState: holo0
questionState: holo1
actionState: holo2
thinkState: holo3

- type: typingIndicator
id: blob
typingState: blob0
questionState: blob1
actionState: blob2
thinkState: blob3

- type: typingIndicator
id: slime
typingState: slime0
questionState: slime1
actionState: slime2
thinkState: slime3

- type: typingIndicator
id: lawyer
typingState: lawyer0
questionState: lawyer1
actionState: lawyer2
thinkState: lawyer3

- type: typingIndicator
id: signlang
typingState: signlang0
questionState: signlang1
actionState: signlang2
thinkState: signlang3
Binary file modified Resources/Textures/Effects/speech.rsi/alien0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/alien1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/alien2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Resources/Textures/Effects/speech.rsi/alien3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/alienroyal0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/alienroyal1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/alienroyal2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/blob0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/blob1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/blob2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Resources/Textures/Effects/speech.rsi/blob3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed Resources/Textures/Effects/speech.rsi/clock0.png
Binary file not shown.
Binary file removed Resources/Textures/Effects/speech.rsi/clock1.png
Binary file not shown.
Binary file removed Resources/Textures/Effects/speech.rsi/clock2.png
Binary file not shown.
Binary file modified Resources/Textures/Effects/speech.rsi/default0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/default1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/default2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/guardian0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/guardian1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/guardian2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/holo0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/holo1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/Textures/Effects/speech.rsi/holo2.png
Binary file added Resources/Textures/Effects/speech.rsi/holo3.png
Binary file modified Resources/Textures/Effects/speech.rsi/lawyer0.png
Binary file modified Resources/Textures/Effects/speech.rsi/lawyer1.png
Binary file modified Resources/Textures/Effects/speech.rsi/lawyer2.png
Binary file modified Resources/Textures/Effects/speech.rsi/machine0.png
Binary file modified Resources/Textures/Effects/speech.rsi/machine1.png
Binary file modified Resources/Textures/Effects/speech.rsi/machine2.png
Loading

0 comments on commit bddb102

Please sign in to comment.