|  | @@ -1,747 +0,0 @@
 | 
	
		
			
				|  |  | -<template>
 | 
	
		
			
				|  |  | -  <div
 | 
	
		
			
				|  |  | -    class="message-bubble"
 | 
	
		
			
				|  |  | -    :class="[message.flow === 'in' ? '' : 'reverse']"
 | 
	
		
			
				|  |  | -    ref="htmlRefHook"
 | 
	
		
			
				|  |  | -  >
 | 
	
		
			
				|  |  | -    <img
 | 
	
		
			
				|  |  | -      class="avatar"
 | 
	
		
			
				|  |  | -      :src="
 | 
	
		
			
				|  |  | -        message?.avatar ||
 | 
	
		
			
				|  |  | -        'https://news-info.ks3-cn-beijing.ksyuncs.com/07/1690787574969.png'
 | 
	
		
			
				|  |  | -      "
 | 
	
		
			
				|  |  | -      onerror="this.src='https://news-info.ks3-cn-beijing.ksyuncs.com/07/1690787574969.png'"
 | 
	
		
			
				|  |  | -    />
 | 
	
		
			
				|  |  | -    <main class="message-area">
 | 
	
		
			
				|  |  | -      <label
 | 
	
		
			
				|  |  | -        class="name"
 | 
	
		
			
				|  |  | -        v-if="message.flow === 'in' && message.conversationType === 'GROUP'"
 | 
	
		
			
				|  |  | -      >
 | 
	
		
			
				|  |  | -        {{ message.nameCard || message.nick || message.from }}
 | 
	
		
			
				|  |  | -      </label>
 | 
	
		
			
				|  |  | -      <div
 | 
	
		
			
				|  |  | -        :class="handleImageOrVideoBubbleStyle(message)"
 | 
	
		
			
				|  |  | -        @click.prevent.right="toggleDialog"
 | 
	
		
			
				|  |  | -      >
 | 
	
		
			
				|  |  | -        <div
 | 
	
		
			
				|  |  | -          class="message-replie-area"
 | 
	
		
			
				|  |  | -          :class="[
 | 
	
		
			
				|  |  | -            message?.flow === 'in' ? '' : 'message-replies-area-reverse'
 | 
	
		
			
				|  |  | -          ]"
 | 
	
		
			
				|  |  | -          v-if="
 | 
	
		
			
				|  |  | -            message?.cloudCustomData &&
 | 
	
		
			
				|  |  | -            referenceMessage &&
 | 
	
		
			
				|  |  | -            referenceMessage?.messageRootID
 | 
	
		
			
				|  |  | -          "
 | 
	
		
			
				|  |  | -          @click="showRepliesDialog(message, false)"
 | 
	
		
			
				|  |  | -        >
 | 
	
		
			
				|  |  | -          <MessageReference
 | 
	
		
			
				|  |  | -            :message="message"
 | 
	
		
			
				|  |  | -            :referenceMessage="referenceMessage"
 | 
	
		
			
				|  |  | -            :referenceForShow="referenceForShow"
 | 
	
		
			
				|  |  | -            :url="url"
 | 
	
		
			
				|  |  | -            :face="face"
 | 
	
		
			
				|  |  | -            :allMessageID="allMessageID"
 | 
	
		
			
				|  |  | -            type="reply"
 | 
	
		
			
				|  |  | -          />
 | 
	
		
			
				|  |  | -        </div>
 | 
	
		
			
				|  |  | -        <slot />
 | 
	
		
			
				|  |  | -        <div v-if="dropdown" ref="dropdownRef" class="dropdown-inner">
 | 
	
		
			
				|  |  | -          <div
 | 
	
		
			
				|  |  | -            class="dialog"
 | 
	
		
			
				|  |  | -            :class="[message.flow === 'in' ? '' : 'dialog-right']"
 | 
	
		
			
				|  |  | -            @click="dropdown = false"
 | 
	
		
			
				|  |  | -          >
 | 
	
		
			
				|  |  | -            <slot name="dialog" />
 | 
	
		
			
				|  |  | -          </div>
 | 
	
		
			
				|  |  | -        </div>
 | 
	
		
			
				|  |  | -        <MessageEmojiReact
 | 
	
		
			
				|  |  | -          :message="message"
 | 
	
		
			
				|  |  | -          type="content"
 | 
	
		
			
				|  |  | -          v-if="needEmojiReact && isEmojiReactionInMessage(message)"
 | 
	
		
			
				|  |  | -        />
 | 
	
		
			
				|  |  | -      </div>
 | 
	
		
			
				|  |  | -    </main>
 | 
	
		
			
				|  |  | -    <label
 | 
	
		
			
				|  |  | -      class="message-label fail"
 | 
	
		
			
				|  |  | -      v-if="message.status === 'fail'"
 | 
	
		
			
				|  |  | -      @click="resendMessage(message)"
 | 
	
		
			
				|  |  | -    >
 | 
	
		
			
				|  |  | -      !
 | 
	
		
			
				|  |  | -    </label>
 | 
	
		
			
				|  |  | -    <label
 | 
	
		
			
				|  |  | -      class="message-label"
 | 
	
		
			
				|  |  | -      :class="readReceiptStyle(message)"
 | 
	
		
			
				|  |  | -      v-if="showReadReceiptTag(message)"
 | 
	
		
			
				|  |  | -      @click="showReadReceiptDialog(message)"
 | 
	
		
			
				|  |  | -    >
 | 
	
		
			
				|  |  | -      <span>{{ readReceiptCont(message) }}</span>
 | 
	
		
			
				|  |  | -    </label>
 | 
	
		
			
				|  |  | -  </div>
 | 
	
		
			
				|  |  | -  <div
 | 
	
		
			
				|  |  | -    class="message-reference-area"
 | 
	
		
			
				|  |  | -    :class="[message.flow === 'in' ? '' : 'message-reference-area-reverse']"
 | 
	
		
			
				|  |  | -    v-if="
 | 
	
		
			
				|  |  | -      message?.cloudCustomData &&
 | 
	
		
			
				|  |  | -      referenceMessage &&
 | 
	
		
			
				|  |  | -      !referenceMessage?.messageRootID
 | 
	
		
			
				|  |  | -    "
 | 
	
		
			
				|  |  | -    @click="jumpToAim(referenceMessage)"
 | 
	
		
			
				|  |  | -  >
 | 
	
		
			
				|  |  | -    <MessageReference
 | 
	
		
			
				|  |  | -      :message="message"
 | 
	
		
			
				|  |  | -      :referenceMessage="referenceMessage"
 | 
	
		
			
				|  |  | -      :referenceForShow="referenceForShow"
 | 
	
		
			
				|  |  | -      :url="url"
 | 
	
		
			
				|  |  | -      :face="face"
 | 
	
		
			
				|  |  | -      :allMessageID="allMessageID"
 | 
	
		
			
				|  |  | -      type="reference"
 | 
	
		
			
				|  |  | -    />
 | 
	
		
			
				|  |  | -  </div>
 | 
	
		
			
				|  |  | -  <label
 | 
	
		
			
				|  |  | -    class="message-replies"
 | 
	
		
			
				|  |  | -    :class="[message.flow === 'in' ? '' : 'message-replies-reverse']"
 | 
	
		
			
				|  |  | -    v-if="replies?.length"
 | 
	
		
			
				|  |  | -    @click="showRepliesDialog(message, true)"
 | 
	
		
			
				|  |  | -  >
 | 
	
		
			
				|  |  | -    <i class="icon icon-msg-replies"></i>
 | 
	
		
			
				|  |  | -    <span>{{ replies?.length + $t('TUIChat.条回复') }}</span>
 | 
	
		
			
				|  |  | -  </label>
 | 
	
		
			
				|  |  | -</template>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<script lang="ts">
 | 
	
		
			
				|  |  | -import { decodeText } from '../utils/decodeText';
 | 
	
		
			
				|  |  | -import constant from '../../constant';
 | 
	
		
			
				|  |  | -import {
 | 
	
		
			
				|  |  | -  defineComponent,
 | 
	
		
			
				|  |  | -  watchEffect,
 | 
	
		
			
				|  |  | -  reactive,
 | 
	
		
			
				|  |  | -  toRefs,
 | 
	
		
			
				|  |  | -  ref,
 | 
	
		
			
				|  |  | -  nextTick,
 | 
	
		
			
				|  |  | -  watch
 | 
	
		
			
				|  |  | -} from 'vue';
 | 
	
		
			
				|  |  | -import { onClickOutside, onLongPress, useElementBounding } from '@vueuse/core';
 | 
	
		
			
				|  |  | -import { deepCopy, JSONToObject } from '../utils/utils';
 | 
	
		
			
				|  |  | -import { handleErrorPrompts } from '../../utils';
 | 
	
		
			
				|  |  | -import TUIChat from '../index.vue';
 | 
	
		
			
				|  |  | -import MessageReference from './message-reference.vue';
 | 
	
		
			
				|  |  | -import { Message } from '../interface';
 | 
	
		
			
				|  |  | -import { TUIEnv } from '../../../../TUIPlugin';
 | 
	
		
			
				|  |  | -import MessageEmojiReact from './message-emoji-react.vue';
 | 
	
		
			
				|  |  | -import TIM from '../../../../TUICore/tim/index';
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -const messageBubble = defineComponent({
 | 
	
		
			
				|  |  | -  props: {
 | 
	
		
			
				|  |  | -    data: {
 | 
	
		
			
				|  |  | -      type: Object,
 | 
	
		
			
				|  |  | -      default: () => ({})
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    messagesList: {
 | 
	
		
			
				|  |  | -      type: Array,
 | 
	
		
			
				|  |  | -      default: () => []
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    isH5: {
 | 
	
		
			
				|  |  | -      type: Boolean,
 | 
	
		
			
				|  |  | -      default: false
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    needGroupReceipt: {
 | 
	
		
			
				|  |  | -      type: Boolean,
 | 
	
		
			
				|  |  | -      default: false
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    needReplies: {
 | 
	
		
			
				|  |  | -      type: Boolean,
 | 
	
		
			
				|  |  | -      default: true
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    flow: {
 | 
	
		
			
				|  |  | -      type: String,
 | 
	
		
			
				|  |  | -      default: ''
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    needEmojiReact: {
 | 
	
		
			
				|  |  | -      type: Boolean,
 | 
	
		
			
				|  |  | -      default: false
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -  },
 | 
	
		
			
				|  |  | -  emits: [
 | 
	
		
			
				|  |  | -    'jumpID',
 | 
	
		
			
				|  |  | -    'resendMessage',
 | 
	
		
			
				|  |  | -    'showReadReceiptDialog',
 | 
	
		
			
				|  |  | -    'showRepliesDialog',
 | 
	
		
			
				|  |  | -    'dropDownOpen'
 | 
	
		
			
				|  |  | -  ],
 | 
	
		
			
				|  |  | -  components: {
 | 
	
		
			
				|  |  | -    MessageReference,
 | 
	
		
			
				|  |  | -    MessageEmojiReact
 | 
	
		
			
				|  |  | -  },
 | 
	
		
			
				|  |  | -  setup(props: any, ctx: any) {
 | 
	
		
			
				|  |  | -    const { t } = (window as any).TUIKitTUICore.config.i18n.useI18n();
 | 
	
		
			
				|  |  | -    const { TUIServer } = TUIChat;
 | 
	
		
			
				|  |  | -    const data = reactive({
 | 
	
		
			
				|  |  | -      env: TUIEnv(),
 | 
	
		
			
				|  |  | -      message: {} as Message,
 | 
	
		
			
				|  |  | -      messagesList: [],
 | 
	
		
			
				|  |  | -      show: false,
 | 
	
		
			
				|  |  | -      type: {},
 | 
	
		
			
				|  |  | -      referenceMessage: {},
 | 
	
		
			
				|  |  | -      referenceForShow: {},
 | 
	
		
			
				|  |  | -      allMessageID: '',
 | 
	
		
			
				|  |  | -      needGroupReceipt: false,
 | 
	
		
			
				|  |  | -      needReplies: true,
 | 
	
		
			
				|  |  | -      replies: [],
 | 
	
		
			
				|  |  | -      face: [],
 | 
	
		
			
				|  |  | -      url: '',
 | 
	
		
			
				|  |  | -      needEmojiReact: false
 | 
	
		
			
				|  |  | -    });
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    watchEffect(() => {
 | 
	
		
			
				|  |  | -      data.type = constant;
 | 
	
		
			
				|  |  | -      data.messagesList = props.messagesList;
 | 
	
		
			
				|  |  | -      data.needEmojiReact = props.needEmojiReact;
 | 
	
		
			
				|  |  | -      data.message = deepCopy(
 | 
	
		
			
				|  |  | -        data.messagesList?.find(
 | 
	
		
			
				|  |  | -          (item: any) => (item as any)?.ID === props.message?.ID
 | 
	
		
			
				|  |  | -        ) || props.data
 | 
	
		
			
				|  |  | -      );
 | 
	
		
			
				|  |  | -      data.needGroupReceipt = props.needGroupReceipt;
 | 
	
		
			
				|  |  | -      data.needReplies = props.needReplies;
 | 
	
		
			
				|  |  | -      if ((data.message as any).cloudCustomData) {
 | 
	
		
			
				|  |  | -        const messageIDList: any[] = [];
 | 
	
		
			
				|  |  | -        const cloudCustomData = JSONToObject(
 | 
	
		
			
				|  |  | -          (data.message as any).cloudCustomData
 | 
	
		
			
				|  |  | -        );
 | 
	
		
			
				|  |  | -        data.replies = cloudCustomData?.messageReplies?.replies || [];
 | 
	
		
			
				|  |  | -        data.referenceMessage = cloudCustomData.messageReply
 | 
	
		
			
				|  |  | -          ? cloudCustomData.messageReply
 | 
	
		
			
				|  |  | -          : '';
 | 
	
		
			
				|  |  | -        for (
 | 
	
		
			
				|  |  | -          let index = 0;
 | 
	
		
			
				|  |  | -          index < (data.messagesList as any).length;
 | 
	
		
			
				|  |  | -          index++
 | 
	
		
			
				|  |  | -        ) {
 | 
	
		
			
				|  |  | -          // To determine whether the referenced message is still in the message list, the corresponding field of the referenced message is displayed if it is in the message list. Otherwise, messageabstract/messagesender is displayed
 | 
	
		
			
				|  |  | -          messageIDList.push((data.messagesList as any)[index].ID);
 | 
	
		
			
				|  |  | -          (data as any).allMessageID = JSON.stringify(messageIDList);
 | 
	
		
			
				|  |  | -          if (
 | 
	
		
			
				|  |  | -            (data.messagesList as any)[index].ID ===
 | 
	
		
			
				|  |  | -            (data.referenceMessage as any)?.messageID
 | 
	
		
			
				|  |  | -          ) {
 | 
	
		
			
				|  |  | -            data.referenceForShow = (data.messagesList as any)[index];
 | 
	
		
			
				|  |  | -            if (
 | 
	
		
			
				|  |  | -              (data.referenceMessage as any).messageType === constant.typeText
 | 
	
		
			
				|  |  | -            ) {
 | 
	
		
			
				|  |  | -              (data as any).face = decodeText(
 | 
	
		
			
				|  |  | -                (data.referenceForShow as any).payload
 | 
	
		
			
				|  |  | -              );
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            if (
 | 
	
		
			
				|  |  | -              (data.referenceMessage as any).messageType === constant.typeFace
 | 
	
		
			
				|  |  | -            ) {
 | 
	
		
			
				|  |  | -              (
 | 
	
		
			
				|  |  | -                data as any
 | 
	
		
			
				|  |  | -              ).url = `https://web.sdk.qcloud.com/im/assets/face-elem/${
 | 
	
		
			
				|  |  | -                (data.referenceForShow as any).payload.data
 | 
	
		
			
				|  |  | -              }@2x.png`;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -      } else {
 | 
	
		
			
				|  |  | -        data.replies = [];
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    });
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const htmlRefHook = ref<HTMLElement | null>(null);
 | 
	
		
			
				|  |  | -    const dropdown = ref(false);
 | 
	
		
			
				|  |  | -    const dropdownRef = ref(null);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const toggleDialog = (e: any) => {
 | 
	
		
			
				|  |  | -      dropdown.value = !dropdown.value;
 | 
	
		
			
				|  |  | -      if (dropdown.value) {
 | 
	
		
			
				|  |  | -        ctx.emit('dropDownOpen', dropdownRef);
 | 
	
		
			
				|  |  | -        nextTick(() => {
 | 
	
		
			
				|  |  | -          const dialogDom = (dropdownRef as any)?.value?.children[0];
 | 
	
		
			
				|  |  | -          const dialogElement = document.getElementsByClassName(
 | 
	
		
			
				|  |  | -            'dialog-item'
 | 
	
		
			
				|  |  | -          )[0] as HTMLElement;
 | 
	
		
			
				|  |  | -          const parentDom = (dropdownRef as any)?.value?.offsetParent;
 | 
	
		
			
				|  |  | -          const parentBound = useElementBounding(parentDom);
 | 
	
		
			
				|  |  | -          const messageListDom = document.getElementById(
 | 
	
		
			
				|  |  | -            'messageEle'
 | 
	
		
			
				|  |  | -          ) as HTMLElement;
 | 
	
		
			
				|  |  | -          const messageListBound = useElementBounding(messageListDom);
 | 
	
		
			
				|  |  | -          const leftRange = messageListBound?.left?.value;
 | 
	
		
			
				|  |  | -          const rightRange =
 | 
	
		
			
				|  |  | -            messageListBound?.left?.value +
 | 
	
		
			
				|  |  | -            (messageListDom as any).clientWidth -
 | 
	
		
			
				|  |  | -            dialogDom.clientWidth +
 | 
	
		
			
				|  |  | -            76;
 | 
	
		
			
				|  |  | -          const topRange = messageListBound?.top?.value;
 | 
	
		
			
				|  |  | -          const bottomRange =
 | 
	
		
			
				|  |  | -            messageListBound?.top?.value +
 | 
	
		
			
				|  |  | -            (messageListDom as any).clientHeight -
 | 
	
		
			
				|  |  | -            dialogDom.clientHeight;
 | 
	
		
			
				|  |  | -          const { clientX, clientY } = e;
 | 
	
		
			
				|  |  | -          if (data?.env?.isH5) {
 | 
	
		
			
				|  |  | -            if (parentBound?.top?.value <= dialogElement?.clientHeight) {
 | 
	
		
			
				|  |  | -              dialogDom.style.bottom = `-${dialogElement?.clientHeight}Px`;
 | 
	
		
			
				|  |  | -            } else {
 | 
	
		
			
				|  |  | -              if (data?.message?.flow === 'in') {
 | 
	
		
			
				|  |  | -                dialogDom.style.top = `-${dialogElement?.clientHeight - 20}Px`;
 | 
	
		
			
				|  |  | -              } else {
 | 
	
		
			
				|  |  | -                dialogDom.style.top = `-${dialogElement?.clientHeight}Px`;
 | 
	
		
			
				|  |  | -              }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            const centerWidth =
 | 
	
		
			
				|  |  | -              parentBound?.left?.value + parentBound?.width?.value / 2;
 | 
	
		
			
				|  |  | -            if (
 | 
	
		
			
				|  |  | -              centerWidth > dialogElement.clientWidth / 2 &&
 | 
	
		
			
				|  |  | -              centerWidth <
 | 
	
		
			
				|  |  | -                messageListDom?.clientWidth - dialogElement.clientWidth / 2
 | 
	
		
			
				|  |  | -            ) {
 | 
	
		
			
				|  |  | -              dialogDom.style.left = 'calc(50% - 135Px)';
 | 
	
		
			
				|  |  | -            } else if (centerWidth <= dialogElement.clientWidth / 2) {
 | 
	
		
			
				|  |  | -              dialogDom.style.left = '-20Px';
 | 
	
		
			
				|  |  | -            } else {
 | 
	
		
			
				|  |  | -              dialogDom.style.left = `-${dialogElement.clientWidth / 2 + 10}Px`;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            return;
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -          switch (true) {
 | 
	
		
			
				|  |  | -            case clientX > leftRange && clientX < rightRange:
 | 
	
		
			
				|  |  | -              dialogDom.style.left = `${Math.max(
 | 
	
		
			
				|  |  | -                e.clientX - parentBound?.left?.value - 76,
 | 
	
		
			
				|  |  | -                -40
 | 
	
		
			
				|  |  | -              )}Px`;
 | 
	
		
			
				|  |  | -              break;
 | 
	
		
			
				|  |  | -            case clientX <= leftRange:
 | 
	
		
			
				|  |  | -              dialogDom.style.left = '20Px';
 | 
	
		
			
				|  |  | -              break;
 | 
	
		
			
				|  |  | -            case clientX >= rightRange:
 | 
	
		
			
				|  |  | -              dialogDom.style.right = `${Math.max(
 | 
	
		
			
				|  |  | -                parentBound?.left?.value +
 | 
	
		
			
				|  |  | -                  parentDom?.clientWidth -
 | 
	
		
			
				|  |  | -                  e.clientX -
 | 
	
		
			
				|  |  | -                  256,
 | 
	
		
			
				|  |  | -                -10
 | 
	
		
			
				|  |  | -              )}Px`;
 | 
	
		
			
				|  |  | -              break;
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -          switch (true) {
 | 
	
		
			
				|  |  | -            case clientY > topRange && clientY < bottomRange:
 | 
	
		
			
				|  |  | -              dialogDom.style.top = `${e.clientY - parentBound?.top?.value}Px`;
 | 
	
		
			
				|  |  | -              dialogDom.style.cssText = dialogDom.style.cssText.replace(
 | 
	
		
			
				|  |  | -                'align-items:end;',
 | 
	
		
			
				|  |  | -                ''
 | 
	
		
			
				|  |  | -              );
 | 
	
		
			
				|  |  | -              break;
 | 
	
		
			
				|  |  | -            case clientY <= topRange:
 | 
	
		
			
				|  |  | -              dialogDom.style.top = '0Px';
 | 
	
		
			
				|  |  | -              dialogDom.style.cssText = dialogDom.style.cssText.replace(
 | 
	
		
			
				|  |  | -                'align-items:end;',
 | 
	
		
			
				|  |  | -                ''
 | 
	
		
			
				|  |  | -              );
 | 
	
		
			
				|  |  | -              break;
 | 
	
		
			
				|  |  | -            case clientY >= bottomRange:
 | 
	
		
			
				|  |  | -              dialogDom.style.bottom = `${
 | 
	
		
			
				|  |  | -                parentBound?.top?.value + parentDom?.clientHeight - e.clientY
 | 
	
		
			
				|  |  | -              }Px`;
 | 
	
		
			
				|  |  | -              dialogDom.style.cssText += 'align-items:end;';
 | 
	
		
			
				|  |  | -              break;
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -        });
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const jumpToAim = (message: any) => {
 | 
	
		
			
				|  |  | -      if (
 | 
	
		
			
				|  |  | -        (data.referenceMessage as any)?.messageID &&
 | 
	
		
			
				|  |  | -        data.allMessageID.includes((data.referenceMessage as any)?.messageID)
 | 
	
		
			
				|  |  | -      ) {
 | 
	
		
			
				|  |  | -        ctx.emit('jumpID', (data.referenceMessage as any).messageID);
 | 
	
		
			
				|  |  | -      } else {
 | 
	
		
			
				|  |  | -        const message = t('TUIChat.无法定位到原消息');
 | 
	
		
			
				|  |  | -        handleErrorPrompts(message, props);
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    onClickOutside(dropdownRef, () => {
 | 
	
		
			
				|  |  | -      dropdown.value = false;
 | 
	
		
			
				|  |  | -    });
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const toggleDialogH5 = (e: any) => {
 | 
	
		
			
				|  |  | -      if (data?.env?.isH5) toggleDialog(e);
 | 
	
		
			
				|  |  | -      return;
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    onLongPress(htmlRefHook, toggleDialogH5);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const resendMessage = (message: any) => {
 | 
	
		
			
				|  |  | -      ctx.emit('resendMessage', message);
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const showReadReceiptTag = (message: any) => {
 | 
	
		
			
				|  |  | -      if (
 | 
	
		
			
				|  |  | -        message.flow === 'out' &&
 | 
	
		
			
				|  |  | -        message.status === 'success' &&
 | 
	
		
			
				|  |  | -        message.needReadReceipt
 | 
	
		
			
				|  |  | -      ) {
 | 
	
		
			
				|  |  | -        return true;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      return false;
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const readReceiptStyle = (message: any) => {
 | 
	
		
			
				|  |  | -      if (
 | 
	
		
			
				|  |  | -        message?.readReceiptInfo?.isPeerRead ||
 | 
	
		
			
				|  |  | -        (message?.readReceiptInfo?.isPeerRead === undefined &&
 | 
	
		
			
				|  |  | -          message?.isPeerRead) ||
 | 
	
		
			
				|  |  | -        message?.readReceiptInfo?.unreadCount === 0
 | 
	
		
			
				|  |  | -      ) {
 | 
	
		
			
				|  |  | -        return '';
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      return 'unRead';
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const readReceiptCont = (message: any) => {
 | 
	
		
			
				|  |  | -      switch (message.conversationType) {
 | 
	
		
			
				|  |  | -        case TUIServer.TUICore.TIM.TYPES.CONV_C2C:
 | 
	
		
			
				|  |  | -          if (
 | 
	
		
			
				|  |  | -            message?.readReceiptInfo?.isPeerRead ||
 | 
	
		
			
				|  |  | -            (message?.readReceiptInfo?.isPeerRead === undefined &&
 | 
	
		
			
				|  |  | -              message?.isPeerRead)
 | 
	
		
			
				|  |  | -          ) {
 | 
	
		
			
				|  |  | -            return t('TUIChat.已读');
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -          return t('TUIChat.未读');
 | 
	
		
			
				|  |  | -        case TUIServer.TUICore.TIM.TYPES.CONV_GROUP:
 | 
	
		
			
				|  |  | -          if (message.readReceiptInfo.unreadCount === 0) {
 | 
	
		
			
				|  |  | -            return t('TUIChat.全部已读');
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -          if (
 | 
	
		
			
				|  |  | -            message.readReceiptInfo.readCount === 0 ||
 | 
	
		
			
				|  |  | -            (message.readReceiptInfo.unreadCount === undefined &&
 | 
	
		
			
				|  |  | -              message.readReceiptInfo.readCount === undefined)
 | 
	
		
			
				|  |  | -          ) {
 | 
	
		
			
				|  |  | -            return t('TUIChat.未读');
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -          return `${message.readReceiptInfo.readCount + t('TUIChat.人已读')}`;
 | 
	
		
			
				|  |  | -        default:
 | 
	
		
			
				|  |  | -          return '';
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const showReadReceiptDialog = (message: any) => {
 | 
	
		
			
				|  |  | -      ctx.emit('showReadReceiptDialog', message, 'receipt');
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const showRepliesDialog = (message: any, isRoot: boolean) => {
 | 
	
		
			
				|  |  | -      if (isRoot) {
 | 
	
		
			
				|  |  | -        ctx.emit('showRepliesDialog', message, 'replies');
 | 
	
		
			
				|  |  | -        return;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      if ((data.referenceMessage as any)?.messageRootID) {
 | 
	
		
			
				|  |  | -        const message = data.messagesList?.find(
 | 
	
		
			
				|  |  | -          (item: Message) =>
 | 
	
		
			
				|  |  | -            item.ID === (data.referenceMessage as any)?.messageRootID
 | 
	
		
			
				|  |  | -        );
 | 
	
		
			
				|  |  | -        if (message) {
 | 
	
		
			
				|  |  | -          ctx.emit('showRepliesDialog', message, 'replies');
 | 
	
		
			
				|  |  | -          return;
 | 
	
		
			
				|  |  | -        } else {
 | 
	
		
			
				|  |  | -          const message = t('TUIChat.无法定位到原消息');
 | 
	
		
			
				|  |  | -          handleErrorPrompts(message, props);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const handleImageOrVideoBubbleStyle = (message: Message) => {
 | 
	
		
			
				|  |  | -      const classNameList = ['content'];
 | 
	
		
			
				|  |  | -      if (!message) return classNameList;
 | 
	
		
			
				|  |  | -      classNameList.push(`content-${data.message.flow}`);
 | 
	
		
			
				|  |  | -      if (
 | 
	
		
			
				|  |  | -        data.message.type === TIM.TYPES.MSG_IMAGE &&
 | 
	
		
			
				|  |  | -        !isEmojiReactionInMessage(message)
 | 
	
		
			
				|  |  | -      ) {
 | 
	
		
			
				|  |  | -        classNameList.push('content-image');
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      if (
 | 
	
		
			
				|  |  | -        data.message.type === TIM.TYPES.MSG_VIDEO &&
 | 
	
		
			
				|  |  | -        !isEmojiReactionInMessage(message)
 | 
	
		
			
				|  |  | -      ) {
 | 
	
		
			
				|  |  | -        classNameList.push('content-video');
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      return classNameList;
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const isEmojiReactionInMessage = (message: Message) => {
 | 
	
		
			
				|  |  | -      try {
 | 
	
		
			
				|  |  | -        if (!message?.cloudCustomData) return;
 | 
	
		
			
				|  |  | -        const reactList = JSONToObject(message?.cloudCustomData)?.messageReact
 | 
	
		
			
				|  |  | -          ?.reacts;
 | 
	
		
			
				|  |  | -        if (!reactList || Object.keys(reactList).length === 0) return false;
 | 
	
		
			
				|  |  | -        return true;
 | 
	
		
			
				|  |  | -      } catch (err) {
 | 
	
		
			
				|  |  | -        console.warn(err);
 | 
	
		
			
				|  |  | -        return false;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    return {
 | 
	
		
			
				|  |  | -      ...toRefs(data),
 | 
	
		
			
				|  |  | -      toggleDialog,
 | 
	
		
			
				|  |  | -      htmlRefHook,
 | 
	
		
			
				|  |  | -      jumpToAim,
 | 
	
		
			
				|  |  | -      dropdown,
 | 
	
		
			
				|  |  | -      dropdownRef,
 | 
	
		
			
				|  |  | -      resendMessage,
 | 
	
		
			
				|  |  | -      showReadReceiptTag,
 | 
	
		
			
				|  |  | -      readReceiptStyle,
 | 
	
		
			
				|  |  | -      readReceiptCont,
 | 
	
		
			
				|  |  | -      showReadReceiptDialog,
 | 
	
		
			
				|  |  | -      showRepliesDialog,
 | 
	
		
			
				|  |  | -      handleImageOrVideoBubbleStyle,
 | 
	
		
			
				|  |  | -      isEmojiReactionInMessage,
 | 
	
		
			
				|  |  | -      TIM
 | 
	
		
			
				|  |  | -    };
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -});
 | 
	
		
			
				|  |  | -export default messageBubble;
 | 
	
		
			
				|  |  | -</script>
 | 
	
		
			
				|  |  | -<style lang="scss" scoped>
 | 
	
		
			
				|  |  | -@import url('../../../styles/common.scss');
 | 
	
		
			
				|  |  | -@import url('../../../styles/icon.scss');
 | 
	
		
			
				|  |  | -.reverse {
 | 
	
		
			
				|  |  | -  flex-direction: row-reverse;
 | 
	
		
			
				|  |  | -  justify-content: flex-start;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.avatar {
 | 
	
		
			
				|  |  | -  width: 36Px;
 | 
	
		
			
				|  |  | -  height: 36Px;
 | 
	
		
			
				|  |  | -  border-radius: 5Px;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.message-bubble {
 | 
	
		
			
				|  |  | -  width: 100%;
 | 
	
		
			
				|  |  | -  display: flex;
 | 
	
		
			
				|  |  | -  padding-bottom: 5Px;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.line-left {
 | 
	
		
			
				|  |  | -  border: 1Px solid rgba(0, 110, 255, 0.5);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.message-reference-area {
 | 
	
		
			
				|  |  | -  display: flex;
 | 
	
		
			
				|  |  | -  background: #f2f2f2;
 | 
	
		
			
				|  |  | -  border-radius: 0.5rem;
 | 
	
		
			
				|  |  | -  border-radius: 0.63rem;
 | 
	
		
			
				|  |  | -  align-self: start;
 | 
	
		
			
				|  |  | -  margin-left: 44Px;
 | 
	
		
			
				|  |  | -  margin-right: 8Px;
 | 
	
		
			
				|  |  | -  &-show {
 | 
	
		
			
				|  |  | -    width: 100%;
 | 
	
		
			
				|  |  | -    display: flex;
 | 
	
		
			
				|  |  | -    flex-direction: inherit;
 | 
	
		
			
				|  |  | -    justify-content: center;
 | 
	
		
			
				|  |  | -    padding: 6Px;
 | 
	
		
			
				|  |  | -    p {
 | 
	
		
			
				|  |  | -      font-family: PingFangSC-Regular;
 | 
	
		
			
				|  |  | -      font-weight: 400;
 | 
	
		
			
				|  |  | -      font-size: 0.88rem;
 | 
	
		
			
				|  |  | -      color: #999999;
 | 
	
		
			
				|  |  | -      letter-spacing: 0;
 | 
	
		
			
				|  |  | -      word-break: keep-all;
 | 
	
		
			
				|  |  | -      padding-right: 5Px;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    span {
 | 
	
		
			
				|  |  | -      height: 1.25rem;
 | 
	
		
			
				|  |  | -      font-family: PingFangSC-Regular;
 | 
	
		
			
				|  |  | -      font-weight: 400;
 | 
	
		
			
				|  |  | -      font-size: 0.88rem;
 | 
	
		
			
				|  |  | -      color: #999999;
 | 
	
		
			
				|  |  | -      letter-spacing: 0;
 | 
	
		
			
				|  |  | -      display: inline-block;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.message-replies {
 | 
	
		
			
				|  |  | -  display: flex;
 | 
	
		
			
				|  |  | -  align-self: start;
 | 
	
		
			
				|  |  | -  margin-left: 44Px;
 | 
	
		
			
				|  |  | -  margin-right: 8Px;
 | 
	
		
			
				|  |  | -  padding: 2Px;
 | 
	
		
			
				|  |  | -  color: #999999;
 | 
	
		
			
				|  |  | -  font-size: 10Px;
 | 
	
		
			
				|  |  | -  i {
 | 
	
		
			
				|  |  | -    margin: 4Px;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  span {
 | 
	
		
			
				|  |  | -    line-height: 20Px;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.message-reference-area-reverse,
 | 
	
		
			
				|  |  | -.message-replies-reverse {
 | 
	
		
			
				|  |  | -  align-self: end;
 | 
	
		
			
				|  |  | -  margin-right: 44Px;
 | 
	
		
			
				|  |  | -  margin-left: 8Px;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.message-img {
 | 
	
		
			
				|  |  | -  max-width: min(calc(100vw - 180Px), 300Px);
 | 
	
		
			
				|  |  | -  max-height: min(calc(100vw - 180Px), 300Px);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.message-video-cover {
 | 
	
		
			
				|  |  | -  display: inline-block;
 | 
	
		
			
				|  |  | -  position: relative;
 | 
	
		
			
				|  |  | -  &::before {
 | 
	
		
			
				|  |  | -    position: absolute;
 | 
	
		
			
				|  |  | -    z-index: 1;
 | 
	
		
			
				|  |  | -    content: '';
 | 
	
		
			
				|  |  | -    width: 0Px;
 | 
	
		
			
				|  |  | -    height: 0Px;
 | 
	
		
			
				|  |  | -    border: 15Px solid transparent;
 | 
	
		
			
				|  |  | -    border-left: 20Px solid #ffffff;
 | 
	
		
			
				|  |  | -    top: 0;
 | 
	
		
			
				|  |  | -    left: 0;
 | 
	
		
			
				|  |  | -    bottom: 0;
 | 
	
		
			
				|  |  | -    right: 0;
 | 
	
		
			
				|  |  | -    margin: auto;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.message-videoimg {
 | 
	
		
			
				|  |  | -  max-width: min(calc(100vw - 160Px), 300Px);
 | 
	
		
			
				|  |  | -  max-height: min(calc(100vw - 160Px), 300Px);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.face-box {
 | 
	
		
			
				|  |  | -  display: flex;
 | 
	
		
			
				|  |  | -  align-items: center;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.text-img {
 | 
	
		
			
				|  |  | -  width: 20Px;
 | 
	
		
			
				|  |  | -  height: 20Px;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.message-audio {
 | 
	
		
			
				|  |  | -  padding-left: 10Px;
 | 
	
		
			
				|  |  | -  display: flex;
 | 
	
		
			
				|  |  | -  align-items: center;
 | 
	
		
			
				|  |  | -  position: relative;
 | 
	
		
			
				|  |  | -  .icon {
 | 
	
		
			
				|  |  | -    margin: 0 4Px;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  audio {
 | 
	
		
			
				|  |  | -    width: 0;
 | 
	
		
			
				|  |  | -    height: 0;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.reserve {
 | 
	
		
			
				|  |  | -  flex-direction: row-reverse;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.message-area {
 | 
	
		
			
				|  |  | -  max-width: calc(100% - 54Px);
 | 
	
		
			
				|  |  | -  position: relative;
 | 
	
		
			
				|  |  | -  display: flex;
 | 
	
		
			
				|  |  | -  flex-direction: column;
 | 
	
		
			
				|  |  | -  padding: 0 8Px;
 | 
	
		
			
				|  |  | -  .name {
 | 
	
		
			
				|  |  | -    padding-bottom: 4Px;
 | 
	
		
			
				|  |  | -    font-weight: 400;
 | 
	
		
			
				|  |  | -    font-size: 0.8rem;
 | 
	
		
			
				|  |  | -    color: #999999;
 | 
	
		
			
				|  |  | -    letter-spacing: 0;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  .reference-content {
 | 
	
		
			
				|  |  | -    padding: 12Px;
 | 
	
		
			
				|  |  | -    font-weight: 400;
 | 
	
		
			
				|  |  | -    font-size: 14Px;
 | 
	
		
			
				|  |  | -    color: burlywood;
 | 
	
		
			
				|  |  | -    letter-spacing: 0;
 | 
	
		
			
				|  |  | -    word-wrap: break-word;
 | 
	
		
			
				|  |  | -    word-break: break-all;
 | 
	
		
			
				|  |  | -    animation: reference 800ms;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  @-webkit-keyframes reference {
 | 
	
		
			
				|  |  | -    from {
 | 
	
		
			
				|  |  | -      opacity: 1;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    50% {
 | 
	
		
			
				|  |  | -      background-color: #ff9c19;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    to {
 | 
	
		
			
				|  |  | -      opacity: 1;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  @keyframes reference {
 | 
	
		
			
				|  |  | -    from {
 | 
	
		
			
				|  |  | -      opacity: 1;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    50% {
 | 
	
		
			
				|  |  | -      background-color: #ff9c19;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    to {
 | 
	
		
			
				|  |  | -      opacity: 1;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  .content {
 | 
	
		
			
				|  |  | -    padding: 12Px;
 | 
	
		
			
				|  |  | -    font-weight: 400;
 | 
	
		
			
				|  |  | -    font-size: 14Px;
 | 
	
		
			
				|  |  | -    color: #000000;
 | 
	
		
			
				|  |  | -    letter-spacing: 0;
 | 
	
		
			
				|  |  | -    word-wrap: break-word;
 | 
	
		
			
				|  |  | -    word-break: break-all;
 | 
	
		
			
				|  |  | -    width: fit-content;
 | 
	
		
			
				|  |  | -    &-in {
 | 
	
		
			
				|  |  | -      background: #fbfbfb;
 | 
	
		
			
				|  |  | -      border-radius: 0Px 10Px 10Px 10Px;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    &-out {
 | 
	
		
			
				|  |  | -      background: #dceafd;
 | 
	
		
			
				|  |  | -      border-radius: 10Px 0Px 10Px 10Px;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    &-image {
 | 
	
		
			
				|  |  | -      padding: 0Px;
 | 
	
		
			
				|  |  | -      height: fit-content;
 | 
	
		
			
				|  |  | -      border-radius: 10Px 0Px 10Px 10Px;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    &-video {
 | 
	
		
			
				|  |  | -      padding: 0Px;
 | 
	
		
			
				|  |  | -      height: fit-content;
 | 
	
		
			
				|  |  | -      background: transparent;
 | 
	
		
			
				|  |  | -      border-radius: 10Px;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.message-label {
 | 
	
		
			
				|  |  | -  align-self: flex-end;
 | 
	
		
			
				|  |  | -  font-family: PingFangSC-Regular;
 | 
	
		
			
				|  |  | -  font-weight: 400;
 | 
	
		
			
				|  |  | -  font-size: 12Px;
 | 
	
		
			
				|  |  | -  color: #b6b8ba;
 | 
	
		
			
				|  |  | -  word-break: keep-all;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.fail {
 | 
	
		
			
				|  |  | -  width: 15Px;
 | 
	
		
			
				|  |  | -  height: 15Px;
 | 
	
		
			
				|  |  | -  border-radius: 15Px;
 | 
	
		
			
				|  |  | -  background: red;
 | 
	
		
			
				|  |  | -  color: #ffffff;
 | 
	
		
			
				|  |  | -  display: flex;
 | 
	
		
			
				|  |  | -  justify-content: center;
 | 
	
		
			
				|  |  | -  align-items: center;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.unRead {
 | 
	
		
			
				|  |  | -  color: #679ce1;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.dropdown-inner {
 | 
	
		
			
				|  |  | -  position: absolute;
 | 
	
		
			
				|  |  | -  width: 100%;
 | 
	
		
			
				|  |  | -  height: 100%;
 | 
	
		
			
				|  |  | -  left: 0;
 | 
	
		
			
				|  |  | -  top: 0;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -.dialog {
 | 
	
		
			
				|  |  | -  position: absolute;
 | 
	
		
			
				|  |  | -  z-index: 1;
 | 
	
		
			
				|  |  | -  display: flex;
 | 
	
		
			
				|  |  | -  flex-direction: row;
 | 
	
		
			
				|  |  | -  width: fit-content;
 | 
	
		
			
				|  |  | -  &-right {
 | 
	
		
			
				|  |  | -    right: 0;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -</style>
 |