vue-wiguet-chatweb 0.1.37 → 0.1.38

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.1.37",
3
+ "version": "0.1.38",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -1,35 +1,61 @@
1
1
  <template>
2
2
  <div class="widget">
3
- <div class="header-widget">
3
+ <div class="header-widget flex-0">
4
4
  <h4 class="title-chat">{{ titlePrincipal }}</h4>
5
5
  <button @click="() => toggleChat()" class="btn-close">
6
6
  <IconClose class="pointer" />
7
7
  </button>
8
8
  </div>
9
- <div class="messages-container" ref="messageContainerRef">
10
- <div class="loader" v-if="isLoading">
11
- <Loader />
12
- </div>
13
- <MessageList
14
- v-if="messagesData.data.length > 0"
15
- :messages="messagesData.data"
16
- :canLoadMoreMessages="messagesData.canLoadMoreMessages"
17
- @loadMore="getMessages"
18
- @retry="retryMessage"
19
- @on-qualifying="(args) => onQualifying(args)"
20
- @see="(message: Message) => {
21
- currentDialogView = DIALOG_VIEWS.SEE
22
- urlFileMessage = message.urlFile
23
- dialog.title = 'Imagen'
24
- dialog.modelValue = true
25
- }"
26
- />
27
- <div class="fit" v-else>
28
- <span class="center">No tienes mensajes</span>
9
+
10
+ <div class="flex-1" style="position: relative; height: 0;">
11
+ <div
12
+ ref="dropZoneRef"
13
+ @drop.self.prevent="
14
+ (e) => {
15
+ dropHandler(e);
16
+ (e.target as HTMLElement)?.classList?.remove('drop-over');
17
+ (e.target as HTMLElement).style.zIndex = '-1';
18
+ }
19
+ "
20
+ @dragenter.self="
21
+ (e) => {
22
+ (e.target as HTMLElement)?.classList?.add('drop-over');
23
+ }
24
+ "
25
+ @dragleave.self="
26
+ (e) => {
27
+ (e.target as HTMLElement)?.classList?.remove('drop-over');
28
+ (e.target as HTMLElement).style.zIndex = '-1';
29
+ }
30
+ "
31
+ @dragover.prevent
32
+ style="position: absolute; bottom: 0; left: 0; right: 0; top: 0; z-index: -1;"
33
+ ></div>
34
+ <div class="messages-container" ref="messageContainerRef" @dragenter.prevent="dropZoneRef!.style.zIndex = '1'">
35
+ <div class="loader" v-if="isLoading">
36
+ <Loader />
37
+ </div>
38
+ <MessageList
39
+ v-if="messagesData.data.length > 0"
40
+ :messages="messagesData.data"
41
+ :canLoadMoreMessages="messagesData.canLoadMoreMessages"
42
+ @loadMore="getMessages"
43
+ @retry="retryMessage"
44
+ @on-qualifying="(args) => onQualifying(args)"
45
+ @see="(message: Message) => {
46
+ currentDialogView = DIALOG_VIEWS.SEE
47
+ urlFileMessage = message.urlFile
48
+ dialog.title = 'Imagen'
49
+ dialog.modelValue = true
50
+ }"
51
+ />
52
+ <div class="fit" v-else>
53
+ <span class="center">No tienes mensajes</span>
54
+ </div>
29
55
  </div>
30
56
  </div>
31
57
 
32
- <div class="w-full">
58
+ <div class="w-full flex-0">
33
59
  <form v-if="!isDisabledBoxMessage" class="message-send" @submit.prevent="(event) => submitMessage()">
34
60
  <div class="form-message">
35
61
  <div class="jl-inputgroup-chat">
@@ -46,6 +72,7 @@
46
72
  }
47
73
  "
48
74
  @keyup.enter="saltoDeLineaOEnviar"
75
+ @paste.prevent="handlePaste"
49
76
  />
50
77
 
51
78
  <input
@@ -84,7 +111,7 @@
84
111
 
85
112
  <ODialog v-bind="dialog">
86
113
  <div v-if="currentDialogView === DIALOG_VIEWS.UPLOAD" class="flex flex-col justify-center items-center">
87
- <img v-for="(urlFile, i) in urlFiles" :key="i" :src="urlFile.toString()" alt="Image" width="400" />
114
+ <img v-for="(urlFile, i) in urlFilesPreview" :key="i" :src="urlFile.toString()" alt="Image" width="400" />
88
115
 
89
116
  <form
90
117
  class="message-send"
@@ -176,6 +203,7 @@ const notViewed = ref(0);
176
203
  const fileInputRef = ref();
177
204
  const currentDialogView = ref(DIALOG_VIEWS.SEE)
178
205
  const urlFileMessage = ref<string>()
206
+ const dropZoneRef = ref<InstanceType<typeof HTMLElement>>();
179
207
 
180
208
  const messagesData = ref<{ data: Message[]; canLoadMoreMessages: boolean }>({
181
209
  data: [],
@@ -291,7 +319,7 @@ function createMessage(message: string, codigoTipoMensaje?: TypeMessageTypeCodes
291
319
  createdAt: new Date().toISOString(),
292
320
  updatedAt: new Date().toISOString(),
293
321
  file: inputFiles.value?.[0],
294
- urlFile: urlFiles.value?.[0],
322
+ urlFile: urlFilesPreview.value?.[0],
295
323
  messageType,
296
324
  sender: {
297
325
  nombreCompleto: props.user.nombreCompleto,
@@ -583,10 +611,11 @@ function onQualifying({ message: messageParam, emoji }: { message: Message, emoj
583
611
 
584
612
  const isDisabledBoxMessage = ref(false);
585
613
 
614
+ const tiposArchivosPermitidos = ['image/png', 'image/jpeg', 'image/jpg', 'image/webp'];
586
615
  // Adjuntar
587
616
  function onFileSelect() {
588
617
  inputFiles.value = [];
589
- urlFiles.value = [];
618
+ urlFilesPreview.value = [];
590
619
 
591
620
  const filesParam: File[] = Array.from(fileInputRef.value?.files) ?? []
592
621
 
@@ -596,7 +625,7 @@ function onFileSelect() {
596
625
 
597
626
  if (!file) return;
598
627
 
599
- if (!(['image/png','image/jpeg','image/jpg','image/webp'].includes(file.type))) {
628
+ if (!(tiposArchivosPermitidos.includes(file.type))) {
600
629
  emit('show-toast', {
601
630
  severity: "warn",
602
631
  summary: "Error",
@@ -616,10 +645,10 @@ function onFileSelect() {
616
645
  return
617
646
  }
618
647
 
619
- urlFiles.value.push(URL.createObjectURL(file))
648
+ urlFilesPreview.value.push(URL.createObjectURL(file))
620
649
 
621
650
  currentDialogView.value = DIALOG_VIEWS.UPLOAD;
622
- dialog.title = 'Preparar imagen';
651
+ dialog.title = 'Vista previa';
623
652
  dialog.modelValue = true;
624
653
 
625
654
  nextTick(()=>{
@@ -627,10 +656,69 @@ function onFileSelect() {
627
656
  })
628
657
  }
629
658
 
659
+
660
+ const handlePaste = (e: ClipboardEvent) => {
661
+ const files = e.clipboardData?.files ?? (window as any).clipboardData?.files ?? [];
662
+
663
+ if (files.length === 0) return;
664
+
665
+ const file = files?.[0];
666
+
667
+ if (!file) return;
668
+
669
+ if (!tiposArchivosPermitidos.includes(file?.type)) return;
670
+
671
+ currentDialogView.value = DIALOG_VIEWS.UPLOAD;
672
+ urlFilesPreview.value = [];
673
+
674
+ inputFiles.value = [file];
675
+ urlFilesPreview.value.push(URL.createObjectURL(file));
676
+ dialog.modelValue = true;
677
+
678
+ nextTick(()=>{
679
+ textAreaRef.value?.focus()
680
+ })
681
+ };
682
+
683
+ function dropHandler(ev: DragEvent) {
684
+ if (!ev.dataTransfer?.items) return;
685
+
686
+ currentDialogView.value = DIALOG_VIEWS.UPLOAD;
687
+
688
+ Array.from(ev.dataTransfer.items).forEach((item) => {
689
+ if (item.kind === 'file') {
690
+ const file = item.getAsFile();
691
+
692
+ if (!file) return;
693
+
694
+ if (!tiposArchivosPermitidos.includes(file.type)) {
695
+ emit('show-toast',{
696
+ severity: 'error',
697
+ summary: 'Error',
698
+ detail: 'El archivo debe ser una imagen',
699
+ life: 5000,
700
+ });
701
+
702
+ return;
703
+ }
704
+
705
+ inputFiles.value = [file];
706
+
707
+ urlFilesPreview.value = [];
708
+ urlFilesPreview.value.push(URL.createObjectURL(file));
709
+ dialog.modelValue = true;
710
+ }
711
+ });
712
+
713
+ nextTick(()=>{
714
+ textAreaRef.value?.focus()
715
+ })
716
+ }
717
+
630
718
  // Dialog
631
719
 
632
720
  const inputFiles = ref<File[]>([]);
633
- const urlFiles = ref<Array<string>>([]);
721
+ const urlFilesPreview = ref<Array<string>>([]);
634
722
 
635
723
  const dialog = reactive<IPropsDialog>({
636
724
  modelValue: false,
@@ -639,7 +727,7 @@ const dialog = reactive<IPropsDialog>({
639
727
 
640
728
  if (args) return;
641
729
 
642
- urlFiles.value = [];
730
+ urlFilesPreview.value = [];
643
731
  inputFiles.value = [];
644
732
  },
645
733
  title: 'Preparar imagen'
@@ -690,6 +778,7 @@ onUnmounted(() => {
690
778
 
691
779
  .messages-container {
692
780
  position: relative;
781
+ height: 100%;
693
782
  }
694
783
  .loader {
695
784
  position: absolute;
@@ -716,4 +805,8 @@ onUnmounted(() => {
716
805
  margin: 1.5rem;
717
806
  text-align: center;
718
807
  }
808
+
809
+ .drop-over {
810
+ border: 2px dashed #007bff !important;
811
+ }
719
812
  </style>