[IMP] mail: link preview image as message

This PR hide the message body when the link preview is an image and the message
only contains the link to the image.

closes odoo/odoo#117772

Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
Didier (did)
2023-04-19 20:58:14 +02:00
parent 4fd9cfbe81
commit 6f12a849f6
4 changed files with 112 additions and 16 deletions
@@ -187,6 +187,25 @@ export class Message {
);
}
/**
* Determines if the link preview is actually the main content of the
* message. Meaning:
* - The link is the only part of the message body.
* - There is only one link in the message body.
* - The link preview is of image type.
*/
get linkPreviewSquash() {
return (
this._store.hasLinkPreviewFeature &&
this.body &&
this.body.startsWith("<a") &&
this.body.endsWith("/a>") &&
this.body.match(/<\/a>/im)?.length === 1 &&
this.linkPreviews.length === 1 &&
this.linkPreviews[0].isImage
);
}
get inlineBody() {
if (!this.body) {
return "";
@@ -17,7 +17,11 @@
.o-mail-LinkPreviewImage img {
max-height: $o-mail-LinkPreview-height;
max-width: Min($o-mail-LinkPreview-width, 100%);
max-width: $o-mail-LinkPreview-width;
}
.o-mail-ChatWindow-content .o-mail-LinkPreviewImage img {
max-width: 100%;
}
.o-mail-LinkPreviewVideo {
+18 -15
View File
@@ -94,21 +94,24 @@
>
<div t-if="!state.isEditing" class="o-mail-Message-content position-relative" t-att-class="{'d-flex': env.inDiscussApp}">
<t t-if="message.type !== 'notification' and !message.isTransient and (!message.isBodyEmpty or message.subtypeDescription)">
<div class="position-relative">
<div class="o-mail-Message-bubble rounded-bottom-3 position-absolute top-0 start-0 w-100 h-100" t-att-class="{
'bg-info-light border border-info opacity-25': !message.isSelfAuthored and !message.isNote,
'bg-success-light border border-success opacity-25': message.isSelfAuthored and !message.isNote,
}" t-attf-class="{{ isAlignedRight ? 'rounded-start-3' : 'rounded-end-3' }}"/>
<div class="position-relative" t-att-class="{
'p-1': message.isNote,
'o-mail-Message-body align-self-start text-break mb-0 rounded-end-3 rounded-bottom-3 p-3': !message.isNote,
'flex-grow-1': state.isEditing,
}" t-ref="body">
<em t-if="message.subject and !message.isSubjectSimilarToOriginThreadName and !message.isSubjectDefault" class="mb-1 me-2">Subject: <t t-esc="message.subject"/></em>
<t t-if="message.body" t-out="message.body"/>
<t t-if="showSubtypeDescription" t-out="message.subtypeDescription"/>
<t t-if="!message.linkPreviewSquash">
<div class="position-relative">
<div class="o-mail-Message-bubble rounded-bottom-3 position-absolute top-0 start-0 w-100 h-100" t-att-class="{
'bg-info-light border border-info opacity-25': !message.isSelfAuthored and !message.isNote,
'bg-success-light border border-success opacity-25': message.isSelfAuthored and !message.isNote,
}" t-attf-class="{{ isAlignedRight ? 'rounded-start-3' : 'rounded-end-3' }}"/>
<div class="position-relative" t-att-class="{
'p-1': message.isNote,
'o-mail-Message-body align-self-start text-break mb-0 rounded-end-3 rounded-bottom-3 p-3': !message.isNote,
'flex-grow-1': state.isEditing,
}" t-ref="body">
<em t-if="message.subject and !message.isSubjectSimilarToOriginThreadName and !message.isSubjectDefault" class="mb-1 me-2">Subject: <t t-esc="message.subject"/></em>
<t t-if="message.body" t-out="message.body"/>
<t t-if="showSubtypeDescription" t-out="message.subtypeDescription"/>
</div>
</div>
</div>
</t>
<LinkPreviewList t-else="" linkPreviews="message.linkPreviews" deletable="false"/>
</t>
</div>
@@ -167,7 +170,7 @@
attachments="message.attachments"
unlinkAttachment.bind="onClickAttachmentUnlink"
imagesHeight="300"/>
<LinkPreviewList t-if="message.linkPreviews.length > 0 and store.hasLinkPreviewFeature" linkPreviews="message.linkPreviews" deletable="deletable"/>
<LinkPreviewList t-if="message.linkPreviews.length > 0 and store.hasLinkPreviewFeature and !message.linkPreviewSquash" linkPreviews="message.linkPreviews" deletable="deletable"/>
<MessageReactions message="message" openReactionMenu="openReactionMenu" t-if="message.reactions.length"/>
</div>
</div>
@@ -262,3 +262,73 @@ QUnit.test("No crash on receiving link preview of non-known message", async (ass
await nextAnimationFrame();
assert.ok(true);
});
QUnit.test(
"Squash the message and the link preview when the link preview is an image and the link is the only text in the message",
async (assert) => {
const pyEnv = await startServer();
const linkPreviewId = pyEnv["mail.link.preview"].create({
image_mimetype: "image/jpg",
source_url:
"https://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Siberischer_tiger_de_edit02.jpg/290px-Siberischer_tiger_de_edit02.jpg",
});
const channelId = pyEnv["mail.channel"].create({ name: "wololo" });
pyEnv["mail.message"].create({
body: "<a href='linkPreviewLink'>http://linkPreview</a>",
link_preview_ids: [linkPreviewId],
message_type: "comment",
model: "mail.channel",
res_id: channelId,
});
const { openDiscuss } = await start();
await openDiscuss(channelId);
assert.containsNone($, ".o-mail-Message-bubble");
}
);
QUnit.test(
"Link preview and message should not be squashed when the link preview is not an image",
async (assert) => {
const pyEnv = await startServer();
const linkPreviewId = pyEnv["mail.link.preview"].create({
og_description: "Description",
og_title: "Article title",
og_type: "article",
source_url: "https://www.odoo.com",
});
const channelId = pyEnv["mail.channel"].create({ name: "wololo" });
pyEnv["mail.message"].create({
body: "<a href='linkPreviewLink'>http://linkPreview</a>",
link_preview_ids: [linkPreviewId],
message_type: "comment",
model: "mail.channel",
res_id: channelId,
});
const { openDiscuss } = await start();
await openDiscuss(channelId);
assert.containsOnce($, ".o-mail-Message-bubble");
}
);
QUnit.test(
"Link preview and message should not be squashed when there is more than the link in the message",
async (assert) => {
const pyEnv = await startServer();
const linkPreviewId = pyEnv["mail.link.preview"].create({
image_mimetype: "image/jpg",
source_url:
"https://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Siberischer_tiger_de_edit02.jpg/290px-Siberischer_tiger_de_edit02.jpg",
});
const channelId = pyEnv["mail.channel"].create({ name: "wololo" });
pyEnv["mail.message"].create({
body: "<a href='linkPreviewLink'>http://linkPreview</a> not empty",
link_preview_ids: [linkPreviewId],
message_type: "comment",
model: "mail.channel",
res_id: channelId,
});
const { openDiscuss } = await start();
await openDiscuss(channelId);
assert.containsOnce($, ".o-mail-Message-bubble");
}
);