1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99 import { ref, watch } from 'vue'
import type { SearchMode, Artist, Album, Track } from '../types'
import { useSubsonicApi } from '../subsonicApi'
import { useMainStore } from '../store/main'
import { AlbumList } from '../components/AlbumList.vine'
import { ArtistList } from '../components/ArtistList.vine'
import { TrackList } from '../components/TrackList.vine'
interface State {
artists: Artist[],
albums: Album[],
tracks: Track[],
hasMore: boolean,
}
export const SearchResultView = ({ query, mode = null }: { query: string, mode?: SearchMode }) => {
const
subsonicApi = useSubsonicApi(),
mainStore = useMainStore(),
pageSize = 20,
state = ref<State>({
artists: [],
albums: [],
tracks: [],
hasMore: true,
} as State),
loadMore = async() => {
try {
mainStore.isLoading = true
subsonicApi.search(
query,
mode,
pageSize,
(state.value.albums.length + state.value.artists.length + state.value.tracks.length)
).then(
result => {
const numResults = result.albums.length + result.artists.length + result.tracks.length;
state.value.artists.push(...result.artists)
state.value.albums.push(...result.albums)
state.value.tracks.push(...result.tracks)
state.value.hasMore = (
(numResults >= pageSize)
? true
: false
)
}
)
} finally {
mainStore.isLoading = false
}
}
watch(
() => [ query, mode ],
() => {
state.value = {
artists: [],
albums: [],
tracks: [],
hasMore: true,
} as State;
loadMore()
}
)
return vine`
<template v-if="!!state.artists.length">
<router-link v-if="!mode" :to="{ params: { mode: 'artist' }, query: $route.query }" class="section-title">
<Icon icon="artists" class="title-color" />
Artists <small>({{ state.artists.length }})</small>
</router-link>
<ArtistList :items="state.artists" />
</template>
<template v-if="!!state.albums.length">
<router-link v-if="!mode" :to="{ params: { mode: 'album' }, query: $route.query }" class="section-title">
<Icon icon="albums" />
Albums <small>({{ state.albums.length }})</small>
</router-link>
<AlbumList :items="state.albums" />
</template>
<template v-if="!!state.tracks.length">
<router-link :to="{ params: { mode: 'track' }, query: $route.query }" class="section-title">
<Icon icon="tracks" class="title-color" />
Tracks <small>({{ state.tracks.length }}{{ state.hasMore ? "+" : "" }})</small>
</router-link>
<TrackList :tracks="state.tracks" />
</template>
<EmptyIndicator v-if="!mainStore.isLoading && !state.hasMore && !state.artists.length && !state.albums.length && !state.tracks.length" label="No results" />
<InfiniteLoader :is-loading="mainStore.isLoading" :has-more="state.hasMore" @load-more="loadMore" />
`;
}