thelounge/client/components/MessageSearchForm.vue

157 lines
2.6 KiB
Vue
Raw Normal View History

2019-12-31 16:21:34 +00:00
<template>
<form :class="['message-search', {opened: searchOpened}]" @submit.prevent="searchMessages">
<div class="input-wrapper">
<input
ref="searchInputField"
v-model="searchInput"
type="search"
2019-12-31 16:21:34 +00:00
name="search"
class="input"
placeholder="Search messages…"
2019-12-31 16:21:34 +00:00
@blur="closeSearch"
2021-11-18 21:27:52 +00:00
@keyup.esc="closeSearch"
2019-12-31 16:21:34 +00:00
/>
</div>
<button
v-if="!onSearchPage"
2019-12-31 16:21:34 +00:00
class="search"
type="button"
aria-label="Search messages in this channel"
2020-01-04 18:03:56 +00:00
@mousedown.prevent="toggleSearch"
2019-12-31 16:21:34 +00:00
/>
</form>
</template>
2020-03-07 12:56:50 +00:00
<style>
form.message-search {
display: flex;
}
form.message-search .input-wrapper {
display: flex;
}
form.message-search input {
width: 100%;
height: auto !important;
margin: 7px 0;
border: 0;
color: inherit;
background-color: #fafafa;
appearance: none;
2020-03-07 12:56:50 +00:00
}
form.message-search input::placeholder {
color: rgba(0, 0, 0, 0.35);
2020-03-07 12:56:50 +00:00
}
@media (min-width: 480px) {
form.message-search input {
min-width: 140px;
}
form.message-search input:focus {
min-width: 220px;
}
}
form.message-search .input-wrapper {
position: absolute;
top: 45px;
left: 0;
right: 0;
z-index: 1;
height: 0;
overflow: hidden;
background: var(--window-bg-color);
}
2020-03-07 12:56:50 +00:00
form.message-search .input-wrapper input {
margin: 7px;
}
2020-03-07 12:56:50 +00:00
form.message-search.opened .input-wrapper {
height: 50px;
}
2020-03-07 12:56:50 +00:00
#chat form.message-search button {
display: flex;
color: #607992;
2020-03-07 12:56:50 +00:00
}
</style>
2019-12-31 16:21:34 +00:00
<script>
export default {
name: "MessageSearchForm",
props: {
network: Object,
channel: Object,
},
data() {
return {
searchOpened: false,
searchInput: "",
};
},
computed: {
onSearchPage() {
return this.$route.name === "SearchResults";
},
},
watch: {
"$route.query.q"() {
this.searchInput = this.$route.query.q;
2019-12-31 16:21:34 +00:00
},
},
mounted() {
this.searchInput = this.$route.query.q;
this.searchOpened = this.onSearchPage;
if (!this.searchInput && this.searchOpened) {
this.$refs.searchInputField.focus();
}
},
methods: {
2019-12-31 16:21:34 +00:00
closeSearch() {
if (!this.onSearchPage) {
2021-11-18 21:31:01 +00:00
this.searchInput = "";
this.searchOpened = false;
}
2019-12-31 16:21:34 +00:00
},
2020-01-04 18:03:56 +00:00
toggleSearch() {
2019-12-31 16:21:34 +00:00
if (this.searchOpened) {
2020-01-04 18:03:56 +00:00
this.$refs.searchInputField.blur();
return;
2019-12-31 16:21:34 +00:00
}
2020-01-04 18:03:56 +00:00
this.searchOpened = true;
this.$refs.searchInputField.focus();
2019-12-31 16:21:34 +00:00
},
searchMessages(event) {
event.preventDefault();
if (!this.searchInput) {
return;
}
this.$router
.push({
name: "SearchResults",
params: {
id: this.channel.id,
},
query: {
q: this.searchInput,
},
})
.catch((err) => {
if (err.name === "NavigationDuplicated") {
// Search for the same query again
this.$root.$emit("re-search");
}
});
2019-12-31 16:21:34 +00:00
},
},
};
</script>