Skip to content

Commit abf4589

Browse files
committed
(feat) keyboard control over footer items
1 parent d7baa67 commit abf4589

File tree

6 files changed

+130
-35
lines changed

6 files changed

+130
-35
lines changed

src/lib/Room/Room.vue

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -132,20 +132,26 @@
132132
>
133133
<room-emojis
134134
:filtered-emojis="filteredEmojis"
135+
:select-item="selectEmojiItem"
136+
:active-up-or-down="activeUpOrDownEmojis"
135137
@select-emoji="selectEmoji($event)"
138+
@activate-item="activeUpOrDownEmojis = 0"
136139
/>
137140

138141
<room-users-tag
139142
:filtered-users-tag="filteredUsersTag"
143+
:select-item="selectUsersTagItem"
144+
:active-up-or-down="activeUpOrDownUsersTag"
140145
@select-user-tag="selectUserTag($event)"
146+
@activate-item="activeUpOrDownUsersTag = 0"
141147
/>
142148

143149
<room-templates-text
144150
:filtered-templates-text="filteredTemplatesText"
145-
:active-template="activeTemplate"
146-
:active-up-or-down="activeUpOrDown"
151+
:select-item="selectTemplatesTextItem"
152+
:active-up-or-down="activeUpOrDownTemplatesText"
147153
@select-template-text="selectTemplateText($event)"
148-
@active-item="activeUpOrDown = 0"
154+
@activate-item="activeUpOrDownTemplatesText = 0"
149155
/>
150156

151157
<room-message-reply
@@ -218,14 +224,14 @@
218224
}"
219225
@input="onChangeInput"
220226
@keydown.esc="escapeTextarea"
221-
@keydown.enter.exact.prevent="beforeEnter"
227+
@keydown.enter.exact.prevent="selectItem"
222228
@paste="onPasteImage"
223229
@keydown.tab.exact.prevent=""
224-
@keydown.tab="activeTemplate = true"
230+
@keydown.tab="selectItem"
225231
@keydown.up.exact.prevent=""
226-
@keydown.up="upActiveTemplate"
232+
@keydown.up="updateActiveUpOrDown(-1)"
227233
@keydown.down.exact.prevent=""
228-
@keydown.down="downActiveTemplate"
234+
@keydown.down="updateActiveUpOrDown(1)"
229235
/>
230236

231237
<div class="vac-icon-textarea">
@@ -416,8 +422,12 @@ export default {
416422
filteredUsersTag: [],
417423
selectedUsersTag: [],
418424
filteredTemplatesText: [],
419-
activeTemplate: null,
420-
activeUpOrDown: null,
425+
selectEmojiItem: null,
426+
selectUsersTagItem: null,
427+
selectTemplatesTextItem: null,
428+
activeUpOrDownEmojis: null,
429+
activeUpOrDownUsersTag: null,
430+
activeUpOrDownTemplatesText: null,
421431
textareaCursorPosition: null,
422432
cursorRangePosition: null,
423433
emojisDB: new Database(),
@@ -536,7 +546,11 @@ export default {
536546
if (isMobile) {
537547
this.message = this.message + '\n'
538548
setTimeout(() => this.onChangeInput())
539-
} else if (!this.filteredTemplatesText.length) {
549+
} else if (
550+
!this.filteredEmojis.length &&
551+
!this.filteredUsersTag.length &&
552+
!this.filteredTemplatesText.length
553+
) {
540554
this.sendMessage()
541555
}
542556
}
@@ -736,6 +750,10 @@ export default {
736750
this.filteredEmojis = emojis.map(emoji => emoji.unicode)
737751
},
738752
selectEmoji(emoji) {
753+
this.selectEmojiItem = false
754+
755+
if (!emoji) return
756+
739757
const { position, endPosition } = this.getCharPosition(':')
740758
741759
this.message =
@@ -755,6 +773,10 @@ export default {
755773
).filter(user => user._id !== this.currentUserId)
756774
},
757775
selectUserTag(user, editMode = false) {
776+
this.selectUsersTagItem = false
777+
778+
if (!user) return
779+
758780
const { position, endPosition } = this.getCharPosition('@')
759781
760782
const space = this.message.substr(endPosition, endPosition).length
@@ -785,7 +807,7 @@ export default {
785807
)
786808
},
787809
selectTemplateText(template) {
788-
this.activeTemplate = false
810+
this.selectTemplatesTextItem = false
789811
790812
if (!template) return
791813
@@ -806,16 +828,23 @@ export default {
806828
807829
this.focusTextarea()
808830
},
809-
beforeEnter() {
810-
if (this.filteredTemplatesText.length > 0) {
811-
this.activeTemplate = true
831+
updateActiveUpOrDown(direction) {
832+
if (this.filteredEmojis.length) {
833+
this.activeUpOrDownEmojis = direction
834+
} else if (this.filteredUsersTag.length) {
835+
this.activeUpOrDownUsersTag = direction
836+
} else if (this.filteredTemplatesText.length) {
837+
this.activeUpOrDownTemplatesText = direction
812838
}
813839
},
814-
upActiveTemplate() {
815-
this.activeUpOrDown = -1
816-
},
817-
downActiveTemplate() {
818-
this.activeUpOrDown = 1
840+
selectItem() {
841+
if (this.filteredEmojis.length) {
842+
this.selectEmojiItem = true
843+
} else if (this.filteredUsersTag.length) {
844+
this.selectUsersTagItem = true
845+
} else if (this.filteredTemplatesText.length) {
846+
this.selectTemplatesTextItem = true
847+
}
819848
},
820849
resetFooterList(tagChar = null) {
821850
if (tagChar === ':') {

src/lib/Room/RoomEmojis/RoomEmojis.scss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
cursor: pointer;
1414
background: var(--chat-footer-bg-color-tag);
1515
transition: background-color 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
16+
}
1617

17-
&:hover {
18-
background: var(--chat-footer-bg-color-tag-active);
19-
}
18+
.vac-emoji-element-active {
19+
background: var(--chat-footer-bg-color-tag-active);
2020
}
2121
}
2222

src/lib/Room/RoomEmojis/RoomEmojis.vue

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
:style="{ bottom: `${$parent.$refs.roomFooter.clientHeight}px` }"
77
>
88
<div
9-
v-for="emoji in filteredEmojis"
9+
v-for="(emoji, index) in filteredEmojis"
1010
:key="emoji"
1111
class="vac-emoji-element"
12+
:class="{ 'vac-emoji-element-active': index === activeItem }"
13+
@mouseover="activeItem = index"
1214
@click="$emit('select-emoji', emoji)"
1315
>
1416
{{ emoji }}
@@ -22,9 +24,39 @@ export default {
2224
name: 'RoomEmojis',
2325
2426
props: {
25-
filteredEmojis: { type: Array, required: true }
27+
filteredEmojis: { type: Array, required: true },
28+
selectItem: { type: Boolean, default: null },
29+
activeUpOrDown: { type: Number, default: null }
2630
},
2731
28-
emits: ['select-emoji']
32+
emits: ['select-emoji', 'active-item'],
33+
34+
data() {
35+
return {
36+
activeItem: null
37+
}
38+
},
39+
40+
watch: {
41+
filteredEmojis() {
42+
this.activeItem = 0
43+
},
44+
selectItem(val) {
45+
if (val) {
46+
this.$emit('select-emoji', this.filteredEmojis[this.activeItem])
47+
}
48+
},
49+
activeUpOrDown() {
50+
if (
51+
this.activeUpOrDown > 0 &&
52+
this.activeItem < this.filteredEmojis.length - 1
53+
) {
54+
this.activeItem++
55+
} else if (this.activeUpOrDown < 0 && this.activeItem > 0) {
56+
this.activeItem--
57+
}
58+
this.$emit('activate-item')
59+
}
60+
}
2961
}
3062
</script>

src/lib/Room/RoomTemplatesText/RoomTemplatesText.vue

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@
2929
<script>
3030
export default {
3131
name: 'RoomTemplatesText',
32+
3233
props: {
3334
filteredTemplatesText: { type: Array, required: true },
34-
activeTemplate: { type: Boolean, default: null },
35+
selectItem: { type: Boolean, default: null },
3536
activeUpOrDown: { type: Number, default: null }
3637
},
3738
@@ -42,12 +43,13 @@ export default {
4243
activeItem: null
4344
}
4445
},
46+
4547
watch: {
4648
filteredTemplatesText() {
4749
this.activeItem = 0
4850
},
49-
activeTemplate() {
50-
if (this.activeTemplate) {
51+
selectItem(val) {
52+
if (val) {
5153
this.$emit(
5254
'select-template-text',
5355
this.filteredTemplatesText[this.activeItem]
@@ -63,7 +65,7 @@ export default {
6365
} else if (this.activeUpOrDown < 0 && this.activeItem > 0) {
6466
this.activeItem--
6567
}
66-
this.$emit('active-item')
68+
this.$emit('activate-item')
6769
}
6870
}
6971
}

src/lib/Room/RoomUsersTag/RoomUsersTag.scss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
cursor: pointer;
1313
background: var(--chat-footer-bg-color-tag);
1414
transition: background-color 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
15+
}
1516

16-
&:hover {
17-
background: var(--chat-footer-bg-color-tag-active);
18-
}
17+
.vac-tags-box-active {
18+
background: var(--chat-footer-bg-color-tag-active);
1919
}
2020

2121
.vac-tags-info {

src/lib/Room/RoomUsersTag/RoomUsersTag.vue

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
:style="{ bottom: `${$parent.$refs.roomFooter.clientHeight}px` }"
77
>
88
<div
9-
v-for="user in filteredUsersTag"
9+
v-for="(user, index) in filteredUsersTag"
1010
:key="user._id"
1111
class="vac-tags-box"
12+
:class="{ 'vac-tags-box-active': index === activeItem }"
13+
@mouseover="activeItem = index"
1214
@click="$emit('select-user-tag', user)"
1315
>
1416
<div class="vac-tags-info">
@@ -31,9 +33,39 @@ export default {
3133
name: 'RoomUsersTag',
3234
3335
props: {
34-
filteredUsersTag: { type: Array, required: true }
36+
filteredUsersTag: { type: Array, required: true },
37+
selectItem: { type: Boolean, default: null },
38+
activeUpOrDown: { type: Number, default: null }
3539
},
3640
37-
emits: ['select-user-tag']
41+
emits: ['select-user-tag', 'active-item'],
42+
43+
data() {
44+
return {
45+
activeItem: null
46+
}
47+
},
48+
49+
watch: {
50+
filteredUsersTag() {
51+
this.activeItem = 0
52+
},
53+
selectItem(val) {
54+
if (val) {
55+
this.$emit('select-user-tag', this.filteredUsersTag[this.activeItem])
56+
}
57+
},
58+
activeUpOrDown() {
59+
if (
60+
this.activeUpOrDown > 0 &&
61+
this.activeItem < this.filteredUsersTag.length - 1
62+
) {
63+
this.activeItem++
64+
} else if (this.activeUpOrDown < 0 && this.activeItem > 0) {
65+
this.activeItem--
66+
}
67+
this.$emit('activate-item')
68+
}
69+
}
3870
}
3971
</script>

0 commit comments

Comments
 (0)