Skip to content

Commit 3aba245

Browse files
committed
template text
1 parent d567d13 commit 3aba245

File tree

8 files changed

+229
-38
lines changed

8 files changed

+229
-38
lines changed

demo/src/ChatContainer.vue

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,28 @@
55
<button type="submit" :disabled="disableForm || !addRoomUsername">
66
Create Room
77
</button>
8-
<button class="button-cancel" @click="addNewRoom = false">
9-
Cancel
10-
</button>
8+
<button class="button-cancel" @click="addNewRoom = false">Cancel</button>
119
</form>
1210

1311
<form v-if="inviteRoomId" @submit.prevent="addRoomUser">
1412
<input v-model="invitedUsername" type="text" placeholder="Add username" />
1513
<button type="submit" :disabled="disableForm || !invitedUsername">
1614
Add User
1715
</button>
18-
<button class="button-cancel" @click="inviteRoomId = null">
19-
Cancel
20-
</button>
16+
<button class="button-cancel" @click="inviteRoomId = null">Cancel</button>
2117
</form>
2218

2319
<form v-if="removeRoomId" @submit.prevent="deleteRoomUser">
2420
<select v-model="removeUserId">
25-
<option default value="">
26-
Select User
27-
</option>
21+
<option default value="">Select User</option>
2822
<option v-for="user in removeUsers" :key="user._id" :value="user._id">
2923
{{ user.username }}
3024
</option>
3125
</select>
3226
<button type="submit" :disabled="disableForm || !removeUserId">
3327
Remove User
3428
</button>
35-
<button class="button-cancel" @click="removeRoomId = null">
36-
Cancel
37-
</button>
29+
<button class="button-cancel" @click="removeRoomId = null">Cancel</button>
3830
</form>
3931

4032
<chat-window
@@ -51,6 +43,7 @@
5143
:room-actions="roomActions"
5244
:menu-actions="menuActions"
5345
:room-message="roomMessage"
46+
:templates-text="templatesText"
5447
@fetch-more-rooms="fetchMoreRooms"
5548
@fetch-messages="fetchMessages"
5649
@send-message="sendMessage"
@@ -141,7 +134,21 @@ export default {
141134
{ name: 'removeUser', title: 'Remove User' },
142135
{ name: 'deleteRoom', title: 'Delete Room' }
143136
],
144-
styles: { container: { borderRadius: '4px' } }
137+
styles: { container: { borderRadius: '4px' } },
138+
templatesText: [
139+
{
140+
tag: 'help',
141+
text: 'This is the help'
142+
},
143+
{
144+
tag: 'action',
145+
text: 'this is the action'
146+
},
147+
{
148+
tag: 'action 2',
149+
text: 'this is the second action'
150+
}
151+
]
145152
// ,dbRequestCount: 0
146153
}
147154
},
@@ -502,9 +509,7 @@ export default {
502509
newMessage.files = deleteDbField
503510
}
504511
505-
await messagesRef(roomId)
506-
.doc(messageId)
507-
.update(newMessage)
512+
await messagesRef(roomId).doc(messageId).update(newMessage)
508513
509514
if (files) {
510515
for (let index = 0; index < files.length; index++) {
@@ -516,9 +521,7 @@ export default {
516521
},
517522
518523
async deleteMessage({ message, roomId }) {
519-
await messagesRef(roomId)
520-
.doc(message._id)
521-
.update({ deleted: new Date() })
524+
await messagesRef(roomId).doc(message._id).update({ deleted: new Date() })
522525
523526
const { files } = message
524527
@@ -548,9 +551,7 @@ export default {
548551
await uploadFileRef.put(file.blob, { contentType: type })
549552
const url = await uploadFileRef.getDownloadURL()
550553
551-
const messageDoc = await messagesRef(roomId)
552-
.doc(messageId)
553-
.get()
554+
const messageDoc = await messagesRef(roomId).doc(messageId).get()
554555
555556
const files = messageDoc.data().files
556557
@@ -560,9 +561,7 @@ export default {
560561
}
561562
})
562563
563-
await messagesRef(roomId)
564-
.doc(messageId)
565-
.update({ files })
564+
await messagesRef(roomId).doc(messageId).update({ files })
566565
},
567566
568567
formattedFiles(files) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
"typescript": "^4.0.5",
6969
"vue": "^2.6.14",
7070
"vue-jest": "^3.0.7",
71-
"vue-template-compiler": "^2.6.11"
71+
"vue-template-compiler": "^2.6.14"
7272
},
7373
"peerDependencies": {
7474
"vue": "^2.6.14"

src/lib/ChatWindow.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
:room-info-enabled="roomInfoEnabled"
5555
:textarea-action-enabled="textareaActionEnabled"
5656
:accepted-files="acceptedFiles"
57+
:templates-text="templatesText"
5758
@toggle-rooms-list="toggleRoomsList"
5859
@room-info="roomInfo"
5960
@fetch-messages="fetchMessages"
@@ -138,7 +139,8 @@ export default {
138139
roomInfoEnabled: { type: Boolean, default: false },
139140
textareaActionEnabled: { type: Boolean, default: false },
140141
roomMessage: { type: String, default: '' },
141-
acceptedFiles: { type: String, default: '*' }
142+
acceptedFiles: { type: String, default: '*' },
143+
templatesText: { type: Array, default: null }
142144
},
143145
144146
emits: [

src/lib/Room/Room.vue

Lines changed: 81 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,14 @@
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"
@@ -210,8 +218,14 @@
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">
@@ -264,7 +278,7 @@
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'
298312
import RoomMessageReply from './RoomMessageReply/RoomMessageReply'
299313
import RoomUsersTag from './RoomUsersTag/RoomUsersTag'
300314
import RoomEmojis from './RoomEmojis/RoomEmojis'
315+
import RoomTemplatesText from './RoomTemplatesText/RoomTemplatesText'
301316
import Message from '../Message/Message'
302317
303-
import filteredUsers from '../../utils/filter-items'
318+
import filteredItems from '../../utils/filter-items'
304319
import Recorder from '../../utils/recorder'
305320
306321
const { detectMobile, iOSDevice } = require('../../utils/mobile-detection')
307322
308323
const 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

Comments
 (0)