Use API to get chat/room models in components
This commit is contained in:
parent
afd737f965
commit
6dea5959cc
|
@ -15,17 +15,26 @@ export default class ChatBottomPanel extends ElementView {
|
||||||
'click .toggle-clear': 'clearMessages'
|
'click .toggle-clear': 'clearMessages'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constructor () {
|
||||||
|
super();
|
||||||
|
this.debouncedRender = debounce(this.render, 100);
|
||||||
|
}
|
||||||
|
|
||||||
async connectedCallback () {
|
async connectedCallback () {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
this.debouncedRender = debounce(this.render, 100);
|
await this.initialize();
|
||||||
this.model = _converse.chatboxes.get(this.getAttribute('jid'));
|
this.render(); // don't call in initialize, since the MUCBottomPanel subclasses it
|
||||||
|
// and we want to render after it has finished as wel.
|
||||||
|
}
|
||||||
|
|
||||||
|
async initialize () {
|
||||||
|
this.model = await api.chatboxes.get(this.getAttribute('jid'));
|
||||||
await this.model.initialized;
|
await this.model.initialized;
|
||||||
this.listenTo(this.model, 'change:num_unread', this.debouncedRender)
|
this.listenTo(this.model, 'change:num_unread', this.debouncedRender)
|
||||||
this.listenTo(this.model, 'emoji-picker-autocomplete', this.autocompleteInPicker);
|
this.listenTo(this.model, 'emoji-picker-autocomplete', this.autocompleteInPicker);
|
||||||
|
|
||||||
this.addEventListener('focusin', ev => this.emitFocused(ev));
|
this.addEventListener('focusin', ev => this.emitFocused(ev));
|
||||||
this.addEventListener('focusout', ev => this.emitBlurred(ev));
|
this.addEventListener('focusout', ev => this.emitBlurred(ev));
|
||||||
this.render();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
|
|
@ -14,8 +14,7 @@ describe("A Chat Message", function () {
|
||||||
await mock.openChatBoxFor(_converse, contact_jid);
|
await mock.openChatBoxFor(_converse, contact_jid);
|
||||||
const view = _converse.chatboxviews.get(contact_jid);
|
const view = _converse.chatboxviews.get(contact_jid);
|
||||||
await _converse.handleMessageStanza(mock.createChatMessage(_converse, contact_jid, 'This message will be read'));
|
await _converse.handleMessageStanza(mock.createChatMessage(_converse, contact_jid, 'This message will be read'));
|
||||||
const msg_el = await u.waitUntil(() => view.querySelector('converse-chat-message'));
|
await u.waitUntil(() => view.querySelector('converse-chat-message .chat-msg__text')?.textContent === 'This message will be read');
|
||||||
expect(msg_el.querySelector('.chat-msg__text').textContent).toBe('This message will be read');
|
|
||||||
expect(view.model.get('num_unread')).toBe(0);
|
expect(view.model.get('num_unread')).toBe(0);
|
||||||
|
|
||||||
_converse.windowState = 'hidden';
|
_converse.windowState = 'hidden';
|
||||||
|
@ -26,6 +25,7 @@ describe("A Chat Message", function () {
|
||||||
expect(view.model.get('first_unread_id')).toBe(view.model.messages.last().get('id'));
|
expect(view.model.get('first_unread_id')).toBe(view.model.messages.last().get('id'));
|
||||||
|
|
||||||
await u.waitUntil(() => view.querySelectorAll('converse-chat-message').length === 2);
|
await u.waitUntil(() => view.querySelectorAll('converse-chat-message').length === 2);
|
||||||
|
await u.waitUntil(() => view.querySelector('converse-chat-message:last-child .chat-msg__text')?.textContent === 'This message will be new');
|
||||||
const last_msg_el = view.querySelector('converse-chat-message:last-child');
|
const last_msg_el = view.querySelector('converse-chat-message:last-child');
|
||||||
expect(last_msg_el.firstElementChild?.textContent).toBe('New messages');
|
expect(last_msg_el.firstElementChild?.textContent).toBe('New messages');
|
||||||
done();
|
done();
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'shared/autocomplete/index.js';
|
import 'shared/autocomplete/index.js';
|
||||||
import BottomPanel from 'plugins/chatview/bottom-panel.js';
|
import BottomPanel from 'plugins/chatview/bottom-panel.js';
|
||||||
import debounce from 'lodash-es/debounce';
|
|
||||||
import tpl_muc_bottom_panel from './templates/muc-bottom-panel.js';
|
import tpl_muc_bottom_panel from './templates/muc-bottom-panel.js';
|
||||||
import { _converse, api, converse } from "@converse/headless/core";
|
import { _converse, api, converse } from "@converse/headless/core";
|
||||||
import { render } from 'lit';
|
import { render } from 'lit';
|
||||||
|
@ -15,17 +14,14 @@ export default class MUCBottomPanel extends BottomPanel {
|
||||||
'click .send-button': 'sendButtonClicked',
|
'click .send-button': 'sendButtonClicked',
|
||||||
}
|
}
|
||||||
|
|
||||||
async connectedCallback () {
|
async initialize () {
|
||||||
// this.model gets set in the super method and we also wait there for this.model.initialized
|
await super.initialize();
|
||||||
await super.connectedCallback();
|
|
||||||
this.debouncedRender = debounce(this.render, 100);
|
|
||||||
this.listenTo(this.model, 'change:hidden_occupants', this.debouncedRender);
|
this.listenTo(this.model, 'change:hidden_occupants', this.debouncedRender);
|
||||||
this.listenTo(this.model, 'change:num_unread_general', this.debouncedRender)
|
this.listenTo(this.model, 'change:num_unread_general', this.debouncedRender)
|
||||||
this.listenTo(this.model.features, 'change:moderated', this.debouncedRender);
|
this.listenTo(this.model.features, 'change:moderated', this.debouncedRender);
|
||||||
this.listenTo(this.model.occupants, 'add', this.renderIfOwnOccupant)
|
this.listenTo(this.model.occupants, 'add', this.renderIfOwnOccupant)
|
||||||
this.listenTo(this.model.occupants, 'change:role', this.renderIfOwnOccupant);
|
this.listenTo(this.model.occupants, 'change:role', this.renderIfOwnOccupant);
|
||||||
this.listenTo(this.model.session, 'change:connection_status', this.debouncedRender);
|
this.listenTo(this.model.session, 'change:connection_status', this.debouncedRender);
|
||||||
this.render();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
|
|
@ -12,7 +12,7 @@ describe("Emojis", function () {
|
||||||
const muc_jid = 'lounge@montague.lit';
|
const muc_jid = 'lounge@montague.lit';
|
||||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||||
const view = _converse.chatboxviews.get(muc_jid);
|
const view = _converse.chatboxviews.get(muc_jid);
|
||||||
await u.waitUntil(() => view.querySelector('converse-emoji-dropdown'));
|
await u.waitUntil(() => view.querySelector('converse-emoji-picker'));
|
||||||
const textarea = view.querySelector('textarea.chat-textarea');
|
const textarea = view.querySelector('textarea.chat-textarea');
|
||||||
textarea.value = ':gri';
|
textarea.value = ':gri';
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ describe("Emojis", function () {
|
||||||
await mock.waitForRoster(_converse, 'current', 0);
|
await mock.waitForRoster(_converse, 'current', 0);
|
||||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||||
const view = _converse.chatboxviews.get(muc_jid);
|
const view = _converse.chatboxviews.get(muc_jid);
|
||||||
await u.waitUntil(() => view.querySelector('converse-emoji-dropdown'));
|
await u.waitUntil(() => view.querySelector('converse-emoji-picker'));
|
||||||
const textarea = view.querySelector('textarea.chat-textarea');
|
const textarea = view.querySelector('textarea.chat-textarea');
|
||||||
textarea.value = ':';
|
textarea.value = ':';
|
||||||
// Press tab
|
// Press tab
|
||||||
|
@ -130,7 +130,7 @@ describe("Emojis", function () {
|
||||||
await mock.waitForRoster(_converse, 'current', 0);
|
await mock.waitForRoster(_converse, 'current', 0);
|
||||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||||
const view = _converse.chatboxviews.get(muc_jid);
|
const view = _converse.chatboxviews.get(muc_jid);
|
||||||
await u.waitUntil(() => view.querySelector('converse-emoji-dropdown'));
|
await u.waitUntil(() => view.querySelector('converse-emoji-picker'));
|
||||||
const textarea = view.querySelector('textarea.chat-textarea');
|
const textarea = view.querySelector('textarea.chat-textarea');
|
||||||
textarea.value = ':gri';
|
textarea.value = ':gri';
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import './message-history';
|
import './message-history';
|
||||||
import { CustomElement } from 'shared/components/element.js';
|
import { CustomElement } from 'shared/components/element.js';
|
||||||
import { _converse, api } from '@converse/headless/core';
|
import { api } from '@converse/headless/core';
|
||||||
import { html } from 'lit';
|
import { html } from 'lit';
|
||||||
import { markScrolled } from './utils.js';
|
import { markScrolled } from './utils.js';
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@ export default class ChatContent extends CustomElement {
|
||||||
this.removeEventListener('scroll', markScrolled);
|
this.removeEventListener('scroll', markScrolled);
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize () {
|
async initialize () {
|
||||||
this.model = _converse.chatboxes.get(this.jid);
|
await this.setModels();
|
||||||
this.listenTo(this.model, 'change:hidden_occupants', this.requestUpdate);
|
this.listenTo(this.model, 'change:hidden_occupants', this.requestUpdate);
|
||||||
this.listenTo(this.model.messages, 'add', this.requestUpdate);
|
this.listenTo(this.model.messages, 'add', this.requestUpdate);
|
||||||
this.listenTo(this.model.messages, 'change', this.requestUpdate);
|
this.listenTo(this.model.messages, 'change', this.requestUpdate);
|
||||||
|
@ -43,7 +43,16 @@ export default class ChatContent extends CustomElement {
|
||||||
this.addEventListener('scroll', markScrolled);
|
this.addEventListener('scroll', markScrolled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async setModels () {
|
||||||
|
this.model = await api.chatboxes.get(this.jid);
|
||||||
|
await this.model.initialized;
|
||||||
|
this.requestUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
if (!this.model) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
// This element has "flex-direction: reverse", so elements here are
|
// This element has "flex-direction: reverse", so elements here are
|
||||||
// shown in reverse order.
|
// shown in reverse order.
|
||||||
return html`
|
return html`
|
||||||
|
|
|
@ -28,23 +28,13 @@ export default class Message extends CustomElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
|
||||||
if (this.show_spinner) {
|
|
||||||
return tpl_spinner();
|
|
||||||
} else if (this.model.get('file') && !this.model.get('oob_url')) {
|
|
||||||
return this.renderFileProgress();
|
|
||||||
} else if (['error', 'info'].includes(this.model.get('type'))) {
|
|
||||||
return this.renderInfoMessage();
|
|
||||||
} else {
|
|
||||||
return this.renderChatMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback () {
|
connectedCallback () {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
this.chatbox = _converse.chatboxes.get(this.jid);
|
this.initialize();
|
||||||
this.model = this.chatbox.messages.get(this.mid);
|
}
|
||||||
|
|
||||||
|
async initialize () {
|
||||||
|
await this.setModels();
|
||||||
this.listenTo(this.chatbox, 'change:first_unread_id', this.requestUpdate);
|
this.listenTo(this.chatbox, 'change:first_unread_id', this.requestUpdate);
|
||||||
this.listenTo(this.model, 'change', this.requestUpdate);
|
this.listenTo(this.model, 'change', this.requestUpdate);
|
||||||
this.model.vcard && this.listenTo(this.model.vcard, 'change', this.requestUpdate);
|
this.model.vcard && this.listenTo(this.model.vcard, 'change', this.requestUpdate);
|
||||||
|
@ -60,6 +50,27 @@ export default class Message extends CustomElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async setModels () {
|
||||||
|
this.chatbox = await api.chatboxes.get(this.jid);
|
||||||
|
await this.chatbox.initialized;
|
||||||
|
this.model = this.chatbox.messages.get(this.mid);
|
||||||
|
this.requestUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
if (!this.model) {
|
||||||
|
return '';
|
||||||
|
} else if (this.show_spinner) {
|
||||||
|
return tpl_spinner();
|
||||||
|
} else if (this.model.get('file') && !this.model.get('oob_url')) {
|
||||||
|
return this.renderFileProgress();
|
||||||
|
} else if (['error', 'info'].includes(this.model.get('type'))) {
|
||||||
|
return this.renderInfoMessage();
|
||||||
|
} else {
|
||||||
|
return this.renderChatMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getProps () {
|
getProps () {
|
||||||
return Object.assign(
|
return Object.assign(
|
||||||
this.model.toJSON(),
|
this.model.toJSON(),
|
||||||
|
|
Reference in New Issue