Skip to content

Commit e483434

Browse files
committed
allow browsing additional search results
fixes #132
1 parent c7028c9 commit e483434

File tree

4 files changed

+82
-26
lines changed

4 files changed

+82
-26
lines changed

src/library/search/SearchForm.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
},
1818
methods: {
1919
search(): void {
20-
this.$router.push({ name: 'search', query: { q: this.query } })
20+
this.$router.push({ name: 'search', query: { query: this.query } })
2121
}
2222
}
2323
})

src/library/search/SearchResult.vue

+69-21
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,39 @@
11
<template>
2-
<ContentLoader v-slot :loading="result == null">
3-
<div v-if="result.artists.length > 0" class="mb-5">
4-
<h1>Artists</h1>
5-
<ArtistList :items="result.artists" />
6-
</div>
2+
<div>
73
<div v-if="result.albums.length > 0" class="mb-5">
8-
<h1>Albums</h1>
4+
<h1 v-if="!type">
5+
Albums
6+
<router-link v-if="!type" :to="{params: {type: 'album'}, query: $route.query}" class="text-muted">
7+
<Icon icon="chevron-right" />
8+
</router-link>
9+
</h1>
910
<AlbumList :items="result.albums" />
1011
</div>
12+
13+
<div v-if="result.artists.length > 0" class="mb-5">
14+
<h1 v-if="!type">
15+
Artists
16+
<router-link v-if="!type" :to="{params: {type: 'artist'}, query: $route.query}" class="text-muted">
17+
<Icon icon="chevron-right" />
18+
</router-link>
19+
</h1>
20+
<ArtistList :items="result.artists" />
21+
</div>
22+
1123
<div v-if="result.tracks.length > 0">
12-
<h1>Tracks</h1>
24+
<h1 v-if="!type">
25+
Tracks
26+
<router-link :to="{params: {type: 'track'}, query: $route.query}" class="text-muted">
27+
<Icon icon="chevron-right" />
28+
</router-link>
29+
</h1>
1330
<TrackList :tracks="result.tracks" />
1431
</div>
15-
<EmptyIndicator v-if="!hasResult" label="No results" />
16-
</ContentLoader>
32+
33+
<EmptyIndicator v-if="!loading && !hasResult" label="No results" />
34+
35+
<InfiniteLoader :key="key" :loading="loading" :has-more="type ? hasMore : false" @load-more="loadMore" />
36+
</div>
1737
</template>
1838
<script lang="ts">
1939
import { defineComponent } from 'vue'
@@ -28,30 +48,58 @@
2848
TrackList,
2949
},
3050
props: {
31-
query: { type: String, required: true }
51+
query: { type: String, required: true },
52+
type: { type: String, default: null },
3253
},
3354
data() {
3455
return {
35-
result: null as any,
56+
result: {
57+
albums: [] as any[],
58+
artists: [] as any[],
59+
tracks: [] as any[],
60+
},
61+
loading: true,
62+
offset: 0 as number,
63+
hasMore: true,
3664
}
3765
},
3866
computed: {
67+
key(): string {
68+
return '' + this.type + this.query
69+
},
3970
hasResult(): boolean {
40-
return this.result && (
71+
return this.result.albums.length > 0 ||
4172
this.result.artists.length > 0 ||
42-
this.result.albums.length > 0 ||
43-
this.result.tracks.length > 0)
44-
}
73+
this.result.tracks.length > 0
74+
},
4575
},
4676
watch: {
47-
query: {
77+
key: {
4878
immediate: true,
49-
handler(value: string) {
50-
this.$api.search(value).then(result => {
51-
this.result = result
52-
})
79+
handler() {
80+
this.result.artists = []
81+
this.result.albums = []
82+
this.result.tracks = []
83+
this.offset = 0
84+
this.hasMore = true
85+
this.loading = true
5386
}
54-
}
87+
},
5588
},
89+
methods: {
90+
async loadMore() {
91+
this.loading = true
92+
const result = await this.$api.search(this.query, this.type, this.offset)
93+
const size = result.albums.length + result.artists.length + result.tracks.length
94+
95+
this.result.albums.push(...result.albums)
96+
this.result.artists.push(...result.artists)
97+
this.result.tracks.push(...result.tracks)
98+
99+
this.offset += size
100+
this.hasMore = size > 0
101+
this.loading = false
102+
}
103+
}
56104
})
57105
</script>

src/shared/api.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -390,15 +390,22 @@ export class API {
390390
await this.fetch('rest/unstar', params)
391391
}
392392

393-
async search(query: string): Promise<SearchResult> {
393+
async search(query: string, type?: string, offset?: number): Promise<SearchResult> {
394+
const size = 20
394395
const params = {
395396
query,
397+
albumCount: !type || type === 'album' ? size : 0,
398+
artistCount: !type || type === 'artist' ? size : 0,
399+
songCount: !type || type === 'track' ? size : 0,
400+
albumOffset: offset ?? 0,
401+
artistOffset: offset ?? 0,
402+
songOffset: offset ?? 0,
396403
}
397404
const data = await this.fetch('rest/search3', params)
398405
return {
399-
tracks: (data.searchResult3.song || []).map(this.normalizeTrack, this),
400406
albums: (data.searchResult3.album || []).map(this.normalizeAlbum, this),
401407
artists: (data.searchResult3.artist || []).map(this.normalizeArtist, this),
408+
tracks: (data.searchResult3.song || []).map(this.normalizeTrack, this),
402409
}
403410
}
404411

src/shared/router.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,11 @@ export function setupRouter(auth: AuthService) {
139139
},
140140
{
141141
name: 'search',
142-
path: '/search',
142+
path: '/search/:type?',
143143
component: SearchResult,
144144
props: (route) => ({
145-
query: route.query.q,
145+
...route.params,
146+
...route.query,
146147
})
147148
},
148149
]

0 commit comments

Comments
 (0)