vue-wiguet-chatweb 0.0.20 → 0.0.22

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": "vue-wiguet-chatweb",
3
- "version": "0.0.20",
3
+ "version": "0.0.22",
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
- size: 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.size;
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,103 @@
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
+ // TODO: parece que no se usa
26
+ import {computed } from 'vue';
27
+ import { formatTimeAPDate,textCapitalize } from '../resources/functions.helpers'
28
+ const props = defineProps({
29
+ message:{ type: Object, required: true },
30
+ });
31
+
32
+ const self = computed(() => {
33
+ return props.message.messages.responseOrigin;
34
+ });
35
+
36
+ </script>
37
+
38
+ <style scoped>
39
+ .bubble {
40
+ --r: 25px;
41
+ /* the radius */
42
+ --t: 30px;
43
+ /* the size of the tail */
44
+
45
+ max-width: 50%;
46
+ min-width: 250px;
47
+ padding: calc(2*var(--r)/3);
48
+ -webkit-mask:
49
+ radial-gradient(var(--t) at var(--_d) 0, #0000 98%, #000 102%) var(--_d) 100%/calc(100% - var(--r)) var(--t) no-repeat,
50
+ conic-gradient(at var(--r) var(--r), #000 75%, #0000 0) calc(var(--r)/-2) calc(var(--r)/-2) padding-box,
51
+ radial-gradient(50% 50%, #000 98%, #0000 101%) 0 0/var(--r) var(--r) space padding-box;
52
+ /* background: linear-gradient(135deg, #FE6D00, #1384C5) border-box; */
53
+ color: #fff;
54
+ }
55
+
56
+ .left {
57
+ --_d: 0%;
58
+ border-left: var(--t) solid #0000;
59
+ margin-right: var(--t);
60
+ background-color: #fcd7ae;
61
+ color:#4d4d4d;
62
+ place-self: start;
63
+ }
64
+
65
+ .bubble > .content-left{
66
+ margin-right: 10px;
67
+ margin-bottom: 1px;
68
+ }
69
+
70
+ .right {
71
+ --_d: 100%;
72
+ border-right: var(--t) solid #0000;
73
+ margin-left: var(--t);
74
+ background-color: #fdeedb;
75
+ color:#4d4d4d;
76
+ place-self: end;
77
+ }
78
+
79
+ .bubble > .content-right{
80
+ margin-bottom: 1px;
81
+ margin-right: 10px;
82
+ }
83
+
84
+ .message {
85
+ text-align: initial;
86
+ word-break: break-all;
87
+ margin-bottom: 10px;
88
+ }
89
+ .detail-message{
90
+ font-size: 10px;
91
+ color: #808080;
92
+ display: flex;
93
+ justify-content:space-between;
94
+ }
95
+
96
+ .chat-message {
97
+ display: flex;
98
+ flex-direction: column;
99
+ justify-content: center;
100
+ /* box-shadow: 0 2px 8px rgba(0, 0, 0, 20%); */
101
+ }
102
+
103
+ </style>
@@ -108,7 +108,6 @@ watch(
108
108
  --t: 30px;
109
109
  /* the size of the tail */
110
110
 
111
- width: 100%;
112
111
  padding: calc(2 * var(--r) / 3);
113
112
  -webkit-mask: radial-gradient(var(--t) at var(--_d) 0, #0000 98%, #000 102%)
114
113
  var(--_d) 100% / calc(100% - var(--r)) var(--t) no-repeat,
@@ -5,6 +5,7 @@
5
5
  >
6
6
  <div
7
7
  id="chat-circle"
8
+ role="button"
8
9
  @click="toggleChat"
9
10
  class="widget-container"
10
11
  v-show="!isChatBoxVisible"
@@ -1,3 +0,0 @@
1
- {
2
- "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
3
- }