@bcc-code/vue-bcc-chat-ui 3.15.0 → 3.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@bcc-code/vue-bcc-chat-ui",
3
3
  "author": "bcc-code",
4
4
  "license": "Apache-2.0",
5
- "version": "3.15.0",
5
+ "version": "3.17.0",
6
6
  "type": "module",
7
7
  "private": false,
8
8
  "files": [
@@ -1,14 +1,34 @@
1
1
  <script setup lang="ts">
2
+ import { PlaceholderImage } from '@cometchat/chat-uikit-vue';
3
+ import { computed } from 'vue';
4
+
2
5
  const props = defineProps({
3
6
  captionedAttachment: { type: Object, default: {} },
4
7
  previewStyle: { type: Object, default: {} },
5
8
  });
9
+
10
+ const previewUrl = computed(() => {
11
+ if (!props.captionedAttachment?.fileObject)
12
+ return PlaceholderImage;
13
+
14
+ const blob = new Blob([props.captionedAttachment.fileObject]);
15
+ return URL.createObjectURL(blob);
16
+ });
17
+
18
+ function imgLoaded(event: Event) {
19
+ if (props.captionedAttachment) {
20
+ props.captionedAttachment.dimensions = {
21
+ width: (event.target as HTMLImageElement)?.naturalWidth,
22
+ height: (event.target as HTMLImageElement)?.naturalHeight
23
+ };
24
+ }
25
+ }
6
26
  </script>
7
27
 
8
28
  <template>
9
29
  <div class="bcc__attachment_preview__content_wrapper">
10
30
  <div class="bcc__attachment_preview__content">
11
- <img :src="props.captionedAttachment?.image" />
31
+ <img :src="previewUrl" @load="imgLoaded" />
12
32
  </div>
13
33
  </div>
14
34
  </template>
@@ -28,7 +28,7 @@ import BccChatSendButton from "./BccChatSendButton.vue";
28
28
 
29
29
  const props = defineProps({
30
30
  chatUid: { type: String, required: true },
31
- senderDisplayName: { type: String, required: false }
31
+ senderDisplayName: { type: String, required: false },
32
32
  });
33
33
 
34
34
  const componentId = ref(
@@ -46,7 +46,6 @@ const messageComposerConfiguration = getMessageComposerConfiguration(chatInstanc
46
46
  const messageListConfiguration = getMessageListConfiguration(chatInstance, chatGroup);
47
47
  const threadedMessagesConfiguration = getThreadedMessagesConfiguration(chatGroup);
48
48
  threadedMessagesConfiguration.messageComposerConfiguration = messageComposerConfiguration.value;
49
-
50
49
  provide("chatInstance", chatInstance);
51
50
 
52
51
  const onMessageSend = CometChatMessageEvents.ccMessageSent.subscribe(({ message, status }) => {
@@ -29,8 +29,9 @@ function sendMessage() {
29
29
  const receiverType = msgComposerProps?.group ? "group" : "user";
30
30
  const fileObject = chatInstance.value.captionedAttachment.fileObject;
31
31
  const caption = msgComposerData.messageText;
32
+ const dimensions = chatInstance.value.captionedAttachment.dimensions;
32
33
 
33
- const sendMessageResult = sendMediaMessage(msgComposerProps, fileObject, receiverId, receiverType, "image", caption);
34
+ const sendMessageResult = sendMediaMessage(msgComposerProps, fileObject, receiverId, receiverType, "image", dimensions, caption);
34
35
  if (sendMessageResult) {
35
36
  msgComposerData.showSendButton = false;
36
37
  // Clear text input
@@ -24,10 +24,26 @@ const imageStyle = {
24
24
  height: "auto",
25
25
  maxHeight: "500px",
26
26
  maxWidth: "400px",
27
- borderRadius: "8px",
28
27
  ...props.imageStyle
29
28
  };
30
29
 
30
+ const onePixelPlaceholderImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
31
+ const wideThinTransparentImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+gAAAABCAQAAADnCUy4AAAAF0lEQVR42mNkGAWjYBSMglEwCkbBkAcAD6IAAqr+AZEAAAAASUVORK5CYII=";
32
+ const height300pxImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAEsCAQAAACoWRFeAAAAE0lEQVR42mNkYGAcRaNoFA0cAgAUvAEtNFICWAAAAABJRU5ErkJggg==";
33
+
34
+ const imgDimensions = (props.message?.getMetadata() as any)?.dimensions;
35
+ const numericAspectRatio = imgDimensions ? imgDimensions.width / imgDimensions.height : undefined;
36
+ const isLandscape = imgDimensions ? imgDimensions.height < imgDimensions.width : undefined;
37
+
38
+ let aspectRatio: string | undefined;
39
+ if (numericAspectRatio !== undefined && numericAspectRatio <= 0.28) { // 0.28 is the minimum aspect ratio before min-width is reached.
40
+ aspectRatio = "0.28 / 1";
41
+ } else if (numericAspectRatio !== undefined && numericAspectRatio >= 8) { // 8 is the maximum aspect ratio before min-height is reached.
42
+ aspectRatio = "8 / 1";
43
+ } else if (imgDimensions) {
44
+ aspectRatio = `${imgDimensions.width}/${imgDimensions.height}`;
45
+ }
46
+
31
47
  const openFullscreenView = ref(false);
32
48
  const imageurlToOpen = ref("");
33
49
 
@@ -40,16 +56,20 @@ function closeImageInFullScreen() {
40
56
  imageurlToOpen.value = "";
41
57
  openFullscreenView.value = false;
42
58
  }
43
-
44
59
  </script>
45
60
 
46
61
  <template>
47
- <cometchat-image-bubble
48
- :src="props.src"
49
- :placeholderImage="props.placeholderImage"
50
- :imageStyle="imageStyle"
51
- :onCcImageClicked="openImageInFullScreen"
52
- />
62
+ <div class="bcc-image_container">
63
+ <div class="placeholder" v-if="imgDimensions != undefined" :class="{ 'landscape': isLandscape }" :style="{ 'aspect-ratio': aspectRatio }">
64
+ <img :src="isLandscape ? wideThinTransparentImage : height300pxImage" />
65
+ </div>
66
+ <cometchat-image-bubble
67
+ :src="props.src"
68
+ :placeholderImage="imgDimensions ? onePixelPlaceholderImage : props.placeholderImage"
69
+ :imageStyle="imageStyle"
70
+ :onCcImageClicked="openImageInFullScreen"
71
+ />
72
+ </div>
53
73
  <BccCometChatFullScreenViewer v-if="openFullscreenView"
54
74
  :onCcCloseClicked="closeImageInFullScreen"
55
75
  :URL="imageurlToOpen"
@@ -57,5 +77,48 @@ function closeImageInFullScreen() {
57
77
  </template>
58
78
 
59
79
  <style scoped>
80
+ .bcc-image_container {
81
+ max-height: 300px;
82
+ display: grid;
83
+ grid-template-columns: 1fr;
84
+ justify-content: center;
85
+ overflow: hidden;
86
+ border-radius: 10px;
87
+ isolation: isolate;
88
+ min-height: 28px;
89
+ min-width: 84px;
90
+ }
60
91
 
92
+ /* Placeholder styles */
93
+ .placeholder {
94
+ width: 100%;
95
+ height: auto;
96
+ display: flex;
97
+ justify-content: center;
98
+ align-items: center;
99
+ background-color: var(--cc__accent200, #3e8e7526); /* Placeholder background color */
100
+ grid-row-start: 1;
101
+ grid-column-start: 1;
102
+ position: relative;
103
+ z-index: -1;
104
+ }
105
+
106
+ .placeholder::before {
107
+ content: "⌛";
108
+ position: absolute;
109
+ }
110
+
111
+ .placeholder.landscape > img {
112
+ width: 100%;
113
+ }
114
+
115
+ cometchat-image-bubble {
116
+ display: block;
117
+ max-width: 100%;
118
+ grid-row-start: 1;
119
+ grid-column-start: 1;
120
+ display: flex;
121
+ justify-content: center;
122
+ /* align-items: center; */
123
+ }
61
124
  </style>