|
|
|
@ -9,47 +9,34 @@ define('forum/chats/messages', [
|
|
|
|
|
|
|
|
|
|
messages.sendMessage = async function (roomId, inputEl) {
|
|
|
|
|
let message = inputEl.val();
|
|
|
|
|
let mid = inputEl.attr('data-mid');
|
|
|
|
|
|
|
|
|
|
if (!message.trim().length) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const chatContent = inputEl.parents(`[component="chat/messages"][data-roomid="${roomId}"]`);
|
|
|
|
|
inputEl.val('').trigger('input');
|
|
|
|
|
inputEl.removeAttr('data-mid');
|
|
|
|
|
|
|
|
|
|
messages.updateRemainingLength(inputEl.parent());
|
|
|
|
|
messages.updateTextAreaHeight(chatContent);
|
|
|
|
|
const payload = { roomId, message, mid };
|
|
|
|
|
({ roomId, message, mid } = await hooks.fire('filter:chat.send', payload));
|
|
|
|
|
const payload = { roomId, message };
|
|
|
|
|
({ roomId, message } = await hooks.fire('filter:chat.send', payload));
|
|
|
|
|
|
|
|
|
|
if (!mid) {
|
|
|
|
|
api.post(`/chats/${roomId}`, { message }).then(() => {
|
|
|
|
|
hooks.fire('action:chat.sent', { roomId, message, mid });
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
inputEl.val(message).trigger('input');
|
|
|
|
|
messages.updateRemainingLength(inputEl.parent());
|
|
|
|
|
if (err.message === '[[error:email-not-confirmed-chat]]') {
|
|
|
|
|
return messagesModule.showEmailConfirmWarning(err.message);
|
|
|
|
|
}
|
|
|
|
|
api.post(`/chats/${roomId}`, { message }).then(() => {
|
|
|
|
|
hooks.fire('action:chat.sent', { roomId, message });
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
inputEl.val(message).trigger('input');
|
|
|
|
|
messages.updateRemainingLength(inputEl.parent());
|
|
|
|
|
if (err.message === '[[error:email-not-confirmed-chat]]') {
|
|
|
|
|
return messagesModule.showEmailConfirmWarning(err.message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return alerts.alert({
|
|
|
|
|
alert_id: 'chat_spam_error',
|
|
|
|
|
title: '[[global:alert.error]]',
|
|
|
|
|
message: err.message,
|
|
|
|
|
type: 'danger',
|
|
|
|
|
timeout: 10000,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
api.put(`/chats/${roomId}/messages/${mid}`, { message }).then(() => {
|
|
|
|
|
hooks.fire('action:chat.edited', { roomId, message, mid });
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
inputEl.val(message).trigger('input');
|
|
|
|
|
inputEl.attr('data-mid', mid);
|
|
|
|
|
messages.updateRemainingLength(inputEl.parent());
|
|
|
|
|
return alerts.error(err);
|
|
|
|
|
return alerts.alert({
|
|
|
|
|
alert_id: 'chat_spam_error',
|
|
|
|
|
title: '[[global:alert.error]]',
|
|
|
|
|
message: err.message,
|
|
|
|
|
type: 'danger',
|
|
|
|
|
timeout: 10000,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
messages.updateRemainingLength = function (parent) {
|
|
|
|
@ -76,6 +63,15 @@ define('forum/chats/messages', [
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function autoresizeTextArea(textarea) {
|
|
|
|
|
const scrollHeight = textarea.prop('scrollHeight');
|
|
|
|
|
textarea.css({ height: scrollHeight + 'px' });
|
|
|
|
|
textarea.on('input', function () {
|
|
|
|
|
textarea.css({ height: 0 });
|
|
|
|
|
textarea.css({ height: textarea.prop('scrollHeight') + 'px' });
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
messages.appendChatMessage = function (chatContentEl, data) {
|
|
|
|
|
const lastSpeaker = parseInt(chatContentEl.find('.chat-message').last().attr('data-uid'), 10);
|
|
|
|
|
const lasttimestamp = parseInt(chatContentEl.find('.chat-message').last().attr('data-timestamp'), 10);
|
|
|
|
@ -145,24 +141,63 @@ define('forum/chats/messages', [
|
|
|
|
|
.toggleClass('hidden', isAtBottom);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
messages.prepEdit = function (inputEl, messageId, roomId) {
|
|
|
|
|
socket.emit('modules.chats.getRaw', { mid: messageId, roomId: roomId }, function (err, raw) {
|
|
|
|
|
if (err) {
|
|
|
|
|
return alerts.error(err);
|
|
|
|
|
messages.prepEdit = async function (inputEl, mid, roomId) {
|
|
|
|
|
const raw = await socket.emit('modules.chats.getRaw', { mid: mid, roomId: roomId });
|
|
|
|
|
const editEl = await app.parseAndTranslate('partials/chats/edit-message', {
|
|
|
|
|
rawContent: raw,
|
|
|
|
|
});
|
|
|
|
|
const messageBody = $(`[data-roomid="${roomId}"] [data-mid="${mid}"] [component="chat/message/body"]`);
|
|
|
|
|
const messageControls = $(`[data-roomid="${roomId}"] [data-mid="${mid}"] [component="chat/message/controls"]`);
|
|
|
|
|
const chatContent = messageBody.parents('.chat-content');
|
|
|
|
|
|
|
|
|
|
messageBody.addClass('hidden');
|
|
|
|
|
messageControls.addClass('hidden');
|
|
|
|
|
editEl.insertAfter(messageBody);
|
|
|
|
|
|
|
|
|
|
const textarea = editEl.find('textarea');
|
|
|
|
|
|
|
|
|
|
textarea.focus().putCursorAtEnd();
|
|
|
|
|
autoresizeTextArea(textarea);
|
|
|
|
|
|
|
|
|
|
if (messages.isAtBottom(chatContent)) {
|
|
|
|
|
messages.scrollToBottom(chatContent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const chats = await app.require('forum/chats');
|
|
|
|
|
const autoCompleteEl = chats.createAutoComplete(0, textarea, {
|
|
|
|
|
placement: 'bottom',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function finishEdit() {
|
|
|
|
|
messageBody.removeClass('hidden');
|
|
|
|
|
messageControls.removeClass('hidden');
|
|
|
|
|
editEl.remove();
|
|
|
|
|
if (autoCompleteEl) {
|
|
|
|
|
autoCompleteEl.destroy();
|
|
|
|
|
}
|
|
|
|
|
// Populate the input field with the raw message content
|
|
|
|
|
if (inputEl.val().length === 0) {
|
|
|
|
|
// By setting the `data-mid` attribute, I tell the chat code that I am editing a
|
|
|
|
|
// message, instead of posting a new one.
|
|
|
|
|
inputEl.attr('data-mid', messageId).addClass('editing');
|
|
|
|
|
inputEl.val(raw).trigger('input').focus();
|
|
|
|
|
|
|
|
|
|
hooks.fire('action:chat.prepEdit', {
|
|
|
|
|
inputEl: inputEl,
|
|
|
|
|
messageId: messageId,
|
|
|
|
|
roomId: roomId,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
editEl.find('[data-action="cancel"]').on('click', finishEdit);
|
|
|
|
|
|
|
|
|
|
editEl.find('[data-action="save"]').on('click', function () {
|
|
|
|
|
const message = textarea.val();
|
|
|
|
|
if (!message.trim().length) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
api.put(`/chats/${roomId}/messages/${mid}`, { message }).then(() => {
|
|
|
|
|
finishEdit();
|
|
|
|
|
hooks.fire('action:chat.edited', { roomId, message, mid });
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
textarea.val(message).trigger('input');
|
|
|
|
|
alerts.error(err);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
hooks.fire('action:chat.prepEdit', {
|
|
|
|
|
inputEl: inputEl,
|
|
|
|
|
messageId: mid,
|
|
|
|
|
roomId: roomId,
|
|
|
|
|
editEl: editEl,
|
|
|
|
|
messageBody: messageBody,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|