This commit is contained in:
lyswhut
2022-10-29 11:36:35 +08:00
parent 66b965d9f7
commit e45cee6596
715 changed files with 57096 additions and 31771 deletions
@@ -1,66 +0,0 @@
import { useAction, useCommit } from '@renderer/utils/vueTools'
import { tempList } from '@renderer/core/share/list'
const getListPlayIndex = (list, index) => {
if (index == null) {
index = 1
} else {
index = parseInt(index)
if (Number.isNaN(index)) {
index = 1
} else {
if (index < 1) index = 1
else if (index > list.length) index = list.length
}
}
return index - 1
}
export default () => {
const getListDetail = useAction('songList', 'getListDetail')
const getListDetailAll = useAction('songList', 'getListDetailAll')
const setTempList = useCommit('player', 'setTempList')
const updateTempList = useCommit('player', 'updateTempList')
const playSongListDetail = async(source, link, playIndex) => {
console.log(source, link, playIndex)
if (link == null) return
let isPlayingList = false
const id = decodeURIComponent(link)
const playListId = `${source}__${decodeURIComponent(link)}`
let list
try {
list = await getListDetail({ source, id, page: 1 })
} catch (err) {
console.log(err)
}
if (list.length > playIndex) {
isPlayingList = true
setTempList({
list,
index: getListPlayIndex(list, playIndex),
id: playListId,
})
}
getListDetailAll({ source, id }).then(list => {
if (isPlayingList) {
if (tempList.meta.id == id) {
updateTempList({
list,
id: playListId,
})
}
} else {
setTempList({
list,
index: getListPlayIndex(list, playIndex),
id: playListId,
})
}
})
}
return (source, link, playIndex) => {
playSongListDetail(source, link, playIndex)
}
}
@@ -0,0 +1,46 @@
import { playList } from '@renderer/core/player'
import { setTempList } from '@renderer/store/list/action'
import { tempList, tempListMeta } from '@renderer/store/list/state'
import { getListDetail, getListDetailAll } from '@renderer/store/songList/action'
const getListPlayIndex = (list: LX.Music.MusicInfoOnline[], index?: number) => {
if (index == null) {
index = 1
} else {
if (index < 1) index = 1
else if (index > list.length) index = list.length
}
return index - 1
}
export default () => {
const playSongListDetail = async(source: LX.OnlineSource, link: string, playIndex?: number) => {
// console.log(source, link, playIndex)
if (link == null) return
let isPlayingList = false
const id = decodeURIComponent(link)
const playListId = `${source}__${decodeURIComponent(link)}`
let list = (await getListDetail(id, source, 1)).list
if (playIndex != null && list.length > playIndex) {
isPlayingList = true
await setTempList(playListId, list)
playList(tempList.id, getListPlayIndex(list, playIndex))
}
list = await getListDetailAll(id, source)
if (isPlayingList) {
if (tempListMeta.id == id) await setTempList(playListId, list)
} else {
await setTempList(playListId, list)
playList(tempList.id, getListPlayIndex(list, playIndex))
}
}
return async(source: LX.OnlineSource, link: string, playIndex?: number) => {
try {
await playSongListDetail(source, link, playIndex)
} catch (err) {
console.error(err)
throw new Error('Get play list failed.')
}
}
}
-78
View File
@@ -1,78 +0,0 @@
import { isLinux } from '@common/utils'
import { getEnvParams, setIgnoreMouseEvents } from '@renderer/utils/tools'
import { useRefGetter } from '@renderer/utils/vueTools'
import { sync, apiSource, proxy, isFullscreen } from '@renderer/core/share'
import useSync from './useSync'
import useUpdate from './useUpdate'
import useDataInit from './useDataInit'
import useHandleEnvParams from './useHandleEnvParams'
import useEventListener from './useEventListener'
import useDeepLink from './useDeepLink'
import usePlayer from './usePlayer'
import useListAutoUpdate from './useListAutoUpdate'
export default () => {
const isProd = process.env.NODE_ENV === 'production'
const setting = useRefGetter('setting')
sync.enable = setting.value.sync.enable
apiSource.value = setting.value.apiSource
Object.assign(proxy, setting.value.network.proxy)
isFullscreen.value = setting.value.startInFullscreen
const dieableIgnoreMouseEvents = () => {
if (window.dt) return
setIgnoreMouseEvents(false)
}
const enableIgnoreMouseEvents = () => {
if (window.dt) return
setIgnoreMouseEvents(true)
}
useUpdate(setting)
useSync()
useEventListener({
dieableIgnoreMouseEvents,
enableIgnoreMouseEvents,
setting,
isProd,
isLinux,
})
const initPlayer = usePlayer({ setting })
const handleEnvParams = useHandleEnvParams()
const initData = useDataInit({
setting,
})
const initDeepLink = useDeepLink()
const handleListAutoUpdate = useListAutoUpdate()
getEnvParams().then(envParams => {
// 移除代理相关的环境变量设置,防止请求库自动应用它们
// eslint-disable-next-line no-undef
const processEnv = ENVIRONMENT
for (const key of Object.keys(processEnv)) {
if (/^(?:http_proxy|https_proxy|NO_PROXY)$/i.test(key)) delete processEnv[key]
}
const envProxy = envParams.cmdParams['proxy-server']
if (envProxy && typeof envProxy == 'string') {
const [host, port = ''] = envProxy.split(':')
proxy.envProxy = {
host,
port,
}
}
// 初始化我的列表、下载列表等数据
initData().then(() => {
initPlayer()
handleEnvParams(envParams) // 处理传入的启动参数
initDeepLink(envParams)
handleListAutoUpdate()
})
})
}
+73
View File
@@ -0,0 +1,73 @@
import { checkUpdate, getEnvParams, getViewPrevState, sendInited } from '@renderer/utils/ipc'
import { proxy, isFullscreen, themeId } from '@renderer/store'
import { appSetting } from '@renderer/store/setting'
import useSync from './useSync'
import useUpdate from './useUpdate'
import useDataInit from './useDataInit'
// import useHandleEnvParams from './useHandleEnvParams'
import useEventListener from './useEventListener'
import useDeeplink from './useDeeplink'
import usePlayer from './usePlayer'
import handleListAutoUpdate from './listAutoUpdate'
import { useRouter } from '@common/utils/vueRouter'
import useSettingSync from './useSettingSync'
export default () => {
// apiSource.value = appSetting['common.apiSource']
proxy.enable = appSetting['network.proxy.enable']
proxy.host = appSetting['network.proxy.host']
proxy.port = appSetting['network.proxy.port']
proxy.username = appSetting['network.proxy.username']
proxy.password = appSetting['network.proxy.password']
isFullscreen.value = appSetting['common.startInFullscreen']
themeId.value = appSetting['theme.id']
const router = useRouter()
const initSyncService = useSync()
useEventListener()
const initPlayer = usePlayer()
// const handleEnvParams = useHandleEnvParams()
const initData = useDataInit()
const initDeeplink = useDeeplink()
// const handleListAutoUpdate = useListAutoUpdate()
useUpdate()
useSettingSync()
void getEnvParams().then(envParams => {
// 移除代理相关的环境变量设置,防止请求库自动应用它们
// eslint-disable-next-line no-undef
// const processEnv = ENVIRONMENT
// for (const key of Object.keys(processEnv)) {
// // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
// if (/^(?:http_proxy|https_proxy|NO_PROXY)$/i.test(key)) delete processEnv[key]
// }
const envProxy = envParams.cmdParams['proxy-server']
if (envProxy && typeof envProxy == 'string') {
const [host, port = ''] = envProxy.split(':')
proxy.envProxy = {
host,
port,
}
}
void getViewPrevState().then(state => {
void router.push({ path: state.url, query: state.query })
})
// 初始化我的列表、下载列表等数据
void initData().then(() => {
initPlayer()
// handleEnvParams(envParams) // 处理传入的启动参数
void initDeeplink(envParams)
void initSyncService()
handleListAutoUpdate()
if (window.lx.isDev) checkUpdate()
sendInited()
})
})
}
@@ -0,0 +1,24 @@
import { getListUpdateInfo } from '@renderer/utils/data'
import { userLists } from '@renderer/store/list/state'
import syncSourceList from '@renderer/store/list/syncSourceList'
const handleSyncSourceList = async(waitUpdateLists: LX.List.UserListInfo[]) => {
if (!waitUpdateLists.length) return
const targetListInfo = waitUpdateLists.shift() as LX.List.UserListInfo
// console.log(targetListInfo)
try {
await syncSourceList(targetListInfo)
} catch {}
void handleSyncSourceList(waitUpdateLists)
}
export default () => {
void getListUpdateInfo().then(listUpdateInfo => {
const waitUpdateLists = Object.entries(listUpdateInfo)
.map(([id, info]) => info.isAutoUpdate && userLists.find(l => l.id == id))
.filter(_ => _) as LX.List.UserListInfo[]
for (let i = 2; i > 0; i--) {
void handleSyncSourceList(waitUpdateLists)
}
})
}
-163
View File
@@ -1,163 +0,0 @@
import { useCommit, useRefGetter } from '@renderer/utils/vueTools'
import { getPlayList } from '@renderer/utils'
import { getPlayInfo, getSearchHistoryList } from '@renderer/utils/tools'
import { initListPosition, initListPrevSelectId, initListUpdateInfo } from '@renderer/utils/data'
import music from '@renderer/utils/music'
import { log } from '@common/utils'
import {
defaultList as stateDefaultList,
loveList as stateloveList,
userLists as stateUserLists,
tempList as stateTempList,
} from '@renderer/core/share/list'
import { getList } from '@renderer/core/share/utils'
import { downloadStatus, downloadList } from '@renderer/core/share/download'
import useSaveData from './useSaveData'
import useInitUserApi from './useInitUserApi'
const useListInit = ({
saveMyListThrottle,
}) => {
const initList = useCommit('list', 'initList')
const updateDownloadList = useCommit('download', 'initDownloadList')
const initMyList = ({ defaultList, loveList, userList, tempList }) => {
if (!defaultList) defaultList = { ...stateDefaultList }
if (!loveList) loveList = { ...stateloveList }
if (!tempList) tempList = { ...stateTempList }
if (userList) {
let needSave = false
const getListId = id => id.includes('.') ? getListId(id.substring(0, id.lastIndexOf('_'))) : id
userList.forEach(l => {
if (!l.id.includes('__') || l.source) return
let [source, id] = l.id.split('__')
id = getListId(id)
l.source = source
l.sourceListId = id
if (!needSave) needSave = true
})
if (needSave) saveMyListThrottle({ userList })
} else {
userList = [...stateUserLists]
}
if (!defaultList.list) defaultList.list = []
if (!loveList.list) loveList.list = []
if (!tempList.list) tempList.list = []
initList({ defaultList, loveList, userList, tempList })
}
const initDownloadList = list => {
if (list) {
list = list.filter(item => item?.key)
for (const item of list) {
if (item.status == downloadStatus.RUN || item.status == downloadStatus.WAITING) {
item.status = downloadStatus.PAUSE
item.statusText = '暂停下载'
}
if (!item.metadata) { // 转换v1.15.3及以前的任务信息
if (item.name == null) {
item.name = `${item.musicInfo.name} - ${item.musicInfo.singer}`
item.songmid = item.musicInfo.songmid
}
item.metadata = {
musicInfo: item.musicInfo,
url: item.url,
type: item.type,
ext: item.ext,
fileName: item.fileName,
filePath: item.filePath,
}
delete item.musicInfo
delete item.url
delete item.type
delete item.ext
delete item.fileName
delete item.filePath
}
}
updateDownloadList(list)
}
}
return () => {
return getPlayList().then(({ defaultList, loveList, userList, tempList, downloadList }) => {
initMyList({ defaultList, loveList, userList, tempList })
initDownloadList(downloadList) // 初始化下载列表
})
}
}
const usePlayInfoInit = () => {
const setPlayList = useCommit('player', 'setList')
return () => {
return getPlayInfo().then(info => {
window.restorePlayInfo = null
if (!info?.listId || info.index < 0) return
const list = getList(info.listId)
if (!list || !list[info.index]) return
window.restorePlayInfo = info
setPlayList({
listId: info.listId,
index: info.index,
})
})
}
}
const useSearchHistoryInit = () => {
const setSearchHistoryList = useCommit('search', 'setHistory')
return saveSearchHistoryListThrottle => {
return getSearchHistoryList().then(historyList => {
if (historyList == null) {
historyList = []
saveSearchHistoryListThrottle(historyList)
} else {
setSearchHistoryList(historyList)
}
})
}
}
export default ({
setting,
}) => {
const searchHistoryList = useRefGetter('search', 'historyList')
// 数据保存初始化
const { saveMyListThrottle, saveSearchHistoryListThrottle } = useSaveData({
setting,
searchHistoryList,
})
const initUserApi = useInitUserApi({ setting })
// 列表初始化
const initList = useListInit({
saveMyListThrottle,
})
// 播放信息初始化
const initPlayInfo = usePlayInfoInit()
// 搜索历史初始化
const initSearchHistory = useSearchHistoryInit()
return async() => {
await Promise.all([
initListPosition(), // 列表位置记录
initListPrevSelectId(), // 上次选中的列表记录
initListUpdateInfo(), // 列表更新设置
initUserApi(), // 自定义API
]).catch(err => log.error(err))
music.init() // 初始化音乐sdk
await initList().catch(err => log.error(err)) // 初始化列表
await initPlayInfo(downloadList).catch(err => log.error(err)) // 初始化上次的歌曲播放信息
await initSearchHistory(saveSearchHistoryListThrottle).catch(err => log.error(err)) // 初始化搜索历史记录
}
}
+44
View File
@@ -0,0 +1,44 @@
import { getPlayInfo } from '@renderer/utils/ipc'
import music from '@renderer/utils/musicSdk'
import { log } from '@common/utils'
import { getListMusics, getUserLists, registerAction } from '@renderer/store/list/action'
import useInitUserApi from './useInitUserApi'
import { play, playList } from '@renderer/core/player'
import { onBeforeUnmount } from '@common/utils/vueTools'
import { appSetting } from '@renderer/store/setting'
const initPrevPlayInfo = async() => {
const info = await getPlayInfo()
window.lx.restorePlayInfo = null
if (!info?.listId || info.index < 0) return
const list = await getListMusics(info.listId)
if (!list || !list[info.index]) return
window.lx.restorePlayInfo = info
playList(info.listId, info.index)
if (appSetting['player.startupAutoPlay']) setTimeout(play)
}
export default () => {
const initUserApi = useInitUserApi()
let unregister: null | (() => void) = null
onBeforeUnmount(() => {
if (unregister) unregister()
})
return async() => {
await Promise.all([
initUserApi(), // 自定义API
]).catch(err => log.error(err))
void music.init() // 初始化音乐sdk
unregister = registerAction((ids) => {
window.app_event.myListUpdate(ids)
})
window.lxData.userLists = await getUserLists() // 获取用户列表
await initPrevPlayInfo().catch(err => log.error(err)) // 初始化上次的歌曲播放信息
}
}
@@ -1,6 +1,5 @@
import { onBeforeUnmount } from '@renderer/utils/vueTools'
import { base as eventBaseName } from '@renderer/event/names'
import { getEnvParams, clearEnvParamsDeeplink } from '@renderer/utils/tools'
import { onBeforeUnmount } from '@common/utils/vueTools'
import { clearEnvParamsDeeplink, focusWindow, onDeeplink } from '@renderer/utils/ipc'
import { useDialog } from './utils'
import useMusicAction from './useMusicAction'
@@ -15,11 +14,17 @@ export default () => {
const handleSonglistAction = useSonglistAction()
const handleLinkAction = link => {
const handleLinkAction = async(link: string) => {
// console.log(link)
const [url, search] = link.split('?')
const [type, action, ...paths] = url.replace('lxmusic://', '').split('/')
const params = {}
const params: {
paths: string[]
data?: any
[key: string]: any
} = {
paths: [],
}
if (search) {
for (const param of search.split('&')) {
const [key, value] = param.split('=')
@@ -34,39 +39,36 @@ export default () => {
handleMusicAction(action, params)
break
case 'songlist':
handleSonglistAction(action, params)
await handleSonglistAction(action, params)
break
default: throw new Error('Unknown type: ' + type)
}
}
const handleFocus = () => {
const rDeeplink = onDeeplink(async({ params: link }) => {
console.log(link)
if (!isInited) return
getEnvParams().then(envParams => {
if (!envParams.deeplink) return
clearEnvParamsDeeplink()
try {
handleLinkAction(envParams.deeplink)
} catch (err) {
showErrorDialog(err.message)
}
})
}
window.eventHub.on(eventBaseName.focus, handleFocus)
onBeforeUnmount(() => {
window.eventHub.off(eventBaseName.focus, handleFocus)
clearEnvParamsDeeplink()
try {
await handleLinkAction(link)
} catch (err: any) {
showErrorDialog(err.message)
focusWindow()
}
})
return envParams => {
onBeforeUnmount(() => {
rDeeplink()
})
return async(envParams: LX.EnvParams) => {
if (envParams.deeplink) {
clearEnvParamsDeeplink()
try {
handleLinkAction(envParams.deeplink)
} catch (err) {
await handleLinkAction(envParams.deeplink)
} catch (err: any) {
showErrorDialog(err.message)
focusWindow()
}
}
isInited = true
@@ -1,9 +1,14 @@
import { useCommit, useAction, useRouter, markRaw } from '@renderer/utils/vueTools'
import { decodeName } from '@renderer/utils'
// import { allList, defaultList, loveList, userLists } from '@renderer/core/share/list'
import { playMusicInfo, isShowPlayerDetail, setShowPlayerDetail } from '@renderer/core/share/player'
import { markRaw } from '@common/utils/vueTools'
import { useRouter } from '@common/utils/vueRouter'
import { decodeName } from '@common/utils/common'
// import { allList, defaultList, loveList, userLists } from '@renderer/store/list'
import { playMusicInfo, isShowPlayerDetail } from '@renderer/store/player/state'
import { setShowPlayerDetail, addTempPlayList } from '@renderer/store/player/action'
import { dataVerify, qualityFilter, sources } from './utils'
import { focusWindow } from '@renderer/utils/ipc'
import { playNext } from '@renderer/core/player/action'
import { toNewMusicInfo } from '@common/utils/tools'
const useSearchMusic = () => {
const router = useRouter()
@@ -39,13 +44,11 @@ const useSearchMusic = () => {
source,
},
})
focusWindow()
}
}
const usePlayMusic = () => {
const setTempPlayList = useCommit('player', 'setTempPlayList')
const playNext = useAction('player', 'playNext')
const filterInfoByPlayMusic = musicInfo => {
switch (musicInfo.source) {
case 'kw':
@@ -131,7 +134,7 @@ const usePlayMusic = () => {
return ({ data: _musicInfo }) => {
_musicInfo = filterInfoByPlayMusic(_musicInfo)
const musicInfo = {
let musicInfo = {
..._musicInfo,
singer: decodeName(_musicInfo.singer),
name: decodeName(_musicInfo.name),
@@ -143,9 +146,10 @@ const usePlayMusic = () => {
for (const type of musicInfo.types) {
musicInfo._types[type.type] = { size: type.size }
}
musicInfo = toNewMusicInfo(musicInfo)
markRaw(musicInfo)
const isPlaying = !!playMusicInfo.musicInfo
setTempPlayList([{ listId: '__temp__', musicInfo, isTop: true }])
addTempPlayList([{ listId: '__temp__', musicInfo, isTop: true }])
if (isPlaying) playNext()
}
}
@@ -1,27 +1,30 @@
import { useRouter } from '@renderer/utils/vueTools'
import { isShowPlayerDetail, setShowPlayerDetail } from '@renderer/core/share/player'
import { useRouter, useRoute } from '@common/utils/vueRouter'
import { isShowPlayerDetail } from '@renderer/store/player/state'
import { setShowPlayerDetail } from '@renderer/store/player/action'
import usePlaySonglist from '../compositions/usePlaySonglist'
import { focusWindow } from '@renderer/utils/ipc'
import { dataVerify, sourceVerify } from './utils'
const useOpenSonglist = () => {
const router = useRouter()
const route = useRoute()
const handleOpenSonglist = params => {
if (params.id) {
router.replace({
path: '/songList',
router[route.path == '/songList/detail' ? 'replace' : 'push']({
path: '/songList/detail',
query: {
source: params.source,
id: params.id,
},
})
} else if (params.url) {
router.replace({
path: '/songList',
router[route.path == '/songList/detail' ? 'replace' : 'push']({
path: '/songList/detail',
query: {
source: params.source,
url: params.url,
id: params.url,
},
})
}
@@ -51,12 +54,13 @@ const useOpenSonglist = () => {
if (!songlistInfo.id && !songlistInfo.url) throw new Error('id or url missing')
if (isShowPlayerDetail.value) setShowPlayerDetail(false)
handleOpenSonglist(songlistInfo)
focusWindow()
}
}
const usePlaySonglistDetail = () => {
const playSongListDetail = usePlaySonglist()
return ({ paths, data }) => {
return async({ paths, data }) => {
let songlistInfo = {
source: null,
id: null,
@@ -69,7 +73,10 @@ const usePlaySonglistDetail = () => {
songlistInfo.source = paths[0]
songlistInfo.url = paths[1]
songlistInfo.index = paths[2]
if (songlistInfo.index != null) songlistInfo.index = parseInt(songlistInfo.index)
if (songlistInfo.index != null) {
songlistInfo.index = parseInt(songlistInfo.index)
if (Number.isNaN(songlistInfo.index)) delete songlistInfo.index
}
}
sourceVerify(songlistInfo.source)
@@ -83,7 +90,7 @@ const usePlaySonglistDetail = () => {
if (!songlistInfo.id && !songlistInfo.url) throw new Error('id or url missing')
playSongListDetail(songlistInfo.source, songlistInfo.id ?? songlistInfo.url, songlistInfo.index ?? 0)
await playSongListDetail(songlistInfo.source, songlistInfo.id ?? songlistInfo.url, songlistInfo.index)
}
}
@@ -92,13 +99,13 @@ export default () => {
const handlePlaySonglist = usePlaySonglistDetail()
return (action, info) => {
return async(action, info) => {
switch (action) {
case 'open':
handleOpenSonglist(info)
break
case 'play':
handlePlaySonglist(info)
await handlePlaySonglist(info)
break
default: throw new Error('Unknown action: ' + action)
}
@@ -1,8 +1,8 @@
import { useI18n } from '@renderer/utils/vueTools'
import { useI18n } from '@renderer/plugins/i18n'
import { dialog } from '@renderer/plugins/Dialog'
export const useDialog = () => {
const { t } = useI18n()
const t = useI18n()
const errorDialog = message => {
dialog({
message: `${t('deep_link__handle_error_tip', { message })}`,
@@ -1,149 +0,0 @@
import { openUrl, getFontSizeWithScreen } from '@renderer/utils'
import { base as eventBaseName } from '@renderer/event/names'
import { onSetConfig, onSystemThemeChange } from '@renderer/utils/tools'
import { isFullscreen, themeShouldUseDarkColors } from '@renderer/core/share'
import { rendererSend, NAMES, rendererInvoke } from '@common/ipc'
import {
toRaw,
useCommit,
onBeforeUnmount,
watch,
useRefGetter,
} from '@renderer/utils/vueTools'
const handle_key_down = ({ event, type, key }) => {
// console.log(key)
if (key != 'escape' || !event || event.repeat || type == 'up' || window.isEditingHotKey || event.target.classList.contains('ignore-esc')) return
if (event.target.tagName != 'INPUT') {
if (isFullscreen.value) {
event.lx_handled = true
rendererInvoke(NAMES.mainWindow.fullscreen, false).then(fullscreen => {
isFullscreen.value = fullscreen
})
}
return
}
event.target.value = ''
event.target.blur()
event.lx_handled = true
}
const handleBodyClick = event => {
if (event.target.tagName != 'A') return
if (event.target.host == window.location.host) return
event.preventDefault()
if (/^https?:\/\//.test(event.target.href)) openUrl(event.target.href)
}
const handle_open_devtools = event => {
rendererSend(NAMES.mainWindow.open_dev_tools)
}
const handle_fullscreen = event => {
let fullscreen = !isFullscreen.value
if (typeof event == 'boolean') {
fullscreen = event
} else if (event.event.repeat) return
rendererInvoke(NAMES.mainWindow.fullscreen, fullscreen).then(fullscreen => {
isFullscreen.value = fullscreen
})
}
export default ({
dieableIgnoreMouseEvents,
enableIgnoreMouseEvents,
setting,
isProd,
isLinux,
}) => {
const theme = useRefGetter('theme')
const font = useRefGetter('font')
const windowSizeActive = useRefGetter('windowSizeActive')
const setSetting = useCommit('setSetting')
const isShowAnimation = useRefGetter('isShowAnimation')
const dom_root = document.getElementById('root')
watch(theme, (val) => {
dom_root.className = val
})
watch(font, (val) => {
document.documentElement.style.fontFamily = val
}, {
immediate: true,
})
watch(isFullscreen, val => {
if (val) {
document.body.classList.remove(window.dt ? 'disableTransparent' : 'transparent')
document.body.classList.add('fullscreen')
document.documentElement.style.fontSize = getFontSizeWithScreen(window.screen.width) + 'px'
} else {
document.body.classList.remove('fullscreen')
document.body.classList.add(window.dt ? 'disableTransparent' : 'transparent')
document.documentElement.style.fontSize = windowSizeActive.value.fontSize
}
}, {
immediate: true,
})
watch(windowSizeActive, ({ fontSize }) => {
document.documentElement.style.fontSize = fontSize
})
watch(isShowAnimation, val => {
if (val) {
if (document.body.classList.contains('disableAnimation')) {
document.body.classList.remove('disableAnimation')
}
} else {
if (!document.body.classList.contains('disableAnimation')) {
document.body.classList.add('disableAnimation')
}
}
}, {
immediate: true,
})
const rSetConfig = onSetConfig((event, config) => {
// console.log(config)
setSetting(Object.assign({}, toRaw(setting.value), config))
window.eventHub.emit(eventBaseName.set_config, config)
})
const rSystemThemeChange = onSystemThemeChange((event, isDark) => {
// console.log(isDark)
themeShouldUseDarkColors.value = isDark
})
window.eventHub.emit(eventBaseName.bindKey)
window.eventHub.on(eventBaseName.key_down, handle_key_down)
window.eventHub.on('key_mod+f12_down', handle_open_devtools)
window.eventHub.on('key_f11_down', handle_fullscreen)
window.eventHub.on(eventBaseName.fullscreenToggle, handle_fullscreen)
document.body.addEventListener('click', handleBodyClick, true)
if (isProd && !window.dt && !isLinux) {
document.body.addEventListener('mouseenter', enableIgnoreMouseEvents)
document.body.addEventListener('mouseleave', dieableIgnoreMouseEvents)
const dom_root = document.getElementById('root')
dom_root.addEventListener('mouseenter', dieableIgnoreMouseEvents)
dom_root.addEventListener('mouseleave', enableIgnoreMouseEvents)
}
onBeforeUnmount(() => {
window.eventHub.off(eventBaseName.key_down, handle_key_down)
window.eventHub.off('key_mod+f12_down', handle_open_devtools)
window.eventHub.off('key_f11_down', handle_fullscreen)
window.eventHub.off(eventBaseName.fullscreenToggle, handle_fullscreen)
document.body.removeEventListener('click', handleBodyClick)
window.eventHub.emit(eventBaseName.unbindKey)
rSetConfig()
rSystemThemeChange()
if (isProd && !window.dt && !isLinux) {
document.body.removeEventListener('mouseenter', enableIgnoreMouseEvents)
document.body.removeEventListener('mouseleave', dieableIgnoreMouseEvents)
const dom_root = document.getElementById('root')
dom_root.removeEventListener('mouseenter', dieableIgnoreMouseEvents)
dom_root.removeEventListener('mouseleave', enableIgnoreMouseEvents)
}
})
}
@@ -0,0 +1,144 @@
import { getFontSizeWithScreen } from '@renderer/utils'
import {
minWindow,
onFocus,
onSettingChanged,
onThemeChange,
openDevTools,
quitApp,
setFullScreen,
showHideWindowToggle,
} from '@renderer/utils/ipc'
import {
isFullscreen,
themeId,
themeShouldUseDarkColors,
} from '@renderer/store'
import {
appSetting,
isShowAnimation,
mergeSetting,
} from '@renderer/store/setting'
import {
onBeforeUnmount,
watch,
} from '@common/utils/vueTools'
// import { isLinux, isProd } from '@common/utils'
import { openUrl } from '@common/utils/electron'
import { HOTKEY_COMMON } from '@common/hotKey'
import { applyTheme, getThemes } from '@renderer/store/utils'
import { clearDownKeys } from '@renderer/event'
const handle_key_down = ({ event, type, key }: LX.KeyDownEevent) => {
// console.log(key)
if (key != 'escape' || !event || event.repeat || type == 'up' || window.lx.isEditingHotKey || (event.target as HTMLElement)?.classList.contains('ignore-esc') || event.lx_handled) return
if ((event.target as HTMLElement).tagName != 'INPUT') {
if (isFullscreen.value) {
event.lx_handled = true
void setFullScreen(false).then(fullscreen => {
isFullscreen.value = fullscreen
})
}
return
}
(event.target as HTMLInputElement).value = ''
;(event.target as HTMLInputElement).blur()
event.lx_handled = true
}
const handleBodyClick = (event: MouseEvent) => {
if ((event?.target as HTMLElement)?.tagName != 'A') return
if ((event?.target as HTMLAnchorElement).host == window.location.host) return
event.preventDefault()
if (/^https?:\/\//.test((event?.target as HTMLAnchorElement).href)) void openUrl((event?.target as HTMLAnchorElement).href)
}
const handle_open_devtools = () => {
openDevTools()
}
const handle_fullscreen = (event: LX.KeyDownEevent) => {
let fullscreen = !isFullscreen.value
if (typeof event == 'boolean') {
fullscreen = event
} else if (event.event?.repeat) return
void setFullScreen(fullscreen).then(fullscreen => {
isFullscreen.value = fullscreen
})
}
export default () => {
watch(isFullscreen, val => {
if (val) {
document.documentElement.classList.remove(window.dt ? 'disableTransparent' : 'transparent')
document.documentElement.classList.add('fullscreen')
document.documentElement.style.fontSize = `${getFontSizeWithScreen(window.screen.width)}px`
} else {
document.documentElement.classList.remove('fullscreen')
document.documentElement.classList.add(window.dt ? 'disableTransparent' : 'transparent')
document.documentElement.style.fontSize = `${appSetting['common.fontSize']}px`
}
}, {
immediate: true,
})
watch(isShowAnimation, val => {
if (val) {
if (document.documentElement.classList.contains('disableAnimation')) {
document.documentElement.classList.remove('disableAnimation')
}
} else {
if (!document.documentElement.classList.contains('disableAnimation')) {
document.documentElement.classList.add('disableAnimation')
}
}
}, {
immediate: true,
})
const rSetConfig = onSettingChanged(({ params: setting }) => {
// console.log(config)
mergeSetting(setting)
window.app_event.configUpdate()
})
const rFocus = onFocus(() => {
clearDownKeys()
})
const rThemeChange = onThemeChange(({ params: setting }) => {
// console.log(setting)
if (themeShouldUseDarkColors.value == setting.shouldUseDarkColors) {
if (themeId.value == setting.theme.id) return
themeId.value = setting.theme.id
} else {
themeShouldUseDarkColors.value = setting.shouldUseDarkColors
if (themeId.value != 'auto') return
}
getThemes(({ dataPath }) => {
applyTheme('auto', appSetting['theme.lightId'], appSetting['theme.darkId'], dataPath)
})
})
window.key_event.on(HOTKEY_COMMON.min.action, minWindow)
window.key_event.on(HOTKEY_COMMON.hide_toggle.action, showHideWindowToggle)
window.key_event.on(HOTKEY_COMMON.close.action, quitApp)
window.app_event.on('keyDown', handle_key_down)
window.key_event.on('key_mod+f12_down', handle_open_devtools)
window.key_event.on('key_f11_down', handle_fullscreen)
document.body.addEventListener('click', handleBodyClick, true)
onBeforeUnmount(() => {
window.key_event.off(HOTKEY_COMMON.min.action, minWindow)
window.key_event.off(HOTKEY_COMMON.hide_toggle.action, showHideWindowToggle)
window.key_event.off(HOTKEY_COMMON.close.action, quitApp)
window.app_event.off('keyDown', handle_key_down)
window.key_event.off('key_mod+f12_down', handle_open_devtools)
window.key_event.off('key_f11_down', handle_fullscreen)
document.body.removeEventListener('click', handleBodyClick)
rSetConfig()
rFocus()
rThemeChange()
})
}
@@ -1,88 +0,0 @@
import { useCommit, useRouter } from '@renderer/utils/vueTools'
import { parseUrlParams } from '@renderer/utils'
import { defaultList, loveList, userLists } from '@renderer/core/share/list'
import { getList } from '@renderer/core/share/utils'
import usePlaySonglist from './compositions/usePlaySonglist'
const getListPlayIndex = (list, index) => {
if (index == null) {
index = 1
} else {
index = parseInt(index)
if (Number.isNaN(index)) {
index = 1
} else {
if (index < 1) index = 1
else if (index > list.length) index = list.length
}
}
return index - 1
}
const useInitEnvParamSearch = () => {
const router = useRouter()
return search => {
if (search == null) return
router.push({
path: 'search',
query: {
text: search,
},
})
}
}
const useInitEnvParamPlay = () => {
const setPlayList = useCommit('player', 'setList')
const playSongListDetail = usePlaySonglist()
return (playStr) => {
if (playStr == null || typeof playStr != 'string') return
// -play="source=kw&link=链接、ID"
// -play="source=myList&name=名字"
// -play="source=myList&name=名字&index=位置"
const params = parseUrlParams(playStr)
if (params.type != 'songList') return
switch (params.source) {
case 'myList':
if (params.name != null) {
let targetList
const lists = [defaultList, loveList, ...userLists]
for (const list of lists) {
if (list.name === params.name) {
targetList = list
break
}
}
if (!targetList) return
setPlayList({
listId: targetList.id,
index: getListPlayIndex(getList(targetList.id), params.index),
})
}
break
case 'kw':
case 'kg':
case 'tx':
case 'mg':
case 'wy':
playSongListDetail(params.source, params.link, params.index)
break
}
}
}
export default () => {
// 处理启动参数 search
const initEnvParamSearch = useInitEnvParamSearch()
// 处理启动参数 play
const initEnvParamPlay = useInitEnvParamPlay()
return envParams => {
initEnvParamSearch(envParams.cmdParams.search)
initEnvParamPlay(envParams.cmdParams.play)
}
}
@@ -0,0 +1,90 @@
// import { useRouter } from '@common/utils/vueTools'
// import { parseUrlParams } from '@common/utils/renderer'
// import { defaultList, loveList, userLists } from '@renderer/store/list'
// import { getList } from '@renderer/store/utils'
// import usePlaySonglist from './compositions/usePlaySonglist'
// import { setPlayList } from '@renderer/store/player'
// const getListPlayIndex = (list: LX.Music.MusicInfo[], indexStr?: string): number => {
// let index: number
// if (indexStr == null) {
// index = 1
// } else {
// index = parseInt(indexStr)
// if (Number.isNaN(index)) {
// index = 1
// } else {
// if (index < 1) index = 1
// else if (index > list.length) index = list.length
// }
// }
// return index - 1
// }
// const useInitEnvParamSearch = () => {
// const router = useRouter()
// return (search?: string) => {
// if (search == null) return
// void router.push({
// path: 'search',
// query: {
// text: search,
// },
// })
// }
// }
// const useInitEnvParamPlay = () => {
// // const setPlayList = useCommit('player', 'setList')
// const playSongListDetail = usePlaySonglist()
// return (playStr?: string) => {
// if (playStr == null || typeof playStr != 'string') return
// // -play="source=kw&link=链接、ID"
// // -play="source=myList&name=名字"
// // -play="source=myList&name=名字&index=位置"
// const params = parseUrlParams(playStr)
// if (params.type != 'songList') return
// switch (params.source) {
// case 'myList':
// if (params.name != null) {
// let targetList
// const lists = [defaultList, loveList, ...userLists]
// for (const list of lists) {
// if (list.name === params.name) {
// targetList = list
// break
// }
// }
// if (!targetList) return
// setPlayList({
// listId: targetList.id,
// index: getListPlayIndex(getList(targetList.id), params.index),
// })
// }
// break
// case 'kw':
// case 'kg':
// case 'tx':
// case 'mg':
// case 'wy':
// playSongListDetail(params.source, params.link, params.index)
// break
// }
// }
// }
// export default () => {
// // 处理启动参数 search
// const initEnvParamSearch = useInitEnvParamSearch()
// // 处理启动参数 play
// const initEnvParamPlay = useInitEnvParamPlay()
// return (envParams: LX.EnvParams) => {
// initEnvParamSearch(envParams.cmdParams.search)
// initEnvParamPlay(envParams.cmdParams.play)
// }
// }
@@ -1,42 +1,38 @@
import { onBeforeUnmount, useI18n } from '@renderer/utils/vueTools'
import { onUserApiStatus, setUserApi, getUserApiList, userApiRequest, userApiRequestCancel, onShowUserApiUpdateAlert } from '@renderer/utils/tools'
import { openUrl } from '@renderer/utils'
import apiSourceInfo from '@renderer/utils/music/api-source-info'
import music from '@renderer/utils/music'
import { apiSource, qualityList, userApi } from '@renderer/core/share'
import { onBeforeUnmount } from '@common/utils/vueTools'
import { useI18n } from '@renderer/plugins/i18n'
import { onUserApiStatus, getUserApiList, sendUserApiRequest, userApiRequestCancel, onShowUserApiUpdateAlert } from '@renderer/utils/ipc'
import { openUrl } from '@common/utils/electron'
import { qualityList, userApi } from '@renderer/store'
import { appSetting } from '@renderer/store/setting'
import { dialog } from '@renderer/plugins/Dialog'
import { setUserApi } from '@renderer/core/apiSource'
export default ({ setting }) => {
const { t } = useI18n()
export default () => {
const t = useI18n()
if (/^user_api/.test(setting.value.apiSource)) {
setUserApi(setting.value.apiSource)
} else {
qualityList.value = music.supportQuality[setting.value.apiSource]
}
const rUserApiStatus = onUserApiStatus((event, { status, message, apiInfo }) => {
const rUserApiStatus = onUserApiStatus(({ params: { status, message, apiInfo } }) => {
// console.log({ status, message, apiInfo })
userApi.status = status
userApi.message = message
if (status) {
if (apiInfo.id === setting.value.apiSource) {
let apis = {}
let qualitys = {}
if (status && apiInfo && apiInfo.sources) {
if (apiInfo.id === appSetting['common.apiSource']) {
let apis: any = {}
let qualitys: LX.QualityList = {}
for (const [source, { actions, type, qualitys: sourceQualitys }] of Object.entries(apiInfo.sources)) {
if (type != 'music') continue
apis[source] = {}
apis[source as LX.Source] = {}
for (const action of actions) {
switch (action) {
case 'musicUrl':
apis[source].getMusicUrl = (songInfo, type) => {
apis[source].getMusicUrl = (songInfo: LX.Music.MusicInfo, type: LX.Quality) => {
const requestKey = `request__${Math.random().toString().substring(2)}`
return {
canceleFn() {
userApiRequestCancel(requestKey)
},
promise: userApiRequest({
promise: sendUserApiRequest({
requestKey,
data: {
source,
@@ -50,9 +46,9 @@ export default ({ setting }) => {
// console.log(res)
if (!/^https?:/.test(res.data.url)) return Promise.reject(new Error('Get url failed'))
return { type, url: res.data.url }
}).catch(err => {
}).catch(async err => {
console.log(err.message)
return Promise.reject(err)
return await Promise.reject(err)
}),
}
}
@@ -62,7 +58,7 @@ export default ({ setting }) => {
break
}
}
qualitys[source] = sourceQualitys
qualitys[source as LX.Source] = sourceQualitys
}
qualityList.value = qualitys
userApi.apis = apis
@@ -70,9 +66,9 @@ export default ({ setting }) => {
}
})
const rUserApiShowUpdateAlert = onShowUserApiUpdateAlert((event, { name, log, updateUrl }) => {
const rUserApiShowUpdateAlert = onShowUserApiUpdateAlert(({ params: { name, log, updateUrl } }) => {
if (updateUrl) {
dialog({
void dialog({
message: `${t('user_api__update_alert', { name })}\n${log}`,
selection: true,
showCancel: true,
@@ -80,12 +76,12 @@ export default ({ setting }) => {
cancelButtonText: t('close'),
}).then(confirm => {
if (!confirm) return
setTimeout(() => {
openUrl(updateUrl)
window.setTimeout(() => {
void openUrl(updateUrl)
}, 300)
})
} else {
dialog({
void dialog({
message: `${t('user_api__update_alert', { name })}\n${log}`,
selection: true,
confirmButtonText: t('ok'),
@@ -98,14 +94,15 @@ export default ({ setting }) => {
rUserApiShowUpdateAlert()
})
return () => {
return getUserApiList().then(list => {
return async() => {
void setUserApi(appSetting['common.apiSource'])
return await getUserApiList().then(list => {
// console.log(list)
if (![...apiSourceInfo.map(s => s.id), ...list.map(s => s.id)].includes(setting.value.apiSource)) {
console.warn('reset api')
let api = apiSourceInfo.find(api => !api.disabled)
if (api) apiSource.value = api.id
}
// if (![...apiSourceInfo.map(s => s.id), ...list.map(s => s.id)].includes(appSetting['common.apiSource'])) {
// console.warn('reset api')
// let api = apiSourceInfo.find(api => !api.disabled)
// if (api) apiSource.value = api.id
// }
userApi.list = list
}).catch(err => {
console.log(err)
@@ -1,27 +0,0 @@
import { getListUpdateInfo } from '@renderer/utils/data'
import useSyncSourceList from '@renderer/utils/compositions/useSyncSourceList'
import { userLists } from '@renderer/core/share/list'
export default () => {
const syncSourceList = useSyncSourceList()
const handleSyncSourceList = async(waitUpdateLists) => {
if (!waitUpdateLists.length) return
const targetListInfo = waitUpdateLists.shift()
// console.log(targetListInfo)
try {
await syncSourceList(targetListInfo)
} catch {}
handleSyncSourceList(waitUpdateLists)
}
return () => {
const waitUpdateLists = Object.entries(getListUpdateInfo())
.map(([id, info]) => info.isAutoUpdate && userLists.find(l => l.id === id))
.filter(_ => _)
for (let i = 2; i > 0; i--) {
handleSyncSourceList(waitUpdateLists)
}
}
}
@@ -1,24 +0,0 @@
import {
createAudio,
} from '@renderer/plugins/player'
import useMediaDevice from './useMediaDevice'
import usePlayerEvent from './usePlayerEvent'
import usePlayer from './usePlayer'
import useTaskbar from './useTaskbar'
import { init as initPlayTimeoutStop } from '@renderer/utils/timeoutStop'
export default ({ setting }) => {
createAudio()
usePlayerEvent()
useMediaDevice({ setting }) // 初始化音频驱动输出设置
usePlayer({ setting })
const initTaskbar = useTaskbar()
initPlayTimeoutStop()
return () => {
initTaskbar()
}
}
@@ -0,0 +1,21 @@
import {
createAudio,
} from '@renderer/plugins/player'
import useMediaDevice from './useMediaDevice'
import usePlayerEvent from './usePlayerEvent'
import usePlayer from './usePlayer'
import usePlayStatus from './usePlayStatus'
export default () => {
createAudio()
usePlayerEvent()
useMediaDevice() // 初始化音频驱动输出设置
usePlayer()
const initPlayStatus = usePlayStatus()
return () => {
void initPlayStatus()
}
}
@@ -1,144 +0,0 @@
import { onBeforeUnmount, watch, markRawList } from '@renderer/utils/vueTools'
import Lyric from '@renderer/utils/lyric-font-player'
import { getCurrentTime as getPlayerCurrentTime } from '@renderer/plugins/player'
import { setDesktopLyricInfo, onGetDesktopLyricInfo } from '@renderer/utils/tools'
import { player as eventPlayerNames } from '@renderer/event/names'
import { lyric, setText, setLines, setOffset, setTempOffset } from '@renderer/core/share/lyric'
import { musicInfo, setStatusText, isPlay, playMusicInfo } from '@renderer/core/share/player'
export default ({ setting }) => {
const lrc = window.lrc = new Lyric({
lineClassName: 'lrc-content',
fontClassName: 'font',
shadowContent: false,
activeLineClassName: 'active',
onPlay(line, text) {
setText(text, line)
setStatusText(text)
// console.log(line, text)
},
onSetLyric(lines, offset) { // listening lyrics seting event
// console.log(lines) // lines is array of all lyric text
setLines(markRawList([...lines]))
setText(lines[0] ?? '', 0)
setOffset(offset) // 歌词延迟
setTempOffset(0) // 重置临时延迟
},
// offset: 80,
})
const getCurrentTime = () => {
return getPlayerCurrentTime() * 1000 + lyric.tempOffset
}
const setPlayInfo = ({ musicInfo }) => {
setDesktopLyricInfo('music_info', {
songmid: musicInfo.songmid,
singer: musicInfo.singer,
name: musicInfo.name,
album: musicInfo.album,
})
}
const setLyric = () => {
if (!musicInfo.songmid) return
const extendedLyrics = []
if (setting.value.player.isShowLyricTranslation && musicInfo.tlrc) extendedLyrics.push(musicInfo.tlrc)
if (setting.value.player.isShowLyricRoma && musicInfo.rlrc) extendedLyrics.push(musicInfo.rlrc)
lrc.setLyric(
setting.value.player.isPlayLxlrc && musicInfo.lxlrc ? musicInfo.lxlrc : musicInfo.lrc,
extendedLyrics,
)
setDesktopLyricInfo('lyric', { lrc: musicInfo.lrc, tlrc: musicInfo.tlrc, rlrc: musicInfo.rlrc, lxlrc: musicInfo.lxlrc })
if (isPlay.value && (musicInfo.url || playMusicInfo.listId == 'download')) {
setTimeout(() => {
const time = getCurrentTime()
setDesktopLyricInfo('play', time)
lrc.play(time)
})
}
}
const setLyricOffset = offset => {
setTempOffset(offset)
if (isPlay.value && (musicInfo.url || playMusicInfo.listId == 'download')) {
setTimeout(() => {
const time = getCurrentTime()
setDesktopLyricInfo('play', time)
lrc.play(time)
})
}
}
const handlePlay = () => {
if (!musicInfo.lrc) return
const currentTime = getCurrentTime()
lrc.play(currentTime)
setDesktopLyricInfo('play', currentTime)
}
const handlePause = () => {
lrc.pause()
setDesktopLyricInfo('pause')
}
const handleStop = () => {
lrc.pause()
setDesktopLyricInfo('stop')
setLines([])
setText('', 0)
}
watch(() => setting.value.player.isShowLyricTranslation, setLyric)
watch(() => setting.value.player.isPlayLxlrc, setLyric)
const rGetDesktopLyricInfo = onGetDesktopLyricInfo((event, info) => {
switch (info.action) {
case 'info':
setDesktopLyricInfo('info', {
songmid: musicInfo.songmid,
singer: musicInfo.singer,
name: musicInfo.name,
album: musicInfo.album,
lrc: musicInfo.lrc,
tlrc: musicInfo.tlrc,
rlrc: musicInfo.rlrc,
lxlrc: musicInfo.lxlrc,
isPlay: isPlay.value,
line: lyric.line,
played_time: getCurrentTime(),
}, info)
break
case 'status':
setDesktopLyricInfo('status', {
isPlay: isPlay.value,
line: lyric.line,
played_time: getCurrentTime(),
}, info)
break
default:
break
}
})
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(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)
})
}
@@ -0,0 +1,42 @@
import { onBeforeUnmount, watch } from '@common/utils/vueTools'
// import { setDesktopLyricInfo, onGetDesktopLyricInfo } from '@renderer/utils/ipc'
// import { musicInfo } from '@renderer/store/player/state'
import {
pause,
play,
setLyric,
stop,
init,
sendInfo,
} from '@renderer/core/lyric'
import { appSetting } from '@renderer/store/setting'
export default () => {
init()
const setPlayInfo = () => {
stop()
sendInfo()
}
watch(() => appSetting['player.isShowLyricTranslation'], setLyric)
watch(() => appSetting['player.isShowLyricRoma'], setLyric)
watch(() => appSetting['player.isPlayLxlrc'], setLyric)
window.app_event.on('play', play)
window.app_event.on('pause', pause)
window.app_event.on('stop', stop)
window.app_event.on('error', pause)
window.app_event.on('musicToggled', setPlayInfo)
window.app_event.on('lyricUpdated', setLyric)
onBeforeUnmount(() => {
window.app_event.off('play', play)
window.app_event.off('pause', pause)
window.app_event.off('stop', stop)
window.app_event.off('error', pause)
window.app_event.off('musicToggled', setPlayInfo)
window.app_event.off('lyricUpdated', setLyric)
})
}
@@ -1,23 +1,21 @@
import {
onBeforeUnmount,
watch,
useCommit,
} from '@renderer/utils/vueTools'
} from '@common/utils/vueTools'
import { pause } from '@renderer/core/player/action'
import { setMediaDeviceId } from '@renderer/plugins/player'
import { isPlay } from '@renderer/core/share/player'
import { player as eventPlayerNames } from '@renderer/event/names'
import { isPlay } from '@renderer/store/player/state'
import { appSetting, saveMediaDeviceId } from '@renderer/store/setting'
const getDevices = async() => {
const devices = await navigator.mediaDevices.enumerateDevices()
return devices.filter(({ kind }) => kind == 'audiooutput')
}
export default ({ setting }) => {
let prevDeviceLabel = null
export default () => {
let prevDeviceLabel: string | null = null
const saveMediaDeviceId = useCommit('setMediaDeviceId')
const setMediaDevice = async(mediaDeviceId) => {
const setMediaDevice = async(mediaDeviceId: string) => {
let label = prevDeviceLabel
const devices = await getDevices()
let device = devices.find(device => device.deviceId === mediaDeviceId)
@@ -32,48 +30,52 @@ export default ({ setting }) => {
prevDeviceLabel = label
// console.log(device)
setMediaDeviceId(mediaDeviceId).catch(err => {
setMediaDeviceId(mediaDeviceId).catch((err: any) => {
console.log(err)
saveMediaDeviceId('default')
})
}
const handleDeviceChangeStopPlay = (device, mediaDeviceId) => {
const handleDeviceChangeStopPlay = (device: MediaDeviceInfo, mediaDeviceId: string) => {
// console.log(device)
// console.log(this.setting.player.isMediaDeviceRemovedStopPlay, this.isPlay, device.label, this.prevDeviceLabel)
// console.log(this.appSetting.player['isMediaDeviceRemovedStopPlay,'] this.isPlay, device.label, this.prevDeviceLabel)
if (
setting.value.player.isMediaDeviceRemovedStopPlay &&
appSetting['player.isMediaDeviceRemovedStopPlay'] &&
isPlay.value &&
device.label != prevDeviceLabel
) {
global.isPlayedStop = true
window.eventHub.emit(eventPlayerNames.setPause)
window.lx.isPlayedStop = true
pause()
}
}
const handleMediaListChange = async() => {
let mediaDeviceId = setting.value.player.mediaDeviceId
let mediaDeviceId = appSetting['player.mediaDeviceId']
const devices = await getDevices()
let device = devices.find(device => device.deviceId === mediaDeviceId)
if (!device) device = devices.find(device => device.deviceId === 'default')
if (!device) device = { label: null, deviceId: null }
// @ts-expect-error
if (!device) device = { label: '', deviceId: '' }
// @ts-expect-error
handleDeviceChangeStopPlay(device, mediaDeviceId)
setMediaDeviceId(device.deviceId).catch(err => {
setMediaDeviceId(device!.deviceId).catch((err: any) => {
console.log(err)
saveMediaDeviceId('default')
})
}
watch(() => setting.value.player.mediaDeviceId, setMediaDevice)
watch(() => appSetting['player.mediaDeviceId'], setMediaDevice)
setMediaDevice(setting.value.player.mediaDeviceId)
void setMediaDevice(appSetting['player.mediaDeviceId'])
// eslint-disable-next-line @typescript-eslint/no-misused-promises
navigator.mediaDevices.addEventListener('devicechange', handleMediaListChange)
onBeforeUnmount(() => {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
navigator.mediaDevices.removeEventListener('devicechange', handleMediaListChange)
})
}
@@ -1,110 +0,0 @@
import { onBeforeUnmount } from '@renderer/utils/vueTools'
import { getDuration, getPlaybackRate, getCurrentTime } from '@renderer/plugins/player'
import { player } from '@renderer/event/names'
export default ({ playPrev, playNext }) => {
const updateMediaSessionInfo = ({ name, singer, albumName, img }) => {
const mediaMetadata = {
title: name,
artist: singer,
album: albumName,
}
if (img) mediaMetadata.artwork = [{ src: img }]
navigator.mediaSession.metadata = new window.MediaMetadata(mediaMetadata)
}
const updatePositionState = (state = {}) => {
navigator.mediaSession.setPositionState({
duration: state.duration ?? getDuration(),
playbackRate: state.playbackRate ?? getPlaybackRate(),
position: state.position ?? getCurrentTime(),
})
}
const setProgress = time => {
window.eventHub.emit(player.setProgress, time)
}
const setStop = () => {
window.eventHub.emit(player.setStop)
}
const handlePlay = () => {
navigator.mediaSession.playbackState = 'playing'
}
const handlePause = () => {
navigator.mediaSession.playbackState = 'paused'
}
const handleStop = () => {
navigator.mediaSession.playbackState = 'none'
}
const handleSetPlayInfo = ({ musicInfo, progress }) => {
updateMediaSessionInfo(musicInfo)
updatePositionState({
position: progress.time,
duration: progress.maxTime,
})
handlePause()
}
// const registerMediaSessionHandler = () => {
// navigator.mediaSession.setActionHandler('play', () => {
// if (this.isPlay || !this.playMusicInfo) return
// console.log('play')
// this.startPlay()
// })
// navigator.mediaSession.setActionHandler('pause', () => {
// if (!this.isPlay || !this.playMusicInfo) return
// console.log('pause')
// this.stopPlay()
// })
navigator.mediaSession.setActionHandler('stop', () => {
console.log('stop')
setStop()
})
navigator.mediaSession.setActionHandler('seekbackward', details => {
console.log('seekbackward')
setProgress(Math.max(getCurrentTime() - details.seekOffset, 0))
})
navigator.mediaSession.setActionHandler('seekforward', details => {
console.log('seekforward')
setProgress(Math.min(getCurrentTime() + details.seekOffset, getDuration()))
})
navigator.mediaSession.setActionHandler('seekto', details => {
console.log('seekto', details.seekTime)
let time = Math.min(details.seekTime, getDuration())
time = Math.max(time, 0)
setProgress(time)
})
navigator.mediaSession.setActionHandler('previoustrack', () => {
console.log('previoustrack')
playPrev()
})
navigator.mediaSession.setActionHandler('nexttrack', () => {
console.log('nexttrack')
playNext()
})
// navigator.mediaSession.setActionHandler('skipad', () => {
// console.log('')
// })
// }
window.eventHub.on(player.player_loadeddata, updatePositionState)
window.eventHub.on(player.player_canplay, updatePositionState)
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, handleSetPlayInfo)
window.eventHub.on(player.updatePic, updateMediaSessionInfo)
onBeforeUnmount(() => {
window.eventHub.off(player.player_loadeddata, updatePositionState)
window.eventHub.off(player.player_canplay, updatePositionState)
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, handleSetPlayInfo)
window.eventHub.off(player.updatePic, updateMediaSessionInfo)
})
}
@@ -0,0 +1,123 @@
import { onBeforeUnmount } from '@common/utils/vueTools'
import { getDuration, getPlaybackRate, getCurrentTime } from '@renderer/plugins/player'
import { musicInfo } from '@renderer/store/player/state'
import { playProgress } from '@renderer/store/player/playProgress'
import { playNext, playPrev, stop } from '@renderer/core/player'
// import { } from ''
export default () => {
const updateMediaSessionInfo = () => {
const mediaMetadata: MediaMetadata = {
title: musicInfo.name,
artist: musicInfo.singer,
album: musicInfo.album,
artwork: [],
}
if (musicInfo.pic) mediaMetadata.artwork = [{ src: musicInfo.pic }]
// @ts-expect-error
navigator.mediaSession.metadata = new window.MediaMetadata(mediaMetadata)
}
const updatePositionState = (state: {
duration?: number
position?: number
playbackRate?: number
} = {}) => {
navigator.mediaSession.setPositionState({
duration: state.duration ?? getDuration(),
playbackRate: state.playbackRate ?? getPlaybackRate(),
position: state.position ?? getCurrentTime(),
})
}
const setProgress = (time: number) => {
window.app_event.setProgress(time)
}
const setStop = () => {
stop()
}
const handlePlay = () => {
navigator.mediaSession.playbackState = 'playing'
}
const handlePause = () => {
navigator.mediaSession.playbackState = 'paused'
}
const handleStop = () => {
navigator.mediaSession.playbackState = 'none'
}
const handleSetPlayInfo = () => {
updateMediaSessionInfo()
updatePositionState({
position: playProgress.nowPlayTime,
duration: playProgress.maxPlayTime,
})
handlePause()
}
// const registerMediaSessionHandler = () => {
// navigator.mediaSession.setActionHandler('play', () => {
// if (this.isPlay || !this.playMusicInfo) return
// console.log('play')
// this.startPlay()
// })
// navigator.mediaSession.setActionHandler('pause', () => {
// if (!this.isPlay || !this.playMusicInfo) return
// console.log('pause')
// this.stopPlay()
// })
navigator.mediaSession.setActionHandler('stop', () => {
console.log('stop')
setStop()
})
navigator.mediaSession.setActionHandler('seekbackward', details => {
console.log('seekbackward')
const seekOffset = details.seekOffset == null ? 5 : details.seekOffset
setProgress(Math.max(getCurrentTime() - seekOffset, 0))
})
navigator.mediaSession.setActionHandler('seekforward', details => {
console.log('seekforward')
const seekOffset = details.seekOffset == null ? 5 : details.seekOffset
setProgress(Math.min(getCurrentTime() + seekOffset, getDuration()))
})
navigator.mediaSession.setActionHandler('seekto', details => {
console.log('seekto', details.seekTime)
if (details.seekTime == null) return
let time = Math.min(details.seekTime, getDuration())
time = Math.max(time, 0)
setProgress(time)
})
navigator.mediaSession.setActionHandler('previoustrack', () => {
console.log('previoustrack')
void playPrev()
})
navigator.mediaSession.setActionHandler('nexttrack', () => {
console.log('nexttrack')
void playNext()
})
// navigator.mediaSession.setActionHandler('skipad', () => {
// console.log('')
// })
// }
window.app_event.on('playerLoadeddata', updatePositionState)
window.app_event.on('playerCanplay', updatePositionState)
window.app_event.on('play', handlePlay)
window.app_event.on('pause', handlePause)
window.app_event.on('stop', handleStop)
window.app_event.on('error', handlePause)
window.app_event.on('musicToggled', handleSetPlayInfo)
window.app_event.on('picUpdated', updateMediaSessionInfo)
onBeforeUnmount(() => {
window.app_event.off('playerLoadeddata', updatePositionState)
window.app_event.off('playerCanplay', updatePositionState)
window.app_event.off('play', handlePlay)
window.app_event.off('pause', handlePause)
window.app_event.off('stop', handleStop)
window.app_event.off('error', handlePause)
window.app_event.off('musicToggled', handleSetPlayInfo)
window.app_event.off('picUpdated', updateMediaSessionInfo)
})
}
@@ -1,137 +0,0 @@
import { onBeforeUnmount, useI18n } from '@renderer/utils/vueTools'
import { player as eventPlayerNames } from '@renderer/event/names'
import { wait, waitCancel } from '@renderer/utils/tools'
import { musicInfo, musicInfoItem, playMusicInfo } from '@renderer/core/share/player'
import { setStop, isEmpty } from '@renderer/plugins/player'
export default ({
setting,
playNext,
setAllStatus,
setUrl,
}) => {
const { t } = useI18n()
let retryNum = 0
let prevTimeoutId = null
let loadingTimeout
let delayNextTimeout
const startLoadingTimeout = () => {
// console.log('start load timeout')
clearLoadingTimeout()
loadingTimeout = Math.random()
wait(25000, loadingTimeout).then(() => {
// 如果加载超时,则尝试刷新URL
if (prevTimeoutId == musicInfo.songmid) {
prevTimeoutId = null
playNext()
} else {
prevTimeoutId = musicInfo.songmid
setUrl(musicInfoItem.value, true)
}
}).catch(_ => _)
}
const clearLoadingTimeout = () => {
if (!loadingTimeout) return
// console.log('clear load timeout')
waitCancel(loadingTimeout)
loadingTimeout = null
}
const clearDelayNextTimeout = () => {
// console.log(this.delayNextTimeout)
if (!delayNextTimeout) return
waitCancel(delayNextTimeout)
delayNextTimeout = null
}
const addDelayNextTimeout = () => {
clearDelayNextTimeout()
delayNextTimeout = Math.random()
wait(5000, delayNextTimeout).then(playNext).catch(_ => _)
}
const handleLoadstart = () => {
if (global.isPlayedStop) return
if (setting.value.player.autoSkipOnError) startLoadingTimeout()
setAllStatus(t('player__loading'))
}
const handleLoadeddata = () => {
setAllStatus(t('player__loading'))
}
const handleCanplay = () => {
setAllStatus('')
}
const handlePlaying = () => {
clearLoadingTimeout()
}
const handleEmpied = () => {
clearDelayNextTimeout()
clearLoadingTimeout()
}
const handleWating = () => {
setAllStatus(t('player__buffering'))
}
const handleError = errCode => {
if (!musicInfo.songmid) return
clearLoadingTimeout()
if (global.isPlayedStop) return
if (!isEmpty()) setStop()
if (playMusicInfo.listId != 'download' && errCode !== 1 && retryNum < 2) { // 若音频URL无效则尝试刷新2次URL
// console.log(this.retryNum)
retryNum++
setUrl(musicInfoItem.value, true)
setAllStatus(t('player__refresh_url'))
return
}
if (setting.value.player.autoSkipOnError) {
if (document.hidden) {
playNext()
} else {
setAllStatus(t('player__error'))
setTimeout(addDelayNextTimeout)
}
}
}
const handleSetPlayInfo = () => {
retryNum = 0
prevTimeoutId = null
clearDelayNextTimeout()
clearLoadingTimeout()
}
const handlePlayedStop = () => {
clearDelayNextTimeout()
clearLoadingTimeout()
}
window.eventHub.on(eventPlayerNames.player_loadstart, handleLoadstart)
window.eventHub.on(eventPlayerNames.player_loadeddata, handleLoadeddata)
window.eventHub.on(eventPlayerNames.player_canplay, handleCanplay)
window.eventHub.on(eventPlayerNames.player_playing, handlePlaying)
window.eventHub.on(eventPlayerNames.player_waiting, handleWating)
window.eventHub.on(eventPlayerNames.player_emptied, handleEmpied)
window.eventHub.on(eventPlayerNames.error, handleError)
window.eventHub.on(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
window.eventHub.on(eventPlayerNames.playedStop, handlePlayedStop)
onBeforeUnmount(() => {
window.eventHub.off(eventPlayerNames.player_loadstart, handleLoadstart)
window.eventHub.off(eventPlayerNames.player_loadeddata, handleLoadeddata)
window.eventHub.off(eventPlayerNames.player_canplay, handleCanplay)
window.eventHub.off(eventPlayerNames.player_playing, handlePlaying)
window.eventHub.off(eventPlayerNames.player_waiting, handleWating)
window.eventHub.off(eventPlayerNames.player_emptied, handleEmpied)
window.eventHub.off(eventPlayerNames.error, handleError)
window.eventHub.off(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
window.eventHub.off(eventPlayerNames.playedStop, handlePlayedStop)
})
}
@@ -0,0 +1,140 @@
import { onBeforeUnmount } from '@common/utils/vueTools'
import { useI18n } from '@renderer/plugins/i18n'
import { musicInfo, playMusicInfo } from '@renderer/store/player/state'
import { setStop, isEmpty } from '@renderer/plugins/player'
import { playNext, setMusicUrl } from '@renderer/core/player'
import { setAllStatus } from '@renderer/store/player/action'
import { appSetting } from '@renderer/store/setting'
export default () => {
const t = useI18n()
let retryNum = 0
let prevTimeoutId: string | null = null
let loadingTimeout: NodeJS.Timeout | null = null
let delayNextTimeout: NodeJS.Timeout | null = null
const startLoadingTimeout = () => {
// console.log('start load timeout')
clearLoadingTimeout()
loadingTimeout = setTimeout(() => {
if (window.lx.isPlayedStop) {
prevTimeoutId = null
setAllStatus('')
return
}
// 如果加载超时,则尝试刷新URL
if (prevTimeoutId == musicInfo.id) {
prevTimeoutId = null
void playNext(true)
} else {
prevTimeoutId = musicInfo.id
if (playMusicInfo.musicInfo) setMusicUrl(playMusicInfo.musicInfo, true)
}
}, 25000)
}
const clearLoadingTimeout = () => {
if (!loadingTimeout) return
// console.log('clear load timeout')
clearTimeout(loadingTimeout)
loadingTimeout = null
}
const clearDelayNextTimeout = () => {
// console.log(this.delayNextTimeout)
if (!delayNextTimeout) return
clearTimeout(delayNextTimeout)
delayNextTimeout = null
}
const addDelayNextTimeout = () => {
clearDelayNextTimeout()
delayNextTimeout = setTimeout(() => {
if (window.lx.isPlayedStop) return setAllStatus('')
void playNext(true)
}, 5000)
}
const handleLoadstart = () => {
if (window.lx.isPlayedStop) return
if (appSetting['player.autoSkipOnError']) startLoadingTimeout()
setAllStatus(t('player__loading'))
}
const handleLoadeddata = () => {
setAllStatus(t('player__loading'))
}
const handleCanplay = () => {
setAllStatus('')
}
const handlePlaying = () => {
clearLoadingTimeout()
}
const handleEmpied = () => {
clearDelayNextTimeout()
clearLoadingTimeout()
}
const handleWating = () => {
setAllStatus(t('player__buffering'))
}
const handleError = (errCode?: number) => {
if (!musicInfo.id) return
clearLoadingTimeout()
if (window.lx.isPlayedStop) return
if (!isEmpty()) setStop()
if (playMusicInfo.musicInfo && errCode !== 1 && retryNum < 2) { // 若音频URL无效则尝试刷新2次URL
// console.log(this.retryNum)
retryNum++
setMusicUrl(playMusicInfo.musicInfo, true)
setAllStatus(t('player__refresh_url'))
return
}
if (appSetting['player.autoSkipOnError']) {
if (document.hidden) {
console.warn('error skip to next')
void playNext(true)
} else {
setAllStatus(t('player__error'))
setTimeout(addDelayNextTimeout)
}
}
}
const handleSetPlayInfo = () => {
retryNum = 0
prevTimeoutId = null
clearDelayNextTimeout()
clearLoadingTimeout()
}
// const handlePlayedStop = () => {
// clearDelayNextTimeout()
// clearLoadingTimeout()
// }
window.app_event.on('playerLoadstart', handleLoadstart)
window.app_event.on('playerLoadeddata', handleLoadeddata)
window.app_event.on('playerCanplay', handleCanplay)
window.app_event.on('playerPlaying', handlePlaying)
window.app_event.on('playerWaiting', handleWating)
window.app_event.on('playerEmptied', handleEmpied)
window.app_event.on('playerError', handleError)
window.app_event.on('musicToggled', handleSetPlayInfo)
onBeforeUnmount(() => {
window.app_event.off('playerLoadstart', handleLoadstart)
window.app_event.off('playerLoadeddata', handleLoadeddata)
window.app_event.off('playerCanplay', handleCanplay)
window.app_event.off('playerPlaying', handlePlaying)
window.app_event.off('playerWaiting', handleWating)
window.app_event.off('playerEmptied', handleEmpied)
window.app_event.off('playerError', handleError)
window.app_event.off('musicToggled', handleSetPlayInfo)
})
}
@@ -1,55 +1,66 @@
import { onBeforeUnmount, watch, useCommit } from '@renderer/utils/vueTools'
import { formatPlayTime2, getRandom, throttle } from '@renderer/utils'
import { setTaskBarProgress, wait, waitCancel, savePlayInfo } from '@renderer/utils/tools'
import { player as eventPlayerNames } from '@renderer/event/names'
import { onBeforeUnmount, watch } from '@common/utils/vueTools'
import { formatPlayTime2, getRandom } from '@common/utils/common'
import { throttle } from '@common/utils'
import { setTaskBarProgress, savePlayInfo } from '@renderer/utils/ipc'
import { onTimeupdate, getCurrentTime, getDuration, setCurrentTime, onVisibilityChange } from '@renderer/plugins/player'
import { playProgress, setNowPlayTime, setMaxplayTime } from '@renderer/core/share/playProgress'
import { musicInfo, musicInfoItem, playMusicInfo, playInfo } from '@renderer/core/share/player'
// import { getList } from '@renderer/core/share/utils'
import { playProgress, setNowPlayTime, setMaxplayTime } from '@renderer/store/player/playProgress'
import { musicInfo, playMusicInfo, playInfo } from '@renderer/store/player/state'
// import { getList } from '@renderer/store/utils'
import { appSetting } from '@renderer/store/setting'
import { playNext } from '@renderer/core/player'
import { updateListMusics } from '@renderer/store/list/action'
const delaySavePlayInfo = throttle(savePlayInfo, 2000)
export default ({ setting, playNext }) => {
export default () => {
let restorePlayTime = 0
let prevProgressStatus = 'none'
const mediaBuffer = {
let prevProgressStatus: Electron.ProgressBarOptions['mode'] = 'none'
const mediaBuffer: {
timeout: NodeJS.Timeout | null
playTime: number
} = {
timeout: null,
playTime: 0,
}
const updateMusicInfo = useCommit('list', 'updateMusicInfo')
// const updateMusicInfo = useCommit('list', 'updateMusicInfo')
const startBuffering = () => {
console.log('start t')
if (mediaBuffer.timeout) return
mediaBuffer.timeout = Math.random()
wait(3000, mediaBuffer.timeout).then(() => {
mediaBuffer.timeout = setTimeout(() => {
mediaBuffer.timeout = null
if (window.lx.isPlayedStop) return
const currentTime = getCurrentTime()
if (!mediaBuffer.playTime) mediaBuffer.playTime = currentTime
let skipTime = currentTime + getRandom(3, 6)
if (skipTime > playProgress.maxPlayTime) skipTime = (playProgress.maxPlayTime - currentTime) / 2
if (skipTime - mediaBuffer.playTime < 1 || playProgress.maxPlayTime - skipTime < 1) {
mediaBuffer.playTime = 0
if (setting.value.player.autoSkipOnError) playNext()
if (appSetting['player.autoSkipOnError']) {
console.warn('buffering end')
void playNext(true)
}
return
}
startBuffering()
setCurrentTime(skipTime)
console.log(mediaBuffer.playTime)
console.log(currentTime)
}).catch(_ => _)
}, 3000)
}
const clearBufferTimeout = () => {
console.log('clear t')
if (!mediaBuffer.timeout) return
waitCancel(mediaBuffer.timeout)
clearTimeout(mediaBuffer.timeout)
mediaBuffer.timeout = null
mediaBuffer.playTime = 0
}
const setProgress = (time) => {
if (!musicInfo.songmid) return
const setProgress = (time: number, maxTime?: number) => {
if (!musicInfo.id) return
console.log('setProgress', time, maxTime)
restorePlayTime = time
if (mediaBuffer.playTime) {
clearBufferTimeout()
@@ -59,11 +70,13 @@ export default ({ setting, playNext }) => {
setNowPlayTime(time)
setCurrentTime(time)
if (maxTime != null) setMaxplayTime(maxTime)
// if (!isPlay) audio.play()
}
const handleSetTaskBarState = (progress, status) => {
if (setting.value.player.isShowTaskProgess) setTaskBarProgress(progress, status)
const handleSetTaskBarState = (progress: number, status?: Electron.ProgressBarOptions['mode']) => {
if (appSetting['player.isShowTaskProgess']) setTaskBarProgress(progress, status)
}
const handlePlay = () => {
@@ -85,6 +98,7 @@ export default ({ setting, playNext }) => {
const handleError = () => {
if (!restorePlayTime) restorePlayTime = getCurrentTime() // 记录出错的播放时间
console.log('handleError')
prevProgressStatus = 'error'
handleSetTaskBarState(playProgress.progress, prevProgressStatus)
}
@@ -92,22 +106,30 @@ export default ({ setting, playNext }) => {
const handleLoadeddata = () => {
setMaxplayTime(getDuration())
console.log('handleLoadeddata', restorePlayTime)
if (restorePlayTime) {
setCurrentTime(restorePlayTime)
restorePlayTime = 0
}
if (!musicInfoItem.value.interval && playMusicInfo.listId != 'download') {
updateMusicInfo({
listId: playMusicInfo.listId,
id: musicInfo.songmid,
musicInfo: musicInfoItem.value,
data: { interval: formatPlayTime2(playProgress.maxPlayTime) },
})
if (playMusicInfo.musicInfo && 'source' in playMusicInfo.musicInfo && !playMusicInfo.musicInfo.interval) {
console.log(formatPlayTime2(playProgress.maxPlayTime))
if (playMusicInfo.listId) {
void updateListMusics([{
id: playMusicInfo.listId,
musicInfo: {
...playMusicInfo.musicInfo,
interval: formatPlayTime2(playProgress.maxPlayTime),
},
}])
}
}
}
const handleCanplay = () => {
console.log('handleCanplay', mediaBuffer.playTime)
clearBufferTimeout()
if (mediaBuffer.playTime) {
let playTime = mediaBuffer.playTime
mediaBuffer.playTime = 0
@@ -123,11 +145,12 @@ export default ({ setting, playNext }) => {
clearBufferTimeout()
}
const handleSetPlayInfo = ({ musicInfo, progress }) => {
setNowPlayTime(restorePlayTime = progress.time)
setMaxplayTime(progress.maxTime)
const handleSetPlayInfo = () => {
// restorePlayTime = playProgress.nowPlayTime
setCurrentTime(restorePlayTime = playProgress.nowPlayTime)
// setMaxplayTime(playProgress.maxPlayTime)
handlePause()
if (!playMusicInfo.isTempPlay) {
if (!playMusicInfo.isTempPlay && playMusicInfo.listId) {
delaySavePlayInfo({
time: playProgress.nowPlayTime,
maxTime: playProgress.maxPlayTime,
@@ -142,12 +165,12 @@ export default ({ setting, playNext }) => {
handleSetTaskBarState(newValue, prevProgressStatus)
})
watch(() => playProgress.nowPlayTime, (newValue, oldValue) => {
if (Math.abs(newValue - oldValue) > 2) window.eventHub.emit(eventPlayerNames.activeTransition)
if (setting.value.player.isSavePlayTime && !playMusicInfo.isTempPlay) {
if (Math.abs(newValue - oldValue) > 2) window.app_event.activePlayProgressTransition()
if (appSetting['player.isSavePlayTime'] && !playMusicInfo.isTempPlay) {
delaySavePlayInfo({
time: newValue,
maxTime: playProgress.maxPlayTime,
listId: playMusicInfo.listId,
listId: playMusicInfo.listId as string,
index: playInfo.playIndex,
})
}
@@ -157,23 +180,23 @@ export default ({ setting, playNext }) => {
delaySavePlayInfo({
time: playProgress.nowPlayTime,
maxTime: maxPlayTime,
listId: playMusicInfo.listId,
listId: playMusicInfo.listId as string,
index: playInfo.playIndex,
})
}
})
window.eventHub.on(eventPlayerNames.play, handlePlay)
window.eventHub.on(eventPlayerNames.pause, handlePause)
window.eventHub.on(eventPlayerNames.stop, handleStop)
window.eventHub.on(eventPlayerNames.error, handleError)
window.eventHub.on(eventPlayerNames.setProgress, setProgress)
// window.eventHub.on(eventPlayerNames.restorePlay, handleRestorePlay)
window.eventHub.on(eventPlayerNames.player_loadeddata, handleLoadeddata)
window.eventHub.on(eventPlayerNames.player_canplay, handleCanplay)
window.eventHub.on(eventPlayerNames.player_waiting, handleWating)
window.eventHub.on(eventPlayerNames.player_emptied, handleEmpied)
window.eventHub.on(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
window.app_event.on('play', handlePlay)
window.app_event.on('pause', handlePause)
window.app_event.on('stop', handleStop)
window.app_event.on('error', handleError)
window.app_event.on('setProgress', setProgress)
// window.app_event.on(eventPlayerNames.restorePlay, handleRestorePlay)
window.app_event.on('playerLoadeddata', handleLoadeddata)
window.app_event.on('playerCanplay', handleCanplay)
window.app_event.on('playerWaiting', handleWating)
window.app_event.on('playerEmptied', handleEmpied)
window.app_event.on('musicToggled', handleSetPlayInfo)
const rOnTimeupdate = onTimeupdate(() => {
setNowPlayTime(getCurrentTime())
@@ -185,7 +208,7 @@ export default ({ setting, playNext }) => {
currentPlayTime = playProgress.nowPlayTime
} else {
if (Math.abs(playProgress.nowPlayTime - currentPlayTime) > 2) {
window.eventHub.emit(eventPlayerNames.activeTransition)
window.app_event.activePlayProgressTransition()
}
}
})
@@ -193,16 +216,16 @@ export default ({ setting, playNext }) => {
onBeforeUnmount(() => {
rOnTimeupdate()
rVisibilityChange()
window.eventHub.off(eventPlayerNames.play, handlePlay)
window.eventHub.off(eventPlayerNames.pause, handlePause)
window.eventHub.off(eventPlayerNames.stop, handleStop)
window.eventHub.off(eventPlayerNames.error, handleError)
window.eventHub.off(eventPlayerNames.setProgress, setProgress)
// window.eventHub.off(eventPlayerNames.restorePlay, handleRestorePlay)
window.eventHub.off(eventPlayerNames.player_loadeddata, handleLoadeddata)
window.eventHub.off(eventPlayerNames.player_canplay, handleCanplay)
window.eventHub.off(eventPlayerNames.player_waiting, handleWating)
window.eventHub.off(eventPlayerNames.player_emptied, handleEmpied)
window.eventHub.off(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
window.app_event.off('play', handlePlay)
window.app_event.off('pause', handlePause)
window.app_event.off('stop', handleStop)
window.app_event.off('error', handleError)
window.app_event.off('setProgress', setProgress)
// window.app_event.off(eventPlayerNames.restorePlay, handleRestorePlay)
window.app_event.off('playerLoadeddata', handleLoadeddata)
window.app_event.off('playerCanplay', handleCanplay)
window.app_event.off('playerWaiting', handleWating)
window.app_event.off('playerEmptied', handleEmpied)
window.app_event.off('musicToggled', handleSetPlayInfo)
})
}
@@ -0,0 +1,135 @@
import { onBeforeUnmount } from '@common/utils/vueTools'
import { setPlayerAction, onPlayerAction } from '@renderer/utils/ipc'
// import store from '@renderer/store'
import { loveList } from '@renderer/store/list/state'
import { addListMusics, removeListMusics, checkListExistMusic } from '@renderer/store/list/action'
import { playMusicInfo } from '@renderer/store/player/state'
import { throttle } from '@common/utils'
import { pause, play, playNext, playPrev } from '@renderer/core/player'
export default () => {
// const setVisibleDesktopLyric = useCommit('setVisibleDesktopLyric')
// const setLockDesktopLyric = useCommit('setLockDesktopLyric')
const buttons = {
empty: true,
collect: false,
play: false,
prev: true,
next: true,
lrc: false,
lockLrc: false,
}
const setButtons = () => {
setPlayerAction(buttons)
}
const updateCollectStatus = async() => {
let status = !!playMusicInfo.musicInfo && await checkListExistMusic(loveList.id, playMusicInfo.musicInfo.id)
if (buttons.collect == status) return false
buttons.collect = status
return true
}
const handlePlay = () => {
if (buttons.empty) buttons.empty = false
buttons.play = true
setButtons()
}
const handlePause = () => {
if (buttons.empty) buttons.empty = false
buttons.play = false
setButtons()
}
const handleStop = () => {
if (playMusicInfo.musicInfo != null) return
if (buttons.collect) buttons.collect = false
buttons.empty = true
setButtons()
}
const handleSetPlayInfo = () => {
void updateCollectStatus().then(isExist => {
if (isExist) setButtons()
})
}
// const handleSetTaskbarThumbnailClip = (clip) => {
// setTaskbarThumbnailClip(clip)
// }
const throttleListChange = throttle(async listIds => {
if (!listIds.includes(loveList.id)) return
if (await updateCollectStatus()) setButtons()
})
// const updateSetting = () => {
// const setting = store.getters.setting
// buttons.lrc = setting.desktopLyric.enable
// buttons.lockLrc = setting.desktopLyric.isLock
// setButtons()
// }
const rTaskbarThumbarClick = onPlayerAction(async({ params: action }) => {
switch (action) {
case 'play':
play()
break
case 'pause':
pause()
break
case 'prev':
void playPrev()
break
case 'next':
void playNext()
break
case 'collect':
if (!playMusicInfo.musicInfo) return
void addListMusics(loveList.id, ['progress' in playMusicInfo.musicInfo ? playMusicInfo.musicInfo.metadata.musicInfo : playMusicInfo.musicInfo])
if (await updateCollectStatus()) setButtons()
break
case 'unCollect':
if (!playMusicInfo.musicInfo) return
void removeListMusics({ listId: loveList.id, ids: ['progress' in playMusicInfo.musicInfo ? playMusicInfo.musicInfo.metadata.musicInfo.id : playMusicInfo.musicInfo.id] })
if (await updateCollectStatus()) setButtons()
break
// case 'lrc':
// setVisibleDesktopLyric(true)
// updateSetting()
// break
// case 'unLrc':
// setVisibleDesktopLyric(false)
// updateSetting()
// break
// case 'lockLrc':
// setLockDesktopLyric(true)
// updateSetting()
// break
// case 'unlockLrc':
// setLockDesktopLyric(false)
// updateSetting()
// break
}
})
window.app_event.on('play', handlePlay)
window.app_event.on('pause', handlePause)
window.app_event.on('stop', handleStop)
window.app_event.on('musicToggled', handleSetPlayInfo)
// window.app_event.on(eventTaskbarNames.setTaskbarThumbnailClip, handleSetTaskbarThumbnailClip)
window.app_event.on('myListUpdate', throttleListChange)
onBeforeUnmount(() => {
rTaskbarThumbarClick()
window.app_event.off('play', handlePlay)
window.app_event.off('pause', handlePause)
window.app_event.off('stop', handleStop)
window.app_event.off('musicToggled', handleSetPlayInfo)
// window.app_event.off(eventTaskbarNames.setTaskbarThumbnailClip, handleSetTaskbarThumbnailClip)
window.app_event.off('myListUpdate', throttleListChange)
})
return async() => {
// const setting = store.getters.setting
// buttons.lrc = setting.desktopLyric.enable
// buttons.lockLrc = setting.desktopLyric.isLock
await updateCollectStatus()
if (playMusicInfo.musicInfo != null) buttons.empty = false
setButtons()
}
}
@@ -1,404 +0,0 @@
import { onBeforeUnmount, useI18n, watch, useCommit, useAction } from '@renderer/utils/vueTools'
import { setTitle, checkPath } from '@renderer/utils'
import { langS2T, wait, waitCancel } from '@renderer/utils/tools'
import {
setStop as setPlayerStop,
setPause as setPlayerPause,
setPlay as setPlayerPlay,
setResource,
isEmpty as isPlayerEmpty,
setLoopPlay,
} from '@renderer/plugins/player'
import { player as eventKeyPlayerNames } from '@common/hotKey'
import { player as eventPlayerNames } from '@renderer/event/names'
import useMediaSessionInfo from './useMediaSessionInfo'
import usePlayProgress from './usePlayProgress'
import usePlayEvent from './usePlayEvent'
import { requestMsg } from '@renderer/utils/message'
import {
isPlay,
setPlay,
setAllStatus,
musicInfo,
setMusicInfo,
musicInfoItem,
playMusicInfo,
setPlayList,
setPlayMusicInfo,
playedList,
} from '@renderer/core/share/player'
import { downloadList } from '@renderer/core/share/download'
import { qualityList } from '@renderer/core/share'
import { getList } from '@renderer/core/share/utils'
import path from 'path'
import useLyric from './useLyric'
import useVolume from './useVolume'
import useWatchList from './useWatchList'
const getPlayType = (highQuality, songInfo) => {
let type = '128k'
let list = qualityList.value[songInfo.source]
if (highQuality && songInfo._types['320k'] && list && list.includes('320k')) type = '320k'
return type
}
const useDelayNextTimeout = ({ playNext, timeout }) => {
let delayNextTimeout
const clearDelayNextTimeout = () => {
// console.log(this.delayNextTimeout)
if (delayNextTimeout) {
waitCancel(delayNextTimeout)
delayNextTimeout = null
}
}
const addDelayNextTimeout = () => {
clearDelayNextTimeout()
delayNextTimeout = Math.random()
wait(timeout, delayNextTimeout).then(() => {
delayNextTimeout = null
playNext()
}).catch(_ => _)
}
return {
clearDelayNextTimeout,
addDelayNextTimeout,
}
}
export default ({ setting }) => {
const { t } = useI18n()
const playNext = useAction('player', 'playNext')
const playPrev = useAction('player', 'playPrev')
const getUrl = useAction('player', 'getUrl')
const getPic = useAction('player', 'getPic')
const getLrc = useAction('player', 'getLrc')
const clearPlayedList = useCommit('player', 'clearPlayedList')
const setPlayedList = useCommit('player', 'setPlayedList')
const { addDelayNextTimeout, clearDelayNextTimeout } = useDelayNextTimeout({ playNext, timeout: 5000 })
const { addDelayNextTimeout: addLoadTimeout, clearDelayNextTimeout: clearLoadTimeout } = useDelayNextTimeout({ playNext, timeout: 123000 })
let isGettingUrl = false
const setUrl = (targetSong, isRefresh, isRetryed = false) => {
let type = getPlayType(setting.value.player.highQuality, targetSong)
// this.musicInfo.url = await getMusicUrl(targetSong, type)
setAllStatus(t('player__geting_url'))
if (setting.value.player.autoSkipOnError) addLoadTimeout()
isGettingUrl = true
return getUrl({
musicInfo: targetSong,
type,
isRefresh,
onToggleSource() {
if (targetSong !== musicInfoItem.value || isPlay.value || type != getPlayType(setting.value.player.highQuality, musicInfoItem.value)) return
setAllStatus('Try toggle source...')
},
}).then(url => {
if (global.isPlayedStop) return
if (targetSong !== musicInfoItem.value || isPlay.value || type != getPlayType(setting.value.player.highQuality, musicInfoItem.value)) return
setMusicInfo({ url })
setResource(url)
}).catch(err => {
// console.log('err', err.message)
if (global.isPlayedStop) return
if (targetSong !== musicInfoItem.value || isPlay.value) return
if (err.message == requestMsg.cancelRequest) return
if (!isRetryed) return setUrl(targetSong, isRefresh, true)
setAllStatus(err.message)
if (setting.value.player.autoSkipOnError) addDelayNextTimeout()
return Promise.reject(err)
}).finally(() => {
clearLoadTimeout()
if (targetSong === musicInfoItem.value) isGettingUrl = false
})
}
const setImg = ({ listId, musicInfo: targetSong }) => {
if (targetSong.img) {
setMusicInfo({ img: targetSong.img })
} else {
getPic({ musicInfo: targetSong, listId }).then(() => {
if (targetSong.songmid !== musicInfo.songmid) return
setMusicInfo({ img: targetSong.img })
window.eventHub.emit(eventPlayerNames.updatePic, musicInfo)
})
}
}
const setLrc = (targetSong) => {
getLrc(targetSong).then(({ lyric, tlyric, rlyric, lxlyric, rawInfo }) => {
if (targetSong.songmid !== musicInfo.songmid) return
return (
setting.value.player.isS2t
? Promise.all([
lyric ? langS2T(lyric) : Promise.resolve(''),
tlyric ? langS2T(tlyric) : Promise.resolve(''),
rlyric ? langS2T(rlyric) : Promise.resolve(''),
lxlyric ? langS2T(lxlyric) : Promise.resolve(''),
])
: Promise.resolve([lyric, tlyric, rlyric, lxlyric])
).then(([lyric, tlyric, rlyric, lxlyric]) => {
setMusicInfo({
lrc: lyric,
tlrc: tlyric,
rlrc: rlyric,
lxlrc: lxlyric,
rawlrc: rawInfo.lyric,
})
})
}).catch((err) => {
console.log(err)
if (targetSong.songmid !== musicInfo.songmid) return
setAllStatus(t('lyric__load_error'))
}).finally(() => {
if (targetSong.songmid !== musicInfo.songmid) return
window.eventHub.emit(eventPlayerNames.updateLyric, musicInfo)
})
}
usePlayProgress({ setting, playNext })
useMediaSessionInfo({ playPrev, playNext })
usePlayEvent({
setting,
playNext,
setAllStatus,
setUrl,
})
useLyric({
setting,
})
useVolume({ setting })
useWatchList({ playNext })
// 恢复上次播放的状态
const handleRestorePlay = async(restorePlayInfo) => {
if (!restorePlayInfo.listId) return
const list = getList(restorePlayInfo.listId)
setPlayList(restorePlayInfo.listId)
setPlayMusicInfo(restorePlayInfo.listId, list[restorePlayInfo.index])
window.eventHub.emit(eventPlayerNames.setPlayInfo, {
musicInfo: musicInfoItem.value,
progress: {
time: setting.value.player.isSavePlayTime ? (restorePlayInfo.time || 0) : 0,
maxTime: restorePlayInfo.maxTime || 0,
},
})
setImg({ musicInfo: musicInfoItem.value, listId: playMusicInfo.listId })
setLrc(musicInfoItem.value)
if (setting.value.player.togglePlayMethod == 'random') setPlayedList({ ...playMusicInfo })
}
const setPlayStatus = () => {
setPlay(true)
}
const setPauseStatus = () => {
setPlay(false)
if (global.isPlayedStop) handlePause()
}
const setStopStatus = () => {
setPlay(false)
setTitle()
setAllStatus('')
setMusicInfo({
songmid: null,
img: null,
lrc: null,
tlrc: null,
rlrc: null,
lxlrc: null,
rawlrc: null,
url: null,
name: '',
singer: '',
album: '',
})
}
// 播放音乐
const playMusic = async() => {
// console.log('playMusic')
isGettingUrl = false
setStopStatus()
if (window.restorePlayInfo) {
handleRestorePlay(window.restorePlayInfo)
window.restorePlayInfo = null
return
}
if (playMusicInfo.musicInfo) {
setPlayerStop()
window.eventHub.emit(eventPlayerNames.pause)
setStopStatus()
} else {
window.eventHub.emit(eventPlayerNames.setStop)
}
clearDelayNextTimeout()
let targetSong = playMusicInfo.musicInfo
if (setting.value.player.togglePlayMethod == 'random' && !playMusicInfo.isTempPlay) setPlayedList({ ...playMusicInfo })
if (targetSong.key) { // 如果是已下载的歌曲
const filePath = path.join(setting.value.download.savePath, targetSong.metadata.fileName)
// console.log(filePath)
if (!await checkPath(filePath) || !targetSong.isComplate || /\.ape$/.test(filePath)) {
return getList(playMusicInfo.listId).length == 1 ? null : playNext()
}
window.eventHub.emit(eventPlayerNames.setPlayInfo, {
musicInfo: musicInfoItem.value,
progress: {
time: 0,
maxTime: 0,
},
})
setResource(filePath)
// console.log(filePath)
} else {
// if (!this.assertApiSupport(targetSong.source)) return this.playNext()
window.eventHub.emit(eventPlayerNames.setPlayInfo, {
musicInfo: musicInfoItem.value,
progress: {
time: 0,
maxTime: 0,
},
})
setUrl(musicInfoItem.value)
}
setImg({ musicInfo: musicInfoItem.value, listId: playMusicInfo.listId })
setLrc(musicInfoItem.value)
}
const handleSetPlayInfo = ({ musicInfo }) => {
setMusicInfo({
songmid: musicInfo.songmid,
singer: musicInfo.singer,
name: musicInfo.name,
album: musicInfo.albumName,
})
setTitle(`${musicInfo.name} - ${musicInfo.singer}`)
}
const handelStop = () => {
setPlayerStop()
setPlayMusicInfo(playMusicInfo.listId, null)
window.eventHub.emit(eventPlayerNames.stop)
}
const handleEnded = () => {
setAllStatus(t('player__end'))
if (global.isPlayedStop) return
playNext()
}
const handlePause = () => {
setPlayerPause()
}
const handlePlay = async() => {
if (playMusicInfo.musicInfo == null) return
if (isPlayerEmpty()) {
if (playMusicInfo.listId == 'download') {
const musicInfo = playMusicInfo.musicInfo
const filePath = path.join(setting.value.download.savePath, musicInfo.metadata.fileName)
if (!await checkPath(filePath) || !musicInfo.isComplate || /\.ape$/.test(filePath)) {
if (downloadList.length == 1) {
window.eventHub.emit(eventPlayerNames.setStop)
} else {
playNext()
}
return
}
if (!isGettingUrl) setResource(filePath)
} else {
// if (!this.assertApiSupport(this.targetSong.source)) return this.playNext()
if (!isGettingUrl) setUrl(musicInfoItem.value)
}
return
}
setPlayerPlay()
}
// 播放、暂停播放切换
const handleTogglePlay = () => {
if (global.isPlayedStop) global.isPlayedStop = false
if (isPlay.value) {
handlePause()
} else {
handlePlay()
}
}
const handlePlayedStop = () => {
clearDelayNextTimeout()
clearLoadTimeout()
}
watch(() => setting.value.player.togglePlayMethod, newValue => {
setLoopPlay(newValue === 'singleLoop')
if (playedList.length) clearPlayedList()
if (newValue == 'random' && playMusicInfo.musicInfo && !playMusicInfo.isTempPlay) setPlayedList({ ...playMusicInfo })
})
setLoopPlay(setting.value.player.togglePlayMethod === 'singleLoop')
window.eventHub.on(eventKeyPlayerNames.next.action, playNext)
window.eventHub.on(eventKeyPlayerNames.prev.action, playPrev)
window.eventHub.on(eventKeyPlayerNames.toggle_play.action, handleTogglePlay)
window.eventHub.on(eventPlayerNames.play, setPlayStatus)
window.eventHub.on(eventPlayerNames.pause, setPauseStatus)
window.eventHub.on(eventPlayerNames.error, setPauseStatus)
window.eventHub.on(eventPlayerNames.stop, setStopStatus)
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.setPlayPrev, playPrev)
window.eventHub.on(eventPlayerNames.setPlayNext, playNext)
window.eventHub.on(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
window.eventHub.on(eventPlayerNames.player_ended, handleEnded)
window.eventHub.on(eventPlayerNames.playedStop, handlePlayedStop)
onBeforeUnmount(() => {
window.eventHub.off(eventKeyPlayerNames.next.action, playNext)
window.eventHub.off(eventKeyPlayerNames.prev.action, playPrev)
window.eventHub.off(eventKeyPlayerNames.toggle_play.action, handleTogglePlay)
window.eventHub.off(eventPlayerNames.play, setPlayStatus)
window.eventHub.off(eventPlayerNames.pause, setPauseStatus)
window.eventHub.off(eventPlayerNames.error, setPauseStatus)
window.eventHub.off(eventPlayerNames.stop, setStopStatus)
window.eventHub.off(eventPlayerNames.playMusic, playMusic)
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.setPlayNext, playNext)
window.eventHub.off(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
window.eventHub.off(eventPlayerNames.player_ended, handleEnded)
window.eventHub.off(eventPlayerNames.playedStop, handlePlayedStop)
})
}
@@ -0,0 +1,125 @@
import { onBeforeUnmount, watch } from '@common/utils/vueTools'
import { useI18n } from '@renderer/plugins/i18n'
import { setTitle } from '@renderer/utils'
import {
setLoopPlay, setPause, setStop,
} from '@renderer/plugins/player'
import useMediaSessionInfo from './useMediaSessionInfo'
import usePlayProgress from './usePlayProgress'
import usePlayEvent from './usePlayEvent'
import {
musicInfo,
playMusicInfo,
playedList,
} from '@renderer/store/player/state'
import {
setPlay,
setAllStatus,
addPlayedList,
clearPlayedList,
resetPlayerMusicInfo,
} from '@renderer/store/player/action'
import { appSetting } from '@renderer/store/setting'
import useLyric from './useLyric'
import useVolume from './useVolume'
import useWatchList from './useWatchList'
import { HOTKEY_PLAYER } from '@common/hotKey'
import { playNext, pause, playPrev, togglePlay } from '@renderer/core/player'
export default () => {
const t = useI18n()
usePlayProgress()
useMediaSessionInfo()
usePlayEvent()
useLyric()
useVolume()
useWatchList()
const handlePlayNext = () => {
void playNext()
}
const handlePlayPrev = () => {
void playPrev()
}
const setPlayStatus = () => {
setPlay(true)
}
const setPauseStatus = () => {
setPlay(false)
if (window.lx.isPlayedStop) pause()
}
const handleUpdatePlayInfo = () => {
setTitle(musicInfo.id ? `${musicInfo.name} - ${musicInfo.singer}` : null)
}
const handleCanplay = () => {
if (window.lx.isPlayedStop) {
setPause()
}
}
const handleEnded = () => {
// setTimeout(() => {
if (window.lx.isPlayedStop) return setAllStatus(t('player__end'))
resetPlayerMusicInfo()
window.app_event.stop()
setAllStatus(t('player__end'))
void playNext(true)
// })
}
const setStopStatus = () => {
setPlay(false)
setTitle(null)
setAllStatus('')
setStop()
}
watch(() => appSetting['player.togglePlayMethod'], newValue => {
setLoopPlay(newValue == 'singleLoop')
if (playedList.length) clearPlayedList()
if (newValue == 'random' && playMusicInfo.musicInfo && !playMusicInfo.isTempPlay) addPlayedList({ ...(playMusicInfo as LX.Player.PlayMusicInfo) })
})
setLoopPlay(appSetting['player.togglePlayMethod'] == 'singleLoop')
window.key_event.on(HOTKEY_PLAYER.next.action, handlePlayNext)
window.key_event.on(HOTKEY_PLAYER.prev.action, handlePlayPrev)
window.key_event.on(HOTKEY_PLAYER.toggle_play.action, togglePlay)
window.app_event.on('play', setPlayStatus)
window.app_event.on('pause', setPauseStatus)
window.app_event.on('error', setPauseStatus)
window.app_event.on('stop', setStopStatus)
window.app_event.on('musicToggled', handleUpdatePlayInfo)
window.app_event.on('playerCanplay', handleCanplay)
window.app_event.on('playerEnded', handleEnded)
onBeforeUnmount(() => {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
window.key_event.off(HOTKEY_PLAYER.next.action, handlePlayNext)
// eslint-disable-next-line @typescript-eslint/no-misused-promises
window.key_event.off(HOTKEY_PLAYER.prev.action, handlePlayPrev)
window.key_event.off(HOTKEY_PLAYER.toggle_play.action, togglePlay)
window.app_event.off('play', setPlayStatus)
window.app_event.off('pause', setPauseStatus)
window.app_event.off('error', setPauseStatus)
window.app_event.off('stop', setStopStatus)
window.app_event.off('musicToggled', handleUpdatePlayInfo)
window.app_event.on('playerCanplay', handleCanplay)
window.app_event.off('playerEnded', handleEnded)
})
}
@@ -1,74 +0,0 @@
import { onBeforeUnmount } from '@renderer/utils/vueTools'
import {
onPlaying,
onPause,
onEnded,
onError,
onLoadeddata,
onLoadstart,
onCanplay,
onEmptied,
onWaiting,
getErrorCode,
} from '@renderer/plugins/player'
import { player } from '@renderer/event/names'
export default () => {
const rOnPlaying = onPlaying(() => {
// console.log('onPlaying')
window.eventHub.emit(player.player_playing)
window.eventHub.emit(player.play)
})
const rOnPause = onPause(() => {
// console.log('onPause')
window.eventHub.emit(player.player_pause)
window.eventHub.emit(player.pause)
})
const rOnEnded = onEnded(() => {
// console.log('onEnded')
window.eventHub.emit(player.player_ended)
window.eventHub.emit(player.pause)
})
const rOnError = onError(() => {
// console.log('onError')
const errorCode = getErrorCode()
window.eventHub.emit(player.player_error, errorCode)
window.eventHub.emit(player.error, errorCode)
})
const rOnLoadeddata = onLoadeddata(() => {
// console.log('onLoadeddata')
window.eventHub.emit(player.player_loadeddata)
})
const rOnLoadstart = onLoadstart(() => {
// console.log('onLoadstart')
window.eventHub.emit(player.player_loadstart)
})
const rOnCanplay = onCanplay(() => {
// console.log('onCanplay')
window.eventHub.emit(player.player_canplay)
})
const rOnEmptied = onEmptied(() => {
// console.log('onEmptied')
window.eventHub.emit(player.player_emptied)
// window.eventHub.emit(player.stop)
})
const rOnWaiting = onWaiting(() => {
// console.log('onWaiting')
window.eventHub.emit(player.player_waiting)
window.eventHub.emit(player.pause)
})
onBeforeUnmount(() => {
rOnPlaying()
rOnPause()
rOnEnded()
rOnError()
rOnLoadeddata()
rOnLoadstart()
rOnCanplay()
rOnEmptied()
rOnWaiting()
})
}
@@ -0,0 +1,73 @@
import { onBeforeUnmount } from '@common/utils/vueTools'
import {
onPlaying,
onPause,
onEnded,
onError,
onLoadeddata,
onLoadstart,
onCanplay,
onEmptied,
onWaiting,
getErrorCode,
} from '@renderer/plugins/player'
export default () => {
const rOnPlaying = onPlaying(() => {
console.log('onPlaying')
window.app_event.playerPlaying()
window.app_event.play()
})
const rOnPause = onPause(() => {
console.log('onPause')
window.app_event.playerPause()
window.app_event.pause()
})
const rOnEnded = onEnded(() => {
console.log('onEnded')
window.app_event.playerEnded()
// window.app_event.pause()
})
const rOnError = onError(() => {
console.log('onError')
const errorCode = getErrorCode()
window.app_event.error(errorCode)
window.app_event.playerError(errorCode)
})
const rOnLoadeddata = onLoadeddata(() => {
console.log('onLoadeddata')
window.app_event.playerLoadeddata()
})
const rOnLoadstart = onLoadstart(() => {
console.log('onLoadstart')
window.app_event.playerLoadstart()
})
const rOnCanplay = onCanplay(() => {
console.log('onCanplay')
window.app_event.playerCanplay()
})
const rOnEmptied = onEmptied(() => {
console.log('onEmptied')
window.app_event.playerEmptied()
// window.app_event.stop()
})
const rOnWaiting = onWaiting(() => {
console.log('onWaiting')
window.app_event.pause()
window.app_event.playerWaiting()
})
onBeforeUnmount(() => {
rOnPlaying()
rOnPause()
rOnEnded()
rOnError()
rOnLoadeddata()
rOnLoadstart()
rOnCanplay()
rOnEmptied()
rOnWaiting()
})
}
@@ -1,136 +0,0 @@
import { onBeforeUnmount, useCommit } from '@renderer/utils/vueTools'
import { player as eventPlayerNames, taskbar as eventTaskbarNames, list as eventListNames } from '@renderer/event/names'
import { onTaskbarThumbarClick, setTaskbarThumbnailClip, setTaskbarThumbarButtons } from '@renderer/utils/tools'
// import store from '@renderer/store'
import { loveList, getList } from '@renderer/core/share/list'
import { playMusicInfo, musicInfoItem } from '@renderer/core/share/player'
import { throttle } from '@renderer/utils'
export default () => {
const listAdd = useCommit('list', 'listAdd')
const listRemove = useCommit('list', 'listRemove')
// const setVisibleDesktopLyric = useCommit('setVisibleDesktopLyric')
// const setLockDesktopLyric = useCommit('setLockDesktopLyric')
const buttons = {
empty: true,
collect: false,
play: false,
prev: true,
next: true,
lrc: false,
lockLrc: false,
}
const setButtons = () => {
setTaskbarThumbarButtons(buttons)
}
const updateCollectStatus = () => {
let status = !!playMusicInfo.musicInfo && getList(loveList.id).some(musicInfo => playMusicInfo.musicInfo.songmid == musicInfo.songmid)
if (buttons.collect == status) return false
buttons.collect = status
return true
}
const handlePlay = () => {
if (buttons.empty) buttons.empty = false
buttons.play = true
setButtons()
}
const handlePause = () => {
if (buttons.empty) buttons.empty = false
buttons.play = false
setButtons()
}
const handleStop = async() => {
if (playMusicInfo.musicInfo != null) return
if (buttons.collect) buttons.collect = false
buttons.empty = true
setButtons()
}
const handleSetPlayInfo = () => {
if (!updateCollectStatus()) return
setButtons()
}
const handleSetTaskbarThumbnailClip = (clip) => {
setTaskbarThumbnailClip(clip)
}
const throttleListChange = throttle(listIds => {
if (!listIds.includes(loveList.id)) return
if (!updateCollectStatus()) return
setButtons()
})
// const updateSetting = () => {
// const setting = store.getters.setting
// buttons.lrc = setting.desktopLyric.enable
// buttons.lockLrc = setting.desktopLyric.isLock
// setButtons()
// }
const rTaskbarThumbarClick = onTaskbarThumbarClick((event, action) => {
switch (action) {
case 'play':
window.eventHub.emit(eventPlayerNames.setPlay)
break
case 'pause':
window.eventHub.emit(eventPlayerNames.setPause)
break
case 'prev':
window.eventHub.emit(eventPlayerNames.setPlayPrev)
break
case 'next':
window.eventHub.emit(eventPlayerNames.setPlayNext)
break
case 'collect':
if (!playMusicInfo.musicInfo) return
listAdd({ id: loveList.id, musicInfo: musicInfoItem.value })
if (updateCollectStatus()) setButtons()
break
case 'unCollect':
if (!playMusicInfo.musicInfo) return
listRemove({ listId: loveList.id, id: musicInfoItem.value.songmid })
if (updateCollectStatus()) setButtons()
break
// case 'lrc':
// setVisibleDesktopLyric(true)
// updateSetting()
// break
// case 'unLrc':
// setVisibleDesktopLyric(false)
// updateSetting()
// break
// case 'lockLrc':
// setLockDesktopLyric(true)
// updateSetting()
// break
// case 'unlockLrc':
// setLockDesktopLyric(false)
// updateSetting()
// break
}
})
window.eventHub.on(eventPlayerNames.play, handlePlay)
window.eventHub.on(eventPlayerNames.pause, handlePause)
window.eventHub.on(eventPlayerNames.stop, handleStop)
window.eventHub.on(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
window.eventHub.on(eventTaskbarNames.setTaskbarThumbnailClip, handleSetTaskbarThumbnailClip)
window.eventHub.on(eventListNames.listChange, throttleListChange)
onBeforeUnmount(() => {
rTaskbarThumbarClick()
window.eventHub.off(eventPlayerNames.play, handlePlay)
window.eventHub.off(eventPlayerNames.pause, handlePause)
window.eventHub.off(eventPlayerNames.stop, handleStop)
window.eventHub.off(eventPlayerNames.setPlayInfo, handleSetPlayInfo)
window.eventHub.off(eventTaskbarNames.setTaskbarThumbnailClip, handleSetTaskbarThumbnailClip)
window.eventHub.off(eventListNames.listChange, throttleListChange)
})
return () => {
// const setting = store.getters.setting
// buttons.lrc = setting.desktopLyric.enable
// buttons.lockLrc = setting.desktopLyric.isLock
updateCollectStatus()
if (playMusicInfo.musicInfo != null) buttons.empty = false
setButtons()
}
}
@@ -1,63 +0,0 @@
import { onBeforeUnmount, watch, useCommit } from '@renderer/utils/vueTools'
import { setVolume as setPlayerVolume, setMute as setPlayerMute } from '@renderer/plugins/player'
import { debounce } from '@renderer/utils'
import { player as eventKeyPlayerNames } from '@common/hotKey'
// import { player as eventPlayerNames } from '@renderer/event/names'
import { volume, isMute, setMute, setVolume } from '@renderer/core/share/volume'
export default ({ setting }) => {
const saveVolume = useCommit('setVolume')
const handleSaveVolume = debounce(saveVolume, 300)
const handleToggleVolumeMute = (_isMute) => {
let muteStatus = _isMute ?? !isMute.value
saveVolume(muteStatus)
setMute(muteStatus)
}
const handleSetVolume = num => {
const _volume = num < 0 ? 0 : num > 1 ? 1 : num
setVolume(_volume)
}
const handleSetVolumeUp = (step = 0.02) => {
handleSetVolume(volume.value + step)
}
const handleSetVolumeDown = (step = 0.02) => {
handleSetVolume(volume.value - step)
}
watch(volume, _volume => {
handleSaveVolume(_volume)
setPlayerVolume(_volume)
})
watch(isMute, mute => {
handleSaveVolume(mute)
setPlayerMute(mute)
})
watch(() => setting.value.player.volume, _volume => {
setVolume(_volume)
})
watch(() => setting.value.player.isMute, muteStatus => {
setMute(muteStatus)
})
setVolume(setting.value.player.volume)
setMute(setting.value.player.isMute)
window.eventHub.on(eventKeyPlayerNames.volume_up.action, handleSetVolumeUp)
window.eventHub.on(eventKeyPlayerNames.volume_down.action, handleSetVolumeDown)
window.eventHub.on(eventKeyPlayerNames.volume_mute.action, handleToggleVolumeMute)
// window.eventHub.on(eventPlayerNames.setVolume, handleSetVolume)
// window.eventHub.on(eventPlayerNames.toggleMute, handleToggleVolumeMute)
onBeforeUnmount(() => {
window.eventHub.off(eventKeyPlayerNames.volume_up.action, handleSetVolumeUp)
window.eventHub.off(eventKeyPlayerNames.volume_down.action, handleSetVolumeDown)
window.eventHub.off(eventKeyPlayerNames.volume_mute.action, handleToggleVolumeMute)
// window.eventHub.off(eventPlayerNames.setVolume, handleSetVolume)
// window.eventHub.off(eventPlayerNames.toggleMute, handleToggleVolumeMute)
})
}
@@ -0,0 +1,75 @@
import { onBeforeUnmount, watch } from '@common/utils/vueTools'
import { setVolume as setPlayerVolume, setMute as setPlayerMute } from '@renderer/plugins/player'
import { debounce } from '@common/utils'
import { HOTKEY_PLAYER } from '@common/hotKey'
// import { player as eventPlayerNames } from '@renderer/event/names'
import { volume, isMute, setMute, setVolume } from '@renderer/store/player/volume'
import { appSetting, saveVolume, saveVolumeIsMute } from '@renderer/store/setting'
export default () => {
const handleSaveVolume = debounce(saveVolume, 300)
setVolume(appSetting['player.volume'])
setMute(appSetting['player.isMute'])
setPlayerVolume(appSetting['player.volume'])
setPlayerMute(appSetting['player.isMute'])
const handleToggleVolumeMute = (_isMute?: boolean) => {
let muteStatus = _isMute ?? !isMute.value
saveVolumeIsMute(muteStatus)
setMute(muteStatus)
}
const handleSetVolume = (num: number) => {
const _volume = num < 0 ? 0 : num > 1 ? 1 : num
setVolume(_volume)
}
const handleSetVolumeUp = (step = 0.02) => {
handleSetVolume(volume.value + step)
}
const handleSetVolumeDown = (step = 0.02) => {
handleSetVolume(volume.value - step)
}
const hotkeyVolumeUp = () => {
handleSetVolumeUp()
}
const hotkeyVolumeDown = () => {
handleSetVolumeDown()
}
const hotkeyVolumeMute = () => {
handleToggleVolumeMute()
}
watch(volume, _volume => {
handleSaveVolume(_volume)
setPlayerVolume(_volume)
})
watch(isMute, mute => {
saveVolumeIsMute(mute)
setPlayerMute(mute)
})
watch(() => appSetting['player.volume'], _volume => {
setVolume(_volume)
})
watch(() => appSetting['player.isMute'], muteStatus => {
setMute(muteStatus)
})
window.key_event.on(HOTKEY_PLAYER.volume_up.action, hotkeyVolumeUp)
window.key_event.on(HOTKEY_PLAYER.volume_down.action, hotkeyVolumeDown)
window.key_event.on(HOTKEY_PLAYER.volume_mute.action, hotkeyVolumeMute)
window.app_event.on('setVolume', handleSetVolume)
window.app_event.on('setVolumeIsMute', handleToggleVolumeMute)
onBeforeUnmount(() => {
window.key_event.off(HOTKEY_PLAYER.volume_up.action, hotkeyVolumeUp)
window.key_event.off(HOTKEY_PLAYER.volume_down.action, hotkeyVolumeDown)
window.key_event.off(HOTKEY_PLAYER.volume_mute.action, hotkeyVolumeMute)
window.app_event.off('setVolume', handleSetVolume)
window.app_event.off('setVolumeIsMute', handleToggleVolumeMute)
})
}
@@ -1,44 +0,0 @@
import { onBeforeUnmount } from '@renderer/utils/vueTools'
import { player as eventPlayerNames, list as eventListNames, download as eventDownloadNames } from '@renderer/event/names'
import { playInfo, playMusicInfo, updatePlayIndex } from '@renderer/core/share/player'
import { getList } from '@renderer/core/share/utils'
import { throttle } from '@renderer/utils'
const changedListIds = new Set()
export default ({ playNext }) => {
const throttleListChange = throttle(() => {
const isSkip = !changedListIds.has(playInfo.playListId) && !changedListIds.has(playMusicInfo.listId)
changedListIds.clear()
if (isSkip) return
const { playIndex } = updatePlayIndex()
if (playIndex < 0 && !playMusicInfo.isTempPlay) { // 歌曲被移除
if (getList(playMusicInfo.listId).length && !global.isPlayedStop) {
playNext()
} else {
window.eventHub.emit(eventPlayerNames.setStop)
}
}
})
const handleListChange = listIds => {
for (const id of listIds) {
changedListIds.add(id)
}
throttleListChange()
}
const handleDownloadListChange = () => {
handleListChange(['download'])
}
window.eventHub.on(eventListNames.listChange, handleListChange)
window.eventHub.on(eventDownloadNames.listChange, handleDownloadListChange)
onBeforeUnmount(() => {
window.eventHub.off(eventListNames.listChange, handleListChange)
window.eventHub.off(eventDownloadNames.listChange, handleDownloadListChange)
})
}
@@ -0,0 +1,48 @@
import { onBeforeUnmount } from '@common/utils/vueTools'
import { playInfo, playMusicInfo } from '@renderer/store/player/state'
import { setPlayMusicInfo, updatePlayIndex } from '@renderer/store/player/action'
import { throttle } from '@common/utils'
import { playNext, stop } from '@renderer/core/player'
const changedListIds = new Set<string | null>()
export default () => {
const throttleListChange = throttle(() => {
const isSkip = !changedListIds.has(playInfo.playerListId) && !changedListIds.has(playMusicInfo.listId)
changedListIds.clear()
if (isSkip) return
const { playIndex } = updatePlayIndex()
if (playIndex < 0) { // 歌曲被移除
if (window.lx.isPlayedStop) {
stop()
setTimeout(() => {
setPlayMusicInfo(null, null)
})
} else {
console.log('current music removed')
void playNext(true)
}
}
})
const handleListChange = (listIds: string[]) => {
for (const id of listIds) {
changedListIds.add(id)
}
throttleListChange()
}
const handleDownloadListChange = () => {
handleListChange(['download'])
}
window.app_event.on('myListUpdate', handleListChange)
window.app_event.on('downloadListUpdate', handleDownloadListChange)
onBeforeUnmount(() => {
window.app_event.off('myListUpdate', handleListChange)
window.app_event.off('downloadListUpdate', handleDownloadListChange)
})
}
-127
View File
@@ -1,127 +0,0 @@
import { throttle, saveSetting } from '@renderer/utils'
import { saveMyList, saveDownloadList, saveSearchHistoryList, setUserApi } from '@renderer/utils/tools'
import music from '@renderer/utils/music'
import { useCommit, watch, toRaw, onBeforeUnmount } from '@renderer/utils/vueTools'
import { apiSource, qualityList, userApi, proxy } from '@renderer/core/share'
import { allList, defaultList, loveList, userLists, tempList } from '@renderer/core/share/list'
import { downloadList } from '@renderer/core/share/download'
import { list as eventListNames, download as eventDownloadNames } from '@renderer/event/names'
const listThrottle = (fn, delay = 100) => {
let timer = null
let _data = {}
return function(data) {
Object.assign(_data, data)
if (timer) return
timer = setTimeout(() => {
timer = null
fn.call(this, _data)
_data = {}
}, delay)
}
}
const saveMyListThrottle = listThrottle(data => saveMyList(data), 300)
const saveDownloadListThrottle = throttle(list => saveDownloadList(list), 1000)
const saveSearchHistoryListThrottle = throttle(list => saveSearchHistoryList(list), 500)
export default ({
setting,
searchHistoryList,
}) => {
watch(setting, (newValue, oldValue) => {
saveSetting(toRaw(newValue))
global.appSetting = newValue
}, { deep: true })
// watch(defaultList, (newValue, oldValue) => {
// saveMyListThrottle({ defaultList: toRaw(newValue) })
// }, { deep: true })
// watch(loveList, (newValue, oldValue) => {
// saveMyListThrottle({ loveList: toRaw(newValue) })
// }, { deep: true })
// watch(userList, (newValue, oldValue) => {
// saveMyListThrottle({ userList: toRaw(newValue) })
// }, { deep: true })
// watch(downloadList, (newValue, oldValue) => {
// saveDownloadListThrottle(window.downloadListFull)
// }, { deep: true })
watch(searchHistoryList, (newValue, oldValue) => {
saveSearchHistoryListThrottle(toRaw(newValue))
}, { deep: true })
const setApiSource = useCommit('setApiSource')
watch(apiSource, (apiSource, oldValue) => {
if (/^user_api/.test(apiSource)) {
qualityList.value = {}
userApi.status = false
userApi.message = 'initing'
} else {
qualityList.value = music.supportQuality[apiSource]
}
if (oldValue === null) return
setUserApi(apiSource)
if (apiSource != setting.value.apiSource) {
setApiSource(apiSource)
}
})
const setProxyEnable = useCommit('setProxyEnable')
watch(() => proxy.enable, (enable, oldValue) => {
if (enable != setting.value.network.proxy.enable) setProxyEnable(enable)
})
const handelListChange = ids => {
const lists = {}
let isUserList = false
for (const id of ids) {
switch (id) {
case defaultList.id:
lists.defaultList = { ...toRaw(defaultList), list: toRaw(allList[id]) }
break
case loveList.id:
lists.loveList = { ...toRaw(loveList), list: toRaw(allList[id]) }
break
case tempList.id:
lists.tempList = { ...toRaw(tempList), list: toRaw(allList[id]) }
break
default:
isUserList = true
}
}
if (isUserList) {
lists.userList = userLists.map(l => ({ ...toRaw(l), list: toRaw(allList[l.id]) }))
}
saveMyListThrottle(lists)
}
const handelSaveList = ({ id }) => {
handelListChange([id])
}
const handelDownloadListChange = () => {
saveDownloadListThrottle(toRaw(downloadList))
}
window.eventHub.on(eventListNames.listChange, handelListChange)
window.eventHub.on(eventListNames.musicInfoChange, handelSaveList)
window.eventHub.on(eventDownloadNames.listChange, handelDownloadListChange)
onBeforeUnmount(() => {
window.eventHub.off(eventListNames.listChange, handelListChange)
window.eventHub.off(eventListNames.musicInfoChange, handelSaveList)
window.eventHub.off(eventDownloadNames.listChange, handelDownloadListChange)
})
return {
saveMyListThrottle,
saveSearchHistoryListThrottle,
}
}
@@ -0,0 +1,81 @@
import { watch } from '@common/utils/vueTools'
import { isFullscreen, proxy, sync, windowSizeList } from '@renderer/store'
import { appSetting } from '@renderer/store/setting'
import { sendSyncAction, setTaskBarProgress, setWindowSize } from '@renderer/utils/ipc'
import { setLanguage } from '@/lang'
import { setUserApi } from '../apiSource'
// import { applyTheme, getThemes } from '@renderer/store/utils'
export default () => {
watch(() => appSetting['common.windowSizeId'], (index) => {
let info = index == null ? windowSizeList[2] : windowSizeList[index]
setWindowSize(info.width, info.height)
})
watch(() => appSetting['common.fontSize'], (fontSize) => {
if (isFullscreen.value) return
document.documentElement.style.fontSize = `${fontSize}px`
})
watch(() => appSetting['common.langId'], (id) => {
if (!id) return
setLanguage(id)
})
watch(() => appSetting['common.apiSource'], apiSource => {
setUserApi(apiSource)
})
watch(() => appSetting['common.font'], (val) => {
document.documentElement.style.fontFamily = val
}, {
immediate: true,
})
watch(() => appSetting['sync.enable'], enable => {
void sendSyncAction({
action: 'enable',
data: {
enable,
port: appSetting['sync.port'],
},
})
sync.enable = enable
})
watch(() => appSetting['sync.port'], port => {
void sendSyncAction({
action: 'enable',
data: {
enable: appSetting['sync.enable'],
port: appSetting['sync.port'],
},
})
sync.port = port
})
watch(() => appSetting['network.proxy.enable'], enable => {
proxy.enable = enable
})
watch(() => appSetting['network.proxy.enable'], enable => {
proxy.enable = enable
})
watch(() => appSetting['network.proxy.host'], host => {
proxy.host = host
})
watch(() => appSetting['network.proxy.port'], port => {
proxy.port = port
})
watch(() => appSetting['network.proxy.username'], username => {
proxy.username = username
})
watch(() => appSetting['network.proxy.password'], password => {
proxy.password = password
})
watch(() => appSetting['player.isShowTaskProgess'], val => {
if (val) return
setTimeout(() => {
setTaskBarProgress(-1, 'normal')
})
})
}
-125
View File
@@ -1,125 +0,0 @@
import { useCommit, useRefGetter, onBeforeUnmount, toRaw } from '@renderer/utils/vueTools'
import { sync as eventSyncName } from '@renderer/event/names'
import { syncEnable, onSyncStatus } from '@renderer/utils/tools'
import { sync } from '@renderer/core/share'
import { allList, defaultList, loveList, userLists } from '@renderer/core/share/list'
export default () => {
const setList = useCommit('list', 'setList')
const listAdd = useCommit('list', 'listAdd')
const listMove = useCommit('list', 'listMove')
const listAddMultiple = useCommit('list', 'listAddMultiple')
const listMoveMultiple = useCommit('list', 'listMoveMultiple')
const listRemove = useCommit('list', 'listRemove')
const listRemoveMultiple = useCommit('list', 'listRemoveMultiple')
const listClear = useCommit('list', 'listClear')
const updateMusicInfo = useCommit('list', 'updateMusicInfo')
const createUserList = useCommit('list', 'createUserList')
const removeUserList = useCommit('list', 'removeUserList')
const setUserListName = useCommit('list', 'setUserListName')
const setMusicPosition = useCommit('list', 'setMusicPosition')
const setSyncListData = useCommit('list', 'setSyncListData')
const setUserListPosition = useCommit('list', 'setUserListPosition')
const setting = useRefGetter('setting')
const handleSyncAction = ({ action, data }) => {
if (typeof data == 'object') data.isSync = true
// console.log(action, data)
switch (action) {
case 'set_list':
setList(data)
break
case 'list_add':
listAdd(data)
break
case 'list_move':
listMove(data)
break
case 'list_add_multiple':
listAddMultiple(data)
break
case 'list_move_multiple':
listMoveMultiple(data)
break
case 'list_remove':
listRemove(data)
break
case 'list_remove_multiple':
listRemoveMultiple(data)
break
case 'list_clear':
listClear(data)
break
case 'update_music_info':
updateMusicInfo(data)
break
case 'create_user_list':
createUserList(data)
break
case 'remove_user_list':
removeUserList(data)
break
case 'set_user_list_name':
setUserListName(data)
break
case 'set_user_list_position':
setUserListPosition(data)
break
case 'set_music_position':
setMusicPosition(data)
break
default:
break
}
}
const handleSyncList = ({ action, data }) => {
switch (action) {
case 'getData':
global.eventHub.emit(eventSyncName.send_sync_list, {
action: 'getData',
data: {
defaultList: { ...toRaw(defaultList), list: toRaw(allList[defaultList.id]) },
loveList: { ...toRaw(loveList), list: toRaw(allList[loveList.id]) },
userList: userLists.map(l => ({ ...toRaw(l), list: toRaw(allList[l.id]) })),
},
})
break
case 'setData':
setSyncListData(data)
break
case 'selectMode':
sync.deviceName = data.deviceName
sync.isShowSyncMode = true
break
case 'closeSelectMode':
sync.isShowSyncMode = false
break
}
}
window.eventHub.on(eventSyncName.handle_action_list, handleSyncAction)
window.eventHub.on(eventSyncName.handle_sync_list, handleSyncList)
const rSyncStatus = onSyncStatus((event, status) => {
sync.status.status = status.status
sync.status.message = status.message
sync.status.address = status.address
sync.status.code = status.code
sync.status.devices = status.devices
})
if (setting.value.sync.enable && setting.value.sync.port) {
syncEnable({
enable: setting.value.sync.enable,
port: setting.value.sync.port,
})
}
onBeforeUnmount(() => {
rSyncStatus()
})
}
+47
View File
@@ -0,0 +1,47 @@
import { markRaw, onBeforeUnmount } from '@common/utils/vueTools'
import { onSyncAction, sendSyncAction } from '@renderer/utils/ipc'
import { sync } from '@renderer/store'
import { appSetting } from '@renderer/store/setting'
export default () => {
const handleSyncList = (event: LX.Sync.SyncMainWindowActions) => {
switch (event.action) {
case 'select_mode':
sync.deviceName = event.data.deviceName
sync.isShowSyncMode = true
break
case 'close_select_mode':
sync.isShowSyncMode = false
break
case 'status':
sync.status.status = event.data.status
sync.status.message = event.data.message
sync.status.address = markRaw(event.data.address)
sync.status.code = event.data.code
sync.status.devices = markRaw(event.data.devices)
break
}
}
const rSyncAction = onSyncAction(({ params }) => {
handleSyncList(params)
})
onBeforeUnmount(() => {
rSyncAction()
})
return async() => {
sync.enable = appSetting['sync.enable']
sync.port = appSetting['sync.port']
if (appSetting['sync.enable'] && appSetting['sync.port']) {
void sendSyncAction({
action: 'enable',
data: {
enable: appSetting['sync.enable'],
port: appSetting['sync.port'],
},
})
}
}
}
@@ -1,16 +1,22 @@
import { useAction, nextTick, onBeforeUnmount } from '@renderer/utils/vueTools'
import { onUpdateAvailable, onUpdateDownloaded, onUpdateError, onUpdateNotAvailable, onUpdateProgress } from '@renderer/utils/tools'
import { compareVer } from '@renderer/utils'
import { versionInfo } from '@renderer/core/share'
export default (setting) => {
const getVersionInfo = useAction('getVersionInfo')
import { nextTick, onBeforeUnmount } from '@common/utils/vueTools'
import {
onUpdateAvailable,
onUpdateDownloaded,
onUpdateError,
onUpdateNotAvailable,
onUpdateProgress,
getIgnoreVersion,
} from '@renderer/utils/ipc'
import { compareVer } from '@common/utils'
import { versionInfo } from '@renderer/store'
import { getVersionInfo } from '@renderer/utils/update'
export default () => {
// 更新超时定时器
let updateTimeout = setTimeout(() => {
let updateTimeout: number | null = window.setTimeout(() => {
updateTimeout = null
versionInfo.isTimeOut = true
nextTick(() => {
void nextTick(() => {
showUpdateModal()
})
}, 60 * 30 * 1000)
@@ -22,7 +28,7 @@ export default (setting) => {
}
const showUpdateModal = () => {
(versionInfo.newVersion && versionInfo.newVersion.history
void (versionInfo.newVersion?.history
? Promise.resolve(versionInfo.newVersion)
: getVersionInfo().then(body => {
versionInfo.newVersion = body
@@ -33,11 +39,11 @@ export default (setting) => {
versionInfo.isUnknow = true
let result = {
version: '0.0.0',
desc: null,
desc: '',
}
versionInfo.newVersion = result
return result
}).then(result => {
}).then((result: LX.VersionInfo) => {
if (result.version == '0.0.0') {
versionInfo.isUnknow = true
versionInfo.showModal = true
@@ -48,49 +54,51 @@ export default (setting) => {
return
}
if (result.version === setting.value.ignoreVersion) return
// console.log(this.version)
nextTick(() => {
versionInfo.showModal = true
return getIgnoreVersion().then((ignoreVersion) => {
if (result.version === ignoreVersion) return
// console.log(this.version)
void nextTick(() => {
versionInfo.showModal = true
})
})
})
}
const rUpdateAvailable = onUpdateAvailable((event, info) => {
const rUpdateAvailable = onUpdateAvailable(({ params: info }) => {
versionInfo.isDownloading = true
getVersionInfo().catch(() => ({
void getVersionInfo().catch(() => ({
version: info.version,
desc: info.releaseNotes,
})).then(body => {
// console.log(body)
versionInfo.newVersion = body
nextTick(() => {
void nextTick(() => {
versionInfo.showModal = true
})
})
})
const rUpdateNotAvailable = onUpdateNotAvailable((event, info) => {
const rUpdateNotAvailable = onUpdateNotAvailable(({ params: info }) => {
clearUpdateTimeout()
versionInfo.newVersion = {
version: info.version,
desc: info.releaseNotes,
desc: info.releaseNotes as string,
}
versionInfo.isLatestVer = true
})
const rUpdateError = onUpdateError((event, info) => {
const rUpdateError = onUpdateError(() => {
clearUpdateTimeout()
versionInfo.isError = true
nextTick(() => {
void nextTick(() => {
showUpdateModal()
})
})
const rUpdateProgress = onUpdateProgress((event, progress) => {
const rUpdateProgress = onUpdateProgress(({ params: progress }) => {
versionInfo.downloadProgress = progress
})
const rUpdateDownloaded = onUpdateDownloaded((event, info) => {
const rUpdateDownloaded = onUpdateDownloaded(({ params: info }) => {
clearUpdateTimeout()
versionInfo.isDownloaded = true
nextTick(() => {
void nextTick(() => {
showUpdateModal()
})
})