140
140
@select-user-tag =" selectUserTag($event)"
141
141
/>
142
142
143
+ <room-Templates-Text
144
+ :filtered-templates-text =" filteredTemplatesText"
145
+ :active-template =" activeTemplate"
146
+ :active-up-or-down =" activeUpOrDown"
147
+ @select-template-text =" selectTemplateText($event)"
148
+ @active-item =" activeUpOrDown = 0"
149
+ />
150
+
143
151
<room-message-reply
144
152
:room =" room"
145
153
:message-reply =" messageReply"
210
218
}"
211
219
@input =" onChangeInput"
212
220
@keydown.esc =" escapeTextarea"
213
- @keydown.enter.exact.prevent =" "
221
+ @keydown.enter.exact.prevent =" beforeEnter "
214
222
@paste =" onPasteImage"
223
+ @keydown.tab.exact.prevent =" "
224
+ @keydown.tab =" activeTemplate = true"
225
+ @keydown.up.exact.prevent =" "
226
+ @keydown.up =" upActiveTemplate"
227
+ @keydown.down.exact.prevent =" "
228
+ @keydown.down =" downActiveTemplate"
215
229
/>
216
230
217
231
<div class =" vac-icon-textarea" >
264
278
type =" file"
265
279
multiple
266
280
:accept =" acceptedFiles"
267
- style =" display :none "
281
+ style =" display : none "
268
282
@change =" onFileChange($event.target.files)"
269
283
/>
270
284
@@ -298,16 +312,17 @@ import RoomFiles from './RoomFiles/RoomFiles'
298
312
import RoomMessageReply from ' ./RoomMessageReply/RoomMessageReply'
299
313
import RoomUsersTag from ' ./RoomUsersTag/RoomUsersTag'
300
314
import RoomEmojis from ' ./RoomEmojis/RoomEmojis'
315
+ import RoomTemplatesText from ' ./RoomTemplatesText/RoomTemplatesText'
301
316
import Message from ' ../Message/Message'
302
317
303
- import filteredUsers from ' ../../utils/filter-items'
318
+ import filteredItems from ' ../../utils/filter-items'
304
319
import Recorder from ' ../../utils/recorder'
305
320
306
321
const { detectMobile , iOSDevice } = require (' ../../utils/mobile-detection' )
307
322
308
323
const debounce = (func , delay ) => {
309
324
let inDebounce
310
- return function () {
325
+ return function () {
311
326
const context = this
312
327
const args = arguments
313
328
clearTimeout (inDebounce)
@@ -327,6 +342,7 @@ export default {
327
342
RoomMessageReply,
328
343
RoomUsersTag,
329
344
RoomEmojis,
345
+ RoomTemplatesText,
330
346
Message
331
347
},
332
348
@@ -360,7 +376,8 @@ export default {
360
376
linkOptions: { type: Object , required: true },
361
377
loadingRooms: { type: Boolean , required: true },
362
378
roomInfoEnabled: { type: Boolean , required: true },
363
- textareaActionEnabled: { type: Boolean , required: true }
379
+ textareaActionEnabled: { type: Boolean , required: true },
380
+ templatesText: { type: Array , default: null }
364
381
},
365
382
366
383
emits: [
@@ -398,6 +415,9 @@ export default {
398
415
filteredEmojis: [],
399
416
filteredUsersTag: [],
400
417
selectedUsersTag: [],
418
+ filteredTemplatesText: [],
419
+ activeTemplate: null ,
420
+ activeUpOrDown: null ,
401
421
textareaCursorPosition: null ,
402
422
cursorRangePosition: null ,
403
423
emojisDB: new Database (),
@@ -442,6 +462,7 @@ export default {
442
462
return (
443
463
!! this .filteredEmojis .length ||
444
464
!! this .filteredUsersTag .length ||
465
+ !! this .filteredTemplatesText .length ||
445
466
!! this .files .length ||
446
467
!! this .messageReply
447
468
)
@@ -515,14 +536,15 @@ export default {
515
536
if (isMobile) {
516
537
this .message = this .message + ' \n '
517
538
setTimeout (() => this .onChangeInput ())
518
- } else {
539
+ } else if ( this . filteredTemplatesText . length === 0 ) {
519
540
this .sendMessage ()
520
541
}
521
542
}
522
543
523
544
setTimeout (() => {
524
545
this .updateFooterList (' @' )
525
546
this .updateFooterList (' :' )
547
+ this .updateFooterList (' /' )
526
548
}, 60 )
527
549
}),
528
550
50
@@ -533,6 +555,7 @@ export default {
533
555
534
556
this .updateFooterList (' @' )
535
557
this .updateFooterList (' :' )
558
+ this .updateFooterList (' /' )
536
559
})
537
560
538
561
this .$refs [' roomTextarea' ].addEventListener (' blur' , () => {
@@ -642,6 +665,10 @@ export default {
642
665
return
643
666
}
644
667
668
+ if (tagChar === ' /' && ! this .templatesText ) {
669
+ return
670
+ }
671
+
645
672
if (
646
673
this .textareaCursorPosition ===
647
674
this .$refs [' roomTextarea' ].selectionStart
@@ -676,6 +703,8 @@ export default {
676
703
this .updateEmojis (query)
677
704
} else if (tagChar === ' @' ) {
678
705
this .updateShowUsersTag (query)
706
+ } else if (tagChar === ' /' ) {
707
+ this .updateShowTemplatesText (query)
679
708
}
680
709
} else {
681
710
this .resetFooterList (tagChar)
@@ -717,7 +746,7 @@ export default {
717
746
this .focusTextarea ()
718
747
},
719
748
updateShowUsersTag (query ) {
720
- this .filteredUsersTag = filteredUsers (
749
+ this .filteredUsersTag = filteredItems (
721
750
this .room .users ,
722
751
' username' ,
723
752
query,
@@ -743,22 +772,65 @@ export default {
743
772
position + user .username .length + space .length + 1
744
773
this .focusTextarea ()
745
774
},
775
+ updateShowTemplatesText (query ) {
776
+ this .filteredTemplatesText = filteredItems (
777
+ this .templatesText ,
778
+ ' tag' ,
779
+ query,
780
+ true
781
+ )
782
+ },
783
+ selectTemplateText (template ) {
784
+ this .activeTemplate = false
785
+ if (! template) return
786
+ const { position , endPosition } = this .getCharPosition (' /' )
787
+
788
+ const space = this .message .substr (endPosition, endPosition).length
789
+ ? ' '
790
+ : ' '
791
+
792
+ this .message =
793
+ this .message .substr (0 , position - 1 ) +
794
+ template .text +
795
+ space +
796
+ this .message .substr (endPosition, this .message .length - 1 )
797
+
798
+ this .cursorRangePosition =
799
+ position + template .text .length + space .length + 1
800
+ this .focusTextarea ()
801
+ },
802
+ beforeEnter () {
803
+ if (this .filteredTemplatesText .length > 0 ) {
804
+ this .activeTemplate = true
805
+ }
806
+ },
807
+ upActiveTemplate () {
808
+ this .activeUpOrDown = - 1
809
+ },
810
+ downActiveTemplate () {
811
+ this .activeUpOrDown = 1
812
+ },
746
813
resetFooterList (tagChar = null ) {
747
814
if (tagChar === ' :' ) {
748
815
this .filteredEmojis = []
749
816
} else if (tagChar === ' @' ) {
750
817
this .filteredUsersTag = []
818
+ } else if (tagChar === ' /' ) {
819
+ this .filteredTemplatesText = []
751
820
} else {
752
821
this .filteredEmojis = []
753
822
this .filteredUsersTag = []
823
+ this .filteredTemplatesText = []
754
824
}
755
825
756
826
this .textareaCursorPosition = null
757
827
},
758
828
escapeTextarea () {
759
829
if (this .filteredEmojis .length ) this .filteredEmojis = []
760
830
else if (this .filteredUsersTag .length ) this .filteredUsersTag = []
761
- else this .resetMessage ()
831
+ else if (this .filteredTemplatesText .length ) {
832
+ this .filteredTemplatesText = []
833
+ } else this .resetMessage ()
762
834
},
763
835
resetMessage (disableMobileFocus = false , initRoom = false ) {
764
836
if (! initRoom) {
@@ -897,7 +969,7 @@ export default {
897
969
setTimeout (() => element .classList .remove (' vac-scroll-smooth' ))
898
970
}, 50 )
899
971
},
900
- onChangeInput: debounce (function (e ) {
972
+ onChangeInput: debounce (function (e ) {
901
973
if (e? .target ? .value ) {
902
974
this .message = e .target .value
903
975
}
0 commit comments