Create the converse-avatar
custom element
This commit is contained in:
parent
e347621dc8
commit
a5b73f0309
|
@ -1,4 +1,4 @@
|
|||
import avatar from 'shared/templates/avatar.js';
|
||||
import avatar from 'shared/avatar/templates/avatar.js';
|
||||
import { __ } from 'i18n';
|
||||
import { html } from 'lit';
|
||||
import { modal_close_button, modal_header_close_button } from 'plugins/modal/templates/buttons.js'
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
import './view.js';
|
||||
import '@converse/headless/plugins/chatboxes/index.js';
|
||||
import ChatBoxViews from './container.js';
|
||||
import { ViewWithAvatar } from 'shared/avatar.js';
|
||||
import { _converse, api, converse } from '@converse/headless/core';
|
||||
import { calculateViewportHeightUnit } from './utils.js';
|
||||
|
||||
|
@ -28,7 +27,6 @@ converse.plugins.add('converse-chatboxviews', {
|
|||
'theme': 'default'
|
||||
});
|
||||
|
||||
_converse.ViewWithAvatar = ViewWithAvatar;
|
||||
_converse.chatboxviews = new ChatBoxViews();
|
||||
|
||||
/************************ BEGIN Event Handlers ************************/
|
||||
|
|
|
@ -1,54 +1,21 @@
|
|||
import UserSettingsModal from 'modals/user-settings';
|
||||
import tpl_profile from './templates/profile.js';
|
||||
import { ElementViewWithAvatar } from 'shared/avatar.js';
|
||||
import { CustomElement } from 'shared/components/element.js';
|
||||
import { __ } from 'i18n';
|
||||
import { _converse, api } from '@converse/headless/core';
|
||||
import { render } from 'lit';
|
||||
|
||||
|
||||
function getPrettyStatus (stat) {
|
||||
if (stat === 'chat') {
|
||||
return __('online');
|
||||
} else if (stat === 'dnd') {
|
||||
return __('busy');
|
||||
} else if (stat === 'xa') {
|
||||
return __('away for long');
|
||||
} else if (stat === 'away') {
|
||||
return __('away');
|
||||
} else if (stat === 'offline') {
|
||||
return __('offline');
|
||||
} else {
|
||||
return __(stat) || __('online');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ProfileView extends ElementViewWithAvatar {
|
||||
class ProfileView extends CustomElement {
|
||||
|
||||
async initialize () {
|
||||
this.model = _converse.xmppstatus;
|
||||
this.listenTo(this.model, "change", this.render);
|
||||
this.listenTo(this.model, "change", this.requestUpdate);
|
||||
await api.waitUntil('VCardsInitialized');
|
||||
this.listenTo(this.model.vcard, "change", this.render);
|
||||
this.render();
|
||||
this.listenTo(this.model.vcard, "change", this.requestUpdate);
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
render () {
|
||||
const chat_status = this.model.get('status') || 'offline';
|
||||
render(tpl_profile(Object.assign(
|
||||
this.model.toJSON(),
|
||||
this.model.vcard.toJSON(), {
|
||||
chat_status,
|
||||
'fullname': this.model.vcard.get('fullname') || _converse.bare_jid,
|
||||
"showUserSettingsModal": ev => this.showUserSettingsModal(ev),
|
||||
'status_message': this.model.get('status_message') ||
|
||||
__("I am %1$s", getPrettyStatus(chat_status)),
|
||||
'logout': this.logout,
|
||||
'showStatusChangeModal': () => this.showStatusChangeModal(),
|
||||
'showProfileModal': () => this.showProfileModal()
|
||||
})), this);
|
||||
|
||||
this.renderAvatar();
|
||||
return tpl_profile(this);
|
||||
}
|
||||
|
||||
showProfileModal (ev) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import 'shared/avatar/avatar.js';
|
||||
import { __ } from 'i18n';
|
||||
import { api } from "@converse/headless/core";
|
||||
import { _converse, api } from "@converse/headless/core";
|
||||
import { getPrettyStatus } from '../utils.js';
|
||||
import { html } from "lit";
|
||||
|
||||
|
||||
|
@ -17,15 +19,18 @@ function tpl_user_settings_button (o) {
|
|||
</a>`;
|
||||
}
|
||||
|
||||
export default (o) => {
|
||||
export default (el) => {
|
||||
const chat_status = el.model.get('status') || 'offline';
|
||||
const fullname = el.model.vcard?.get('fullname') || _converse.bare_jid;
|
||||
const status_message = el.model.get('status_message') || __("I am %1$s", getPrettyStatus(chat_status));
|
||||
const i18n_change_status = __('Click to change your chat status');
|
||||
const show_settings_button = api.settings.get('show_client_info') || api.settings.get('allow_adhoc_commands');
|
||||
let classes, color;
|
||||
if (o.chat_status === 'online') {
|
||||
if (chat_status === 'online') {
|
||||
[classes, color] = ['fa fa-circle chat-status', 'chat-status-online'];
|
||||
} else if (o.chat_status === 'dnd') {
|
||||
} else if (chat_status === 'dnd') {
|
||||
[classes, color] = ['fa fa-minus-circle chat-status', 'chat-status-busy'];
|
||||
} else if (o.chat_status === 'away') {
|
||||
} else if (chat_status === 'away') {
|
||||
[classes, color] = ['fa fa-circle chat-status', 'chat-status-away'];
|
||||
} else {
|
||||
[classes, color] = ['fa fa-circle chat-status', 'subdued-color'];
|
||||
|
@ -33,17 +38,17 @@ export default (o) => {
|
|||
return html`
|
||||
<div class="userinfo controlbox-padded">
|
||||
<div class="controlbox-section profile d-flex">
|
||||
<a class="show-profile" href="#" @click=${o.showProfileModal}>
|
||||
<canvas class="avatar align-self-center" height="40" width="40"></canvas>
|
||||
<a class="show-profile" href="#" @click=${el.showProfileModal}>
|
||||
<converse-avatar class="avatar align-self-center" .model=${el.model.vcard} height="40" width="40"></converse-avatar>
|
||||
</a>
|
||||
<span class="username w-100 align-self-center">${o.fullname}</span>
|
||||
${show_settings_button ? tpl_user_settings_button(o) : ''}
|
||||
${api.settings.get('allow_logout') ? tpl_signout(o) : ''}
|
||||
<span class="username w-100 align-self-center">${fullname}</span>
|
||||
${show_settings_button ? tpl_user_settings_button(el) : ''}
|
||||
${api.settings.get('allow_logout') ? tpl_signout(el) : ''}
|
||||
</div>
|
||||
<div class="d-flex xmpp-status">
|
||||
<a class="change-status" title="${i18n_change_status}" data-toggle="modal" data-target="#changeStatusModal" @click=${o.showStatusChangeModal}>
|
||||
<span class="${o.chat_status} w-100 align-self-center" data-value="${o.chat_status}">
|
||||
<converse-icon color="var(--${color})" size="1em" class="${classes}"></converse-icon> ${o.status_message}</span>
|
||||
<a class="change-status" title="${i18n_change_status}" data-toggle="modal" data-target="#changeStatusModal" @click=${el.showStatusChangeModal}>
|
||||
<span class="${chat_status} w-100 align-self-center" data-value="${chat_status}">
|
||||
<converse-icon color="var(--${color})" size="1em" class="${classes}"></converse-icon> ${status_message}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>`
|
||||
|
|
17
src/plugins/profile/utils.js
Normal file
17
src/plugins/profile/utils.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { __ } from 'i18n';
|
||||
|
||||
export function getPrettyStatus (stat) {
|
||||
if (stat === 'chat') {
|
||||
return __('online');
|
||||
} else if (stat === 'dnd') {
|
||||
return __('busy');
|
||||
} else if (stat === 'xa') {
|
||||
return __('away for long');
|
||||
} else if (stat === 'away') {
|
||||
return __('away');
|
||||
} else if (stat === 'offline') {
|
||||
return __('offline');
|
||||
} else {
|
||||
return __(stat) || __('online');
|
||||
}
|
||||
}
|
33
src/shared/avatar/avatar.js
Normal file
33
src/shared/avatar/avatar.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { CustomElement } from 'shared/components/element.js';
|
||||
import tpl_avatar from './templates/avatar.js';
|
||||
import { api } from '@converse/headless/core';
|
||||
|
||||
|
||||
export default class Avatar extends CustomElement {
|
||||
|
||||
static get properties () {
|
||||
return {
|
||||
model: { type: Object },
|
||||
width: { type: String },
|
||||
height: { type: String },
|
||||
}
|
||||
}
|
||||
|
||||
constructor () {
|
||||
super();
|
||||
this.width = 36;
|
||||
this.height = 36;
|
||||
}
|
||||
|
||||
render () {
|
||||
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')
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
api.elements.define('converse-avatar', Avatar);
|
|
@ -2,10 +2,10 @@ import './message-actions.js';
|
|||
import './message-body.js';
|
||||
import 'shared/components/dropdown.js';
|
||||
import 'shared/registry';
|
||||
import tpl_file_progress from './templates/file-progress.js';
|
||||
import MessageVersionsModal from 'modals/message-versions.js';
|
||||
import OccupantModal from 'modals/occupant.js';
|
||||
import UserDetailsModal from 'modals/user-details.js';
|
||||
import filesize from 'filesize';
|
||||
import log from '@converse/headless/log';
|
||||
import tpl_info_message from './templates/info-message.js';
|
||||
import tpl_mep_message from 'plugins/muc-views/templates/mep-message.js';
|
||||
|
@ -18,8 +18,6 @@ import { __ } from 'i18n';
|
|||
import { _converse, api, converse } from '@converse/headless/core';
|
||||
import { getAppSettings } from '@converse/headless/shared/settings/utils.js';
|
||||
import { getHats } from './utils.js';
|
||||
import { html } from 'lit';
|
||||
import { renderAvatar } from 'shared/directives/avatar';
|
||||
|
||||
const { Strophe, dayjs } = converse.env;
|
||||
|
||||
|
@ -116,17 +114,7 @@ export default class Message extends CustomElement {
|
|||
// Can happen when file upload failed and page was reloaded
|
||||
return '';
|
||||
}
|
||||
const i18n_uploading = __('Uploading file:');
|
||||
const filename = this.model.file.name;
|
||||
const size = filesize(this.model.file.size);
|
||||
return html`
|
||||
<div class="message chat-msg">
|
||||
${ renderAvatar(this.getAvatarData()) }
|
||||
<div class="chat-msg__content">
|
||||
<span class="chat-msg__text">${i18n_uploading} <strong>${filename}</strong>, ${size}</span>
|
||||
<progress value="${this.model.get('progress')}"/>
|
||||
</div>
|
||||
</div>`;
|
||||
return tpl_file_progress(this);
|
||||
}
|
||||
|
||||
renderChatMessage () {
|
||||
|
|
24
src/shared/chat/templates/file-progress.js
Normal file
24
src/shared/chat/templates/file-progress.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import 'shared/avatar/avatar.js';
|
||||
import filesize from 'filesize';
|
||||
import { __ } from 'i18n';
|
||||
import { html } from 'lit';
|
||||
|
||||
export default (el) => {
|
||||
const i18n_uploading = __('Uploading file:');
|
||||
const filename = el.model.file.name;
|
||||
const size = filesize(el.model.file.size);
|
||||
return html`
|
||||
<div class="message chat-msg">
|
||||
<converse-avatar class="avatar align-self-center" .model=${el.model.vcard} height="40" width="40"></converse-avatar>
|
||||
|
||||
${ el.shouldShowAvatar() ?
|
||||
html`<a class="show-msg-author-modal" @click=${el.showUserModal}>
|
||||
<converse-avatar class="avatar align-self-center" .model=${el.model.vcard} height="40" width="40"></converse-avatar>
|
||||
</a>` : '' }
|
||||
|
||||
<div class="chat-msg__content">
|
||||
<span class="chat-msg__text">${i18n_uploading} <strong>${filename}</strong>, ${size}</span>
|
||||
<progress value="${el.model.get('progress')}"/>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import 'shared/chat/unfurl.js';
|
||||
import { __ } from 'i18n';
|
||||
import { html } from "lit";
|
||||
import { renderAvatar } from 'shared/directives/avatar';
|
||||
import { shouldRenderMediaFromURL } from '@converse/headless/utils/url.js';
|
||||
|
||||
|
||||
|
@ -18,7 +17,11 @@ export default (el, o) => {
|
|||
<!-- Anchor to allow us to scroll the message into view -->
|
||||
<a id="${o.msgid}"></a>
|
||||
|
||||
<a class="show-msg-author-modal" @click=${el.showUserModal}>${ o.should_show_avatar ? renderAvatar(el.getAvatarData()) : '' }</a>
|
||||
${ o.should_show_avatar ?
|
||||
html`<a class="show-msg-author-modal" @click=${el.showUserModal}>
|
||||
<converse-avatar class="avatar align-self-center" .model=${el.model.vcard} height="40" width="40"></converse-avatar>
|
||||
</a>` : '' }
|
||||
|
||||
<div class="chat-msg__content chat-msg__content--${o.sender} ${o.is_me_message ? 'chat-msg__content--action' : ''}">
|
||||
|
||||
${ !o.is_me_message ? html`
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import tpl_avatar from 'shared/templates/avatar.js';
|
||||
import tpl_avatar from 'shared/avatar/templates/avatar.js';
|
||||
import { Directive, directive } from "lit/directive.js";
|
||||
|
||||
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
import { __ } from '../i18n';
|
||||
import { html } from "lit";
|
||||
import { renderAvatar } from './../templates/directives/avatar';
|
||||
|
||||
|
||||
export default (o) => {
|
||||
const i18n_uploading = __('Uploading file:')
|
||||
return html`
|
||||
<div class="message chat-msg" data-isodate="${o.time}" data-msgid="${o.msgid}">
|
||||
${ renderAvatar(this) }
|
||||
<div class="chat-msg__content">
|
||||
<span class="chat-msg__text">${i18n_uploading} <strong>${o.filename}</strong>, ${o.filesize}</span>
|
||||
<progress value="${o.progress}"/>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
Loading…
Reference in New Issue
Block a user