Chat: Highlight a message if the current user is mentioned

jocadbz
Joca 2025-08-29 14:48:38 -03:00
parent 3a82e2a0d1
commit e18d7ba193
Signed by: jocadbz
GPG Key ID: B1836DCE2F50BDF7
3 changed files with 98 additions and 13 deletions

View File

@ -127,6 +127,18 @@ func ChatHandler(app *App) http.HandlerFunc {
}
}
currentUser, err := models.GetUserByID(app.DB, userID)
if err != nil {
log.Printf("Error fetching current user: %v", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
if currentUser == nil {
http.Error(w, "User not found", http.StatusNotFound)
return
}
currentUsername := currentUser.Username
if r.URL.Query().Get("ws") == "true" {
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
@ -203,6 +215,7 @@ func ChatHandler(app *App) http.HandlerFunc {
Board models.Board
Messages []models.ChatMessage
AllUsernames template.JS
CurrentUsername string
}{
PageData: PageData{
Title: "ThreadR Chat - " + board.Name,
@ -216,6 +229,7 @@ func ChatHandler(app *App) http.HandlerFunc {
Board: *board,
Messages: messages,
AllUsernames: template.JS(allUsernamesJSON),
CurrentUsername: currentUsername,
}
if err := app.Tmpl.ExecuteTemplate(w, "chat", data); err != nil {
log.Printf("Error executing template in ChatHandler: %v", err)

View File

@ -284,6 +284,23 @@ p.board-desc {
color: #fef6e4;
}
/* New style for highlighted chat messages */
.chat-message-highlighted {
border: 2px solid #f582ae; /* Pink border */
background-color: #ffe0f0; /* Light pink background */
animation: highlight-fade 2s ease-out;
}
@keyframes highlight-fade {
from {
background-color: #f582ae;
border-color: #f582ae;
}
to {
background-color: #ffe0f0;
border-color: #f582ae;
}
}
@media (prefers-color-scheme: dark) {
body {
background-color: #333;
@ -347,6 +364,22 @@ p.board-desc {
p, a, li {
color: #fef6e4;
}
/* Dark mode highlight */
.chat-message-highlighted {
border: 2px solid #f582ae; /* Pink border */
background-color: #6a0e3f; /* Darker pink background */
animation: highlight-fade-dark 2s ease-out;
}
@keyframes highlight-fade-dark {
from {
background-color: #f582ae;
border-color: #f582ae;
}
to {
background-color: #6a0e3f;
border-color: #f582ae;
}
}
}
@media (max-width: 600px) {

View File

@ -172,6 +172,22 @@
background: none;
color: #f582ae;
}
/* New style for highlighted messages */
.chat-message-highlighted {
border: 2px solid #f582ae; /* Pink border */
background-color: #ffe0f0; /* Light pink background */
animation: highlight-fade 2s ease-out;
}
@keyframes highlight-fade {
from {
background-color: #f582ae;
border-color: #f582ae;
}
to {
background-color: #ffe0f0;
border-color: #f582ae;
}
}
@media (prefers-color-scheme: dark) {
.chat-container {
background-color: #444;
@ -217,6 +233,22 @@
.reply-indicator button:hover {
color: #f582ae;
}
/* Dark mode highlight */
.chat-message-highlighted {
border: 2px solid #f582ae; /* Pink border */
background-color: #6a0e3f; /* Darker pink background */
animation: highlight-fade-dark 2s ease-out;
}
@keyframes highlight-fade-dark {
from {
background-color: #f582ae;
border-color: #f582ae;
}
to {
background-color: #6a0e3f;
border-color: #f582ae;
}
}
}
</style>
</head>
@ -230,7 +262,7 @@
</header>
<div class="chat-messages" id="chat-messages">
{{range .Messages}}
<div class="chat-message" id="msg-{{.ID}}">
<div class="chat-message{{if .Mentions}}{{range .Mentions}}{{if eq . $.CurrentUsername}} chat-message-highlighted{{end}}{{end}}{{end}}" id="msg-{{.ID}}">
<div class="chat-message-header">
{{if .PfpFileID.Valid}}
<img src="{{$.BasePath}}/file?id={{.PfpFileID.Int64}}" alt="PFP" class="chat-message-pfp">
@ -267,6 +299,7 @@
let autocompleteActive = false;
let replyToId = -1;
const allUsernames = {{.AllUsernames}};
const currentUsername = "{{.CurrentUsername}}"; // Get current user's username
function connectWebSocket() {
const boardID = {{.Board.ID}};
@ -305,7 +338,11 @@
function appendMessage(msg) {
const messages = document.getElementById('chat-messages');
const msgDiv = document.createElement('div');
msgDiv.className = 'chat-message';
let highlightClass = '';
if (msg.mentions && msg.mentions.includes(currentUsername)) {
highlightClass = ' chat-message-highlighted';
}
msgDiv.className = 'chat-message' + highlightClass;
msgDiv.id = 'msg-' + msg.id;
let pfpHTML = `<div class="chat-message-pfp" style="background-color: #001858;"></div>`;
if (msg.pfpFileId && msg.pfpFileId.Valid) {
@ -463,11 +500,12 @@
window.onload = function() {
connectWebSocket();
document.querySelectorAll('.chat-message-content').forEach(function(el) {
const text = el.innerHTML;
const newHTML = text.replace(/@(\w+)/g, '<span class="chat-message-mention">@$1</span>');
el.innerHTML = newHTML;
});
// This part is now handled by the server-side rendering with the `chat-message-highlighted` class
// document.querySelectorAll('.chat-message-content').forEach(function(el) {
// const text = el.innerHTML;
// const newHTML = text.replace(/@(\w+)/g, '<span class="chat-message-mention">@$1</span>');
// el.innerHTML = newHTML;
// });
document.getElementById('chat-messages').scrollTop = document.getElementById('chat-messages').scrollHeight;
};