diff --git a/src/modals/templates/user-details.js b/src/modals/templates/user-details.js index 4c4187862..c16b1c8fe 100644 --- a/src/modals/templates/user-details.js +++ b/src/modals/templates/user-details.js @@ -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' diff --git a/src/plugins/chatboxviews/index.js b/src/plugins/chatboxviews/index.js index 6cc518940..1fcb9b457 100644 --- a/src/plugins/chatboxviews/index.js +++ b/src/plugins/chatboxviews/index.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 ************************/ diff --git a/src/plugins/profile/statusview.js b/src/plugins/profile/statusview.js index 40ee3f4f2..b9c9fb204 100644 --- a/src/plugins/profile/statusview.js +++ b/src/plugins/profile/statusview.js @@ -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) { diff --git a/src/plugins/profile/templates/profile.js b/src/plugins/profile/templates/profile.js index 83eac1978..34506c94b 100644 --- a/src/plugins/profile/templates/profile.js +++ b/src/plugins/profile/templates/profile.js @@ -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) { `; } -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`
- - + + - ${o.fullname} - ${show_settings_button ? tpl_user_settings_button(o) : ''} - ${api.settings.get('allow_logout') ? tpl_signout(o) : ''} + ${fullname} + ${show_settings_button ? tpl_user_settings_button(el) : ''} + ${api.settings.get('allow_logout') ? tpl_signout(el) : ''}
- - - ${o.status_message} + + + ${status_message}
` diff --git a/src/plugins/profile/utils.js b/src/plugins/profile/utils.js new file mode 100644 index 000000000..51f14c207 --- /dev/null +++ b/src/plugins/profile/utils.js @@ -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'); + } +} diff --git a/src/shared/avatar/avatar.js b/src/shared/avatar/avatar.js new file mode 100644 index 000000000..bf00868ab --- /dev/null +++ b/src/shared/avatar/avatar.js @@ -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); diff --git a/src/shared/templates/avatar.js b/src/shared/avatar/templates/avatar.js similarity index 100% rename from src/shared/templates/avatar.js rename to src/shared/avatar/templates/avatar.js diff --git a/src/shared/avatar.js b/src/shared/avatar/view.js similarity index 100% rename from src/shared/avatar.js rename to src/shared/avatar/view.js diff --git a/src/shared/chat/message.js b/src/shared/chat/message.js index 71b24f3af..9b93df4b7 100644 --- a/src/shared/chat/message.js +++ b/src/shared/chat/message.js @@ -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` -
- ${ renderAvatar(this.getAvatarData()) } -
- ${i18n_uploading} ${filename}, ${size} - -
-
`; + return tpl_file_progress(this); } renderChatMessage () { diff --git a/src/shared/chat/templates/file-progress.js b/src/shared/chat/templates/file-progress.js new file mode 100644 index 000000000..7daa06e70 --- /dev/null +++ b/src/shared/chat/templates/file-progress.js @@ -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` +
+ + + ${ el.shouldShowAvatar() ? + html` + + ` : '' } + +
+ ${i18n_uploading} ${filename}, ${size} + +
+
`; +} diff --git a/src/shared/chat/templates/message.js b/src/shared/chat/templates/message.js index 940797ee8..fb7e531b3 100644 --- a/src/shared/chat/templates/message.js +++ b/src/shared/chat/templates/message.js @@ -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) => { - ${ o.should_show_avatar ? renderAvatar(el.getAvatarData()) : '' } + ${ o.should_show_avatar ? + html` + + ` : '' } +
${ !o.is_me_message ? html` diff --git a/src/shared/directives/avatar.js b/src/shared/directives/avatar.js index fa4c108ac..b55036aeb 100644 --- a/src/shared/directives/avatar.js +++ b/src/shared/directives/avatar.js @@ -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"; diff --git a/src/templates/file_progress.js b/src/templates/file_progress.js deleted file mode 100644 index dd9e78d6a..000000000 --- a/src/templates/file_progress.js +++ /dev/null @@ -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` -
- ${ renderAvatar(this) } -
- ${i18n_uploading} ${o.filename}, ${o.filesize} - -
-
- `; -}