Fixes #1642 Add option to hide participant list by default

In the process, turn it into a component
This commit is contained in:
JC Brand 2020-10-23 20:49:10 +02:00
parent ae7b29cb90
commit 4252a17f62
6 changed files with 95 additions and 70 deletions

View File

@ -910,6 +910,14 @@ geouri_replacement
String used to replace geo-URIs with. Ought to be a link to osm or similar. ``$1`` and ``$2`` is replaced by
latitude and longitude respectively.
hide_muc_participants
---------------------
* Default: ``false``
Option which allows you to hide the participants list by default.
hide_offline_users
------------------

View File

@ -0,0 +1,46 @@
import "./autocomplete.js"
import tpl_muc_sidebar from "templates/muc_sidebar.js";
import { CustomElement } from './element.js';
import { api, converse } from "@converse/headless/converse-core";
const u = converse.env.utils;
export default class MUCSidebar extends CustomElement {
static get properties () {
return {
chatroom: { type: Object },
occupants: { type: Object}
}
}
connectedCallback () {
super.connectedCallback();
this.listenTo(this.occupants, 'add', this.requestUpdate);
this.listenTo(this.occupants, 'remove', this.requestUpdate);
this.listenTo(this.occupants, 'change', this.requestUpdate);
}
render () {
const tpl = tpl_muc_sidebar(Object.assign(
this.chatroom.toJSON(),
{'occupants': [...this.occupants.models] }
));
return tpl;
}
shouldShow () {
return !this.chatroom.get('hidden_occupants') &&
this.chatroom.session.get('connection_status') === converse.ROOMSTATUS.ENTERED;
}
setVisibility () {
// TODO: We're still manually showing/hiding stuff in ChatRoomView,
// eventually we want everything to render declaratively, after which this
// method won't be necessary anymore
this.shouldShow() ? u.showElement(this) : u.hideElement(this);
}
}
api.elements.define('converse-muc-sidebar', MUCSidebar);

View File

@ -4,6 +4,7 @@
* @description XEP-0045 Multi-User Chat Views
* @license Mozilla Public License (MPLv2)
*/
import "./components/muc-sidebar";
import "@converse/headless/utils/muc";
import "converse-modal";
import AddMUCModal from 'modals/add-muc.js';
@ -20,7 +21,6 @@ import tpl_chatroom_head from "templates/chatroom_head.js";
import tpl_muc_nickname_form from "templates/muc_nickname_form.js";
import tpl_muc_config_form from "templates/muc_config_form.js";
import tpl_muc_password_form from "templates/muc_password_form.js";
import tpl_muc_sidebar from "templates/muc_sidebar.js";
import tpl_room_panel from "templates/room_panel.js";
import tpl_spinner from "templates/spinner.js";
import { ChatBoxView } from "./converse-chatview";
@ -90,7 +90,7 @@ export const ChatRoomView = ChatBoxView.extend({
this.listenTo(this.model, 'change', debounce(() => this.renderHeading(), 250));
this.listenTo(this.model, 'change:composing_spoiler', this.renderMessageForm);
this.listenTo(this.model, 'change:hidden', m => m.get('hidden') ? this.hide() : this.show());
this.listenTo(this.model, 'change:hidden_occupants', this.renderToolbar);
this.listenTo(this.model, 'change:hidden_occupants', this.onSidebarToggle);
this.listenTo(this.model, 'configurationNeeded', this.getAndRenderConfigurationForm);
this.listenTo(this.model, 'destroy', this.hide);
this.listenTo(this.model, 'show', this.show);
@ -121,7 +121,6 @@ export const ChatRoomView = ChatBoxView.extend({
this.listenTo(this.model.occupants, 'change:show', this.showJoinOrLeaveNotification);
this.listenTo(this.model.occupants, 'remove', this.onOccupantRemoved);
this.createSidebarView();
await this.updateAfterMessagesFetched();
// Register later due to await
@ -141,8 +140,14 @@ export const ChatRoomView = ChatBoxView.extend({
},
async render () {
const sidebar_hidden = !this.shouldShowSidebar();
this.el.setAttribute('id', this.model.get('box_id'));
render(tpl_chatroom({
sidebar_hidden,
'model': this.model,
'occupants': this.model.occupants,
'show_sidebar': !this.model.get('hidden_occupants') &&
this.model.session.get('connection_status') === converse.ROOMSTATUS.ENTERED,
'markScrolled': ev => this.markScrolled(ev),
'muc_show_logs_before_join': api.settings.get('muc_show_logs_before_join'),
'show_send_button': _converse.show_send_button,
@ -280,23 +285,13 @@ export const ChatRoomView = ChatBoxView.extend({
}
},
createSidebarView () {
this.model.occupants.chatroomview = this;
this.sidebar_view = new _converse.MUCSidebar({'model': this.model.occupants});
const container_el = this.el.querySelector('.chatroom-body');
const occupants_width = this.model.get('occupants_width');
if (this.sidebar_view && occupants_width !== undefined) {
this.sidebar_view.el.style.flex = "0 0 " + occupants_width + "px";
}
container_el.insertAdjacentElement('beforeend', this.sidebar_view.el);
},
onStartResizeOccupants (ev) {
this.resizing = true;
this.el.addEventListener('mousemove', this.onMouseMove);
this.el.addEventListener('mouseup', this.onMouseUp);
const style = window.getComputedStyle(this.sidebar_view.el);
const sidebar_el = this.el.querySelector('converse-muc-sidebar');
const style = window.getComputedStyle(sidebar_el);
this.width = parseInt(style.width.replace(/px$/, ''), 10);
this.prev_pageX = ev.pageX;
},
@ -316,7 +311,8 @@ export const ChatRoomView = ChatBoxView.extend({
this.resizing = false;
this.el.removeEventListener('mousemove', this.onMouseMove);
this.el.removeEventListener('mouseup', this.onMouseUp);
const element_position = this.sidebar_view.el.getBoundingClientRect();
const sidebar_el = this.el.querySelector('converse-muc-sidebar');
const element_position = sidebar_el.getBoundingClientRect();
const occupants_width = this.calculateSidebarWidth(element_position, 0);
const attrs = {occupants_width};
_converse.connection.connected ? this.model.save(attrs) : this.model.set(attrs);
@ -324,14 +320,15 @@ export const ChatRoomView = ChatBoxView.extend({
},
resizeSidebarView (delta, current_mouse_position) {
const element_position = this.sidebar_view.el.getBoundingClientRect();
const sidebar_el = this.el.querySelector('converse-muc-sidebar');
const element_position = sidebar_el.getBoundingClientRect();
if (this.is_minimum) {
this.is_minimum = element_position.left < current_mouse_position;
} else if (this.is_maximum) {
this.is_maximum = element_position.left > current_mouse_position;
} else {
const occupants_width = this.calculateSidebarWidth(element_position, delta);
this.sidebar_view.el.style.flex = "0 0 " + occupants_width + "px";
sidebar_el.style.flex = "0 0 " + occupants_width + "px";
}
},
@ -528,6 +525,16 @@ export const ChatRoomView = ChatBoxView.extend({
return _converse.ChatBoxView.prototype.showChatStateNotification.apply(this, arguments);
},
shouldShowSidebar () {
return !this.model.get('hidden_occupants') &&
this.model.session.get('connection_status') === converse.ROOMSTATUS.ENTERED;
},
onSidebarToggle () {
this.renderToolbar();
this.el.querySelector('.occupants')?.setVisibility();
},
onOccupantAffiliationChanged (occupant) {
if (occupant.get('jid') === _converse.bare_jid) {
this.renderHeading();
@ -737,6 +744,7 @@ export const ChatRoomView = ChatBoxView.extend({
* @method _converse.ChatRoomView#hideOccupants
*/
hideOccupants (ev) {
debugger;
if (ev) {
ev.preventDefault();
ev.stopPropagation();
@ -1293,7 +1301,7 @@ export const ChatRoomView = ChatBoxView.extend({
} else if (conn_status == converse.ROOMSTATUS.ENTERED) {
this.hideChatRoomContents();
u.showElement(this.el.querySelector('.chat-area'));
u.showElement(this.el.querySelector('.occupants'));
this.el.querySelector('.occupants')?.setVisibility();
this.scrollDown();
}
},
@ -1546,46 +1554,6 @@ converse.plugins.add('converse-muc-views', {
});
_converse.MUCSidebar = View.extend({
tagName: 'div',
className: 'occupants col-md-3 col-4',
async initialize () {
this.chatroomview = this.model.chatroomview;
this.listenTo(this.model, 'add', this.render);
this.listenTo(this.model, 'remove', this.render);
this.listenTo(this.model, 'change', this.render);
this.listenTo(this.chatroomview.model.features, 'change', this.render);
this.listenTo(this.chatroomview.model, 'change:hidden_occupants', this.setVisibility);
this.render();
await this.model.fetched;
},
toHTML () {
return tpl_muc_sidebar(
Object.assign(this.chatroomview.model.toJSON(), {
_converse,
'features': this.chatroomview.model.features,
'occupants': this.model.models
})
);
},
afterRender () {
this.setVisibility();
},
setVisibility () {
if (this.chatroomview.model.get('hidden_occupants') ||
this.chatroomview.model.session.get('connection_status') !== converse.ROOMSTATUS.ENTERED) {
u.hideElement(this.el);
} else {
u.showElement(this.el);
}
}
});
function setMUCDomain (domain, controlboxview) {
controlboxview.getRoomsPanel().model.save('muc_domain', Strophe.getDomainFromJid(domain));
}

View File

@ -123,6 +123,7 @@ converse.plugins.add('converse-muc', {
'auto_join_on_invite': false,
'auto_join_rooms': [],
'auto_register_muc_nickname': false,
'hide_muc_participants': false,
'locked_muc_domain': false,
'muc_domain': undefined,
'muc_fetch_members': true,
@ -371,6 +372,7 @@ converse.plugins.add('converse-muc', {
'bookmarked': false,
'chat_state': undefined,
'hidden': _converse.isUniView() && !api.settings.get('singleton'),
'hidden_occupants': !!api.settings.get('hide_muc_participants'),
'message_type': 'groupchat',
'name': '',
'num_unread': 0,

View File

@ -12,6 +12,9 @@ export default (o) => html`
<div class="bottom-panel"></div>
</div>
<div class="disconnect-container hidden"></div>
<converse-muc-sidebar class="occupants col-md-3 col-4 ${o.sidebar_hidden ? 'hidden' : ''}"
.occupants=${o.occupants}
.chatroom=${o.model}></converse-muc-sidebar>
</div>
</div>
`;

View File

@ -17,6 +17,14 @@ const PRETTY_CHAT_STATUS = {
export default (o) => {
const i18n_occupant_hint = (occupant) => __('Click to mention %1$s in your message.', occupant.get('nick'))
const i18n_participants = __('Participants');
const occupant_tpls = o.occupants.map(occupant => {
return tpl_occupant(Object.assign({
'jid': '',
'hint_show': PRETTY_CHAT_STATUS[occupant.get('show')],
'hint_occupant': i18n_occupant_hint(occupant)
}, occupant.toJSON()));
});
return html`
<div class="occupants-header">
<i class="hide-occupants fa fa-times"></i>
@ -25,16 +33,6 @@ export default (o) => {
</div>
</div>
<div class="dragresize dragresize-occupants-left"></div>
<ul class="occupant-list">
${ o.occupants.map(occupant => {
return tpl_occupant(
Object.assign({
'jid': '',
'hint_show': PRETTY_CHAT_STATUS[occupant.get('show')],
'hint_occupant': i18n_occupant_hint(occupant)
}, occupant.toJSON())
);
}) }
</ul>
<ul class="occupant-list">${occupant_tpls}</ul>
`;
}