Render chat messages loading spinner declaratively
instead of imperatively. Add new non-persisted UI model for rendering UI changes. Currently only being used for rendering the spinner
This commit is contained in:
parent
59d55b3526
commit
ec93e2fff3
@ -56,6 +56,7 @@ const ChatBox = ModelWithContact.extend({
|
|||||||
this.set({'box_id': `box-${jid}`});
|
this.set({'box_id': `box-${jid}`});
|
||||||
this.initNotifications();
|
this.initNotifications();
|
||||||
this.initMessages();
|
this.initMessages();
|
||||||
|
this.initUI();
|
||||||
|
|
||||||
if (this.get('type') === _converse.PRIVATE_CHAT_TYPE) {
|
if (this.get('type') === _converse.PRIVATE_CHAT_TYPE) {
|
||||||
this.presence = _converse.presences.findWhere({'jid': jid}) || _converse.presences.create({'jid': jid});
|
this.presence = _converse.presences.findWhere({'jid': jid}) || _converse.presences.create({'jid': jid});
|
||||||
@ -106,6 +107,10 @@ const ChatBox = ModelWithContact.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
initUI () {
|
||||||
|
this.ui = new Model();
|
||||||
|
},
|
||||||
|
|
||||||
initNotifications () {
|
initNotifications () {
|
||||||
this.notifications = new Model();
|
this.notifications = new Model();
|
||||||
},
|
},
|
||||||
|
@ -90,6 +90,7 @@ const ChatRoomMixin = {
|
|||||||
this.set('box_id', `box-${this.get('jid')}`);
|
this.set('box_id', `box-${this.get('jid')}`);
|
||||||
this.initNotifications();
|
this.initNotifications();
|
||||||
this.initMessages();
|
this.initMessages();
|
||||||
|
this.initUI();
|
||||||
this.initOccupants();
|
this.initOccupants();
|
||||||
this.initDiscoModels(); // sendChatState depends on this.features
|
this.initDiscoModels(); // sendChatState depends on this.features
|
||||||
this.registerHandlers();
|
this.registerHandlers();
|
||||||
|
@ -188,7 +188,6 @@ describe("A Chat Message", function () {
|
|||||||
await _converse.handleMessageStanza(msg);
|
await _converse.handleMessageStanza(msg);
|
||||||
await u.waitUntil(() => view.querySelectorAll('.chat-msg').length === 7);
|
await u.waitUntil(() => view.querySelectorAll('.chat-msg').length === 7);
|
||||||
|
|
||||||
view.clearSpinner(); //cleanup
|
|
||||||
expect(view.querySelectorAll('.date-separator').length).toEqual(4);
|
expect(view.querySelectorAll('.date-separator').length).toEqual(4);
|
||||||
|
|
||||||
let day = sizzle('.date-separator:first', view).pop();
|
let day = sizzle('.date-separator:first', view).pop();
|
||||||
@ -704,7 +703,7 @@ describe("A Chat Message", function () {
|
|||||||
jasmine.clock().tick(1*ONE_MINUTE_LATER);
|
jasmine.clock().tick(1*ONE_MINUTE_LATER);
|
||||||
await mock.sendMessage(view, "Another message within 10 minutes, but from a different person");
|
await mock.sendMessage(view, "Another message within 10 minutes, but from a different person");
|
||||||
|
|
||||||
expect(view.querySelectorAll('.message').length).toBe(6);
|
await u.waitUntil(() => view.querySelectorAll('.message').length === 6);
|
||||||
expect(view.querySelectorAll('.chat-msg').length).toBe(5);
|
expect(view.querySelectorAll('.chat-msg').length).toBe(5);
|
||||||
|
|
||||||
const nth_child = (n) => `converse-chat-message:nth-child(${n}) .chat-msg`;
|
const nth_child = (n) => `converse-chat-message:nth-child(${n}) .chat-msg`;
|
||||||
|
@ -8,13 +8,13 @@ export async function fetchMessagesOnScrollUp (view) {
|
|||||||
if (oldest_message) {
|
if (oldest_message) {
|
||||||
const by_jid = is_groupchat ? view.model.get('jid') : _converse.bare_jid;
|
const by_jid = is_groupchat ? view.model.get('jid') : _converse.bare_jid;
|
||||||
const stanza_id = oldest_message && oldest_message.get(`stanza_id ${by_jid}`);
|
const stanza_id = oldest_message && oldest_message.get(`stanza_id ${by_jid}`);
|
||||||
view.addSpinner();
|
view.model.ui.set('chat-content-spinner-top', true);
|
||||||
if (stanza_id) {
|
if (stanza_id) {
|
||||||
await fetchArchivedMessages(view.model, { 'before': stanza_id });
|
await fetchArchivedMessages(view.model, { 'before': stanza_id });
|
||||||
} else {
|
} else {
|
||||||
await fetchArchivedMessages(view.model, { 'end': oldest_message.get('time') });
|
await fetchArchivedMessages(view.model, { 'end': oldest_message.get('time') });
|
||||||
}
|
}
|
||||||
view.clearSpinner();
|
view.model.ui.set('chat-content-spinner-top', false);
|
||||||
if (api.settings.get('allow_url_history_change')) {
|
if (api.settings.get('allow_url_history_change')) {
|
||||||
_converse.router.history.navigate(`#${oldest_message.get('msgid')}`);
|
_converse.router.history.navigate(`#${oldest_message.get('msgid')}`);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import debounce from 'lodash-es/debounce';
|
import debounce from 'lodash-es/debounce';
|
||||||
import log from '@converse/headless/log';
|
import log from '@converse/headless/log';
|
||||||
import tpl_spinner from 'templates/spinner.js';
|
|
||||||
import { ElementView } from '@converse/skeletor/src/element.js';
|
import { ElementView } from '@converse/skeletor/src/element.js';
|
||||||
import { _converse, api, converse } from '@converse/headless/core';
|
import { _converse, api, converse } from '@converse/headless/core';
|
||||||
|
|
||||||
@ -92,23 +91,6 @@ export default class BaseChatView extends ElementView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addSpinner (append = false) {
|
|
||||||
const content = this.querySelector('.chat-content');
|
|
||||||
if (this.querySelector('.spinner') === null) {
|
|
||||||
const el = u.getElementFromTemplateResult(tpl_spinner());
|
|
||||||
if (append) {
|
|
||||||
content.insertAdjacentElement('beforeend', el);
|
|
||||||
this.scrollDown();
|
|
||||||
} else {
|
|
||||||
content.insertAdjacentElement('afterbegin', el);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clearSpinner () {
|
|
||||||
this.querySelectorAll('.chat-content .spinner').forEach(u.removeElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
onStatusMessageChanged (item) {
|
onStatusMessageChanged (item) {
|
||||||
this.renderHeading();
|
this.renderHeading();
|
||||||
/**
|
/**
|
||||||
|
@ -21,10 +21,10 @@ export default class ChatContent extends CustomElement {
|
|||||||
this.listenTo(this.model.messages, 'remove', this.requestUpdate);
|
this.listenTo(this.model.messages, 'remove', this.requestUpdate);
|
||||||
this.listenTo(this.model.messages, 'reset', this.requestUpdate);
|
this.listenTo(this.model.messages, 'reset', this.requestUpdate);
|
||||||
this.listenTo(this.model.notifications, 'change', this.requestUpdate);
|
this.listenTo(this.model.notifications, 'change', this.requestUpdate);
|
||||||
|
this.listenTo(this.model.ui, 'change', this.requestUpdate);
|
||||||
if (this.model.occupants) {
|
if (this.model.occupants) {
|
||||||
this.listenTo(this.model.occupants, 'change', this.requestUpdate);
|
this.listenTo(this.model.occupants, 'change', this.requestUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We jot down whether we were scrolled down before rendering, because when an
|
// We jot down whether we were scrolled down before rendering, because when an
|
||||||
// image loads, it triggers 'scroll' and the chat will be marked as scrolled,
|
// image loads, it triggers 'scroll' and the chat will be marked as scrolled,
|
||||||
// which is technically true, but not what we want because the user
|
// which is technically true, but not what we want because the user
|
||||||
@ -37,6 +37,7 @@ export default class ChatContent extends CustomElement {
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
return html`
|
return html`
|
||||||
|
${ this.model.ui.get('chat-content-spinner-top') ? html`<span class="spinner fa fa-spinner centered"></span>` : '' }
|
||||||
<converse-message-history
|
<converse-message-history
|
||||||
.model=${this.model}
|
.model=${this.model}
|
||||||
.messages=${[...this.model.messages.models]}>
|
.messages=${[...this.model.messages.models]}>
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
// bosh_service_url: 'http://chat.example.org:5280/http-bind',
|
// bosh_service_url: 'http://chat.example.org:5280/http-bind',
|
||||||
muc_show_logs_before_join: true,
|
muc_show_logs_before_join: true,
|
||||||
whitelisted_plugins: ['converse-debug', 'converse-batched-probe'],
|
whitelisted_plugins: ['converse-debug', 'converse-batched-probe'],
|
||||||
|
blacklisted_plugins: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user