Commit d7d810ba authored by JC Brand's avatar JC Brand

Improvements to rendering MUC MAM logs before joining

- Add config variable `muc_show_logs_before_join`
- Restore nickname form for the original use-case (when not showing MAM logs before joining).
- Render nickname form in the `.muc-bottom-panel` when showing MAM logs (instead of in a modal)
- Show a message when there aren't any archived messages to show
- Fix converse-mam so that chat logs are properly fetched before entering a MUC

closes #1266
parent a83911d6
......@@ -10,9 +10,10 @@
To add custom emojis, edit the `emojis.json` file.
- Refactor some presence and status handling code from `converse-core` into `@converse/headless/converse-status`.
- New API [\_converse.api.headlines](https://conversejs.org/docs/html/api/-_converse.api.headlines.html#.get)
- New config option [muc-mention-autocomplete-filter](https://conversejs.org/docs/html/configuration.html#muc-mention-autocomplete-filter)
- New config option [muc-mention-autocomplete-show-avatar](https://conversejs.org/docs/html/configuration.html#muc-mention-autocomplete-show-avatar)
- New config option [allow_message_retraction](https://conversejs.org/docs/html/configuration.html#allow-message-retraction)
- New config option [muc-show-logs-before-join](https://conversejs.org/docs/html/configuration.html#muc-show-logs-before-join)
_ New config option [muc_mention_autocomplete_filter](https://conversejs.org/docs/html/configuration.html#muc_mention_autocomplete_filter)
_ New config option [muc_mention_autocomplete_show_avatar](https://conversejs.org/docs/html/configuration.html#muc_mention_autocomplete_show_avatar)
- #129: Add support for XEP-0156: Disovering Alternative XMPP Connection Methods. Only XML is supported for now.
- #1105: Preliminary support for storing persistent data in IndexedDB instead of localStorage
......
......@@ -316,6 +316,18 @@
}
}
.empty-history-feedback {
position: relative;
height: 100%;
color: var(--text-color-lighten-15-percent);
span {
width: 100%;
text-align: center;
position: absolute;
margin-top: 50%;
}
}
.muc-bottom-panel {
border-top: var(--message-input-border-top);
height: 3em;
......@@ -324,6 +336,20 @@
font-size: var(--font-size-small);
background-color: var(--chatroom-head-color);
color: white;
&.muc-bottom-panel--nickname {
padding: 0;
height: 16em;
.chatroom-form-container {
border-radius: 0 !important;
.chatroom-form {
padding-top: 2em;
padding-bottom: 0;
}
}
}
}
.sendXMPPMessage {
......
......@@ -196,7 +196,7 @@
</iq>`);
_converse.connection._dataRecv(test_utils.createRequest(result));
await u.waitUntil(() => view.model.messages.length === 5);
expect(view.model.fetchArchivedMessages.calls.count()).toBe(3);
expect(view.model.fetchArchivedMessages.calls.count()).toBe(5);
const msg_els = view.content.querySelectorAll('.chat-msg__text');
expect(Array.from(msg_els).map(e => e.textContent).join(' ')).toBe("2nd Message 3rd Message 4th Message 5th Message 6th Message");
done();
......
......@@ -1547,7 +1547,7 @@
expect(presencebroadcast.length).toBe(1);
presencebroadcast[0].value = ['moderator'];
view.el.querySelector('input[type="submit"]').click();
view.el.querySelector('.chatroom-form input[type="submit"]').click();
const sent_stanza = sent_IQ.nodeTree;
expect(sent_stanza.querySelector('field[var="muc#roomconfig_membersonly"] value').textContent.trim()).toBe('1');
......@@ -2578,7 +2578,7 @@
expect(el.textContent.trim()).toBe("Configuration for room@conference.example.org");
sizzle('[name="muc#roomconfig_membersonly"]', chatroomview.el).pop().click();
sizzle('[name="muc#roomconfig_roomname"]', chatroomview.el).pop().value = "New room name"
chatroomview.el.querySelector('.btn-primary').click();
chatroomview.el.querySelector('.chatroom-form input[type="submit"]').click();
iq = await u.waitUntil(() => _.filter(IQs, iq => u.matchesSelector(iq, `iq[to="${jid}"][type="set"]`)).pop());
const result = $iq({
......
......@@ -979,7 +979,7 @@
await u.waitUntil(() => view.el.querySelector('.chat-msg__text').textContent ===
'hello z3r0 gibson sw0rdf1sh, how are you?', 500);
const correction = _converse.connection.send.calls.all()[2].args[0];
const correction = _converse.connection.send.calls.all()[3].args[0];
expect(correction.toLocaleString())
.toBe(`<message from="romeo@montague.lit/orchard" id="${correction.nodeTree.getAttribute("id")}" `+
`to="lounge@montague.lit" type="groupchat" `+
......
This diff is collapsed.
......@@ -58,6 +58,7 @@ converse.plugins.add('converse-mam', {
/**
* Fetches messages that might have been archived *after*
* the last archived message in our local cache.
* @private
*/
fetchNewestMessages () {
if (this.disable_mam) {
......@@ -165,8 +166,9 @@ converse.plugins.add('converse-mam', {
Object.assign(_converse.ChatRoom.prototype, {
fetchArchivedMessagesIfNecessary () {
if (this.get('connection_status') !== converse.ROOMSTATUS.ENTERED ||
!this.get('mam_enabled') ||
const conn_status = this.get('connection_status');
if ((!_converse.muc_show_logs_before_join && conn_status !== converse.ROOMSTATUS.ENTERED) ||
!this.features.get('mam_enabled') ||
this.get('mam_initialized')) {
return;
}
......@@ -177,7 +179,7 @@ converse.plugins.add('converse-mam', {
_converse.onMAMError = function (iq) {
if (iq.querySelectorAll('feature-not-implemented').length) {
if (iq && iq.querySelectorAll('feature-not-implemented').length) {
log.warn("Message Archive Management (XEP-0313) not supported by this server");
} else {
log.error("An error occured while trying to set archiving preferences.");
......@@ -232,7 +234,11 @@ converse.plugins.add('converse-mam', {
_converse.api.listen.on('addClientFeatures', () => _converse.api.disco.own.features.add(Strophe.NS.MAM));
_converse.api.listen.on('serviceDiscovered', getMAMPrefsFromFeature);
_converse.api.listen.on('enteredNewRoom', chat => chat.fetchNewestMessages());
_converse.api.listen.on('enteredNewRoom', room => room.features.get('mam_enabled') && room.fetchNewestMessages());
_converse.api.listen.on('chatRoomOpened', (view) => {
view.listenTo(view.model, 'change:connection_status', () => view.model.fetchArchivedMessagesIfNecessary());
});
_converse.api.listen.on('chatReconnected', chat => {
// XXX: For MUCs, we listen to enteredNewRoom instead
if (chat.get('type') === _converse.PRIVATE_CHAT_TYPE) {
......@@ -250,11 +256,6 @@ converse.plugins.add('converse-mam', {
chat.fetchNewestMessages();
}
});
_converse.api.listen.on('chatRoomOpened', (room) => {
room.on('change:mam_enabled', room.fetchArchivedMessagesIfNecessary, room);
room.on('change:connection_status', room.fetchArchivedMessagesIfNecessary, room);
});
/************************ END Event Handlers **************************/
......
......@@ -129,7 +129,8 @@ converse.plugins.add('converse-muc', {
'muc_fetch_members': true,
'muc_history_max_stanzas': undefined,
'muc_instant_rooms': true,
'muc_nickname_from_jid': false
'muc_nickname_from_jid': false,
'muc_show_logs_before_join': false
});
_converse.api.promises.add(['roomsAutoJoined']);
......
<div class="chat-area col">
<div class="chat-content {[ if (o.show_send_button) { ]}chat-content-sendbutton{[ } ]}" aria-live="polite"></div>
<div class="chat-content {[ if (o.show_send_button) { ]}chat-content-sendbutton{[ } ]}" aria-live="polite">
{[ if (o.muc_show_logs_before_join) { ]}
<div class="empty-history-feedback"><span>{{{o.__('No message history available.')}}}</span></div>
{[ } ]}
</div>
<div class="bottom-panel"></div>
</div>
{[ if (o.can_edit) { ]}
<div class="emoji-picker__container dropup"></div>
<div class="message-form-container">
{[ if (o.entered) { ]}
{[ if (o.can_edit) { ]}
<div class="emoji-picker__container dropup"></div>
<div class="message-form-container">
{[ } else { ]}
<div class="muc-bottom-panel">{{{o.__("You're not allowed to send messages in this room")}}}</div>
{[ } ]}
{[ } else { ]}
<div class="muc-bottom-panel">{{{o.__("You're not allowed to send messages in this room")}}}</div>
<div class="muc-bottom-panel"></div>
{[ } ]}
<div class="chatroom-form-container muc-nickname-form">
<form class="converse-form chatroom-form converse-centered-form">
<fieldset class="form-group">
<label>{{{o.heading}}}</label>
<p class="validation-message">{{{o.validation_message}}}</p>
<input type="text" required="required" name="nick" value="{{{o.nickname}}}"
class="form-control {{o.error_class}}" placeholder="{{{o.label_nickname}}}"/>
</fieldset>
<fieldset class="form-group">
<input type="submit" class="btn btn-primary" name="join" value="{{{o.label_join}}}"/>
</fieldset>
</form>
</div>
<div class="modal" id="ask-nickname-modal" tabindex="-1" role="dialog" aria-labelledby="ask-nickname-modal-label" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"
id="ask-nickname-modal-label">{{{o.heading}}}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form class="converse-form chatroom-form converse-centered-form">
<fieldset class="form-group">
<label>{{{o.__('Nickname:')}}}</label>
<p class="validation-message">{{{o.validation_message}}}</p>
<input type="text" required="required" name="nick" value="{{{o.nickname}}}"
class="form-control {{o.error_class}}" placeholder="{{{o.label_nickname}}}"/>
</fieldset>
<fieldset class="form-group">
<input type="submit" class="btn btn-primary" name="join" value="{{{o.label_join}}}"/>
</fieldset>
</form>
</div>
</div>
</div>
</div>
......@@ -19,7 +19,7 @@
converse.initialize({
auto_away: 300,
auto_register_muc_nickname: true,
debug: true,
loglevel: 'debug',
enable_smacks: true,
i18n: 'en',
message_archiving: 'always',
......@@ -27,6 +27,7 @@
muc_respect_autojoin: true,
view_mode: 'fullscreen',
websocket_url: 'ws://chat.example.org:5380/xmpp-websocket',
muc_show_logs_before_join: true,
whitelisted_plugins: ['converse-debug'],
});
</script>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment