新增定时暂停播放功能
parent
c891ed81e1
commit
c12be6a1c8
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
- 新增“双击列表里的歌曲时自动切换到当前列表播放”设置,此功能仅对歌单、排行榜有效,默认关闭
|
- 新增“双击列表里的歌曲时自动切换到当前列表播放”设置,此功能仅对歌单、排行榜有效,默认关闭
|
||||||
- 新增打开收藏的在线列表的对应平台详情页功能,可以在我的列表-列表右键菜单中使用
|
- 新增打开收藏的在线列表的对应平台详情页功能,可以在我的列表-列表右键菜单中使用
|
||||||
|
- 新增定时暂停播放功能,由于此功能大多数人可能不常用,所以将其放在设置-基本设置中
|
||||||
|
|
||||||
### 优化
|
### 优化
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ const path = require('path')
|
||||||
const os = require('os')
|
const os = require('os')
|
||||||
|
|
||||||
const defaultSetting = {
|
const defaultSetting = {
|
||||||
version: '1.0.49',
|
version: '1.0.50',
|
||||||
player: {
|
player: {
|
||||||
togglePlayMethod: 'listLoop',
|
togglePlayMethod: 'listLoop',
|
||||||
highQuality: false,
|
highQuality: false,
|
||||||
|
@ -16,6 +16,8 @@ const defaultSetting = {
|
||||||
isPlayLxlrc: true,
|
isPlayLxlrc: true,
|
||||||
isSavePlayTime: false,
|
isSavePlayTime: false,
|
||||||
audioVisualization: false,
|
audioVisualization: false,
|
||||||
|
waitPlayEndStop: true,
|
||||||
|
waitPlayEndStopTime: 0,
|
||||||
},
|
},
|
||||||
desktopLyric: {
|
desktopLyric: {
|
||||||
enable: false,
|
enable: false,
|
||||||
|
|
|
@ -11,6 +11,9 @@ const names = {
|
||||||
clear_env_params_deeplink: 'clear_env_params_deeplink',
|
clear_env_params_deeplink: 'clear_env_params_deeplink',
|
||||||
wait: 'wait',
|
wait: 'wait',
|
||||||
wait_cancel: 'wait_cancel',
|
wait_cancel: 'wait_cancel',
|
||||||
|
interval: 'interval',
|
||||||
|
interval_callback: 'interval_callback',
|
||||||
|
interval_cancel: 'interval_cancel',
|
||||||
open_dev_tools: 'open_dev_tools',
|
open_dev_tools: 'open_dev_tools',
|
||||||
|
|
||||||
set_music_meta: 'set_music_meta',
|
set_music_meta: 'set_music_meta',
|
||||||
|
|
|
@ -143,6 +143,12 @@
|
||||||
"pagination__next": "Next page",
|
"pagination__next": "Next page",
|
||||||
"pagination__page": "Page {num}",
|
"pagination__page": "Page {num}",
|
||||||
"pagination__prev": "Previous page",
|
"pagination__prev": "Previous page",
|
||||||
|
"play_timeout": "Timed pause",
|
||||||
|
"play_timeout_close": "Close",
|
||||||
|
"play_timeout_confirm": "Confirm",
|
||||||
|
"play_timeout_end": "Wait for the song to finish before pausing",
|
||||||
|
"play_timeout_unit": "minute",
|
||||||
|
"play_timeout_update": "Update timing",
|
||||||
"player__add_music_to": "Add the current song to...",
|
"player__add_music_to": "Add the current song to...",
|
||||||
"player__buffering": "Buffering...",
|
"player__buffering": "Buffering...",
|
||||||
"player__desktop_lyric_lock": "Right click to lock lyrics",
|
"player__desktop_lyric_lock": "Right click to lock lyrics",
|
||||||
|
@ -322,6 +328,7 @@
|
||||||
"setting__play_quality": "Play 320K quality songs first (if supported)",
|
"setting__play_quality": "Play 320K quality songs first (if supported)",
|
||||||
"setting__play_save_play_time": "Remember playback progress",
|
"setting__play_save_play_time": "Remember playback progress",
|
||||||
"setting__play_task_bar": "Show playing progress on the taskbar",
|
"setting__play_task_bar": "Show playing progress on the taskbar",
|
||||||
|
"setting__play_timeout": "Timed pause",
|
||||||
"setting__search": "Search",
|
"setting__search": "Search",
|
||||||
"setting__search_focus_search_box": "Automatically focus the search box on startup",
|
"setting__search_focus_search_box": "Automatically focus the search box on startup",
|
||||||
"setting__search_history": "Search history",
|
"setting__search_history": "Search history",
|
||||||
|
|
|
@ -143,6 +143,14 @@
|
||||||
"pagination__next": "下一页",
|
"pagination__next": "下一页",
|
||||||
"pagination__page": "第 {num} 页",
|
"pagination__page": "第 {num} 页",
|
||||||
"pagination__prev": "上一页",
|
"pagination__prev": "上一页",
|
||||||
|
"play_timeout": "定时暂停",
|
||||||
|
"play_timeout_close": "关闭",
|
||||||
|
"play_timeout_confirm": "确认",
|
||||||
|
"play_timeout_end": "等待歌曲播放完毕再暂停",
|
||||||
|
"play_timeout_stop": "取消定时",
|
||||||
|
"play_timeout_tip": "{time} 后暂停播放",
|
||||||
|
"play_timeout_unit": "分钟",
|
||||||
|
"play_timeout_update": "更新定时",
|
||||||
"player__add_music_to": "添加当前歌曲到...",
|
"player__add_music_to": "添加当前歌曲到...",
|
||||||
"player__buffering": "缓冲中...",
|
"player__buffering": "缓冲中...",
|
||||||
"player__desktop_lyric_lock": "右击锁定歌词",
|
"player__desktop_lyric_lock": "右击锁定歌词",
|
||||||
|
@ -322,6 +330,7 @@
|
||||||
"setting__play_quality": "优先播放320K品质的歌曲(如果支持)",
|
"setting__play_quality": "优先播放320K品质的歌曲(如果支持)",
|
||||||
"setting__play_save_play_time": "记住播放进度",
|
"setting__play_save_play_time": "记住播放进度",
|
||||||
"setting__play_task_bar": "在任务栏上显示当前歌曲播放进度",
|
"setting__play_task_bar": "在任务栏上显示当前歌曲播放进度",
|
||||||
|
"setting__play_timeout": "定时暂停",
|
||||||
"setting__search": "搜索设置",
|
"setting__search": "搜索设置",
|
||||||
"setting__search_focus_search_box": "启动时自动聚焦搜索框",
|
"setting__search_focus_search_box": "启动时自动聚焦搜索框",
|
||||||
"setting__search_history": "显示历史搜索记录",
|
"setting__search_history": "显示历史搜索记录",
|
||||||
|
|
|
@ -143,6 +143,12 @@
|
||||||
"pagination__next": "下一頁",
|
"pagination__next": "下一頁",
|
||||||
"pagination__page": "第 {num} 頁",
|
"pagination__page": "第 {num} 頁",
|
||||||
"pagination__prev": "上一頁",
|
"pagination__prev": "上一頁",
|
||||||
|
"play_timeout": "定時暫停",
|
||||||
|
"play_timeout_close": "關閉",
|
||||||
|
"play_timeout_confirm": "確認",
|
||||||
|
"play_timeout_end": "等待歌曲播放完畢再暫停",
|
||||||
|
"play_timeout_unit": "分鐘",
|
||||||
|
"play_timeout_update": "更新定時",
|
||||||
"player__add_music_to": "添加當前歌曲到...",
|
"player__add_music_to": "添加當前歌曲到...",
|
||||||
"player__album": "專輯名:",
|
"player__album": "專輯名:",
|
||||||
"player__buffering": "緩衝中...",
|
"player__buffering": "緩衝中...",
|
||||||
|
@ -322,6 +328,7 @@
|
||||||
"setting__play_quality": "優先播放320K品質的歌曲(如果支持)",
|
"setting__play_quality": "優先播放320K品質的歌曲(如果支持)",
|
||||||
"setting__play_save_play_time": "記住播放進度",
|
"setting__play_save_play_time": "記住播放進度",
|
||||||
"setting__play_task_bar": "在任務欄上顯示當前歌曲播放進度",
|
"setting__play_task_bar": "在任務欄上顯示當前歌曲播放進度",
|
||||||
|
"setting__play_timeout": "定時暫停",
|
||||||
"setting__search": "搜索設置",
|
"setting__search": "搜索設置",
|
||||||
"setting__search_focus_search_box": "啟動時自動聚焦搜索框",
|
"setting__search_focus_search_box": "啟動時自動聚焦搜索框",
|
||||||
"setting__search_history": "顯示歷史搜索記錄",
|
"setting__search_history": "顯示歷史搜索記錄",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const { mainOn, mainHandle, NAMES: { mainWindow: ipcMainWindowNames } } = require('@common/ipc')
|
const { mainOn, mainHandle, mainSend, NAMES: { mainWindow: ipcMainWindowNames } } = require('@common/ipc')
|
||||||
|
|
||||||
const timeoutMap = new Map()
|
const timeoutMap = new Map()
|
||||||
|
|
||||||
|
@ -23,3 +23,24 @@ mainOn(ipcMainWindowNames.wait_cancel, (event, id) => {
|
||||||
clearTimeout(timeout.timeout)
|
clearTimeout(timeout.timeout)
|
||||||
timeout.reject('cancelled')
|
timeout.reject('cancelled')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mainOn(ipcMainWindowNames.interval, (event, { time, id }) => {
|
||||||
|
if (timeoutMap.has(id)) return
|
||||||
|
const timeout = setInterval(() => {
|
||||||
|
if (global.modules.mainWindow) mainSend(global.modules.mainWindow, ipcMainWindowNames.interval_callback, id)
|
||||||
|
}, time)
|
||||||
|
|
||||||
|
timeoutMap.set(id, {
|
||||||
|
timeout,
|
||||||
|
type: 'interval',
|
||||||
|
time,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
mainOn(ipcMainWindowNames.interval_cancel, (event, id) => {
|
||||||
|
if (!timeoutMap.has(id)) return
|
||||||
|
const timeout = timeoutMap.get(id)
|
||||||
|
timeoutMap.delete(id)
|
||||||
|
if (timeout.type != 'interval') return
|
||||||
|
clearInterval(timeout.timeout)
|
||||||
|
})
|
||||||
|
|
|
@ -24,7 +24,7 @@ export default {
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: String,
|
type: [String, Number],
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
import useMediaDevice from './useMediaDevice'
|
import useMediaDevice from './useMediaDevice'
|
||||||
import usePlayerEvent from './usePlayerEvent'
|
import usePlayerEvent from './usePlayerEvent'
|
||||||
import usePlayer from './usePlayer'
|
import usePlayer from './usePlayer'
|
||||||
|
import { init as initPlayTimeoutStop } from '@renderer/utils/timeoutStop'
|
||||||
|
|
||||||
export default ({ setting }) => {
|
export default ({ setting }) => {
|
||||||
createAudio()
|
createAudio()
|
||||||
|
@ -11,5 +12,7 @@ export default ({ setting }) => {
|
||||||
usePlayerEvent()
|
usePlayerEvent()
|
||||||
useMediaDevice({ setting }) // 初始化音频驱动输出设置
|
useMediaDevice({ setting }) // 初始化音频驱动输出设置
|
||||||
usePlayer({ setting })
|
usePlayer({ setting })
|
||||||
|
|
||||||
|
initPlayTimeoutStop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ export default ({
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleLoadstart = () => {
|
const handleLoadstart = () => {
|
||||||
|
if (global.isPlayedStop) return
|
||||||
startLoadingTimeout()
|
startLoadingTimeout()
|
||||||
setAllStatus(t('player__loading'))
|
setAllStatus(t('player__loading'))
|
||||||
}
|
}
|
||||||
|
@ -77,6 +78,7 @@ export default ({
|
||||||
const handleError = errCode => {
|
const handleError = errCode => {
|
||||||
if (!musicInfo.songmid) return
|
if (!musicInfo.songmid) return
|
||||||
clearLoadingTimeout()
|
clearLoadingTimeout()
|
||||||
|
if (global.isPlayedStop) return
|
||||||
if (playMusicInfo.listId != 'download' && errCode !== 1 && retryNum < 2) { // 若音频URL无效则尝试刷新2次URL
|
if (playMusicInfo.listId != 'download' && errCode !== 1 && retryNum < 2) { // 若音频URL无效则尝试刷新2次URL
|
||||||
// console.log(this.retryNum)
|
// console.log(this.retryNum)
|
||||||
retryNum++
|
retryNum++
|
||||||
|
@ -96,6 +98,11 @@ export default ({
|
||||||
clearLoadingTimeout()
|
clearLoadingTimeout()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handlePlayedStop = () => {
|
||||||
|
clearDelayNextTimeout()
|
||||||
|
clearLoadingTimeout()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
window.eventHub.on(eventPlayerNames.player_loadstart, handleLoadstart)
|
window.eventHub.on(eventPlayerNames.player_loadstart, handleLoadstart)
|
||||||
window.eventHub.on(eventPlayerNames.player_loadeddata, handleLoadeddata)
|
window.eventHub.on(eventPlayerNames.player_loadeddata, handleLoadeddata)
|
||||||
|
@ -105,6 +112,7 @@ export default ({
|
||||||
window.eventHub.on(eventPlayerNames.player_emptied, handleEmpied)
|
window.eventHub.on(eventPlayerNames.player_emptied, handleEmpied)
|
||||||
window.eventHub.on(eventPlayerNames.error, handleError)
|
window.eventHub.on(eventPlayerNames.error, handleError)
|
||||||
window.eventHub.on(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
|
window.eventHub.on(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
|
||||||
|
window.eventHub.on(eventPlayerNames.playedStop, handlePlayedStop)
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
window.eventHub.off(eventPlayerNames.player_loadstart, handleLoadstart)
|
window.eventHub.off(eventPlayerNames.player_loadstart, handleLoadstart)
|
||||||
|
@ -115,5 +123,6 @@ export default ({
|
||||||
window.eventHub.off(eventPlayerNames.player_emptied, handleEmpied)
|
window.eventHub.off(eventPlayerNames.player_emptied, handleEmpied)
|
||||||
window.eventHub.off(eventPlayerNames.error, handleError)
|
window.eventHub.off(eventPlayerNames.error, handleError)
|
||||||
window.eventHub.off(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
|
window.eventHub.off(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
|
||||||
|
window.eventHub.off(eventPlayerNames.playedStop, handlePlayedStop)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,11 +103,13 @@ export default ({ setting }) => {
|
||||||
setAllStatus('Try toggle source...')
|
setAllStatus('Try toggle source...')
|
||||||
},
|
},
|
||||||
}).then(url => {
|
}).then(url => {
|
||||||
|
if (global.isPlayedStop) return
|
||||||
if (targetSong !== musicInfoItem.value || isPlay.value || type != getPlayType(setting.value.player.highQuality, musicInfoItem.value)) return
|
if (targetSong !== musicInfoItem.value || isPlay.value || type != getPlayType(setting.value.player.highQuality, musicInfoItem.value)) return
|
||||||
setMusicInfo({ url })
|
setMusicInfo({ url })
|
||||||
setResource(url)
|
setResource(url)
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
// console.log('err', err.message)
|
// console.log('err', err.message)
|
||||||
|
if (global.isPlayedStop) return
|
||||||
if (targetSong !== musicInfoItem.value || isPlay.value) return
|
if (targetSong !== musicInfoItem.value || isPlay.value) return
|
||||||
if (err.message == requestMsg.cancelRequest) return
|
if (err.message == requestMsg.cancelRequest) return
|
||||||
if (!isRetryed) return setUrl(targetSong, isRefresh, true)
|
if (!isRetryed) return setUrl(targetSong, isRefresh, true)
|
||||||
|
@ -198,6 +200,7 @@ export default ({ setting }) => {
|
||||||
const setPauseStatus = () => {
|
const setPauseStatus = () => {
|
||||||
setPlay(false)
|
setPlay(false)
|
||||||
setTitle()
|
setTitle()
|
||||||
|
if (global.isPlayedStop) handlePause()
|
||||||
}
|
}
|
||||||
const setStopStatus = () => {
|
const setStopStatus = () => {
|
||||||
setPlay(false)
|
setPlay(false)
|
||||||
|
@ -288,11 +291,16 @@ export default ({ setting }) => {
|
||||||
|
|
||||||
const handleEnded = () => {
|
const handleEnded = () => {
|
||||||
setAllStatus(t('player__end'))
|
setAllStatus(t('player__end'))
|
||||||
|
|
||||||
|
if (global.isPlayedStop) return
|
||||||
playNext()
|
playNext()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 播放、暂停播放切换
|
const handlePause = () => {
|
||||||
const handleTogglePlay = async() => {
|
setPlayerPause()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePlay = async() => {
|
||||||
if (playMusicInfo.musicInfo == null) return
|
if (playMusicInfo.musicInfo == null) return
|
||||||
if (isPlayerEmpty()) {
|
if (isPlayerEmpty()) {
|
||||||
if (playMusicInfo.listId == 'download') {
|
if (playMusicInfo.listId == 'download') {
|
||||||
|
@ -313,13 +321,24 @@ export default ({ setting }) => {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
setPlayerPlay()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 播放、暂停播放切换
|
||||||
|
const handleTogglePlay = () => {
|
||||||
|
if (global.isPlayedStop) global.isPlayedStop = false
|
||||||
if (isPlay.value) {
|
if (isPlay.value) {
|
||||||
setPlayerPause()
|
handlePause()
|
||||||
} else {
|
} else {
|
||||||
setPlayerPlay()
|
handlePlay()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handlePlayedStop = () => {
|
||||||
|
clearDelayNextTimeout()
|
||||||
|
clearLoadTimeout()
|
||||||
|
}
|
||||||
|
|
||||||
watch(() => setting.value.player.togglePlayMethod, newValue => {
|
watch(() => setting.value.player.togglePlayMethod, newValue => {
|
||||||
setLoopPlay(newValue === 'singleLoop')
|
setLoopPlay(newValue === 'singleLoop')
|
||||||
if (playedList.length) clearPlayedList()
|
if (playedList.length) clearPlayedList()
|
||||||
|
@ -339,13 +358,16 @@ export default ({ setting }) => {
|
||||||
window.eventHub.on(eventPlayerNames.stop, setStopStatus)
|
window.eventHub.on(eventPlayerNames.stop, setStopStatus)
|
||||||
|
|
||||||
window.eventHub.on(eventPlayerNames.playMusic, playMusic)
|
window.eventHub.on(eventPlayerNames.playMusic, playMusic)
|
||||||
|
window.eventHub.on(eventPlayerNames.setPlay, handlePlay)
|
||||||
|
window.eventHub.on(eventPlayerNames.setPause, handlePause)
|
||||||
|
window.eventHub.on(eventPlayerNames.setStop, handelStop)
|
||||||
window.eventHub.on(eventPlayerNames.setTogglePlay, handleTogglePlay)
|
window.eventHub.on(eventPlayerNames.setTogglePlay, handleTogglePlay)
|
||||||
window.eventHub.on(eventPlayerNames.setPlayPrev, playPrev)
|
window.eventHub.on(eventPlayerNames.setPlayPrev, playPrev)
|
||||||
window.eventHub.on(eventPlayerNames.setPlayNext, playNext)
|
window.eventHub.on(eventPlayerNames.setPlayNext, playNext)
|
||||||
window.eventHub.on(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
|
window.eventHub.on(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
|
||||||
window.eventHub.on(eventPlayerNames.setStop, handelStop)
|
|
||||||
|
|
||||||
window.eventHub.on(eventPlayerNames.player_ended, handleEnded)
|
window.eventHub.on(eventPlayerNames.player_ended, handleEnded)
|
||||||
|
window.eventHub.on(eventPlayerNames.playedStop, handlePlayedStop)
|
||||||
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
|
@ -360,11 +382,14 @@ export default ({ setting }) => {
|
||||||
|
|
||||||
window.eventHub.off(eventPlayerNames.playMusic, playMusic)
|
window.eventHub.off(eventPlayerNames.playMusic, playMusic)
|
||||||
window.eventHub.off(eventPlayerNames.setTogglePlay, handleTogglePlay)
|
window.eventHub.off(eventPlayerNames.setTogglePlay, handleTogglePlay)
|
||||||
|
window.eventHub.off(eventPlayerNames.setPlay, handlePlay)
|
||||||
|
window.eventHub.off(eventPlayerNames.setPause, handlePause)
|
||||||
|
window.eventHub.off(eventPlayerNames.setStop, handelStop)
|
||||||
window.eventHub.off(eventPlayerNames.setPlayPrev, playPrev)
|
window.eventHub.off(eventPlayerNames.setPlayPrev, playPrev)
|
||||||
window.eventHub.off(eventPlayerNames.setPlayNext, playNext)
|
window.eventHub.off(eventPlayerNames.setPlayNext, playNext)
|
||||||
window.eventHub.off(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
|
window.eventHub.off(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
|
||||||
window.eventHub.off(eventPlayerNames.setStop, handelStop)
|
|
||||||
|
|
||||||
window.eventHub.off(eventPlayerNames.player_ended, handleEnded)
|
window.eventHub.off(eventPlayerNames.player_ended, handleEnded)
|
||||||
|
window.eventHub.off(eventPlayerNames.playedStop, handlePlayedStop)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ export default ({ playNext }) => {
|
||||||
|
|
||||||
const { playIndex } = updatePlayIndex()
|
const { playIndex } = updatePlayIndex()
|
||||||
if (playIndex < 0 && !playMusicInfo.isTempPlay) { // 歌曲被移除
|
if (playIndex < 0 && !playMusicInfo.isTempPlay) { // 歌曲被移除
|
||||||
if (getList(playMusicInfo.listId).length) {
|
if (getList(playMusicInfo.listId).length && !global.isPlayedStop) {
|
||||||
playNext()
|
playNext()
|
||||||
} else {
|
} else {
|
||||||
window.eventHub.emit(eventPlayerNames.setStop)
|
window.eventHub.emit(eventPlayerNames.setStop)
|
||||||
|
|
|
@ -15,6 +15,7 @@ const names = {
|
||||||
},
|
},
|
||||||
player: {
|
player: {
|
||||||
setTogglePlay: 'setTogglePlay', // 播放/暂停切换
|
setTogglePlay: 'setTogglePlay', // 播放/暂停切换
|
||||||
|
setPlay: 'setPlay', // 播放
|
||||||
setPause: 'setPause', // 暂停
|
setPause: 'setPause', // 暂停
|
||||||
setStop: 'setStop', // 停止
|
setStop: 'setStop', // 停止
|
||||||
setPlayPrev: 'setPlayPrev', // 上一曲
|
setPlayPrev: 'setPlayPrev', // 上一曲
|
||||||
|
@ -31,6 +32,7 @@ const names = {
|
||||||
updateLyric: 'updateLyric',
|
updateLyric: 'updateLyric',
|
||||||
|
|
||||||
activeTransition: 'activeTransition', // 激活进度条动画事件
|
activeTransition: 'activeTransition', // 激活进度条动画事件
|
||||||
|
playedStop: 'playedStop', // 定时停止事件
|
||||||
|
|
||||||
// 播放器事件
|
// 播放器事件
|
||||||
play: 'play',
|
play: 'play',
|
||||||
|
|
|
@ -32,6 +32,7 @@ const state = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const playMusic = () => {
|
const playMusic = () => {
|
||||||
|
if (global.isPlayedStop) global.isPlayedStop = false
|
||||||
window.eventHub.emit(eventPlayerNames.playMusic)
|
window.eventHub.emit(eventPlayerNames.playMusic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
import { ref, computed } from '@renderer/utils/vueTools'
|
||||||
|
import { rendererSend, rendererOn, NAMES } from '@common/ipc'
|
||||||
|
import { isPlay } from '@renderer/core/share/player'
|
||||||
|
import store from '@renderer/store'
|
||||||
|
import { player as eventPlayerNames } from '@renderer/event/names'
|
||||||
|
|
||||||
|
global.isPlayedStop = false
|
||||||
|
|
||||||
|
const time = ref(-1)
|
||||||
|
|
||||||
|
|
||||||
|
const timeoutTools = {
|
||||||
|
inited: false,
|
||||||
|
isRunning: false,
|
||||||
|
timeout: null,
|
||||||
|
time: -1,
|
||||||
|
id: 'play__stop__timeout',
|
||||||
|
exit() {
|
||||||
|
const setting = store.getters.setting
|
||||||
|
global.isPlayedStop = true
|
||||||
|
if (!setting.player.waitPlayEndStop && isPlay.value) {
|
||||||
|
window.eventHub.emit(eventPlayerNames.setPause)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clearTimeout() {
|
||||||
|
rendererSend(NAMES.mainWindow.interval_cancel, this.id)
|
||||||
|
if (!this.isRunning) return
|
||||||
|
this.time = -1
|
||||||
|
time.value = -1
|
||||||
|
this.isRunning = false
|
||||||
|
},
|
||||||
|
start(_time) {
|
||||||
|
this.clearTimeout()
|
||||||
|
this.time = _time
|
||||||
|
time.value = _time
|
||||||
|
this.isRunning = true
|
||||||
|
rendererSend(NAMES.mainWindow.interval, {
|
||||||
|
time: 1000,
|
||||||
|
id: this.id,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
if (this.inited) return
|
||||||
|
this.clearTimeout()
|
||||||
|
rendererOn(NAMES.mainWindow.interval_callback, (event, id) => {
|
||||||
|
if (id !== this.id) return
|
||||||
|
|
||||||
|
if (this.time > 0) {
|
||||||
|
this.time--
|
||||||
|
time.value--
|
||||||
|
} else {
|
||||||
|
this.clearTimeout()
|
||||||
|
this.exit()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.inited = true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const init = () => {
|
||||||
|
timeoutTools.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const startTimeoutStop = time => {
|
||||||
|
if (global.isPlayedStop) global.isPlayedStop = false
|
||||||
|
timeoutTools.start(time)
|
||||||
|
}
|
||||||
|
export const stopTimeoutStop = () => {
|
||||||
|
if (global.isPlayedStop) global.isPlayedStop = false
|
||||||
|
timeoutTools.clearTimeout()
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatTime = time => {
|
||||||
|
// let d = parseInt(time / 86400)
|
||||||
|
// d = d ? d.toString() + ':' : ''
|
||||||
|
// time = time % 86400
|
||||||
|
let h = parseInt(time / 3600)
|
||||||
|
h = h ? h.toString() + ':' : ''
|
||||||
|
time = time % 3600
|
||||||
|
const m = parseInt(time / 60).toString().padStart(2, '0')
|
||||||
|
const s = parseInt(time % 60).toString().padStart(2, '0')
|
||||||
|
return `${h}${m}:${s}`
|
||||||
|
}
|
||||||
|
export const useTimeout = () => {
|
||||||
|
const timeLabel = computed(() => {
|
||||||
|
return time.value > 0 ? formatTime(time.value) : ''
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
time,
|
||||||
|
timeLabel,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,175 @@
|
||||||
|
<template lang="pug">
|
||||||
|
material-modal(:show="modelValue" bg-close @close="handleCloseModal" @after-enter="$refs.dom_input.focus()" teleport="#view")
|
||||||
|
main(:class="$style.main")
|
||||||
|
h2 {{$t('play_timeout')}}
|
||||||
|
div(:class="$style.content")
|
||||||
|
div(:class="[$style.row, $style.inputGroup]")
|
||||||
|
base-input(:class="$style.input" ref="dom_input" v-model="time" type="number")
|
||||||
|
p(:class="$style.inputLabel") {{$t('play_timeout_unit')}}
|
||||||
|
div(:class="$style.row")
|
||||||
|
base-checkbox(id="play_timeout_end" v-model="currentStting.player.waitPlayEndStop" :label="$t('play_timeout_end')")
|
||||||
|
div(:class="[$style.row, $style.tip, { [$style.show]: !!timeLabel }]")
|
||||||
|
p {{$t('play_timeout_tip', { time: timeLabel })}}
|
||||||
|
div(:class="$style.footer")
|
||||||
|
base-btn(:class="$style.footerBtn" @click="handleCancel") {{$t(timeLabel ? 'play_timeout_stop' : 'play_timeout_close')}}
|
||||||
|
base-btn(:class="$style.footerBtn" @click="handleConfirm") {{$t(timeLabel ? 'play_timeout_update' : 'play_timeout_confirm')}}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { currentStting } from '../setting'
|
||||||
|
import { useTimeout, startTimeoutStop, stopTimeoutStop } from '@renderer/utils/timeoutStop'
|
||||||
|
import { ref } from '@renderer/utils/vueTools'
|
||||||
|
|
||||||
|
const MAX_MIN = 1440
|
||||||
|
|
||||||
|
const rxp = /([1-9]\d*)/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
modelValue: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const { timeLabel } = useTimeout()
|
||||||
|
const time = ref(currentStting.value.player.waitPlayEndStopTime)
|
||||||
|
|
||||||
|
const handleCloseModal = () => {
|
||||||
|
emit('update:modelValue', false)
|
||||||
|
}
|
||||||
|
const handleCancel = () => {
|
||||||
|
if (timeLabel.value) {
|
||||||
|
stopTimeoutStop()
|
||||||
|
}
|
||||||
|
handleCloseModal()
|
||||||
|
}
|
||||||
|
const verify = () => {
|
||||||
|
const orgText = time.value
|
||||||
|
let text = time.value
|
||||||
|
|
||||||
|
if (rxp.test(text)) {
|
||||||
|
text = RegExp.$1
|
||||||
|
if (parseInt(text) > MAX_MIN) {
|
||||||
|
text = text.substring(0, text.length - 1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
text = ''
|
||||||
|
}
|
||||||
|
time.value = text
|
||||||
|
return orgText == text ? parseInt(text) : ''
|
||||||
|
}
|
||||||
|
const handleConfirm = () => {
|
||||||
|
let time = verify()
|
||||||
|
if (time == '') return
|
||||||
|
currentStting.value.player.waitPlayEndStopTime = time
|
||||||
|
startTimeoutStop(time * 60)
|
||||||
|
handleCloseModal()
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
currentStting,
|
||||||
|
timeLabel,
|
||||||
|
time,
|
||||||
|
handleCloseModal,
|
||||||
|
handleCancel,
|
||||||
|
handleConfirm,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="less" module>
|
||||||
|
@import '@renderer/assets/styles/layout.less';
|
||||||
|
|
||||||
|
.main {
|
||||||
|
padding: 15px;
|
||||||
|
max-width: 530px;
|
||||||
|
min-width: 280px;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 0;
|
||||||
|
// max-height: 100%;
|
||||||
|
// overflow: hidden;
|
||||||
|
h2 {
|
||||||
|
font-size: 16px;
|
||||||
|
color: @color-theme_2-font;
|
||||||
|
line-height: 1.3;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
padding-top: 15px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.row {
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
.inputGroup {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.input {
|
||||||
|
flex: auto;
|
||||||
|
}
|
||||||
|
.inputLabel {
|
||||||
|
flex: none;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
.tip {
|
||||||
|
visibility: hidden;
|
||||||
|
|
||||||
|
&.show {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
margin-top: 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
}
|
||||||
|
.footerBtn {
|
||||||
|
flex: auto;
|
||||||
|
height: 36px;
|
||||||
|
line-height: 36px;
|
||||||
|
padding: 0 10px !important;
|
||||||
|
width: 150px;
|
||||||
|
.mixin-ellipsis-1;
|
||||||
|
+ .footerBtn {
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ruleLink {
|
||||||
|
.mixin-ellipsis-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
each(@themes, {
|
||||||
|
:global(#root.@{value}) {
|
||||||
|
.main {
|
||||||
|
h2 {
|
||||||
|
color: ~'@{color-@{value}-theme_2-font}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.listItem {
|
||||||
|
&:hover {
|
||||||
|
background-color: ~'@{color-@{value}-theme_2-hover}';
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
background-color: ~'@{color-@{value}-theme_2-active}';
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
color: ~'@{color-@{value}-theme_2-font}';
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
color: ~'@{color-@{value}-theme_2-font-label}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.noitem {
|
||||||
|
color: ~'@{color-@{value}-theme_2-font-label}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</style>
|
|
@ -9,12 +9,15 @@ dd
|
||||||
label {{$t('theme_' + theme.className)}}
|
label {{$t('theme_' + theme.className)}}
|
||||||
|
|
||||||
dd
|
dd
|
||||||
.gap-top.top
|
div
|
||||||
base-checkbox(id="setting_show_animate" v-model="currentStting.isShowAnimation" :label="$t('setting__basic_show_animation')")
|
.gap-top.top
|
||||||
.gap-top
|
base-checkbox(id="setting_show_animate" v-model="currentStting.isShowAnimation" :label="$t('setting__basic_show_animation')")
|
||||||
base-checkbox(id="setting_animate" v-model="currentStting.randomAnimate" :label="$t('setting__basic_animation')")
|
.gap-top
|
||||||
.gap-top
|
base-checkbox(id="setting_animate" v-model="currentStting.randomAnimate" :label="$t('setting__basic_animation')")
|
||||||
base-checkbox(id="setting_to_tray" v-model="currentStting.tray.isShow" :label="$t('setting__basic_to_tray')")
|
.gap-top
|
||||||
|
base-checkbox(id="setting_to_tray" v-model="currentStting.tray.isShow" :label="$t('setting__basic_to_tray')")
|
||||||
|
p.gap-top
|
||||||
|
base-btn.btn(min @click="isShowPlayTimeoutModal = true") {{$t('setting__play_timeout')}} {{ timeLabel ? ` (${timeLabel})` : '' }}
|
||||||
|
|
||||||
dd(:tips="$t('setting__basic_source_title')")
|
dd(:tips="$t('setting__basic_source_title')")
|
||||||
h3#basic_source {{$t('setting__basic_source')}}
|
h3#basic_source {{$t('setting__basic_source')}}
|
||||||
|
@ -48,6 +51,7 @@ dd
|
||||||
div
|
div
|
||||||
base-checkbox.gap-left(v-for="item in controlBtnPositionList" :key="item.id" :id="`setting_basic_control_btn_position_${item.id}`"
|
base-checkbox.gap-left(v-for="item in controlBtnPositionList" :key="item.id" :id="`setting_basic_control_btn_position_${item.id}`"
|
||||||
name="setting_basic_control_btn_position" need v-model="currentStting.controlBtnPosition" :value="item.id" :label="item.name")
|
name="setting_basic_control_btn_position" need v-model="currentStting.controlBtnPosition" :value="item.id" :label="item.name")
|
||||||
|
play-timeout-modal(v-model="isShowPlayTimeoutModal")
|
||||||
user-api-modal(v-model="isShowUserApiModal")
|
user-api-modal(v-model="isShowUserApiModal")
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -58,12 +62,15 @@ import { langList } from '@/lang'
|
||||||
import { currentStting } from '../setting'
|
import { currentStting } from '../setting'
|
||||||
import { setWindowSize } from '@renderer/utils'
|
import { setWindowSize } from '@renderer/utils'
|
||||||
import apiSourceInfo from '@renderer/utils/music/api-source-info'
|
import apiSourceInfo from '@renderer/utils/music/api-source-info'
|
||||||
|
import { useTimeout } from '@renderer/utils/timeoutStop'
|
||||||
|
|
||||||
|
import PlayTimeoutModal from './PlayTimeoutModal'
|
||||||
import UserApiModal from './UserApiModal'
|
import UserApiModal from './UserApiModal'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SettingBasic',
|
name: 'SettingBasic',
|
||||||
components: {
|
components: {
|
||||||
|
PlayTimeoutModal,
|
||||||
UserApiModal,
|
UserApiModal,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
@ -81,6 +88,9 @@ export default {
|
||||||
apiSource.value = visible
|
apiSource.value = visible
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const isShowPlayTimeoutModal = ref(false)
|
||||||
|
const { timeLabel } = useTimeout()
|
||||||
|
|
||||||
const isShowUserApiModal = ref(false)
|
const isShowUserApiModal = ref(false)
|
||||||
const getApiStatus = () => {
|
const getApiStatus = () => {
|
||||||
let status
|
let status
|
||||||
|
@ -138,6 +148,8 @@ export default {
|
||||||
return {
|
return {
|
||||||
currentStting,
|
currentStting,
|
||||||
themes,
|
themes,
|
||||||
|
isShowPlayTimeoutModal,
|
||||||
|
timeLabel,
|
||||||
apiSources,
|
apiSources,
|
||||||
isShowUserApiModal,
|
isShowUserApiModal,
|
||||||
windowSizeList,
|
windowSizeList,
|
||||||
|
|
|
@ -8,6 +8,8 @@ export const currentStting = ref({
|
||||||
volume: 1,
|
volume: 1,
|
||||||
mediaDeviceId: 'default',
|
mediaDeviceId: 'default',
|
||||||
isMediaDeviceRemovedStopPlay: false,
|
isMediaDeviceRemovedStopPlay: false,
|
||||||
|
waitPlayEndStop: true,
|
||||||
|
waitPlayEndStopTime: 0,
|
||||||
},
|
},
|
||||||
desktopLyric: {
|
desktopLyric: {
|
||||||
enable: false,
|
enable: false,
|
||||||
|
|
Loading…
Reference in New Issue