YesPlayMusic/src/views/settings.vue
Mr. Will 1d34aa794f
Update animations for lyrics, panels and tracklists | 为歌词、面板和列表更新动画 (#249)
* Update lyrics scrolling animation

* Remove the useless module imported by mistake

* Auto prettify the changed code

* Update lyrics animation curve and add blur effect to lyrics

* Auto prettify the changed code

* Add initial lyrics blur filter

* Update lyrics blur and fade effect

* Update open and close animation for explore page's panel

* Update tracklist hover animation

* Add scale animation to lyrics

* Auto prettify the changed code

* Update lyrics blur effect with CSS variables

* Support small screen devices for all pages

* Fix paddings for some pages

* Auto prettify the changed code

* Update lyrics page for small screen devices
2021-02-12 15:18:55 +08:00

593 lines
20 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="settings">
<div class="container">
<div class="user" v-if="data.user.nickname !== undefined">
<div class="left">
<img class="avatar" :src="data.user.avatarUrl" />
<div class="info">
<div class="nickname">{{ data.user.nickname }}</div>
<div class="extra-info">
<span v-if="data.user.vipType !== 0" class="vip"
><img
class="cvip"
src="data:image/png;base64,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"
/>
<span class="text">黑胶VIP</span>
</span>
<span class="text" v-else>{{ data.user.signature }}</span>
</div>
</div>
</div>
<div class="right">
<button @click="logout">
<svg-icon icon-class="logout" />
{{ $t("settings.logout") }}
</button>
</div>
</div>
<h2>{{ $t("settings.settings") }}</h2>
<div class="item">
<div class="left">
<div class="title"> {{ $t("settings.language") }} </div>
</div>
<div class="right">
<select v-model="lang">
<option value="en">🇬🇧 English</option>
<option value="zh-CN">🇨🇳 简体中文</option>
</select>
</div>
</div>
<div class="item">
<div class="left">
<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="light"
>🌞 {{ $t("settings.appearance.light") }}</option
>
<option value="dark"
>🌚 {{ $t("settings.appearance.dark") }}</option
>
</select>
</div>
</div>
<div class="item">
<div class="left">
<div class="title"> {{ $t("settings.musicQuality.text") }} </div>
</div>
<div class="right">
<select v-model="musicQuality">
<option value="128000">
{{ $t("settings.musicQuality.low") }} - 128Kbps
</option>
<option value="192000">
{{ $t("settings.musicQuality.medium") }} - 192Kbps
</option>
<option value="320000">
{{ $t("settings.musicQuality.high") }} - 320Kbps
</option>
<option value="999000">
{{ $t("settings.musicQuality.lossless") }} - FLAC
</option>
</select>
</div>
</div>
<div class="item">
<div class="left">
<div class="title">
{{ $t("settings.automaticallyCacheSongs") }}
</div>
</div>
<div class="right">
<div class="toggle">
<input
type="checkbox"
name="automatically-cache-songs"
id="automatically-cache-songs"
v-model="automaticallyCacheSongs"
/>
<label for="automatically-cache-songs"></label>
</div>
</div>
</div>
<div class="item">
<div class="left">
<div class="title">
{{
$t("settings.cacheCount", {
song: tracksCache.length,
size: tracksCache.size,
})
}}</div
>
</div>
<div class="right">
<button @click="clearCache('tracks')">
{{ $t("settings.clearSongsCache") }}
</button>
</div>
</div>
<div class="item">
<div class="left">
<div class="title">显示歌词翻译</div>
</div>
<div class="right">
<div class="toggle">
<input
type="checkbox"
name="show-lyrics-translation"
id="show-lyrics-translation"
v-model="showLyricsTranslation"
/>
<label for="show-lyrics-translation"></label>
</div>
</div>
</div>
<div class="item" v-if="isElectron && !isMac">
<div class="left">
<div class="title">最小化到托盘</div>
</div>
<div class="right">
<div class="toggle">
<input
type="checkbox"
name="minimize-to-tray"
id="minimize-to-tray"
v-model="minimizeToTray"
/>
<label for="minimize-to-tray"></label>
</div>
</div>
</div>
<div class="item">
<div class="left">
<div class="title"> {{ $t("settings.showGitHubIcon") }} </div>
</div>
<div class="right">
<div class="toggle">
<input
type="checkbox"
name="show-github-icon"
id="show-github-icon"
v-model="showGithubIcon"
/>
<label for="show-github-icon"></label>
</div>
</div>
</div>
<div class="item">
<div class="left">
<div class="title">
{{ $t("settings.showUnavailableSongInGreyStyle") }}</div
>
</div>
<div class="right">
<div class="toggle">
<input
type="checkbox"
name="show-unavailable-song-grey"
id="show-unavailable-song-grey"
v-model="showUnavailableSongInGreyStyle"
/>
<label for="show-unavailable-song-grey"></label>
</div>
</div>
</div>
<div class="item">
<div class="left">
<div class="title">
{{ $t("settings.showPlaylistsByAppleMusic") }}</div
>
</div>
<div class="right">
<div class="toggle">
<input
type="checkbox"
name="show-playlists-by-apple-music"
id="show-playlists-by-apple-music"
v-model="showPlaylistsByAppleMusic"
/>
<label for="show-playlists-by-apple-music"></label>
</div>
</div>
</div>
<div class="item">
<div class="left">
<div class="title" style="transform: scaleX(-1)">🐈 🏳🌈</div>
</div>
<div class="right">
<div class="toggle">
<input
type="checkbox"
name="nyancat-style"
id="nyancat-style"
v-model="nyancatStyle"
/>
<label for="nyancat-style"></label>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapState } from "vuex";
import { doLogout } from "@/utils/auth";
import { changeAppearance, bytesToSize } from "@/utils/common";
import { countDBSize, clearDB } from "@/utils/db";
export default {
name: "settings",
data() {
return {
tracksCache: {
size: "0KB",
length: 0,
},
};
},
computed: {
...mapState(["settings", "data"]),
isElectron() {
return process.env.IS_ELECTRON;
},
isMac() {
return /macintosh|mac os x/i.test(navigator.userAgent);
},
lang: {
get() {
return this.settings.lang;
},
set(lang) {
this.$i18n.locale = lang;
this.$store.commit("changeLang", lang);
},
},
appearance: {
get() {
if (this.settings.appearance === undefined) return "auto";
return this.settings.appearance;
},
set(value) {
this.$store.commit("updateSettings", {
key: "appearance",
value,
});
changeAppearance(value);
},
},
musicQuality: {
get() {
if (this.settings.musicQuality === undefined) return 320000;
return this.settings.musicQuality;
},
set(value) {
if (value === this.settings.musicQuality) return;
this.$store.commit("changeMusicQuality", value);
this.clearCache("tracks");
},
},
showGithubIcon: {
get() {
if (this.settings.showGithubIcon === undefined) return true;
return this.settings.showGithubIcon;
},
set(value) {
this.$store.commit("updateSettings", {
key: "showGithubIcon",
value,
});
},
},
showUnavailableSongInGreyStyle: {
get() {
return this.settings.showUnavailableSongInGreyStyle;
},
set(value) {
this.$store.commit("updateSettings", {
key: "showUnavailableSongInGreyStyle",
value,
});
},
},
showPlaylistsByAppleMusic: {
get() {
if (this.settings.showPlaylistsByAppleMusic === undefined) return true;
return this.settings.showPlaylistsByAppleMusic;
},
set(value) {
this.$store.commit("updateSettings", {
key: "showPlaylistsByAppleMusic",
value,
});
},
},
nyancatStyle: {
get() {
if (this.settings.nyancatStyle === undefined) return false;
return this.settings.nyancatStyle;
},
set(value) {
this.$store.commit("updateSettings", {
key: "nyancatStyle",
value,
});
},
},
automaticallyCacheSongs: {
get() {
if (this.settings.automaticallyCacheSongs === undefined) return false;
return this.settings.automaticallyCacheSongs;
},
set(value) {
this.$store.commit("updateSettings", {
key: "automaticallyCacheSongs",
value,
});
if (value === false) {
this.clearCache("tracks");
}
},
},
showLyricsTranslation: {
get() {
return this.settings.showLyricsTranslation;
},
set(value) {
this.$store.commit("updateSettings", {
key: "showLyricsTranslation",
value,
});
},
},
minimizeToTray: {
get() {
return this.settings.minimizeToTray;
},
set(value) {
this.$store.commit("updateSettings", {
key: "minimizeToTray",
value,
});
},
},
},
methods: {
logout() {
doLogout();
this.$router.push({ name: "home" });
},
countDBSize(dbName) {
countDBSize(dbName).then((data) => {
if (data === undefined) {
this.tracksCache = {
size: "0KB",
length: 0,
};
return;
}
this.tracksCache.size = bytesToSize(data.bytes);
this.tracksCache.length = data.length;
});
},
clearCache(dbName) {
// TODO: toast
clearDB(dbName).then(() => {
this.countDBSize("tracks");
});
},
},
created() {
this.countDBSize("tracks");
},
activated() {
this.countDBSize("tracks");
},
};
</script>
<style lang="scss" scoped>
.settings {
display: flex;
justify-content: center;
padding: var(--main-content-padding);
}
.container {
margin-top: 24px;
width: 720px;
}
h2 {
margin-top: 48px;
font-size: 36px;
color: var(--color-text);
}
.user {
display: flex;
align-items: center;
justify-content: space-between;
background: var(--color-secondary-bg);
color: var(--color-text);
padding: 16px 20px;
border-radius: 16px;
img.avatar {
border-radius: 50%;
height: 64px;
width: 64px;
}
img.cvip {
height: 13px;
margin-right: 4px;
}
.left {
display: flex;
align-items: center;
.info {
margin-left: 24px;
}
.nickname {
font-size: 20px;
font-weight: 600;
margin-bottom: 2px;
}
.extra-info {
font-size: 13px;
.text {
opacity: 0.68;
}
.vip {
display: flex;
align-items: center;
}
}
}
.right {
.svg-icon {
height: 18px;
width: 18px;
margin-right: 4px;
}
button {
display: flex;
align-items: center;
font-size: 18px;
font-weight: 600;
text-decoration: none;
border-radius: 10px;
padding: 8px 12px;
opacity: 0.68;
color: var(--color-text);
transition: 0.2s;
margin: {
right: 12px;
left: 12px;
}
&:hover {
opacity: 1;
background: #eaeffd;
color: #335eea;
}
&:active {
opacity: 1;
transform: scale(0.92);
transition: 0.2s;
}
}
}
}
.item {
margin: 24px 0;
display: flex;
align-items: center;
justify-content: space-between;
color: var(--color-text);
.title {
font-size: 18px;
font-weight: 600;
opacity: 0.88;
}
select {
min-width: 192px;
font-weight: 600;
border: none;
padding: 8px 12px 8px 12px;
border-radius: 8px;
color: var(--color-text);
background: var(--color-secondary-bg);
appearance: none;
&:focus {
outline: none;
color: var(--color-primary);
background: var(--color-primary-bg);
}
}
button {
color: var(--color-text);
background: var(--color-secondary-bg);
padding: 8px 12px 8px 12px;
font-weight: 600;
border-radius: 8px;
transition: 0.2s;
&:hover {
transform: scale(1.06);
}
&:active {
transform: scale(0.94);
}
}
}
.beforeAnimation {
-webkit-transition: 0.2s cubic-bezier(0.24, 0, 0.5, 1);
transition: 0.2s cubic-bezier(0.24, 0, 0.5, 1);
}
.afterAnimation {
box-shadow: 0 0 0 1px hsla(0, 0%, 0%, 0.1), 0 4px 0px 0 hsla(0, 0%, 0%, 0.04),
0 4px 9px hsla(0, 0%, 0%, 0.13), 0 3px 3px hsla(0, 0%, 0%, 0.05);
-webkit-transition: 0.35s cubic-bezier(0.54, 1.6, 0.5, 1);
transition: 0.35s cubic-bezier(0.54, 1.6, 0.5, 1);
}
.toggle {
margin: auto;
}
.toggle input {
opacity: 0;
position: absolute;
}
.toggle input + label {
position: relative;
display: inline-block;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-transition: 0.4s ease;
transition: 0.4s ease;
height: 32px;
width: 52px;
background: var(--color-secondary-bg);
border-radius: 8px;
}
.toggle input + label:before {
content: "";
position: absolute;
display: block;
-webkit-transition: 0.2s cubic-bezier(0.24, 0, 0.5, 1);
transition: 0.2s cubic-bezier(0.24, 0, 0.5, 1);
height: 32px;
width: 52px;
top: 0;
left: 0;
border-radius: 8px;
}
.toggle input + label:after {
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),
0 4px 9px hsla(0, 0%, 0%, 0.08), 0 3px 3px hsla(0, 0%, 0%, 0.03);
-webkit-transition: 0.35s cubic-bezier(0.54, 1.6, 0.5, 1);
transition: 0.35s cubic-bezier(0.54, 1.6, 0.5, 1);
background: #fff;
height: 20px;
width: 20px;
top: 6px;
left: 6px;
border-radius: 6px;
}
.toggle input:checked + label:before {
background: var(--color-primary);
-webkit-transition: width 0.2s cubic-bezier(0, 0, 0, 0.1);
transition: width 0.2s cubic-bezier(0, 0, 0, 0.1);
}
.toggle input:checked + label:after {
left: 26px;
}
</style>