优化代码逻辑,修复潜在播放问题

pull/1155/head
lyswhut 2023-01-14 16:03:56 +08:00
parent d3c8f16aed
commit 850a429243
35 changed files with 85 additions and 342 deletions

View File

@ -3,7 +3,7 @@
- 修复备份文件导入指引无法识别v2配置的问题
- 修复从搜索界面进入歌单详情后,若启用强迫症设置的清空功能会导致意外清空搜索框、搜索列表的问题
- 就放桌面歌词在启用卡拉OK歌词后字体边缘可能被截断的问题
- 修复桌面歌词在启用卡拉OK歌词后字体边缘可能被截断的问题(特别是纵向歌词某些字的边角被截断导致后面的阴影露出来或阴影不均匀的问题)
- 修复桌面歌词启用歌词缩放后的阴影显示问题
- 修复Linux armv7l系统如树莓派下无法启动的问题与修复Linux arm64的方法一样采用内置预编译模块的方式修复
- 修复备份与恢复的列表导入列表信息设置逻辑问题与潜在导入问题

View File

@ -36,7 +36,7 @@ exports.createThemeColors = (rgbaColor, fontRgbaColor, isDark) => {
const createFontColors = (rgbaColor, isDark) => {
// rgb(238, 238, 238)
// let prec = 'rgb(255, 255, 255)'
if (rgbaColor == null) rgbaColor = isDark ? 'rgb(229, 229, 229)' : 'rgb(33, 33, 33)'
rgbaColor ??= isDark ? 'rgb(229, 229, 229)' : 'rgb(33, 33, 33)'
if (isDark) return createFontDarkColors(rgbaColor)
let colors = {

View File

@ -141,7 +141,7 @@ module.exports = class FontPlayer {
// lineText += text
if (this.shadowContent) {
if (!lrcShadowContent) lrcShadowContent = document.createElement('div')
lrcShadowContent ??= document.createElement('div')
const shadowDom = document.createElement('span')
shadowDom.textContent = text
lrcShadowContent.appendChild(shadowDom)

View File

@ -25,7 +25,7 @@ export default (setting: any): Partial<LX.AppSetting> => {
// 迁移列表滚动位置设置 ~0.18.3
if (setting.list?.scroll) {
let scroll = setting.list.scroll
if (setting.list.isSaveScrollLocation) setting.list.isSaveScrollLocation = scroll.enable
setting.list.isSaveScrollLocation &&= scroll.enable
delete setting.list.scroll
}

View File

@ -244,7 +244,7 @@ export const scrollXRTo = (element: HTMLElement, to: number, duration = 300, fn
*/
let dom_title = document.getElementsByTagName('title')[0]
export const setTitle = (title: string | null) => {
if (!title) title = '洛雪音乐助手'
title ||= '洛雪音乐助手'
dom_title.innerText = title
}

View File

@ -44,7 +44,7 @@ export const createClientKeyInfo = (deviceName: string): LX.Sync.KeyInfo => {
deviceName,
}
const store = getStore(STORE_NAME)
if (!keyInfos) keyInfos = store.get('keys') as KeyInfos || {}
keyInfos ??= store.get('keys') as KeyInfos || {}
if (Object.keys(keyInfos).length > 101) throw new Error('max keys')
keyInfos[keyInfo.clientId] = keyInfo

View File

@ -27,7 +27,7 @@ const winEvent = () => {
export const createWindow = async(userApi: LX.UserApi.UserApiInfo) => {
await closeWindow()
if (!dir) dir = global.isDev ? webpackUserApiPath : join(encodePath(__dirname), 'userApi')
dir ??= global.isDev ? webpackUserApiPath : join(encodePath(__dirname), 'userApi')
if (!html) {
html = await fs.promises.readFile(join(dir, 'renderer/user-api.html'), 'utf8')

View File

@ -33,7 +33,7 @@ export const importApi = (script: string): LX.UserApi.UserApiInfo => {
script,
allowShowUpdateAlert: true,
}
if (!userApis) userApis = []
userApis ??= []
userApis.push(apiInfo)
getStore(STORE_NAMES.USER_API).set('userApis', userApis)
return apiInfo

View File

@ -20,7 +20,7 @@ const winEvent = () => {
return
}
if (global.lx.isTrafficLightClose) global.lx.isTrafficLightClose = false
global.lx.isTrafficLightClose &&= false
event.preventDefault()
browserWindow!.hide()
})

View File

@ -113,7 +113,7 @@ export const updateSetting = (setting?: Partial<LX.AppSetting>, isInit: boolean
let originSetting: LX.AppSetting
if (isInit) {
if (setting) setting = migrateSetting(setting)
setting &&= migrateSetting(setting)
originSetting = { ...defaultSetting }
} else originSetting = global.lx.appSetting
@ -196,7 +196,7 @@ export const openDevTools = (webContents: Electron.WebContents) => {
let userThemes: LX.Theme[]
export const getAllThemes = () => {
if (!userThemes) userThemes = getStore(STORE_NAMES.THEME).get('themes') as LX.Theme[] | null ?? []
userThemes ??= getStore(STORE_NAMES.THEME).get('themes') as (LX.Theme[] | null) ?? []
return {
themes,
userThemes,

View File

@ -39,7 +39,7 @@ const toDBMusicInfo = (musicInfos: LX.Music.MusicInfo[], listId: string, offset:
* @returns
*/
export const getAllUserList = (): LX.List.UserListInfo[] => {
if (userLists == null) userLists = queryAllUserList()
userLists ??= queryAllUserList()
return userLists.map(list => {
const { position, ...newList } = list
@ -53,7 +53,7 @@ export const getAllUserList = (): LX.List.UserListInfo[] => {
* @param lists
*/
export const createUserLists = (position: number, lists: LX.List.UserListInfo[]) => {
if (userLists == null) userLists = queryAllUserList()
userLists ??= queryAllUserList()
if (position < 0 || position >= userLists.length) {
const newLists: LX.DBService.UserListInfo[] = lists.map((list, index) => {
return {
@ -96,7 +96,7 @@ export const setUserLists = (lists: LX.List.UserListInfo[]) => {
*/
export const removeUserLists = (ids: string[]) => {
deleteUserLists(ids)
if (userLists) userLists = queryAllUserList()
userLists &&= queryAllUserList()
}
/**
@ -117,7 +117,7 @@ export const updateUserLists = (lists: LX.List.UserListInfo[]) => {
}
}).filter(Boolean) as LX.DBService.UserListInfo[]
updateUserListsFromDB(dbList)
if (userLists) userLists = queryAllUserList()
userLists &&= queryAllUserList()
}
/**
@ -126,7 +126,7 @@ export const updateUserLists = (lists: LX.List.UserListInfo[]) => {
* @param ids ids
*/
export const updateUserListsPosition = (position: number, ids: string[]) => {
if (userLists == null) userLists = queryAllUserList()
userLists ??= queryAllUserList()
const newUserLists = [...userLists]

View File

@ -91,7 +91,7 @@ export default () => {
const handleMove = (x, y) => {
if (isMsDown.value) {
if (!isStopScroll) isStopScroll = true
isStopScroll ||= true
if (cancelScrollFn) {
cancelScrollFn()
cancelScrollFn = null
@ -164,7 +164,7 @@ export default () => {
const scrollLine = (line, oldLine) => {
if (line < 0 || !lyric.lines.length) return
if (line == 0 && isSetedLines) return isSetedLines = false
if (isSetedLines) isSetedLines = false
isSetedLines &&= false
if (oldLine == null || line - oldLine != 1) return handleScrollLrc()
if (setting['desktopLyric.isDelayScroll']) {

View File

@ -91,7 +91,7 @@ export default () => {
const handleMove = (x, y) => {
if (isMsDown.value) {
if (!isStopScroll) isStopScroll = true
isStopScroll ||= true
if (cancelScrollFn) {
cancelScrollFn()
cancelScrollFn = null
@ -164,7 +164,7 @@ export default () => {
const scrollLine = (line, oldLine) => {
if (line < 0) return
if (line == 0 && isSetedLines) return isSetedLines = false
if (isSetedLines) isSetedLines = false
isSetedLines &&= false
if (oldLine == null || line - oldLine != 1) return handleScrollLrc()
if (setting['desktopLyric.isDelayScroll']) {

View File

@ -56,7 +56,7 @@ export default {
}
const handleMsMove = event => {
if (!msEvent.isMsDown) return
if (!dragging.value) dragging.value = true
dragging.value ||= true
let progress = msEvent.msDownProgress + (event.clientX - msEvent.msDownX) / dom_progress.value.clientWidth
if (progress > 1) progress = 1

View File

@ -125,14 +125,14 @@ export default {
let lxlyric = props.lyricInfo.lxlyric
if (offsetTagRxp.test(lyric)) {
lyric = lyric.replace(offsetTagAllRxp, `$1[offset:${offset}]`)
if (tlyric) tlyric = tlyric.replace(offsetTagAllRxp, `$1[offset:${offset}]`)
if (lxlyric) lxlyric = lxlyric.replace(offsetTagAllRxp, `$1[offset:${offset}]`)
if (rlyric) rlyric = rlyric.replace(offsetTagAllRxp, `$1[offset:${offset}]`)
tlyric &&= tlyric.replace(offsetTagAllRxp, `$1[offset:${offset}]`)
lxlyric &&= lxlyric.replace(offsetTagAllRxp, `$1[offset:${offset}]`)
rlyric &&= rlyric.replace(offsetTagAllRxp, `$1[offset:${offset}]`)
} else {
lyric = `[offset:${offset}]\n` + lyric
if (tlyric) tlyric = `[offset:${offset}]\n` + tlyric
if (lxlyric) lxlyric = `[offset:${offset}]\n` + lxlyric
if (rlyric) rlyric = `[offset:${offset}]\n` + rlyric
lyric &&= `[offset:${offset}]\n` + lyric
tlyric &&= `[offset:${offset}]\n` + tlyric
lxlyric &&= `[offset:${offset}]\n` + lxlyric
rlyric &&= `[offset:${offset}]\n` + rlyric
}
const musicInfo = 'progress' in props.lyricInfo.musicInfo ? props.lyricInfo.musicInfo.meta.musicInfo : props.lyricInfo.musicInfo

View File

@ -64,7 +64,7 @@ export default {
}
const handleSearch = () => {
if (visibleList.value) visibleList.value = false
visibleList.value &&= false
if (!searchText.value && route.path != '/search') {
setSearchText('')
return
@ -83,13 +83,13 @@ export default {
switch (action) {
case 'focus':
isFocused = true
if (!visibleList.value) visibleList.value = true
visibleList.value ||= true
if (searchText.value) handleTipSearch()
break
case 'blur':
isFocused = false
setTimeout(() => {
if (visibleList.value) visibleList.value = false
visibleList.value &&= false
}, 50)
break
case 'submit':

View File

@ -12,16 +12,16 @@ const useKeyEvent = ({ handleSelectAllData }: {
}
const handle_key_shift_down = () => {
if (!keyEvent.isShiftDown) keyEvent.isShiftDown = true
keyEvent.isShiftDown ||= true
}
const handle_key_shift_up = () => {
if (keyEvent.isShiftDown) keyEvent.isShiftDown = false
keyEvent.isShiftDown &&= false
}
const handle_key_mod_down = () => {
if (!keyEvent.isModDown) keyEvent.isModDown = true
keyEvent.isModDown ||= true
}
const handle_key_mod_up = () => {
if (keyEvent.isModDown) keyEvent.isModDown = false
keyEvent.isModDown &&= false
}
const handle_key_mod_a_down = ({ event }: LX.KeyDownEevent) => {
if (!event || (event.target as HTMLElement).tagName == 'INPUT') return

View File

@ -19,7 +19,7 @@ import { requestMsg } from '@renderer/utils/message'
import { getRandom } from '@renderer/utils/index'
// import { checkMusicFileAvailable } from '@renderer/utils/music'
let isGettingUrl = false
let gettingUrlId = ''
const createDelayNextTimeout = (delay: number) => {
let timeout: NodeJS.Timeout | null
const clearDelayNextTimeout = () => {
@ -86,7 +86,7 @@ const getMusicPlayUrl = async(musicInfo: LX.Music.MusicInfo | LX.Download.ListIt
export const setMusicUrl = (musicInfo: LX.Music.MusicInfo | LX.Download.ListItem, isRefresh?: boolean) => {
if (appSetting['player.autoSkipOnError']) addLoadTimeout()
isGettingUrl = true
gettingUrlId = musicInfo.id
void getMusicPlayUrl(musicInfo, isRefresh).then((url) => {
if (!url) return
setResource(url)
@ -96,8 +96,10 @@ export const setMusicUrl = (musicInfo: LX.Music.MusicInfo | LX.Download.ListItem
window.app_event.error()
if (appSetting['player.autoSkipOnError']) addDelayNextTimeout()
}).finally(() => {
clearLoadTimeout()
if (musicInfo === playMusicInfo.musicInfo) isGettingUrl = false
if (musicInfo === playMusicInfo.musicInfo) {
gettingUrlId = ''
clearLoadTimeout()
}
})
}
@ -139,14 +141,17 @@ const handleRestorePlay = async(restorePlayInfo: LX.Player.SavedPlayInfo) => {
// 处理音乐播放
const handlePlay = () => {
if (window.lx.isPlayedStop) window.lx.isPlayedStop = false
if (isGettingUrl) isGettingUrl = false
window.lx.isPlayedStop &&= false
if (window.lx.restorePlayInfo) {
void handleRestorePlay(window.lx.restorePlayInfo)
window.lx.restorePlayInfo = null
return
}
const musicInfo = playMusicInfo.musicInfo
if (!musicInfo || gettingUrlId == musicInfo.id) return
gettingUrlId &&= ''
setStop()
window.app_event.pause()
@ -154,9 +159,6 @@ const handlePlay = () => {
clearDelayNextTimeout()
clearLoadTimeout()
const musicInfo = playMusicInfo.musicInfo
if (!musicInfo) return
if (appSetting['player.togglePlayMethod'] == 'random' && playMusicInfo.listId) addPlayedList({ ...(playMusicInfo as LX.Player.PlayMusicInfo) })
@ -414,7 +416,7 @@ export const playPrev = async(isAutoToggle = false): Promise<void> => {
export const play = () => {
if (playMusicInfo.musicInfo == null) return
if (isEmpty()) {
setMusicUrl(playMusicInfo.musicInfo)
if (playMusicInfo.musicInfo.id != gettingUrlId) setMusicUrl(playMusicInfo.musicInfo)
return
}
setPlay()
@ -441,7 +443,7 @@ export const stop = () => {
*
*/
export const togglePlay = () => {
if (window.lx.isPlayedStop) window.lx.isPlayedStop = false
window.lx.isPlayedStop &&= false
if (isPlay.value) {
pause()
} else {

View File

@ -67,12 +67,12 @@ const timeoutTools: {
}
export const startTimeoutStop = (time: number) => {
if (window.lx.isPlayedStop) window.lx.isPlayedStop = false
window.lx.isPlayedStop &&= false
timeoutTools.start(time)
}
export const stopTimeoutStop = () => {
console.warn('stopTimeoutStop')
if (window.lx.isPlayedStop) window.lx.isPlayedStop = false
window.lx.isPlayedStop &&= false
timeoutTools.clearTimeout()
}

View File

@ -60,9 +60,9 @@ export default () => {
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')
device ??= devices.find(device => device.deviceId === 'default')
// @ts-expect-error
if (!device) device = { label: '', deviceId: '' }
device ??= { label: '', deviceId: '' }
// @ts-expect-error
handleDeviceChangeStopPlay(device, mediaDeviceId)

View File

@ -33,7 +33,7 @@ export default () => {
if (window.lx.isPlayedStop) return
const currentTime = getCurrentTime()
if (!mediaBuffer.playTime) mediaBuffer.playTime = currentTime
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) {
@ -97,7 +97,7 @@ export default () => {
}
const handleError = () => {
if (!restorePlayTime) restorePlayTime = getCurrentTime() // 记录出错的播放时间
restorePlayTime ||= getCurrentTime() // 记录出错的播放时间
console.log('handleError')
prevProgressStatus = 'error'
handleSetTaskBarState(playProgress.progress, prevProgressStatus)

View File

@ -32,18 +32,18 @@ export default () => {
}
const handlePlay = () => {
if (buttons.empty) buttons.empty = false
buttons.empty &&= false
buttons.play = true
setButtons()
}
const handlePause = () => {
if (buttons.empty) buttons.empty = false
buttons.empty &&= false
buttons.play = false
setButtons()
}
const handleStop = () => {
if (playMusicInfo.musicInfo != null) return
if (buttons.collect) buttons.collect = false
buttons.collect &&= false
buttons.empty = true
setButtons()
}

View File

@ -53,7 +53,7 @@ void getSetting().then(setting => {
break
}
}
if (langId == null) langId = 'en-us'
langId ??= 'en-us'
}
setting['common.langId'] = langId
void updateSetting({ 'common.langId': langId })

View File

@ -191,12 +191,12 @@ export const registerListAction = (appSetting: LX.AppSetting, onListChanged: (li
userListsUpdatePosition(position, ids)
}
const list_music_add = ({ params: { id, musicInfos, addMusicLocationType } }: LX.IpcRendererEventParams<LX.List.ListActionMusicAdd>) => {
if (!addMusicLocationType) addMusicLocationType = appSetting['list.addMusicLocationType']
addMusicLocationType ??= appSetting['list.addMusicLocationType']
const updatedListIds = listMusicAdd(id, musicInfos, addMusicLocationType)
if (updatedListIds.length) onListChanged(updatedListIds)
}
const list_music_move = ({ params: { fromId, toId, musicInfos, addMusicLocationType } }: LX.IpcRendererEventParams<LX.List.ListActionMusicMove>) => {
if (!addMusicLocationType) addMusicLocationType = appSetting['list.addMusicLocationType']
addMusicLocationType ??= appSetting['list.addMusicLocationType']
const updatedListIds = listMusicMove(fromId, toId, musicInfos, addMusicLocationType)
if (updatedListIds.length) onListChanged(updatedListIds)
}

View File

@ -21,7 +21,7 @@ export default (name: string) => {
}
const handle_key_up = () => {
if (keyDown.value) keyDown.value = false
keyDown.value &&= false
}
onMounted(() => {

View File

@ -128,7 +128,7 @@ export default ({ isPlay, lyric, playProgress, isShowLyricProgressSetting, offse
}
const handleMove = (y) => {
if (isMsDown.value) {
if (!isStopScroll.value) isStopScroll.value = true
isStopScroll.value ||= true
if (cancelScrollFn) {
cancelScrollFn()
cancelScrollFn = null
@ -150,7 +150,7 @@ export default ({ isPlay, lyric, playProgress, isShowLyricProgressSetting, offse
const handleWheel = (event) => {
console.log(event.deltaY)
if (!isStopScroll.value) isStopScroll.value = true
isStopScroll.value ||= true
if (cancelScrollFn) {
cancelScrollFn()
cancelScrollFn = null
@ -197,7 +197,7 @@ export default ({ isPlay, lyric, playProgress, isShowLyricProgressSetting, offse
const scrollLine = (line, oldLine) => {
if (line < 0) return
if (line == 0 && isSetedLines) return isSetedLines = false
if (isSetedLines) isSetedLines = false
isSetedLines &&= false
if (oldLine == null || line - oldLine != 1) return handleScrollLrc()
delayScrollTimeout = setTimeout(() => {

View File

@ -44,7 +44,7 @@ const saveViewPrevStateThrottle = throttle((state) => {
}, 1000)
const initPosition = async() => {
if (listPosition == null) listPosition = await getListPositionInfoFromData() ?? {}
listPosition ??= await getListPositionInfoFromData() ?? {}
}
export const getListPosition = async(id: string): Promise<number> => {
await initPosition()
@ -74,7 +74,7 @@ const saveListPrevSelectIdThrottle = throttle(() => {
saveListPrevSelectIdFromData(listPrevSelectId)
}, 200)
export const getListPrevSelectId = async() => {
if (listPrevSelectId == null) listPrevSelectId = await getListPrevSelectIdFromData() ?? LIST_IDS.DEFAULT
listPrevSelectId ??= await getListPrevSelectIdFromData() ?? LIST_IDS.DEFAULT
return listPrevSelectId ?? LIST_IDS.DEFAULT
}
export const saveListPrevSelectId = (id: string) => {
@ -138,7 +138,7 @@ export const overwriteListUpdateInfo = async(ids: string[]) => {
export const getSearchSetting = async() => {
if (!searchSetting) searchSetting = await getSearchSettingFromData()
searchSetting ??= await getSearchSettingFromData()
return { ...searchSetting }
}
export const setSearchSetting = async(setting: Partial<typeof DEFAULT_SETTING['search']>) => {
@ -154,7 +154,7 @@ export const setSearchSetting = async(setting: Partial<typeof DEFAULT_SETTING['s
}
export const getSongListSetting = async() => {
if (!songListSetting) songListSetting = await getSongListSettingFromData()
songListSetting ??= await getSongListSettingFromData()
return { ...songListSetting }
}
export const setSongListSetting = async(setting: Partial<typeof DEFAULT_SETTING['songList']>) => {
@ -164,7 +164,7 @@ export const setSongListSetting = async(setting: Partial<typeof DEFAULT_SETTING[
}
export const getLeaderboardSetting = async() => {
if (!leaderboardSetting) leaderboardSetting = await getLeaderboardSettingFromData()
leaderboardSetting ??= await getLeaderboardSettingFromData()
return { ...leaderboardSetting }
}
export const setLeaderboardSetting = async(setting: Partial<typeof DEFAULT_SETTING['leaderboard']>) => {

View File

@ -27,7 +27,7 @@ export const dateFormat2 = (time: number): string => {
*/
let dom_title = document.getElementsByTagName('title')[0]
export const setTitle = (title: string | null) => {
if (!title) title = '洛雪音乐助手'
title ||= '洛雪音乐助手'
dom_title.innerText = title
}

View File

@ -10,16 +10,16 @@ const useKeyEvent = ({ handleSelectAllData }) => {
}
const handle_key_shift_down = () => {
if (!keyEvent.isShiftDown) keyEvent.isShiftDown = true
keyEvent.isShiftDown ||= true
}
const handle_key_shift_up = () => {
if (keyEvent.isShiftDown) keyEvent.isShiftDown = false
keyEvent.isShiftDown &&= false
}
const handle_key_mod_down = () => {
if (!keyEvent.isModDown) keyEvent.isModDown = true
keyEvent.isModDown ||= true
}
const handle_key_mod_up = () => {
if (keyEvent.isModDown) keyEvent.isModDown = false
keyEvent.isModDown &&= false
}
const handle_key_mod_a_down = ({ event }) => {
if (event.target.tagName == 'INPUT') return

View File

@ -137,10 +137,10 @@ export default {
},
handle_key_mod_down() {
console.log('handle_key_mod_down')
if (!this.isModDown) this.isModDown = true
this.isModDown ||= true
},
handle_key_mod_up() {
if (this.isModDown) this.isModDown = false
this.isModDown &&= false
},
handle_key_mod_f_down() {
if (this.visible) this.$refs.dom_input.focus()

View File

@ -10,16 +10,16 @@ const useKeyEvent = ({ handleSelectAllData }) => {
}
const handle_key_shift_down = () => {
if (!keyEvent.isShiftDown) keyEvent.isShiftDown = true
keyEvent.isShiftDown ||= true
}
const handle_key_shift_up = () => {
if (keyEvent.isShiftDown) keyEvent.isShiftDown = false
keyEvent.isShiftDown &&= false
}
const handle_key_mod_down = () => {
if (!keyEvent.isModDown) keyEvent.isModDown = true
keyEvent.isModDown ||= true
}
const handle_key_mod_up = () => {
if (keyEvent.isModDown) keyEvent.isModDown = false
keyEvent.isModDown &&= false
}
const handle_key_mod_a_down = ({ event }) => {
if (event.target.tagName == 'INPUT') return

View File

@ -1,259 +0,0 @@
<!-- <template>
<teleport to="#root">
<div ref="dom_menu" :class="$style.container" :style="menuStyles" :aria-hidden="!modelValue">
<div :class="$style.group">
<div :class="$style.subGroup">
<button :class="$style.btn" :disabled="!itemMenuControl.rename" ignore-tip :aria-label="$t('lists__rename')" @click="menuClick('rename')">{{ $t('lists__rename') }}</button>
<button :class="$style.btn" :disabled="offsetDisabled" ignore-tip :aria-label="$t('lists__sync')" @click="menuClick('sync')">{{ $t('lists__sync') }}</button>
</div>
<div :class="$style.subGroup">
<button :class="$style.btn" :disabled="offsetDisabled" ignore-tip :aria-label="$t('lists__sort_list')" @click="menuClick('sort')">{{ $t('lists__sort_list') }}</button>
<button :class="$style.btn" :disabled="offsetDisabled" ignore-tip :aria-label="$t('lyric_menu__offset_dec_100')" @click="menuClick(-100)">- 100ms</button>
</div>
</div>
</div>
</teleport>
</template>
<script>
import { computed, useRefGetter, ref, useCommit, watch } from '@common/utils/vueTools'
import useMenuLocation from '@renderer/utils/compositions/useMenuLocation'
import { setLyricEdited, removeLyricEdited, debounce } from '@renderer/utils'
const offsetTagRxp = /(?:^|\n)\s*\[offset:\s*(\S+(?:\d+)*)\s*\]/
const offsetTagAllRxp = /(?:^|\n)\s*\[offset:\s*(\S+(?:\d+)*)\s*\]/g
const saveLyric = debounce((musicInfo, lyricInfo) => {
setLyricEdited(musicInfo, lyricInfo)
})
const removeLyric = debounce(musicInfo => {
removeLyricEdited(musicInfo)
})
const getOffset = lrc => {
let offset = offsetTagRxp.exec(lrc)
if (offset) {
offset = parseInt(offset[1])
if (Number.isNaN(offset)) offset = 0
} else offset = 0
return offset
}
export default {
name: 'LyricMenu',
props: {
modelValue: Boolean,
xy: Object,
lyricInfo: Object,
},
emits: ['updateLyric', 'update:modelValue'],
setup(props, { emit }) {
const setting = useRefGetter('setting')
const playDetailSetting = useRefGetter('playDetailSetting')
const setPlayDetailLyricAlign = useCommit('setPlayDetailLyricAlign')
const setPlayDetailLyricFont = useCommit('setPlayDetailLyricFont')
const offset = ref(0)
const offsetDisabled = ref(true)
const originOffset = ref(0)
const visible = computed(() => props.modelValue)
const musicInfo = computed(() => props.lyricInfo.musicInfo)
const location = computed(() => props.xy)
const onHide = () => {
emit('update:modelValue', false)
}
const setFontAlign = val => {
if (playDetailSetting.value.style.align == val) return
setPlayDetailLyricAlign(val)
}
const fontSizeUp = step => {
if (setting.value.playDetail.style.fontSize >= 200) return
setPlayDetailLyricFont(Math.min(setting.value.playDetail.style.fontSize + step, 200))
}
const fontSizeDown = step => {
if (setting.value.playDetail.style.fontSize <= 70) return
setPlayDetailLyricFont(Math.max(setting.value.playDetail.style.fontSize - step, 70))
}
const fontSizeReset = () => {
setPlayDetailLyricFont(100)
}
const updateLyric = offset => {
let lyric = props.lyricInfo.lyric
let tlyric = props.lyricInfo.tlyric
let rlyric = props.lyricInfo.rlyric
let lxlyric = props.lyricInfo.lxlyric
if (offsetTagRxp.test(lyric)) {
lyric = lyric.replace(offsetTagAllRxp, `[offset:${offset}]`)
if (tlyric) tlyric = tlyric.replace(offsetTagAllRxp, `[offset:${offset}]`)
if (lxlyric) lxlyric = lxlyric.replace(offsetTagAllRxp, `[offset:${offset}]`)
if (rlyric) rlyric = rlyric.replace(offsetTagAllRxp, `[offset:${offset}]`)
} else {
lyric = `[offset:${offset}]\n` + lyric
if (tlyric) tlyric = `[offset:${offset}]\n` + tlyric
if (lxlyric) lxlyric = `[offset:${offset}]\n` + lxlyric
if (rlyric) rlyric = `[offset:${offset}]\n` + rlyric
}
if (offset == originOffset.value) {
removeLyric(props.lyricInfo.musicInfo)
} else {
saveLyric(props.lyricInfo.musicInfo, {
lyric,
tlyric,
rlyric,
lxlyric,
})
}
emit('updateLyric', {
lyric,
tlyric,
rlyric,
lxlyric,
offset,
})
}
const setOffset = step => {
offset.value += step
updateLyric(offset.value)
}
const offsetReset = () => {
if (offset.value == originOffset.value) return
offset.value = originOffset.value
updateLyric(originOffset.value)
}
const parseLrcOffset = () => {
offset.value = getOffset(props.lyricInfo.lyric)
originOffset.value = getOffset(props.lyricInfo.rawlyric)
offsetDisabled.value = !props.lyricInfo.lyric
}
const { dom_menu, menuStyles } = useMenuLocation({
visible,
location,
onHide,
})
watch(musicInfo, () => {
if (!props.modelValue) return
parseLrcOffset()
})
watch(visible, val => {
if (!val) return
parseLrcOffset()
})
return {
dom_menu,
menuStyles,
playDetailSetting,
offset,
originOffset,
fontSizeUp,
fontSizeDown,
fontSizeReset,
setOffset,
offsetReset,
setFontAlign,
offsetDisabled,
}
},
}
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.container {
font-size: 12px;
position: absolute;
opacity: 0;
transform: scale(0);
transform-origin: 0 0 0;
transition: .25s ease;
transition-property: transform, opacity;
border-radius: @radius-border;
background-color: var(--color-main-background);
box-shadow: 0 1px 8px 0 rgba(0,0,0,.2);
z-index: 10;
overflow: hidden;
}
.group {
display: flex;
flex-direction: column;
}
.title {
flex: auto;
padding: 10px 0 10px 10px;
color: var(--color-font-label);
white-space: nowrap;
min-width: 120px;
}
.subGroup {
display: flex;
flex-flow: row nowrap;
}
.btn {
flex: auto;
white-space: nowrap;
cursor: pointer;
min-width: 60px;
height: 34px;
display: flex;
align-items: center;
justify-content: center;
// color: var(--color-button-font);
padding: 0 10px;
outline: none;
transition: @transition-normal;
transition-property: background-color, opacity;
box-sizing: border-box;
.mixin-ellipsis-1;
background-color: var(--color-main-background);
border: none;
&:hover {
opacity: .7;
background-color: @color-theme_2-hover;
}
&:active {
background-color: @color-theme_2-active;
}
&.active {
background-color: var(--color-main-background);
color: var(--color-button-background-active);
cursor: default;
opacity: 1;
}
&[disabled] {
cursor: default;
opacity: .4;
&:hover {
background: none !important;
}
}
}
.titleBtn {
flex: none;
padding: 0 10;
min-width: 40px;
opacity: .7;
&[disabled] {
opacity: .3;
}
}
</style>
-->

View File

@ -35,8 +35,8 @@ const verifyQueryParams = async(to, from, next) => {
if (_source == null || _type == null) {
const setting = await getSearchSetting()
if (!_source) _source = setting.source
if (!_type) _type = setting.type
_source ??= setting.source
_type ??= setting.type
next({
path: to.path,

View File

@ -127,9 +127,9 @@ export default {
const autoTheme = reactive({})
const updateAutoTheme = (info) => {
let light = findTheme(info, appSetting['theme.lightId'])
if (!light) light = info.themes.find(theme => theme.id == 'green')
light ??= info.themes.find(theme => theme.id == 'green')
let dark = findTheme(info, appSetting['theme.darkId'])
if (!dark) dark = info.themes.find(theme => theme.id == 'black')
dark ??= info.themes.find(theme => theme.id == 'black')
autoTheme['--color-primary-theme-light'] = light.config.themeColors['--color-theme']
autoTheme['--background-image-theme-light'] = light.isCustom
? light.config.extInfo['--background-image'] == 'none'

View File

@ -172,7 +172,7 @@ export const filterDuplicateMusic = async(list: LX.Music.MusicInfo[], isFilterVa
if (isFilterVariant) {
list.forEach((musicInfo, index) => {
let musicInfoName = musicInfo.name.toLowerCase().replace(variantRxp, '').replace(variantRxp2, '')
if (!musicInfoName) musicInfoName = musicInfo.name.toLowerCase().replace(/\s+/g, '')
musicInfoName ||= musicInfo.name.toLowerCase().replace(/\s+/g, '')
handleFilter(musicInfoName, index, musicInfo)
})
} else {