vue-wiguet-chatweb 0.0.19 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-wiguet-chatweb",
3
- "version": "0.0.19",
3
+ "version": "0.0.21",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -27,7 +27,8 @@
27
27
  "scripts": {
28
28
  "dev": "vite",
29
29
  "build": "vue-tsc && vite build",
30
- "preview": "vite preview"
30
+ "preview": "vite preview",
31
+ "prepack": "npm run build"
31
32
  },
32
33
  "peerDependencies": {
33
34
  "@vueuse/core": "^10.0.0",
@@ -37,14 +38,19 @@
37
38
  "vue": "^3.2.0"
38
39
  },
39
40
  "dependencies": {
41
+ "@vueuse/core": "^10.0.0",
42
+ "axios": "^1.4.0",
43
+ "luxon": "^3.0.0",
40
44
  "socket.io-client": "^4.7.2",
45
+ "uuid": "^9.0.1",
41
46
  "vite-plugin-dts": "^3.4.0",
47
+ "vue": "^3.2.0",
42
48
  "vue-rabbit-frontend": "^0.0.15"
43
49
  },
44
50
  "devDependencies": {
45
51
  "@types/luxon": "^3.4.2",
46
52
  "@types/node": "^20.4.6",
47
- "@types/uuid": "^9.0.8",
53
+ "@types/uuid": "^10.0.0",
48
54
  "@vitejs/plugin-vue": "^4.2.3",
49
55
  "typescript": "^5.0.2",
50
56
  "vite": "^4.4.5",
@@ -29,9 +29,10 @@
29
29
  v-model="message"
30
30
  class="jl2-input-chat"
31
31
  required
32
- ref="textArea"
32
+ ref="textAreaRef"
33
33
  @input="() => autoAdjustHeight()"
34
- @keyup.enter="(ev) => submitMessage(ev)"
34
+ @keydown.enter.prevent
35
+ @keyup.enter.prevent="submitMessage"
35
36
  />
36
37
  <button type="submit" class="pointer btn-primary">
37
38
  <IconSend style="width: 20px; height: 20px" />
@@ -52,7 +53,6 @@ import {
52
53
  type SendMessageBody,
53
54
  ListMessageBody,
54
55
  Message,
55
- RABBIT_EVENTS,
56
56
  } from "../dto/app.dto";
57
57
  import IconClose from "./IconClose.vue";
58
58
  import IconSend from "./IconSend.vue";
@@ -66,6 +66,7 @@ import { getInformationApi } from "../store";
66
66
  import MessageList from "./MessageList.vue";
67
67
  import Loader from "./Loader.vue";
68
68
  import { searchFromLast } from "../resources/functions.helpers";
69
+ import { RABBIT_EVENTS } from "../dto/app.dto";
69
70
 
70
71
  //DATA
71
72
  const rabbitMQServiceListen: any = ref(null);
@@ -111,39 +112,42 @@ const messageContainerRef = ref<HTMLElement | null>(null);
111
112
  watch(
112
113
  () => props.visible,
113
114
  async (current) => {
114
- if (current) {
115
- emit("clear-new-messages");
116
- scrollToBottom();
117
- if (!virtualHost.value || !appChatId.value) {
118
- const resp = await getInformationApi(props.tokenAuth);
119
- const data = resp.response.data;
120
- virtualHost.value = data.virtualHost;
121
- appChatId.value = data.appChat.id;
122
- connectMsRabbit();
123
- }
124
- if (notViewed.value > 0) {
125
- setVistoToTrueApi(appChatId.value, props.tokenAuth);
126
- }
115
+ if(!current) return
116
+
117
+ emit("clear-new-messages");
118
+ scrollToBottom();
119
+
120
+ if (notViewed.value > 0) {
121
+ setVistoToTrueApi(appChatId.value, props.tokenAuth);
122
+ }
123
+
124
+ if (virtualHost.value && appChatId.value) return;
125
+
126
+ const resp = await getInformationApi(props.tokenAuth);
127
+
128
+ if(resp) {
129
+ virtualHost.value = resp.virtualHost;
130
+ appChatId.value = resp.appChat.id;
131
+ connectMsRabbit();
127
132
  }
128
133
  }
129
134
  );
130
135
  onMounted(async () => {
131
- if (!virtualHost.value || !appChatId.value) {
132
- try {
133
- const resp = await getInformationApi(props.tokenAuth);
134
- const data = resp.response.data;
135
- virtualHost.value = data.virtualHost;
136
- appChatId.value = data.appChat.id;
137
- emit("not-viewed-total", data.appChat.totalNoVistosCliente);
138
- notViewed.value = data.appChat.totalNoVistosCliente;
139
- getMessages();
140
- connectMsRabbit();
141
- } catch (error) {}
142
- }
136
+ if (virtualHost.value && appChatId.value) return;
137
+
138
+ const resp = await getInformationApi(props.tokenAuth);
139
+
140
+ if(!resp) return;
141
+
142
+ virtualHost.value = resp.virtualHost;
143
+ appChatId.value = resp.appChat.id;
144
+ emit("not-viewed-total", resp.appChat.totalNoVistosCliente);
145
+ notViewed.value = resp.appChat.totalNoVistosCliente;
146
+ getMessages();
147
+ connectMsRabbit();
143
148
  });
144
149
 
145
- const submitMessage = async (event: any) => {
146
- event.preventDefault();
150
+ const submitMessage = async (event: Event) => {
147
151
  if (message.value?.length > 300) {
148
152
  emit("show-toast", {
149
153
  severity: "warn",
@@ -153,6 +157,7 @@ const submitMessage = async (event: any) => {
153
157
  });
154
158
  return;
155
159
  }
160
+
156
161
  if (!message.value.trim()) {
157
162
  emit("show-toast", {
158
163
  severity: "warn",
@@ -162,6 +167,7 @@ const submitMessage = async (event: any) => {
162
167
  });
163
168
  return;
164
169
  }
170
+
165
171
  const newMessage = {
166
172
  id: uuidv4(),
167
173
  message: message.value,
@@ -177,25 +183,31 @@ const submitMessage = async (event: any) => {
177
183
  msPersonaId: props.user.msPersonaId,
178
184
  },
179
185
  };
186
+
187
+
180
188
  const idx = messagesData.value.data.push(newMessage) - 1;
181
- try {
182
- const newMsg = await sendApi(message.value, appChatId.value);
183
- messagesData.value.data[idx] = newMsg.response.data;
184
- } catch (error) {
185
- messagesData.value.data[idx].error = {
186
- error: true,
187
- id: newMessage.id,
188
- };
189
- emit("show-toast", {
190
- severity: "error",
191
- summary: "Error",
192
- detail: "Ocurrio un error al enviar el mensaje, intente nuevamente",
193
- life: 5000,
194
- });
195
- } finally {
196
- message.value = "";
197
- scrollToBottom();
198
- }
189
+
190
+ sendApi(message.value, appChatId.value).then((newMsg)=>{
191
+ if(!newMsg) {
192
+ messagesData.value.data[idx].error = {
193
+ error: true,
194
+ id: newMessage.id,
195
+ };
196
+
197
+ emit("show-toast", {
198
+ severity: "error",
199
+ summary: "Error",
200
+ detail: "Ocurrio un error al enviar el mensaje, intente nuevamente",
201
+ life: 5000,
202
+ });
203
+ } else {
204
+ messagesData.value.data[idx] = newMsg;
205
+ }
206
+ });
207
+
208
+ message.value = "";
209
+ scrollToBottom();
210
+ textAreaRef.value && (textAreaRef.value.style.height = "20px")
199
211
  };
200
212
 
201
213
  const sendApi = async (message: string, appChatId: string) => {
@@ -208,54 +220,57 @@ const sendApi = async (message: string, appChatId: string) => {
208
220
  };
209
221
 
210
222
  const getMessages = async () => {
211
- try {
212
- isLoading.value = true;
213
- const lastMessagesId = messagesData.value.data[0]?.id;
214
- const body: ListMessageBody = {
215
- limit: 10,
216
- lastMessagesId,
217
- appChatId: appChatId.value,
218
- };
219
-
220
- const resp = await getMessagesApi({ body, token: props.tokenAuth });
221
- messagesData.value.data.unshift(
222
- ...resp.data.sort((a, b) => -b.createdAt.localeCompare(a.createdAt))
223
- );
224
- messagesData.value.canLoadMoreMessages =
225
- resp.pagination.total > resp.pagination.limit;
226
- if (lastMessagesId && messageContainerRef.value?.scrollHeight) {
227
- mantainElementsOnViewport(messageContainerRef.value?.scrollHeight);
228
- }
229
- if (!lastMessagesId) scrollToBottom();
230
- } catch (error) {
231
- isLoading.value = false;
232
- throw error;
233
- } finally {
234
- isLoading.value = false;
223
+
224
+ const lastMessagesId = messagesData.value.data[0]?.id;
225
+ const body: ListMessageBody = {
226
+ lastMessagesId,
227
+ appChatId: appChatId.value,
228
+ limit: 10
229
+ };
230
+
231
+ isLoading.value = true;
232
+ const resp = await getMessagesApi({ body, token: props.tokenAuth });
233
+ isLoading.value = false;
234
+
235
+ messagesData.value.data.unshift(
236
+ ...resp.data.sort((a, b) => -b.createdAt.localeCompare(a.createdAt))
237
+ );
238
+
239
+ messagesData.value.canLoadMoreMessages =
240
+ resp.pagination.total > resp.pagination.size;
241
+
242
+ if (lastMessagesId && messageContainerRef.value?.scrollHeight) {
243
+ mantainElementsOnViewport(messageContainerRef.value?.scrollHeight);
235
244
  }
245
+
246
+ if (!lastMessagesId) scrollToBottom();
236
247
  };
237
248
 
238
249
  const retryMessage = async (message: Message) => {
239
250
  emit("show-confirm", async () => {
240
- try {
241
- if (!message.error?.id) return;
242
- const msg = await sendApi(message.message, appChatId.value);
243
- const idx = searchFromLast<Message>(
244
- messagesData.value.data,
245
- "id",
246
- message.error.id
247
- );
248
- messagesData.value.data[idx] = { ...msg.response.data, error: undefined };
249
- } catch (error) {
251
+
252
+ if (!message.error?.id) return;
253
+
254
+ const msg = await sendApi(message.message, appChatId.value);
255
+
256
+ if (!msg) {
250
257
  emit("show-toast", {
251
258
  severity: "error",
252
259
  summary: "Error",
253
260
  detail: "Ocurrio un error al enviar el mensaje, intente nuevamente",
254
261
  life: 5000,
255
262
  });
256
- } finally {
257
- scrollToBottom();
263
+ } else {
264
+ const idx = searchFromLast<Message>(
265
+ messagesData.value.data,
266
+ "id",
267
+ message.error.id
268
+ );
269
+
270
+ messagesData.value.data[idx] = { ...msg, error: undefined };
258
271
  }
272
+
273
+ scrollToBottom();
259
274
  });
260
275
  };
261
276
 
@@ -313,18 +328,20 @@ const mantainElementsOnViewport = (scrollHeightBeforeAdd: number) => {
313
328
  });
314
329
  };
315
330
 
316
- const textArea = ref<HTMLTextAreaElement>();
331
+ const textAreaRef = ref<HTMLTextAreaElement>();
332
+
333
+ const fontSpace = 14;
317
334
 
318
335
  function autoAdjustHeight() {
319
- if (!textArea.value) return;
320
- // Reset the height to default to get the scroll height
321
- textArea.value.style.height = "auto";
322
- // Set the new height based on the scroll height
323
- textArea.value.style.height =
324
- textArea.value.scrollHeight === 54
325
- ? textArea.value.scrollHeight - 12 + "px"
326
- : textArea.value.scrollHeight + "px";
336
+ if (!textAreaRef.value) return;
337
+
338
+ textAreaRef.value.style.height = textAreaRef.value.scrollHeight - fontSpace + 'px'
339
+
340
+ if(textAreaRef.value.scrollHeight === textAreaRef.value.clientHeight) return;
341
+
342
+ textAreaRef.value.style.height = textAreaRef.value.scrollHeight + "px"
327
343
  }
344
+
328
345
  </script>
329
346
 
330
347
  <style scoped>
@@ -0,0 +1,104 @@
1
+ <template>
2
+ <div class="chat-message">
3
+
4
+ <div class="bubble" :class="self ? 'left' : 'right'">
5
+ <div :class="self ? 'content-left' : 'content-right'">
6
+ <div class="message">
7
+ {{ message.messages.dataMessage }}
8
+ </div>
9
+ <div class="detail-message flex justify-content-between">
10
+ <span class="mr-5" v-if="message.messages.user?.nombreCompleto">
11
+ {{ textCapitalize(message.messages.user.nombreCompleto) }}
12
+ </span>
13
+ <span class="mr-5" v-else>
14
+ </span>
15
+ <span>
16
+ {{ formatTimeAPDate(message.messages.createdAt) }}
17
+ </span>
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </div>
22
+ </template>
23
+
24
+ <script setup lang="ts">
25
+ import {computed } from 'vue';
26
+ import { formatTimeAPDate,textCapitalize } from '../resources/functions.helpers'
27
+ const props = defineProps({
28
+ message:{ type: Object, required: true },
29
+ });
30
+
31
+ const self = computed(() => {
32
+ return props.message.messages.responseOrigin;
33
+ });
34
+
35
+ </script>
36
+
37
+ <style scoped>
38
+ .bubble {
39
+ --r: 25px;
40
+ /* the radius */
41
+ --t: 30px;
42
+ /* the size of the tail */
43
+
44
+ max-width: 50%;
45
+ min-width: 250px;
46
+ padding: calc(2*var(--r)/3);
47
+ -webkit-mask:
48
+ radial-gradient(var(--t) at var(--_d) 0, #0000 98%, #000 102%) var(--_d) 100%/calc(100% - var(--r)) var(--t) no-repeat,
49
+ conic-gradient(at var(--r) var(--r), #000 75%, #0000 0) calc(var(--r)/-2) calc(var(--r)/-2) padding-box,
50
+ radial-gradient(50% 50%, #000 98%, #0000 101%) 0 0/var(--r) var(--r) space padding-box;
51
+ /* background: linear-gradient(135deg, #FE6D00, #1384C5) border-box; */
52
+ color: #fff;
53
+ }
54
+
55
+ .left {
56
+ --_d: 0%;
57
+ border-left: var(--t) solid #0000;
58
+ margin-right: var(--t);
59
+ background-color: #fcd7ae;
60
+ color:#4d4d4d;
61
+ place-self: start;
62
+ }
63
+
64
+ .bubble > .content-left{
65
+ margin-right: 10px;
66
+ margin-bottom: 1px;
67
+ }
68
+
69
+ .right {
70
+ --_d: 100%;
71
+ border-right: var(--t) solid #0000;
72
+ margin-left: var(--t);
73
+ background-color: #fdeedb;
74
+ color:#4d4d4d;
75
+ place-self: end;
76
+ }
77
+
78
+ .bubble > .content-right{
79
+ margin-bottom: 1px;
80
+ margin-right: 10px;
81
+ }
82
+
83
+ .message{
84
+ text-align: initial;
85
+ word-break: break-all;
86
+ margin-bottom: 10px;
87
+ }
88
+ .detail-message{
89
+ font-size: 10px;
90
+ color: #808080;
91
+ display: flex;
92
+ justify-content:space-between;
93
+ }
94
+
95
+ .chat-message {
96
+ max-width: 250px;
97
+ min-width: 90%;
98
+ display: flex;
99
+ flex-direction: column;
100
+ justify-content: center;
101
+ /* box-shadow: 0 2px 8px rgba(0, 0, 0, 20%); */
102
+ }
103
+
104
+ </style>