Fix the MUC occupant modal and add more info

Fixes #1419
This commit is contained in:
JC Brand 2021-11-19 10:49:22 +01:00
parent a5b73f0309
commit f36c3fefdd
7 changed files with 74 additions and 33 deletions

View File

@ -7,6 +7,7 @@
- Fix trimming of chats in overlayed view mode
- OMEMO bugfix: Always create device session based on real JID.
- If `auto_register_muc_nickname` is set, make sure to register when the user changes current nick.
- #1419: Clicking on avatar should show bigger version
- #2647: Singleton mode doesn't work
- #2704: Send button doesn't work in a multi-user chat

14
src/modals/modals.scss Normal file
View File

@ -0,0 +1,14 @@
.conversejs {
.modal-body {
.row {
margin-left: 0;
margin-right: 0;
}
}
.occupant-details {
li {
margin-bottom: 1em;
}
}
}

View File

@ -2,42 +2,37 @@ import BootstrapModal from "plugins/modal/base.js";
import tpl_occupant_modal from "./templates/occupant.js";
import { _converse, api } from "@converse/headless/core";
import './modals.scss';
const OccupantModal = BootstrapModal.extend({
id: "muc-occupant",
initialize () {
BootstrapModal.prototype.initialize.apply(this, arguments);
this.listenTo(this.model, 'change', this.render);
if (this.model) {
this.listenTo(this.model, 'change', this.render);
}
/**
* Triggered once the OccupantModal has been initialized
* @event _converse#userDetailsModalInitialized
* @type { _converse.ChatBox }
* @example _converse.api.listen.on('userDetailsModalInitialized', chatbox => { ... });
* @event _converse#occupantModalInitialized
* @type { Object }
* @example _converse.api.listen.on('occupantModalInitialized', data);
*/
api.trigger('occupantModalInitialized', this.model);
api.trigger('occupantModalInitialized', { 'model': this.model, 'message': this.message });
},
toHTML () {
return tpl_occupant_modal(Object.assign(
this.model.toJSON(),
{
'avatar_data': this.getAvatarData(),
'display_name': this.model.getDisplayName()
}
));
},
getAvatarData () {
const vcard = _converse.vcards.findWhere({'jid': this.model.get('jid')});
const image_type = vcard?.get('image_type') || _converse.DEFAULT_IMAGE_TYPE;
const image_data = vcard?.get('image') || _converse.DEFAULT_IMAGE;
const image = "data:" + image_type + ";base64," + image_data;
return {
'classes': 'chat-msg__avatar',
'height': 120,
'width': 120,
image,
};
const model = this.model ?? this.message;
const jid = model?.get('jid');
const vcard = _converse.vcards.findWhere({ jid });
const display_name = model?.getDisplayName();
const nick = model.get('nick');
const occupant_id = model.get('occupant_id');
const role = this.model?.get('role');
const affiliation = this.model?.get('affiliation');
const hats = this.model?.get('hats')?.length ? this.model.get('hats') : null;
return tpl_occupant_modal({ jid, vcard, display_name, nick, occupant_id, role, affiliation, hats });
}
});

View File

@ -1,6 +1,7 @@
import 'shared/avatar/avatar.js';
import { __ } from 'i18n';
import { html } from "lit";
import { modal_close_button, modal_header_close_button } from "plugins/modal/templates/buttons.js"
import { renderAvatar } from 'shared/directives/avatar';
export default (o) => {
@ -11,8 +12,34 @@ export default (o) => {
<h5 class="modal-title" id="user-details-modal-label">${o.display_name}</h5>
${modal_header_close_button}
</div>
<div class="modal-body">
${renderAvatar(o.avatar_data)}
<div class="modal-body" class="d-flex">
<div class="row">
<div class="col-auto">
<converse-avatar class="avatar chat-msg__avatar" .model=${o.vcard} height="120" width="120"></converse-avatar>
</div>
<div class="col">
<ul class="occupant-details">
<li>
${ o.nick ? html`<div class="row"><strong>${__('Nickname')}:</strong></div><div class="row">${o.nick}</div>` : '' }
</li>
<li>
${ o.jid ? html`<div class="row"><strong>${__('XMPP Address')}:</strong></div><div class="row">${o.jid}</div>` : '' }
</li>
<li>
${ o.affiliation ? html`<div class="row"><strong>${__('Affiliation')}:</strong></div><div class="row">${o.affiliation}</div>` : '' }
</li>
<li>
${ o.role ? html`<div class="row"><strong>${__('Roles')}:</strong></div><div class="row">${o.role}</div>` : '' }
</li>
<li>
${ o.hats ? html`<div class="row"><strong>${__('Hats')}:</strong></div><div class="row">${o.hats}</div>` : '' }
</li>
<li>
${ o.occupant_id ? html`<div class="row"><strong>${__('Occupant Id')}:</strong></div><div class="row">${o.occupant_id}</div>` : '' }
</li>
</ul>
</div>
</div>
</div>
<div class="modal-footer">
${modal_close_button}

View File

@ -1,6 +1,6 @@
import { CustomElement } from 'shared/components/element.js';
import tpl_avatar from './templates/avatar.js';
import { api } from '@converse/headless/core';
import { _converse, api } from '@converse/headless/core';
export default class Avatar extends CustomElement {
@ -20,12 +20,15 @@ export default class Avatar extends CustomElement {
}
render () {
const image_type = this.model?.get('image_type') || _converse.DEFAULT_IMAGE_TYPE;
const image_data = this.model?.get('image') || _converse.DEFAULT_IMAGE;
const image = "data:" + image_type + ";base64," + image_data;
return tpl_avatar({
'classes': this.getAttribute('class'),
'width': this.width,
'height': this.height,
'image_type': this.model?.get('image_type'),
'image': this.model?.get('image')
'width': this.width,
image,
image_type,
});
}
}

View File

@ -229,7 +229,7 @@ export default class Message extends CustomElement {
api.modal.show(_converse.ProfileModal, {model: this.model}, ev);
} else if (this.model.get('type') === 'groupchat') {
ev.preventDefault();
api.modal.show(OccupantModal, { 'model': this.model.occupant }, ev);
api.modal.show(OccupantModal, { 'model': this.model.occupant, 'message': this.model }, ev);
} else {
ev.preventDefault();
const chatbox = this.model.collection.chatbox;

View File

@ -1,3 +1,4 @@
import 'shared/avatar/avatar.js';
import 'shared/chat/unfurl.js';
import { __ } from 'i18n';
import { html } from "lit";