mirror of
				https://github.com/TeamPiped/Piped.git
				synced 2024-08-14 23:57:27 +00:00 
			
		
		
		
	Make suggestions interactive
This commit is contained in:
		
							parent
							
								
									9016032d48
								
							
						
					
					
						commit
						f922dd74eb
					
				
					 2 changed files with 75 additions and 23 deletions
				
			
		| 
						 | 
					@ -6,11 +6,7 @@
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
        <div class="uk-navbar-left">
 | 
					        <div class="uk-navbar-left">
 | 
				
			||||||
            <router-link class="uk-navbar-item uk-logo uk-text-bold" to="/"
 | 
					            <router-link class="uk-navbar-item uk-logo uk-text-bold" to="/"
 | 
				
			||||||
                ><img
 | 
					                ><img src="/img/icons/logo.svg" height="32" width="32" />iped</router-link
 | 
				
			||||||
                    src="/img/icons/logo.svg"
 | 
					 | 
				
			||||||
                    height="32"
 | 
					 | 
				
			||||||
                    width="32"
 | 
					 | 
				
			||||||
                />iped</router-link
 | 
					 | 
				
			||||||
            >
 | 
					            >
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="uk-navbar-center uk-flex uk-visible@m">
 | 
					        <div class="uk-navbar-center uk-flex uk-visible@m">
 | 
				
			||||||
| 
						 | 
					@ -19,7 +15,7 @@
 | 
				
			||||||
                type="text"
 | 
					                type="text"
 | 
				
			||||||
                placeholder="Search"
 | 
					                placeholder="Search"
 | 
				
			||||||
                v-model="searchText"
 | 
					                v-model="searchText"
 | 
				
			||||||
                @keypress="onChange($event)"
 | 
					                @keydown="onKeyDown"
 | 
				
			||||||
                @focus="onInputFocus"
 | 
					                @focus="onInputFocus"
 | 
				
			||||||
                @blur="onInputBlur"
 | 
					                @blur="onInputBlur"
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
| 
						 | 
					@ -44,20 +40,20 @@
 | 
				
			||||||
            type="text"
 | 
					            type="text"
 | 
				
			||||||
            placeholder="Search"
 | 
					            placeholder="Search"
 | 
				
			||||||
            v-model="searchText"
 | 
					            v-model="searchText"
 | 
				
			||||||
            @keypress="onChange($event)"
 | 
					            @keydown="onKeyDown"
 | 
				
			||||||
            @focus="onInputFocus"
 | 
					            @focus="onInputFocus"
 | 
				
			||||||
            @blur="onInputBlur"
 | 
					            @blur="onInputBlur"
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <SearchSuggestions
 | 
					    <SearchSuggestions
 | 
				
			||||||
        v-if="searchText && suggestionsVisible && searchSuggestions.length > 0"
 | 
					        v-show="searchText && suggestionsVisible"
 | 
				
			||||||
        :searchSuggestions="searchSuggestions"
 | 
					        :searchText="searchText"
 | 
				
			||||||
 | 
					        @searchchange="onSearchTextChange"
 | 
				
			||||||
    />
 | 
					    />
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
import SearchSuggestions from "@/components/SearchSuggestions";
 | 
					import SearchSuggestions from "@/components/SearchSuggestions";
 | 
				
			||||||
import Constants from "@/Constants.js";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
    components: {
 | 
					    components: {
 | 
				
			||||||
| 
						 | 
					@ -66,31 +62,29 @@ export default {
 | 
				
			||||||
    data() {
 | 
					    data() {
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            searchText: "",
 | 
					            searchText: "",
 | 
				
			||||||
            searchSuggestions: [],
 | 
					 | 
				
			||||||
            suggestionsVisible: false
 | 
					            suggestionsVisible: false
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    methods: {
 | 
					    methods: {
 | 
				
			||||||
        async onChange(e) {
 | 
					        onKeyDown(e) {
 | 
				
			||||||
            if (e.key === "Enter") {
 | 
					            if (e.key === "Enter") {
 | 
				
			||||||
                this.$router.push({
 | 
					                this.$router.push({
 | 
				
			||||||
                    name: "SearchResults",
 | 
					                    name: "SearchResults",
 | 
				
			||||||
                    query: { search_query: this.searchText }
 | 
					                    query: { search_query: this.searchText }
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					            } else if (e.key === "ArrowUp" || e.key === "ArrowDown") {
 | 
				
			||||||
 | 
					                e.preventDefault();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            this.searchSuggestions = await this.fetchJson(
 | 
					 | 
				
			||||||
                Constants.BASE_URL +
 | 
					 | 
				
			||||||
                    "/suggestions?query=" +
 | 
					 | 
				
			||||||
                    encodeURI(this.searchText + e.key)
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        onInputFocus() {
 | 
					        onInputFocus() {
 | 
				
			||||||
            this.suggestionsVisible = true;
 | 
					            this.suggestionsVisible = true;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        onInputBlur() {
 | 
					        onInputBlur() {
 | 
				
			||||||
            this.suggestionsVisible = false;
 | 
					            this.suggestionsVisible = false;
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        onSearchTextChange(searchText) {
 | 
				
			||||||
 | 
					            this.searchText = searchText;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,12 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <div
 | 
					    <div class="uk-position-absolute uk-panel uk-box-shadow-large suggestions-container">
 | 
				
			||||||
        class="uk-position-absolute uk-panel uk-box-shadow-large uk-padding-small suggestions-container"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
        <ul class="uk-list uk-margin-remove uk-text-secondary">
 | 
					        <ul class="uk-list uk-margin-remove uk-text-secondary">
 | 
				
			||||||
            <li v-for="(suggestion, i) in searchSuggestions" :key="i">
 | 
					            <li
 | 
				
			||||||
 | 
					                v-for="(suggestion, i) in searchSuggestions"
 | 
				
			||||||
 | 
					                :key="i"
 | 
				
			||||||
 | 
					                :class="{ selected: selected === i }"
 | 
				
			||||||
 | 
					                class="uk-margin-remove suggestion"
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
                {{ suggestion }}
 | 
					                {{ suggestion }}
 | 
				
			||||||
            </li>
 | 
					            </li>
 | 
				
			||||||
        </ul>
 | 
					        </ul>
 | 
				
			||||||
| 
						 | 
					@ -11,9 +14,57 @@
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
 | 
					import Constants from "@/Constants.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
    props: {
 | 
					    props: {
 | 
				
			||||||
        searchSuggestions: Array
 | 
					        searchText: String
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    data() {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            selected: 0,
 | 
				
			||||||
 | 
					            searchSuggestions: []
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    methods: {
 | 
				
			||||||
 | 
					        onKeyUp(e) {
 | 
				
			||||||
 | 
					            if (e.key === "ArrowUp") {
 | 
				
			||||||
 | 
					                if (this.selected <= 0) {
 | 
				
			||||||
 | 
					                    this.selected = this.searchSuggestions.length - 1;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    this.selected -= 1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                e.preventDefault();
 | 
				
			||||||
 | 
					            } else if (e.key === "ArrowDown") {
 | 
				
			||||||
 | 
					                if (this.selected >= this.searchSuggestions.length - 1) {
 | 
				
			||||||
 | 
					                    this.selected = 0;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    this.selected += 1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                e.preventDefault();
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                this.refreshSuggestions();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        async refreshSuggestions() {
 | 
				
			||||||
 | 
					            this.searchSuggestions = await this.fetchJson(
 | 
				
			||||||
 | 
					                Constants.BASE_URL + "/suggestions?query=" + encodeURI(this.searchText)
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            this.searchSuggestions.unshift(this.searchText);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    watch: {
 | 
				
			||||||
 | 
					        selected(newValue, oldValue) {
 | 
				
			||||||
 | 
					            if (newValue !== oldValue && this.searchSuggestions[this.selected]) {
 | 
				
			||||||
 | 
					                this.$emit("searchchange", this.searchSuggestions[this.selected]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    mounted() {
 | 
				
			||||||
 | 
					        window.addEventListener("keyup", this.onKeyUp);
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    beforeUnmount() {
 | 
				
			||||||
 | 
					        window.removeEventListener("keyup", this.onKeyUp);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					@ -26,6 +77,13 @@ export default {
 | 
				
			||||||
    max-width: 640px;
 | 
					    max-width: 640px;
 | 
				
			||||||
    width: 100%;
 | 
					    width: 100%;
 | 
				
			||||||
    box-sizing: border-box;
 | 
					    box-sizing: border-box;
 | 
				
			||||||
 | 
					    padding: 5px 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.suggestion {
 | 
				
			||||||
 | 
					    padding: 4px 15px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.suggestion.selected {
 | 
				
			||||||
 | 
					    background-color: #393d3d;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@media screen and (max-width: 959px) {
 | 
					@media screen and (max-width: 959px) {
 | 
				
			||||||
    .suggestions-container {
 | 
					    .suggestions-container {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue