Use converse-avatar for roster items

This commit is contained in:
JC Brand 2021-11-19 11:20:20 +01:00
parent 8db12e61bf
commit c62ea03e2e
7 changed files with 47 additions and 67 deletions

View File

@ -0,0 +1,10 @@
import { __ } from 'i18n';
export const STATUSES = {
'dnd': __('This contact is busy'),
'online': __('This contact is online'),
'offline': __('This contact is offline'),
'unavailable': __('This contact is unavailable'),
'xa': __('This contact is away for an extended period'),
'away': __('This contact is away')
};

View File

@ -69,53 +69,7 @@ export default class RosterContact extends CustomElement {
}
renderRosterItem (item) {
const STATUSES = {
'dnd': __('This contact is busy'),
'online': __('This contact is online'),
'offline': __('This contact is offline'),
'unavailable': __('This contact is unavailable'),
'xa': __('This contact is away for an extended period'),
'away': __('This contact is away')
};
const show = item.presence.get('show') || 'offline';
let status_icon;
if (show === 'online') {
status_icon = 'fa fa-circle chat-status chat-status--online';
} else if (show === 'away') {
status_icon = 'fa fa-circle chat-status chat-status--away';
} else if (show === 'xa') {
status_icon = 'far fa-circle chat-status chat-status-xa';
} else if (show === 'dnd') {
status_icon = 'fa fa-minus-circle chat-status chat-status--busy';
} else {
status_icon = 'fa fa-times-circle chat-status chat-status--offline';
}
const display_name = item.getDisplayName();
return tpl_roster_item(
Object.assign(item.toJSON(), {
show,
display_name,
status_icon,
'openChat': ev => this.openChat(ev),
'removeContact': ev => this.removeContact(ev),
'getAvatarData': () => this.getAvatarData(),
'desc_status': STATUSES[show],
'num_unread': item.get('num_unread') || 0
})
);
}
getAvatarData () {
const image_type = this.model.vcard?.get('image_type') || _converse.DEFAULT_IMAGE_TYPE;
const image_data = this.model.vcard?.get('image') || _converse.DEFAULT_IMAGE;
const image = "data:" + image_type + ";base64," + image_data;
return {
'classes': 'avatar',
'height': 30,
'width': 30,
image,
};
return tpl_roster_item(this, item);
}
openChat (ev) {

View File

@ -1,17 +1,34 @@
import { __ } from 'i18n';
import { api } from "@converse/headless/core";
import { html } from "lit";
import { renderAvatar } from 'shared/directives/avatar.js';
import { STATUSES } from '../constants.js';
export default (o) => {
const i18n_chat = __('Click to chat with %1$s (XMPP address: %2$s)', o.display_name, o.jid);
const i18n_remove = __('Click to remove %1$s as a contact', o.display_name);
export default (el, item) => {
const show = item.presence.get('show') || 'offline';
let status_icon;
if (show === 'online') {
status_icon = 'fa fa-circle chat-status chat-status--online';
} else if (show === 'away') {
status_icon = 'fa fa-circle chat-status chat-status--away';
} else if (show === 'xa') {
status_icon = 'far fa-circle chat-status chat-status-xa';
} else if (show === 'dnd') {
status_icon = 'fa fa-minus-circle chat-status chat-status--busy';
} else {
status_icon = 'fa fa-times-circle chat-status chat-status--offline';
}
const display_name = item.getDisplayName();
const desc_status = STATUSES[show];
const num_unread = item.get('num_unread') || 0;
const i18n_chat = __('Click to chat with %1$s (XMPP address: %2$s)', display_name, el.jid);
const i18n_remove = __('Click to remove %1$s as a contact', display_name);
return html`
<a class="list-item-link cbox-list-item open-chat ${ o.num_unread ? 'unread-msgs' : '' }" title="${i18n_chat}" href="#" @click=${o.openChat}>
${ renderAvatar(o.getAvatarData()) }
<span class="${o.status_icon}" title="${o.desc_status}"></span>
${ o.num_unread ? html`<span class="msgs-indicator">${ o.num_unread }</span>` : '' }
<span class="contact-name contact-name--${o.show} ${ o.num_unread ? 'unread-msgs' : ''}">${o.display_name}</span>
<a class="list-item-link cbox-list-item open-chat ${ num_unread ? 'unread-msgs' : '' }" title="${i18n_chat}" href="#" @click=${el.openChat}>
<converse-avatar class="avatar" .model=${el.model.vcard} height="30" width="30"></converse-avatar>
<span class="${status_icon}" title="${desc_status}"></span>
${ num_unread ? html`<span class="msgs-indicator">${ num_unread }</span>` : '' }
<span class="contact-name contact-name--${el.show} ${ num_unread ? 'unread-msgs' : ''}">${display_name}</span>
</a>
${ api.settings.get('allow_contact_removal') ? html`<a class="list-item-action remove-xmpp-contact far fa-trash-alt" @click=${o.removeContact} title="${i18n_remove}" href="#"></a>` : '' }`;
${ api.settings.get('allow_contact_removal') ? html`<a class="list-item-action remove-xmpp-contact far fa-trash-alt" @click=${el.removeContact} title="${i18n_remove}" href="#"></a>` : '' }`;
}

View File

@ -2,6 +2,8 @@ import { CustomElement } from 'shared/components/element.js';
import tpl_avatar from './templates/avatar.js';
import { _converse, api } from '@converse/headless/core';
import './avatar.scss';
export default class Avatar extends CustomElement {

View File

@ -0,0 +1,7 @@
converse-avatar {
border: 0;
background: transparent;
.avatar {
border-radius: var(--avatar-border-radius);
}
}

View File

@ -396,12 +396,6 @@
width: 100%;
}
.avatar {
border-radius: var(--avatar-border-radius);
border: var(--avatar-border);
background-color: var(--avatar-background-color);
}
.avatar-autocomplete {
margin-right: 0.5em;
vertical-align: middle;

View File

@ -170,8 +170,6 @@ $mobile_portrait_length: 480px !default;
--embedded-emoji-picker-height: 300px;
--avatar-border-radius: 10%;
--avatar-border: 1px solid lightgrey;
--avatar-background-color: white;
--fullpage-chat-height: calc(var(--vh, 1vh) * 100);
--fullpage-chat-width: 100%;
@ -200,8 +198,6 @@ $mobile_portrait_length: 480px !default;
.conversejs.theme-concord {
--avatar-border-radius: 10%;
--avatar-border: 0px;
--avatar-background-color: none;
--controlbox-pane-background-color: #333;
--panel-divider-color: #333;