chore: format codes

This commit is contained in:
qier222 2021-04-26 16:26:49 +08:00
parent 6922c716e2
commit 9351f6bc89
No known key found for this signature in database
GPG key ID: 9C85007ED905F14D
73 changed files with 2321 additions and 2321 deletions

View file

@ -1,21 +1,21 @@
<template>
<div class="album" v-show="show">
<div v-show="show" class="album">
<div class="playlist-info">
<Cover
:imageUrl="album.picUrl | resizeImage(1024)"
:showPlayButton="true"
:alwaysShowShadow="true"
:clickCoverToPlay="true"
:fixedSize="288"
type="album"
:id="album.id"
:coverHover="false"
:playButtonSize="18"
:image-url="album.picUrl | resizeImage(1024)"
:show-play-button="true"
:always-show-shadow="true"
:click-cover-to-play="true"
:fixed-size="288"
type="album"
:cover-hover="false"
:play-button-size="18"
@click.right.native="openMenu"
/>
<div class="info">
<div class="title" @click.right="openMenu"> {{ title }}</div>
<div class="subtitle" v-if="subtitle !== ''" @click.right="openMenu">{{
<div v-if="subtitle !== ''" class="subtitle" @click.right="openMenu">{{
subtitle
}}</div>
<div class="artist">
@ -28,42 +28,42 @@
<span v-else>Compilation by Various Artists</span>
</div>
<div class="date-and-count">
<span class="explicit-symbol" v-if="album.mark === 1056768"
<span v-if="album.mark === 1056768" class="explicit-symbol"
><ExplicitSymbol
/></span>
<span :title="album.publishTime | formatDate">{{
new Date(album.publishTime).getFullYear()
}}</span>
<span> · {{ album.size }} {{ $t("common.songs") }}</span
<span> · {{ album.size }} {{ $t('common.songs') }}</span
>,
{{ albumTime | formatTime("Human") }}
{{ albumTime | formatTime('Human') }}
</div>
<div class="description" @click="showFullDescription = true">
{{ album.description }}
</div>
<div class="buttons" style="margin-top: 32px">
<ButtonTwoTone
icon-class="play"
@click.native="playAlbumByID(album.id)"
iconClass="play"
>
{{ $t("common.play") }}
{{ $t('common.play') }}
</ButtonTwoTone>
<ButtonTwoTone
:iconClass="dynamicDetail.isSub ? 'heart-solid' : 'heart'"
:iconButton="true"
:horizontalPadding="0"
:icon-class="dynamicDetail.isSub ? 'heart-solid' : 'heart'"
:icon-button="true"
:horizontal-padding="0"
:color="dynamicDetail.isSub ? 'blue' : 'grey'"
:textColor="dynamicDetail.isSub ? '#335eea' : ''"
:backgroundColor="
:text-color="dynamicDetail.isSub ? '#335eea' : ''"
:background-color="
dynamicDetail.isSub ? 'var(--color-secondary-bg)' : ''
"
@click.native="likeAlbum"
>
</ButtonTwoTone>
<ButtonTwoTone
iconClass="more"
:iconButton="true"
:horizontalPadding="0"
icon-class="more"
:icon-button="true"
:horizontal-padding="0"
color="grey"
@click.native="openMenu"
>
@ -72,22 +72,22 @@
</div>
</div>
<TrackList
:id="album.id"
:tracks="tracks"
:type="'album'"
:id="album.id"
:albumObject="album"
:album-object="album"
/>
<div class="extra-info">
<div class="album-time"></div>
<div class="release-date">
{{ $t("album.released") }}
{{ album.publishTime | formatDate("MMMM D, YYYY") }}
{{ $t('album.released') }}
{{ album.publishTime | formatDate('MMMM D, YYYY') }}
</div>
<div class="copyright" v-if="album.company !== null">
<div v-if="album.company !== null" class="copyright">
© {{ album.company }}
</div>
</div>
<div class="more-by" v-if="filteredMoreAlbums.length !== 0">
<div v-if="filteredMoreAlbums.length !== 0" class="more-by">
<div class="section-title">
More by
<router-link :to="`/artist/${album.artist.id}`"
@ -98,15 +98,15 @@
<CoverRow
type="album"
:items="filteredMoreAlbums"
subText="albumType+releaseYear"
sub-text="albumType+releaseYear"
/>
</div>
</div>
<Modal
:show="showFullDescription"
:close="() => (showFullDescription = false)"
:showFooter="false"
:clickOutsideHide="true"
:show-footer="false"
:click-outside-hide="true"
title="专辑介绍"
>
<p class="description-fulltext">
@ -114,9 +114,9 @@
</p>
</Modal>
<ContextMenu ref="albumMenu">
<div class="item">{{ $t("contextMenu.playNext") }}</div>
<div class="item">{{ $t('contextMenu.playNext') }}</div>
<div class="item" @click="likeAlbum(true)">{{
dynamicDetail.isSub ? "从音乐库删除" : "保存到音乐库"
dynamicDetail.isSub ? '从音乐库删除' : '保存到音乐库'
}}</div>
<div class="item">添加到歌单</div>
</ContextMenu>
@ -124,24 +124,24 @@
</template>
<script>
import { mapMutations, mapActions, mapState } from "vuex";
import { getArtistAlbum } from "@/api/artist";
import { getTrackDetail } from "@/api/track";
import { getAlbum, albumDynamicDetail, likeAAlbum } from "@/api/album";
import { splitSoundtrackAlbumTitle, splitAlbumTitle } from "@/utils/common";
import NProgress from "nprogress";
import { isAccountLoggedIn } from "@/utils/auth";
import { mapMutations, mapActions, mapState } from 'vuex';
import { getArtistAlbum } from '@/api/artist';
import { getTrackDetail } from '@/api/track';
import { getAlbum, albumDynamicDetail, likeAAlbum } from '@/api/album';
import { splitSoundtrackAlbumTitle, splitAlbumTitle } from '@/utils/common';
import NProgress from 'nprogress';
import { isAccountLoggedIn } from '@/utils/auth';
import ExplicitSymbol from "@/components/ExplicitSymbol.vue";
import ButtonTwoTone from "@/components/ButtonTwoTone.vue";
import ContextMenu from "@/components/ContextMenu.vue";
import TrackList from "@/components/TrackList.vue";
import CoverRow from "@/components/CoverRow.vue";
import Cover from "@/components/Cover.vue";
import Modal from "@/components/Modal.vue";
import ExplicitSymbol from '@/components/ExplicitSymbol.vue';
import ButtonTwoTone from '@/components/ButtonTwoTone.vue';
import ContextMenu from '@/components/ContextMenu.vue';
import TrackList from '@/components/TrackList.vue';
import CoverRow from '@/components/CoverRow.vue';
import Cover from '@/components/Cover.vue';
import Modal from '@/components/Modal.vue';
export default {
name: "Album",
name: 'Album',
components: {
Cover,
ButtonTwoTone,
@ -151,11 +151,16 @@ export default {
Modal,
ContextMenu,
},
beforeRouteUpdate(to, from, next) {
NProgress.start();
this.loadData(to.params.id);
next();
},
data() {
return {
album: {
id: 0,
picUrl: "",
picUrl: '',
artist: {
id: 0,
},
@ -165,27 +170,27 @@ export default {
show: false,
moreAlbums: [],
dynamicDetail: {},
subtitle: "",
title: "",
subtitle: '',
title: '',
};
},
computed: {
...mapState(["player", "data"]),
...mapState(['player', 'data']),
albumTime() {
let time = 0;
this.tracks.map((t) => (time = time + t.dt));
this.tracks.map(t => (time = time + t.dt));
return time;
},
filteredMoreAlbums() {
let moreAlbums = this.moreAlbums.filter((a) => a.id !== this.album.id);
let realAlbums = moreAlbums.filter((a) => a.type === "专辑");
let moreAlbums = this.moreAlbums.filter(a => a.id !== this.album.id);
let realAlbums = moreAlbums.filter(a => a.type === '专辑');
let eps = moreAlbums.filter(
(a) => a.type === "EP" || (a.type === "EP/Single" && a.size > 1)
a => a.type === 'EP' || (a.type === 'EP/Single' && a.size > 1)
);
let restItems = moreAlbums.filter(
(a) =>
realAlbums.find((a1) => a1.id === a.id) === undefined &&
eps.find((a1) => a1.id === a.id) === undefined
a =>
realAlbums.find(a1 => a1.id === a.id) === undefined &&
eps.find(a1 => a1.id === a.id) === undefined
);
if (realAlbums.length === 0) {
return [...realAlbums, ...eps, ...restItems].slice(0, 5);
@ -198,31 +203,31 @@ export default {
this.loadData(this.$route.params.id);
},
methods: {
...mapMutations(["appendTrackToPlayerList"]),
...mapActions(["playFirstTrackOnList", "playTrackOnListByID", "showToast"]),
playAlbumByID(id, trackID = "first") {
...mapMutations(['appendTrackToPlayerList']),
...mapActions(['playFirstTrackOnList', 'playTrackOnListByID', 'showToast']),
playAlbumByID(id, trackID = 'first') {
this.$store.state.player.playAlbumByID(id, trackID);
},
likeAlbum(toast = false) {
if (!isAccountLoggedIn()) {
this.showToast("此操作需要登录网易云账号");
this.showToast('此操作需要登录网易云账号');
return;
}
likeAAlbum({
id: this.album.id,
t: this.dynamicDetail.isSub ? 0 : 1,
})
.then((data) => {
.then(data => {
if (data.code === 200) {
this.dynamicDetail.isSub = !this.dynamicDetail.isSub;
if (toast === true)
this.showToast(
this.dynamicDetail.isSub ? "已保存到音乐库" : "已从音乐库删除"
this.dynamicDetail.isSub ? '已保存到音乐库' : '已从音乐库删除'
);
}
console.log(data);
})
.catch((error) => {
.catch(error => {
this.showToast(`${error.response.data.message || error}`);
});
},
@ -230,17 +235,17 @@ export default {
let splitTitle = splitSoundtrackAlbumTitle(this.album.name);
let splitTitle2 = splitAlbumTitle(splitTitle.title);
this.title = splitTitle2.title;
if (splitTitle.subtitle !== "" && splitTitle2.subtitle !== "") {
this.subtitle = splitTitle.subtitle + " · " + splitTitle2.subtitle;
if (splitTitle.subtitle !== '' && splitTitle2.subtitle !== '') {
this.subtitle = splitTitle.subtitle + ' · ' + splitTitle2.subtitle;
} else {
this.subtitle =
splitTitle.subtitle === ""
splitTitle.subtitle === ''
? splitTitle2.subtitle
: splitTitle.subtitle;
}
},
loadData(id) {
getAlbum(id).then((data) => {
getAlbum(id).then(data => {
this.album = data.album;
this.tracks = data.songs;
this.formatTitle();
@ -248,19 +253,17 @@ export default {
this.show = true;
// to get explicit mark
let trackIDs = this.tracks.map((t) => t.id);
getTrackDetail(trackIDs.join(",")).then((data) => {
let trackIDs = this.tracks.map(t => t.id);
getTrackDetail(trackIDs.join(',')).then(data => {
this.tracks = data.songs;
});
// get more album by this artist
getArtistAlbum({ id: this.album.artist.id, limit: 100 }).then(
(data) => {
this.moreAlbums = data.hotAlbums;
}
);
getArtistAlbum({ id: this.album.artist.id, limit: 100 }).then(data => {
this.moreAlbums = data.hotAlbums;
});
});
albumDynamicDetail(id).then((data) => {
albumDynamicDetail(id).then(data => {
this.dynamicDetail = data;
});
},
@ -268,11 +271,6 @@ export default {
this.$refs.albumMenu.openMenu(e);
},
},
beforeRouteUpdate(to, from, next) {
NProgress.start();
this.loadData(to.params.id);
next();
},
};
</script>

View file

@ -1,46 +1,46 @@
<template>
<div class="artist" v-show="show">
<div v-show="show" class="artist">
<div class="artist-info">
<div class="head">
<img :src="artist.img1v1Url | resizeImage(1024)" />
</div>
<div>
<div class="name">{{ artist.name }}</div>
<div class="artist">{{ $t("artist.artist") }}</div>
<div class="artist">{{ $t('artist.artist') }}</div>
<div class="statistics">
<a @click="scrollTo('popularTracks')"
>{{ artist.musicSize }} {{ $t("common.songs") }}</a
>{{ artist.musicSize }} {{ $t('common.songs') }}</a
>
·
<a @click="scrollTo('seeMore', 'start')"
>{{ artist.albumSize }} {{ $t("artist.withAlbums") }}</a
>{{ artist.albumSize }} {{ $t('artist.withAlbums') }}</a
>
·
<a @click="scrollTo('mvs')"
>{{ artist.mvSize }} {{ $t("artist.videos") }}</a
>{{ artist.mvSize }} {{ $t('artist.videos') }}</a
>
</div>
<div class="buttons">
<ButtonTwoTone @click.native="playPopularSongs()" :iconClass="`play`">
{{ $t("common.play") }}
<ButtonTwoTone :icon-class="play" @click.native="playPopularSongs()">
{{ $t('common.play') }}
</ButtonTwoTone>
<ButtonTwoTone @click.native="followArtist" color="grey">
<span v-if="artist.followed">{{ $t("artist.following") }}</span>
<span v-else>{{ $t("artist.follow") }}</span>
<ButtonTwoTone color="grey" @click.native="followArtist">
<span v-if="artist.followed">{{ $t('artist.following') }}</span>
<span v-else>{{ $t('artist.follow') }}</span>
</ButtonTwoTone>
</div>
</div>
</div>
<div class="latest-release">
<div class="section-title">{{ $t("artist.latestRelease") }}</div>
<div class="section-title">{{ $t('artist.latestRelease') }}</div>
<div class="release">
<div class="container">
<Cover
:imageUrl="latestRelease.picUrl | resizeImage"
type="album"
:id="latestRelease.id"
:fixedSize="128"
:playButtonSize="30"
:image-url="latestRelease.picUrl | resizeImage"
type="album"
:fixed-size="128"
:play-button-size="30"
/>
<div class="info">
<div class="name">
@ -53,60 +53,60 @@
</div>
<div class="type">
{{ latestRelease.type | formatAlbumType(latestRelease) }} ·
{{ latestRelease.size }} {{ $t("common.songs") }}
{{ latestRelease.size }} {{ $t('common.songs') }}
</div>
</div>
</div>
<div></div>
</div>
</div>
<div class="popular-tracks" id="popularTracks">
<div class="section-title">{{ $t("artist.popularSongs") }}</div>
<div id="popularTracks" class="popular-tracks">
<div class="section-title">{{ $t('artist.popularSongs') }}</div>
<TrackList
:tracks="popularTracks.slice(0, showMorePopTracks ? 24 : 12)"
:type="'tracklist'"
/>
<div class="show-more" id="seeMore">
<div id="seeMore" class="show-more">
<button @click="showMorePopTracks = !showMorePopTracks">
<span v-show="!showMorePopTracks">{{ $t("artist.showMore") }}</span>
<span v-show="showMorePopTracks">{{ $t("artist.showLess") }}</span>
<span v-show="!showMorePopTracks">{{ $t('artist.showMore') }}</span>
<span v-show="showMorePopTracks">{{ $t('artist.showLess') }}</span>
</button>
</div>
</div>
<div class="albums" id="albums" v-if="albums.length !== 0">
<div class="section-title">{{ $t("artist.albums") }}</div>
<div v-if="albums.length !== 0" id="albums" class="albums">
<div class="section-title">{{ $t('artist.albums') }}</div>
<CoverRow
:type="'album'"
:items="albums"
:subText="'releaseYear'"
:showPlayButton="true"
:sub-text="'releaseYear'"
:show-play-button="true"
/>
</div>
<div class="mvs" id="mvs" v-if="mvs.length !== 0">
<div v-if="mvs.length !== 0" id="mvs" class="mvs">
<div class="section-title"
>MVs
<router-link v-show="hasMoreMV" :to="`/artist/${this.artist.id}/mv`">{{
$t("home.seeMore")
$t('home.seeMore')
}}</router-link>
</div>
<MvRow :mvs="mvs" subtitle="publishTime" />
</div>
<div class="eps" v-if="eps.length !== 0">
<div class="section-title">{{ $t("artist.EPsSingles") }}</div>
<div v-if="eps.length !== 0" class="eps">
<div class="section-title">{{ $t('artist.EPsSingles') }}</div>
<CoverRow
:type="'album'"
:items="eps"
:subText="'albumType+releaseYear'"
:showPlayButton="true"
:sub-text="'albumType+releaseYear'"
:show-play-button="true"
/>
</div>
<div class="similar-artists" v-if="similarArtists.length !== 0">
<div v-if="similarArtists.length !== 0" class="similar-artists">
<div class="section-title">相似艺人</div>
<CoverRow
type="artist"
:columnNumber="6"
:column-number="6"
gap="36px 28px"
:items="similarArtists.slice(0, 12)"
/>
@ -115,42 +115,48 @@
</template>
<script>
import { mapMutations, mapActions, mapState } from "vuex";
import { mapMutations, mapActions, mapState } from 'vuex';
import {
getArtist,
getArtistAlbum,
artistMv,
followAArtist,
similarArtists,
} from "@/api/artist";
import { isAccountLoggedIn } from "@/utils/auth";
import NProgress from "nprogress";
} from '@/api/artist';
import { isAccountLoggedIn } from '@/utils/auth';
import NProgress from 'nprogress';
import ButtonTwoTone from "@/components/ButtonTwoTone.vue";
import TrackList from "@/components/TrackList.vue";
import CoverRow from "@/components/CoverRow.vue";
import Cover from "@/components/Cover.vue";
import MvRow from "@/components/MvRow.vue";
import ButtonTwoTone from '@/components/ButtonTwoTone.vue';
import TrackList from '@/components/TrackList.vue';
import CoverRow from '@/components/CoverRow.vue';
import Cover from '@/components/Cover.vue';
import MvRow from '@/components/MvRow.vue';
export default {
name: "Artist",
name: 'Artist',
components: { Cover, ButtonTwoTone, TrackList, CoverRow, MvRow },
beforeRouteUpdate(to, from, next) {
NProgress.start();
this.artist.img1v1Url =
'https://p1.music.126.net/VnZiScyynLG7atLIZ2YPkw==/18686200114669622.jpg';
this.loadData(to.params.id, next);
},
data() {
return {
show: false,
artist: {
img1v1Url:
"https://p1.music.126.net/VnZiScyynLG7atLIZ2YPkw==/18686200114669622.jpg",
'https://p1.music.126.net/VnZiScyynLG7atLIZ2YPkw==/18686200114669622.jpg',
},
popularTracks: [],
albumsData: [],
latestRelease: {
picUrl: "",
picUrl: '',
publishTime: 0,
id: 0,
name: "",
type: "",
size: "",
name: '',
type: '',
size: '',
},
showMorePopTracks: false,
mvs: [],
@ -159,73 +165,16 @@ export default {
};
},
computed: {
...mapState(["player"]),
...mapState(['player']),
albums() {
return this.albumsData.filter((a) => a.type === "专辑");
return this.albumsData.filter(a => a.type === '专辑');
},
eps() {
return this.albumsData.filter((a) =>
["EP/Single", "EP", "Single"].includes(a.type)
return this.albumsData.filter(a =>
['EP/Single', 'EP', 'Single'].includes(a.type)
);
},
},
methods: {
...mapMutations(["appendTrackToPlayerList"]),
...mapActions(["playFirstTrackOnList", "playTrackOnListByID"]),
loadData(id, next = undefined) {
getArtist(id).then((data) => {
this.artist = data.artist;
this.popularTracks = data.hotSongs;
if (next !== undefined) next();
NProgress.done();
this.show = true;
});
getArtistAlbum({ id: id, limit: 200 }).then((data) => {
this.albumsData = data.hotAlbums;
this.latestRelease = data.hotAlbums[0];
});
artistMv({ id }).then((data) => {
this.mvs = data.mvs;
this.hasMoreMV = data.hasMore;
});
similarArtists(id).then((data) => {
this.similarArtists = data.artists;
});
},
goToAlbum(id) {
this.$router.push({
name: "album",
params: { id },
});
},
playPopularSongs(trackID = "first") {
let trackIDs = this.popularTracks.map((t) => t.id);
this.$store.state.player.replacePlaylist(
trackIDs,
this.artist.id,
"artist",
trackID
);
},
followArtist() {
if (!isAccountLoggedIn()) {
this.showToast("此操作需要登录网易云账号");
return;
}
followAArtist({
id: this.artist.id,
t: this.artist.followed ? 0 : 1,
}).then((data) => {
if (data.code === 200) this.artist.followed = !this.artist.followed;
});
},
scrollTo(div, block = "center") {
document.getElementById(div).scrollIntoView({
behavior: "smooth",
block,
});
},
},
created() {
this.loadData(this.$route.params.id);
},
@ -238,11 +187,62 @@ export default {
}
}
},
beforeRouteUpdate(to, from, next) {
NProgress.start();
this.artist.img1v1Url =
"https://p1.music.126.net/VnZiScyynLG7atLIZ2YPkw==/18686200114669622.jpg";
this.loadData(to.params.id, next);
methods: {
...mapMutations(['appendTrackToPlayerList']),
...mapActions(['playFirstTrackOnList', 'playTrackOnListByID']),
loadData(id, next = undefined) {
getArtist(id).then(data => {
this.artist = data.artist;
this.popularTracks = data.hotSongs;
if (next !== undefined) next();
NProgress.done();
this.show = true;
});
getArtistAlbum({ id: id, limit: 200 }).then(data => {
this.albumsData = data.hotAlbums;
this.latestRelease = data.hotAlbums[0];
});
artistMv({ id }).then(data => {
this.mvs = data.mvs;
this.hasMoreMV = data.hasMore;
});
similarArtists(id).then(data => {
this.similarArtists = data.artists;
});
},
goToAlbum(id) {
this.$router.push({
name: 'album',
params: { id },
});
},
playPopularSongs(trackID = 'first') {
let trackIDs = this.popularTracks.map(t => t.id);
this.$store.state.player.replacePlaylist(
trackIDs,
this.artist.id,
'artist',
trackID
);
},
followArtist() {
if (!isAccountLoggedIn()) {
this.showToast('此操作需要登录网易云账号');
return;
}
followAArtist({
id: this.artist.id,
t: this.artist.followed ? 0 : 1,
}).then(data => {
if (data.code === 200) this.artist.followed = !this.artist.followed;
});
},
scrollTo(div, block = 'center') {
document.getElementById(div).scrollIntoView({
behavior: 'smooth',
block,
});
},
},
};
</script>

View file

@ -7,26 +7,32 @@
</h1>
<MvRow :mvs="mvs" subtitle="publishTime" />
<div class="load-more">
<ButtonTwoTone v-show="hasMore" @click.native="loadMVs" color="grey">{{
$t("explore.loadMore")
<ButtonTwoTone v-show="hasMore" color="grey" @click.native="loadMVs">{{
$t('explore.loadMore')
}}</ButtonTwoTone>
</div>
</div>
</template>
<script>
import { artistMv, getArtist } from "@/api/artist";
import NProgress from "nprogress";
import { artistMv, getArtist } from '@/api/artist';
import NProgress from 'nprogress';
import ButtonTwoTone from "@/components/ButtonTwoTone.vue";
import MvRow from "@/components/MvRow.vue";
import ButtonTwoTone from '@/components/ButtonTwoTone.vue';
import MvRow from '@/components/MvRow.vue';
export default {
name: "artistMV",
name: 'artistMV',
components: {
MvRow,
ButtonTwoTone,
},
beforeRouteUpdate(to, from, next) {
NProgress.start();
this.id = to.params.id;
this.loadData();
next();
},
data() {
return {
id: 0,
@ -36,24 +42,6 @@ export default {
mvs: [],
};
},
methods: {
loadData() {
getArtist(this.id).then((data) => {
this.artist = data.artist;
});
this.loadMVs();
},
loadMVs() {
artistMv({ id: this.id, limit: 100, offset: this.mvs.length }).then(
(data) => {
this.mvs.push(...data.mvs);
this.hasMore = data.hasMore;
NProgress.done();
this.show = true;
}
);
},
},
created() {
this.id = this.$route.params.id;
this.loadData();
@ -68,11 +56,23 @@ export default {
this.loadData();
}
},
beforeRouteUpdate(to, from, next) {
NProgress.start();
this.id = to.params.id;
this.loadData();
next();
methods: {
loadData() {
getArtist(this.id).then(data => {
this.artist = data.artist;
});
this.loadMVs();
},
loadMVs() {
artistMv({ id: this.id, limit: 100, offset: this.mvs.length }).then(
data => {
this.mvs.push(...data.mvs);
this.hasMore = data.hasMore;
NProgress.done();
this.show = true;
}
);
},
},
};
</script>

View file

@ -8,20 +8,20 @@
<TrackList
:tracks="dailyTracks"
type="playlist"
dbclickTrackFunc="dailyTracks"
dbclick-track-func="dailyTracks"
/>
</div>
</template>
<script>
import { mapMutations, mapState } from "vuex";
import NProgress from "nprogress";
import { dailyRecommendTracks } from "@/api/playlist";
import { mapMutations, mapState } from 'vuex';
import NProgress from 'nprogress';
import { dailyRecommendTracks } from '@/api/playlist';
import TrackList from "@/components/TrackList.vue";
import TrackList from '@/components/TrackList.vue';
export default {
name: "dailyTracks",
name: 'dailyTracks',
components: {
TrackList,
},
@ -30,6 +30,9 @@ export default {
show: false,
};
},
computed: {
...mapState(['player', 'data', 'dailyTracks']),
},
created() {
if (this.dailyTracks.length === 0) {
NProgress.start();
@ -38,13 +41,10 @@ export default {
this.show = true;
}
},
computed: {
...mapState(["player", "data", "dailyTracks"]),
},
methods: {
...mapMutations(["updateDailyTracks"]),
...mapMutations(['updateDailyTracks']),
loadDailyTracks() {
dailyRecommendTracks().then((result) => {
dailyRecommendTracks().then(result => {
this.updateDailyTracks(result.data.dailySongs);
NProgress.done();
this.show = true;

View file

@ -1,6 +1,6 @@
<template>
<div class="explore">
<h1>{{ $t("explore.explore") }}</h1>
<h1>{{ $t('explore.explore') }}</h1>
<div class="buttons">
<div
v-for="category in settings.enabledPlaylistCategories"
@ -57,29 +57,29 @@
color="grey"
:loading="loadingMore"
@click.native="getPlaylist"
>{{ $t("explore.loadMore") }}</ButtonTwoTone
>{{ $t('explore.loadMore') }}</ButtonTwoTone
>
</div>
</div>
</template>
<script>
import { mapState, mapMutations } from "vuex";
import NProgress from "nprogress";
import { mapState, mapMutations } from 'vuex';
import NProgress from 'nprogress';
import {
topPlaylist,
highQualityPlaylist,
recommendPlaylist,
toplists,
} from "@/api/playlist";
import { playlistCategories } from "@/utils/staticData";
} from '@/api/playlist';
import { playlistCategories } from '@/utils/staticData';
import ButtonTwoTone from "@/components/ButtonTwoTone.vue";
import CoverRow from "@/components/CoverRow.vue";
import SvgIcon from "@/components/SvgIcon.vue";
import ButtonTwoTone from '@/components/ButtonTwoTone.vue';
import CoverRow from '@/components/CoverRow.vue';
import SvgIcon from '@/components/SvgIcon.vue';
export default {
name: "Explore",
name: 'Explore',
components: {
CoverRow,
ButtonTwoTone,
@ -99,38 +99,38 @@ export default {
return {
show: false,
playlists: [],
activeCategory: "全部",
activeCategory: '全部',
loadingMore: false,
showLoadMoreButton: false,
hasMore: true,
allBigCats: ["语种", "风格", "场景", "情感", "主题"],
allBigCats: ['语种', '风格', '场景', '情感', '主题'],
showCatOptions: false,
};
},
computed: {
...mapState(["settings"]),
...mapState(['settings']),
subText() {
if (this.activeCategory === "排行榜") return "updateFrequency";
if (this.activeCategory === "推荐歌单") return "copywriter";
return "none";
if (this.activeCategory === '排行榜') return 'updateFrequency';
if (this.activeCategory === '推荐歌单') return 'copywriter';
return 'none';
},
},
activated() {
this.loadData();
},
methods: {
...mapMutations(["togglePlaylistCategory"]),
...mapMutations(['togglePlaylistCategory']),
loadData() {
if (!this.show) NProgress.start();
this.activeCategory =
this.$route.query.category === undefined
? "全部"
? '全部'
: this.$route.query.category;
this.getPlaylist();
},
goToCategory(Category) {
this.showCatOptions = false;
this.$router.push({ path: "/explore?category=" + Category });
this.$router.push({ path: '/explore?category=' + Category });
},
updatePlaylist(playlists) {
this.playlists.push(...playlists);
@ -141,19 +141,19 @@ export default {
},
getPlaylist() {
this.loadingMore = true;
if (this.activeCategory === "推荐歌单") {
if (this.activeCategory === '推荐歌单') {
return this.getRecommendPlayList();
}
if (this.activeCategory === "精品歌单") {
if (this.activeCategory === '精品歌单') {
return this.getHighQualityPlaylist();
}
if (this.activeCategory === "排行榜") {
if (this.activeCategory === '排行榜') {
return this.getTopLists();
}
return this.getTopPlayList();
},
getRecommendPlayList() {
recommendPlaylist({ limit: 100 }).then((data) => {
recommendPlaylist({ limit: 100 }).then(data => {
this.playlists = [];
this.updatePlaylist(data.result);
});
@ -162,13 +162,13 @@ export default {
let playlists = this.playlists;
let before =
playlists.length !== 0 ? playlists[playlists.length - 1].updateTime : 0;
highQualityPlaylist({ limit: 50, before }).then((data) => {
highQualityPlaylist({ limit: 50, before }).then(data => {
this.updatePlaylist(data.playlists);
this.hasMore = data.more;
});
},
getTopLists() {
toplists().then((data) => {
toplists().then(data => {
this.playlists = [];
this.updatePlaylist(data.list);
});
@ -177,13 +177,13 @@ export default {
topPlaylist({
cat: this.activeCategory,
offset: this.playlists.length,
}).then((data) => {
}).then(data => {
this.updatePlaylist(data.playlists);
this.hasMore = data.more;
});
},
getCatsByBigCat(name) {
return playlistCategories.filter((c) => c.bigCat === name);
return playlistCategories.filter(c => c.bigCat === name);
},
toggleCat(name) {
this.togglePlaylistCategory(name);

View file

@ -1,25 +1,25 @@
<template>
<div class="home" v-show="show">
<div class="index-row" v-if="settings.showPlaylistsByAppleMusic !== false">
<div v-show="show" class="home">
<div v-if="settings.showPlaylistsByAppleMusic !== false" class="index-row">
<div class="title"> by Apple Music </div>
<CoverRow
:type="'playlist'"
:items="byAppleMusic"
:subText="'appleMusic'"
:imageSize="1024"
sub-text="appleMusic"
:image-size="1024"
/>
</div>
<div class="index-row">
<div class="title">
{{ $t("home.recommendPlaylist") }}
{{ $t('home.recommendPlaylist') }}
<router-link to="/explore?category=推荐歌单">{{
$t("home.seeMore")
$t('home.seeMore')
}}</router-link>
</div>
<CoverRow
:type="'playlist'"
:items="recommendPlaylist.items"
:subText="'copywriter'"
sub-text="copywriter"
/>
</div>
<div class="index-row">
@ -30,51 +30,55 @@
</div>
</div>
<div class="index-row">
<div class="title">{{ $t("home.recommendArtist") }}</div>
<div class="title">{{ $t('home.recommendArtist') }}</div>
<CoverRow
type="artist"
:columnNumber="6"
:column-number="6"
:items="recommendArtists.items"
/>
</div>
<div class="index-row">
<div class="title">
{{ $t("home.newAlbum") }}
<router-link to="/new-album">{{ $t("home.seeMore") }}</router-link>
{{ $t('home.newAlbum') }}
<router-link to="/new-album">{{ $t('home.seeMore') }}</router-link>
</div>
<CoverRow type="album" :items="newReleasesAlbum.items" subText="artist" />
<CoverRow
type="album"
:items="newReleasesAlbum.items"
sub-text="artist"
/>
</div>
<div class="index-row">
<div class="title">
{{ $t("home.charts") }}
{{ $t('home.charts') }}
<router-link to="/explore?category=排行榜">{{
$t("home.seeMore")
$t('home.seeMore')
}}</router-link>
</div>
<CoverRow
type="playlist"
:items="topList.items"
:subText="'updateFrequency'"
:imageSize="1024"
sub-text="updateFrequency"
:image-size="1024"
/>
</div>
</div>
</template>
<script>
import { toplists, recommendPlaylist } from "@/api/playlist";
import { toplistOfArtists } from "@/api/artist";
import { byAppleMusic } from "@/utils/staticData";
import { countDBSize } from "@/utils/db";
import { newAlbums } from "@/api/album";
import NProgress from "nprogress";
import { mapState } from "vuex";
import CoverRow from "@/components/CoverRow.vue";
import FMCard from "@/components/FMCard.vue";
import DailyTracksCard from "@/components/DailyTracksCard.vue";
import { toplists, recommendPlaylist } from '@/api/playlist';
import { toplistOfArtists } from '@/api/artist';
import { byAppleMusic } from '@/utils/staticData';
import { countDBSize } from '@/utils/db';
import { newAlbums } from '@/api/album';
import NProgress from 'nprogress';
import { mapState } from 'vuex';
import CoverRow from '@/components/CoverRow.vue';
import FMCard from '@/components/FMCard.vue';
import DailyTracksCard from '@/components/DailyTracksCard.vue';
export default {
name: "Home",
name: 'Home',
components: { CoverRow, FMCard, DailyTracksCard },
data() {
return {
@ -92,28 +96,31 @@ export default {
};
},
computed: {
...mapState(["settings"]),
...mapState(['settings']),
byAppleMusic() {
return byAppleMusic;
},
},
activated() {
this.loadData();
},
methods: {
loadData() {
if (!this.show) NProgress.start();
recommendPlaylist({
limit: 10,
}).then((data) => {
}).then(data => {
this.recommendPlaylist.items = data.result;
NProgress.done();
this.show = true;
});
newAlbums({
area: "EA",
area: 'EA',
limit: 10,
}).then((data) => {
}).then(data => {
this.newReleasesAlbum.items = data.albums;
});
toplistOfArtists(2).then((data) => {
toplistOfArtists(2).then(data => {
let indexs = [];
while (indexs.length < 6) {
let tmp = ~~(Math.random() * 100);
@ -124,17 +131,14 @@ export default {
indexs.includes(index)
);
});
toplists().then((data) => {
this.topList.items = data.list.filter((l) =>
toplists().then(data => {
this.topList.items = data.list.filter(l =>
this.topList.ids.includes(l.id)
);
});
countDBSize();
},
},
activated() {
this.loadData();
},
};
</script>

View file

@ -6,36 +6,36 @@
<img src="/img/logos/lastfm.png" />
</div>
<div class="message">{{ message }}</div>
<button @click="close" v-show="done"> 完成 </button>
<button v-show="done" @click="close"> 完成 </button>
</div>
</template>
<script>
import { authGetSession } from "@/api/lastfm";
import { authGetSession } from '@/api/lastfm';
export default {
name: "lastfmCallback",
name: 'LastfmCallback',
data() {
return { message: "请稍等...", done: false };
return { message: '请稍等...', done: false };
},
created() {
const token = new URLSearchParams(window.location.search).get("token");
const token = new URLSearchParams(window.location.search).get('token');
if (!token) {
this.message = "连接失败请重试或联系开发者无Token";
this.message = '连接失败请重试或联系开发者无Token';
this.done = true;
return;
}
console.log(token);
authGetSession(token).then((result) => {
authGetSession(token).then(result => {
console.log(result);
if (!result.data.session) {
this.message = "连接失败请重试或联系开发者无Session";
this.message = '连接失败请重试或联系开发者无Session';
this.done = true;
return;
}
localStorage.setItem("lastfm", JSON.stringify(result.data.session));
this.$store.commit("updateLastfm", result.data.session);
this.message = "已成功连接到 Last.fm";
localStorage.setItem('lastfm', JSON.stringify(result.data.session));
this.$store.commit('updateLastfm', result.data.session);
this.message = '已成功连接到 Last.fm';
this.done = true;
});
},

View file

@ -14,8 +14,8 @@
>
<div class="container" :class="{ active: activeCard === 1 }">
<div class="title-info">
<div class="title">{{ $t("login.loginText") }}</div>
<div class="info">{{ $t("login.accessToAll") }}</div>
<div class="title">{{ $t('login.loginText') }}</div>
<div class="info">{{ $t('login.accessToAll') }}</div>
</div>
<svg-icon icon-class="arrow-right"></svg-icon>
</div>
@ -28,8 +28,8 @@
>
<div class="container" :class="{ active: activeCard === 2 }">
<div class="title-info">
<div class="title">{{ $t("login.search") }}</div>
<div class="info">{{ $t("login.readonly") }}</div>
<div class="title">{{ $t('login.search') }}</div>
<div class="info">{{ $t('login.readonly') }}</div>
</div>
<svg-icon icon-class="arrow-right"></svg-icon>
</div>
@ -39,12 +39,12 @@
</template>
<script>
import NProgress from "nprogress";
import NProgress from 'nprogress';
import SvgIcon from "@/components/SvgIcon.vue";
import SvgIcon from '@/components/SvgIcon.vue';
export default {
name: "Login",
name: 'Login',
components: {
SvgIcon,
},
@ -58,7 +58,7 @@ export default {
},
methods: {
goTo(path) {
this.$router.push({ path: "/login/" + path });
this.$router.push({ path: '/login/' + path });
},
},
};

View file

@ -3,26 +3,26 @@
<div class="section-1">
<img src="/img/logos/netease-music.png" />
</div>
<div class="title">{{ $t("login.loginText") }}</div>
<div class="title">{{ $t('login.loginText') }}</div>
<div class="section-2">
<div class="input-box" v-show="mode === 'phone'">
<div v-show="mode === 'phone'" class="input-box">
<div class="container" :class="{ active: inputFocus === 'phone' }">
<svg-icon icon-class="mobile" />
<div class="inputs">
<input
id="countryCode"
v-model="countryCode"
:placeholder="
inputFocus === 'phone' ? '' : $t('login.countryCode')
"
v-model="countryCode"
@focus="inputFocus = 'phone'"
@blur="inputFocus = ''"
@keyup.enter="login"
/>
<input
id="phoneNumber"
:placeholder="inputFocus === 'phone' ? '' : $t('login.phone')"
v-model="phoneNumber"
:placeholder="inputFocus === 'phone' ? '' : $t('login.phone')"
@focus="inputFocus = 'phone'"
@blur="inputFocus = ''"
@keyup.enter="login"
@ -30,15 +30,15 @@
</div>
</div>
</div>
<div class="input-box" v-show="mode === 'email'">
<div v-show="mode === 'email'" class="input-box">
<div class="container" :class="{ active: inputFocus === 'email' }">
<svg-icon icon-class="mail" />
<div class="inputs">
<input
type="email"
id="email"
:placeholder="inputFocus === 'email' ? '' : $t('login.email')"
v-model="email"
type="email"
:placeholder="inputFocus === 'email' ? '' : $t('login.email')"
@focus="inputFocus = 'email'"
@blur="inputFocus = ''"
@keyup.enter="login"
@ -51,12 +51,12 @@
<svg-icon icon-class="lock" />
<div class="inputs">
<input
type="password"
id="password"
v-model="password"
type="password"
:placeholder="
inputFocus === 'password' ? '' : $t('login.password')
"
v-model="password"
@focus="inputFocus = 'password'"
@blur="inputFocus = ''"
@keyup.enter="login"
@ -66,8 +66,8 @@
</div>
</div>
<div class="confirm">
<button @click="login" v-show="!processing">
{{ $t("login.login") }}
<button v-show="!processing" @click="login">
{{ $t('login.login') }}
</button>
<button v-show="processing" class="loading" disabled>
<span></span>
@ -77,10 +77,10 @@
</div>
<div class="other-login">
<a v-show="mode === 'phone'" @click="mode = 'email'">{{
$t("login.loginWithEmail")
$t('login.loginWithEmail')
}}</a>
<a v-show="mode === 'email'" @click="mode = 'phone'">{{
$t("login.loginWithPhone")
$t('login.loginWithPhone')
}}</a>
</div>
<div
@ -91,25 +91,25 @@
</template>
<script>
import NProgress from "nprogress";
import { loginWithPhone, loginWithEmail } from "@/api/auth";
import { setCookies } from "@/utils/auth";
import md5 from "crypto-js/md5";
import { mapMutations } from "vuex";
import nativeAlert from "@/utils/nativeAlert";
import NProgress from 'nprogress';
import { loginWithPhone, loginWithEmail } from '@/api/auth';
import { setCookies } from '@/utils/auth';
import md5 from 'crypto-js/md5';
import { mapMutations } from 'vuex';
import nativeAlert from '@/utils/nativeAlert';
export default {
name: "Login",
name: 'Login',
data() {
return {
processing: false,
mode: "email",
countryCode: "+86",
phoneNumber: "",
email: "",
password: "",
smsCode: "",
inputFocus: "",
mode: 'email',
countryCode: '+86',
phoneNumber: '',
email: '',
password: '',
smsCode: '',
inputFocus: '',
};
},
computed: {
@ -118,20 +118,20 @@ export default {
},
},
created() {
if (this.$route.query.mode === "phone") {
this.mode = "phone";
if (this.$route.query.mode === 'phone') {
this.mode = 'phone';
}
NProgress.done();
},
methods: {
...mapMutations(["updateData"]),
...mapMutations(['updateData']),
validatePhone() {
if (
this.countryCode === "" ||
this.phone === "" ||
this.password === ""
this.countryCode === '' ||
this.phone === '' ||
this.password === ''
) {
nativeAlert("国家区号或手机号不正确");
nativeAlert('国家区号或手机号不正确');
this.processing = false;
return false;
}
@ -140,27 +140,27 @@ export default {
validateEmail() {
const emailReg = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (
this.email === "" ||
this.password === "" ||
this.email === '' ||
this.password === '' ||
!emailReg.test(this.email)
) {
nativeAlert("邮箱不正确");
nativeAlert('邮箱不正确');
return false;
}
return true;
},
login() {
if (this.mode === "phone") {
if (this.mode === 'phone') {
this.processing = this.validatePhone();
if (!this.processing) return;
loginWithPhone({
countrycode: this.countryCode.replace("+", "").replace(/\s/g, ""),
phone: this.phoneNumber.replace(/\s/g, ""),
password: "fakePassword",
countrycode: this.countryCode.replace('+', '').replace(/\s/g, ''),
phone: this.phoneNumber.replace(/\s/g, ''),
password: 'fakePassword',
md5_password: md5(this.password).toString(),
})
.then(this.handleLoginResponse)
.catch((error) => {
.catch(error => {
this.processing = false;
nativeAlert(`发生错误,请检查你的账号密码是否正确\n${error}`);
});
@ -168,12 +168,12 @@ export default {
this.processing = this.validateEmail();
if (!this.processing) return;
loginWithEmail({
email: this.email.replace(/\s/g, ""),
password: "fakePassword",
email: this.email.replace(/\s/g, ''),
password: 'fakePassword',
md5_password: md5(this.password).toString(),
})
.then(this.handleLoginResponse)
.catch((error) => {
.catch(error => {
this.processing = false;
nativeAlert(`发生错误,请检查你的账号密码是否正确\n${error}`);
});
@ -186,13 +186,13 @@ export default {
}
if (data.code === 200) {
setCookies(data.cookie);
this.updateData({ key: "user", value: data.profile });
this.updateData({ key: "loginMode", value: "account" });
this.$router.push({ path: "/library" });
this.updateData({ key: 'user', value: data.profile });
this.updateData({ key: 'loginMode', value: 'account' });
this.$router.push({ path: '/library' });
} else {
this.processing = false;
console.log(data.msg);
nativeAlert(data.msg ?? data.message ?? "账号或密码错误,请检查");
nativeAlert(data.msg ?? data.message ?? '账号或密码错误,请检查');
}
},
},

View file

@ -1,15 +1,15 @@
<template>
<div class="login">
<div>
<div class="title">{{ $t("login.usernameLogin") }}</div>
<div class="sestion">
<div class="title">{{ $t('login.usernameLogin') }}</div>
<div class="section">
<div class="search-box">
<div class="container">
<svg-icon icon-class="search" />
<div class="input">
<input
:placeholder="$t('login.searchHolder')"
v-model="keyword"
:placeholder="$t('login.searchHolder')"
@keydown.enter="throttleSearch"
/>
</div>
@ -17,17 +17,17 @@
</div>
</div>
<div class="sestion">
<div class="name" v-show="activeUser.nickname === undefined">
{{ $t("login.enterTip") }}
<div v-show="activeUser.nickname === undefined" class="name">
{{ $t('login.enterTip') }}
</div>
<div class="name" v-show="activeUser.nickname !== undefined">
{{ $t("login.choose") }}
<div v-show="activeUser.nickname !== undefined" class="name">
{{ $t('login.choose') }}
</div>
<div class="user-list">
<div
class="user"
v-for="user in result"
:key="user.id"
class="user"
:class="{ active: user.nickname === activeUser.nickname }"
@click="activeUser = user"
>
@ -39,32 +39,32 @@
</div>
</div>
<ButtonTwoTone
@click.native="confirm"
v-show="activeUser.nickname !== undefined"
@click.native="confirm"
>
{{ $t("login.confirm") }}
{{ $t('login.confirm') }}
</ButtonTwoTone>
</div>
</div>
</template>
<script>
import { mapMutations } from "vuex";
import NProgress from "nprogress";
import { search } from "@/api/others";
import { userPlaylist } from "@/api/user";
import { throttle } from "@/utils/common";
import { mapMutations } from 'vuex';
import NProgress from 'nprogress';
import { search } from '@/api/others';
import { userPlaylist } from '@/api/user';
import { throttle } from '@/utils/common';
import ButtonTwoTone from "@/components/ButtonTwoTone.vue";
import ButtonTwoTone from '@/components/ButtonTwoTone.vue';
export default {
name: "loginUsername",
name: 'LoginUsername',
components: {
ButtonTwoTone,
},
data() {
return {
keyword: "",
keyword: '',
result: [],
activeUser: {},
};
@ -73,26 +73,26 @@ export default {
NProgress.done();
},
methods: {
...mapMutations(["updateData"]),
...mapMutations(['updateData']),
search() {
if (!this.keyword) return;
search({ keywords: this.keyword, limit: 9, type: 1002 }).then((data) => {
search({ keywords: this.keyword, limit: 9, type: 1002 }).then(data => {
this.result = data.result.userprofiles;
this.activeUser = this.result[0];
});
},
confirm() {
this.updateData({ key: "user", value: this.activeUser });
this.updateData({ key: "loginMode", value: "username" });
this.updateData({ key: 'user', value: this.activeUser });
this.updateData({ key: 'loginMode', value: 'username' });
userPlaylist({
uid: this.activeUser.userId,
limit: 1,
}).then((data) => {
}).then(data => {
this.updateData({
key: "likedSongPlaylistID",
key: 'likedSongPlaylistID',
value: data.playlist[0].id,
});
this.$router.push({ path: "/library" });
this.$router.push({ path: '/library' });
});
},
throttleSearch: throttle(function () {

View file

@ -215,7 +215,7 @@ export default {
return this.player.currentTrack?.al?.picUrl + '?param=1024y1024';
},
bgImageUrl() {
return this.player.currentTrack?.al?.picUrl + "?param=500y500";
return this.player.currentTrack?.al?.picUrl + '?param=500y500';
},
progress: {
get() {

View file

@ -13,8 +13,8 @@
{{ mv.data.name }}
<div class="like-button">
<button-icon @click.native="likeMV">
<svg-icon icon-class="heart-solid" v-if="mv.subed"></svg-icon>
<svg-icon icon-class="heart" v-else></svg-icon>
<svg-icon v-if="mv.subed" icon-class="heart-solid"></svg-icon>
<svg-icon v-else icon-class="heart"></svg-icon>
</button-icon>
</div>
</div>
@ -25,107 +25,107 @@
</div>
</div>
<div class="more-video">
<div class="section-title">{{ $t("mv.moreVideo") }}</div>
<div class="section-title">{{ $t('mv.moreVideo') }}</div>
<MvRow :mvs="simiMvs" />
</div>
</div>
</template>
<script>
import { mvDetail, mvUrl, simiMv, likeAMV } from "@/api/mv";
import { isAccountLoggedIn } from "@/utils/auth";
import NProgress from "nprogress";
import "@/assets/css/plyr.css";
import Plyr from "plyr";
import { mvDetail, mvUrl, simiMv, likeAMV } from '@/api/mv';
import { isAccountLoggedIn } from '@/utils/auth';
import NProgress from 'nprogress';
import '@/assets/css/plyr.css';
import Plyr from 'plyr';
import ButtonIcon from "@/components/ButtonIcon.vue";
import MvRow from "@/components/MvRow.vue";
import { mapActions } from "vuex";
import ButtonIcon from '@/components/ButtonIcon.vue';
import MvRow from '@/components/MvRow.vue';
import { mapActions } from 'vuex';
export default {
name: "mv",
name: 'mv',
components: {
MvRow,
ButtonIcon,
},
beforeRouteUpdate(to, from, next) {
this.getData(to.params.id);
next();
},
data() {
return {
mv: {
url: "",
url: '',
data: {
name: "",
artistName: "",
playCount: "",
publishTime: "",
name: '',
artistName: '',
playCount: '',
publishTime: '',
},
},
player: null,
simiMvs: [],
};
},
methods: {
...mapActions(["showToast"]),
getData(id) {
mvDetail(id).then((data) => {
this.mv = data;
let requests = data.data.brs.map((br) => {
return mvUrl({ id, r: br.br });
});
Promise.all(requests).then((results) => {
let sources = results.map((result) => {
return {
src: result.data.url.replace(/^http:/, "https:"),
type: "video/mp4",
size: result.data.r,
};
});
this.player.source = {
type: "video",
title: this.mv.data.name,
sources: sources,
poster: this.mv.data.cover.replace(/^http:/, "https:"),
};
NProgress.done();
});
});
simiMv(id).then((data) => {
this.simiMvs = data.mvs;
});
},
likeMV() {
if (!isAccountLoggedIn()) {
this.showToast("此操作需要登录网易云账号");
return;
}
likeAMV({
mvid: this.mv.data.id,
t: this.mv.subed ? 0 : 1,
}).then((data) => {
if (data.code === 200) this.mv.subed = !this.mv.subed;
});
},
},
mounted() {
let videoOptions = {
settings: ["quality"],
settings: ['quality'],
autoplay: false,
quality: {
default: 1080,
options: [1080, 720, 480, 240],
},
};
if (this.$route.query.autoplay === "true") videoOptions.autoplay = true;
if (this.$route.query.autoplay === 'true') videoOptions.autoplay = true;
this.player = new Plyr(this.$refs.videoPlayer, videoOptions);
this.player.volume = this.$store.state.player.volume;
this.player.on("playing", () => {
this.player.on('playing', () => {
this.$store.state.player.pause();
});
this.getData(this.$route.params.id);
console.log("网易云你这mv音频码率也太糊了吧🙄");
console.log('网易云你这mv音频码率也太糊了吧🙄');
},
beforeRouteUpdate(to, from, next) {
this.getData(to.params.id);
next();
methods: {
...mapActions(['showToast']),
getData(id) {
mvDetail(id).then(data => {
this.mv = data;
let requests = data.data.brs.map(br => {
return mvUrl({ id, r: br.br });
});
Promise.all(requests).then(results => {
let sources = results.map(result => {
return {
src: result.data.url.replace(/^http:/, 'https:'),
type: 'video/mp4',
size: result.data.r,
};
});
this.player.source = {
type: 'video',
title: this.mv.data.name,
sources: sources,
poster: this.mv.data.cover.replace(/^http:/, 'https:'),
};
NProgress.done();
});
});
simiMv(id).then(data => {
this.simiMvs = data.mvs;
});
},
likeMV() {
if (!isAccountLoggedIn()) {
this.showToast('此操作需要登录网易云账号');
return;
}
likeAMV({
mvid: this.mv.data.id,
t: this.mv.subed ? 0 : 1,
}).then(data => {
if (data.code === 200) this.mv.subed = !this.mv.subed;
});
},
},
};
</script>

View file

@ -1,12 +1,12 @@
<template>
<div class="newAlbum">
<h1>{{ $t("home.newAlbum") }}</h1>
<h1>{{ $t('home.newAlbum') }}</h1>
<div class="playlist-row">
<div class="playlists">
<CoverRow
type="album"
:items="albums"
subText="artist"
sub-text="artist"
:show-play-button="true"
/>
</div>
@ -15,25 +15,25 @@
</template>
<script>
import { newAlbums } from "@/api/album";
import NProgress from "nprogress";
import { newAlbums } from '@/api/album';
import NProgress from 'nprogress';
import CoverRow from "@/components/CoverRow.vue";
import CoverRow from '@/components/CoverRow.vue';
export default {
components: {
CoverRow,
},
data() {
return {
albums: [],
};
},
components: {
CoverRow,
},
created() {
newAlbums({
area: "EA",
area: 'EA',
limit: 100,
}).then((data) => {
}).then(data => {
this.albums = data.albums;
NProgress.done();
});

View file

@ -1,37 +1,37 @@
<template>
<div class="next-tracks">
<h1>{{ $t("next.nowPlaying") }}</h1>
<h1>{{ $t('next.nowPlaying') }}</h1>
<TrackList
:tracks="[currentTrack]"
type="playlist"
dbclickTrackFunc="none"
dbclick-track-func="none"
/>
<h1 v-show="playNextList.length > 0">插队播放</h1>
<TrackList
v-show="playNextList.length > 0"
:tracks="playNextTracks"
type="playlist"
:highlightPlayingTrack="false"
dbclickTrackFunc="playTrackOnListByID"
itemKey="id+index"
v-show="playNextList.length > 0"
:highlight-playing-track="false"
dbclick-track-func="playTrackOnListByID"
item-key="id+index"
/>
<h1>{{ $t("next.nextUp") }}</h1>
<h1>{{ $t('next.nextUp') }}</h1>
<TrackList
:tracks="filteredTracks"
type="playlist"
:highlightPlayingTrack="false"
dbclickTrackFunc="playTrackOnListByID"
:highlight-playing-track="false"
dbclick-track-func="playTrackOnListByID"
/>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
import { getTrackDetail } from "@/api/track";
import TrackList from "@/components/TrackList.vue";
import { mapState, mapActions } from 'vuex';
import { getTrackDetail } from '@/api/track';
import TrackList from '@/components/TrackList.vue';
export default {
name: "Next",
name: 'Next',
components: {
TrackList,
},
@ -41,7 +41,7 @@ export default {
};
},
computed: {
...mapState(["player"]),
...mapState(['player']),
currentTrack() {
return this.player.currentTrack;
},
@ -53,14 +53,14 @@ export default {
this.player.current + 1,
this.player.current + 100
);
return this.tracks.filter((t) => trackIDs.includes(t.id));
return this.tracks.filter(t => trackIDs.includes(t.id));
},
playNextList() {
return this.player.playNextList;
},
playNextTracks() {
return this.playNextList.map((tid) => {
return this.tracks.find((t) => t.id === tid);
return this.playNextList.map(tid => {
return this.tracks.find(t => t.id === tid);
});
},
},
@ -75,8 +75,11 @@ export default {
this.loadTracks();
},
},
activated() {
this.loadTracks();
},
methods: {
...mapActions(["playTrackOnListByID"]),
...mapActions(['playTrackOnListByID']),
loadTracks() {
// 100
let trackIDs = this.player.list.slice(
@ -88,21 +91,18 @@ export default {
trackIDs.push(...this.playNextList);
//
let loadedTrackIDs = this.tracks.map((t) => t.id);
let loadedTrackIDs = this.tracks.map(t => t.id);
if (trackIDs.length > 0) {
getTrackDetail(trackIDs.join(",")).then((data) => {
getTrackDetail(trackIDs.join(',')).then(data => {
let newTracks = data.songs.filter(
(t) => !loadedTrackIDs.includes(t.id)
t => !loadedTrackIDs.includes(t.id)
);
this.tracks.push(...newTracks);
});
}
},
},
activated() {
this.loadTracks();
},
};
</script>

View file

@ -1,31 +1,30 @@
<template>
<div v-show="show">
<div
class="playlist-info"
v-if="specialPlaylistInfo === undefined && !isLikeSongsPage"
class="playlist-info"
>
<Cover
:imageUrl="playlist.coverImgUrl | resizeImage(1024)"
:showPlayButton="true"
:alwaysShowShadow="true"
:clickCoverToPlay="true"
:fixedSize="288"
type="playlist"
:id="playlist.id"
:coverHover="false"
:playButtonSize="18"
:image-url="playlist.coverImgUrl | resizeImage(1024)"
:show-play-button="true"
:always-show-shadow="true"
:click-cover-to-play="true"
:fixed-size="288"
type="playlist"
:cover-hover="false"
:play-button-size="18"
@click.right.native="openMenu"
/>
<div class="info">
<div class="title" @click.right="openMenu"
><span class="lock-icon" v-if="playlist.privacy === 10">
><span v-if="playlist.privacy === 10" class="lock-icon">
<svg-icon icon-class="lock" /></span
>{{ playlist.name }}</div
>
<div class="artist">
Playlist by
<span
style="font-weight: 600"
v-if="
[
5277771961,
@ -35,6 +34,7 @@
5278068783,
].includes(playlist.id)
"
style="font-weight: 600"
>Apple Music</span
>
<a
@ -45,48 +45,48 @@
>
</div>
<div class="date-and-count">
{{ $t("playlist.updatedAt") }}
{{ $t('playlist.updatedAt') }}
{{ playlist.updateTime | formatDate }} · {{ playlist.trackCount }}
{{ $t("common.songs") }}
{{ $t('common.songs') }}
</div>
<div class="description" @click="showFullDescription = true">
{{ playlist.description }}
</div>
<div class="buttons">
<ButtonTwoTone @click.native="playPlaylistByID()" :iconClass="`play`">
{{ $t("common.play") }}
<ButtonTwoTone icon-class="play" @click.native="playPlaylistByID()">
{{ $t('common.play') }}
</ButtonTwoTone>
<ButtonTwoTone
v-if="playlist.creator.userId !== data.user.userId"
:iconClass="playlist.subscribed ? 'heart-solid' : 'heart'"
:iconButton="true"
:horizontalPadding="0"
:icon-class="playlist.subscribed ? 'heart-solid' : 'heart'"
:icon-button="true"
:horizontal-padding="0"
:color="playlist.subscribed ? 'blue' : 'grey'"
:textColor="playlist.subscribed ? '#335eea' : ''"
:backgroundColor="
:text-color="playlist.subscribed ? '#335eea' : ''"
:background-color="
playlist.subscribed ? 'var(--color-secondary-bg)' : ''
"
@click.native="likePlaylist"
>
</ButtonTwoTone>
<ButtonTwoTone
iconClass="more"
:iconButton="true"
:horizontalPadding="0"
icon-class="more"
:icon-button="true"
:horizontal-padding="0"
color="grey"
@click.native="openMenu"
>
</ButtonTwoTone>
</div>
</div>
<div class="search-box" v-if="displaySearchInPlaylist">
<div v-if="displaySearchInPlaylist" class="search-box">
<div class="container" :class="{ active: inputFocus }">
<svg-icon icon-class="search" />
<div class="input">
<input
:placeholder="inputFocus ? '' : $t('playlist.search')"
v-model.trim="inputSearchKeyWords"
v-focus="displaySearchInPlaylist"
:placeholder="inputFocus ? '' : $t('playlist.search')"
@input="inputDebounce()"
@focus="inputFocus = true"
@blur="inputFocus = false"
@ -95,7 +95,7 @@
</div>
</div>
</div>
<div class="special-playlist" v-if="specialPlaylistInfo !== undefined">
<div v-if="specialPlaylistInfo !== undefined" class="special-playlist">
<div
class="title"
:class="specialPlaylistInfo.gradient"
@ -111,29 +111,29 @@
<div class="buttons">
<ButtonTwoTone
class="play-button"
@click.native="playPlaylistByID()"
iconClass="play"
icon-class="play"
color="grey"
@click.native="playPlaylistByID()"
>
{{ $t("common.play") }}
{{ $t('common.play') }}
</ButtonTwoTone>
<ButtonTwoTone
v-if="playlist.creator.userId !== data.user.userId"
:iconClass="playlist.subscribed ? 'heart-solid' : 'heart'"
:iconButton="true"
:horizontalPadding="0"
:icon-class="playlist.subscribed ? 'heart-solid' : 'heart'"
:icon-button="true"
:horizontal-padding="0"
:color="playlist.subscribed ? 'blue' : 'grey'"
:textColor="playlist.subscribed ? '#335eea' : ''"
:backgroundColor="
:text-color="playlist.subscribed ? '#335eea' : ''"
:background-color="
playlist.subscribed ? 'var(--color-secondary-bg)' : ''
"
@click.native="likePlaylist"
>
</ButtonTwoTone>
<ButtonTwoTone
iconClass="more"
:iconButton="true"
:horizontalPadding="0"
icon-class="more"
:icon-button="true"
:horizontal-padding="0"
color="grey"
@click.native="openMenu"
>
@ -141,19 +141,19 @@
</div>
</div>
<div class="user-info" v-if="isLikeSongsPage">
<div v-if="isLikeSongsPage" class="user-info">
<h1>
<img class="avatar" :src="data.user.avatarUrl | resizeImage" />{{
data.user.nickname
}}{{ $t("library.sLikedSongs") }}
}}{{ $t('library.sLikedSongs') }}
</h1>
</div>
<TrackList
:tracks="filteredTracks"
:type="'playlist'"
:id="playlist.id"
:extraContextMenuItem="
:tracks="filteredTracks"
type="playlist"
:extra-context-menu-item="
isUserOwnPlaylist ? ['removeTrackFromPlaylist'] : []
"
/>
@ -161,27 +161,27 @@
<Modal
:show="showFullDescription"
:close="() => (showFullDescription = false)"
:showFooter="false"
:clickOutsideHide="true"
:show-footer="false"
:click-outside-hide="true"
title="歌单介绍"
>{{ playlist.description }}</Modal
>
<ContextMenu ref="playlistMenu">
<div class="item">{{ $t("contextMenu.playNext") }}</div>
<div class="item">{{ $t('contextMenu.playNext') }}</div>
<div class="item" @click="likePlaylist(true)">{{
playlist.subscribed ? "从音乐库删除" : "保存到音乐库"
playlist.subscribed ? '从音乐库删除' : '保存到音乐库'
}}</div>
<div class="item" @click="searchInPlaylist()">歌单内搜索</div>
<div
class="item"
v-if="playlist.creator.userId === data.user.userId"
class="item"
@click="editPlaylist"
>编辑歌单信息</div
>
<div
class="item"
v-if="playlist.creator.userId === data.user.userId"
class="item"
@click="deletePlaylist"
>删除歌单</div
>
@ -190,112 +190,112 @@
</template>
<script>
import { mapMutations, mapActions, mapState } from "vuex";
import NProgress from "nprogress";
import { mapMutations, mapActions, mapState } from 'vuex';
import NProgress from 'nprogress';
import {
getPlaylistDetail,
subscribePlaylist,
deletePlaylist,
} from "@/api/playlist";
import { getTrackDetail } from "@/api/track";
import { isAccountLoggedIn } from "@/utils/auth";
import nativeAlert from "@/utils/nativeAlert";
} from '@/api/playlist';
import { getTrackDetail } from '@/api/track';
import { isAccountLoggedIn } from '@/utils/auth';
import nativeAlert from '@/utils/nativeAlert';
import ButtonTwoTone from "@/components/ButtonTwoTone.vue";
import ContextMenu from "@/components/ContextMenu.vue";
import TrackList from "@/components/TrackList.vue";
import Cover from "@/components/Cover.vue";
import Modal from "@/components/Modal.vue";
import ButtonTwoTone from '@/components/ButtonTwoTone.vue';
import ContextMenu from '@/components/ContextMenu.vue';
import TrackList from '@/components/TrackList.vue';
import Cover from '@/components/Cover.vue';
import Modal from '@/components/Modal.vue';
const specialPlaylist = {
2829816518: {
name: "欧美私人订制",
gradient: "gradient-pink-purple-blue",
name: '欧美私人订制',
gradient: 'gradient-pink-purple-blue',
},
2890490211: {
name: "助眠鸟鸣声",
gradient: "gradient-green",
name: '助眠鸟鸣声',
gradient: 'gradient-green',
},
5089855855: {
name: "夜的胡思乱想",
gradient: "gradient-moonstone-blue",
name: '夜的胡思乱想',
gradient: 'gradient-moonstone-blue',
},
2888212971: {
name: "全球百大DJ",
gradient: "gradient-orange-red",
name: '全球百大DJ',
gradient: 'gradient-orange-red',
},
2829733864: {
name: "睡眠伴侣",
gradient: "gradient-midnight-blue",
name: '睡眠伴侣',
gradient: 'gradient-midnight-blue',
},
2829844572: {
name: "洗澡时听的歌",
gradient: "gradient-yellow",
name: '洗澡时听的歌',
gradient: 'gradient-yellow',
},
2920647537: {
name: "还是会想你",
gradient: "gradient-dark-blue-midnight-blue",
name: '还是会想你',
gradient: 'gradient-dark-blue-midnight-blue',
},
2890501416: {
name: "助眠白噪声",
gradient: "gradient-sky-blue",
name: '助眠白噪声',
gradient: 'gradient-sky-blue',
},
5217150082: {
name: "摇滚唱片行",
gradient: "gradient-yellow-red",
name: '摇滚唱片行',
gradient: 'gradient-yellow-red',
},
2829961453: {
name: "古风音乐大赏",
gradient: "gradient-fog",
name: '古风音乐大赏',
gradient: 'gradient-fog',
},
4923261701: {
name: "Trance",
gradient: "gradient-light-red-light-blue ",
name: 'Trance',
gradient: 'gradient-light-red-light-blue ',
},
5212729721: {
name: "欧美点唱机",
gradient: "gradient-indigo-pink-yellow",
name: '欧美点唱机',
gradient: 'gradient-indigo-pink-yellow',
},
3103434282: {
name: "甜蜜少女心",
gradient: "gradient-pink",
name: '甜蜜少女心',
gradient: 'gradient-pink',
},
2829896389: {
name: "日系私人订制",
gradient: "gradient-yellow-pink",
name: '日系私人订制',
gradient: 'gradient-yellow-pink',
},
2829779628: {
name: "运动随身听",
gradient: "gradient-orange-red",
name: '运动随身听',
gradient: 'gradient-orange-red',
},
2860654884: {
name: "独立女声精选",
gradient: "gradient-sharp-blue",
name: '独立女声精选',
gradient: 'gradient-sharp-blue',
},
898150: {
name: "浪漫婚礼专用",
gradient: "gradient-pink",
name: '浪漫婚礼专用',
gradient: 'gradient-pink',
},
2638104052: {
name: "牛奶泡泡浴",
gradient: "gradient-fog",
name: '牛奶泡泡浴',
gradient: 'gradient-fog',
},
5317236517: {
name: "后朋克精选",
gradient: "gradient-pink-purple-blue",
name: '后朋克精选',
gradient: 'gradient-pink-purple-blue',
},
2821115454: {
name: "一周原创发现",
gradient: "gradient-blue-purple",
name: '一周原创发现',
gradient: 'gradient-blue-purple',
},
3136952023: {
name: "私人雷达",
gradient: "gradient-radar",
name: '私人雷达',
gradient: 'gradient-radar',
},
};
export default {
name: "Playlist",
name: 'Playlist',
components: {
Cover,
ButtonTwoTone,
@ -303,14 +303,21 @@ export default {
Modal,
ContextMenu,
},
directives: {
focus: {
inserted: function (el) {
el.focus();
},
},
},
data() {
return {
show: false,
playlist: {
id: 0,
coverImgUrl: "",
coverImgUrl: '',
creator: {
userId: "",
userId: '',
},
trackIds: [],
},
@ -319,26 +326,16 @@ export default {
loadingMore: false,
lastLoadedTrackIndex: 9,
displaySearchInPlaylist: false,
searchKeyWords: "", // 使
inputSearchKeyWords: "", //
searchKeyWords: '', // 使
inputSearchKeyWords: '', //
inputFocus: false,
debounceTimeout: null,
};
},
created() {
if (this.$route.name === "likedSongs") {
this.loadData(this.data.likedSongPlaylistID);
} else {
this.loadData(this.$route.params.id);
}
},
destroyed() {
window.removeEventListener("scroll", this.handleScroll, true);
},
computed: {
...mapState(["player", "data"]),
...mapState(['player', 'data']),
isLikeSongsPage() {
return this.$route.name === "likedSongs";
return this.$route.name === 'likedSongs';
},
specialPlaylistInfo() {
return specialPlaylist[this.playlist.id];
@ -351,7 +348,7 @@ export default {
},
filteredTracks() {
return this.tracks.filter(
(track) =>
track =>
(track.name &&
track.name
.toLowerCase()
@ -361,7 +358,7 @@ export default {
.toLowerCase()
.includes(this.searchKeyWords.toLowerCase())) ||
track.ar.find(
(artist) =>
artist =>
artist.name &&
artist.name
.toLowerCase()
@ -370,35 +367,45 @@ export default {
);
},
},
created() {
if (this.$route.name === 'likedSongs') {
this.loadData(this.data.likedSongPlaylistID);
} else {
this.loadData(this.$route.params.id);
}
},
destroyed() {
window.removeEventListener('scroll', this.handleScroll, true);
},
methods: {
...mapMutations(["appendTrackToPlayerList"]),
...mapActions(["playFirstTrackOnList", "playTrackOnListByID", "showToast"]),
playPlaylistByID(trackID = "first") {
let trackIDs = this.playlist.trackIds.map((t) => t.id);
...mapMutations(['appendTrackToPlayerList']),
...mapActions(['playFirstTrackOnList', 'playTrackOnListByID', 'showToast']),
playPlaylistByID(trackID = 'first') {
let trackIDs = this.playlist.trackIds.map(t => t.id);
this.$store.state.player.replacePlaylist(
trackIDs,
this.playlist.id,
"playlist",
'playlist',
trackID
);
},
likePlaylist(toast = false) {
if (!isAccountLoggedIn()) {
this.showToast("此操作需要登录网易云账号");
this.showToast('此操作需要登录网易云账号');
return;
}
subscribePlaylist({
id: this.playlist.id,
t: this.playlist.subscribed ? 2 : 1,
}).then((data) => {
}).then(data => {
if (data.code === 200) {
this.playlist.subscribed = !this.playlist.subscribed;
if (toast === true)
this.showToast(
this.playlist.subscribed ? "已保存到音乐库" : "已从音乐库删除"
this.playlist.subscribed ? '已保存到音乐库' : '已从音乐库删除'
);
}
getPlaylistDetail(this.id, true).then((data) => {
getPlaylistDetail(this.id, true).then(data => {
this.playlist = data.playlist;
});
});
@ -406,7 +413,7 @@ export default {
loadData(id, next = undefined) {
this.id = id;
getPlaylistDetail(this.id, true)
.then((data) => {
.then(data => {
this.playlist = data.playlist;
this.tracks = data.playlist.tracks;
NProgress.done();
@ -414,7 +421,7 @@ export default {
this.show = true;
this.lastLoadedTrackIndex = data.playlist.tracks.length - 1;
if (this.playlist.trackCount > this.tracks.length) {
window.addEventListener("scroll", this.handleScroll, true);
window.addEventListener('scroll', this.handleScroll, true);
}
return data;
})
@ -433,15 +440,15 @@ export default {
)
return t;
});
trackIDs = trackIDs.map((t) => t.id);
getTrackDetail(trackIDs.join(",")).then((data) => {
trackIDs = trackIDs.map(t => t.id);
getTrackDetail(trackIDs.join(',')).then(data => {
this.tracks.push(...data.songs);
this.lastLoadedTrackIndex += trackIDs.length;
this.loadingMore = false;
});
},
handleScroll(e) {
let dom = document.querySelector("html");
let dom = document.querySelector('html');
let scrollHeight = Math.max(dom.scrollHeight, dom.scrollHeight);
let scrollTop = e.target.scrollingElement.scrollTop;
let clientHeight =
@ -461,39 +468,39 @@ export default {
},
deletePlaylist() {
if (!isAccountLoggedIn()) {
this.showToast("此操作需要登录网易云账号");
this.showToast('此操作需要登录网易云账号');
return;
}
let confirmation = confirm(`确定要删除歌单 ${this.playlist.name}`);
if (confirmation === true) {
deletePlaylist(this.playlist.id).then((data) => {
deletePlaylist(this.playlist.id).then(data => {
if (data.code === 200) {
nativeAlert(`已删除歌单 ${this.playlist.name}`);
this.$router.go(-1);
} else {
nativeAlert("发生错误");
nativeAlert('发生错误');
}
});
}
},
editPlaylist() {
nativeAlert("此功能开发中");
nativeAlert('此功能开发中');
},
searchInPlaylist() {
this.displaySearchInPlaylist = !this.displaySearchInPlaylist;
if (this.displaySearchInPlaylist == false) {
this.searchKeyWords = "";
this.inputSearchKeyWords = "";
this.searchKeyWords = '';
this.inputSearchKeyWords = '';
} else {
this.loadMore(500);
}
},
removeTrack(trackID) {
if (!isAccountLoggedIn()) {
this.showToast("此操作需要登录网易云账号");
this.showToast('此操作需要登录网易云账号');
return;
}
this.tracks = this.tracks.filter((t) => t.id !== trackID);
this.tracks = this.tracks.filter(t => t.id !== trackID);
},
inputDebounce() {
if (this.debounceTimeout) clearTimeout(this.debounceTimeout);
@ -502,13 +509,6 @@ export default {
}, 600);
},
},
directives: {
focus: {
inserted: function (el) {
el.focus();
},
},
},
};
</script>
@ -647,7 +647,7 @@ export default {
background-image: linear-gradient(to left, #92fe9d 0%, #00c9ff 100%);
}
[data-theme="dark"] {
[data-theme='dark'] {
.gradient-radar {
background-image: linear-gradient(to left, #92fe9d 0%, #00c9ff 100%);
}
@ -824,7 +824,7 @@ export default {
}
}
[data-theme="dark"] {
[data-theme='dark'] {
.search-box {
.active {
input,

View file

@ -1,83 +1,83 @@
<template>
<div class="search" v-show="show">
<div class="row" v-show="artists.length > 0 || albums.length > 0">
<div class="artists" v-show="artists.length > 0">
<div class="section-title" v-show="artists.length > 0"
>{{ $t("search.artist")
<div v-show="show" class="search">
<div v-show="artists.length > 0 || albums.length > 0" class="row">
<div v-show="artists.length > 0" class="artists">
<div v-show="artists.length > 0" class="section-title"
>{{ $t('search.artist')
}}<router-link :to="`/search/${keywords}/artists`">{{
$t("home.seeMore")
$t('home.seeMore')
}}</router-link></div
>
<CoverRow
type="artist"
:columnNumber="3"
:column-number="3"
:items="artists.slice(0, 3)"
gap="34px 24px"
/>
</div>
<div class="albums">
<div class="section-title" v-show="albums.length > 0"
>{{ $t("search.album")
<div v-show="albums.length > 0" class="section-title"
>{{ $t('search.album')
}}<router-link :to="`/search/${keywords}/albums`">{{
$t("home.seeMore")
$t('home.seeMore')
}}</router-link></div
>
<CoverRow
type="album"
:items="albums.slice(0, 3)"
subText="artist"
:columnNumber="3"
subTextFontSize="14px"
sub-text="artist"
:column-number="3"
sub-text-font-size="14px"
gap="34px 24px"
:playButtonSize="26"
:play-button-size="26"
/>
</div>
</div>
<div class="tracks" v-show="tracks.length > 0">
<div v-show="tracks.length > 0" class="tracks">
<div class="section-title"
>{{ $t("search.song")
>{{ $t('search.song')
}}<router-link :to="`/search/${keywords}/tracks`">{{
$t("home.seeMore")
$t('home.seeMore')
}}</router-link></div
>
<TrackList :tracks="tracks" type="tracklist" />
</div>
<div class="music-videos" v-show="musicVideos.length > 0">
<div v-show="musicVideos.length > 0" class="music-videos">
<div class="section-title"
>{{ $t("search.mv")
>{{ $t('search.mv')
}}<router-link :to="`/search/${keywords}/music-videos`">{{
$t("home.seeMore")
$t('home.seeMore')
}}</router-link></div
>
<MvRow :mvs="musicVideos.slice(0, 5)" />
</div>
<div class="playlists" v-show="playlists.length > 0">
<div v-show="playlists.length > 0" class="playlists">
<div class="section-title"
>{{ $t("search.playlist")
>{{ $t('search.playlist')
}}<router-link :to="`/search/${keywords}/playlists`">{{
$t("home.seeMore")
$t('home.seeMore')
}}</router-link></div
>
<CoverRow
type="playlist"
:items="playlists.slice(0, 12)"
subText="title"
:columnNumber="6"
subTextFontSize="14px"
sub-text="title"
:column-number="6"
sub-text-font-size="14px"
gap="34px 24px"
:playButtonSize="26"
:play-button-size="26"
/>
</div>
<div class="no-results" v-show="!haveResult">
<div v-show="!haveResult" class="no-results">
<div
><svg-icon icon-class="search" />
{{
keywords.length === 0 ? "输入关键字搜索" : $t("search.noResult")
keywords.length === 0 ? '输入关键字搜索' : $t('search.noResult')
}}</div
>
</div>
@ -85,16 +85,16 @@
</template>
<script>
import { getTrackDetail } from "@/api/track";
import { search } from "@/api/others";
import NProgress from "nprogress";
import { getTrackDetail } from '@/api/track';
import { search } from '@/api/others';
import NProgress from 'nprogress';
import TrackList from "@/components/TrackList.vue";
import MvRow from "@/components/MvRow.vue";
import CoverRow from "@/components/CoverRow.vue";
import TrackList from '@/components/TrackList.vue';
import MvRow from '@/components/MvRow.vue';
import CoverRow from '@/components/CoverRow.vue';
export default {
name: "Search",
name: 'Search',
components: {
TrackList,
MvRow,
@ -112,7 +112,7 @@ export default {
},
computed: {
keywords() {
return this.$route.params.keywords ?? "";
return this.$route.params.keywords ?? '';
},
haveResult() {
return (
@ -125,12 +125,21 @@ export default {
);
},
},
watch: {
keywords: function (newKeywords) {
if (newKeywords.length === 0) return;
this.getData();
},
},
created() {
this.getData();
},
methods: {
playTrackInSearchResult(id) {
let track = this.tracks.find((t) => t.id === id);
let track = this.tracks.find(t => t.id === id);
this.$store.state.player.appendTrackToPlayerList(track, true);
},
search(type = "all") {
search(type = 'all') {
const typeTable = {
all: 1018,
musicVideos: 1004,
@ -143,7 +152,7 @@ export default {
keywords: this.keywords,
type: typeTable[type],
limit: 16,
}).then((result) => {
}).then(result => {
return { result: result.result, type };
});
},
@ -151,32 +160,32 @@ export default {
NProgress.start();
this.show = false;
const requestAll = (requests) => {
const requestAll = requests => {
const keywords = this.keywords;
Promise.all(requests).then((results) => {
Promise.all(requests).then(results => {
if (keywords != this.keywords) return;
results.map((result) => {
results.map(result => {
const searchType = result.type;
if (result.result === undefined) return;
result = result.result;
switch (searchType) {
case "all":
case 'all':
this.result = result;
break;
case "musicVideos":
case 'musicVideos':
this.musicVideos = result.mvs ?? [];
break;
case "artists":
case 'artists':
this.artists = result.artists ?? [];
break;
case "albums":
case 'albums':
this.albums = result.albums ?? [];
break;
case "tracks":
case 'tracks':
this.tracks = result.songs ?? [];
this.getTracksDetail();
break;
case "playlists":
case 'playlists':
this.playlists = result.playlists ?? [];
break;
}
@ -187,32 +196,23 @@ export default {
};
const requests = [
this.search("artists"),
this.search("albums"),
this.search("tracks"),
this.search('artists'),
this.search('albums'),
this.search('tracks'),
];
const requests2 = [this.search("musicVideos"), this.search("playlists")];
const requests2 = [this.search('musicVideos'), this.search('playlists')];
requestAll(requests);
requestAll(requests2);
},
getTracksDetail() {
const trackIDs = this.tracks.map((t) => t.id);
const trackIDs = this.tracks.map(t => t.id);
if (trackIDs.length === 0) return;
getTrackDetail(trackIDs.join(",")).then((result) => {
getTrackDetail(trackIDs.join(',')).then(result => {
this.tracks = result.songs;
});
},
},
created() {
this.getData();
},
watch: {
keywords: function (newKeywords) {
if (newKeywords.length === 0) return;
this.getData();
},
},
};
</script>

View file

@ -1,57 +1,57 @@
<template>
<div class="search" v-show="show">
<div v-show="show" class="search">
<h1>
<span>{{ $t("search.searchFor") }}{{ typeNameTable[type] }}</span> "{{
<span>{{ $t('search.searchFor') }}{{ typeNameTable[type] }}</span> "{{
keywords
}}"
</h1>
<div v-if="type === 'artists'">
<CoverRow type="artist" :items="result" :columnNumber="6" />
<CoverRow type="artist" :items="result" :column-number="6" />
</div>
<div v-if="type === 'albums'">
<CoverRow
type="album"
:items="result"
subText="artist"
subTextFontSize="14px"
sub-text="artist"
sub-text-font-size="14px"
/>
</div>
<div v-if="type === 'tracks'">
<TrackList
:tracks="result"
type="playlist"
dbclickTrackFunc="playAList"
dbclick-track-func="playAList"
/>
</div>
<div v-if="type === 'musicVideos'">
<MvRow :mvs="result" />
</div>
<div v-if="type === 'playlists'">
<CoverRow type="playlist" :items="result" subText="title" />
<CoverRow type="playlist" :items="result" sub-text="title" />
</div>
<div class="load-more">
<ButtonTwoTone v-show="hasMore" @click.native="fetchData" color="grey">{{
$t("explore.loadMore")
<ButtonTwoTone v-show="hasMore" color="grey" @click.native="fetchData">{{
$t('explore.loadMore')
}}</ButtonTwoTone>
</div>
</div>
</template>
<script>
import { getTrackDetail } from "@/api/track";
import { search } from "@/api/others";
import { camelCase } from "change-case";
import NProgress from "nprogress";
import { getTrackDetail } from '@/api/track';
import { search } from '@/api/others';
import { camelCase } from 'change-case';
import NProgress from 'nprogress';
import TrackList from "@/components/TrackList.vue";
import MvRow from "@/components/MvRow.vue";
import CoverRow from "@/components/CoverRow.vue";
import ButtonTwoTone from "@/components/ButtonTwoTone.vue";
import TrackList from '@/components/TrackList.vue';
import MvRow from '@/components/MvRow.vue';
import CoverRow from '@/components/CoverRow.vue';
import ButtonTwoTone from '@/components/ButtonTwoTone.vue';
export default {
name: "Search",
name: 'Search',
components: {
TrackList,
MvRow,
@ -70,14 +70,17 @@ export default {
},
typeNameTable() {
return {
musicVideos: "MV",
tracks: "歌曲",
albums: "专辑",
artists: "艺人",
playlists: "歌单",
musicVideos: 'MV',
tracks: '歌曲',
albums: '专辑',
artists: '艺人',
playlists: '歌单',
};
},
},
created() {
this.fetchData();
},
methods: {
fetchData() {
const typeTable = {
@ -91,30 +94,30 @@ export default {
keywords: this.keywords,
type: typeTable[this.type],
offset: this.result.length,
}).then((result) => {
}).then(result => {
result = result.result;
this.hasMore = result.hasMore ?? true;
switch (this.type) {
case "musicVideos":
case 'musicVideos':
this.result.push(...result.mvs);
if (result.mvCount <= this.result.length) {
this.hasMore = false;
}
break;
case "artists":
case 'artists':
this.result.push(...result.artists);
break;
case "albums":
case 'albums':
this.result.push(...result.albums);
if (result.albumCount <= this.result.length) {
this.hasMore = false;
}
break;
case "tracks":
case 'tracks':
this.result.push(...result.songs);
this.getTracksDetail();
break;
case "playlists":
case 'playlists':
this.result.push(...result.playlists);
break;
}
@ -123,16 +126,13 @@ export default {
});
},
getTracksDetail() {
const trackIDs = this.result.map((t) => t.id);
const trackIDs = this.result.map(t => t.id);
if (trackIDs.length === 0) return;
getTrackDetail(trackIDs.join(",")).then((result) => {
getTrackDetail(trackIDs.join(',')).then(result => {
this.result = result.songs;
});
},
},
created() {
this.fetchData();
},
};
</script>

View file

@ -21,14 +21,14 @@
<div class="right">
<button @click="logout">
<svg-icon icon-class="logout" />
{{ $t("settings.logout") }}
{{ $t('settings.logout') }}
</button>
</div>
</div>
<h2>{{ $t("settings.settings") }}</h2>
<h2>{{ $t('settings.settings') }}</h2>
<div class="item">
<div class="left">
<div class="title"> {{ $t("settings.language") }} </div>
<div class="title"> {{ $t('settings.language') }} </div>
</div>
<div class="right">
<select v-model="lang">
@ -40,44 +40,44 @@
</div>
<div class="item">
<div class="left">
<div class="title"> {{ $t("settings.appearance.text") }} </div>
<div class="title"> {{ $t('settings.appearance.text') }} </div>
</div>
<div class="right">
<select v-model="appearance">
<option value="auto">{{ $t("settings.appearance.auto") }}</option>
<option value="auto">{{ $t('settings.appearance.auto') }}</option>
<option value="light"
>🌞 {{ $t("settings.appearance.light") }}</option
>🌞 {{ $t('settings.appearance.light') }}</option
>
<option value="dark"
>🌚 {{ $t("settings.appearance.dark") }}</option
>🌚 {{ $t('settings.appearance.dark') }}</option
>
</select>
</div>
</div>
<div class="item">
<div class="left">
<div class="title"> {{ $t("settings.musicQuality.text") }} </div>
<div class="title"> {{ $t('settings.musicQuality.text') }} </div>
</div>
<div class="right">
<select v-model="musicQuality">
<option value="128000">
{{ $t("settings.musicQuality.low") }} - 128Kbps
{{ $t('settings.musicQuality.low') }} - 128Kbps
</option>
<option value="192000">
{{ $t("settings.musicQuality.medium") }} - 192Kbps
{{ $t('settings.musicQuality.medium') }} - 192Kbps
</option>
<option value="320000">
{{ $t("settings.musicQuality.high") }} - 320Kbps
{{ $t('settings.musicQuality.high') }} - 320Kbps
</option>
<option value="999000">
{{ $t("settings.musicQuality.lossless") }} - FLAC
{{ $t('settings.musicQuality.lossless') }} - FLAC
</option>
</select>
</div>
</div>
<div v-if="isElectron" class="item">
<div class="left">
<div class="title"> {{ $t("settings.deviceSelector") }} </div>
<div class="title"> {{ $t('settings.deviceSelector') }} </div>
</div>
<div class="right">
<select v-model="outputDevice" :disabled="withoutAudioPrivilege">
@ -95,7 +95,7 @@
<div v-if="isElectron" class="item">
<div class="left">
<div class="title">
{{ $t("settings.automaticallyCacheSongs") }}
{{ $t('settings.automaticallyCacheSongs') }}
</div>
</div>
<div class="right">
@ -112,12 +112,12 @@
</div>
<div v-if="isElectron" class="item">
<div class="left">
<div class="title"> {{ $t("settings.cacheLimit.text") }} </div>
<div class="title"> {{ $t('settings.cacheLimit.text') }} </div>
</div>
<div class="right">
<select v-model="cacheLimit">
<option :value="false">
{{ $t("settings.cacheLimit.none") }}
{{ $t('settings.cacheLimit.none') }}
</option>
<option :value="512"> 500MB </option>
<option :value="1024"> 1GB </option>
@ -130,7 +130,7 @@
<div class="left">
<div class="title">
{{
$t("settings.cacheCount", {
$t('settings.cacheCount', {
song: tracksCache.length,
size: tracksCache.size,
})
@ -139,13 +139,13 @@
</div>
<div class="right">
<button @click="clearCache()">
{{ $t("settings.clearSongsCache") }}
{{ $t('settings.clearSongsCache') }}
</button>
</div>
</div>
<div class="item">
<div class="left">
<div class="title">{{ $t("settings.showLyricsTranslation") }}</div>
<div class="title">{{ $t('settings.showLyricsTranslation') }}</div>
</div>
<div class="right">
<div class="toggle">
@ -162,7 +162,7 @@
<div class="item">
<div class="left">
<div class="title">{{
$t("settings.showLyricsDynamicBackground")
$t('settings.showLyricsDynamicBackground')
}}</div>
</div>
<div class="right">
@ -179,28 +179,28 @@
</div>
<div class="item">
<div class="left">
<div class="title"> {{ $t("settings.lyricFontSize.text") }} </div>
<div class="title"> {{ $t('settings.lyricFontSize.text') }} </div>
</div>
<div class="right">
<select v-model="lyricFontSize">
<option value="16">
{{ $t("settings.lyricFontSize.small") }} - 16px
{{ $t('settings.lyricFontSize.small') }} - 16px
</option>
<option value="22">
{{ $t("settings.lyricFontSize.medium") }} - 22px
{{ $t('settings.lyricFontSize.medium') }} - 22px
</option>
<option value="28">
{{ $t("settings.lyricFontSize.large") }} - 28px
{{ $t('settings.lyricFontSize.large') }} - 28px
</option>
<option value="36">
{{ $t("settings.lyricFontSize.xlarge") }} - 36px
{{ $t('settings.lyricFontSize.xlarge') }} - 36px
</option>
</select>
</div>
</div>
<div v-if="isElectron && !isMac" class="item">
<div class="left">
<div class="title">{{ $t("settings.minimizeToTray") }}</div>
<div class="title">{{ $t('settings.minimizeToTray') }}</div>
</div>
<div class="right">
<div class="toggle">
@ -221,7 +221,7 @@
{{
isLastfmConnected
? `已连接到 Last.fm (${lastfm.name})`
: "连接 Last.fm "
: '连接 Last.fm '
}}</div
>
</div>
@ -235,7 +235,7 @@
<div class="item">
<div class="left">
<div class="title"> {{ $t("settings.showLibraryDefault") }}</div>
<div class="title"> {{ $t('settings.showLibraryDefault') }}</div>
</div>
<div class="right">
<div class="toggle">
@ -277,7 +277,7 @@
<div class="item">
<div class="left">
<div class="title">
{{ $t("settings.showPlaylistsByAppleMusic") }}</div
{{ $t('settings.showPlaylistsByAppleMusic') }}</div
>
</div>
<div class="right">
@ -295,7 +295,7 @@
<div v-if="isElectron" class="item">
<div class="left">
<div class="title">
{{ $t("settings.enableDiscordRichPresence") }}</div
{{ $t('settings.enableDiscordRichPresence') }}</div
>
</div>
<div class="right">
@ -312,7 +312,7 @@
</div>
<div v-if="isElectron" class="item">
<div class="left">
<div class="title"> {{ $t("settings.enableGlobalShortcut") }}</div>
<div class="title"> {{ $t('settings.enableGlobalShortcut') }}</div>
</div>
<div class="right">
<div class="toggle">
@ -355,32 +355,32 @@
</template>
<script>
import { mapState } from "vuex";
import { isLooseLoggedIn, doLogout } from "@/utils/auth";
import { auth as lastfmAuth } from "@/api/lastfm";
import { changeAppearance, bytesToSize } from "@/utils/common";
import { countDBSize, clearDB } from "@/utils/db";
import pkg from "../../package.json";
import { mapState } from 'vuex';
import { isLooseLoggedIn, doLogout } from '@/utils/auth';
import { auth as lastfmAuth } from '@/api/lastfm';
import { changeAppearance, bytesToSize } from '@/utils/common';
import { countDBSize, clearDB } from '@/utils/db';
import pkg from '../../package.json';
export default {
name: "Settings",
name: 'Settings',
data() {
return {
tracksCache: {
size: "0KB",
size: '0KB',
length: 0,
},
allOutputDevices: [
{
deviceId: "default",
label: "settings.permissionRequired",
deviceId: 'default',
label: 'settings.permissionRequired',
},
],
withoutAudioPrivilege: true,
};
},
computed: {
...mapState(["player", "settings", "data", "lastfm"]),
...mapState(['player', 'settings', 'data', 'lastfm']),
isElectron() {
return process.env.IS_ELECTRON;
},
@ -400,17 +400,17 @@ export default {
},
set(lang) {
this.$i18n.locale = lang;
this.$store.commit("changeLang", lang);
this.$store.commit('changeLang', lang);
},
},
appearance: {
get() {
if (this.settings.appearance === undefined) return "auto";
if (this.settings.appearance === undefined) return 'auto';
return this.settings.appearance;
},
set(value) {
this.$store.commit("updateSettings", {
key: "appearance",
this.$store.commit('updateSettings', {
key: 'appearance',
value,
});
changeAppearance(value);
@ -423,7 +423,7 @@ export default {
},
set(value) {
if (value === this.settings.musicQuality) return;
this.$store.commit("changeMusicQuality", value);
this.$store.commit('changeMusicQuality', value);
this.clearCache();
},
},
@ -433,26 +433,26 @@ export default {
return this.settings.lyricFontSize;
},
set(value) {
this.$store.commit("changeLyricFontSize", value);
this.$store.commit('changeLyricFontSize', value);
},
},
outputDevice: {
get() {
if (this.withoutAudioPrivilege === true) this.getAllOutputDevices();
const isValidDevice = this.allOutputDevices.find(
(device) => device.deviceId === this.settings.outputDevice
device => device.deviceId === this.settings.outputDevice
);
if (
this.settings.outputDevice === undefined ||
isValidDevice === undefined
)
return "default"; // Default deviceId
return 'default'; // Default deviceId
return this.settings.outputDevice;
},
set(deviceId) {
if (deviceId === this.settings.outputDevice || deviceId === undefined)
return;
this.$store.commit("changeOutputDevice", deviceId);
this.$store.commit('changeOutputDevice', deviceId);
this.player.setOutputDevice();
},
},
@ -461,8 +461,8 @@ export default {
return this.settings.enableUnblockNeteaseMusic || true;
},
set(value) {
this.$store.commit("updateSettings", {
key: "enableUnblockNeteaseMusic",
this.$store.commit('updateSettings', {
key: 'enableUnblockNeteaseMusic',
value,
});
},
@ -473,8 +473,8 @@ export default {
return this.settings.showPlaylistsByAppleMusic;
},
set(value) {
this.$store.commit("updateSettings", {
key: "showPlaylistsByAppleMusic",
this.$store.commit('updateSettings', {
key: 'showPlaylistsByAppleMusic',
value,
});
},
@ -485,8 +485,8 @@ export default {
return this.settings.nyancatStyle;
},
set(value) {
this.$store.commit("updateSettings", {
key: "nyancatStyle",
this.$store.commit('updateSettings', {
key: 'nyancatStyle',
value,
});
},
@ -497,8 +497,8 @@ export default {
return this.settings.automaticallyCacheSongs;
},
set(value) {
this.$store.commit("updateSettings", {
key: "automaticallyCacheSongs",
this.$store.commit('updateSettings', {
key: 'automaticallyCacheSongs',
value,
});
if (value === false) {
@ -511,8 +511,8 @@ export default {
return this.settings.showLyricsTranslation;
},
set(value) {
this.$store.commit("updateSettings", {
key: "showLyricsTranslation",
this.$store.commit('updateSettings', {
key: 'showLyricsTranslation',
value,
});
},
@ -522,8 +522,8 @@ export default {
return this.settings.showLyricsDynamicBackground;
},
set(value) {
this.$store.commit("updateSettings", {
key: "showLyricsDynamicBackground",
this.$store.commit('updateSettings', {
key: 'showLyricsDynamicBackground',
value,
});
},
@ -533,8 +533,8 @@ export default {
return this.settings.minimizeToTray;
},
set(value) {
this.$store.commit("updateSettings", {
key: "minimizeToTray",
this.$store.commit('updateSettings', {
key: 'minimizeToTray',
value,
});
},
@ -544,8 +544,8 @@ export default {
return this.settings.enableDiscordRichPresence;
},
set(value) {
this.$store.commit("updateSettings", {
key: "enableDiscordRichPresence",
this.$store.commit('updateSettings', {
key: 'enableDiscordRichPresence',
value,
});
},
@ -555,8 +555,8 @@ export default {
return this.settings.enableGlobalShortcut;
},
set(value) {
this.$store.commit("updateSettings", {
key: "enableGlobalShortcut",
this.$store.commit('updateSettings', {
key: 'enableGlobalShortcut',
value,
});
},
@ -566,8 +566,8 @@ export default {
return this.settings.showLibraryDefault || false;
},
set(value) {
this.$store.commit("updateSettings", {
key: "showLibraryDefault",
this.$store.commit('updateSettings', {
key: 'showLibraryDefault',
value,
});
},
@ -577,8 +577,8 @@ export default {
return this.settings.cacheLimit || false;
},
set(value) {
this.$store.commit("updateSettings", {
key: "cacheLimit",
this.$store.commit('updateSettings', {
key: 'cacheLimit',
value,
});
},
@ -588,27 +588,27 @@ export default {
},
},
created() {
this.countDBSize("tracks");
this.countDBSize('tracks');
},
activated() {
this.countDBSize("tracks");
this.countDBSize('tracks');
},
methods: {
getAllOutputDevices() {
navigator.mediaDevices.enumerateDevices().then((devices) => {
this.allOutputDevices = devices.filter((device) => {
return device.kind == "audiooutput";
navigator.mediaDevices.enumerateDevices().then(devices => {
this.allOutputDevices = devices.filter(device => {
return device.kind == 'audiooutput';
});
if (
this.allOutputDevices.length > 0 &&
this.allOutputDevices[0].label !== ""
this.allOutputDevices[0].label !== ''
) {
this.withoutAudioPriviledge = false;
} else {
this.allOutputDevices = [
{
deviceId: "default",
label: "settings.permissionRequired",
deviceId: 'default',
label: 'settings.permissionRequired',
},
];
}
@ -616,13 +616,13 @@ export default {
},
logout() {
doLogout();
this.$router.push({ name: "home" });
this.$router.push({ name: 'home' });
},
countDBSize() {
countDBSize().then((data) => {
countDBSize().then(data => {
if (data === undefined) {
this.tracksCache = {
size: "0KB",
size: '0KB',
length: 0,
};
return;
@ -639,16 +639,16 @@ export default {
lastfmConnect() {
lastfmAuth();
let lastfmChecker = setInterval(() => {
const session = localStorage.getItem("lastfm");
const session = localStorage.getItem('lastfm');
if (session) {
this.$store.commit("updateLastfm", JSON.parse(session));
this.$store.commit('updateLastfm', JSON.parse(session));
clearInterval(lastfmChecker);
}
}, 1000);
},
lastfmDisconnect() {
localStorage.removeItem("lastfm");
this.$store.commit("updateLastfm", {});
localStorage.removeItem('lastfm');
this.$store.commit('updateLastfm', {});
},
},
};
@ -835,7 +835,7 @@ h2 {
border-radius: 8px;
}
.toggle input + label:before {
content: "";
content: '';
position: absolute;
display: block;
-webkit-transition: 0.2s cubic-bezier(0.24, 0, 0.5, 1);
@ -847,7 +847,7 @@ h2 {
border-radius: 8px;
}
.toggle input + label:after {
content: "";
content: '';
position: absolute;
display: block;
box-shadow: 0 0 0 1px hsla(0, 0%, 0%, 0.02), 0 4px 0px 0 hsla(0, 0%, 0%, 0.01),