rewrite search for mobile

This commit is contained in:
hay-kot 2021-04-25 12:50:28 -08:00
commit 953dde4afc
6 changed files with 112 additions and 77 deletions

View file

@ -35,14 +35,6 @@ export default {
},
},
async created() {
window.addEventListener("keyup", e => {
if (e.key == "/" && !document.activeElement.id.startsWith("input")) {
this.search = !this.search;
}
});
},
async mounted() {
this.$store.dispatch("initTheme");
this.$store.dispatch("requestRecentRecipes");

View file

@ -1,29 +1,49 @@
<template>
<v-menu v-model="menuModel" offset-y readonly :width="maxWidth">
<v-menu
v-model="menuModel"
readonly
offset-y
offset-overflow
max-height="75vh"
>
<template #activator="{ attrs }">
<v-text-field
class="mt-6"
ref="searchInput"
class="my-auto pt-1"
v-model="search"
v-bind="attrs"
:dense="dense"
light
:label="$t('search.search-mealie')"
autofocus
dark
flat
:placeholder="$t('search.search-mealie')"
background-color="primary lighten-1"
color="white"
:solo="solo"
:style="`max-width: ${maxWidth};`"
@focus="onFocus"
@blur="isFocused = false"
autocomplete="off"
:autofocus="autofocus"
>
<template #prepend-inner>
<v-icon color="grey lighten-3" size="29">
mdi-magnify
</v-icon>
</template>
</v-text-field>
</template>
<v-card v-if="showResults" max-height="500" :max-width="maxWidth">
<v-card
v-if="showResults"
max-height="75vh"
:max-width="maxWidth"
scrollable
>
<v-card-text class="flex row mx-auto ">
<div class="mr-auto">
Results
</div>
<router-link to="/search">
Advanced Search
</router-link>
<router-link to="/search"> Advanced Search </router-link>
</v-card-text>
<v-divider></v-divider>
<v-list scrollable v-if="autoResults">
@ -77,21 +97,21 @@ export default {
navOnClick: {
default: true,
},
resetSearch: {
default: false,
},
solo: {
default: true,
},
autofocus: {
default: false,
},
},
data() {
return {
isFocused: false,
searchSlug: "",
search: "",
menuModel: false,
result: [],
fuseResults: [],
isDark: false,
options: {
shouldSort: true,
threshold: 0.6,
@ -105,8 +125,10 @@ export default {
};
},
mounted() {
this.isDark = this.$store.getters.getIsDark;
this.$store.dispatch("requestAllRecipes");
document.addEventListener("keydown", this.onDocumentKeydown);
},
beforeDestroy() {
document.removeEventListener("keydown", this.onDocumentKeydown);
},
computed: {
data() {
@ -124,11 +146,7 @@ export default {
},
watch: {
isSearching(val) {
val ? (this.menuModel = true) : null;
},
resetSearch(val) {
val ? (this.search = "") : null;
val ? (this.menuModel = true) : this.resetSearch();
},
search() {
@ -167,9 +185,26 @@ export default {
this.$emit("selected", slug, name);
},
async onFocus() {
clearTimeout(this.timeout);
this.$store.dispatch("requestAllRecipes");
this.isFocused = true;
},
resetSearch() {
this.$nextTick(() => {
this.search = "";
this.isFocused = false;
this.menuModel = false;
});
},
onDocumentKeydown(e) {
if (
e.key === "/" &&
e.target !== this.$refs.searchInput.$refs.input &&
!document.activeElement.id.startsWith("input")
) {
e.preventDefault();
this.$refs.searchInput.focus();
}
},
},
};
</script>
@ -181,4 +216,9 @@ export default {
</style>
<style lang="sass" scoped>
.v-menu__content
width: 100
&, & > *
display: flex
flex-direction: column
</style>

View file

@ -1,22 +1,29 @@
<template>
<div class="text-center ">
<v-dialog v-model="dialog" width="600px" height="0" :fullscreen="isMobile">
<v-dialog
v-model="dialog"
width="600px"
height="0"
:fullscreen="isMobile"
content-class="top-dialog"
>
<v-card>
<v-app-bar dark color="primary">
<v-toolbar-title class="headline">Search a Recipe</v-toolbar-title>
</v-app-bar>
<v-card-text>
<v-app-bar dark color="primary lighten-1" rounded="0">
<SearchBar
ref="mealSearchBar"
@results="updateResults"
@selected="emitSelect"
:show-results="!isMobile"
max-width="550px"
max-width="568"
:dense="false"
:nav-on-click="false"
:reset-search="dialog"
:solo="false"
:autofocus="true"
/>
<div v-if="isMobile">
<v-btn icon @click="dialog = false" class="mt-1">
<v-icon> mdi-close </v-icon>
</v-btn>
</v-app-bar>
<v-card-text v-if="isMobile">
<div v-for="recipe in searchResults.slice(0, 7)" :key="recipe.name">
<MobileRecipeCard
class="ma-1 px-0"
@ -29,7 +36,6 @@
@selected="dialog = false"
/>
</div>
</div>
</v-card-text>
</v-card>
</v-dialog>
@ -74,11 +80,12 @@ export default {
},
open() {
this.dialog = true;
this.$router.push("#mobile-search");
this.$refs.mealSearchBar.resetSearch();
this.$router.push("#search");
},
toggleDialog(open) {
if (open) {
this.$router.push("#mobile-search");
this.$router.push("#search");
} else {
this.$router.back(); // 😎 back button click
}
@ -92,4 +99,8 @@ export default {
align-items: flex-start;
justify-content: flex-start;
}
.top-dialog {
align-self: flex-start;
}
</style>

View file

@ -13,7 +13,7 @@
<v-btn icon @click="openSidebar">
<v-icon> mdi-menu </v-icon>
</v-btn>
<router-link v-if="!(isMobile && search)" to="/">
<router-link to="/">
<v-btn icon>
<v-icon size="40"> mdi-silverware-variant </v-icon>
</v-btn>
@ -26,18 +26,18 @@
</div>
<v-spacer></v-spacer>
<v-expand-x-transition>
<SearchBar
ref="mainSearchBar"
v-if="search"
v-if="!isMobile"
:show-results="true"
@selected="navigateFromSearch"
:max-width="isMobile ? '100%' : '450px'"
/>
</v-expand-x-transition>
<v-btn icon @click="search = !search">
<div v-else>
<v-btn icon @click="$refs.recipeSearch.open()">
<v-icon> mdi-magnify </v-icon>
</v-btn>
<SearchDialog ref="recipeSearch"/>
</div>
<TheSiteMenu />
@ -54,6 +54,7 @@
<script>
import TheSiteMenu from "@/components/UI/TheSiteMenu";
import SearchBar from "@/components/UI/Search/SearchBar";
import SearchDialog from "@/components/UI/Search/SearchDialog";
import TheRecipeFab from "@/components/UI/TheRecipeFab";
import TheSidebar from "@/components/UI/TheSidebar";
import { user } from "@/mixins/user";
@ -62,6 +63,7 @@ export default {
mixins: [user],
components: {
SearchDialog,
TheRecipeFab,
TheSidebar,
TheSiteMenu,
@ -69,15 +71,9 @@ export default {
},
data() {
return {
search: false,
showSidebar: false,
};
},
watch: {
$route() {
this.search = false;
},
},
computed: {
isMobile() {
return this.$vuetify.breakpoint.name === "xs";
@ -95,8 +91,4 @@ export default {
</script>
<style scoped>
fab-position {
position: absolute;
bottom: 0;
}
</style>

View file

@ -137,7 +137,7 @@ export default {
mainMenu() {
return [...this.baseMainLinks, ...this.customPages];
},
settingsLink() {
settingsLinks() {
return [
{
icon: "mdi-account",

View file

@ -169,7 +169,7 @@
"image": "Image"
},
"search": {
"search-mealie": "Search Mealie",
"search-mealie": "Search Mealie (press /)",
"search-placeholder": "Search...",
"max-results": "Max Results",
"category-filter": "Category Filter",