From 7a2492ac67b09e7b2e21b9e9d9e49861a9405afe Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Mon, 21 Sep 2026 09:13:55 +0200 Subject: [PATCH] [Chat] Render room chat history usernames as live user tags (#7269) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Render room chat history usernames as live user tags (#1595) Room chat history carries no user-level data, so history usernames were rendered as fixed, zero-level tags: the moderation context menu was missing the buddy/ignore and promote/demote entries and the stored name casing was never corrected. Resolve each history author against the online user list and, when found, build the user tag with the real user level and name so the entry behaves exactly like a live chat tag. Offline users keep the plain fallback. - chat_view: look up history authors via getOnlineUser for the real level/name * Fix offline history usernames getting a leading underscore The offline fallback used "_" as the level placeholder, producing an href of user://__NAME. The hover handler splits at the first underscore, so interactions targeted a nonexistent "_NAME" user. Use level 0 so offline history entries render as zero-level tags like before. --------- Co-authored-by: Lukas BrĂ¼bach --- .../widgets/server/chat_view/chat_view.cpp | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/cockatrice/src/interface/widgets/server/chat_view/chat_view.cpp b/cockatrice/src/interface/widgets/server/chat_view/chat_view.cpp index bebc2e3c4..0a287c9ce 100644 --- a/cockatrice/src/interface/widgets/server/chat_view/chat_view.cpp +++ b/cockatrice/src/interface/widgets/server/chat_view/chat_view.cpp @@ -340,16 +340,27 @@ void ChatView::appendMessage(QString message, pos.relativePosition = match.captured(0).length(); // set message start auto before = match.captured(1); auto sentBy = match.captured(2); + + // The user level is not carried in the room chat history, so history + // entries used to render as fixed-level user tags. Resolve online users + // against the user list to turn their history entries into full user + // tags (correct level, name casing and moderation context menu). + QString displayName = sentBy; + // Offline users have no known level; render them as zero-level tags. + QString levelMarker = "0"; + if (const ServerInfo_User *onlineUser = userListProxy->getOnlineUser(sentBy)) { + displayName = QString::fromStdString(onlineUser->name()); + levelMarker = QString::number(onlineUser->user_level()); + } + cursor.insertText(before); // add message timestamp QTextCharFormat senderFormat(defaultFormat); senderFormat.setAnchor(true); - // this underscore is important, it is used to add the user level, but in this case the level is - // unknown, if the name contains an underscore it would split up the name - senderFormat.setAnchorHref("user://_" + sentBy); + senderFormat.setAnchorHref("user://" + levelMarker + "_" + displayName); cursor.setCharFormat(senderFormat); - cursor.insertText(sentBy); // add username with href so it shows the menu - userMessagePositions[sentBy].append(pos); // save message position - message.remove(0, pos.relativePosition - 2); // do not remove semicolon + cursor.insertText(displayName); // add username with href so it shows the menu + userMessagePositions[displayName].append(pos); // save message position + message.remove(0, pos.relativePosition - 2); // do not remove semicolon } } else { //! \todo Remove hardcoded color.