2019-08-14 09:48:44 +00:00
|
|
|
<template>
|
2020-04-17 15:45:20 +00:00
|
|
|
<li v-if="hasAttachments || data.content" :class="alignBubble">
|
2019-08-14 09:48:44 +00:00
|
|
|
<div :class="wrapClass">
|
2020-12-25 07:45:01 +00:00
|
|
|
<div v-tooltip.top-start="sentByMessage" :class="bubbleClass">
|
2019-11-17 07:39:10 +00:00
|
|
|
<bubble-text
|
|
|
|
v-if="data.content"
|
|
|
|
:message="message"
|
2020-08-01 15:26:47 +00:00
|
|
|
:is-email="isEmailContentType"
|
2019-11-17 07:39:10 +00:00
|
|
|
:readable-time="readableTime"
|
|
|
|
/>
|
2020-12-25 07:45:01 +00:00
|
|
|
<span
|
|
|
|
v-if="isPending && hasAttachments"
|
|
|
|
class="chat-bubble has-attachment agent"
|
|
|
|
>
|
|
|
|
{{ $t('CONVERSATION.UPLOADING_ATTACHMENTS') }}
|
|
|
|
</span>
|
2021-01-06 12:26:29 +00:00
|
|
|
<div v-if="!isPending && hasAttachments">
|
|
|
|
<div v-for="attachment in data.attachments" :key="attachment.id">
|
2020-04-17 15:45:20 +00:00
|
|
|
<bubble-image
|
|
|
|
v-if="attachment.file_type === 'image'"
|
|
|
|
:url="attachment.data_url"
|
|
|
|
:readable-time="readableTime"
|
|
|
|
/>
|
2021-02-11 11:56:14 +00:00
|
|
|
<audio v-else-if="attachment.file_type === 'audio'" controls>
|
|
|
|
<source :src="attachment.data_url" />
|
|
|
|
</audio>
|
2020-04-17 15:45:20 +00:00
|
|
|
<bubble-file
|
2021-02-11 11:56:14 +00:00
|
|
|
v-else
|
2020-04-17 15:45:20 +00:00
|
|
|
:url="attachment.data_url"
|
|
|
|
:readable-time="readableTime"
|
|
|
|
/>
|
2021-01-06 12:26:29 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
2020-12-25 07:45:01 +00:00
|
|
|
|
2020-08-01 15:26:47 +00:00
|
|
|
<bubble-actions
|
2020-08-11 04:27:42 +00:00
|
|
|
:id="data.id"
|
|
|
|
:sender="data.sender"
|
|
|
|
:is-a-tweet="isATweet"
|
2020-08-01 15:26:47 +00:00
|
|
|
:is-email="isEmailContentType"
|
|
|
|
:is-private="data.private"
|
2020-08-11 04:27:42 +00:00
|
|
|
:message-type="data.message_type"
|
|
|
|
:readable-time="readableTime"
|
|
|
|
:source-id="data.source_id"
|
2019-12-16 12:53:14 +00:00
|
|
|
/>
|
2020-12-25 07:45:01 +00:00
|
|
|
</div>
|
|
|
|
<spinner v-if="isPending" size="tiny" />
|
2020-08-11 04:27:42 +00:00
|
|
|
|
2021-01-05 04:36:40 +00:00
|
|
|
<a
|
|
|
|
v-if="isATweet && isIncoming && sender"
|
|
|
|
class="sender--info"
|
|
|
|
:href="twitterProfileLink"
|
|
|
|
target="_blank"
|
|
|
|
rel="noopener noreferrer nofollow"
|
|
|
|
>
|
2020-08-11 04:27:42 +00:00
|
|
|
<woot-thumbnail
|
|
|
|
:src="sender.thumbnail"
|
|
|
|
:username="sender.name"
|
|
|
|
size="16px"
|
|
|
|
/>
|
|
|
|
<div class="sender--available-name">
|
2020-10-13 18:46:35 +00:00
|
|
|
{{ sender.name }}
|
2020-08-11 04:27:42 +00:00
|
|
|
</div>
|
2021-01-05 04:36:40 +00:00
|
|
|
</a>
|
2019-08-14 09:48:44 +00:00
|
|
|
</div>
|
|
|
|
</li>
|
|
|
|
</template>
|
|
|
|
<script>
|
2019-11-23 18:59:55 +00:00
|
|
|
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';
|
2019-08-14 09:48:44 +00:00
|
|
|
import timeMixin from '../../../mixins/time';
|
|
|
|
import BubbleText from './bubble/Text';
|
|
|
|
import BubbleImage from './bubble/Image';
|
2020-04-02 06:58:38 +00:00
|
|
|
import BubbleFile from './bubble/File';
|
2020-12-25 07:45:01 +00:00
|
|
|
import Spinner from 'shared/components/Spinner';
|
|
|
|
|
2020-08-01 15:26:47 +00:00
|
|
|
import contentTypeMixin from 'shared/mixins/contentTypeMixin';
|
|
|
|
import BubbleActions from './bubble/Actions';
|
2020-12-25 07:45:01 +00:00
|
|
|
import { MESSAGE_TYPE, MESSAGE_STATUS } from 'shared/constants/messages';
|
2021-02-09 09:49:47 +00:00
|
|
|
import { generateBotMessageContent } from './helpers/botMessageContentHelper';
|
2019-08-14 09:48:44 +00:00
|
|
|
export default {
|
|
|
|
components: {
|
2020-08-01 15:26:47 +00:00
|
|
|
BubbleActions,
|
2019-08-14 09:48:44 +00:00
|
|
|
BubbleText,
|
|
|
|
BubbleImage,
|
2020-04-02 06:58:38 +00:00
|
|
|
BubbleFile,
|
2020-12-25 07:45:01 +00:00
|
|
|
Spinner,
|
2019-08-14 09:48:44 +00:00
|
|
|
},
|
2020-08-01 15:26:47 +00:00
|
|
|
mixins: [timeMixin, messageFormatterMixin, contentTypeMixin],
|
2019-11-17 07:39:10 +00:00
|
|
|
props: {
|
|
|
|
data: {
|
|
|
|
type: Object,
|
|
|
|
required: true,
|
|
|
|
},
|
2020-08-11 04:27:42 +00:00
|
|
|
isATweet: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false,
|
|
|
|
},
|
2019-11-17 07:39:10 +00:00
|
|
|
},
|
2019-08-14 09:48:44 +00:00
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
isHovered: false,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
message() {
|
2021-02-09 09:49:47 +00:00
|
|
|
const botMessageContent = generateBotMessageContent(
|
|
|
|
this.contentType,
|
|
|
|
this.contentAttributes,
|
|
|
|
this.$t('CONVERSATION.NO_RESPONSE')
|
|
|
|
);
|
|
|
|
let messageContent =
|
|
|
|
this.formatMessage(this.data.content, this.isATweet) +
|
|
|
|
botMessageContent;
|
|
|
|
|
|
|
|
return messageContent;
|
|
|
|
},
|
|
|
|
contentAttributes() {
|
|
|
|
return this.data.content_attributes || {};
|
2020-08-11 04:27:42 +00:00
|
|
|
},
|
|
|
|
sender() {
|
|
|
|
return this.data.sender || {};
|
2019-08-14 09:48:44 +00:00
|
|
|
},
|
2020-08-01 15:26:47 +00:00
|
|
|
contentType() {
|
|
|
|
const {
|
|
|
|
data: { content_type: contentType },
|
|
|
|
} = this;
|
|
|
|
return contentType;
|
|
|
|
},
|
2021-01-05 04:36:40 +00:00
|
|
|
twitterProfileLink() {
|
|
|
|
const additionalAttributes = this.sender.additional_attributes || {};
|
|
|
|
const { screen_name: screenName } = additionalAttributes;
|
|
|
|
return `https://twitter.com/${screenName}`;
|
|
|
|
},
|
2019-08-14 09:48:44 +00:00
|
|
|
alignBubble() {
|
2020-01-09 07:36:40 +00:00
|
|
|
return !this.data.message_type ? 'left' : 'right';
|
2019-08-14 09:48:44 +00:00
|
|
|
},
|
|
|
|
readableTime() {
|
2021-02-11 06:40:08 +00:00
|
|
|
return this.messageStamp(this.data.created_at, 'LLL d, h:mm a');
|
2019-08-14 09:48:44 +00:00
|
|
|
},
|
|
|
|
isBubble() {
|
2020-01-09 07:36:40 +00:00
|
|
|
return [0, 1, 3].includes(this.data.message_type);
|
2019-08-14 09:48:44 +00:00
|
|
|
},
|
2020-08-11 04:27:42 +00:00
|
|
|
isIncoming() {
|
|
|
|
return this.data.message_type === MESSAGE_TYPE.INCOMING;
|
|
|
|
},
|
2020-04-17 15:45:20 +00:00
|
|
|
hasAttachments() {
|
|
|
|
return !!(this.data.attachments && this.data.attachments.length > 0);
|
|
|
|
},
|
2020-03-22 10:24:36 +00:00
|
|
|
hasImageAttachment() {
|
2020-04-17 15:45:20 +00:00
|
|
|
if (this.hasAttachments && this.data.attachments.length > 0) {
|
|
|
|
const { attachments = [{}] } = this.data;
|
|
|
|
const { file_type: fileType } = attachments[0];
|
|
|
|
return fileType === 'image';
|
|
|
|
}
|
|
|
|
return false;
|
2020-03-22 10:24:36 +00:00
|
|
|
},
|
2021-01-06 12:26:29 +00:00
|
|
|
hasText() {
|
|
|
|
return !!this.data.content;
|
|
|
|
},
|
2019-08-14 09:48:44 +00:00
|
|
|
sentByMessage() {
|
2020-08-11 04:27:42 +00:00
|
|
|
const { sender } = this;
|
2020-07-27 16:49:26 +00:00
|
|
|
|
|
|
|
return this.data.message_type === 1 && !this.isHovered && sender
|
|
|
|
? {
|
2020-12-08 18:01:25 +00:00
|
|
|
content: `${this.$t('CONVERSATION.SENT_BY')} ${sender.name}`,
|
2020-07-27 16:49:26 +00:00
|
|
|
classes: 'top',
|
|
|
|
}
|
2019-11-17 07:39:10 +00:00
|
|
|
: false;
|
2019-08-14 09:48:44 +00:00
|
|
|
},
|
|
|
|
wrapClass() {
|
|
|
|
return {
|
|
|
|
wrap: this.isBubble,
|
|
|
|
'activity-wrap': !this.isBubble,
|
2020-12-25 07:45:01 +00:00
|
|
|
'is-pending': this.isPending,
|
2019-08-14 09:48:44 +00:00
|
|
|
};
|
|
|
|
},
|
2020-03-22 10:24:36 +00:00
|
|
|
bubbleClass() {
|
|
|
|
return {
|
|
|
|
bubble: this.isBubble,
|
2020-08-01 15:26:47 +00:00
|
|
|
'is-private': this.data.private,
|
2020-03-22 10:24:36 +00:00
|
|
|
'is-image': this.hasImageAttachment,
|
2021-01-06 12:26:29 +00:00
|
|
|
'is-text': this.hasText,
|
2020-03-22 10:24:36 +00:00
|
|
|
};
|
|
|
|
},
|
2020-12-25 07:45:01 +00:00
|
|
|
isPending() {
|
|
|
|
return this.data.status === MESSAGE_STATUS.PROGRESS;
|
|
|
|
},
|
2019-08-14 09:48:44 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
</script>
|
2020-08-01 15:26:47 +00:00
|
|
|
<style lang="scss">
|
2020-12-25 07:45:01 +00:00
|
|
|
.wrap {
|
2021-01-06 12:26:29 +00:00
|
|
|
> .bubble {
|
|
|
|
&.is-image {
|
|
|
|
padding: 0;
|
|
|
|
overflow: hidden;
|
2020-12-25 07:45:01 +00:00
|
|
|
|
2021-01-06 12:26:29 +00:00
|
|
|
.image {
|
|
|
|
max-width: 32rem;
|
|
|
|
padding: var(--space-micro);
|
|
|
|
|
|
|
|
> img {
|
|
|
|
border-radius: var(--border-radius-medium);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
&.is-image.is-text > .message-text__wrap {
|
2020-12-25 07:45:01 +00:00
|
|
|
max-width: 32rem;
|
2021-01-06 12:26:29 +00:00
|
|
|
padding: var(--space-small) var(--space-normal);
|
2020-12-25 07:45:01 +00:00
|
|
|
}
|
|
|
|
}
|
2021-01-06 12:26:29 +00:00
|
|
|
|
2020-12-25 07:45:01 +00:00
|
|
|
&.is-pending {
|
|
|
|
position: relative;
|
|
|
|
opacity: 0.8;
|
|
|
|
|
|
|
|
.spinner {
|
|
|
|
position: absolute;
|
|
|
|
bottom: var(--space-smaller);
|
|
|
|
right: var(--space-smaller);
|
|
|
|
}
|
2021-01-06 12:26:29 +00:00
|
|
|
|
|
|
|
> .is-image.is-text.bubble > .message-text__wrap {
|
|
|
|
padding: 0;
|
|
|
|
}
|
2020-03-22 10:24:36 +00:00
|
|
|
}
|
|
|
|
}
|
2020-08-11 04:27:42 +00:00
|
|
|
|
|
|
|
.sender--info {
|
|
|
|
align-items: center;
|
2021-01-05 04:36:40 +00:00
|
|
|
color: var(--b-700);
|
|
|
|
display: inline-flex;
|
2020-08-11 04:27:42 +00:00
|
|
|
padding: var(--space-smaller) 0;
|
|
|
|
|
|
|
|
.sender--available-name {
|
|
|
|
font-size: var(--font-size-mini);
|
|
|
|
margin-left: var(--space-smaller);
|
|
|
|
}
|
|
|
|
}
|
2020-03-22 10:24:36 +00:00
|
|
|
</style>
|