升级到 vue3

This commit is contained in:
lyswhut
2021-12-03 22:11:11 +08:00
parent c6635e554a
commit 8059d9cd73
260 changed files with 14443 additions and 10979 deletions
+136
View File
@@ -0,0 +1,136 @@
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from '@renderer/utils/vueTools'
import { scrollTo } from '@renderer/utils'
export default ({ isPlay, lyric }) => {
const dom_lyric = ref(null)
const dom_lyric_text = ref(null)
const isMsDown = ref(false)
let msDownY = 0
let msDownScrollY = 0
let isStopScroll = false
let timeout = null
let cancelScrollFn
let dom_lines
let isSetedLines = false
const handleScrollLrc = () => {
if (!dom_lines?.length) return
if (cancelScrollFn) {
cancelScrollFn()
cancelScrollFn = null
}
if (isStopScroll) return
let dom_p = dom_lines[lyric.line]
cancelScrollFn = scrollTo(dom_lyric.value, dom_p ? (dom_p.offsetTop - dom_lyric.value.clientHeight * 0.38) : 0)
}
const clearLyricScrollTimeout = () => {
if (!timeout) return
clearTimeout(timeout)
timeout = null
}
const startLyricScrollTimeout = () => {
clearLyricScrollTimeout()
timeout = setTimeout(() => {
timeout = null
isStopScroll = false
if (!isPlay.value) return
handleScrollLrc()
}, 3000)
}
const handleLyricMouseDown = event => {
// console.log(event)
isMsDown.value = true
msDownY = event.clientY
msDownScrollY = dom_lyric.value.scrollTop
}
const handleMouseMsUp = event => {
isMsDown.value = false
}
const handleMouseMsMove = event => {
if (isMsDown.value) {
if (!isStopScroll) isStopScroll = true
if (cancelScrollFn) {
cancelScrollFn()
cancelScrollFn = null
}
dom_lyric.value.scrollTop = msDownScrollY + msDownY - event.clientY
startLyricScrollTimeout()
}
}
const handleWheel = (event) => {
console.log(event.deltaY)
if (!isStopScroll) isStopScroll = true
if (cancelScrollFn) {
cancelScrollFn()
cancelScrollFn = null
}
dom_lyric.value.scrollTop = dom_lyric.value.scrollTop + event.deltaY
startLyricScrollTimeout()
}
const setLyric = (lines) => {
const dom_line_content = document.createDocumentFragment()
for (const line of lines) {
dom_line_content.appendChild(line.dom_line)
}
dom_lyric_text.value.textContent = ''
dom_lyric_text.value.appendChild(dom_line_content)
nextTick(() => {
dom_lines = dom_lyric.value.querySelectorAll('.lrc-content')
handleScrollLrc()
})
}
const initLrc = (lines, oLines) => {
isSetedLines = true
if (oLines) {
if (lines.length) {
setLyric(lines)
} else {
if (cancelScrollFn) {
cancelScrollFn()
cancelScrollFn = null
}
cancelScrollFn = scrollTo(dom_lyric.value, 0, 300, () => {
if (lyric.lines !== lines) return
setLyric(lines)
}, 50)
}
} else {
setLyric(lines)
}
}
const scrollLine = line => {
if (line < 0) return
if (line == 0 && isSetedLines) return isSetedLines = false
handleScrollLrc()
}
watch(() => lyric.lines, initLrc)
watch(() => lyric.line, scrollLine)
onMounted(() => {
initLrc(lyric.lines, null)
nextTick(() => {
scrollLine(lyric.line)
})
})
document.addEventListener('mousemove', handleMouseMsMove)
document.addEventListener('mouseup', handleMouseMsUp)
onBeforeUnmount(() => {
document.removeEventListener('mousemove', handleMouseMsMove)
document.removeEventListener('mouseup', handleMouseMsUp)
})
return {
dom_lyric,
dom_lyric_text,
isMsDown,
handleLyricMouseDown,
handleWheel,
}
}
@@ -0,0 +1,36 @@
import {
computed,
useCommit,
} from '@renderer/utils/vueTools'
const playNextModes = [
'listLoop',
'random',
'list',
'singleLoop',
]
export default ({ setting, t }) => {
const setPlayNextMode = useCommit('setPlayNextMode')
const nextTogglePlayName = computed(() => {
switch (setting.value.player.togglePlayMethod) {
case 'listLoop': return t('player__play_toggle_mode_list_loop')
case 'random': return t('player__play_toggle_mode_random')
case 'singleLoop': return t('player__play_toggle_mode_single_loop')
case 'list': return t('player__play_toggle_mode_list')
default: return t('player__play_toggle_mode_off')
}
})
const toggleNextPlayMode = () => {
let index = playNextModes.indexOf(setting.value.player.togglePlayMethod)
if (++index >= playNextModes.length) index = -1
setPlayNextMode(playNextModes[index] || '')
}
return {
nextTogglePlayName,
toggleNextPlayMode,
}
}
@@ -0,0 +1,31 @@
import { ref, onBeforeUnmount, toRef } from '@renderer/utils/vueTools'
import { player as eventPlayerNames } from '@renderer/event/names'
import { playProgress } from '@renderer/core/share/playProgress'
export default () => {
const isActiveTransition = ref(false)
const progress = toRef(playProgress, 'progress')
const nowPlayTimeStr = toRef(playProgress, 'nowPlayTimeStr')
const maxPlayTimeStr = toRef(playProgress, 'maxPlayTimeStr')
const handleTransitionEnd = () => {
isActiveTransition.value = false
}
const handleActiveTransition = () => {
isActiveTransition.value = true
}
window.eventHub.on(eventPlayerNames.activeTransition, handleActiveTransition)
onBeforeUnmount(() => {
window.eventHub.off(eventPlayerNames.activeTransition, handleActiveTransition)
})
return {
nowPlayTimeStr,
maxPlayTimeStr,
progress,
isActiveTransition,
handleTransitionEnd,
}
}
@@ -0,0 +1,34 @@
import {
computed,
useCommit,
} from '@renderer/utils/vueTools'
export default ({ setting, t }) => {
const setVisibleDesktopLyric = useCommit('setVisibleDesktopLyric')
const setLockDesktopLyric = useCommit('setLockDesktopLyric')
const toggleDesktopLyricBtnTitle = computed(() => {
return `${
setting.value.desktopLyric.enable
? t('player__desktop_lyric_off')
: t('player__desktop_lyric_on')
}(${
setting.value.desktopLyric.isLock
? t('player__desktop_lyric_unlock')
: t('player__desktop_lyric_lock')
})`
})
const toggleDesktopLyric = () => {
setVisibleDesktopLyric(!setting.value.desktopLyric.enable)
}
const toggleLockDesktopLyric = () => {
setLockDesktopLyric(!setting.value.desktopLyric.isLock)
}
return {
toggleDesktopLyricBtnTitle,
toggleDesktopLyric,
toggleLockDesktopLyric,
}
}
+9 -7
View File
@@ -2,9 +2,11 @@ import fs from 'fs'
import path from 'path'
import { shell, clipboard } from 'electron'
import crypto from 'crypto'
import { rendererSend, rendererInvoke, NAMES } from '../../common/ipc'
import { rendererSend, rendererInvoke, NAMES } from '@common/ipc'
import iconv from 'iconv-lite'
import { gzip, gunzip } from 'zlib'
import { proxy, qualityList } from '@renderer/core/share'
/**
* 获取两个数之间的随机整数,大于等于min,小于max
@@ -45,11 +47,11 @@ export const dateFormat = (date = new Date(), format = 'YYYY-MM-DD hh:mm:ss') =>
export const dateFormat2 = time => {
let differ = parseInt((Date.now() - time) / 1000)
if (differ < 60) {
return window.i18n.t('base.date_format_second', { num: differ })
return window.i18n.t('date_format_second', { num: differ })
} else if (differ < 3600) {
return window.i18n.t('base.date_format_minute', { num: parseInt(differ / 60) })
return window.i18n.t('date_format_minute', { num: parseInt(differ / 60) })
} else if (differ < 86400) {
return window.i18n.t('base.date_format_hour', { num: parseInt(differ / 3600) })
return window.i18n.t('date_format_hour', { num: parseInt(differ / 3600) })
} else {
return dateFormat(time)
}
@@ -384,12 +386,12 @@ export const clearCache = () => rendererInvoke(NAMES.mainWindow.clear_cache)
export const setWindowSize = (width, height) => rendererSend(NAMES.mainWindow.set_window_size, { width, height })
export const getProxyInfo = () => window.globalObj.proxy.enable && window.globalObj.proxy.host
? `http://${window.globalObj.proxy.username}:${window.globalObj.proxy.password}@${window.globalObj.proxy.host}:${window.globalObj.proxy.port};`
export const getProxyInfo = () => proxy.enable && proxy.host
? `http://${proxy.username}:${proxy.password}@${proxy.host}:${proxy.port};`
: undefined
export const assertApiSupport = source => window.globalObj.qualityList[source] != undefined
export const assertApiSupport = source => qualityList.value[source] != undefined
export const getSetting = () => rendererInvoke(NAMES.mainWindow.get_setting)
export const saveSetting = setting => rendererInvoke(NAMES.mainWindow.set_app_setting, setting)
+3 -2
View File
@@ -1,4 +1,5 @@
import apiSourceInfo from './api-source-info'
import { apiSource, userApi } from '@renderer/core/share'
const apiList = {}
const supportQuality = {}
@@ -10,10 +11,10 @@ for (const api of apiSourceInfo) {
}
}
const getAPI = source => apiList[`${window.globalObj.apiSource}_api_${source}`]
const getAPI = source => apiList[`${apiSource.value}_api_${source}`]
const apis = source => {
if (/^user_api/.test(window.globalObj.apiSource)) return window.globalObj.userApi.apis[source]
if (/^user_api/.test(apiSource.value)) return userApi.apis[source]
let api = getAPI(source)
if (api) return api
throw new Error('Api is not found')
+2 -1
View File
@@ -1,5 +1,6 @@
import crypto from 'crypto'
import dns from 'dns'
import { qualityList } from '@renderer/core/share'
/**
@@ -10,7 +11,7 @@ import dns from 'dns'
const types = ['flac', 'wav', 'ape', '320k', '192k', '128k']
export const getMusicType = (info, type) => {
let list = window.globalObj.qualityList[info.source]
let list = qualityList.value[info.source]
if (!list) return '128k'
if (!list.includes(type)) type = list[list.length - 1]
const rangeType = types.slice(types.indexOf(type))
+297
View File
@@ -0,0 +1,297 @@
import { rendererOn, rendererSend, rendererInvoke, NAMES, rendererOff } from '@common/ipc'
import apiSourceInfo from '../utils/music/api-source-info'
import { apiSource } from '@renderer/core/share'
import * as hotKeys from '@common/hotKey'
import { markRaw } from '@renderer/utils/vueTools'
import { mainWindow as eventsNameMainWindow, winLyric as eventsNameWinLyric } from '@main/events/_name'
export const setUserApi = source => {
return rendererInvoke(NAMES.mainWindow.set_user_api, source).catch(err => {
console.log(err)
let api = apiSourceInfo.find(api => !api.disabled)
if (api) apiSource.value = api.id
})
}
export const saveMyList = data => {
rendererSend(NAMES.mainWindow.save_playlist, {
type: 'myList',
data: data,
})
}
export const saveDownloadList = list => {
rendererSend(NAMES.mainWindow.save_playlist, {
type: 'downloadList',
data: list,
})
}
export const saveSearchHistoryList = list => {
rendererSend(NAMES.mainWindow.save_data, {
path: 'searchHistoryList',
data: list,
})
}
export const syncEnable = ({ enable, port }) => {
return rendererInvoke(NAMES.mainWindow.sync_enable, {
enable,
port,
})
}
export const setIgnoreMouseEvents = ignore => {
rendererSend(NAMES.mainWindow.set_ignore_mouse_events, ignore)
}
export const getEnvParams = () => {
return rendererInvoke(NAMES.mainWindow.get_env_params)
}
export const onUpdateAvailable = callback => {
rendererOn(NAMES.mainWindow.update_available, callback)
return () => {
rendererOff(callback)
}
}
export const onUpdateError = callback => {
rendererOn(NAMES.mainWindow.update_error, callback)
return () => {
rendererOff(callback)
}
}
export const onUpdateProgress = callback => {
rendererOn(NAMES.mainWindow.update_progress, callback)
return () => {
rendererOff(callback)
}
}
export const onUpdateDownloaded = callback => {
rendererOn(NAMES.mainWindow.update_downloaded, callback)
return () => {
rendererOff(callback)
}
}
export const onUpdateNotAvailable = callback => {
rendererOn(NAMES.mainWindow.update_not_available, callback)
return () => {
rendererOff(callback)
}
}
export const onSetConfig = callback => {
rendererOn(NAMES.mainWindow.set_config, callback)
return () => {
rendererOff(callback)
}
}
// 获取上次关闭时的当前歌曲播放信息
export const getPlayInfo = () => {
return rendererInvoke(NAMES.mainWindow.get_data, 'playInfo')
}
// 获取搜索历史列表
export const getSearchHistoryList = () => {
return rendererInvoke(NAMES.mainWindow.get_data, 'searchHistoryList')
}
export const onUserApiStatus = callback => {
rendererOn(NAMES.mainWindow.user_api_status, (event, { status, message, apiInfo }) => callback({ status, message, apiInfo }))
return () => {
rendererOff(callback)
}
}
export const getUserApiList = () => {
return rendererInvoke(NAMES.mainWindow.get_user_api_list)
}
export const userApiRequest = ({ requestKey, data }) => {
return rendererInvoke(NAMES.mainWindow.request_user_api, {
requestKey,
data,
})
}
export const userApiRequestCancel = requestKey => {
rendererSend(NAMES.mainWindow.request_user_api_cancel, requestKey)
}
export const setDesktopLyricInfo = (type, data, info) => {
rendererSend(NAMES.mainWindow.set_lyric_info, {
type,
data,
info,
})
}
export const onGetDesktopLyricInfo = callback => {
rendererOn(NAMES.mainWindow.get_lyric_info, (event, info) => callback(event, info))
return () => {
rendererOff(callback)
}
}
export const setTaskBarProgress = (status, mode) => {
rendererSend(NAMES.mainWindow.progress, {
status: status < 0.01 ? 0.01 : status,
mode: mode || 'normal',
})
}
export const savePlayInfo = ({ time, maxTime, listId, list, index }) => {
rendererSend(NAMES.mainWindow.save_data, {
path: 'playInfo',
data: {
time,
maxTime,
listId,
list: [],
index,
},
})
}
export const wait = (time, id) => {
return rendererInvoke(NAMES.mainWindow.wait, { time, id })
}
export const waitCancel = id => {
return rendererSend(NAMES.mainWindow.wait_cancel, id)
}
// 简体转繁体
export const langS2T = str => {
return rendererInvoke(NAMES.mainWindow.lang_s2t, Buffer.from(str).toString('base64'))
.then(b64 => Buffer.from(b64, 'base64').toString())
}
export const getSystemFonts = () => {
return rendererInvoke(NAMES.mainWindow.get_system_fonts).catch(() => {
return []
})
}
export const refreshSyncCode = () => {
return rendererInvoke(NAMES.mainWindow.sync_generate_code)
}
export const onSyncStatus = callback => {
rendererOn(NAMES.mainWindow.sync_status, callback)
return () => {
rendererOff(callback)
}
}
export const allHotKeys = markRaw({
local: [
{
name: hotKeys.player.toggle_play.name,
action: hotKeys.player.toggle_play.action,
type: eventsNameMainWindow.name,
},
{
name: hotKeys.player.prev.name,
action: hotKeys.player.prev.action,
type: eventsNameMainWindow.name,
},
{
name: hotKeys.player.next.name,
action: hotKeys.player.next.action,
type: eventsNameMainWindow.name,
},
{
name: hotKeys.common.focusSearchInput.name,
action: hotKeys.common.focusSearchInput.action,
type: eventsNameMainWindow.name,
},
{
name: hotKeys.common.min.name,
action: hotKeys.common.min.action,
type: eventsNameMainWindow.name,
},
{
name: hotKeys.common.close.name,
action: hotKeys.common.close.action,
type: eventsNameMainWindow.name,
},
],
global: [
{
name: hotKeys.common.min_toggle.name,
action: hotKeys.common.min_toggle.action,
type: eventsNameMainWindow.name,
},
{
name: hotKeys.common.hide_toggle.name,
action: hotKeys.common.hide_toggle.action,
type: eventsNameMainWindow.name,
},
{
name: hotKeys.common.close.name,
action: hotKeys.common.close.action,
type: eventsNameMainWindow.name,
},
{
name: hotKeys.player.toggle_play.name,
action: hotKeys.player.toggle_play.action,
type: eventsNameMainWindow.name,
},
{
name: hotKeys.player.prev.name,
action: hotKeys.player.prev.action,
type: eventsNameMainWindow.name,
},
{
name: hotKeys.player.next.name,
action: hotKeys.player.next.action,
type: eventsNameMainWindow.name,
},
{
name: hotKeys.player.volume_up.name,
action: hotKeys.player.volume_up.action,
type: eventsNameMainWindow.name,
},
{
name: hotKeys.player.volume_down.name,
action: hotKeys.player.volume_down.action,
type: eventsNameMainWindow.name,
},
{
name: hotKeys.player.volume_mute.name,
action: hotKeys.player.volume_mute.action,
type: eventsNameMainWindow.name,
},
{
name: hotKeys.desktop_lyric.toggle_visible.name,
action: hotKeys.desktop_lyric.toggle_visible.action,
type: eventsNameWinLyric.name,
},
{
name: hotKeys.desktop_lyric.toggle_lock.name,
action: hotKeys.desktop_lyric.toggle_lock.action,
type: eventsNameWinLyric.name,
},
{
name: hotKeys.desktop_lyric.toggle_always_top.name,
action: hotKeys.desktop_lyric.toggle_always_top.action,
type: eventsNameWinLyric.name,
},
],
})
export const hotKeySetEnable = (enable) => {
return rendererInvoke(NAMES.hotKey.enable, enable)
}
export const hotKeySetConfig = (config) => {
return rendererInvoke(NAMES.hotKey.set_config, config)
}
export const hotKeyGetStatus = () => {
return rendererInvoke(NAMES.hotKey.status)
}
+78
View File
@@ -0,0 +1,78 @@
import {
ref,
reactive,
computed,
watch,
watchEffect,
nextTick,
onMounted,
onBeforeUnmount,
toRaw,
useCssModule,
toRef,
toRefs,
shallowRef,
unref,
markRaw,
onBeforeUpdate,
onUpdated,
} from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useStore } from 'vuex'
import { useI18n } from 'vue-i18n'
export const useState = name => {
const store = useStore()
return store.state[name]
}
export const useGetter = (...names) => {
const store = useStore()
return store.getters[names.join('/')]
}
export const useRefGetter = (...names) => {
const store = useStore()
return computed(() => store.getters[names.join('/')])
}
export const useAction = (...names) => {
const store = useStore()
return params => {
return store.dispatch(names.join('/'), params)
}
}
export const useCommit = (...names) => {
const store = useStore()
return params => {
return store.commit(names.join('/'), params)
}
}
export const markRawList = list => {
for (const item of list) {
markRaw(item)
}
return list
}
export {
nextTick,
onBeforeUnmount,
ref,
toRaw,
reactive,
watch,
watchEffect,
computed,
useRouter,
useRoute,
useI18n,
useCssModule,
toRef,
toRefs,
shallowRef,
unref,
onMounted,
markRaw,
onBeforeUpdate,
onUpdated,
}