Add the ability to show/hide unfurls

This commit is contained in:
JC Brand 2021-03-05 15:00:01 +01:00
parent a24aa1487e
commit 68d461bd42
6 changed files with 103 additions and 9 deletions

View File

@ -61,6 +61,7 @@ In embedded mode, Converse can be embedded into an element in the DOM.
- A [plugin architecture](https://conversejs.org/docs/html/plugin_development.html) based on [pluggable.js](https://conversejs.github.io/pluggable.js/)
- Chat statuses (online, busy, away, offline)
- Anonymous logins, see the [anonymous login demo](https://conversejs.org/demo/anonymous.html)
- URL Previews (requires server support, for example [mod_ogp](https://modules.prosody.im/mod_ogp.html)
- Translated into over 30 languages
### Supported XMPP Extensions

View File

@ -2,7 +2,7 @@
opacity: 0; /* make things invisible upon start */
animation-name: fadein;
animation-fill-mode: forwards;
animation-duration: 0.75s;
animation-duration: 0.5s;
animation-timing-function: ease;
}

View File

@ -261,4 +261,46 @@ describe("A Groupchat Message", function () {
done();
}));
it("lets the user hide an unfurl",
mock.initConverse(['chatBoxesFetched'],
{'show_images_inline': []},
async function (done, _converse) {
const nick = 'romeo';
const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, nick);
const view = _converse.api.chatviews.get(muc_jid);
const message_stanza = u.toStanza(`
<message xmlns="jabber:client" type="groupchat" from="${muc_jid}/arzu" xml:lang="en" to="${_converse.jid}" id="eda6c790-b4f3-4c07-b5e2-13fff99e6c04">
<body>https://www.youtube.com/watch?v=dQw4w9WgXcQ</body>
<active xmlns="http://jabber.org/protocol/chatstates"/>
<origin-id xmlns="urn:xmpp:sid:0" id="eda6c790-b4f3-4c07-b5e2-13fff99e6c04"/>
<stanza-id xmlns="urn:xmpp:sid:0" by="${muc_jid}" id="8f7613cc-27d4-40ca-9488-da25c4baf92a"/>
<markable xmlns="urn:xmpp:chat-markers:0"/>
</message>`);
_converse.connection._dataRecv(mock.createRequest(message_stanza));
const el = await u.waitUntil(() => view.querySelector('.chat-msg__text'));
expect(el.textContent).toBe('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
const metadata_stanza = u.toStanza(`
<message xmlns="jabber:client" from="${muc_jid}" to="${_converse.jid}" type="groupchat">
<apply-to xmlns="urn:xmpp:fasten:0" id="eda6c790-b4f3-4c07-b5e2-13fff99e6c04">
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:url" content="https://www.youtube.com/watch?v=dQw4w9WgXcQ" />
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:title" content="Rick Astley - Never Gonna Give You Up (Video)" />
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:image" content="https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg" />
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:description" content="Rick Astley&amp;#39;s official music video for &quot;Never Gonna Give You Up&quot; Listen to Rick Astley: https://RickAstley.lnk.to/_listenYD Subscribe to the official Rick Ast..." />
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:type" content="video.other" />
</apply-to>
</message>`);
_converse.connection._dataRecv(mock.createRequest(metadata_stanza));
await u.waitUntil(() => view.querySelector('converse-message-unfurl'));
const button = await u.waitUntil(() => view.querySelector('.chat-msg__content .chat-msg__action-hide-previews'));
button.click();
await u.waitUntil(() => view.querySelector('converse-message-unfurl') === null, 750);
button.click();
await u.waitUntil(() => view.querySelector('converse-message-unfurl'), 750);
done();
}));
});

View File

@ -12,11 +12,13 @@ class MessageActions extends CustomElement {
static get properties () {
return {
model: { type: Object },
editable: { type: Boolean },
correcting: { type: Boolean },
message_type: { type: String },
editable: { type: Boolean },
hide_url_previews: { type: Boolean },
is_retracted: { type: Boolean },
message_type: { type: String },
model: { type: Object },
unfurls: { type: Number }
}
}
@ -147,7 +149,7 @@ class MessageActions extends CustomElement {
}
onMessageRetractButtonClicked (ev) {
ev.preventDefault();
ev?.preventDefault?.();
const chatbox = this.model.collection.chatbox;
if (chatbox.get('type') === _converse.CHATROOMS_TYPE) {
this.onMUCMessageRetractButtonClicked();
@ -156,6 +158,19 @@ class MessageActions extends CustomElement {
}
}
onHidePreviewsButtonClicked (ev) {
ev?.preventDefault?.();
if (this.hide_url_previews) {
this.model.save({
'hide_url_previews': false,
'url_preview_transition': 'fade-in'
});
} else {
this.model.set('url_preview_transition', 'fade-out');
}
}
async getActionButtons () {
const buttons = [];
if (this.editable) {
@ -178,6 +193,29 @@ class MessageActions extends CustomElement {
'name': 'retract'
});
}
const ogp_metadata = this.model.get('ogp_metadata') || [];
const chatbox = this.model.collection.chatbox;
if (chatbox.get('type') === _converse.CHATROOMS_TYPE &&
api.settings.get('muc_show_ogp_unfurls') &&
ogp_metadata.length) {
let title;
const hidden_preview = this.hide_url_previews;
if (ogp_metadata.length > 1) {
title = hidden_preview ? __('Show URL previews') : __('Hide URL previews');
} else {
title = hidden_preview ? __('Show URL preview') : __('Hide URL preview');
}
buttons.push({
'i18n_text': title,
'handler': ev => this.onHidePreviewsButtonClicked(ev),
'button_class': 'chat-msg__action-hide-previews',
'icon_class': this.hide_url_previews ? 'fas fa-eye' : 'fas fa-eye-slash',
'name': 'hide'
});
}
/**
* *Hook* which allows plugins to add more message action buttons
* @event _converse#getMessageActionButtons

View File

@ -7,7 +7,7 @@ import OccupantModal from 'modals/occupant.js';
import UserDetailsModal from 'modals/user-details.js';
import dayjs from 'dayjs';
import filesize from 'filesize';
import tpl_chat_message from './templates/message.js';
import tpl_message from './templates/message.js';
import tpl_spinner from 'templates/spinner.js';
import { CustomElement } from 'components/element.js';
import { __ } from 'i18n';
@ -126,7 +126,7 @@ export default class Message extends CustomElement {
}
renderChatMessage () {
return tpl_chat_message(this);
return tpl_message(this);
}
shouldShowAvatar () {
@ -145,6 +145,15 @@ export default class Message extends CustomElement {
};
}
onUnfurlAnimationEnd () {
if (this.model.get('url_preview_transition') === 'fade-out') {
this.model.save({
'hide_url_previews': !this.model.get('hide_url_previews'),
'url_preview_transition': 'fade-in'
});
}
}
async onRetryClicked () {
this.show_spinner = true;
await api.trigger(this.retry_event_id, {'synchronous': true});

View File

@ -38,16 +38,20 @@ export default (o) => {
?correcting="${o.correcting}"
?editable="${o.editable}"
?is_retracted="${o.is_retracted}"
?hide_url_previews="${o.model.get('hide_url_previews')}"
unfurls="${o.model.get('ogp_metadata')?.length}"
message_type="${o.message_type}"></converse-message-actions>
</div>
${ o.model.get('ogp_metadata')?.map(m =>
${ !o.model.get('hide_url_previews') ? o.model.get('ogp_metadata')?.map(m =>
html`<converse-message-unfurl
@animationend="${o.onUnfurlAnimationEnd}"
class="${o.model.get('url_preview_transition')}"
jid="${o.model.collection.chatbox?.get('jid')}"
description="${m['og:description'] || ''}"
title="${m['og:title'] || ''}"
image="${m['og:image'] || ''}"
url="${m['og:url'] || ''}"></converse-message-unfurl>`) }
url="${m['og:url'] || ''}"></converse-message-unfurl>`) : '' }
</div>
</div>`;
}