show headline messages in controlbox
This commit is contained in:
parent
464c68a3b6
commit
a472a0806e
@ -10,6 +10,7 @@
|
||||
- #1823: New config options [muc_roomid_policy](https://conversejs.org/docs/html/configuration.html#muc-roomid-policy)
|
||||
and [muc_roomid_policy_hint](https://conversejs.org/docs/html/configuration.html#muc-roomid-policy-hint)
|
||||
- #1826: A user can now add himself as a contact
|
||||
- #1839: Headline messages are shown in controlbox
|
||||
|
||||
## 6.0.0 (2020-01-09)
|
||||
|
||||
|
@ -230,6 +230,10 @@
|
||||
color: var(--chat-head-color-dark);
|
||||
}
|
||||
|
||||
.controlbox-heading--headline {
|
||||
color: var(--headline-head-color);
|
||||
}
|
||||
|
||||
.controlbox-heading__btn {
|
||||
cursor: pointer;
|
||||
font-size: 1em;
|
||||
|
@ -87,6 +87,79 @@
|
||||
done();
|
||||
}));
|
||||
|
||||
it("will show headline messages in the controlbox", mock.initConverse(
|
||||
['rosterGroupsFetched'], {}, async function (done, _converse) {
|
||||
|
||||
/* <message from='notify.example.com'
|
||||
* to='romeo@im.example.com'
|
||||
* type='headline'
|
||||
* xml:lang='en'>
|
||||
* <subject>SIEVE</subject>
|
||||
* <body><juliet@example.com> You got mail.</body>
|
||||
* <x xmlns='jabber:x:oob'>
|
||||
* <url>
|
||||
* imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18
|
||||
* </url>
|
||||
* </x>
|
||||
* </message>
|
||||
*/
|
||||
const stanza = $msg({
|
||||
'type': 'headline',
|
||||
'from': 'notify.example.com',
|
||||
'to': 'romeo@montague.lit',
|
||||
'xml:lang': 'en'
|
||||
})
|
||||
.c('subject').t('SIEVE').up()
|
||||
.c('body').t('<juliet@example.com> You got mail.').up()
|
||||
.c('x', {'xmlns': 'jabber:x:oob'})
|
||||
.c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18');
|
||||
|
||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||
const view = _converse.chatboxviews.get('controlbox');
|
||||
await u.waitUntil(() => view.el.querySelectorAll(".open-headline").length);
|
||||
expect(view.el.querySelectorAll('.open-headline').length).toBe(1);
|
||||
expect(view.el.querySelector('.open-headline').text).toBe('notify.example.com');
|
||||
done();
|
||||
}));
|
||||
|
||||
it("will remove headline messages from the controlbox if closed", mock.initConverse(
|
||||
['rosterGroupsFetched'], {}, async function (done, _converse) {
|
||||
|
||||
/* <message from='notify.example.com'
|
||||
* to='romeo@im.example.com'
|
||||
* type='headline'
|
||||
* xml:lang='en'>
|
||||
* <subject>SIEVE</subject>
|
||||
* <body><juliet@example.com> You got mail.</body>
|
||||
* <x xmlns='jabber:x:oob'>
|
||||
* <url>
|
||||
* imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18
|
||||
* </url>
|
||||
* </x>
|
||||
* </message>
|
||||
*/
|
||||
const stanza = $msg({
|
||||
'type': 'headline',
|
||||
'from': 'notify.example.com',
|
||||
'to': 'romeo@montague.lit',
|
||||
'xml:lang': 'en'
|
||||
})
|
||||
.c('subject').t('SIEVE').up()
|
||||
.c('body').t('<juliet@example.com> You got mail.').up()
|
||||
.c('x', {'xmlns': 'jabber:x:oob'})
|
||||
.c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18');
|
||||
|
||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
await u.waitUntil(() => cbview.el.querySelectorAll(".open-headline").length);
|
||||
const hlview = _converse.chatboxviews.get('notify.example.com');
|
||||
const close_el = hlview.el.querySelector('.close-chatbox-button');
|
||||
close_el.click();
|
||||
await u.waitUntil(() => cbview.el.querySelectorAll(".open-headline").length === 0);
|
||||
expect(cbview.el.querySelectorAll('.open-headline').length).toBe(0);
|
||||
done();
|
||||
}));
|
||||
|
||||
it("will not show a headline messages from a full JID if allow_non_roster_messaging is false",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched', 'chatBoxesFetched'], {}, function (done, _converse) {
|
||||
|
@ -9,8 +9,10 @@
|
||||
import "converse-chatview";
|
||||
import converse from "@converse/headless/converse-core";
|
||||
import { isString } from "lodash";
|
||||
import tpl_headline_list from "templates/headline_list.html";
|
||||
import tpl_headline_panel from "templates/headline_panel.html";
|
||||
|
||||
const { utils } = converse.env;
|
||||
const { Backbone, utils } = converse.env;
|
||||
|
||||
|
||||
converse.plugins.add('converse-headlines', {
|
||||
@ -42,7 +44,13 @@ converse.plugins.add('converse-headlines', {
|
||||
return this.__super__.model.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
ControlBoxView: {
|
||||
renderControlBoxPane () {
|
||||
this.__super__.renderControlBoxPane.apply(this, arguments);
|
||||
this.renderHeadlinePanel();
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@ -50,7 +58,33 @@ converse.plugins.add('converse-headlines', {
|
||||
/* The initialize function gets called as soon as the plugin is
|
||||
* loaded by converse.js's plugin machinery.
|
||||
*/
|
||||
const { _converse } = this;
|
||||
const { _converse } = this,
|
||||
{ __ } = _converse;
|
||||
|
||||
const viewWithHeadlinePanel = {
|
||||
renderHeadlinePanel () {
|
||||
if (this.headlinepanel && utils.isInDOM(this.headlinepanel.el)) {
|
||||
return this.headlinepanel;
|
||||
}
|
||||
this.headlinepanel = new _converse.HeadlinePanel();
|
||||
this.el.querySelector('.controlbox-pane').insertAdjacentElement(
|
||||
'beforeEnd', this.headlinepanel.render().el);
|
||||
|
||||
return this.headlinepanel;
|
||||
},
|
||||
|
||||
getHeadlinePanel () {
|
||||
if (this.headlinepanel && utils.isInDOM(this.headlinepanel.el)) {
|
||||
return this.headlinepanel;
|
||||
} else {
|
||||
return this.renderHeadlinePanel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_converse.ControlBoxView) {
|
||||
Object.assign(_converse.ControlBoxView.prototype, viewWithHeadlinePanel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows headline messages
|
||||
@ -83,6 +117,26 @@ converse.plugins.add('converse-headlines', {
|
||||
}
|
||||
});
|
||||
|
||||
function getAllHeadlineBoxes (removedBox = null) {
|
||||
const chatboxviews = _converse.chatboxviews.getAll();
|
||||
return Object.keys(chatboxviews)
|
||||
.filter(
|
||||
id => chatboxviews[id].el.classList.contains('headlines') &&
|
||||
id !== removedBox
|
||||
);
|
||||
}
|
||||
|
||||
function renderHeadlineList (removedBox = null) {
|
||||
const controlboxview = _converse.chatboxviews.get('controlbox');
|
||||
if (controlboxview !== undefined) {
|
||||
const el = controlboxview.el.querySelector('.list-container--headline');
|
||||
const headline_list = tpl_headline_list({
|
||||
'headlineboxes': getAllHeadlineBoxes(removedBox),
|
||||
'open_title': __('Click to open this server message'),
|
||||
});
|
||||
el && (el.outerHTML = headline_list);
|
||||
}
|
||||
}
|
||||
|
||||
async function onHeadlineMessage (message) {
|
||||
// Handler method for all incoming messages of type "headline".
|
||||
@ -106,9 +160,45 @@ converse.plugins.add('converse-headlines', {
|
||||
const attrs = await chatbox.getMessageAttributesFromStanza(message, message);
|
||||
await chatbox.messages.create(attrs);
|
||||
_converse.api.trigger('message', {'chatbox': chatbox, 'stanza': message});
|
||||
renderHeadlineList();
|
||||
_converse.chatboxviews.get(from_jid).el
|
||||
.querySelector('.close-chatbox-button')
|
||||
.addEventListener("click",
|
||||
() => renderHeadlineList(from_jid)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Backbone.NativeView which renders headlines section of the control box.
|
||||
* @class
|
||||
* @namespace _converse.HeadlinePanel
|
||||
* @memberOf _converse
|
||||
*/
|
||||
_converse.HeadlinePanel = Backbone.NativeView.extend({
|
||||
tagName: 'div',
|
||||
className: 'controlbox-section',
|
||||
id: 'headline',
|
||||
|
||||
events: {
|
||||
'click .open-headline': 'openHeadline'
|
||||
},
|
||||
|
||||
openHeadline (ev) {
|
||||
ev.preventDefault();
|
||||
const jid = ev.target.getAttribute('data-headline-jid');
|
||||
const chat = _converse.chatboxes.get(jid);
|
||||
chat.maybeShow(true);
|
||||
},
|
||||
|
||||
render () {
|
||||
this.el.innerHTML = tpl_headline_panel({
|
||||
'heading_headline': __('Server Messages')
|
||||
});
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/************************ BEGIN Event Handlers ************************/
|
||||
function registerHeadlineHandler () {
|
||||
|
12
src/templates/headline_list.html
Normal file
12
src/templates/headline_list.html
Normal file
@ -0,0 +1,12 @@
|
||||
<div class="list-container list-container--headline {{{ !o.headlineboxes.length && 'hidden' || '' }}}">
|
||||
<div class="items-list rooms-list headline-list">
|
||||
{[o.headlineboxes.forEach(function (headline) { ]}
|
||||
<div class="list-item controlbox-padded d-flex flex-row"
|
||||
data-headline-jid="{{{headline}}}">
|
||||
<a class="list-item-link open-headline available-room w-100"
|
||||
data-headline-jid="{{{headline}}}"
|
||||
title="{{{o.open_title}}}" href="#">{{{headline}}}</a>
|
||||
</div>
|
||||
{[ }) ]}
|
||||
</div>
|
||||
</div>
|
6
src/templates/headline_panel.html
Normal file
6
src/templates/headline_panel.html
Normal file
@ -0,0 +1,6 @@
|
||||
<!-- <div id="headline"> -->
|
||||
<div class="d-flex controlbox-padded">
|
||||
<span class="w-100 controlbox-heading controlbox-heading--headline">{{{o.heading_headline}}}</span>
|
||||
</div>
|
||||
<div class="list-container list-container--headline"></div>
|
||||
<!-- </div> -->
|
Loading…
Reference in New Issue
Block a user