mirror of
https://github.com/owntone/owntone-server.git
synced 2025-04-16 09:08:04 -04:00
[web] Simplify search pages
This commit is contained in:
parent
9bea7fef7d
commit
722307653a
File diff suppressed because one or more lines are too long
@ -8,7 +8,7 @@
|
|||||||
<div class="control has-icons-left">
|
<div class="control has-icons-left">
|
||||||
<input
|
<input
|
||||||
ref="search_field"
|
ref="search_field"
|
||||||
v-model="query"
|
v-model="searchStore.query"
|
||||||
class="input is-rounded"
|
class="input is-rounded"
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="$t('page.search.placeholder')"
|
:placeholder="$t('page.search.placeholder')"
|
||||||
@ -39,7 +39,7 @@
|
|||||||
<div v-for="item in history" :key="item" class="control">
|
<div v-for="item in history" :key="item" class="control">
|
||||||
<div class="tags has-addons">
|
<div class="tags has-addons">
|
||||||
<a class="tag" @click="openSearch(item)" v-text="item" />
|
<a class="tag" @click="openSearch(item)" v-text="item" />
|
||||||
<a class="tag is-delete" @click="removeSearch(item)" />
|
<a class="tag is-delete" @click="searchStore.remove(item)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -56,20 +56,17 @@
|
|||||||
<component :is="components[type]" :items="items" />
|
<component :is="components[type]" :items="items" />
|
||||||
</template>
|
</template>
|
||||||
<template v-if="!expanded" #footer>
|
<template v-if="!expanded" #footer>
|
||||||
<nav v-if="showAllButton(items)" class="level">
|
<control-button
|
||||||
<div class="level-item">
|
v-if="showAllButton(items)"
|
||||||
<control-button
|
:button="{
|
||||||
:button="{
|
handler: () => expand(type),
|
||||||
handler: () => expand(type),
|
title: $t(
|
||||||
title: $t(
|
`page.search.show-${type}s`,
|
||||||
`page.search.show-${type}s`,
|
{ count: $n(items.total) },
|
||||||
{ count: $n(items.total) },
|
items.total
|
||||||
items.total
|
)
|
||||||
)
|
}"
|
||||||
}"
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<div v-if="!items.total" class="has-text-centered-mobile">
|
<div v-if="!items.total" class="has-text-centered-mobile">
|
||||||
<i v-text="$t('page.search.no-results')" />
|
<i v-text="$t('page.search.no-results')" />
|
||||||
</div>
|
</div>
|
||||||
@ -131,7 +128,6 @@ export default {
|
|||||||
},
|
},
|
||||||
results: new Map(),
|
results: new Map(),
|
||||||
limit: {},
|
limit: {},
|
||||||
query: '',
|
|
||||||
types: SEARCH_TYPES
|
types: SEARCH_TYPES
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -143,33 +139,23 @@ export default {
|
|||||||
return this.searchStore.history
|
return this.searchStore.history
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
query() {
|
|
||||||
this.searchStore.query = this.query
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.searchStore.source = this.$route.name
|
this.searchStore.source = this.$route.name
|
||||||
this.query = this.searchStore.query
|
|
||||||
this.limit = PAGE_SIZE
|
this.limit = PAGE_SIZE
|
||||||
this.search()
|
this.search()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
expand(type) {
|
expand(type) {
|
||||||
this.query = this.searchStore.query
|
|
||||||
this.types = [type]
|
this.types = [type]
|
||||||
this.limit = -1
|
this.limit = -1
|
||||||
this.search()
|
this.search()
|
||||||
},
|
},
|
||||||
openSearch(query) {
|
openSearch(query) {
|
||||||
this.query = query
|
this.searchStore.query = query
|
||||||
this.types = SEARCH_TYPES
|
this.types = SEARCH_TYPES
|
||||||
this.limit = PAGE_SIZE
|
this.limit = PAGE_SIZE
|
||||||
this.search()
|
this.search()
|
||||||
},
|
},
|
||||||
removeSearch(query) {
|
|
||||||
this.searchStore.remove(query)
|
|
||||||
},
|
|
||||||
reset() {
|
reset() {
|
||||||
this.results.clear()
|
this.results.clear()
|
||||||
this.types.forEach((type) => {
|
this.types.forEach((type) => {
|
||||||
@ -181,8 +167,11 @@ export default {
|
|||||||
this.types = SEARCH_TYPES
|
this.types = SEARCH_TYPES
|
||||||
this.limit = PAGE_SIZE
|
this.limit = PAGE_SIZE
|
||||||
}
|
}
|
||||||
this.query = this.query.trim()
|
this.searchStore.query = this.searchStore.query.trim()
|
||||||
if (!this.query || !this.query.replace(/^query:/u, '')) {
|
if (
|
||||||
|
!this.searchStore.query ||
|
||||||
|
!this.searchStore.query.replace(/^query:/u, '')
|
||||||
|
) {
|
||||||
this.$refs.search_field.focus()
|
this.$refs.search_field.focus()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -190,7 +179,7 @@ export default {
|
|||||||
this.types.forEach((type) => {
|
this.types.forEach((type) => {
|
||||||
this.searchItems(type)
|
this.searchItems(type)
|
||||||
})
|
})
|
||||||
this.searchStore.add(this.query)
|
this.searchStore.add(this.searchStore.query)
|
||||||
},
|
},
|
||||||
searchItems(type) {
|
searchItems(type) {
|
||||||
const music = type !== 'audiobook' && type !== 'podcast'
|
const music = type !== 'audiobook' && type !== 'podcast'
|
||||||
@ -199,13 +188,13 @@ export default {
|
|||||||
limit: this.limit,
|
limit: this.limit,
|
||||||
type: music ? type : 'album'
|
type: music ? type : 'album'
|
||||||
}
|
}
|
||||||
if (this.query.startsWith('query:')) {
|
if (this.searchStore.query.startsWith('query:')) {
|
||||||
parameters.expression = `(${this.query.replace(/^query:/u, '').trim()}) and media_kind is ${kind}`
|
parameters.expression = `(${this.searchStore.query.replace(/^query:/u, '').trim()}) and media_kind is ${kind}`
|
||||||
} else if (music) {
|
} else if (music) {
|
||||||
parameters.query = this.query
|
parameters.query = this.searchStore.query
|
||||||
parameters.media_kind = kind
|
parameters.media_kind = kind
|
||||||
} else {
|
} else {
|
||||||
parameters.expression = `(album includes "${this.query}" or artist includes "${this.query}") and media_kind is ${kind}`
|
parameters.expression = `(album includes "${this.searchStore.query}" or artist includes "${this.searchStore.query}") and media_kind is ${kind}`
|
||||||
}
|
}
|
||||||
webapi.search(parameters).then(({ data }) => {
|
webapi.search(parameters).then(({ data }) => {
|
||||||
this.results.set(type, new GroupedList(data[`${parameters.type}s`]))
|
this.results.set(type, new GroupedList(data[`${parameters.type}s`]))
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<div class="control has-icons-left">
|
<div class="control has-icons-left">
|
||||||
<input
|
<input
|
||||||
ref="search_field"
|
ref="search_field"
|
||||||
v-model="query"
|
v-model="searchStore.query"
|
||||||
class="input is-rounded"
|
class="input is-rounded"
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="$t('page.search.placeholder')"
|
:placeholder="$t('page.search.placeholder')"
|
||||||
@ -22,7 +22,7 @@
|
|||||||
<div v-for="item in history" :key="item" class="control">
|
<div v-for="item in history" :key="item" class="control">
|
||||||
<div class="tags has-addons">
|
<div class="tags has-addons">
|
||||||
<a class="tag" @click="openSearch(item)" v-text="item" />
|
<a class="tag" @click="openSearch(item)" v-text="item" />
|
||||||
<a class="tag is-delete" @click="removeSearch(item)" />
|
<a class="tag is-delete" @click="searchStore.remove(item)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -51,20 +51,17 @@
|
|||||||
</vue-eternal-loading>
|
</vue-eternal-loading>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="!expanded" #footer>
|
<template v-if="!expanded" #footer>
|
||||||
<nav v-if="showAllButton(items)" class="level">
|
<control-button
|
||||||
<div class="level-item">
|
v-if="showAllButton(items)"
|
||||||
<control-button
|
:button="{
|
||||||
:button="{
|
handler: () => expand(type),
|
||||||
handler: () => expand(type),
|
title: $t(
|
||||||
title: $t(
|
`page.search.show-${type}s`,
|
||||||
`page.search.show-${type}s`,
|
{ count: $n(items.total) },
|
||||||
{ count: $n(items.total) },
|
items.total
|
||||||
items.total
|
)
|
||||||
)
|
}"
|
||||||
}"
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<div v-if="!items.total" class="has-text-centered-mobile">
|
<div v-if="!items.total" class="has-text-centered-mobile">
|
||||||
<i v-text="$t('page.search.no-results')" />
|
<i v-text="$t('page.search.no-results')" />
|
||||||
</div>
|
</div>
|
||||||
@ -116,7 +113,6 @@ export default {
|
|||||||
},
|
},
|
||||||
results: new Map(),
|
results: new Map(),
|
||||||
parameters: {},
|
parameters: {},
|
||||||
query: '',
|
|
||||||
types: SEARCH_TYPES
|
types: SEARCH_TYPES
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -130,35 +126,25 @@ export default {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
query() {
|
|
||||||
this.searchStore.query = this.query
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.searchStore.source = this.$route.name
|
this.searchStore.source = this.$route.name
|
||||||
this.query = this.searchStore.query
|
|
||||||
this.parameters.limit = PAGE_SIZE
|
this.parameters.limit = PAGE_SIZE
|
||||||
this.search()
|
this.search()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
expand(type) {
|
expand(type) {
|
||||||
this.query = this.searchStore.query
|
|
||||||
this.types = [type]
|
this.types = [type]
|
||||||
this.parameters.limit = PAGE_SIZE_EXPANDED
|
this.parameters.limit = PAGE_SIZE_EXPANDED
|
||||||
this.parameters.offset = 0
|
this.parameters.offset = 0
|
||||||
this.search()
|
this.search()
|
||||||
},
|
},
|
||||||
openSearch(query) {
|
openSearch(query) {
|
||||||
this.query = query
|
this.searchStore.query = query
|
||||||
this.types = SEARCH_TYPES
|
this.types = SEARCH_TYPES
|
||||||
this.parameters.limit = PAGE_SIZE
|
this.parameters.limit = PAGE_SIZE
|
||||||
this.parameters.offset = 0
|
this.parameters.offset = 0
|
||||||
this.search()
|
this.search()
|
||||||
},
|
},
|
||||||
removeSearch(query) {
|
|
||||||
this.searchStore.remove(query)
|
|
||||||
},
|
|
||||||
reset() {
|
reset() {
|
||||||
this.results.clear()
|
this.results.clear()
|
||||||
this.types.forEach((type) => {
|
this.types.forEach((type) => {
|
||||||
@ -170,8 +156,8 @@ export default {
|
|||||||
this.types = SEARCH_TYPES
|
this.types = SEARCH_TYPES
|
||||||
this.parameters.limit = PAGE_SIZE
|
this.parameters.limit = PAGE_SIZE
|
||||||
}
|
}
|
||||||
this.query = this.query.trim()
|
this.searchStore.query = this.searchStore.query.trim()
|
||||||
if (!this.query) {
|
if (!this.searchStore.query) {
|
||||||
this.$refs.search_field.focus()
|
this.$refs.search_field.focus()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -181,20 +167,22 @@ export default {
|
|||||||
this.results.set(type, data[`${type}s`])
|
this.results.set(type, data[`${type}s`])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
this.searchStore.add(this.query)
|
this.searchStore.add(this.searchStore.query)
|
||||||
},
|
},
|
||||||
searchItems() {
|
searchItems() {
|
||||||
return webapi.spotify().then(({ data }) => {
|
return webapi.spotify().then(({ data }) => {
|
||||||
this.parameters.market = data.webapi_country
|
this.parameters.market = data.webapi_country
|
||||||
const spotifyApi = new SpotifyWebApi()
|
const spotifyApi = new SpotifyWebApi()
|
||||||
spotifyApi.setAccessToken(data.webapi_token)
|
spotifyApi.setAccessToken(data.webapi_token)
|
||||||
return spotifyApi.search(this.query, this.types, this.parameters)
|
return spotifyApi.search(
|
||||||
|
this.searchStore.query,
|
||||||
|
this.types,
|
||||||
|
this.parameters
|
||||||
|
)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
searchLibrary() {
|
searchLibrary() {
|
||||||
this.$router.push({
|
this.$router.push({ name: 'search-library' })
|
||||||
name: 'search-library'
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
searchNext({ loaded }) {
|
searchNext({ loaded }) {
|
||||||
const [type] = this.types,
|
const [type] = this.types,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user