fix: Update Instagram story rendering (#8240)

This commit is contained in:
Pranav Raj S
2023-10-30 11:16:14 -07:00
committed by GitHub
parent dfba4770bd
commit 2ba81830f3
10 changed files with 140 additions and 99 deletions

View File

@@ -22,18 +22,7 @@
:bcc="emailHeadAttributes.bcc"
:is-incoming="isIncoming"
/>
<blockquote v-if="storyReply" class="story-reply-quote">
<span>{{ $t('CONVERSATION.REPLIED_TO_STORY') }}</span>
<bubble-image
v-if="!hasImgStoryError && storyUrl"
:url="storyUrl"
@error="onStoryLoadError"
/>
<bubble-video
v-else-if="hasImgStoryError && storyUrl"
:url="storyUrl"
/>
</blockquote>
<instagram-story-reply v-if="storyUrl" :story-url="storyUrl" />
<bubble-reply-to
v-if="inReplyToMessageId && inboxSupportsReplyTo"
:message="inReplyTo"
@@ -59,10 +48,15 @@
</span>
<div v-if="!isPending && hasAttachments">
<div v-for="attachment in attachments" :key="attachment.id">
<instagram-story
v-if="isAnInstagramStory"
:story-url="attachment.data_url"
@error="onMediaLoadError"
/>
<bubble-image-audio-video
v-if="isAttachmentImageVideoAudio(attachment.file_type)"
v-else-if="isAttachmentImageVideoAudio(attachment.file_type)"
:attachment="attachment"
@error="onImageLoadError"
@error="onMediaLoadError"
/>
<bubble-location
v-else-if="attachment.file_type === 'location'"
@@ -75,9 +69,6 @@
:name="data.content"
:phone-number="attachment.fallback_title"
/>
<instagram-image-error-placeholder
v-else-if="hasImageError && hasInstagramStory"
/>
<bubble-file v-else :url="attachment.data_url" />
</div>
</div>
@@ -89,7 +80,6 @@
:story-id="`${storyId}`"
:is-a-tweet="isATweet"
:is-a-whatsapp-channel="isAWhatsAppChannel"
:has-instagram-story="hasInstagramStory"
:is-email="isEmailContentType"
:is-private="data.private"
:message-type="data.message_type"
@@ -138,19 +128,18 @@
<script>
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';
import BubbleActions from './bubble/Actions.vue';
import BubbleContact from './bubble/Contact.vue';
import BubbleFile from './bubble/File.vue';
import BubbleImage from './bubble/Image.vue';
import BubbleVideo from './bubble/Video.vue';
import BubbleImageAudioVideo from './bubble/ImageAudioVideo.vue';
import BubbleIntegration from './bubble/Integration.vue';
import BubbleLocation from './bubble/Location.vue';
import BubbleMailHead from './bubble/MailHead.vue';
import BubbleText from './bubble/Text.vue';
import BubbleContact from './bubble/Contact.vue';
import BubbleReplyTo from './bubble/ReplyTo.vue';
import Spinner from 'shared/components/Spinner.vue';
import BubbleText from './bubble/Text.vue';
import ContextMenu from 'dashboard/modules/conversations/components/MessageContextMenu.vue';
import instagramImageErrorPlaceholder from './instagramImageErrorPlaceholder.vue';
import InstagramStory from './bubble/InstagramStory.vue';
import InstagramStoryReply from './bubble/InstagramStoryReply.vue';
import Spinner from 'shared/components/Spinner.vue';
import alertMixin from 'shared/mixins/alertMixin';
import contentTypeMixin from 'shared/mixins/contentTypeMixin';
import { MESSAGE_TYPE, MESSAGE_STATUS } from 'shared/constants/messages';
@@ -163,19 +152,18 @@ import { LocalStorage } from 'shared/helpers/localStorage';
export default {
components: {
BubbleActions,
BubbleContact,
BubbleFile,
BubbleImage,
BubbleVideo,
BubbleImageAudioVideo,
BubbleIntegration,
BubbleLocation,
BubbleMailHead,
BubbleText,
BubbleContact,
BubbleReplyTo,
BubbleText,
ContextMenu,
InstagramStory,
InstagramStoryReply,
Spinner,
instagramImageErrorPlaceholder,
},
mixins: [alertMixin, messageFormatterMixin, contentTypeMixin],
props: {
@@ -191,10 +179,6 @@ export default {
type: Boolean,
default: false,
},
hasInstagramStory: {
type: Boolean,
default: false,
},
isWebWidgetInbox: {
type: Boolean,
default: false,
@@ -211,10 +195,9 @@ export default {
data() {
return {
showContextMenu: false,
hasImageError: false,
hasMediaLoadError: false,
contextMenuPosition: {},
showBackgroundHighlight: false,
hasImgStoryError: false,
};
},
computed: {
@@ -290,6 +273,9 @@ export default {
// since old messages are only loaded when the user scrolls up
return this.data.content_attributes?.in_reply_to;
},
isAnInstagramStory() {
return this.contentAttributes.image_type === 'story_mention';
},
contextMenuEnabledOptions() {
return {
copy: this.hasText,
@@ -302,7 +288,7 @@ export default {
return this.data.content_attributes || {};
},
externalError() {
return this.contentAttributes.external_error || null;
return this.contentAttributes.external_error || '';
},
sender() {
return this.data.sender || {};
@@ -319,9 +305,6 @@ export default {
storyUrl() {
return this.contentAttributes.story_url || null;
},
storyReply() {
return this.storyUrl && this.hasInstagramStory;
},
contentType() {
const {
data: { content_type: contentType },
@@ -402,7 +385,7 @@ export default {
return false;
}
if (this.isFailed) {
return this.externalError ? '' : this.$t(`CONVERSATION.SEND_FAILED`);
return this.externalError || this.$t(`CONVERSATION.SEND_FAILED`);
}
return false;
},
@@ -460,13 +443,11 @@ export default {
},
watch: {
data() {
this.hasImageError = false;
this.hasImgStoryError = false;
this.hasMediaLoadError = false;
},
},
mounted() {
this.hasImageError = false;
this.hasImgStoryError = false;
this.hasMediaLoadError = false;
bus.$on(BUS_EVENTS.ON_MESSAGE_LIST_SCROLL, this.closeContextMenu);
this.setupHighlightTimer();
},
@@ -476,13 +457,13 @@ export default {
},
methods: {
isAttachmentImageVideoAudio(fileType) {
return ['image', 'audio', 'video'].includes(fileType);
return ['image', 'audio', 'video', 'story_mention'].includes(fileType);
},
hasMediaAttachment(type) {
if (this.hasAttachments && this.data.attachments.length > 0) {
const { attachments = [{}] } = this.data;
const { file_type: fileType } = attachments[0];
return fileType === type && !this.hasImageError;
return fileType === type && !this.hasMediaLoadError;
}
if (this.storyReply) {
return true;
@@ -495,11 +476,8 @@ export default {
async retrySendMessage() {
await this.$store.dispatch('sendMessageWithData', this.data);
},
onImageLoadError() {
this.hasImageError = true;
},
onStoryLoadError() {
this.hasImgStoryError = true;
onMediaLoadError() {
this.hasMediaLoadError = true;
},
openContextMenu(e) {
const shouldSkipContextMenu =
@@ -731,8 +709,4 @@ li.right {
}
}
}
.story-reply-quote {
@apply mt-2 mx-4 mb-0 px-2 pb-0 pt-2 border-l-4 border-solid border-slate-75 dark:border-slate-600 text-slate-600 dark:text-slate-200;
}
</style>

View File

@@ -31,7 +31,6 @@
:data="message"
:is-a-tweet="isATweet"
:is-a-whatsapp-channel="isAWhatsAppChannel"
:has-instagram-story="hasInstagramStory"
:is-web-widget-inbox="isAWebWidgetInbox"
:inbox-supports-reply-to="inboxSupportsReplyTo"
:in-reply-to="getInReplyToMessage(message)"
@@ -54,7 +53,6 @@
:data="message"
:is-a-tweet="isATweet"
:is-a-whatsapp-channel="isAWhatsAppChannel"
:has-instagram-story="hasInstagramStory"
:is-web-widget-inbox="isAWebWidgetInbox"
:inbox-supports-reply-to="inboxSupportsReplyTo"
:in-reply-to="getInReplyToMessage(message)"
@@ -238,10 +236,6 @@ export default {
isATweet() {
return this.conversationType === 'tweet';
},
hasInstagramStory() {
return this.conversationType === 'instagram_direct_message';
},
isRightOrLeftIcon() {
if (this.isContactPanelOpen) {
return 'arrow-chevron-right';

View File

@@ -114,10 +114,6 @@ export default {
type: Boolean,
default: true,
},
hasInstagramStory: {
type: Boolean,
default: true,
},
messageType: {
type: Number,
default: 1,

View File

@@ -1,6 +1,6 @@
<template>
<div class="image message-text__wrap">
<img :src="url" @click="onClick" @error="onImgError()" />
<img :src="url" @click="onClick" @error="$emit('error')" />
<woot-modal :full-width="true" :show.sync="show" :on-close="onClose">
<img :src="url" class="modal-image skip-context-menu" />
</woot-modal>
@@ -28,9 +28,6 @@ export default {
onClick() {
this.show = true;
},
onImgError() {
this.$emit('error');
},
},
};
</script>

View File

@@ -4,13 +4,14 @@
v-if="isImage && !isImageError"
:src="attachment.data_url"
@click="onClick"
@error="onImgError()"
@error="onImgError"
/>
<video
v-if="isVideo"
:src="attachment.data_url"
muted
playsInline
@error="onImgError"
@click="onClick"
/>
<audio v-else-if="isAudio" controls class="skip-context-menu">
@@ -21,7 +22,7 @@
:show.sync="show"
:attachment="attachment"
:all-attachments="filteredCurrentChatAttachments"
@error="onImgError()"
@error="onImgError"
@close="onClose"
/>
</div>

View File

@@ -0,0 +1,51 @@
<template>
<bubble-image
v-if="!hasImgStoryError"
:url="storyUrl"
@error="onImageLoadError"
/>
<bubble-video
v-else-if="!hasVideoStoryError"
:url="storyUrl"
@error="onVideoLoadError"
/>
<instagram-story-error-place-holder v-else />
</template>
<script>
import BubbleImage from './Image.vue';
import BubbleVideo from './Video.vue';
import InstagramStoryErrorPlaceHolder from './InstagramStoryErrorPlaceHolder.vue';
export default {
components: {
BubbleImage,
BubbleVideo,
InstagramStoryErrorPlaceHolder,
},
props: {
storyUrl: {
type: String,
default: '',
},
},
data() {
return {
hasImgStoryError: false,
hasVideoStoryError: false,
};
},
methods: {
onImageLoadError() {
this.hasImgStoryError = true;
this.emitError();
},
onVideoLoadError() {
this.hasVideoStoryError = true;
this.emitError();
},
emitError() {
this.$emit('error');
},
},
};
</script>

View File

@@ -0,0 +1,14 @@
<template>
<div
class="flex items-center justify-center px-8 h-28 w-full bg-slate-100 text-slate-700 dark:bg-slate-500 dark:text-slate-75"
>
<fluent-icon icon="document-error" size="32" />
<p class="mb-0 text-slate-700 dark:text-slate-75">
{{ $t('COMPONENTS.FILE_BUBBLE.INSTAGRAM_STORY_UNAVAILABLE') }}
</p>
</div>
</template>
<script>
export default {};
</script>

View File

@@ -0,0 +1,35 @@
<template>
<blockquote
class="my-0 px-2 pb-0 pt-0 border-l-4 border-solid border-slate-75 dark:border-slate-600 text-slate-600 dark:text-slate-200"
>
<span>{{ $t('CONVERSATION.REPLIED_TO_STORY') }}</span>
<instagram-story :story-url="storyUrl" class="mt-3 rounded-md" />
</blockquote>
</template>
<script>
import InstagramStory from './InstagramStory.vue';
export default {
components: { InstagramStory },
props: {
storyUrl: {
type: String,
default: '',
},
},
data() {
return {
hasImgStoryError: false,
hasVideoStoryError: false,
};
},
methods: {
onImageLoadError() {
this.hasImgStoryError = true;
},
onVideoLoadError() {
this.hasVideoStoryError = true;
},
},
};
</script>

View File

@@ -1,12 +1,12 @@
<template>
<div class="video message-text__wrap">
<video :src="url" muted playsInline @click="onClick" />
<video ref="videoElement" :src="url" muted playsInline @click="onClick" />
<woot-modal :show.sync="show" :on-close="onClose">
<video
:src="url"
controls
playsInline
class="modal-video skip-context-menu"
class="modal-video skip-context-menu mx-auto"
/>
</woot-modal>
</div>
@@ -25,6 +25,11 @@ export default {
show: false,
};
},
mounted() {
this.$refs.videoElement.onerror = () => {
this.$emit('error');
};
},
methods: {
onClose() {
this.show = false;

View File

@@ -1,26 +0,0 @@
<template>
<div class="image-placeholder">
<fluent-icon icon="document-error" size="32" />
<p>{{ $t('COMPONENTS.FILE_BUBBLE.INSTAGRAM_STORY_UNAVAILABLE') }}</p>
</div>
</template>
<script>
export default {};
</script>
<style scoped>
.image-placeholder {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
padding: var(--space-slab);
height: calc(var(--space-large) * 10);
margin-top: var(--space-one);
width: 100%;
background-color: var(--s-75);
color: var(--s-800);
border-radius: var(--border-radius-normal);
}
</style>