diff --git a/postcss.config.js b/postcss.config.js
index 456a2009..260098a9 100644
--- a/postcss.config.js
+++ b/postcss.config.js
@@ -11,9 +11,14 @@ module.exports = {
'line-height',
'letter-spacing',
'padding', 'margin',
+ 'padding-left', 'padding-right',
+ 'padding-top', 'padding-bottom',
+ 'margin-left', 'margin-right',
+ 'margin-top', 'margin-bottom',
'height', 'width',
'max-width', 'max-height',
'min-width', 'min-height',
+ 'flex', '::-webkit-scrollbar',
'top', 'left', 'bottom', 'right',
'border-radius',
],
diff --git a/publish/changeLog.md b/publish/changeLog.md
index 08531797..b61ee280 100644
--- a/publish/changeLog.md
+++ b/publish/changeLog.md
@@ -8,6 +8,7 @@
- 新增虾米音源
- 新增新皮肤“粉妆玉琢”、“青出于黑”,可去体验下~
- 新增“超大”、“巨大”窗口尺寸
+- 新增播放详情页(退出详情页可点击右上角退出按钮或者在播放详情页任意地方**鼠标快速右击两次**)
### 优化
@@ -20,6 +21,7 @@
- 下载列表的歌曲下载、播放将随设置中的保存路径改变而改变,不再固定指向其初始位置
- 移除列表多选框,现在多选需要键盘配合,想要多选前需按下`Shift`或`Ctrl`键然后再鼠标点击想要选中的内容即可触发多选机制,其中`Shift`键用于连续选择,`Ctrl`键用于不连续选择,`Ctrl+a`用于快速全选。例子一:想要选中1-5项,则先按下`Shift`键后,鼠标点击第一项,再点击第五项即可完成选择;例子二:想要选中1项与第3项,则先按下`Ctrl`键后,鼠标点击第一项,再点击第三项即可完成选择;例子三:想要选中当前列表的全部内容,键盘先按下`Ctrl`键不放,然后按`a`键,即可完成选择。用`Shift`或`Ctrl`选择时,鼠标点击未选中的内容会将其选中,点击已选择的内容会将其取消选择,若想全部取消选择,在不按`Shift`或`Alt`键的情况下,随意点击列表里的一项内容即可全部取消选择。(P.S:`Ctrl`键对应Mac OS上的`Command`键)
+- 现在进度条的封面图左击改为打开播放详情页,在列表定位歌曲改为右击
### 修复
diff --git a/src/main/utils/flacMeta.js b/src/main/utils/flacMeta.js
index c9beaf26..9be44505 100644
--- a/src/main/utils/flacMeta.js
+++ b/src/main/utils/flacMeta.js
@@ -19,7 +19,6 @@ const writeMeta = async(filePath, meta, picPath) => {
}
if (picPath) {
const apicData = await fsPromises.readFile(picPath)
- console.log(apicData)
let imgSize = getImgSize(apicData)
let mime_type
let bitsPerPixel
diff --git a/src/renderer/App.vue b/src/renderer/App.vue
index f4e1107d..19f74dcd 100644
--- a/src/renderer/App.vue
+++ b/src/renderer/App.vue
@@ -1,24 +1,24 @@
-#container(v-if="isProd && !isNt" :class="theme" @mouseenter="enableIgnoreMouseEvents" @mouseleave="dieableIgnoreMouseEvents")
+#container(v-if="isProd && !isNt" :class="[theme, nd ? 'nd' : '']" @mouseenter="enableIgnoreMouseEvents" @mouseleave="dieableIgnoreMouseEvents")
core-aside#left
#right
core-toolbar#toolbar
core-view#view
core-player#player
core-icons
- material-pact-modal(v-show="!setting.isAgreePact || globalObj.isShowPact")
- material-version-modal(v-show="version.showModal")
material-xm-verify-modal(v-show="globalObj.xm.isShowVerify" :show="globalObj.xm.isShowVerify" :bg-close="false" @close="handleXMVerifyModalClose")
-#container(v-else :class="theme")
+ material-version-modal(v-show="version.showModal")
+ material-pact-modal(v-show="!setting.isAgreePact || globalObj.isShowPact")
+#container(v-else :class="[theme, nd ? 'nd' : '']")
core-aside#left
#right
core-toolbar#toolbar
core-view#view
core-player#player
core-icons
- material-pact-modal(v-show="!setting.isAgreePact || globalObj.isShowPact")
- material-version-modal(v-show="version.showModal")
material-xm-verify-modal(v-show="globalObj.xm.isShowVerify" :show="globalObj.xm.isShowVerify" :bg-close="false" @close="handleXMVerifyModalClose")
+ material-version-modal(v-show="version.showModal")
+ material-pact-modal(v-show="!setting.isAgreePact || globalObj.isShowPact")
@@ -609,13 +670,14 @@ export default {
border-top: 2px solid @color-theme;
box-sizing: border-box;
display: flex;
- z-index: 1;
+ z-index: 2;
* {
box-sizing: border-box;
}
}
.left {
width: @height-player - 2;
+ height: @height-player - 2;
color: @color-theme;
transition: @transition-theme;
transition-property: color;
@@ -863,7 +925,6 @@ each(@themes, {
.volume-bar {
background-color: ~'@{color-@{value}-theme}';
- box-shadow: 0 0 2px rgba(0, 0, 0, 0.3);
}
@@ -875,7 +936,6 @@ each(@themes, {
}
.progress-bar2 {
background-color: ~'@{color-@{value}-player-progress-bar2}';
- box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
}
.column3 {
diff --git a/src/renderer/components/core/PlayerDetail.vue b/src/renderer/components/core/PlayerDetail.vue
new file mode 100644
index 00000000..aa6106ab
--- /dev/null
+++ b/src/renderer/components/core/PlayerDetail.vue
@@ -0,0 +1,706 @@
+
+ div(:class="$style.container" @contextmenu="handleContextMenu")
+ //- div(:class="$style.bg" :style="bgStyle")
+ //- div(:class="$style.bg2")
+ div(:class="$style.header")
+ div(:class="$style.control")
+ button(type="button" :class="$style.hide" :title="$t('core.player.hide_detail')" @click="visiblePlayerDetail(false)")
+ button(type="button" :class="$style.min" :title="$t('core.toolbar.min')" @click="min")
+ //- button(type="button" :class="$style.max" @click="max")
+ button(type="button" :class="$style.close" :title="$t('core.toolbar.close')" @click="close")
+
+ div(:class="$style.main")
+ div(:class="$style.left")
+ div(:class="$style.info")
+ div(:class="$style.img")
+ img(:src="musicInfo.img" v-if="musicInfo.img")
+ div(:class="$style.description")
+ p {{$t('core.player.name')}}{{musicInfo.name}}
+ p {{$t('core.player.singer')}}{{musicInfo.singer}}
+ p(v-if="musicInfo.album") {{$t('core.player.album')}}{{musicInfo.album}}
+ //- div(:class="$style.list")
+ ul
+
+ div(:class="$style.right")
+ div(:class="[$style.lyric, lyricEvent.isMsDown ? $style.draging : null]" @mousedown="handleLyricMouseDown" ref="dom_lyric")
+ div(:class="$style.lyricSpace")
+ p(v-for="(info, index) in lyric.lines" :key="index" :class="lyric.line == index ? $style.lrcActive : null") {{info.text}}
+ div(:class="$style.lyricSpace")
+ div(:class="$style.footer")
+ div(:class="$style.left")
+ div(:class="$style.progressContainer")
+ div(:class="$style.progressContent")
+ div(:class="$style.progress")
+ //- div(:class="[$style.progressBar, $style.progressBar1]" :style="{ transform: `scaleX(${progress || 0})` }")
+ div(:class="[$style.progressBar, $style.progressBar2, isActiveTransition ? $style.barTransition : '']" @transitionend="handleTransitionEnd" :style="{ transform: `scaleX(${playInfo.progress || 0})` }")
+ div(:class="$style.progressMask" @click='setProgress' ref="dom_progress")
+ div(:class="$style.timeLabel")
+ span(style="margin-left: 15px") {{playInfo.status}}
+ div
+ span {{playInfo.nowPlayTimeStr}}
+ span(style="margin: 0 5px;") /
+ span {{playInfo.maxPlayTimeStr}}
+ div(:class="$style.playControl")
+ //- div(:class="$style.playBtn")
+ //- div(:class="$style.playBtn")
+ div(:class="$style.playBtn" @click="$emit('action', { type: 'prev' })" style="transform: rotate(180deg);" :title="$t('core.player.prev')")
+ svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 220.847 220.847' space='preserve')
+ use(xlink:href='#icon-nextMusic')
+ div(:class="$style.playBtn" :title="isPlay ? $t('core.player.pause') : $t('core.player.play')" @click="$emit('action', { type: 'togglePlay' })")
+ svg(v-if="isPlay" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 277.338 277.338' space='preserve')
+ use(xlink:href='#icon-pause')
+ svg(v-else version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 170 170' space='preserve')
+ use(xlink:href='#icon-play')
+ div(:class="$style.playBtn" @click="$emit('action', { type: 'next' })" :title="$t('core.player.next')")
+ svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 220.847 220.847' space='preserve')
+ use(xlink:href='#icon-nextMusic')
+
+
+
+
+
+
+
diff --git a/src/renderer/components/core/Toolbar.vue b/src/renderer/components/core/Toolbar.vue
index f778c611..a0219eb8 100644
--- a/src/renderer/components/core/Toolbar.vue
+++ b/src/renderer/components/core/Toolbar.vue
@@ -141,6 +141,11 @@ export default {
z-index: 2;
position: relative;
}
+:global(.nd) {
+ .toolbar {
+ -webkit-app-region: no-drag;
+ }
+}
.input {
-webkit-app-region: no-drag;
position: absolute;
@@ -166,7 +171,7 @@ export default {
align-items: center;
height: 100%;
-webkit-app-region: no-drag;
- padding: 0 @control-btn-width / 2;
+ padding: 0 @control-btn-width * 0.6;
&:hover {
button:before {
opacity: 1;
@@ -186,7 +191,7 @@ export default {
padding: 0;
cursor: pointer;
+ button {
- margin-left: @control-btn-width / 2;
+ margin-left: @control-btn-width * 0.4;
}
&:after {
diff --git a/src/renderer/lang/cns/core/player.json b/src/renderer/lang/cns/core/player.json
index 86ebfc0d..36936ad5 100644
--- a/src/renderer/lang/cns/core/player.json
+++ b/src/renderer/lang/cns/core/player.json
@@ -3,6 +3,7 @@
"volume": "当前音量:",
"pause": "暂停",
"play": "播放",
+ "prev": "上一首",
"next": "下一首",
"playing": "播放中...",
"stop": "暂停播放",
@@ -12,5 +13,9 @@
"loading": "音乐加载中...",
"buffering": "缓冲中...",
"geting_url": "歌曲链接获取中...",
- "lyric_error": "歌词获取失败"
+ "lyric_error": "歌词获取失败",
+ "hide_detail": "隐藏详情页",
+ "name": "歌曲名:",
+ "singer": "艺术家:",
+ "album": "专辑名:"
}
diff --git a/src/renderer/lang/cnt/core/player.json b/src/renderer/lang/cnt/core/player.json
index 0b68ff96..513ea11f 100644
--- a/src/renderer/lang/cnt/core/player.json
+++ b/src/renderer/lang/cnt/core/player.json
@@ -3,6 +3,7 @@
"volume": "當前音量:",
"pause": "暫停",
"play": "播放",
+ "prev": "上一首",
"next": "下一首",
"playing": "播放中...",
"stop": "暫停播放",
@@ -12,5 +13,9 @@
"loading": "音樂加載中...",
"buffering": "緩衝中...",
"geting_url": "歌曲鏈接獲取中...",
- "lyric_error": "歌詞獲取失敗"
+ "lyric_error": "歌詞獲取失敗",
+ "hide_detail": "隱藏詳情頁",
+ "name": "歌曲名:",
+ "singer": "藝術家:",
+ "album": "專輯名:"
}
diff --git a/src/renderer/lang/en/core/player.json b/src/renderer/lang/en/core/player.json
index 4a4e883f..dff70093 100644
--- a/src/renderer/lang/en/core/player.json
+++ b/src/renderer/lang/en/core/player.json
@@ -3,6 +3,7 @@
"volume": "Volume: ",
"pause": "Pause",
"play": "Play",
+ "prev": "Prev",
"next": "Next",
"playing": "Now playing...",
"stop": "Paused",
@@ -12,5 +13,9 @@
"loading": "Music loading...",
"buffering": "Buffering...",
"geting_url": "Getting music link...",
- "lyric_error": "Failed to get lyrics"
+ "lyric_error": "Failed to get lyrics",
+ "hide_detail": "Hide detail page",
+ "name": "Name: ",
+ "singer": "Artist: ",
+ "album": "Album: "
}
diff --git a/src/renderer/store/modules/player.js b/src/renderer/store/modules/player.js
index f3c27621..2af51c1e 100644
--- a/src/renderer/store/modules/player.js
+++ b/src/renderer/store/modules/player.js
@@ -6,6 +6,7 @@ const state = {
listId: null,
playIndex: -1,
changePlay: false,
+ isShowPlayerDetail: false,
}
let urlRequest
@@ -18,6 +19,7 @@ const getters = {
listId: state => state.listId,
changePlay: satte => satte.changePlay,
playIndex: state => state.playIndex,
+ isShowPlayerDetail: state => state.isShowPlayerDetail,
}
// actions
@@ -87,6 +89,9 @@ const mutations = {
resetChangePlay(state) {
state.changePlay = false
},
+ visiblePlayerDetail(state, visible) {
+ state.isShowPlayerDetail = visible
+ },
}
export default {
diff --git a/src/renderer/utils/index.js b/src/renderer/utils/index.js
index 17bbfa6b..4c6f677d 100644
--- a/src/renderer/utils/index.js
+++ b/src/renderer/utils/index.js
@@ -65,6 +65,7 @@ const easeInOutQuad = (t, b, c, d) => {
export const scrollTo = (element, to, duration = 300, fn = () => {}) => {
if (!element) return
const start = element.scrollTop || element.scrollY || 0
+ let cancel = false
if (to > start) {
let maxScrollTop = element.scrollHeight - element.clientHeight
if (to > maxScrollTop) to = maxScrollTop
@@ -87,12 +88,16 @@ export const scrollTo = (element, to, duration = 300, fn = () => {}) => {
element.scrollTop = val
}
if (currentTime < duration) {
+ if (cancel) return fn()
setTimeout(animateScroll, increment)
} else {
fn()
}
}
animateScroll()
+ return () => {
+ cancel = true
+ }
}
/**