Add the ability to show/hide unfurls
This commit is contained in:
parent
a24aa1487e
commit
68d461bd42
@ -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/)
|
- 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)
|
- Chat statuses (online, busy, away, offline)
|
||||||
- Anonymous logins, see the [anonymous login demo](https://conversejs.org/demo/anonymous.html)
|
- 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
|
- Translated into over 30 languages
|
||||||
|
|
||||||
### Supported XMPP Extensions
|
### Supported XMPP Extensions
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
opacity: 0; /* make things invisible upon start */
|
opacity: 0; /* make things invisible upon start */
|
||||||
animation-name: fadein;
|
animation-name: fadein;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
animation-duration: 0.75s;
|
animation-duration: 0.5s;
|
||||||
animation-timing-function: ease;
|
animation-timing-function: ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,4 +261,46 @@ describe("A Groupchat Message", function () {
|
|||||||
done();
|
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&#39;s official music video for "Never Gonna Give You Up" 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();
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
@ -12,11 +12,13 @@ class MessageActions extends CustomElement {
|
|||||||
|
|
||||||
static get properties () {
|
static get properties () {
|
||||||
return {
|
return {
|
||||||
model: { type: Object },
|
|
||||||
editable: { type: Boolean },
|
|
||||||
correcting: { type: Boolean },
|
correcting: { type: Boolean },
|
||||||
message_type: { type: String },
|
editable: { type: Boolean },
|
||||||
|
hide_url_previews: { type: Boolean },
|
||||||
is_retracted: { 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) {
|
onMessageRetractButtonClicked (ev) {
|
||||||
ev.preventDefault();
|
ev?.preventDefault?.();
|
||||||
const chatbox = this.model.collection.chatbox;
|
const chatbox = this.model.collection.chatbox;
|
||||||
if (chatbox.get('type') === _converse.CHATROOMS_TYPE) {
|
if (chatbox.get('type') === _converse.CHATROOMS_TYPE) {
|
||||||
this.onMUCMessageRetractButtonClicked();
|
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 () {
|
async getActionButtons () {
|
||||||
const buttons = [];
|
const buttons = [];
|
||||||
if (this.editable) {
|
if (this.editable) {
|
||||||
@ -178,6 +193,29 @@ class MessageActions extends CustomElement {
|
|||||||
'name': 'retract'
|
'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
|
* *Hook* which allows plugins to add more message action buttons
|
||||||
* @event _converse#getMessageActionButtons
|
* @event _converse#getMessageActionButtons
|
||||||
|
@ -7,7 +7,7 @@ import OccupantModal from 'modals/occupant.js';
|
|||||||
import UserDetailsModal from 'modals/user-details.js';
|
import UserDetailsModal from 'modals/user-details.js';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import filesize from 'filesize';
|
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 tpl_spinner from 'templates/spinner.js';
|
||||||
import { CustomElement } from 'components/element.js';
|
import { CustomElement } from 'components/element.js';
|
||||||
import { __ } from 'i18n';
|
import { __ } from 'i18n';
|
||||||
@ -126,7 +126,7 @@ export default class Message extends CustomElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderChatMessage () {
|
renderChatMessage () {
|
||||||
return tpl_chat_message(this);
|
return tpl_message(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldShowAvatar () {
|
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 () {
|
async onRetryClicked () {
|
||||||
this.show_spinner = true;
|
this.show_spinner = true;
|
||||||
await api.trigger(this.retry_event_id, {'synchronous': true});
|
await api.trigger(this.retry_event_id, {'synchronous': true});
|
||||||
|
@ -38,16 +38,20 @@ export default (o) => {
|
|||||||
?correcting="${o.correcting}"
|
?correcting="${o.correcting}"
|
||||||
?editable="${o.editable}"
|
?editable="${o.editable}"
|
||||||
?is_retracted="${o.is_retracted}"
|
?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>
|
message_type="${o.message_type}"></converse-message-actions>
|
||||||
</div>
|
</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
|
html`<converse-message-unfurl
|
||||||
|
@animationend="${o.onUnfurlAnimationEnd}"
|
||||||
|
class="${o.model.get('url_preview_transition')}"
|
||||||
jid="${o.model.collection.chatbox?.get('jid')}"
|
jid="${o.model.collection.chatbox?.get('jid')}"
|
||||||
description="${m['og:description'] || ''}"
|
description="${m['og:description'] || ''}"
|
||||||
title="${m['og:title'] || ''}"
|
title="${m['og:title'] || ''}"
|
||||||
image="${m['og:image'] || ''}"
|
image="${m['og:image'] || ''}"
|
||||||
url="${m['og:url'] || ''}"></converse-message-unfurl>`) }
|
url="${m['og:url'] || ''}"></converse-message-unfurl>`) : '' }
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user