@webitel/ui-chats 0.1.9 → 0.1.11

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webitel/ui-chats",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "Reusable Webitel Frontend Code for Chats UI",
5
5
  "workspaces": [
6
6
  "../../",
@@ -0,0 +1,69 @@
1
+ <template>
2
+ <aside
3
+ v-if="media"
4
+ class="media-viewer"
5
+ @click="close"
6
+ >
7
+ <div class="media-viewer__shadow" />
8
+ <div class="media-viewer__content-wrapper">
9
+ <img
10
+ class="media-viewer__content-img"
11
+ :src="media.url"
12
+ :alt="media.name"
13
+ >
14
+ </div>
15
+ </aside>
16
+ </template>
17
+
18
+ <script setup lang="ts">
19
+ import type { ChatMessageFile } from '../messaging/types/ChatMessage.types';
20
+
21
+ defineProps<{
22
+ media: ChatMessageFile | null;
23
+ }>();
24
+
25
+ const emit = defineEmits<{
26
+ close: [];
27
+ }>();
28
+
29
+ function close() {
30
+ emit('close');
31
+ }
32
+ </script>
33
+
34
+ <style scoped>
35
+ .media-viewer {
36
+ position: fixed;
37
+ top: 0;
38
+ right: 0;
39
+ bottom: 0;
40
+ left: 0;
41
+ z-index: var(--popup-wrapper-z-index);
42
+ display: flex;
43
+ align-items: center;
44
+ justify-content: center;
45
+ }
46
+
47
+ .media-viewer__shadow {
48
+ position: absolute;
49
+ top: 0;
50
+ right: 0;
51
+ bottom: 0;
52
+ left: 0;
53
+ background: var(--wt-popup-shadow-color);
54
+ }
55
+
56
+ .media-viewer__content-wrapper {
57
+ position: relative;
58
+ z-index: 1;
59
+ }
60
+
61
+ .media-viewer__content-img {
62
+ /* like on web telegram preview */
63
+ display: block;
64
+ max-width: 100vw;
65
+ max-height: 90vh;
66
+ object-fit: contain;
67
+ margin: auto;
68
+ }
69
+ </style>
@@ -1,5 +1,9 @@
1
1
  <template>
2
2
  <section class="the-chat-container">
3
+ <media-viewer
4
+ :media="mediaView"
5
+ @close="closeMedia"
6
+ />
3
7
  <slot name="main">
4
8
  <dropzone
5
9
  v-if="!isDropzoneDisabled && isDropzoneVisible"
@@ -45,23 +49,26 @@
45
49
  </template>
46
50
 
47
51
  <script setup lang="ts">
48
- import { ComponentSize } from "@webitel/ui-sdk/enums";
49
- import { computed, provide, ref } from "vue";
52
+ import { ComponentSize } from '@webitel/ui-sdk/enums';
53
+ import { computed, provide, ref } from 'vue';
50
54
 
51
- import ChatFooterWrapper from "./chat-footer/components/chat-footer-wrapper.vue";
52
- import ChatInputActionsBar from "./chat-footer/modules/user-input/components/chat-input-actions-bar.vue";
53
- import ChatTextField from "./chat-footer/modules/user-input/components/chat-text-field.vue";
55
+ import ChatFooterWrapper from './chat-footer/components/chat-footer-wrapper.vue';
56
+ import ChatInputActionsBar from './chat-footer/modules/user-input/components/chat-input-actions-bar.vue';
57
+ import ChatTextField from './chat-footer/modules/user-input/components/chat-text-field.vue';
54
58
  import {
55
59
  ChatAction,
56
60
  type SharedActionSlots,
57
- } from "./chat-footer/modules/user-input/enums/ChatAction.enum";
58
- import Dropzone from "./messaging/components/dropzone.vue";
59
- import MessagesContainer from "./messaging/components/the-messages-container.vue";
60
- import { useDropzoneHandlers } from "./messaging/composables/useDropzoneHandlers";
61
- import { MessageAction } from "./messaging/modules/message/enums/MessageAction.enum";
62
- import type { ChatMessageType } from "./messaging/types/ChatMessage.types";
63
- import { createUiChatsEmitter } from "./utils/emitter";
64
- import type { ResultCallbacks } from "./utils/ResultCallbacks.types";
61
+ } from './chat-footer/modules/user-input/enums/ChatAction.enum';
62
+ import MediaViewer from './media-viewer/media-viewer.vue';
63
+ import Dropzone from './messaging/components/dropzone.vue';
64
+ import MessagesContainer from './messaging/components/the-messages-container.vue';
65
+ import { useDropzoneHandlers } from './messaging/composables/useDropzoneHandlers';
66
+ import type {
67
+ ChatMessageFile,
68
+ ChatMessageType,
69
+ } from './messaging/types/ChatMessage.types';
70
+ import { createUiChatsEmitter } from './utils/emitter';
71
+ import type { ResultCallbacks } from './utils/ResultCallbacks.types';
65
72
 
66
73
  const props = withDefaults(
67
74
  defineProps<{
@@ -71,7 +78,7 @@ const props = withDefaults(
71
78
  canLoadNextMessages?: boolean; // 'next'
72
79
  isNextMessagesLoading?: boolean;
73
80
  withoutAvatars?: boolean;
74
- readonly?: boolean; // hide chat footer with textarea and action-buttons
81
+ readonly?: boolean; // hide chat footer with textarea and action-buttons
75
82
  }>(),
76
83
  {
77
84
  size: ComponentSize.MD,
@@ -79,7 +86,7 @@ const props = withDefaults(
79
86
  chatActions: () => [],
80
87
  canLoadNextMessages: false,
81
88
  isNextMessagesLoading: false,
82
- readonly: false,
89
+ readonly: false,
83
90
  },
84
91
  );
85
92
 
@@ -95,7 +102,6 @@ const emit = defineEmits<{
95
102
  options: ResultCallbacks,
96
103
  ): void;
97
104
  (e: typeof ChatAction.LoadNextMessages): void;
98
- (e: typeof MessageAction.ClickOnImage, message: ChatMessageType): void;
99
105
  }>();
100
106
 
101
107
  const slots = defineSlots<
@@ -107,20 +113,30 @@ const slots = defineSlots<
107
113
 
108
114
  const uiChatsEmitter = createUiChatsEmitter();
109
115
 
110
- provide("size", props.size);
111
- provide("uiChatsEmitter", uiChatsEmitter);
116
+ provide('size', props.size);
117
+ provide('uiChatsEmitter', uiChatsEmitter);
112
118
 
113
- uiChatsEmitter?.on("clickChatMessageImage", (message) => {
114
- emit(MessageAction.ClickOnImage, message);
119
+ const mediaView = ref<ChatMessageFile | null>(null);
120
+
121
+ uiChatsEmitter?.on('clickChatMessageImage', (message) => {
122
+ openMedia(message);
115
123
  });
116
124
  const { isDropzoneVisible, handleDragLeave } = useDropzoneHandlers();
117
125
 
118
- const draft = ref<string>("");
126
+ function openMedia(message: ChatMessageType) {
127
+ mediaView.value = message.file ?? null;
128
+ }
129
+
130
+ function closeMedia() {
131
+ mediaView.value = null;
132
+ }
133
+
134
+ const draft = ref<string>('');
119
135
 
120
136
  const slottedChatActions = computed(() => {
121
137
  return Object.keys(slots)
122
- .filter((key) => key.startsWith("action:"))
123
- .map((key) => key.replace("action:", ""));
138
+ .filter((key) => key.startsWith('action:'))
139
+ .map((key) => key.replace('action:', ''));
124
140
  });
125
141
  const isDropzoneDisabled = computed(
126
142
  () => !props.chatActions.includes(ChatAction.AttachFiles),
@@ -128,7 +144,7 @@ const isDropzoneDisabled = computed(
128
144
 
129
145
  function sendMessage() {
130
146
  emit(`action:${ChatAction.SendMessage}`, draft.value, {
131
- onSuccess: () => (draft.value = ""),
147
+ onSuccess: () => (draft.value = ''),
132
148
  });
133
149
  }
134
150
 
@@ -0,0 +1,11 @@
1
+ import type { ChatMessageFile } from '../messaging/types/ChatMessage.types';
2
+ type __VLS_Props = {
3
+ media: ChatMessageFile | null;
4
+ };
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
6
+ close: () => any;
7
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
8
+ onClose?: () => any;
9
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
10
+ declare const _default: typeof __VLS_export;
11
+ export default _default;