mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-18 03:31:03 +01:00
feat: add toMid to chat messages
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
"chat.no_active": "You have no active chats.",
|
"chat.no_active": "You have no active chats.",
|
||||||
"chat.user_typing": "%1 is typing ...",
|
"chat.user_typing": "%1 is typing ...",
|
||||||
"chat.user_has_messaged_you": "%1 has messaged you.",
|
"chat.user_has_messaged_you": "%1 has messaged you.",
|
||||||
|
"chat.replying-to": "Replying to %1",
|
||||||
"chat.see_all": "All chats",
|
"chat.see_all": "All chats",
|
||||||
"chat.mark_all_read": "Mark all read",
|
"chat.mark_all_read": "Mark all read",
|
||||||
"chat.no-messages": "Please select a recipient to view chat message history",
|
"chat.no-messages": "Please select a recipient to view chat message history",
|
||||||
|
|||||||
@@ -72,16 +72,18 @@ define('forum/chats', [
|
|||||||
Chats.addEventListeners = function () {
|
Chats.addEventListeners = function () {
|
||||||
const { roomId } = ajaxify.data;
|
const { roomId } = ajaxify.data;
|
||||||
const mainWrapper = $('[component="chat/main-wrapper"]');
|
const mainWrapper = $('[component="chat/main-wrapper"]');
|
||||||
|
const chatMessageContent = $('[component="chat/message/content"]');
|
||||||
const chatControls = components.get('chat/controls');
|
const chatControls = components.get('chat/controls');
|
||||||
Chats.addSendHandlers(roomId, $('.chat-input'), $('.expanded-chat button[data-action="send"]'));
|
Chats.addSendHandlers(roomId, $('.chat-input'), $('.expanded-chat button[data-action="send"]'));
|
||||||
Chats.addPopoutHandler();
|
Chats.addPopoutHandler();
|
||||||
Chats.addActionHandlers(components.get('chat/messages'), roomId);
|
Chats.addActionHandlers(components.get('chat/messages'), roomId);
|
||||||
Chats.addManageHandler(roomId, chatControls.find('[data-action="members"]'));
|
Chats.addManageHandler(roomId, chatControls.find('[data-action="manage"]'));
|
||||||
Chats.addRenameHandler(roomId, chatControls.find('[data-action="rename"]'));
|
Chats.addRenameHandler(roomId, chatControls.find('[data-action="rename"]'));
|
||||||
Chats.addLeaveHandler(roomId, chatControls.find('[data-action="leave"]'));
|
Chats.addLeaveHandler(roomId, chatControls.find('[data-action="leave"]'));
|
||||||
Chats.addDeleteHandler(roomId, chatControls.find('[data-action="delete"]'));
|
Chats.addDeleteHandler(roomId, chatControls.find('[data-action="delete"]'));
|
||||||
Chats.addScrollHandler(roomId, ajaxify.data.uid, $('[component="chat/message/content"]'));
|
Chats.addScrollHandler(roomId, ajaxify.data.uid, chatMessageContent);
|
||||||
Chats.addScrollBottomHandler($('[component="chat/message/content"]'));
|
Chats.addScrollBottomHandler(chatMessageContent);
|
||||||
|
Chats.addParentHandler(chatMessageContent);
|
||||||
Chats.addCharactersLeftHandler(mainWrapper);
|
Chats.addCharactersLeftHandler(mainWrapper);
|
||||||
Chats.addTextareaResizeHandler(mainWrapper);
|
Chats.addTextareaResizeHandler(mainWrapper);
|
||||||
Chats.addIPHandler(mainWrapper);
|
Chats.addIPHandler(mainWrapper);
|
||||||
@@ -98,10 +100,10 @@ define('forum/chats', [
|
|||||||
Chats.switchChat();
|
Chats.switchChat();
|
||||||
});
|
});
|
||||||
userList.init(roomId, mainWrapper);
|
userList.init(roomId, mainWrapper);
|
||||||
messageSearch.init(roomId);
|
Chats.addNotificationSettingHandler(roomId, mainWrapper);
|
||||||
|
messageSearch.init(roomId, mainWrapper);
|
||||||
Chats.addPublicRoomSortHandler();
|
Chats.addPublicRoomSortHandler();
|
||||||
Chats.addTooltipHandler();
|
Chats.addTooltipHandler();
|
||||||
Chats.addNotificationSettingHandler();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Chats.addPublicRoomSortHandler = function () {
|
Chats.addPublicRoomSortHandler = function () {
|
||||||
@@ -141,20 +143,32 @@ define('forum/chats', [
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Chats.addNotificationSettingHandler = function () {
|
Chats.addNotificationSettingHandler = function (roomId, containerEl) {
|
||||||
const notifSettingEl = $('[component="chat/notification/setting"]');
|
const notifSettingEl = containerEl.find('[component="chat/notification/setting"]');
|
||||||
|
|
||||||
notifSettingEl.find('[data-value]').on('click', async function () {
|
notifSettingEl.find('[data-value]').on('click', async function () {
|
||||||
notifSettingEl.find('i.fa-check').addClass('hidden');
|
notifSettingEl.find('i.fa-check').addClass('hidden');
|
||||||
const $this = $(this);
|
const $this = $(this);
|
||||||
$this.find('i.fa-check').removeClass('hidden');
|
$this.find('i.fa-check').removeClass('hidden');
|
||||||
$('[component="chat/notification/setting/icon"]').attr('class', `fa ${$this.attr('data-icon')}`);
|
notifSettingEl.find('[component="chat/notification/setting/icon"]').attr('class', `fa ${$this.attr('data-icon')}`);
|
||||||
await socket.emit('modules.chats.setNotificationSetting', {
|
await socket.emit('modules.chats.setNotificationSetting', {
|
||||||
roomId: ajaxify.data.roomId,
|
roomId: roomId,
|
||||||
value: $this.attr('data-value'),
|
value: $this.attr('data-value'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
Chats.addParentHandler = function (chatContent) {
|
||||||
|
chatContent.on('click', '[component="chat/message/parent"]', function () {
|
||||||
|
const parentEl = $(this);
|
||||||
|
parentEl.find('[component="chat/message/parent/content"]').toggleClass('line-clamp-1');
|
||||||
|
parentEl.find('.chat-timestamp').toggleClass('hidden');
|
||||||
|
parentEl.toggleClass('flex-column').toggleClass('flex-row');
|
||||||
|
if (chatContent.length && messages.isAtBottom(chatContent)) {
|
||||||
|
messages.scrollToBottom(chatContent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
Chats.addUploadHandler = function (options) {
|
Chats.addUploadHandler = function (options) {
|
||||||
uploadHelpers.init({
|
uploadHelpers.init({
|
||||||
@@ -285,14 +299,15 @@ define('forum/chats', [
|
|||||||
const action = this.getAttribute('data-action');
|
const action = this.getAttribute('data-action');
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'edit': {
|
case 'reply':
|
||||||
|
messages.prepReplyTo(msgEl, roomId);
|
||||||
|
break;
|
||||||
|
case 'edit':
|
||||||
messages.prepEdit(msgEl, messageId, roomId);
|
messages.prepEdit(msgEl, messageId, roomId);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case 'delete':
|
case 'delete':
|
||||||
messages.delete(messageId, roomId);
|
messages.delete(messageId, roomId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'restore':
|
case 'restore':
|
||||||
messages.restore(messageId, roomId);
|
messages.restore(messageId, roomId);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -11,17 +11,17 @@ define('forum/chats/message-search', [
|
|||||||
let chatContent;
|
let chatContent;
|
||||||
let clearEl;
|
let clearEl;
|
||||||
let toggleEl;
|
let toggleEl;
|
||||||
let containerEl;
|
let searchContainerEl;
|
||||||
messageSearch.init = function (_roomId) {
|
messageSearch.init = function (_roomId, containerEl) {
|
||||||
roomId = _roomId;
|
roomId = _roomId;
|
||||||
|
|
||||||
resultListEl = $('[component="chat/message/search/results"]');
|
resultListEl = containerEl.find('[component="chat/message/search/results"]');
|
||||||
chatContent = $('[component="chat/message/content"]');
|
chatContent = containerEl.find('[component="chat/message/content"]');
|
||||||
clearEl = $('[component="chat/room/search/clear"]');
|
clearEl = containerEl.find('[component="chat/room/search/clear"]');
|
||||||
containerEl = $('[component="chat/room/search/container"]');
|
searchContainerEl = containerEl.find('[component="chat/room/search/container"]');
|
||||||
toggleEl = $('[component="chat/room/search/toggle"');
|
toggleEl = containerEl.find('[component="chat/room/search/toggle"');
|
||||||
|
|
||||||
searchInputEl = $('[component="chat/room/search"]');
|
searchInputEl = containerEl.find('[component="chat/room/search"]');
|
||||||
searchInputEl.on('keyup', utils.debounce(doSearch, 250))
|
searchInputEl.on('keyup', utils.debounce(doSearch, 250))
|
||||||
.on('focus', () => {
|
.on('focus', () => {
|
||||||
if (searchInputEl.val()) {
|
if (searchInputEl.val()) {
|
||||||
@@ -29,14 +29,14 @@ define('forum/chats/message-search', [
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$('[component="chat/input"]').on('focus', () => {
|
containerEl.find('[component="chat/input"]').on('focus', () => {
|
||||||
resultListEl.addClass('hidden');
|
resultListEl.addClass('hidden');
|
||||||
chatContent.removeClass('hidden');
|
chatContent.removeClass('hidden');
|
||||||
});
|
});
|
||||||
clearEl.on('click', clearInputAndResults);
|
clearEl.on('click', clearInputAndResults);
|
||||||
|
|
||||||
toggleEl.on('click', () => {
|
toggleEl.on('click', () => {
|
||||||
containerEl.removeClass('hidden');
|
searchContainerEl.removeClass('hidden');
|
||||||
toggleEl.addClass('hidden');
|
toggleEl.addClass('hidden');
|
||||||
searchInputEl.trigger('focus');
|
searchInputEl.trigger('focus');
|
||||||
});
|
});
|
||||||
@@ -52,7 +52,7 @@ define('forum/chats/message-search', [
|
|||||||
removeResults();
|
removeResults();
|
||||||
resultListEl.addClass('hidden');
|
resultListEl.addClass('hidden');
|
||||||
clearEl.addClass('hidden');
|
clearEl.addClass('hidden');
|
||||||
containerEl.addClass('hidden');
|
searchContainerEl.addClass('hidden');
|
||||||
chatContent.removeClass('hidden');
|
chatContent.removeClass('hidden');
|
||||||
toggleEl.removeClass('hidden');
|
toggleEl.removeClass('hidden');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,13 @@ define('forum/chats/messages', [
|
|||||||
messages.updateTextAreaHeight(chatContent);
|
messages.updateTextAreaHeight(chatContent);
|
||||||
const payload = { roomId, message };
|
const payload = { roomId, message };
|
||||||
({ roomId, message } = await hooks.fire('filter:chat.send', payload));
|
({ roomId, message } = await hooks.fire('filter:chat.send', payload));
|
||||||
|
const replyToEl = inputEl.parents('[component="chat/composer"]')
|
||||||
api.post(`/chats/${roomId}`, { message }).then(() => {
|
.find('[component="chat/composer/replying-to"]');
|
||||||
|
const toMid = replyToEl.attr('data-tomid');
|
||||||
|
api.post(`/chats/${roomId}`, { message, toMid: toMid }).then(() => {
|
||||||
hooks.fire('action:chat.sent', { roomId, message });
|
hooks.fire('action:chat.sent', { roomId, message });
|
||||||
|
replyToEl.addClass('hidden');
|
||||||
|
replyToEl.attr('data-tomid', '');
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
inputEl.val(message).trigger('input');
|
inputEl.val(message).trigger('input');
|
||||||
messages.updateRemainingLength(inputEl.parent());
|
messages.updateRemainingLength(inputEl.parent());
|
||||||
@@ -76,7 +80,7 @@ define('forum/chats/messages', [
|
|||||||
const lastSpeaker = parseInt(lastMsgEl.attr('data-uid'), 10);
|
const lastSpeaker = parseInt(lastMsgEl.attr('data-uid'), 10);
|
||||||
const lasttimestamp = parseInt(lastMsgEl.attr('data-timestamp'), 10);
|
const lasttimestamp = parseInt(lastMsgEl.attr('data-timestamp'), 10);
|
||||||
if (!Array.isArray(data)) {
|
if (!Array.isArray(data)) {
|
||||||
data.newSet = lastSpeaker !== parseInt(data.fromuid, 10) ||
|
data.newSet = data.toMid || lastSpeaker !== parseInt(data.fromuid, 10) ||
|
||||||
parseInt(data.timestamp, 10) > parseInt(lasttimestamp, 10) + (1000 * 60 * 3);
|
parseInt(data.timestamp, 10) > parseInt(lasttimestamp, 10) + (1000 * 60 * 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +160,28 @@ define('forum/chats/messages', [
|
|||||||
.toggleClass('hidden', isAtBottom);
|
.toggleClass('hidden', isAtBottom);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
messages.prepReplyTo = async function (msgEl, roomId) {
|
||||||
|
const chatMessages = msgEl.parents(`[component="chat/messages"][data-roomid="${roomId}"]`);
|
||||||
|
const chatContent = chatMessages.find('[component="chat/message/content"]');
|
||||||
|
const composerEl = chatMessages.find('[component="chat/composer"]');
|
||||||
|
const mid = msgEl.attr('data-mid');
|
||||||
|
const replyToEl = composerEl.find('[component="chat/composer/replying-to"]');
|
||||||
|
replyToEl.attr('data-tomid', mid)
|
||||||
|
.find('[component="chat/composer/replying-to-text"]')
|
||||||
|
.translateText(`[[modules:chat.replying-to, ${msgEl.attr('data-username')}]]`);
|
||||||
|
replyToEl.removeClass('hidden');
|
||||||
|
replyToEl.find('[component="chat/composer/replying-to-cancel"]').off('click')
|
||||||
|
.on('click', () => {
|
||||||
|
replyToEl.attr('data-tomid', '');
|
||||||
|
replyToEl.addClass('hidden');
|
||||||
|
});
|
||||||
|
|
||||||
|
if (chatContent.length && messages.isAtBottom(chatContent)) {
|
||||||
|
messages.scrollToBottom(chatContent);
|
||||||
|
}
|
||||||
|
composerEl.find('[component="chat/input"]').trigger('focus');
|
||||||
|
};
|
||||||
|
|
||||||
messages.prepEdit = async function (msgEl, mid, roomId) {
|
messages.prepEdit = async function (msgEl, mid, roomId) {
|
||||||
const raw = await socket.emit('modules.chats.getRaw', { mid: mid, roomId: roomId });
|
const raw = await socket.emit('modules.chats.getRaw', { mid: mid, roomId: roomId });
|
||||||
const editEl = await app.parseAndTranslate('partials/chats/edit-message', {
|
const editEl = await app.parseAndTranslate('partials/chats/edit-message', {
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ define('chat', [
|
|||||||
newMessage = data.self === 0;
|
newMessage = data.self === 0;
|
||||||
}
|
}
|
||||||
data.message.self = data.self;
|
data.message.self = data.self;
|
||||||
data.message.timestamp = Math.min(Date.now(), data.message.timetamp);
|
data.message.timestamp = Math.min(Date.now(), data.message.timestamp);
|
||||||
data.message.timestampISO = utils.toISOString(data.message.timestamp);
|
data.message.timestampISO = utils.toISOString(data.message.timestamp);
|
||||||
addMessageToModal(data);
|
addMessageToModal(data);
|
||||||
}
|
}
|
||||||
@@ -203,13 +203,13 @@ define('chat', [
|
|||||||
require(['forum/chats/messages'], function (ChatsMessages) {
|
require(['forum/chats/messages'], function (ChatsMessages) {
|
||||||
// don't add if already added
|
// don't add if already added
|
||||||
if (!modal.find('[data-mid="' + data.message.messageId + '"]').length) {
|
if (!modal.find('[data-mid="' + data.message.messageId + '"]').length) {
|
||||||
ChatsMessages.appendChatMessage(modal.find('.chat-content'), data.message);
|
ChatsMessages.appendChatMessage(modal.find('[component="chat/message/content"]'), data.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modal.is(':visible')) {
|
if (modal.is(':visible')) {
|
||||||
taskbar.updateActive(modal.attr('data-uuid'));
|
taskbar.updateActive(modal.attr('data-uuid'));
|
||||||
if (ChatsMessages.isAtBottom(modal.find('.chat-content'))) {
|
if (ChatsMessages.isAtBottom(modal.find('[component="chat/message/content"]'))) {
|
||||||
ChatsMessages.scrollToBottom(modal.find('.chat-content'));
|
ChatsMessages.scrollToBottom(modal.find('[component="chat/message/content"]'));
|
||||||
}
|
}
|
||||||
} else if (!ajaxify.data.template.chats) {
|
} else if (!ajaxify.data.template.chats) {
|
||||||
module.toggleNew(modal.attr('data-uuid'), true, true);
|
module.toggleNew(modal.attr('data-uuid'), true, true);
|
||||||
@@ -254,17 +254,18 @@ define('chat', [
|
|||||||
module.createModal = function (data, callback) {
|
module.createModal = function (data, callback) {
|
||||||
callback = callback || function () {};
|
callback = callback || function () {};
|
||||||
require([
|
require([
|
||||||
'scrollStop', 'forum/chats', 'forum/chats/messages',
|
'scrollStop', 'forum/chats', 'forum/chats/messages', 'forum/chats/message-search',
|
||||||
], function (scrollStop, Chats, ChatsMessages) {
|
], function (scrollStop, Chats, ChatsMessages, messageSearch) {
|
||||||
app.parseAndTranslate('chat', data, function (chatModal) {
|
app.parseAndTranslate('chat', data, function (chatModal) {
|
||||||
if (module.modalExists(data.roomId)) {
|
const roomId = data.roomId;
|
||||||
|
if (module.modalExists(roomId)) {
|
||||||
return callback(module.getModal(data.roomId));
|
return callback(module.getModal(data.roomId));
|
||||||
}
|
}
|
||||||
const uuid = utils.generateUUID();
|
const uuid = utils.generateUUID();
|
||||||
let dragged = false;
|
let dragged = false;
|
||||||
|
|
||||||
chatModal.attr('id', 'chat-modal-' + data.roomId);
|
chatModal.attr('id', 'chat-modal-' + roomId);
|
||||||
chatModal.attr('data-roomid', data.roomId);
|
chatModal.attr('data-roomid', roomId);
|
||||||
chatModal.attr('intervalId', 0);
|
chatModal.attr('intervalId', 0);
|
||||||
chatModal.attr('data-uuid', uuid);
|
chatModal.attr('data-uuid', uuid);
|
||||||
chatModal.css('position', 'fixed');
|
chatModal.css('position', 'fixed');
|
||||||
@@ -313,7 +314,7 @@ define('chat', [
|
|||||||
components.get('chat/input').val(text);
|
components.get('chat/input').val(text);
|
||||||
});
|
});
|
||||||
|
|
||||||
ajaxify.go('user/' + app.user.userslug + '/chats/' + chatModal.attr('data-roomid'));
|
ajaxify.go(`user/${app.user.userslug}/chats/${roomId}`);
|
||||||
module.close(uuid);
|
module.close(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,23 +341,23 @@ define('chat', [
|
|||||||
|
|
||||||
chatModal.on('mousemove keypress click', function () {
|
chatModal.on('mousemove keypress click', function () {
|
||||||
if (newMessage) {
|
if (newMessage) {
|
||||||
api.del(`/chats/${data.roomId}/state`, {});
|
api.del(`/chats/${roomId}/state`, {});
|
||||||
newMessage = false;
|
newMessage = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Chats.addActionHandlers(chatModal.find('[component="chat/messages"]'), data.roomId);
|
Chats.addActionHandlers(chatModal.find('[component="chat/messages"]'), roomId);
|
||||||
Chats.addRenameHandler(chatModal.attr('data-roomid'), chatModal.find('[data-action="rename"]'), data.roomName);
|
Chats.addRenameHandler(roomId, chatModal.find('[data-action="rename"]'), data.roomName);
|
||||||
Chats.addLeaveHandler(chatModal.attr('data-roomid'), chatModal.find('[data-action="leave"]'));
|
Chats.addLeaveHandler(roomId, chatModal.find('[data-action="leave"]'));
|
||||||
Chats.addDeleteHandler(chatModal.attr('data-roomid'), chatModal.find('[data-action="delete"]'));
|
Chats.addDeleteHandler(roomId, chatModal.find('[data-action="delete"]'));
|
||||||
Chats.addSendHandlers(chatModal.attr('data-roomid'), chatModal.find('.chat-input'), chatModal.find('[data-action="send"]'));
|
Chats.addSendHandlers(roomId, chatModal.find('.chat-input'), chatModal.find('[data-action="send"]'));
|
||||||
Chats.addManageHandler(chatModal.attr('data-roomid'), chatModal.find('[data-action="members"]'));
|
Chats.addManageHandler(roomId, chatModal.find('[data-action="manage"]'));
|
||||||
|
|
||||||
Chats.createAutoComplete(chatModal.attr('data-roomid'), chatModal.find('[component="chat/input"]'));
|
Chats.createAutoComplete(roomId, chatModal.find('[component="chat/input"]'));
|
||||||
|
|
||||||
Chats.addScrollHandler(chatModal.attr('data-roomid'), data.uid, chatModal.find('.chat-content'));
|
|
||||||
Chats.addScrollBottomHandler(chatModal.find('.chat-content'));
|
|
||||||
|
|
||||||
|
Chats.addScrollHandler(roomId, data.uid, chatModal.find('[component="chat/message/content"]'));
|
||||||
|
Chats.addScrollBottomHandler(chatModal.find('[component="chat/message/content"]'));
|
||||||
|
Chats.addParentHandler(chatModal.find('[component="chat/message/content"]'));
|
||||||
Chats.addCharactersLeftHandler(chatModal);
|
Chats.addCharactersLeftHandler(chatModal);
|
||||||
Chats.addTextareaResizeHandler(chatModal);
|
Chats.addTextareaResizeHandler(chatModal);
|
||||||
Chats.addIPHandler(chatModal);
|
Chats.addIPHandler(chatModal);
|
||||||
@@ -370,6 +371,8 @@ define('chat', [
|
|||||||
});
|
});
|
||||||
|
|
||||||
ChatsMessages.addSocketListeners();
|
ChatsMessages.addSocketListeners();
|
||||||
|
messageSearch.init(roomId, chatModal);
|
||||||
|
Chats.addNotificationSettingHandler(roomId, chatModal);
|
||||||
|
|
||||||
taskbar.push('chat', chatModal.attr('data-uuid'), {
|
taskbar.push('chat', chatModal.attr('data-uuid'), {
|
||||||
title: '[[modules:chat.chatting_with]] ' + (data.roomName || (data.users.length ? data.users[0].username : '')),
|
title: '[[modules:chat.chatting_with]] ' + (data.roomName || (data.users.length ? data.users[0].username : '')),
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ chatsAPI.post = async (caller, data) => {
|
|||||||
uid: caller.uid,
|
uid: caller.uid,
|
||||||
roomId: data.roomId,
|
roomId: data.roomId,
|
||||||
content: data.message,
|
content: data.message,
|
||||||
|
toMid: data.toMid,
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
ip: caller.ip,
|
ip: caller.ip,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ Chats.get = async (req, res) => {
|
|||||||
Chats.post = async (req, res) => {
|
Chats.post = async (req, res) => {
|
||||||
const messageObj = await api.chats.post(req, {
|
const messageObj = await api.chats.post(req, {
|
||||||
message: req.body.message,
|
message: req.body.message,
|
||||||
|
toMid: req.body.toMid,
|
||||||
roomId: req.params.roomId,
|
roomId: req.params.roomId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ const meta = require('../meta');
|
|||||||
const plugins = require('../plugins');
|
const plugins = require('../plugins');
|
||||||
const db = require('../database');
|
const db = require('../database');
|
||||||
const user = require('../user');
|
const user = require('../user');
|
||||||
|
const utils = require('../utils');
|
||||||
|
|
||||||
module.exports = function (Messaging) {
|
module.exports = function (Messaging) {
|
||||||
Messaging.sendMessage = async (data) => {
|
Messaging.sendMessage = async (data) => {
|
||||||
@@ -41,6 +42,9 @@ module.exports = function (Messaging) {
|
|||||||
if (!roomData) {
|
if (!roomData) {
|
||||||
throw new Error('[[error:no-room]]');
|
throw new Error('[[error:no-room]]');
|
||||||
}
|
}
|
||||||
|
if (data.toMid && !utils.isNumber(data.toMid)) {
|
||||||
|
throw new Error('[[error:invalid-mid]]');
|
||||||
|
}
|
||||||
const mid = await db.incrObjectField('global', 'nextMid');
|
const mid = await db.incrObjectField('global', 'nextMid');
|
||||||
const timestamp = data.timestamp || Date.now();
|
const timestamp = data.timestamp || Date.now();
|
||||||
let message = {
|
let message = {
|
||||||
@@ -50,7 +54,9 @@ module.exports = function (Messaging) {
|
|||||||
fromuid: uid,
|
fromuid: uid,
|
||||||
roomId: roomId,
|
roomId: roomId,
|
||||||
};
|
};
|
||||||
|
if (data.toMid) {
|
||||||
|
message.toMid = data.toMid;
|
||||||
|
}
|
||||||
if (data.system) {
|
if (data.system) {
|
||||||
message.system = data.system;
|
message.system = data.system;
|
||||||
}
|
}
|
||||||
@@ -69,6 +75,9 @@ module.exports = function (Messaging) {
|
|||||||
db.sortedSetAdd('messages:mid', timestamp, mid),
|
db.sortedSetAdd('messages:mid', timestamp, mid),
|
||||||
db.incrObjectField('global', 'messageCount'),
|
db.incrObjectField('global', 'messageCount'),
|
||||||
];
|
];
|
||||||
|
if (data.toMid) {
|
||||||
|
tasks.push(db.sortedSetAdd(`mid:${data.toMid}:replies`, timestamp, mid));
|
||||||
|
}
|
||||||
if (roomData.public) {
|
if (roomData.public) {
|
||||||
tasks.push(
|
tasks.push(
|
||||||
db.sortedSetAdd('chat:rooms:public:lastpost', timestamp, roomId)
|
db.sortedSetAdd('chat:rooms:public:lastpost', timestamp, roomId)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const _ = require('lodash');
|
||||||
const validator = require('validator');
|
const validator = require('validator');
|
||||||
|
|
||||||
const db = require('../database');
|
const db = require('../database');
|
||||||
@@ -73,16 +74,7 @@ module.exports = function (Messaging) {
|
|||||||
message.roomId = String(message.roomId || roomId);
|
message.roomId = String(message.roomId || roomId);
|
||||||
});
|
});
|
||||||
|
|
||||||
messages = await Promise.all(messages.map(async (message) => {
|
await parseMessages(messages, uid, roomId, isNew);
|
||||||
if (message.system) {
|
|
||||||
message.content = validator.escape(String(message.content));
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await Messaging.parse(message.content, message.fromuid, uid, roomId, isNew);
|
|
||||||
message.content = result;
|
|
||||||
return message;
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (messages.length > 1) {
|
if (messages.length > 1) {
|
||||||
// Add a spacer in between messages with time gaps between them
|
// Add a spacer in between messages with time gaps between them
|
||||||
@@ -96,7 +88,7 @@ module.exports = function (Messaging) {
|
|||||||
message.newSet = true;
|
message.newSet = true;
|
||||||
} else if (index > 0 && messages[index - 1].system) {
|
} else if (index > 0 && messages[index - 1].system) {
|
||||||
message.newSet = true;
|
message.newSet = true;
|
||||||
} else if (index === 0) {
|
} else if (index === 0 || message.toMid) {
|
||||||
message.newSet = true;
|
message.newSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +103,7 @@ module.exports = function (Messaging) {
|
|||||||
const fields = await Messaging.getMessageFields(mid, ['fromuid', 'timestamp']);
|
const fields = await Messaging.getMessageFields(mid, ['fromuid', 'timestamp']);
|
||||||
if ((messages[0].timestamp > fields.timestamp + Messaging.newMessageCutoff) ||
|
if ((messages[0].timestamp > fields.timestamp + Messaging.newMessageCutoff) ||
|
||||||
(messages[0].fromuid !== fields.fromuid) ||
|
(messages[0].fromuid !== fields.fromuid) ||
|
||||||
messages[0].system) {
|
messages[0].system || messages[0].toMid) {
|
||||||
// If it's been 5 minutes, this is a new set of messages
|
// If it's been 5 minutes, this is a new set of messages
|
||||||
messages[0].newSet = true;
|
messages[0].newSet = true;
|
||||||
}
|
}
|
||||||
@@ -120,6 +112,8 @@ module.exports = function (Messaging) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await addParentMessages(messages, uid, roomId);
|
||||||
|
|
||||||
const data = await plugins.hooks.fire('filter:messaging.getMessages', {
|
const data = await plugins.hooks.fire('filter:messaging.getMessages', {
|
||||||
messages: messages,
|
messages: messages,
|
||||||
uid: uid,
|
uid: uid,
|
||||||
@@ -130,6 +124,60 @@ module.exports = function (Messaging) {
|
|||||||
|
|
||||||
return data && data.messages;
|
return data && data.messages;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function addParentMessages(messages, uid, roomId) {
|
||||||
|
let parentMids = messages.map(msg => (msg && msg.hasOwnProperty('toMid') ? parseInt(msg.toMid, 10) : null)).filter(Boolean);
|
||||||
|
|
||||||
|
if (!parentMids.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parentMids = _.uniq(parentMids);
|
||||||
|
const parentMessages = await Messaging.getMessagesFields(parentMids, [
|
||||||
|
'fromuid', 'content', 'timestamp',
|
||||||
|
]);
|
||||||
|
const parentUids = _.uniq(parentMessages.map(msg => msg && msg.fromuid));
|
||||||
|
const usersMap = _.zipObject(
|
||||||
|
parentUids,
|
||||||
|
await user.getUsersFields(parentUids, ['uid', 'username', 'userslug', 'picture'])
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(parentMessages.map(async (parentMsg) => {
|
||||||
|
const foundMsg = messages.find(msg => parseInt(msg.mid, 10) === parseInt(parentMsg.mid, 10));
|
||||||
|
if (foundMsg) {
|
||||||
|
parentMsg.content = foundMsg.content;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parentMsg.content = await parseMessage(parentMsg, uid, roomId, false);
|
||||||
|
}));
|
||||||
|
|
||||||
|
const parents = {};
|
||||||
|
parentMessages.forEach((msg, i) => {
|
||||||
|
if (usersMap[msg.fromuid]) {
|
||||||
|
msg.user = usersMap[msg.fromuid];
|
||||||
|
parents[parentMids[i]] = msg;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
messages.forEach((msg) => {
|
||||||
|
if (parents[msg.toMid]) {
|
||||||
|
msg.parent = parents[msg.toMid];
|
||||||
|
msg.parent.mid = msg.toMid;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function parseMessages(messages, uid, roomId, isNew) {
|
||||||
|
await Promise.all(messages.map(async (message) => {
|
||||||
|
message.content = await parseMessage(message, uid, roomId, isNew);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
async function parseMessage(message, uid, roomId, isNew) {
|
||||||
|
if (message.system) {
|
||||||
|
return validator.escape(String(message.content));
|
||||||
|
}
|
||||||
|
|
||||||
|
return await Messaging.parse(message.content, message.fromuid, uid, roomId, isNew);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
async function modifyMessage(message, fields, mid) {
|
async function modifyMessage(message, fields, mid) {
|
||||||
|
|||||||
@@ -189,14 +189,18 @@ module.exports = function (Topics) {
|
|||||||
const usersMap = _.zipObject(parentUids, userData);
|
const usersMap = _.zipObject(parentUids, userData);
|
||||||
const parents = {};
|
const parents = {};
|
||||||
parentPosts.forEach((post, i) => {
|
parentPosts.forEach((post, i) => {
|
||||||
parents[parentPids[i]] = {
|
if (usersMap[post.uid]) {
|
||||||
username: usersMap[post.uid].username,
|
parents[parentPids[i]] = {
|
||||||
displayname: usersMap[post.uid].displayname,
|
username: usersMap[post.uid].username,
|
||||||
};
|
displayname: usersMap[post.uid].displayname,
|
||||||
|
};
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
postData.forEach((post) => {
|
postData.forEach((post) => {
|
||||||
post.parent = parents[post.toPid];
|
if (parents[post.toPid]) {
|
||||||
|
post.parent = parents[post.toPid];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user