From be219f03d5dfd018fbad47bc93630ebbc9f5bfb2 Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sun, 20 Mar 2022 14:28:59 +0800 Subject: [PATCH 01/68] typo --- FAQ.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FAQ.md b/FAQ.md index 0abf6804..26b2b22c 100644 --- a/FAQ.md +++ b/FAQ.md @@ -8,8 +8,8 @@ ## 音乐播放列表机制 -1. 默认情况下,播放搜索列表、歌单列表、排行榜列表的歌曲时会自动将该歌曲添加到“我的列表”的试听列表后再播放,手动将歌曲添加到试听列表,再去试听列表找到这首歌点播放是等价的 -2. 如果你想要播放多首歌曲,需要使用多选功能(若不知道如何多选请看常见问题)多选后,将歌曲这些歌曲添加到“我的列表”播放,或使用稍后播放功能播放 +1. 默认情况下,播放搜索列表、歌单列表、排行榜列表的歌曲时会自动将该歌曲添加到“我的列表”的试听列表后再播放,这与手动将歌曲添加到试听列表,再去试听列表找到这首歌点播放是等价的 +2. 如果你想要播放多首歌曲,需要使用多选功能(若不知道如何多选请看常见问题)多选后,将这些歌曲添加到“我的列表”播放,或使用稍后播放功能播放 3. 第2条适用于搜索列表、歌单列表、排行榜列表、我的列表中的歌曲 4. 对于歌单详情列表,除了可以使用第2条的方式播放外,你可以点击详情页上面的播放按钮临时播放当前歌单,或点击收藏将当前歌单收藏到“我的列表”后再去播放 5. 对于排行榜详情列表,除了可以使用第2条的方式播放外,你可以在右击排行榜名字后弹出的菜单中,播放或收藏整个排行榜,这与第四条的歌单中的播放、与收藏按钮功能一致 From 226fb05337b5d9d0474e53fa3b180098c7d86dd8 Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sun, 20 Mar 2022 20:16:01 +0800 Subject: [PATCH 02/68] =?UTF-8?q?=E4=BF=AE=E5=A4=8DLinux=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E5=85=A8=E5=B1=8F=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- publish/changeLog.md | 43 +------------------------ src/main/rendererEvents/trafficLight.js | 13 +++++++- 3 files changed, 14 insertions(+), 44 deletions(-) diff --git a/package.json b/package.json index f7315e42..55020b1d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lx-music-desktop", - "version": "1.19.0", + "version": "1.19.1-beta", "description": "一个免费的音乐查找助手", "main": "./dist/electron/main.js", "productName": "lx-music-desktop", diff --git a/publish/changeLog.md b/publish/changeLog.md index c24347e6..08a31d0f 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -1,44 +1,3 @@ -### 新增 - -- 新增对播放详情页歌词大小、是否缩放、对齐方式的设置,可以去设置-播放详情页设置查看 -- 新增播放详情页通过歌词调整播放进度,默认关闭,需要到设置-播放详情页设置开启,开启后在播放详情页拖动歌词时将会出现跳转当前行歌词播放的按钮 -- 新增全屏状态,按F11可以进入、退出全屏状态,由于全屏时会隐藏控制栏按钮,所以需要使用鼠标右键双击(详情页的任意地方都可以)来关闭播放详情页 -- 新增动态主题“道法自然”,你可以预先设置一个亮色主题及暗色主题,此后将根据系统的亮、暗主题色自动切换为你预先设置的相应主题。注:鼠标 右击 此主题项即可打开亮、暗色主题设置窗口。 -- 新增对kw源卡拉OK歌词的支持 - -### 优化 - -- 优化Windows任务栏缩略图工具栏控制按钮在浅色任务栏下的显示效果 -- 添加音频可视化与音频输出设备冲突的提示 -- 优化歌词的播放偏移 -- 优化托盘菜单操作(#686) -- 优化播放下载列表时的切歌性能 - ### 修复 -- 修复“当前的声音输出设备被改变时暂停播放歌曲”设置无效的问题 -- 修复桌面歌词没有处理停止播放状态的问题 -- 修复AppImage包无法运行的问题 -- 修复Windows任务栏缩略图工具栏控制按钮的歌曲收藏按钮状态更新问题 -- 修复使用链接导入的歌单无法在我的列表打开原歌单详情页的问题 -- 修复播放下载列表的歌曲时增删下载任务导致正在的歌曲序号改变时,不会更新到新增序号的问题 - -### 文档 - -添加LX中定义的快捷操作汇总说明到常见问题中,这是目前可用的鼠标、键盘快捷操作,它们都可以在更新日志中找到 - -- 鼠标右击播放栏的歌曲图片封面可以定位当前播放的歌曲 -- 鼠标右击播放栏进度条上的LRC按钮可以锁定/解锁桌面歌词 -- 歌曲搜索框、歌单链接输入框内鼠标右击可以将当前剪贴板上的文字粘贴到输入框内 -- 鼠标右击搜索界面中的单条搜索历史可以将其移除 -- 歌曲列表内的文字在选中后,鼠标右击可以复制已选中的文字,此功能只对搜索、歌单、排行榜、我的列表中的列表有效 -- 鼠标在播放详情页内右键双击可以关闭播放详情页 -- 鼠标左击播放栏上的歌曲名字可以将它复制 -- 鼠标右击“道法自然(英文Auto)”主题可以打开亮、暗主题设置窗口 -- 歌曲搜索框的候选内容可以用键盘上下方向键选择,按回车键搜索已选内容 -- 在歌单详情页按退格键可以返回歌单列表 -- 歌曲列表中可以使用Ctrl、Shift键进行多选,这类似Windows下的文件选择,详情看常见问题列表多选部分 -- 在我的列表内可以使用Ctrl+f键打开搜索框进行列表内歌曲搜索,搜索框按Esc键可以关闭搜索框,搜索框内按上下方向键可以选择歌曲,按回车键跳转到已选歌曲,按Ctrl+回车可以跳转并播放已选歌曲 -- 在我的列表按住Ctrl键可以进入列表拖动模式,此时可以用鼠标拖动列表调整列表的位置 -- 编辑列表名时按Esc键可以取消编辑 -- 按F11可以进入、退出全屏状态 +- 修复Linux无法全屏的问题 diff --git a/src/main/rendererEvents/trafficLight.js b/src/main/rendererEvents/trafficLight.js index 324a914c..2e43f281 100644 --- a/src/main/rendererEvents/trafficLight.js +++ b/src/main/rendererEvents/trafficLight.js @@ -1,5 +1,6 @@ const { app } = require('electron') const { mainOn, mainHandle, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc') +const { isLinux } = require('@common/utils') mainOn(ipcMainWindowNames.min, event => { if (global.modules.mainWindow) { @@ -18,6 +19,16 @@ mainOn(ipcMainWindowNames.close, (event, isForce) => { }) mainHandle(ipcMainWindowNames.fullscreen, async(event, isFullscreen) => { if (!global.modules.mainWindow) return false - await global.modules.mainWindow.setFullScreen(isFullscreen) + if (isLinux) { // linux 需要先设置为可调整窗口大小才能全屏 + if (isFullscreen) { + await global.modules.mainWindow.setResizable(isFullscreen) + await global.modules.mainWindow.setFullScreen(isFullscreen) + } else { + await global.modules.mainWindow.setFullScreen(isFullscreen) + await global.modules.mainWindow.setResizable(isFullscreen) + } + } else { + await global.modules.mainWindow.setFullScreen(isFullscreen) + } return isFullscreen }) From 82ea1935deefd77f4fb1cd3147f8beff01dc0cdb Mon Sep 17 00:00:00 2001 From: lyswhut Date: Mon, 21 Mar 2022 10:03:35 +0800 Subject: [PATCH 03/68] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=A0=8F=E6=94=B6=E8=97=8F=E6=8C=89=E9=92=AE=E7=9A=84=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E5=88=97=E8=A1=A8=E6=AD=8C=E6=9B=B2=E6=94=B6=E8=97=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- publish/changeLog.md | 1 + src/renderer/core/useApp/usePlayer/useTaskbar.js | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/publish/changeLog.md b/publish/changeLog.md index 08a31d0f..160c4947 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -1,3 +1,4 @@ ### 修复 - 修复Linux无法全屏的问题 +- 修复播放下载列表的歌曲时,使用Windows任务栏缩略图工具栏控制按钮的收藏按钮收藏歌曲时的异常问题 diff --git a/src/renderer/core/useApp/usePlayer/useTaskbar.js b/src/renderer/core/useApp/usePlayer/useTaskbar.js index 4b3af07f..6cad52d6 100644 --- a/src/renderer/core/useApp/usePlayer/useTaskbar.js +++ b/src/renderer/core/useApp/usePlayer/useTaskbar.js @@ -4,7 +4,7 @@ import { onTaskbarThumbarClick, setTaskbarThumbnailClip, setTaskbarThumbarButton // import store from '@renderer/store' import { loveList, getList } from '@renderer/core/share/list' -import { playMusicInfo } from '@renderer/core/share/player' +import { playMusicInfo, musicInfoItem } from '@renderer/core/share/player' import { throttle } from '@renderer/utils' export default () => { @@ -82,12 +82,12 @@ export default () => { break case 'collect': if (!playMusicInfo.musicInfo) return - listAdd({ id: loveList.id, musicInfo: playMusicInfo.musicInfo }) + listAdd({ id: loveList.id, musicInfo: musicInfoItem.value }) if (updateCollectStatus()) setButtons() break case 'unCollect': if (!playMusicInfo.musicInfo) return - listRemove({ listId: loveList.id, id: playMusicInfo.musicInfo.songmid }) + listRemove({ listId: loveList.id, id: musicInfoItem.value.songmid }) if (updateCollectStatus()) setButtons() break // case 'lrc': From bc301c27c2071a68ba319ce64827176a960308e1 Mon Sep 17 00:00:00 2001 From: lyswhut Date: Tue, 22 Mar 2022 16:55:44 +0800 Subject: [PATCH 04/68] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=92=AD=E6=94=BE?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E6=AD=8C=E8=AF=8D=E5=8F=B3=E9=94=AE?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=EF=BC=8C=E6=96=B0=E5=A2=9E=E6=AD=8C=E8=AF=8D?= =?UTF-8?q?=E5=81=8F=E7=A7=BB=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- publish/changeLog.md | 14 + src/common/ipcNames.js | 6 + src/lang/en-us.json | 15 +- src/lang/zh-cn.json | 15 +- src/lang/zh-tw.json | 15 +- src/main/rendererEvents/lyric.js | 16 +- src/renderer/components/core/Icons.vue | 8 + .../core/PlayDetail/LyricPlayer.vue | 64 ++-- .../core/PlayDetail/components/LyricMenu.vue | 300 ++++++++++++++++++ src/renderer/core/share/lyric.js | 4 + .../core/useApp/usePlayer/useLyric.js | 60 ++-- src/renderer/event/names.js | 1 + src/renderer/store/getters.js | 3 + src/renderer/store/mutations.js | 3 + .../utils/compositions/useMenuLocation.js | 81 +++++ src/renderer/utils/index.js | 10 +- src/renderer/views/setting/Setting.vue | 6 +- .../setting/components/SettingPlayDetail.vue | 13 +- 18 files changed, 572 insertions(+), 62 deletions(-) create mode 100644 src/renderer/components/core/PlayDetail/components/LyricMenu.vue create mode 100644 src/renderer/utils/compositions/useMenuLocation.js diff --git a/publish/changeLog.md b/publish/changeLog.md index 160c4947..160dfa70 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -1,4 +1,18 @@ +### 新增 + +- 新增播放详情页歌词右键菜单,原来设置-播放详情页设置的字体重置已迁移到此菜单内 +- 新增歌词偏移设置,可以在播放详情页歌词右键菜单中使用 + ### 修复 - 修复Linux无法全屏的问题 - 修复播放下载列表的歌曲时,使用Windows任务栏缩略图工具栏控制按钮的收藏按钮收藏歌曲时的异常问题 + +### 变更 + +- 播放详情页的任意地方右键双击隐藏详情页的行为,“任意区域”改为在“非歌词区域” + +### 移除 + +- 移除设置-播放详情页设置-歌词字体重置,此设置项已迁移到播放详情页的歌词菜单中 +- 移除播放详情页使用+-快捷键调整字体大小的功能,改用歌词右键菜单的字体大小调整功能 diff --git a/src/common/ipcNames.js b/src/common/ipcNames.js index 0277fee9..f1b70ee4 100644 --- a/src/common/ipcNames.js +++ b/src/common/ipcNames.js @@ -77,6 +77,12 @@ const names = { get_lyric: 'get_lyric', save_lyric: 'save_lyric', clear_lyric: 'clear_lyric', + get_lyric_raw: 'get_lyric_raw', + save_lyric_raw: 'save_lyric_raw', + clear_lyric_raw: 'clear_lyric_raw', + get_lyric_edited: 'get_lyric_edited', + save_lyric_edited: 'save_lyric_edited', + remove_lyric_edited: 'remove_lyric_edited', get_music_url: 'get_music_url', save_music_url: 'save_music_url', clear_music_url: 'clear_music_url', diff --git a/src/lang/en-us.json b/src/lang/en-us.json index bd86a0e0..32cff940 100644 --- a/src/lang/en-us.json +++ b/src/lang/en-us.json @@ -127,6 +127,19 @@ "love_list": "Favorites", "lyric__load_error": "Failed to get lyrics", "lyric__select": "Lyric text selection", + "lyric_menu__align": "Lyric Alignment", + "lyric_menu__align_center": "Centered", + "lyric_menu__align_left": "Left", + "lyric_menu__lrc_size": "Font size [{size}]", + "lyric_menu__offset": "Offset [ {offset}ms ]", + "lyric_menu__offset_add_10": "10ms faster (right click speeds up 5ms)", + "lyric_menu__offset_add_100": "100ms faster (right click speeds up 50ms)", + "lyric_menu__offset_dec_10": "10ms slow down (right click slows down 5ms)", + "lyric_menu__offset_dec_100": "Slow down by 100ms (right click slows down by 50ms)", + "lyric_menu__offset_reset": "Reset", + "lyric_menu__size_add": "Increase font size (right click to fine-tune)", + "lyric_menu__size_dec": "Decrease font (right click to fine tune)", + "lyric_menu__size_reset": "Reset", "min": "Minimize", "music_album": "Album", "music_duplicate": "Duplicate song", @@ -330,11 +343,11 @@ "setting__play_detail_align_center": "Centered", "setting__play_detail_align_left": "Left", "setting__play_detail_align_right": "Right", - "setting__play_detail_detail_lyric_progress": "Allows to adjust playback progress by lyrics", "setting__play_detail_font_size": "Lyrics font size (you can use the keyboard + - adjust the font size on the playback details page)", "setting__play_detail_font_size_current": "Current font size: {size}", "setting__play_detail_font_size_reset": "Reset", "setting__play_detail_font_zoom": "Zoom the currently playing lyrics", + "setting__play_detail_lyric_progress": "Allows to adjust playback progress by lyrics", "setting__play_lyric_lxlrc": "Use Karaoke-style lyrics playback (if supported)", "setting__play_lyric_s2t": "Convert the playing and downloading lyrics to Traditional Chinese", "setting__play_lyric_transition": "Show lyrics translation", diff --git a/src/lang/zh-cn.json b/src/lang/zh-cn.json index 1ab072e1..75b8275a 100644 --- a/src/lang/zh-cn.json +++ b/src/lang/zh-cn.json @@ -127,6 +127,19 @@ "love_list": "收藏", "lyric__load_error": "歌词获取失败", "lyric__select": "歌词文本选择", + "lyric_menu__align": "歌词对齐方式", + "lyric_menu__align_center": "居中", + "lyric_menu__align_left": "居左", + "lyric_menu__lrc_size": "字体大小 [ {size} ]", + "lyric_menu__offset": "歌词偏移 [ {offset}ms ]", + "lyric_menu__offset_add_10": "加快10毫秒(右击加快5毫秒)", + "lyric_menu__offset_add_100": "加快100毫秒(右击加快50毫秒)", + "lyric_menu__offset_dec_10": "减慢10毫秒(右击减慢5毫秒)", + "lyric_menu__offset_dec_100": "减慢100毫秒(右击减慢50毫秒)", + "lyric_menu__offset_reset": "重置", + "lyric_menu__size_add": "加大字体(右击可微调)", + "lyric_menu__size_dec": "减小字体(右击可微调)", + "lyric_menu__size_reset": "重置", "min": "最小化", "music_album": "专辑名", "music_duplicate": "重复歌曲", @@ -330,7 +343,7 @@ "setting__play_detail_align_center": "居中", "setting__play_detail_align_left": "居左", "setting__play_detail_align_right": "居右", - "setting__play_detail_detail_lyric_progress": "允许通过歌词调整播放进度", + "setting__play_detail_lyric_progress": "允许通过歌词调整播放进度", "setting__play_detail_font_size": "歌词字体大小(可以在播放详情页使用键盘的 + - 调整字体大小)", "setting__play_detail_font_size_current": "当前字体大小:{size}", "setting__play_detail_font_size_reset": "重置", diff --git a/src/lang/zh-tw.json b/src/lang/zh-tw.json index 9f04819d..6173e370 100644 --- a/src/lang/zh-tw.json +++ b/src/lang/zh-tw.json @@ -127,6 +127,19 @@ "love_list": "收藏列表", "lyric__load_error": "歌詞獲取失敗", "lyric__select": "歌詞文本選擇", + "lyric_menu__align": "歌詞對齊方式", + "lyric_menu__align_center": "居中", + "lyric_menu__align_left": "居左", + "lyric_menu__lrc_size": "字體大小 [ {size} ]", + "lyric_menu__offset": "歌詞偏移 [ {offset}ms ]", + "lyric_menu__offset_add_10": "加快10毫秒(右擊加快5毫秒)", + "lyric_menu__offset_add_100": "加快100毫秒(右擊加快50毫秒)", + "lyric_menu__offset_dec_10": "減慢10毫秒(右擊減慢5毫秒)", + "lyric_menu__offset_dec_100": "減慢100毫秒(右擊減慢50毫秒)", + "lyric_menu__offset_reset": "重置偏移", + "lyric_menu__size_add": "加大字體(右擊可微調)", + "lyric_menu__size_dec": "減小字體(右擊可微調)", + "lyric_menu__size_reset": "重置", "min": "最小化", "music_album": "專輯名", "music_duplicate": "重複歌曲", @@ -330,7 +343,7 @@ "setting__play_detail_align_center": "居中", "setting__play_detail_align_left": "居左", "setting__play_detail_align_right": "居右", - "setting__play_detail_detail_lyric_progress": "允許通過歌詞調整播放進度", + "setting__play_detail_lyric_progress": "允許通過歌詞調整播放進度", "setting__play_detail_font_size": "歌詞字體大小(可以在播放詳情頁使用鍵盤的 + - 調整字體大小)", "setting__play_detail_font_size_current": "當前字體大小:{size}", "setting__play_detail_font_size_reset": "重置", diff --git a/src/main/rendererEvents/lyric.js b/src/main/rendererEvents/lyric.js index 839a33f0..a96b2580 100644 --- a/src/main/rendererEvents/lyric.js +++ b/src/main/rendererEvents/lyric.js @@ -1,10 +1,20 @@ const { mainOn, NAMES: { mainWindow: ipcMainWindowNames }, mainHandle } = require('../../common/ipc') const getStore = require('@common/store') +const LRC_RAW = 'lyrics' +const LRC_EDITED = 'lyrics_edited' -mainHandle(ipcMainWindowNames.get_lyric, async(event, id) => getStore('lyrics', true, false).get(id) || {}) +mainHandle(ipcMainWindowNames.get_lyric, async(event, id) => { + return getStore(LRC_EDITED, true, false).get(id) || getStore(LRC_RAW, true, false).get(id) || {} +}) -mainOn(ipcMainWindowNames.save_lyric, (event, { id, lyrics }) => getStore('lyrics', true, false).set(id, lyrics)) +// 原始歌词 +mainHandle(ipcMainWindowNames.get_lyric_raw, async(event, id) => getStore(LRC_RAW, true, false).get(id) || {}) +mainOn(ipcMainWindowNames.save_lyric_raw, (event, { id, lyrics }) => getStore(LRC_RAW, true, false).set(id, lyrics)) +mainOn(ipcMainWindowNames.clear_lyric_raw, () => getStore(LRC_RAW, true, false).clear()) -mainOn(ipcMainWindowNames.clear_lyric, () => getStore('lyrics', true, false).clear()) +// 已编辑的歌词 +mainHandle(ipcMainWindowNames.get_lyric_edited, async(event, id) => getStore(LRC_EDITED, true, false).get(id) || {}) +mainOn(ipcMainWindowNames.save_lyric_edited, (event, { id, lyrics }) => getStore(LRC_EDITED, true, false).set(id, lyrics)) +mainOn(ipcMainWindowNames.remove_lyric_edited, async(event, id) => getStore(LRC_EDITED, true, false).delete(id)) diff --git a/src/renderer/components/core/Icons.vue b/src/renderer/components/core/Icons.vue index 72ecee74..419fd12e 100644 --- a/src/renderer/components/core/Icons.vue +++ b/src/renderer/components/core/Icons.vue @@ -234,5 +234,13 @@ svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/19 // 0 0 24 24 path(fill='currentColor', d='M22 12L20 13L19 14L18 13L17 16L16 13L15 21L14 13L13 15L12 13L11 17L10 13L9 22L8 13L7 19L6 13L5 14L4 13L2 12L4 11L5 10L6 11L7 5L8 11L9 2L10 11L11 7L12 11L13 9L14 11L15 3L16 11L17 8L18 11L19 10L20 11L22 12Z') + g#icon-font-decrease(fill='currentColor') + // 0 0 24 24 + path(d='M5.12,14L7.5,7.67L9.87,14M6.5,5L1,19H3.25L4.37,16H10.62L11.75,19H14L8.5,5H6.5M18,17L23,11.93L21.59,10.5L19,13.1V7H17V13.1L14.41,10.5L13,11.93L18,17Z') + + g#icon-font-increase(fill='currentColor') + // 0 0 24 24 + path(d='M5.12,14L7.5,7.67L9.87,14M6.5,5L1,19H3.25L4.37,16H10.62L11.75,19H14L8.5,5H6.5M18,7L13,12.07L14.41,13.5L17,10.9V17H19V10.9L21.59,13.5L23,12.07L18,7Z') + diff --git a/src/renderer/components/core/PlayDetail/LyricPlayer.vue b/src/renderer/components/core/PlayDetail/LyricPlayer.vue index bb06c4ce..7bc0cf6d 100644 --- a/src/renderer/components/core/PlayDetail/LyricPlayer.vue +++ b/src/renderer/components/core/PlayDetail/LyricPlayer.vue @@ -1,5 +1,5 @@ @@ -32,14 +33,18 @@ import { clipboardWriteText } from '@renderer/utils' import { lyric } from '@renderer/core/share/lyric' import { isFullscreen } from '@renderer/core/share' -import { isPlay, isShowLrcSelectContent, isShowPlayComment } from '@renderer/core/share/player' -import { onMounted, onBeforeUnmount, useCommit, useRefGetter, computed } from '@renderer/utils/vueTools' +import { isPlay, isShowLrcSelectContent, isShowPlayComment, musicInfo as playerMusicInfo, musicInfoItem, setMusicInfo } from '@renderer/core/share/player' +import { onMounted, onBeforeUnmount, useRefGetter, computed, reactive, ref } from '@renderer/utils/vueTools' import useLyric from '@renderer/utils/compositions/useLyric' +import LyricMenu from './components/LyricMenu' +import { player as eventPlayerNames } from '@renderer/event/names' export default { + components: { + LyricMenu, + }, setup() { const setting = useRefGetter('setting') - const setPlayDetailLyricFont = useCommit('setPlayDetailLyricFont') const { dom_lyric, dom_lyric_text, @@ -54,13 +59,37 @@ export default { handleSkipMouseLeave, } = useLyric({ isPlay, lyric }) - const fontSizeUp = () => { - if (setting.value.playDetail.style.fontSize >= 200) return - setPlayDetailLyricFont(setting.value.playDetail.style.fontSize + 1) + const lyricMenuVisible = ref(false) + const lyricMenuXY = reactive({ + x: 0, + y: 0, + }) + const lyricInfo = reactive({ + lyric: '', + tlyric: '', + lxlyric: '', + musicInfo: null, + }) + const updateMusicInfo = () => { + lyricInfo.lyric = playerMusicInfo.lrc + lyricInfo.tlyric = playerMusicInfo.tlrc + lyricInfo.lxlyric = playerMusicInfo.lxlrc + lyricInfo.musicInfo = musicInfoItem.value } - const fontSizeDown = () => { - if (setting.value.playDetail.style.fontSize <= 70) return - setPlayDetailLyricFont(setting.value.playDetail.style.fontSize - 1) + const handleShowLyricMenu = event => { + updateMusicInfo() + lyricMenuXY.x = event.pageX + lyricMenuXY.y = event.pageY + lyricMenuVisible.value = true + } + const handleUpdateLyric = ({ lyric, tlyric, lxlyric, offset }) => { + setMusicInfo({ + lrc: lyric, + tlrc: tlyric, + lxlrc: lxlyric, + }) + console.log(offset) + window.eventHub.emit(eventPlayerNames.updateLyricOffset, offset) } const lrcStyles = computed(() => { @@ -79,16 +108,10 @@ export default { const isShowLyricProgressSetting = computed(() => setting.value.playDetail.isShowLyricProgressSetting) onMounted(() => { - window.eventHub.on('key_shift++_down', fontSizeUp) - window.eventHub.on('key_numadd_down', fontSizeUp) - window.eventHub.on('key_-_down', fontSizeDown) - window.eventHub.on('key_numsub_down', fontSizeDown) + window.eventHub.on(eventPlayerNames.updateLyric, updateMusicInfo) }) onBeforeUnmount(() => { - window.eventHub.off('key_shift++_down', fontSizeUp) - window.eventHub.off('key_numadd_down', fontSizeUp) - window.eventHub.off('key_-_down', fontSizeDown) - window.eventHub.off('key_numsub_down', fontSizeDown) + window.eventHub.off(eventPlayerNames.updateLyric, updateMusicInfo) }) return { @@ -109,6 +132,11 @@ export default { isShowLyricProgressSetting, isZoomActiveLrc, isStopScroll, + lyricMenuVisible, + lyricMenuXY, + handleShowLyricMenu, + handleUpdateLyric, + lyricInfo, } }, methods: { diff --git a/src/renderer/components/core/PlayDetail/components/LyricMenu.vue b/src/renderer/components/core/PlayDetail/components/LyricMenu.vue new file mode 100644 index 00000000..ae5a3881 --- /dev/null +++ b/src/renderer/components/core/PlayDetail/components/LyricMenu.vue @@ -0,0 +1,300 @@ + + + + + + diff --git a/src/renderer/core/share/lyric.js b/src/renderer/core/share/lyric.js index 3d9efd62..026c25af 100644 --- a/src/renderer/core/share/lyric.js +++ b/src/renderer/core/share/lyric.js @@ -4,6 +4,7 @@ export const lyric = reactive({ lines: [], text: '', line: 0, + offset: 0, // 临时延迟 }) export const setLines = lines => { @@ -13,3 +14,6 @@ export const setText = (text, line) => { lyric.text = text lyric.line = line } +export const setOffset = offset => { + lyric.offset = offset +} diff --git a/src/renderer/core/useApp/usePlayer/useLyric.js b/src/renderer/core/useApp/usePlayer/useLyric.js index 3a9a79b1..71ca6c13 100644 --- a/src/renderer/core/useApp/usePlayer/useLyric.js +++ b/src/renderer/core/useApp/usePlayer/useLyric.js @@ -1,9 +1,9 @@ import { onBeforeUnmount, watch, markRawList } from '@renderer/utils/vueTools' import Lyric from '@renderer/utils/lyric-font-player' -import { getCurrentTime } from '@renderer/plugins/player' +import { getCurrentTime as getPlayerCurrentTime } from '@renderer/plugins/player' import { setDesktopLyricInfo, onGetDesktopLyricInfo } from '@renderer/utils/tools' -import { player } from '@renderer/event/names' -import { lyric, setText, setLines } from '@renderer/core/share/lyric' +import { player as eventPlayerNames } from '@renderer/event/names' +import { lyric, setText, setLines, setOffset } from '@renderer/core/share/lyric' import { musicInfo, setStatusText, isPlay, playMusicInfo } from '@renderer/core/share/player' export default ({ setting }) => { @@ -12,19 +12,24 @@ export default ({ setting }) => { fontClassName: 'font', shadowContent: false, activeLineClassName: 'active', - onPlay: (line, text) => { + onPlay(line, text) { setText(text, line) setStatusText(text) // console.log(line, text) }, - onSetLyric: lines => { // listening lyrics seting event + onSetLyric(lines) { // listening lyrics seting event // console.log(lines) // lines is array of all lyric text setLines(markRawList([...lines])) setText(lines[0] ?? '', 0) + setOffset(0) // 重置临时延迟 }, // offset: 80, }) + const getCurrentTime = () => { + return getPlayerCurrentTime() * 1000 + lyric.offset + } + const setPlayInfo = ({ musicInfo }) => { setDesktopLyricInfo('music_info', { @@ -45,7 +50,18 @@ export default ({ setting }) => { if (isPlay.value && (musicInfo.url || playMusicInfo.listId == 'download')) { setTimeout(() => { - const time = getCurrentTime() * 1000 + const time = getCurrentTime() + setDesktopLyricInfo('play', time) + lrc.play(time) + }) + } + } + + const setLyricOffset = offset => { + setOffset(offset) + if (isPlay.value && (musicInfo.url || playMusicInfo.listId == 'download')) { + setTimeout(() => { + const time = getCurrentTime() setDesktopLyricInfo('play', time) lrc.play(time) }) @@ -54,7 +70,7 @@ export default ({ setting }) => { const handlePlay = () => { if (!musicInfo.lrc) return - const currentTime = getCurrentTime() * 1000 + const currentTime = getCurrentTime() lrc.play(currentTime) setDesktopLyricInfo('play', currentTime) } @@ -85,14 +101,14 @@ export default ({ setting }) => { lxlrc: musicInfo.lxlrc, isPlay: isPlay.value, line: lyric.line, - played_time: getCurrentTime() * 1000, + played_time: getCurrentTime(), }, info) break case 'status': setDesktopLyricInfo('status', { isPlay: isPlay.value, line: lyric.line, - played_time: getCurrentTime() * 1000, + played_time: getCurrentTime(), }, info) break @@ -102,20 +118,22 @@ export default ({ setting }) => { }) - window.eventHub.on(player.play, handlePlay) - window.eventHub.on(player.pause, handlePause) - window.eventHub.on(player.stop, handleStop) - window.eventHub.on(player.error, handlePause) - window.eventHub.on(player.setPlayInfo, setPlayInfo) - window.eventHub.on(player.updateLyric, setLyric) + window.eventHub.on(eventPlayerNames.play, handlePlay) + window.eventHub.on(eventPlayerNames.pause, handlePause) + window.eventHub.on(eventPlayerNames.stop, handleStop) + window.eventHub.on(eventPlayerNames.error, handlePause) + window.eventHub.on(eventPlayerNames.setPlayInfo, setPlayInfo) + window.eventHub.on(eventPlayerNames.updateLyric, setLyric) + window.eventHub.on(eventPlayerNames.updateLyricOffset, setLyricOffset) onBeforeUnmount(() => { rGetDesktopLyricInfo() - window.eventHub.off(player.play, handlePlay) - window.eventHub.off(player.pause, handlePause) - window.eventHub.off(player.stop, handleStop) - window.eventHub.off(player.error, handlePause) - window.eventHub.off(player.setPlayInfo, setPlayInfo) - window.eventHub.off(player.updateLyric, setLyric) + window.eventHub.off(eventPlayerNames.play, handlePlay) + window.eventHub.off(eventPlayerNames.pause, handlePause) + window.eventHub.off(eventPlayerNames.stop, handleStop) + window.eventHub.off(eventPlayerNames.error, handlePause) + window.eventHub.off(eventPlayerNames.setPlayInfo, setPlayInfo) + window.eventHub.off(eventPlayerNames.updateLyric, setLyric) + window.eventHub.off(eventPlayerNames.updateLyricOffset, setLyricOffset) }) } diff --git a/src/renderer/event/names.js b/src/renderer/event/names.js index 36f701fb..5867f105 100644 --- a/src/renderer/event/names.js +++ b/src/renderer/event/names.js @@ -30,6 +30,7 @@ const names = { setPlayInfo: 'setPlayInfo', // 设置播放信息 updatePic: 'updatePic', // 更新图片事件 updateLyric: 'updateLyric', // 更新歌词事件 + updateLyricOffset: 'updateLyricOffset', // 更新歌词偏移 activeTransition: 'activeTransition', // 激活进度条动画事件 playedStop: 'playedStop', // 定时停止事件 diff --git a/src/renderer/store/getters.js b/src/renderer/store/getters.js index a3426862..9446e5ee 100644 --- a/src/renderer/store/getters.js +++ b/src/renderer/store/getters.js @@ -69,4 +69,7 @@ export default { isShowAnimation(state) { return state.setting.isShowAnimation }, + playDetailSetting(state) { + return state.setting.playDetail + }, } diff --git a/src/renderer/store/mutations.js b/src/renderer/store/mutations.js index 408dc9d9..203168b8 100644 --- a/src/renderer/store/mutations.js +++ b/src/renderer/store/mutations.js @@ -35,6 +35,9 @@ export default { state.setting.player.volume = val } }, + setPlayDetailLyricAlign(state, val) { + state.setting.playDetail.style.align = val + }, setPlayDetailLyricFont(state, val) { state.setting.playDetail.style.fontSize = val }, diff --git a/src/renderer/utils/compositions/useMenuLocation.js b/src/renderer/utils/compositions/useMenuLocation.js new file mode 100644 index 00000000..f390e3fb --- /dev/null +++ b/src/renderer/utils/compositions/useMenuLocation.js @@ -0,0 +1,81 @@ +import { onMounted, onBeforeUnmount, watch, reactive, ref, nextTick } from '@renderer/utils/vueTools' + +export default ({ visible, location, onHide }) => { + const transition1 = 'transform, opacity' + const transition2 = 'transform, opacity, top, left' + let show = false + const dom_menu = ref(null) + const menuStyles = reactive({ + left: 0, + top: 0, + opacity: 0, + transitionProperty: 'transform, opacity', + transform: 'scale(0) translate(0,0)', + }) + + const handleShow = () => { + show = true + menuStyles.opacity = 1 + menuStyles.transform = `scaleY(1) translate(${handleGetOffsetXY(location.x, location.y)})` + } + const handleHide = () => { + menuStyles.opacity = 0 + menuStyles.transform = 'scale(0) translate(0, 0)' + show = false + } + const handleGetOffsetXY = (left, top) => { + const listWidth = dom_menu.value.clientWidth + const listHeight = dom_menu.value.clientHeight + const dom_container_parant = dom_menu.value.offsetParent + const containerWidth = dom_container_parant.clientWidth + const containerHeight = dom_container_parant.clientHeight + const offsetWidth = containerWidth - left - listWidth + const offsetHeight = containerHeight - top - listHeight + let x = 0 + let y = 0 + if (containerWidth > listWidth && offsetWidth < 17) { + x = offsetWidth - 17 + } + if (containerHeight > listHeight && offsetHeight < 5) { + y = offsetHeight - 5 + } + return `${x}px, ${y}px` + } + const handleDocumentClick = (event) => { + if (!show) return + + if (event.target == dom_menu.value || dom_menu.value.contains(event.target)) return + + if (show && menuStyles.transitionProperty != transition1) menuStyles.transitionProperty = transition1 + + onHide() + } + + watch(visible, visible => { + visible ? handleShow() : handleHide() + }, { immediate: true }) + + watch(location, location => { + menuStyles.left = location.x + 2 + 'px' + menuStyles.top = location.y + 'px' + nextTick(() => { + if (show) { + if (menuStyles.transitionProperty != transition2) menuStyles.transitionProperty = transition2 + menuStyles.transform = `scaleY(1) translate(${handleGetOffsetXY(location.x, location.y)})` + } + }) + }, { deep: true }) + + onMounted(() => { + document.addEventListener('click', handleDocumentClick) + }) + + onBeforeUnmount(() => { + document.removeEventListener('click', handleDocumentClick) + }) + + return { + dom_menu, + menuStyles, + } +} diff --git a/src/renderer/utils/index.js b/src/renderer/utils/index.js index 659af08d..ad176f3d 100644 --- a/src/renderer/utils/index.js +++ b/src/renderer/utils/index.js @@ -491,11 +491,17 @@ export const parseUrlParams = str => { } export const getLyric = musicInfo => rendererInvoke(NAMES.mainWindow.get_lyric, `${musicInfo.source}_${musicInfo.songmid}`) -export const setLyric = (musicInfo, { lyric, tlyric, lxlyric }) => rendererSend(NAMES.mainWindow.save_lyric, { +export const setLyric = (musicInfo, { lyric, tlyric, lxlyric }) => rendererSend(NAMES.mainWindow.save_lyric_raw, { id: `${musicInfo.source}_${musicInfo.songmid}`, lyrics: { lyric, tlyric, lxlyric }, }) -export const clearLyric = () => rendererSend(NAMES.mainWindow.clear_lyric) +export const setLyricEdited = (musicInfo, { lyric, tlyric, lxlyric }) => rendererSend(NAMES.mainWindow.save_lyric_edited, { + id: `${musicInfo.source}_${musicInfo.songmid}`, + lyrics: { lyric, tlyric, lxlyric }, +}) +export const removeLyricEdited = musicInfo => rendererSend(NAMES.mainWindow.remove_lyric_edited, `${musicInfo.source}_${musicInfo.songmid}`) + +export const clearLyric = () => rendererSend(NAMES.mainWindow.clear_lyric_raw) export const getMusicUrl = (musicInfo, type) => rendererInvoke(NAMES.mainWindow.get_music_url, `${musicInfo.source}_${musicInfo.songmid}_${type}`) export const setMusicUrl = (musicInfo, type, url) => rendererSend(NAMES.mainWindow.save_music_url, { diff --git a/src/renderer/views/setting/Setting.vue b/src/renderer/views/setting/Setting.vue index 3ee5973f..d07de06f 100644 --- a/src/renderer/views/setting/Setting.vue +++ b/src/renderer/views/setting/Setting.vue @@ -97,9 +97,9 @@ export default { watch(() => setting.value.player.mediaDeviceId, val => { currentStting.value.player.mediaDeviceId = val }) - watch(() => setting.value.playDetail.style.fontSize, val => { - currentStting.value.playDetail.style.fontSize = val - }) + watch(() => setting.value.playDetail, val => { + currentStting.value.playDetail = val + }, { deep: true }) watch(() => setting.value.player.isMute, val => { currentStting.value.player.isMute = val }) diff --git a/src/renderer/views/setting/components/SettingPlayDetail.vue b/src/renderer/views/setting/components/SettingPlayDetail.vue index 44ad73ba..13274928 100644 --- a/src/renderer/views/setting/components/SettingPlayDetail.vue +++ b/src/renderer/views/setting/components/SettingPlayDetail.vue @@ -4,7 +4,7 @@ dd .gap-top base-checkbox(id="setting_play_detail_font_zoom_enable" v-model="currentStting.playDetail.isZoomActiveLrc" :label="$t('setting__play_detail_font_zoom')") .gap-top - base-checkbox(id="setting_play_detail_lyric_progress_enable" v-model="currentStting.playDetail.isShowLyricProgressSetting" :label="$t('setting__play_detail_detail_lyric_progress')") + base-checkbox(id="setting_play_detail_lyric_progress_enable" v-model="currentStting.playDetail.isShowLyricProgressSetting" :label="$t('setting__play_detail_lyric_progress')") dd h3#play_detail_align {{$t('setting__play_detail_align')}} @@ -13,12 +13,6 @@ dd base-checkbox.gap-left(id="setting_play_detail_align_center" v-model="currentStting.playDetail.style.align" value="center" :label="$t('setting__play_detail_align_center')") //- base-checkbox.gap-left(id="setting_play_detail_align_right" v-model="currentStting.playDetail.style.align" value="right" :label="$t('setting__play_detail_align_right')") -dd - h3#play_detail_align {{$t('setting__play_detail_font_size')}} - div - p.gap-top {{$t('setting__play_detail_font_size_current', { size: currentStting.playDetail.style.fontSize })}} - base-btn.gap-top.btn(min @click="handleResetFont") {{$t('setting__play_detail_font_size_reset')}} - + + diff --git a/src/renderer/views/list/components/MyLists.vue b/src/renderer/views/list/components/MyLists.vue index c1bea281..36ec149f 100644 --- a/src/renderer/views/list/components/MyLists.vue +++ b/src/renderer/views/list/components/MyLists.vue @@ -2,11 +2,18 @@

{{$t('my_list')}}

- +
+ + +
  • +