Add hover selection to user list.

This commit is contained in:
Richard Lewis 2018-07-11 02:25:21 +03:00 committed by Pavel Djundik
parent 060097c118
commit c431ac6306
4 changed files with 37 additions and 26 deletions

View file

@ -28,6 +28,7 @@
<template v-if="userSearchInput.length > 0"> <template v-if="userSearchInput.length > 0">
<UsernameFiltered <UsernameFiltered
v-for="user in users" v-for="user in users"
:onHover="hoverUser"
:key="user.original.nick" :key="user.original.nick"
:active="user.original === activeUser" :active="user.original === activeUser"
:user="user"/> :user="user"/>
@ -35,6 +36,7 @@
<template v-else> <template v-else>
<Username <Username
v-for="user in users" v-for="user in users"
:onHover="hoverUser"
:key="user.nick" :key="user.nick"
:active="user === activeUser" :active="user === activeUser"
:user="user"/> :user="user"/>
@ -75,19 +77,24 @@ export default {
}; };
}, },
computed: { computed: {
// filteredUsers is computed, to avoid unnecessary filtering
// as it is shared between filtering and keybindings.
filteredUsers() {
return fuzzy.filter(
this.userSearchInput,
this.channel.users,
{
pre: "<b>",
post: "</b>",
extract: (u) => u.nick,
}
);
},
groupedUsers() { groupedUsers() {
const groups = {}; const groups = {};
if (this.userSearchInput) { if (this.userSearchInput) {
const result = fuzzy.filter( const result = this.filteredUsers;
this.userSearchInput,
this.channel.users,
{
pre: "<b>",
post: "</b>",
extract: (u) => u.nick,
}
);
for (const user of result) { for (const user of result) {
if (!groups[user.original.mode]) { if (!groups[user.original.mode]) {
@ -131,21 +138,15 @@ export default {
}); });
el.dispatchEvent(ev); el.dispatchEvent(ev);
}, },
hoverUser(user) {
this.activeUser = user;
},
navigateUserList(direction) { navigateUserList(direction) {
let users = this.channel.users; let users = this.channel.users;
// If a search is active, get the matching user objects // Only using filteredUsers when we have to avoids filtering when it's not needed
// TODO: this could probably be cached via `computed`
// to avoid refiltering on each keypress
if (this.userSearchInput) { if (this.userSearchInput) {
const results = fuzzy.filter( users = this.filteredUsers.map((result) => result.original);
this.userSearchInput,
this.channel.users,
{
extract: (u) => u.nick,
}
);
users = results.map((result) => result.original);
} }
// Bail out if there's no users to select // Bail out if there's no users to select

View file

@ -2,7 +2,9 @@
<span <span
:class="['user', $options.filters.colorClass(user.nick), active ? 'active' : '']" :class="['user', $options.filters.colorClass(user.nick), active ? 'active' : '']"
:data-name="user.nick" :data-name="user.nick"
role="button">{{ user.mode }}{{ user.nick }}</span> role="button">{{ user.mode }}{{ user.nick }}
@mouseover="hover"
></span>
</template> </template>
<script> <script>
@ -11,6 +13,12 @@ export default {
props: { props: {
user: Object, user: Object,
active: Boolean, active: Boolean,
onHover: Function,
},
methods: {
hover() {
this.onHover ? this.onHover(this.user) : null;
},
}, },
}; };
</script> </script>

View file

@ -2,6 +2,7 @@
<span <span
:class="['user', $options.filters.colorClass(user.original.nick), active ? 'active' : '']" :class="['user', $options.filters.colorClass(user.original.nick), active ? 'active' : '']"
:data-name="user.original.nick" :data-name="user.original.nick"
@mouseover="hover"
role="button" role="button"
v-html="user.original.mode + user.string"/> v-html="user.original.mode + user.string"/>
</template> </template>
@ -12,6 +13,12 @@ export default {
props: { props: {
user: Object, user: Object,
active: Boolean, active: Boolean,
onHover: Function,
},
methods: {
hover() {
this.onHover ? this.onHover(this.user.original) : null;
},
}, },
}; };
</script> </script>

View file

@ -20,11 +20,6 @@ Vue.filter("friendlysize", friendlysize);
Vue.filter("colorClass", colorClass); Vue.filter("colorClass", colorClass);
Vue.filter("roundBadgeNumber", roundBadgeNumber); Vue.filter("roundBadgeNumber", roundBadgeNumber);
Vue.config.keyCodes = {
"page-up": 33,
"page-down": 34,
};
const vueApp = new Vue({ const vueApp = new Vue({
el: "#viewport", el: "#viewport",
data: { data: {