mirror of
https://github.com/bra1n/townsquare.git
synced 2025-04-04 22:24:36 +00:00
Add a search function to the role modal.
When assigning a role to a player, it is now possible to type a case- and whitespace-insensitive prefix of it to quickly find the desired role. Pressing Enter will set the role, if the query is specific enough to have a unique match.
This commit is contained in:
parent
c00b89824c
commit
c116721684
1 changed files with 66 additions and 17 deletions
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<Modal v-if="modals.role && availableRoles.length" @close="close">
|
<Modal v-if="isDisplayed" @close="close">
|
||||||
<h3>
|
<h3>
|
||||||
Choose a new character for
|
Choose a new character for
|
||||||
{{
|
{{
|
||||||
|
@ -8,20 +8,10 @@
|
||||||
: "bluffing"
|
: "bluffing"
|
||||||
}}
|
}}
|
||||||
</h3>
|
</h3>
|
||||||
<ul class="tokens" v-if="tab === 'editionRoles' || !otherTravelers.size">
|
<ul class="tokens">
|
||||||
<li
|
<li
|
||||||
v-for="role in availableRoles"
|
v-for="role in displayedRoles"
|
||||||
:class="[role.team]"
|
:class="[role.team, { match: queryMatches(role.name) }]"
|
||||||
:key="role.id"
|
|
||||||
@click="setRole(role)"
|
|
||||||
>
|
|
||||||
<Token :role="role" />
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="tokens" v-if="tab === 'otherTravelers' && otherTravelers.size">
|
|
||||||
<li
|
|
||||||
v-for="role in otherTravelers.values()"
|
|
||||||
:class="[role.team]"
|
|
||||||
:key="role.id"
|
:key="role.id"
|
||||||
@click="setRole(role)"
|
@click="setRole(role)"
|
||||||
>
|
>
|
||||||
|
@ -45,6 +35,13 @@
|
||||||
>Other Travelers</span
|
>Other Travelers</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
<input
|
||||||
|
ref="searchInput"
|
||||||
|
class="role-search"
|
||||||
|
placeholder="Search"
|
||||||
|
v-model="query"
|
||||||
|
@keyup="keyup"
|
||||||
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -73,13 +70,22 @@ export default {
|
||||||
availableRoles.push({});
|
availableRoles.push({});
|
||||||
return availableRoles;
|
return availableRoles;
|
||||||
},
|
},
|
||||||
|
isDisplayed() {
|
||||||
|
return this.modals.role && this.availableRoles.length;
|
||||||
|
},
|
||||||
|
displayedRoles() {
|
||||||
|
if (this.tab === "editionRoles" || !this.otherTravelers.size)
|
||||||
|
return this.availableRoles;
|
||||||
|
else return [...this.otherTravelers.values()];
|
||||||
|
},
|
||||||
...mapState(["modals", "roles", "session"]),
|
...mapState(["modals", "roles", "session"]),
|
||||||
...mapState("players", ["players"]),
|
...mapState("players", ["players"]),
|
||||||
...mapState(["otherTravelers"])
|
...mapState(["otherTravelers"])
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tab: "editionRoles"
|
tab: "editionRoles",
|
||||||
|
query: ""
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -100,14 +106,39 @@ export default {
|
||||||
value: role
|
value: role
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.tab = "editionRoles";
|
this.reset();
|
||||||
this.$store.commit("toggleModal", "role");
|
this.$store.commit("toggleModal", "role");
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
this.tab = "editionRoles";
|
this.reset();
|
||||||
this.toggleModal("role");
|
this.toggleModal("role");
|
||||||
},
|
},
|
||||||
|
reset() {
|
||||||
|
this.tab = "editionRoles";
|
||||||
|
this.query = "";
|
||||||
|
},
|
||||||
|
queryMatches(name) {
|
||||||
|
const simplify = str => str.replaceAll(/\W+/g, "").toLowerCase();
|
||||||
|
return simplify(name || "").startsWith(simplify(this.query));
|
||||||
|
},
|
||||||
|
keyup(event) {
|
||||||
|
// Allow Escape for modal dialog dismissal.
|
||||||
|
if (event.key == "Esc" || event.key == "Escape") return;
|
||||||
|
|
||||||
|
event.stopPropagation();
|
||||||
|
if (event.key == "Enter") {
|
||||||
|
const matchingRoles = this.displayedRoles.filter(r =>
|
||||||
|
this.queryMatches(r.name)
|
||||||
|
);
|
||||||
|
if (matchingRoles.length === 1) this.setRole(matchingRoles[0]);
|
||||||
|
}
|
||||||
|
},
|
||||||
...mapMutations(["toggleModal"])
|
...mapMutations(["toggleModal"])
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
isDisplayed(shown) {
|
||||||
|
if (shown) this.$nextTick(() => this.$refs.searchInput.focus());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -140,9 +171,27 @@ ul.tokens li {
|
||||||
transform: scale(1.2);
|
transform: scale(1.2);
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
&:not(.match) {
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#townsquare.spectator ul.tokens li.traveler {
|
#townsquare.spectator ul.tokens li.traveler {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input.role-search {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
background: transparent;
|
||||||
|
border: solid white;
|
||||||
|
border-width: 0 0 1px 0;
|
||||||
|
outline: none;
|
||||||
|
color: white;
|
||||||
|
font-size: 1em;
|
||||||
|
|
||||||
|
&:not(:focus) {
|
||||||
|
border-bottom-color: #777;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Add table
Reference in a new issue