adding search suggestions

This commit is contained in:
vapormusic 2022-09-04 18:38:26 +07:00
parent 6cbe9522fc
commit 167893e890
5 changed files with 152 additions and 18 deletions

View file

@ -334,6 +334,15 @@
width: 42px;
height: 42px;
flex: 0 0 auto;
&.circle{
border-radius: 50%;
.mediaitem-artwork{
border-radius: 50%;
}
img {
border-radius: 50%;
}
}
}
&:hover {
@ -349,6 +358,11 @@
color: #eee;
}
&.hintactive {
background: var(--keyColor);
border-radius: 6px;
}
.queue-info {
justify-content: center;
display: flex;
@ -392,6 +406,18 @@
}
}
.search-hints .cd-queue-item{
&:hover {
background: var(--selected);
border-radius: 6px;
}
&:active {
background: var(--selected-click);
color: #eee;
border-radius: 6px;
}
}
/* horizontal media scroller */
.cd-hmedia-scroller {
&::-webkit-scrollbar-thumb {

View file

@ -1903,8 +1903,18 @@ const app = new Vue({
this.search.hints = [];
return;
}
let hints = await (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search/hints?term=${this.search.term}`)).data.results;
this.search.hints = hints ? hints.terms : [];
let hints = await (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search/suggestions?term=${this.search.term}`,
{"fields[albums]": "artwork,name,playParams,url,artistName,id",
"fields[artists]": "url,name,artwork,id",
"fields[songs]": "artwork,name,playParams,url,artistName,id",
"kinds": "terms,topResults",
"l": this.mklang,
"limit[results:terms]": 5,
"limit[results:topResults]": 5,
"omit[resource]": "autos",
"platform": "web",
"types": "activities,albums,artists,editorial-items,music-movies,playlists,record-labels,songs,stations"})).data.results;
this.search.hints = hints ? hints.suggestions : [];
},
getSongProgress() {
if (this.playerLCD.userInteraction) {
@ -3890,15 +3900,22 @@ const app = new Vue({
if (e.keyCode == "40") {
if (this.search.hints.length - 1 < this.search.cursor + 1) return;
this.search.cursor++;
this.search.term = this.search.hints[this.search.cursor];
let item = this.search.hints[this.search.cursor]
this.search.term = item.content ? (item.content?.attributes?.name ?? "") :item.displayTerm;
} else if (e.keyCode == "38") {
if (this.search.cursor == 0) return;
this.search.cursor--;
this.search.term = this.search.hints[this.search.cursor];
let item = this.search.hints[this.search.cursor]
this.search.term = item.content ? (item.content?.attributes?.name ?? "") :item.displayTerm;
}
},
async searchQuery(term = this.search.term) {
let self = this;
if (typeof term === "object"){
this.routeView(term)
this.search.term = ""
return;
}
if (term == "") {
return;
}

View file

@ -277,10 +277,10 @@
<div class="app-chrome-item search">
<div class="search-input-container">
<div class="search-input--icon"></div>
<input type="search" spellcheck="false" @click="$root.appRoute('search');"
<input type="search" spellcheck="false" @click="$root.appRoute('search');search.showHints = true"
@focus="search.showHints = true"
@blur="setTimeout(()=>{search.showHints = false}, 300)"
v-on:keyup.enter="searchQuery();search.showHints = false;search.cursor = -1" @change="$root.appRoute('search');"
v-on:keyup.enter="searchQuery(search.hints[search.cursor].content ?? search.hints[search.cursor].searchTerm);search.showHints = false;search.cursor = -1" @change="$root.appRoute('search');"
v-on:keyup="searchCursor"
@input="getSearchHints()"
:placeholder="$root.getLz('term.search') + '...'" v-model="search.term" ref="searchInput"
@ -288,10 +288,40 @@
<div class="search-hints-container" v-if="search.showHints && search.hints.length != 0">
<div class="search-hints">
<button class="search-hint text-overflow-elipsis" :class="{active: (search.cursor == index)}" v-for="(hint, index) in search.hints"
@click="search.term = hint;search.showHints = false;searchQuery(hint);search.cursor = -1">
{{ hint }}
<button class="search-hint text-overflow-elipsis" :class="{active: (search.cursor == index)}" v-for="(hint, index) in search.hints.filter((a) => {return a.content == null})"
@click="search.term = hint.searchTerm;search.showHints = false;searchQuery(hint.searchTerm);search.cursor = -1">
{{ hint.displayTerm }}
</button>
<template v-for="(item, position) in search.hints.filter((a) => {return a.content != null})">
<div class="cd-queue-item" @click="search.showHints = false;routeView(item.content);search.cursor = -1"
:class="{'hintactive': (search.cursor == position + search.hints.filter((a) => {return a.content == null}).length)}">
<div class="row">
<div class="col-auto cider-flex-center">
<div class="artwork" :class="{'circle': item.content.type == 'artists'}">
<mediaitem-artwork
:url="item.content.attributes.artwork ? item.content.attributes.artwork.url : ''"
:size="32"></mediaitem-artwork>
</div>
</div>
<div class="col queue-info">
<div class="queue-title text-overflow-elipsis">{{ item.content.attributes.name }}
</div>
<div class="queue-subtitle text-overflow-elipsis">{{
item.content.attributes.artistName }}
</div>
</div>
<div class="queue-explicit-icon cider-flex-center"
v-if="item.content.attributes.contentRating == 'explicit'">
<div class="explicit-icon"></div>
</div>
<!-- <div class="col queue-duration-info">
<div class="queue-duration cider-flex-center">
{{convertTimeToString(item.content.attributes.durationInMillis)}}
</div>
</div> -->
</div>
</div>
</template>
</div>
</div>
</div>

View file

@ -7,10 +7,10 @@
<input
type="search"
spellcheck="false"
@click="$root.appRoute('search');"
@click="$root.appRoute('search');$root.search.showHints = true"
@focus="$root.search.showHints = true"
@blur="$root.setTimeout(()=>{$root.search.showHints = false}, 300)"
v-on:keyup.enter="$root.searchQuery();$root.search.showHints = false;$root.search.cursor = -1"
v-on:keyup.enter="$root.searchQuery($root.search.hints[$root.search.cursor].content ?? $root.search.hints[$root.search.cursor].searchTerm);$root.search.showHints = false;$root.search.cursor = -1"
v-on:keyup="$root.searchCursor"
@change="$root.appRoute('search');"
@input="$root.getSearchHints()"
@ -27,11 +27,41 @@
<div class="search-hints">
<button
class="search-hint text-overflow-elipsis"
v-for="hint in $root.search.hints"
@click="$root.search.term = hint;$root.search.showHints = false;$root.searchQuery(hint);$root.search.cursor = -1"
v-for="(hint, index) in $root.search.hints.filter((a) => {return a.content == null})" :class="{active: ($root.search.cursor == index)}"
@click="$root.search.term = hint.searchTerm;$root.search.showHints = false;$root.searchQuery(hint.searchTerm);$root.search.cursor = -1"
>
{{ hint }}
{{ hint.displayTerm }}
</button>
<template v-for="(item, position) in $root.search.hints.filter((a) => {return a.content != null})">
<div class="cd-queue-item" @click="$root.search.showHints = false;$root.routeView(item.content);$root.search.cursor = -1"
:class="{'hintactive': ($root.search.cursor == position + $root.search.hints.filter((a) => {return a.content == null}).length)}">
<div class="row">
<div class="col-auto cider-flex-center">
<div class="artwork" :class="{'circle': item.content.type == 'artists'}">
<mediaitem-artwork
:url="item.content.attributes.artwork ? item.content.attributes.artwork.url : ''"
:size="32"></mediaitem-artwork>
</div>
</div>
<div class="col queue-info">
<div class="queue-title text-overflow-elipsis">{{ item.content.attributes.name }}
</div>
<div class="queue-subtitle text-overflow-elipsis">{{
item.content.attributes.artistName }}
</div>
</div>
<div class="queue-explicit-icon cider-flex-center"
v-if="item.content.attributes.contentRating == 'explicit'">
<div class="explicit-icon"></div>
</div>
<!-- <div class="col queue-duration-info">
<div class="queue-duration cider-flex-center">
{{convertTimeToString(item.content.attributes.durationInMillis)}}
</div>
</div> -->
</div>
</div>
</template>
</div>
</div>
</div>

View file

@ -4,17 +4,48 @@
<div class="search-input--icon"></div>
<input type="search" spellcheck="false" @focus="$root.search.showHints = true"
@blur="$root.setTimeout(()=>{$root.search.showHints = false}, 300)"
v-on:keyup.enter="$root.searchQuery();$root.search.showHints = false" @input="$root.getSearchHints()"
v-on:keyup.enter="$root.searchQuery($root.search.hints[$root.search.cursor].content ?? $root.search.hints[$root.search.cursor].searchTerm);$root.search.showHints = false" @input="$root.getSearchHints()"
:placeholder="$root.getLz('term.search') + '...'" v-model="$root.search.term"
class="search-input" />
<div class="search-hints-container" v-if="$root.search.showHints && $root.search.hints.length != 0">
<div class="search-hints">
<button class="search-hint text-overflow-elipsis" v-for="hint in $root.search.hints"
@click="$root.search.term = hint;$root.search.showHints = false;$root.searchQuery(hint)">
{{ hint }}
<button class="search-hint text-overflow-elipsis" v-for="(hint, index) in $root.search.hints.filter((a) => {return a.content == null})" :class="{active: ($root.search.cursor == index)}"
@click="$root.search.term = hint.searchTerm;$root.search.showHints = false;$root.searchQuery(hint.searchTerm)">
{{ hint.displayTerm }}
</button>
<template v-for="(item, position) in $root.search.hints.filter((a) => {return a.content != null})">
<div class="cd-queue-item" @click="$root.search.showHints = false;$root.routeView(item.content);$root.search.cursor = -1"
:class="{'hintactive': ($root.search.cursor == position + $root.search.hints.filter((a) => {return a.content == null}).length)}">
<div class="row">
<div class="col-auto cider-flex-center">
<div class="artwork" :class="{'circle': item.content.type == 'artists'}">
<mediaitem-artwork
:url="item.content.attributes.artwork ? item.content.attributes.artwork.url : ''"
:size="32"></mediaitem-artwork>
</div>
</div>
<div class="col queue-info">
<div class="queue-title text-overflow-elipsis">{{ item.content.attributes.name }}
</div>
<div class="queue-subtitle text-overflow-elipsis">{{
item.content.attributes.artistName }}
</div>
</div>
<div class="queue-explicit-icon cider-flex-center"
v-if="item.content.attributes.contentRating == 'explicit'">
<div class="explicit-icon"></div>
</div>
<!-- <div class="col queue-duration-info">
<div class="queue-duration cider-flex-center">
{{convertTimeToString(item.content.attributes.durationInMillis)}}
</div>
</div> -->
</div>
</div>
</template>
</div>
</div>
</div>
<div class="btn-group searchToggle">