140140 @select-user-tag =" selectUserTag($event)"
141141 />
142142
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+
143151 <room-message-reply
144152 :room =" room"
145153 :message-reply =" messageReply"
210218 }"
211219 @input =" onChangeInput"
212220 @keydown.esc =" escapeTextarea"
213- @keydown.enter.exact.prevent =" "
221+ @keydown.enter.exact.prevent =" beforeEnter "
214222 @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"
215229 />
216230
217231 <div class =" vac-icon-textarea" >
264278 type =" file"
265279 multiple
266280 :accept =" acceptedFiles"
267- style =" display :none "
281+ style =" display : none "
268282 @change =" onFileChange($event.target.files)"
269283 />
270284
@@ -298,16 +312,17 @@ import RoomFiles from './RoomFiles/RoomFiles'
298312import RoomMessageReply from ' ./RoomMessageReply/RoomMessageReply'
299313import RoomUsersTag from ' ./RoomUsersTag/RoomUsersTag'
300314import RoomEmojis from ' ./RoomEmojis/RoomEmojis'
315+ import RoomTemplatesText from ' ./RoomTemplatesText/RoomTemplatesText'
301316import Message from ' ../Message/Message'
302317
303- import filteredUsers from ' ../../utils/filter-items'
318+ import filteredItems from ' ../../utils/filter-items'
304319import Recorder from ' ../../utils/recorder'
305320
306321const { detectMobile , iOSDevice } = require (' ../../utils/mobile-detection' )
307322
308323const debounce = (func , delay ) => {
309324 let inDebounce
310- return function () {
325+ return function () {
311326 const context = this
312327 const args = arguments
313328 clearTimeout (inDebounce)
@@ -327,6 +342,7 @@ export default {
327342 RoomMessageReply,
328343 RoomUsersTag,
329344 RoomEmojis,
345+ RoomTemplatesText,
330346 Message
331347 },
332348
@@ -360,7 +376,8 @@ export default {
360376 linkOptions: { type: Object , required: true },
361377 loadingRooms: { type: Boolean , required: true },
362378 roomInfoEnabled: { type: Boolean , required: true },
363- textareaActionEnabled: { type: Boolean , required: true }
379+ textareaActionEnabled: { type: Boolean , required: true },
380+ templatesText: { type: Array , default: null }
364381 },
365382
366383 emits: [
@@ -398,6 +415,9 @@ export default {
398415 filteredEmojis: [],
399416 filteredUsersTag: [],
400417 selectedUsersTag: [],
418+ filteredTemplatesText: [],
419+ activeTemplate: null ,
420+ activeUpOrDown: null ,
401421 textareaCursorPosition: null ,
402422 cursorRangePosition: null ,
403423 emojisDB: new Database (),
@@ -442,6 +462,7 @@ export default {
442462 return (
443463 !! this .filteredEmojis .length ||
444464 !! this .filteredUsersTag .length ||
465+ !! this .filteredTemplatesText .length ||
445466 !! this .files .length ||
446467 !! this .messageReply
447468 )
@@ -515,14 +536,15 @@ export default {
515536 if (isMobile) {
516537 this .message = this .message + ' \n '
517538 setTimeout (() => this .onChangeInput ())
518- } else {
539+ } else if ( this . filteredTemplatesText . length === 0 ) {
519540 this .sendMessage ()
520541 }
521542 }
522543
523544 setTimeout (() => {
524545 this .updateFooterList (' @' )
525546 this .updateFooterList (' :' )
547+ this .updateFooterList (' /' )
526548 }, 60 )
527549 }),
528550 50
@@ -533,6 +555,7 @@ export default {
533555
534556 this .updateFooterList (' @' )
535557 this .updateFooterList (' :' )
558+ this .updateFooterList (' /' )
536559 })
537560
538561 this .$refs [' roomTextarea' ].addEventListener (' blur' , () => {
@@ -642,6 +665,10 @@ export default {
642665 return
643666 }
644667
668+ if (tagChar === ' /' && ! this .templatesText ) {
669+ return
670+ }
671+
645672 if (
646673 this .textareaCursorPosition ===
647674 this .$refs [' roomTextarea' ].selectionStart
@@ -676,6 +703,8 @@ export default {
676703 this .updateEmojis (query)
677704 } else if (tagChar === ' @' ) {
678705 this .updateShowUsersTag (query)
706+ } else if (tagChar === ' /' ) {
707+ this .updateShowTemplatesText (query)
679708 }
680709 } else {
681710 this .resetFooterList (tagChar)
@@ -717,7 +746,7 @@ export default {
717746 this .focusTextarea ()
718747 },
719748 updateShowUsersTag (query ) {
720- this .filteredUsersTag = filteredUsers (
749+ this .filteredUsersTag = filteredItems (
721750 this .room .users ,
722751 ' username' ,
723752 query,
@@ -743,22 +772,65 @@ export default {
743772 position + user .username .length + space .length + 1
744773 this .focusTextarea ()
745774 },
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+ },
746813 resetFooterList (tagChar = null ) {
747814 if (tagChar === ' :' ) {
748815 this .filteredEmojis = []
749816 } else if (tagChar === ' @' ) {
750817 this .filteredUsersTag = []
818+ } else if (tagChar === ' /' ) {
819+ this .filteredTemplatesText = []
751820 } else {
752821 this .filteredEmojis = []
753822 this .filteredUsersTag = []
823+ this .filteredTemplatesText = []
754824 }
755825
756826 this .textareaCursorPosition = null
757827 },
758828 escapeTextarea () {
759829 if (this .filteredEmojis .length ) this .filteredEmojis = []
760830 else if (this .filteredUsersTag .length ) this .filteredUsersTag = []
761- else this .resetMessage ()
831+ else if (this .filteredTemplatesText .length ) {
832+ this .filteredTemplatesText = []
833+ } else this .resetMessage ()
762834 },
763835 resetMessage (disableMobileFocus = false , initRoom = false ) {
764836 if (! initRoom) {
@@ -897,7 +969,7 @@ export default {
897969 setTimeout (() => element .classList .remove (' vac-scroll-smooth' ))
898970 }, 50 )
899971 },
900- onChangeInput: debounce (function (e ) {
972+ onChangeInput: debounce (function (e ) {
901973 if (e? .target ? .value ) {
902974 this .message = e .target .value
903975 }
0 commit comments