add search in playlist

master
Vidocq 4 years ago
parent c6ddf9ac3f
commit 25c35c4e79

@ -51,6 +51,7 @@ export default {
playlist: { playlist: {
playlist: "Playlists", playlist: "Playlists",
updatedAt: "Updated at", updatedAt: "Updated at",
search: "Search in playlist",
}, },
login: { login: {
accessToAll: "Access to all data", accessToAll: "Access to all data",

@ -48,6 +48,7 @@ export default {
playlist: { playlist: {
playlist: "歌单", playlist: "歌单",
updatedAt: "最后更新于", updatedAt: "最后更新于",
search: "搜索歌单音乐",
}, },
login: { login: {
accessToAll: "可访问全部数据", accessToAll: "可访问全部数据",

@ -135,8 +135,22 @@
</h1> </h1>
</div> </div>
<div class="search-box">
<div class="container" :class="{ active: inputFocus }">
<svg-icon icon-class="search" />
<div class="input">
<input
v-model="playlistKeyword"
:placeholder="inputFocus ? '' : $t('playlist.search')"
@focus="inputFocus = true"
@blur="inputFocus = false"
/>
</div>
</div>
</div>
<TrackList <TrackList
:tracks="tracks" :tracks="filteredTracks"
:type="'playlist'" :type="'playlist'"
:id="playlist.id" :id="playlist.id"
:extraContextMenuItem=" :extraContextMenuItem="
@ -302,6 +316,8 @@ export default {
tracks: [], tracks: [],
loadingMore: false, loadingMore: false,
lastLoadedTrackIndex: 9, lastLoadedTrackIndex: 9,
playlistKeyword: "",
inputFocus: false,
}; };
}, },
created() { created() {
@ -328,6 +344,13 @@ export default {
this.playlist.id !== this.data.likedSongPlaylistID this.playlist.id !== this.data.likedSongPlaylistID
); );
}, },
filteredTracks() {
return this.tracks.filter(song =>
song.name.toLowerCase().includes(this.playlistKeyword.toLowerCase()) ||
song.al.name.toLowerCase().includes(this.playlistKeyword.toLowerCase()) ||
song.ar.find(artist => artist.name.toLowerCase().includes(this.playlistKeyword.toLowerCase()))
);
},
}, },
methods: { methods: {
...mapMutations(["appendTrackToPlayerList"]), ...mapMutations(["appendTrackToPlayerList"]),
@ -374,6 +397,7 @@ export default {
this.lastLoadedTrackIndex = data.playlist.tracks.length - 1; this.lastLoadedTrackIndex = data.playlist.tracks.length - 1;
if (this.playlist.trackCount > this.tracks.length) { if (this.playlist.trackCount > this.tracks.length) {
window.addEventListener("scroll", this.handleScroll, true); window.addEventListener("scroll", this.handleScroll, true);
window.addEventListener("input", this.handleSearch, this.playlistKeyword);
} }
return data; return data;
}) })
@ -384,11 +408,11 @@ export default {
} }
}); });
}, },
loadMore() { loadMore(loadNum = 50) {
let trackIDs = this.playlist.trackIds.filter((t, index) => { let trackIDs = this.playlist.trackIds.filter((t, index) => {
if ( if (
index > this.lastLoadedTrackIndex && index > this.lastLoadedTrackIndex &&
index <= this.lastLoadedTrackIndex + 50 index <= this.lastLoadedTrackIndex + loadNum
) )
return t; return t;
}); });
@ -415,6 +439,15 @@ export default {
this.loadMore(); this.loadMore();
} }
}, },
handleSearch() {
if (
this.lastLoadedTrackIndex + 1 === this.playlist.trackIds.length ||
this.loadingMore
)
return;
this.loadingMore = true;
this.loadMore(this.playlist.trackIds.length - this.lastLoadedTrackIndex);
},
openMenu(e) { openMenu(e) {
this.$refs.playlistMenu.openMenu(e); this.$refs.playlistMenu.openMenu(e);
}, },
@ -452,7 +485,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.playlist-info { .playlist-info {
display: flex; display: flex;
margin-bottom: 72px; margin-bottom: 40px;
padding: var(--main-content-padding); padding: var(--main-content-padding);
.info { .info {
display: flex; display: flex;
@ -602,6 +635,54 @@ export default {
} }
} }
.search-box {
display: flex;
justify-content: flex-end;
margin-bottom: 10px;
-webkit-app-region: no-drag;
padding: var(--main-content-padding);
.container {
display: flex;
align-items: center;
height: 32px;
background: var(--color-secondary-bg-for-transparent);
border-radius: 8px;
width: 200px;
}
.svg-icon {
height: 15px;
width: 15px;
color: var(--color-text);
opacity: 0.28;
margin: {
left: 8px;
right: 4px;
bottom: 4px;
}
}
input {
font-size: 16px;
border: none;
background: transparent;
width: 96%;
font-weight: 600;
margin-top: -1px;
color: var(--color-text);
}
.active {
background: var(--color-primary-bg-for-transparent);
input,
.svg-icon {
opacity: 1;
color: var(--color-primary);
}
}
}
.gradient-test { .gradient-test {
background-image: linear-gradient(to left, #92fe9d 0%, #00c9ff 100%); background-image: linear-gradient(to left, #92fe9d 0%, #00c9ff 100%);
} }

Loading…
Cancel
Save