From 5a9c81e8e66483492b5f4ff1a1c25d9e1fa4546b Mon Sep 17 00:00:00 2001 From: Anders Evenrud Date: Sat, 25 Jan 2020 20:33:26 +0100 Subject: [PATCH 1/3] Added MUC plugin --- package.json | 3 ++- src/app.js | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 069d398..80e7bc0 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ }, "dependencies": { "hyperapp": "^1.2.10", - "strophe.js": "^1.3.4" + "strophe.js": "^1.3.4", + "strophejs-plugin-muc": "^1.1.0" }, "files": [ "dist/", diff --git a/src/app.js b/src/app.js index 46a7122..6818a4c 100644 --- a/src/app.js +++ b/src/app.js @@ -27,6 +27,7 @@ * @author Anders Evenrud * @licence Simplified BSD License */ +import 'strophejs-plugin-muc'; import {$pres, Strophe} from 'strophe.js'; import {createConnectionWindow} from './connection-window.js'; import {createChatWindow} from './chat-window.js'; From 51468755f63f544c13519babe6f4b8e2d7829c01 Mon Sep 17 00:00:00 2001 From: Anders Evenrud Date: Sun, 26 Jan 2020 21:45:56 +0100 Subject: [PATCH 2/3] Added MUC join room functionality --- src/app.js | 32 +++++++++++++++++++++++++++++++- src/chat-window.js | 2 +- src/main-window.js | 2 ++ src/utils.js | 1 + 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/app.js b/src/app.js index 6818a4c..6a68987 100644 --- a/src/app.js +++ b/src/app.js @@ -113,13 +113,42 @@ const createApplication = (core, proc) => { id, self: connection.jid, title: username, - user: from + target: from }); } return chatWindow; }; + const findOrCreateMucWindow = name => { + let chatWindow = findChatWindow(name); + if (!chatWindow) { + const id = 'StropheJSChatWindow_' + name; + + chatWindow = createChatWindow(core, proc, win, bus, { + id, + self: connection.jid, + title: name, + target: name, + muc: true + }); + } + }; + + const createJoinRoomDialog = () => { + core.make('osjs/dialog', 'prompt', { + title: 'Room name', + message: 'Enter room name', + parent: win, + value: `conference@${proc.settings.username.split('@')[1]}` + }, (btn, value) => { + if (btn === 'ok' && value) { + connection.muc.join(value); + findOrCreateMucWindow(value); + } + }); + }; + const onReceiveMessage = msg => { const from = msg.getAttribute('from'); const isTyping = msg.getElementsByTagName('cha:composing').length > 0; @@ -166,6 +195,7 @@ const createApplication = (core, proc) => { } }; + bus.on('open-room-join-dialog', () => createJoinRoomDialog()); bus.on('open-connection-window', () => createConnectionWindow(core, proc, win, bus)); bus.on('open-chat-window', from => findOrCreateChatWindow(from).focus()); bus.on('send-message', msg => connection.send(msg)); diff --git a/src/chat-window.js b/src/chat-window.js index de4b961..c6cda1e 100644 --- a/src/chat-window.js +++ b/src/chat-window.js @@ -126,7 +126,7 @@ export const createChatWindow = (core, proc, parent, bus, options) => { return; } - const msg = createMessage(options.self, options.user, value); + const msg = createMessage(options.self, options.target, value); actions.sendMessage(msg); actions.addMessage({date: new Date(), msg}); diff --git a/src/main-window.js b/src/main-window.js index bb2a34f..e5bcc8e 100644 --- a/src/main-window.js +++ b/src/main-window.js @@ -51,6 +51,7 @@ const createFileMenu = (state, actions) => ([ {label: 'Connection Options', onclick: () => actions.menuOptions()}, {label: 'Connect', disabled: state.connected, onclick: () => actions.menuConnect()}, {label: 'Disconnect', disabled: !state.connected, onclick: () => actions.menuDisconnect()}, + {label: 'Join Room', disabled: !state.connected, onclick: () => actions.menuJoinRoom()}, {label: 'Quit', onclick: () => actions.menuQuit()} ]); @@ -107,6 +108,7 @@ export const createMainWindow = (core, proc, bus) => { menuOptions: () => () => bus.emit('open-connection-window'), menuConnect: () => () => bus.emit('connect'), menuDisconnect: () => () => bus.emit('disconnect'), + menuJoinRoom: () => () => bus.emit('open-room-join-dialog'), menuQuit: () => () => proc.destroy(), menuFile: ev => (state, actions) => { core.make('osjs/contextmenu').show({ diff --git a/src/utils.js b/src/utils.js index a12a203..6e4a4b5 100644 --- a/src/utils.js +++ b/src/utils.js @@ -67,6 +67,7 @@ export const getMessageText = msg => { .join('\n'); } + console.warn(msg); return ''; }; From 11d3adaebfbab3389f37b35821650e0317ba0a96 Mon Sep 17 00:00:00 2001 From: Anders Evenrud Date: Sun, 26 Jan 2020 22:44:54 +0100 Subject: [PATCH 3/3] Updated chat window MUC functionality --- src/app.js | 24 +++++++++++++++++++++--- src/chat-window.js | 23 ++++++++++++++++++----- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/app.js b/src/app.js index 6a68987..2208af3 100644 --- a/src/app.js +++ b/src/app.js @@ -132,6 +132,12 @@ const createApplication = (core, proc) => { target: name, muc: true }); + + const onRoomMessage = (...args) => chatWindow.emit('strophejs/room:message', ...args); + const onRoomPresence = (...args) => chatWindow.emit('strophejs/room:precense', ...args); + const onRoomRoster = (...args) => chatWindow.emit('strophejs/room:roster', ...args); + + connection.muc.join(name, null, onRoomMessage, onRoomPresence, onRoomRoster); } }; @@ -140,10 +146,9 @@ const createApplication = (core, proc) => { title: 'Room name', message: 'Enter room name', parent: win, - value: `conference@${proc.settings.username.split('@')[1]}` + value: `room@conference.${proc.settings.username.split('@')[1]}` }, (btn, value) => { if (btn === 'ok' && value) { - connection.muc.join(value); findOrCreateMucWindow(value); } }); @@ -195,10 +200,23 @@ const createApplication = (core, proc) => { } }; + const onLeaveRoom = name => { + connection.muc.leave(name); + }; + + const sendMessage = (msg, target, muc) => { + if (muc) { + connection.muc.groupchat(target, msg); + } else { + connection.send(msg); + } + }; + bus.on('open-room-join-dialog', () => createJoinRoomDialog()); bus.on('open-connection-window', () => createConnectionWindow(core, proc, win, bus)); bus.on('open-chat-window', from => findOrCreateChatWindow(from).focus()); - bus.on('send-message', msg => connection.send(msg)); + bus.on('send-message', sendMessage); + bus.on('leave-room', onLeaveRoom); bus.on('receive-message', onReceiveMessage); bus.on('set-status', onSetStatus); bus.on('set-connection', onSetConnection); diff --git a/src/chat-window.js b/src/chat-window.js index c6cda1e..1665fe9 100644 --- a/src/chat-window.js +++ b/src/chat-window.js @@ -67,7 +67,7 @@ export const createChatWindow = (core, proc, parent, bus, options) => { const messages = (state, actions) => state.messages.map(({date, msg}) => { return h(ChatMessage, { date: format(date, 'longTime'), - self: getUsername(msg.getAttribute('from')) !== getUsername(options.user), + self: getUsername(msg.getAttribute('from')) !== getUsername(options.target), to: msg.getAttribute('to'), from: msg.getAttribute('from'), type: msg.getAttribute('type'), @@ -127,20 +127,19 @@ export const createChatWindow = (core, proc, parent, bus, options) => { } const msg = createMessage(options.self, options.target, value); - - actions.sendMessage(msg); + actions.sendMessage(options.muc ? value : msg); actions.addMessage({date: new Date(), msg}); setTimeout(() => (textarea.value = ''), 1); }, setTypeStatus: typing => () => ({typing}), - sendMessage: msg => () => bus.emit('send-message', msg), + sendMessage: msg => () => bus.emit('send-message', msg, options.target, options.muc), addMessage: obj => state => ({messages: [...state.messages, obj]}) }, view, $content); let typeStatusTimeout; - win.on('strophejs/message', msg => { + const addMessage = msg => { a.addMessage({date: new Date(), msg}); const container = $content.querySelector('.chat-messages'); @@ -149,7 +148,21 @@ export const createChatWindow = (core, proc, parent, bus, options) => { container.scrollTop = container.scrollHeight; }, 1); } + }; + + if (options.muc) { + win.on('destroy', () => bus.emit('leave-room', options.target)); + } + + win.on('strophejs/room:message', addMessage); + win.on('strophejs/room:presence', (...args) => { + console.warn('TODO', 'strophejs/room:presence', args); }); + win.on('strophejs/room:roster', (...args) => { + console.warn('TODO', 'strophejs/room:roster', args); + }); + + win.on('strophejs/message', addMessage); win.on('strophejs/started-typing', () => { clearTimeout(typeStatusTimeout);