Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: user mentions #3324

Merged

Conversation

fcolarich
Copy link
Contributor

@fcolarich fcolarich commented Feb 10, 2025

Pull Request Description

What does this PR change?

This PR includes all the logic necessary to handle Mentions + fixes and tweaks to hyperlinks functionality (which is also used by mentions).

Also bear in mind some changes (particularly moving fields around) are done automatically when running our auto-styling/formatting thing, so dont blame me :P

These are the main changes and some explanation about them:

INPUT AND CHAT

ChatInputBoxElement -> extracts and implements logic related to the chat input field, including handling suggestions, showing the emote panel, paste logic & character counting.
I also cleaned the ChatPlugin from unused references and moved a lot of logic from ChatView into the ChatInputBoxElement.

INPUT SUGGESTIONS

InputSuggestionPanelController & InputSuggestionPanelElement -> extracts all functionality related to suggestions, being made now a generic element, that works with any type of suggestion instead of only for emotes. Right now there are implemented emoticons suggestions and userNames suggestions, but more can easily be added. Basically we send the data to the controller, it uses a REGEX to parse the sent text and detects if the suggestions are in a dictionary, if so, returns the list of valid suggestions.
Relevant classes are:
BaseInputSuggestionElement and its inheritors.
IInputSuggestionElementData and its inheritors.
SuggestionPanelConfigurationSO which contains the list of valid suggestion elements that we want to use.

HYPERLINK HANDLING

TextHyperlinkHandlerElement -> This was introduced in a previous PR but has been heavily changed here, this class takes the text in a TMP_Text component and converts links found in it into clickable hyperlinks, with all the necessary actions for each type of link already configured. So its basically a plug and play component that only needs to have its dependencies sent to it to work.

CUSTOM INPUT FIELD

CustomInputField -> this little freak inherits from TMP_InputField and adds some functionality to it required on the chat and in other input fields (that I have not yet replaced for this one as it was out of scope for now).
The most important thing to note here is an override to the OnUpdateSelected method. Which is needed to be able to have custom actions with certain inputs (or disable them altogether under certain circumstances). In this case, we need to override the Ctrl+V shortcut to handle pasting on our terms (otherwise it appends character by character and it kills performance by sending an onValueChanged event per character with all the overhead it has - including audio being played for each character-, so if we paste a 200 character text, it will send 200 events in a quick succession freezing the game and saturating the audio manager), also we need to disable the Up and Down keys when the suggestion panel is open (as we use them to navigate the panel). The implementation of this override is not the best, but the original implementation of OnUpdateSelected is hideous, using old IMGUI events and we cannot really intercept them. This can and will be improved in the next shape up or doring cooldown, but the current solution is the best I could get working and not breaking the input 😞

TEXT FORMATTER

ITextFormatter & HyperlinkTextFormatter -> this class basically formats an input text using whatever criteria is defined inside the formatter. In this case, the HyperlinkTextFormatter acts in the ChatController after receiving a new message adding rich text tags for Links and making inert invalid rich text tags (right now we only support b and i tags). There is a bunch of logic there trying to make it as performant and low allocating as possible, but for sure can be improved :)

CHAT MESSAGES

I needed to introduce changes to the ChatMessage to handle the new "isMention" value, that detects when a message has a mention for the player and changes it appearance when displayed in the chat and in chat bubbles.
This also meant changes to the MultiplayerChatMessagesBus && SelfResendChatMessageBus to handle detecting if there is a mention.
NametagView -> this includes changes to display the new state of the name tag view when the chat contains a mention of the current player. Basically a new outline that must be shown along with a different background color. This also includes changes to NametagPlacementSystem to send the isMention value to the nametag.

OTHER CHANGES

IChatCommandsBus & ChatCommandsBus-> introduced this class to remove dependencies between chat commands and any other class, as there were some very weird unnecessary calls to external plugins or controllers from inside the chat commands, which should be a nono. So now we add the event, subscribe wherever we need to and invoke the event from the chat command and we are happy. (for example DebugPanelChatCommand that used to call ConnectionStatusPanelPlugin)
Also to avoid weird circular references for assemblies and whatnot, I also moved all Chat commands to be inside the DCL/Chat/Commands folder, instead of wherever the hell they were before.

IClipboardManager & ClipboardManager -> I introduced this previously, but I had to add some changes to it for this part of the feature, mainly, to sanitize copied messages and remove all rich text tags from copied text, so users get sanitized text when copying it from other users messages.

IProfileNameColorHelper -> introduced this to avoid having to reference the chat everywhere just to get the color of the profile. Ideally, the color should be cached on the profile itself, but for now, this helps to avoid assembly circular references.

ICursor & DCLCursor -> had to add a change here when setting its style, so we can Force it, meaning that ECS will no longer change it while its forced. This was needed because how we are handling cursor appareance from ECS side (in UpdateCursorInputSystem) and I needed the cursor to change shape only when over links in a text (so not over the whole text, but just links part of it). That could be easily done from the HyperlinkHandler but ECS would revert it. There was no way to add this logic easily to ECS as it depends on a list of interactable components and parts of text inside a TMP_Text component does not count xD
Also added new actions for UP and DOWN arrow keys to be recognized as UI inputs, even if they are disabled as user movement inputs.

GenericContextMenuPlugin -> had to add new types of views to use here. Why not use the default button one and change the icon and whatnot? Because I needed some custom behaviour and I had no way to get the references to the images from where Im calling this from. The idea is that the MVCManagerMenusAccessFacade can call this new context menu from anywhere without any further knowledge from the class that uses it. So we just call ShowUserProfileContextMenu, send the Profile (and color for now) and the position and the context menu will show up, no further work for the caller class.
This meant I needed the configuration to be already set in the prefabs. Also the current implementation of the GenericContextMenu doenst allow to reuse a view for different object with different configs (a pools issue that with more time we can probably fix), so I was forced to create empty classes to handle it. Please take a look at ButtonWithProfileContextMenuControlSettings and its inheritors as well as GenericContextMenuButtonWithProfileView and its inheritors.

IProfileCache & DefaultProfileCache -> had to add a new method to retrieve a profile by using the users username, as in many places I can no longer access the profile or the userId but I do have access to the full username which is unique (when including the #). So yeah, did that 😬

GenesisCityData -> had to add a new EXTENDED_WORLD_BOUNDS so our check of IsInsideBounds works correctly, because rect.Contains excludes the edge elements, so the bounds need to be one point bigger in each side :S

ChatAudioSettingsAsset -> had to create a new asset to store the selected audio setting and send it around to other plugins/controllers (for now only the chat, which makes sense xD) also made some changes coz now its a dropdown instead of a toggle...

Test Instructions

How to test this sucker?

Easy, just follow these 4030 steps instructions and you will have a fully tested feature 💪

  • First, forgo all hope
  • Sacrifice a goat or goat-like animal (the Cube cant tell the difference, it has low poly count :))
  • Now the juicy part:

Mention Suggestions

The main thing of this PR, to test if the mentions suggestions functionality is working correctly, just go to any scene with a lot of people in it and start typing @something after the first letter, a suggestion should appear with the name(s) of connected users in the same scene that start with those letters. If you press the Arrow keys UP or DOWN you can navigate the suggestion panel and if you click on a suggestion or press ENTER, the suggestion will be inserted into the text. Please test this thoroughly, particularly with longer texts or trying to introduce suggestions in the middle of sentences.
Also please check that emoji suggestions work correctly as well, as they are using the same implementation basically. Keep in mind that emojis need at least 2 characters before showing a suggestion.
In all cases if there are no matches a message saying "No result found" will be displayed.

Mention Hyperlinks

Once a suggestion is introduced (or you copy paste a username into the chat, preceded by an @) and send the message, the userName will become a MENTION™️. If you mention other user, it will appear in the chat with a blue color and if you hover over it, it will get underlined. If you click on it, a context menu will appear that will display its profile information an ADD FRIEND button that you should NOT press as its not part of this feature and that it looks oversized and ugly, ignore it for now xD , a button to mention the user that will add a mention for that user on your input box and a button to open their passport/profile.
This also includes changes to ALL other hyperlinks, so please give them a check. After some deliberation, web links will only be hyperlinked if they start with http/https.
Also, worth to note, text on the input box wont change appearance (so you wont see colored text or bold text or whatever) in the input box, but only after sending the message.
KNOWN ISSUE: The context menu will appear next to the mouse position, not next to the clicked hyperlink as its described in the docs. I'm working on it. But didn't seem critical enough to delay this more.

Getting Mentioned

When another user mentions YOU, you will get a fancy new chat message, with colors and all. Your name will be not only colored but also will have a bluish background. Same will happen with the chat bubble of the user that is mentioning you.
Keep in mind that you wont be able to click on your name (it wont be an hyperlink).
Also if you mention yourself, it will be colored and highlighted, but again, wont be clickable and it wont change the appearance of the chat/chat bubble.

Chat Sounds

If you go to the settings menu, you will find a new drop down menu under sounds with options for the chat sounds.
ALL will allow all chat sounds, NONE will disable them all and MENTIONS ONLY will only play a sound when you receive a mention from another player.
The only sounds that are considered "Chat Sounds" are for sending and receiving messages. So you will hear typing and buttons and whatnot from the chat even if Chat Sounds are "disabled"...

Other stuff

I polished the copy message feature, so please check that it copies correctly other messages. It should strip all rich text from a copied message, so no matter how fancy it looks in the chat, when you paste it it will look as plain as unflavored yogurt.

I think that's all :)
Happy bug hunting!!! 🐛

This was linked to issues Feb 13, 2025
Copy link
Collaborator

@mikhail-dcl mikhail-dcl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good overall, good job.

I ma not going to block the PR for long, I just have several concerns

Copy link

@Ludmilafantaniella Ludmilafantaniella left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feat tested on Windows and Mac.
Test Result:

  • Mention Suggestions
    ✔️ Click Behavior: Clicking a mention opens a context menu with:
    ✔️Profile information
    ✔️ “Mention User” button (adds mention to input box)
    ✔️ “Open Profile” button

  • Hyperlinks Behavior:
    ✔️ Web links are only clickable if they start with http/https.
    ✔️ No formatting changes in the input box before sending.

  • Mention Hyperlinks:
    ✔️ Username with @ turns blue in chat
    ✔️ Underlined on hover

    • ✔️Clicking a mention opens a context menu with:
      • Profile information
      • “Mention User” button (adds mention to input box)
      • “Open Profile” button
        ✔️Mentioning a non-existent or incorrect username (with @) does not trigger any action (this is expected behavior)
  • Getting mentioned:
    🟡 When mentioned, your name will be colored with a bluish background in the chat
    The bluish background feels unnecessary. The hyperlink and color change for mentions are enough to highlight them cleanly.
    This was removed because it looked odd and unnecesary
    ✔️The user’s chat bubble mentioning you will also have a colored background
    ✔️Your name cannot be clicked (not a hyperlink)
    ✔️Mentioning yourself will highlight your name but it won’t be clickable
    ✔️Self-mention will not change the appearance of the chat or chat bubble

  • Chat Sounds Settings:
    ✔️ALL: Plays all chat sounds.
    ✔️ NONE: Disables all sounds.
    ✔️ MENTIONS ONLY: Plays a sound only when you receive a mention.
    ✔️ Chat sounds only apply to message sending/receiving, so typing sounds still play even if disabled.
    ✔️ The '@' + nonexistent or incorrect username doesn’t work (which is correct).

select mention

chat bubble

chat box mention color

hyperlink

hiperLink

clickingAMention

chat.mp4

🐛 Issues Found:
When using the three-dot menu on a message to copy a hyperlink or mention (from unverified users), it pastes four times instead of once (Windows Only). COULDN'T REPRO
I think they mentioned changing the chat bubble's spike to gray instead of keeping it black. ✔️ FIXED

@fcolarich fcolarich merged commit 52fc7a7 into feat/chat/chat_improvements_main Feb 14, 2025
4 of 6 checks passed
@fcolarich fcolarich deleted the feat/chat/mentions_suggestion_box branch February 14, 2025 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Autofill Mentions Autofill Mentions Mentions
4 participants