diff --git a/src/assets/icons/sort-up.svg b/src/assets/icons/sort-up.svg
new file mode 100644
index 0000000..3efe4cf
--- /dev/null
+++ b/src/assets/icons/sort-up.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/src/components/Player.vue b/src/components/Player.vue
index 4ee8c54..ff92882 100644
--- a/src/components/Player.vue
+++ b/src/components/Player.vue
@@ -132,6 +132,13 @@
@click.native="player.switchShuffle"
>
+
diff --git a/src/locale/lang/en.js b/src/locale/lang/en.js
index fd33dc4..087f7c5 100644
--- a/src/locale/lang/en.js
+++ b/src/locale/lang/en.js
@@ -100,6 +100,7 @@ export default {
repeat: 'Repeat',
repeatTrack: 'Repeat Track',
shuffle: 'Shuffle',
+ reversed: 'Reversed',
play: 'Play',
pause: 'Pause',
mute: 'Mute',
@@ -154,8 +155,9 @@ export default {
showPlaylistsByAppleMusic: 'Show playlists by Apple Music',
enableDiscordRichPresence: 'Enable Discord Rich Presence',
enableGlobalShortcut: 'Enable Global Shortcut',
- showLibraryDefault: 'Show library default',
- subTitleDefault: 'Sub title alia default',
+ showLibraryDefault: 'Show Library after App Launched',
+ subTitleDefault: 'Show Alias for Subtitle by default',
+ enableReversedMode: 'Enable Reversed Mode (Experimental)',
lyricsBackground: {
text: 'Show Lyrics Background',
off: 'Off',
diff --git a/src/locale/lang/zh-CN.js b/src/locale/lang/zh-CN.js
index 084c94a..cb077ad 100644
--- a/src/locale/lang/zh-CN.js
+++ b/src/locale/lang/zh-CN.js
@@ -101,6 +101,7 @@ export default {
repeat: '循环播放',
repeatTrack: '单曲循环',
shuffle: '随机播放',
+ reversed: '倒序播放',
play: '播放',
pause: '暂停',
mute: '静音',
@@ -157,6 +158,7 @@ export default {
enableGlobalShortcut: '启用全局快捷键',
showLibraryDefault: '启动后显示音乐库',
subTitleDefault: '副标题使用别名',
+ enableReversedMode: '启用倒序播放功能 (实验性功能)',
lyricsBackground: {
text: '显示歌词背景',
off: '关闭',
diff --git a/src/locale/lang/zh-TW.js b/src/locale/lang/zh-TW.js
index 06ac527..55fa5d3 100644
--- a/src/locale/lang/zh-TW.js
+++ b/src/locale/lang/zh-TW.js
@@ -97,6 +97,7 @@ export default {
repeat: '循環播放',
repeatTrack: '單曲循環',
shuffle: '隨機播放',
+ reversed: '倒序播放',
play: '播放',
pause: '暫停',
mute: '靜音',
@@ -154,6 +155,7 @@ export default {
enableGlobalShortcut: '啟用全域快捷鍵',
showLibraryDefault: '啟動後顯示音樂庫',
subTitleDefault: '副標題使用別名',
+ enableReversedMode: '啟用倒序播放功能 (實驗性功能)',
lyricsBackground: {
text: '顯示歌詞背景',
off: '關閉',
diff --git a/src/store/initLocalStorage.js b/src/store/initLocalStorage.js
index 5fa494a..b16e847 100644
--- a/src/store/initLocalStorage.js
+++ b/src/store/initLocalStorage.js
@@ -19,6 +19,7 @@ let localStorage = {
enableUnblockNeteaseMusic: true,
automaticallyCacheSongs: true,
cacheLimit: 8192,
+ enableReversedMode: false,
nyancatStyle: false,
showLyricsTranslation: true,
lyricsBackground: true,
diff --git a/src/utils/Player.js b/src/utils/Player.js
index c6d9fda..5bb7cd9 100644
--- a/src/utils/Player.js
+++ b/src/utils/Player.js
@@ -28,6 +28,7 @@ export default class {
this._enabled = false; // 是否启用Player
this._repeatMode = 'off'; // off | on | one
this._shuffle = false; // true | false
+ this._reversed = false;
this._volume = 1; // 0 to 1
this._volumeBeforeMuted = 1; // 用于保存静音前的音量
this._personalFMLoading = false; // 是否正在私人FM中加载新的track
@@ -91,6 +92,18 @@ export default class {
this._shuffleTheList();
}
}
+ get reversed() {
+ return this._reversed;
+ }
+ set reversed(reversed) {
+ if (this._isPersonalFM) return;
+ if (reversed !== true && reversed !== false) {
+ console.warn('reversed: invalid args, must be Boolean');
+ return;
+ }
+ console.log('changing reversed to:', reversed);
+ this._reversed = reversed;
+ }
get volume() {
return this._volume;
}
@@ -191,27 +204,43 @@ export default class {
}, 1000);
}
_getNextTrack() {
+ const next = this._reversed ? this.current - 1 : this.current + 1;
+
if (this._playNextList.length > 0) {
let trackID = this._playNextList.shift();
return [trackID, this.current];
}
- // 当歌曲是列表最后一首 && 循环模式开启
- if (this.list.length === this.current + 1 && this.repeatMode === 'on') {
- return [this.list[0], 0];
+ // 循环模式开启,则重新播放当前模式下的相对的下一首
+ if (this.repeatMode === 'on') {
+ if (this._reversed && this.current === 0) {
+ // 倒序模式,当前歌曲是第一首,则重新播放列表最后一首
+ return [this.list[this.list.length - 1], this.list.length - 1];
+ } else if (this.list.length === this.current + 1) {
+ // 正序模式,当前歌曲是最后一首,则重新播放第一首
+ return [this.list[0], 0];
+ }
}
// 返回 [trackID, index]
- return [this.list[this.current + 1], this.current + 1];
+ return [this.list[next], next];
}
_getPrevTrack() {
- // 当歌曲是列表第一首 && 循环模式开启
- if (this.current === 0 && this.repeatMode === 'on') {
- return [this.list[this.list.length - 1], this.list.length - 1];
+ const next = this._reversed ? this.current + 1 : this.current - 1;
+
+ // 循环模式开启,则重新播放当前模式下的相对的下一首
+ if (this.repeatMode === 'on') {
+ if (this._reversed && this.current === 0) {
+ // 倒序模式,当前歌曲是最后一首,则重新播放列表第一首
+ return [this.list[0], 0];
+ } else if (this.list.length === this.current + 1) {
+ // 正序模式,当前歌曲是第一首,则重新播放列表最后一首
+ return [this.list[this.list.length - 1], this.list.length - 1];
+ }
}
// 返回 [trackID, index]
- return [this.list[this.current - 1], this.current - 1];
+ return [this.list[next], next];
}
async _shuffleTheList(firstTrackID = this._currentTrack.id) {
let list = this._list.filter(tid => tid !== firstTrackID);
@@ -726,6 +755,9 @@ export default class {
switchShuffle() {
this.shuffle = !this.shuffle;
}
+ switchReversed() {
+ this.reversed = !this.reversed;
+ }
clearPlayNextList() {
this._playNextList = [];
diff --git a/src/views/lyrics.vue b/src/views/lyrics.vue
index 7cf9817..d7f4216 100644
--- a/src/views/lyrics.vue
+++ b/src/views/lyrics.vue
@@ -59,8 +59,8 @@
{{ artist.name }}
-
+ >{{ artist.name }}
-
+ >
+ {{ line.contents[0] }}
+
+ {{ line.contents[1] }}
+
@@ -400,16 +410,6 @@ export default {
}
}, 50);
},
- formatLine(line) {
- const showLyricsTranslation = this.$store.state.settings
- .showLyricsTranslation;
- if (showLyricsTranslation && line.contents[1]) {
- return `${line.contents[0]}
${line.contents[1]}`;
- } else if (line.contents[0] !== undefined) {
- return `${line.contents[0]}`;
- }
- return 'unknown';
- },
moveToFMTrash() {
this.player.moveToFMTrash();
},
@@ -673,17 +673,28 @@ export default {
scrollbar-width: none; // firefox
.line {
- padding: 18px;
- transition: 0.2s;
+ margin: 2px 0;
+ padding: 12px 18px;
+ transition: 0.5s;
border-radius: 12px;
&:hover {
background: var(--color-secondary-bg-for-transparent);
}
+ &:active {
+ transform: scale(0.95);
+ }
span {
opacity: 0.28;
cursor: default;
+ font-size: 1em;
+ transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94);
+ }
+
+ span.translation {
+ opacity: 0.2;
+ font-size: 0.95em;
}
}
@@ -691,9 +702,19 @@ export default {
background: unset;
}
+ .translation {
+ margin-top: 0.1em;
+ }
+
.highlight span {
opacity: 0.98;
- transition: 0.5s;
+ display: inline-block;
+ font-size: 1.25em;
+ }
+
+ .highlight span.translation {
+ opacity: 0.65;
+ font-size: 1.1em;
}
}
@@ -755,6 +776,12 @@ export default {
}
}
+@media screen and (min-width: 1200px) {
+ .right-side .lyrics-container {
+ max-width: 600px;
+ }
+}
+
.slide-up-enter-active,
.slide-up-leave-active {
transition: all 0.4s;
diff --git a/src/views/settings.vue b/src/views/settings.vue
index 37da6a9..a36ec7b 100644
--- a/src/views/settings.vue
+++ b/src/views/settings.vue
@@ -384,6 +384,23 @@
+
+
+
{{ $t('settings.enableReversedMode') }}
+
+
+
+
🐈️ 🏳️🌈
@@ -805,6 +822,21 @@ export default {
});
},
},
+ enableReversedMode: {
+ get() {
+ if (this.settings.enableReversedMode === undefined) return false;
+ return this.settings.enableReversedMode;
+ },
+ set(value) {
+ this.$store.commit('updateSettings', {
+ key: 'enableReversedMode',
+ value,
+ });
+ if (value === false) {
+ this.$store.state.player.reversed = false;
+ }
+ },
+ },
enableGlobalShortcut: {
get() {
return this.settings.enableGlobalShortcut;