From 0204f2aafa4a510a23b2c9f3a4139f2558812a85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Wed, 31 Jul 2024 15:20:51 -0400 Subject: [PATCH] feat: update chat teasers when a new chat starts, closes #12713 --- public/src/client/chats.js | 42 ++++++++++++++++++++++++ src/api/chats.js | 2 +- src/views/partials/chats/recent_room.tpl | 14 +++----- src/views/partials/chats/room-teaser.tpl | 10 ++++++ 4 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 src/views/partials/chats/room-teaser.tpl diff --git a/public/src/client/chats.js b/public/src/client/chats.js index abaae9f818..af18c73ec2 100644 --- a/public/src/client/chats.js +++ b/public/src/client/chats.js @@ -684,6 +684,31 @@ define('forum/chats', [ }; Chats.addSocketListeners = function () { + socket.on('event:new_notification', async function (notif) { + const { type, roomId } = notif; + if (ajaxify.data.template.chats && app.user.userslug && (type === 'new-chat' || type === 'new-group-chat')) { + const inRoom = parseInt(roomId, 10) === parseInt(ajaxify.data.roomId, 10); + if (inRoom) { + return; + } + const { rooms } = await api.get(`/chats`, { start: 0, perPage: 1 }); + const room = rooms.find(r => parseInt(r.roomId, 10) === parseInt(roomId, 10)); + if (room) { + const roomEl = chatNavWrapper.find(`[data-roomid="${roomId}"]`); + if (roomEl.length) { + updateTeaser(roomId, room.teaser); + } else { + const recentEl = components.get('chat/recent'); + const html = await app.parseAndTranslate('chats', 'rooms', { + rooms: [room], + showBottomHr: true, + }); + recentEl.prepend(html); + } + } + } + }); + socket.on('event:chats.receive', function (data) { if (chatModule.isFromBlockedUser(data.fromUid)) { return; @@ -697,9 +722,26 @@ define('forum/chats', [ data.message.timestamp = Math.min(Date.now(), data.message.timestamp); data.message.timestampISO = utils.toISOString(data.message.timestamp); messages.appendChatMessage($('[component="chat/message/content"]'), data.message); + + updateTeaser(data.roomId, { + content: utils.stripHTMLTags(utils.decodeHTMLEntities(data.message.content)), + user: data.message.fromUser, + timestampISO: data.message.timestampISO, + }); } }); + async function updateTeaser(roomId, teaser) { + const roomEl = $(`[data-roomid="${roomId}"]`); + if (roomEl.length) { + const html = await app.parseAndTranslate('partials/chats/room-teaser', { + teaser: teaser, + }); + roomEl.find('[component="chat/room/teaser"]').html(html[0].outerHTML); + roomEl.find('.timeago').timeago(); + } + } + socket.on('event:chats.public.unread', function (data) { if ( chatModule.isFromBlockedUser(data.fromUid) || diff --git a/src/api/chats.js b/src/api/chats.js index db07ac32f0..4de434e4ef 100644 --- a/src/api/chats.js +++ b/src/api/chats.js @@ -37,7 +37,7 @@ async function rateLimitExceeded(caller, field) { } chatsAPI.list = async (caller, { uid = caller.uid, start, stop, page, perPage } = {}) => { - if (!start && !stop && !page) { + if (!utils.isNumber(start) && !utils.isNumber(stop) && !utils.isNumber(page)) { throw new Error('[[error:invalid-data]]'); } diff --git a/src/views/partials/chats/recent_room.tpl b/src/views/partials/chats/recent_room.tpl index 57caf57301..ae48ac531f 100644 --- a/src/views/partials/chats/recent_room.tpl +++ b/src/views/partials/chats/recent_room.tpl @@ -31,15 +31,7 @@ {{{ end }}} {{{ end }}} - - {{{ if ./teaser }}} -
- {buildAvatar(./teaser.user, "14px", true, "align-middle")} - {./teaser.user.username}: - {./teaser.content} -
-
{{{ if ./teaser.timeagoLong }}}{./teaser.timeagoLong}{{{ else }}}{{{ end }}}
- {{{ end }}} +
@@ -52,4 +44,8 @@
{{{ if !@last }}}
+{{{ else }}} +{{{ if showBottomHr }}} +
+{{{ end }}} {{{ end }}} diff --git a/src/views/partials/chats/room-teaser.tpl b/src/views/partials/chats/room-teaser.tpl new file mode 100644 index 0000000000..ae7f53f251 --- /dev/null +++ b/src/views/partials/chats/room-teaser.tpl @@ -0,0 +1,10 @@ +
+ {{{ if ./teaser }}} +
+ {buildAvatar(./teaser.user, "14px", true, "align-middle")} + {./teaser.user.username}: + {./teaser.content} +
+
{{{ if ./teaser.timeagoLong }}}{./teaser.timeagoLong}{{{ else }}}{{{ end }}}
+ {{{ end }}} +
\ No newline at end of file