From c116721684f39a047effc7996bc4341a6cbd32e9 Mon Sep 17 00:00:00 2001 From: Jeremy Roman Date: Sun, 19 Sep 2021 22:51:17 +0000 Subject: [PATCH] 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. --- src/components/modals/RoleModal.vue | 83 +++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 17 deletions(-) diff --git a/src/components/modals/RoleModal.vue b/src/components/modals/RoleModal.vue index eadde8c..f488d87 100644 --- a/src/components/modals/RoleModal.vue +++ b/src/components/modals/RoleModal.vue @@ -1,5 +1,5 @@ @@ -73,13 +70,22 @@ export default { availableRoles.push({}); 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("players", ["players"]), ...mapState(["otherTravelers"]) }, data() { return { - tab: "editionRoles" + tab: "editionRoles", + query: "" }; }, methods: { @@ -100,14 +106,39 @@ export default { value: role }); } - this.tab = "editionRoles"; + this.reset(); this.$store.commit("toggleModal", "role"); }, close() { - this.tab = "editionRoles"; + this.reset(); 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"]) + }, + watch: { + isDisplayed(shown) { + if (shown) this.$nextTick(() => this.$refs.searchInput.focus()); + } } }; @@ -140,9 +171,27 @@ ul.tokens li { transform: scale(1.2); z-index: 10; } + &:not(.match) { + opacity: 0.4; + } } #townsquare.spectator ul.tokens li.traveler { 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; + } +}