Make sure a moderator can also add contacts...

since they can see real JIDs, even if the room is semi-anonymous.

Also made changes regarding programming style and conventions:

- Pass in `this` to the template
    Recently I've started simplifying the `render` method by just
    passing `this` into the template and letting the template calculate
    what it needs from that.
- Don't use `bind()`
    It's slow and arrow functions can be used instead.
- Don't use an i18n string inside a tagged template literal
    Due to limitations with `xgettext` which cannot parse properly
    inside tagged template literals
- Use snake-case for variables
This commit is contained in:
JC Brand 2022-11-03 09:55:20 +01:00
parent ec70d4bc56
commit 659a69e7b7
4 changed files with 36 additions and 30 deletions

View File

@ -28,6 +28,7 @@
}); });
converse.initialize({ converse.initialize({
theme: 'dracula',
auto_away: 300, auto_away: 300,
enable_smacks: true, enable_smacks: true,
loglevel: 'debug', loglevel: 'debug',

View File

@ -28,24 +28,10 @@ export default class OccupantModal extends BaseModal {
} }
renderModal () { renderModal () {
const model = this.model ?? this.message; return tpl_occupant_modal(this);
const jid = model?.get('jid');
const vcard = this.getVcard();
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;
const muc = this.model.collection.chatroom;
const addToContacts = api.contacts.get(jid).then(contact => {
if (!contact && muc.features.get('nonanonymous') && jid && jid != _converse.bare_jid) {
return this.addToContacts.bind(this);
}
});
return tpl_occupant_modal({ jid, vcard, nick, occupant_id, role, affiliation, hats, addToContacts });
} }
getModalTitle () { // eslint-disable-line class-methods-use-this getModalTitle () {
const model = this.model ?? this.message; const model = this.model ?? this.message;
return model?.getDisplayName(); return model?.getDisplayName();
} }

View File

@ -2,40 +2,59 @@ import 'shared/avatar/avatar.js';
import { __ } from 'i18n'; import { __ } from 'i18n';
import { html } from "lit"; import { html } from "lit";
import { until } from 'lit/directives/until.js'; import { until } from 'lit/directives/until.js';
import { _converse, api } from "@converse/headless/core";
export default (o) => { export default (el) => {
const addToContacts = o.addToContacts.then(add => add ? html`<li><button class="btn btn-primary" type="button" @click=${add}>${__('Add to Contacts')}</button></li>` : ''); const model = el.model ?? el.message;
const jid = model?.get('jid');
const vcard = el.getVcard();
const nick = model.get('nick');
const occupant_id = model.get('occupant_id');
const role = el.model?.get('role');
const affiliation = el.model?.get('affiliation');
const hats = el.model?.get('hats')?.length ? el.model.get('hats') : null;
const muc = el.model.collection.chatroom;
const i18n_add_to_contacts = __('Add to Contacts');
const can_see_real_jids = muc.features.get('nonanonymous') || muc.getOwnRole() === 'moderator';
const not_me = jid != _converse.bare_jid;
const add_to_contacts = api.contacts.get(jid)
.then(contact => !contact && not_me && can_see_real_jids)
.then(add => add ? html`<li><button class="btn btn-primary" type="button" @click=${() => el.addToContacts()}>${i18n_add_to_contacts}</button></li>` : '');
return html` return html`
<div class="row"> <div class="row">
<div class="col-auto"> <div class="col-auto">
<converse-avatar <converse-avatar
class="avatar modal-avatar" class="avatar modal-avatar"
.data=${o.vcard?.attributes} .data=${vcard?.attributes}
nonce=${o.vcard?.get('vcard_updated')} nonce=${vcard?.get('vcard_updated')}
height="120" width="120"></converse-avatar> height="120" width="120"></converse-avatar>
</div> </div>
<div class="col"> <div class="col">
<ul class="occupant-details"> <ul class="occupant-details">
<li> <li>
${ o.nick ? html`<div class="row"><strong>${__('Nickname')}:</strong></div><div class="row">${o.nick}</div>` : '' } ${ nick ? html`<div class="row"><strong>${__('Nickname')}:</strong></div><div class="row">${nick}</div>` : '' }
</li> </li>
<li> <li>
${ o.jid ? html`<div class="row"><strong>${__('XMPP Address')}:</strong></div><div class="row">${o.jid}</div>` : '' } ${ jid ? html`<div class="row"><strong>${__('XMPP Address')}:</strong></div><div class="row">${jid}</div>` : '' }
</li> </li>
<li> <li>
${ o.affiliation ? html`<div class="row"><strong>${__('Affiliation')}:</strong></div><div class="row">${o.affiliation}</div>` : '' } ${ affiliation ? html`<div class="row"><strong>${__('Affiliation')}:</strong></div><div class="row">${affiliation}</div>` : '' }
</li> </li>
<li> <li>
${ o.role ? html`<div class="row"><strong>${__('Roles')}:</strong></div><div class="row">${o.role}</div>` : '' } ${ role ? html`<div class="row"><strong>${__('Roles')}:</strong></div><div class="row">${role}</div>` : '' }
</li> </li>
<li> <li>
${ o.hats ? html`<div class="row"><strong>${__('Hats')}:</strong></div><div class="row">${o.hats}</div>` : '' } ${ hats ? html`<div class="row"><strong>${__('Hats')}:</strong></div><div class="row">${hats}</div>` : '' }
</li> </li>
<li> <li>
${ o.occupant_id ? html`<div class="row"><strong>${__('Occupant Id')}:</strong></div><div class="row">${o.occupant_id}</div>` : '' } ${ occupant_id ? html`<div class="row"><strong>${__('Occupant Id')}:</strong></div><div class="row">${occupant_id}</div>` : '' }
</li> </li>
${ until(addToContacts, '') } ${ until(add_to_contacts, '') }
</ul> </ul>
</div> </div>
</div> </div>

View File

@ -3,16 +3,16 @@ import { generateFingerprint, getDevicesForContact, } from '../utils.js';
const ConverseMixins = { const ConverseMixins = {
generateFingerprints: async function (jid) { async generateFingerprints (jid) {
const devices = await getDevicesForContact(jid); const devices = await getDevicesForContact(jid);
return Promise.all(devices.map(d => generateFingerprint(d))); return Promise.all(devices.map(d => generateFingerprint(d)));
}, },
getDeviceForContact: function (jid, device_id) { getDeviceForContact (jid, device_id) {
return getDevicesForContact(jid).then(devices => devices.get(device_id)); return getDevicesForContact(jid).then(devices => devices.get(device_id));
}, },
contactHasOMEMOSupport: async function (jid) { async contactHasOMEMOSupport (jid) {
/* Checks whether the contact advertises any OMEMO-compatible devices. */ /* Checks whether the contact advertises any OMEMO-compatible devices. */
const devices = await getDevicesForContact(jid); const devices = await getDevicesForContact(jid);
return devices.length > 0; return devices.length > 0;