mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-19 14:13:34 +01:00
chat: New chatSendMessage
client-side hook
This commit is contained in:
parent
4c2f7f9a11
commit
9fbd2e5c3d
4 changed files with 71 additions and 3 deletions
|
@ -56,6 +56,9 @@
|
||||||
see the original unprocessed message text and any added metadata.
|
see the original unprocessed message text and any added metadata.
|
||||||
* `rendered`: Allows plugins to completely override how the message is
|
* `rendered`: Allows plugins to completely override how the message is
|
||||||
rendered in the UI.
|
rendered in the UI.
|
||||||
|
* New `chatSendMessage` client-side hook that enables plugins to process the
|
||||||
|
text before sending it to the server or augment the message object with
|
||||||
|
custom metadata.
|
||||||
|
|
||||||
# 1.8.14
|
# 1.8.14
|
||||||
|
|
||||||
|
|
|
@ -315,6 +315,18 @@ Context properties:
|
||||||
* `duration`: How long (in milliseconds) to display the gritter notification (0
|
* `duration`: How long (in milliseconds) to display the gritter notification (0
|
||||||
to disable).
|
to disable).
|
||||||
|
|
||||||
|
## `chatSendMessage`
|
||||||
|
|
||||||
|
Called from: `src/static/js/chat.js`
|
||||||
|
|
||||||
|
This hook runs on the client side whenever the user sends a new chat message.
|
||||||
|
Plugins can mutate the message object to change the message text or add metadata
|
||||||
|
to control how the message will be rendered by the `chatNewMessage` hook.
|
||||||
|
|
||||||
|
Context properties:
|
||||||
|
|
||||||
|
* `message`: The message object that will be sent to the Etherpad server.
|
||||||
|
|
||||||
## collectContentPre
|
## collectContentPre
|
||||||
|
|
||||||
Called from: src/static/js/contentcollector.js
|
Called from: src/static/js/contentcollector.js
|
||||||
|
|
|
@ -100,10 +100,12 @@ exports.chat = (() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
send() {
|
async send() {
|
||||||
const text = $('#chatinput').val();
|
const text = $('#chatinput').val();
|
||||||
if (text.replace(/\s+/, '').length === 0) return;
|
if (text.replace(/\s+/, '').length === 0) return;
|
||||||
this._pad.collabClient.sendMessage({type: 'CHAT_MESSAGE', message: new ChatMessage(text)});
|
const message = new ChatMessage(text);
|
||||||
|
await hooks.aCallAll('chatSendMessage', Object.freeze({message}));
|
||||||
|
this._pad.collabClient.sendMessage({type: 'CHAT_MESSAGE', message});
|
||||||
$('#chatinput').val('');
|
$('#chatinput').val('');
|
||||||
},
|
},
|
||||||
async addMessage(msg, increment, isHistoryAdd) {
|
async addMessage(msg, increment, isHistoryAdd) {
|
||||||
|
|
|
@ -4,9 +4,10 @@ describe('chat hooks', function () {
|
||||||
let ChatMessage;
|
let ChatMessage;
|
||||||
let hooks;
|
let hooks;
|
||||||
const hooksBackup = {};
|
const hooksBackup = {};
|
||||||
|
let padId;
|
||||||
|
|
||||||
const loadPad = async (opts = {}) => {
|
const loadPad = async (opts = {}) => {
|
||||||
await helper.aNewPad(opts);
|
padId = await helper.aNewPad(opts);
|
||||||
ChatMessage = helper.padChrome$.window.require('ep_etherpad-lite/static/js/ChatMessage');
|
ChatMessage = helper.padChrome$.window.require('ep_etherpad-lite/static/js/ChatMessage');
|
||||||
({hooks} = helper.padChrome$.window.require('ep_etherpad-lite/static/js/pluginfw/plugin_defs'));
|
({hooks} = helper.padChrome$.window.require('ep_etherpad-lite/static/js/pluginfw/plugin_defs'));
|
||||||
for (const [name, defs] of Object.entries(hooks)) {
|
for (const [name, defs] of Object.entries(hooks)) {
|
||||||
|
@ -95,4 +96,54 @@ describe('chat hooks', function () {
|
||||||
expect(helper.chatTextParagraphs().last()[0]).to.be(rendered);
|
expect(helper.chatTextParagraphs().last()[0]).to.be(rendered);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('chatSendMessage', function () {
|
||||||
|
it('message is a ChatMessage object', async function () {
|
||||||
|
await Promise.all([
|
||||||
|
checkHook('chatSendMessage', ({message}) => {
|
||||||
|
expect(message).to.be.a(ChatMessage);
|
||||||
|
}),
|
||||||
|
helper.sendChatMessage(`${this.test.title}{enter}`),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('message metadata propagates end-to-end', async function () {
|
||||||
|
const metadata = {foo: this.test.title};
|
||||||
|
await Promise.all([
|
||||||
|
checkHook('chatSendMessage', ({message}) => {
|
||||||
|
message.customMetadata = metadata;
|
||||||
|
}),
|
||||||
|
checkHook('chatNewMessage', ({message: {customMetadata}}) => {
|
||||||
|
expect(JSON.stringify(customMetadata)).to.equal(JSON.stringify(metadata));
|
||||||
|
}),
|
||||||
|
helper.sendChatMessage(`${this.test.title}{enter}`),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('message metadata is saved in the database', async function () {
|
||||||
|
const msg = this.test.title;
|
||||||
|
const metadata = {foo: this.test.title};
|
||||||
|
await Promise.all([
|
||||||
|
checkHook('chatSendMessage', ({message}) => {
|
||||||
|
message.customMetadata = metadata;
|
||||||
|
}),
|
||||||
|
helper.sendChatMessage(`${msg}{enter}`),
|
||||||
|
]);
|
||||||
|
let gotMessage;
|
||||||
|
const messageP = new Promise((resolve) => gotMessage = resolve);
|
||||||
|
await loadPad({
|
||||||
|
id: padId,
|
||||||
|
hookFns: {
|
||||||
|
chatNewMessage: [
|
||||||
|
(hookName, {message}) => {
|
||||||
|
if (message.text === `${msg}\n`) gotMessage(message);
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const message = await messageP;
|
||||||
|
expect(message).to.be.a(ChatMessage);
|
||||||
|
expect(JSON.stringify(message.customMetadata)).to.equal(JSON.stringify(metadata));
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue