新增“不喜欢歌曲”功能&新增“收藏歌曲”、“取消收藏”、“不喜欢该歌曲”快捷键设置

This commit is contained in:
lyswhut
2023-09-04 14:13:47 +08:00
parent 3ca8f09971
commit baf69e397a
40 changed files with 861 additions and 26 deletions
@@ -60,6 +60,10 @@ export default {
type: String,
default: 'auto',
},
height: {
type: String,
default: 'auto',
},
},
emits: ['after-enter', 'after-leave', 'close'],
data() {
@@ -147,6 +151,7 @@ export default {
maxWidth: this.maxWidth,
minWidth: this.minWidth,
width: this.width,
height: this.height,
maxHeight: this.maxHeight,
}
},
@@ -180,6 +180,7 @@ export default {
const {
handleSearch,
handleOpenMusicDetail,
handleDislikeMusic,
} = useMusicActions({ props })
const {
@@ -199,6 +200,7 @@ export default {
handleSearch,
handleShowMusicAddModal,
handleOpenMusicDetail,
handleDislikeMusic,
})
const handleListItemClick = (event, index) => {
@@ -1,6 +1,7 @@
import { computed, ref, reactive, nextTick } from '@common/utils/vueTools'
import musicSdk from '@renderer/utils/musicSdk'
import { useI18n } from '@renderer/plugins/i18n'
import { hasDislike } from '@renderer/core/dislikeList'
export default ({
props,
@@ -13,6 +14,7 @@ export default ({
handleSearch,
handleShowMusicAddModal,
handleOpenMusicDetail,
handleDislikeMusic,
}) => {
const itemMenuControl = reactive({
play: true,
@@ -21,6 +23,7 @@ export default ({
download: true,
search: true,
sourceDetail: true,
dislike: true,
})
const t = useI18n()
const menuLocation = reactive({ x: 0, y: 0 })
@@ -58,6 +61,11 @@ export default ({
action: 'sourceDetail',
disabled: !itemMenuControl.sourceDetail,
},
{
name: t('list__dislike'),
action: 'dislike',
disabled: !itemMenuControl.dislike,
},
]
})
@@ -67,6 +75,8 @@ export default ({
// this.listMenu.itemMenuControl.playLater =
itemMenuControl.download = assertApiSupport(musicInfo.source)
itemMenuControl.dislike = !hasDislike(musicInfo)
if (props.checkApiSource) {
itemMenuControl.playLater =
itemMenuControl.play =
@@ -110,6 +120,9 @@ export default ({
break
case 'sourceDetail':
handleOpenMusicDetail(index)
case 'dislike':
handleDislikeMusic(index)
break
}
}
@@ -2,6 +2,9 @@ import { useRouter } from '@common/utils/vueRouter'
import musicSdk from '@renderer/utils/musicSdk'
import { openUrl } from '@common/utils/electron'
import { toOldMusicInfo } from '@renderer/utils'
import { addDislikeInfo, hasDislike } from '@renderer/core/dislikeList'
import { playNext } from '@renderer/core/player'
import { playMusicInfo } from '@renderer/store/player/state'
export default ({ props }) => {
@@ -24,8 +27,18 @@ export default ({ props }) => {
openUrl(url)
}
const handleDislikeMusic = async(index) => {
const minfo = props.list[index]
await addDislikeInfo([{ name: minfo.name, singer: minfo.singer }])
if (!playMusicInfo.isTempPlay && hasDislike(playMusicInfo.musicInfo)) {
playNext(true)
}
}
return {
handleSearch,
handleOpenMusicDetail,
handleDislikeMusic,
}
}
+48
View File
@@ -0,0 +1,48 @@
// import { toRaw } from '@common/utils/vueTools'
import { action } from '@renderer/store/dislikeList'
import {
getDislikeListInfo,
addDislikeInfo as addDislikeInfoRemote,
overwirteDislikeInfo as overwirteDislikeInfoRemote,
// updateDislikeInfo as updateDislikeInfoRemote,
// removeDislikeInfo as removeDislikeInfoRemote,
// clearDislikeInfo as clearDislikeInfoRemote,
} from '@renderer/utils/ipc'
export const initDislikeInfo = async() => {
action.initDislikeInfo(await getDislikeListInfo())
}
export const addDislikeInfo = async(infos: LX.Dislike.DislikeMusicInfo[]) => {
await addDislikeInfoRemote(infos)
return action.addDislikeInfo(infos)
}
export const overwirteDislikeInfo = async(rules: string) => {
await overwirteDislikeInfoRemote(rules)
return action.overwirteDislikeInfo(rules)
}
// export const updateDislikeInfo = async(info: LX.Dislike.ListItem) => {
// await updateDislikeInfoRemote([toRaw(info)])
// action.updateDislikeInfo(info)
// }
// export const removeDislikeInfo = async(ids: string[]) => {
// await removeDislikeInfoRemote(toRaw(ids))
// action.removeDislikeInfo(ids)
// }
// export const clearDislikeInfo = async() => {
// await clearDislikeInfoRemote()
// action.clearDislikeInfo()
// }
export const hasDislike = (info: LX.Music.MusicInfo | null) => {
if (!info) return false
return action.hasDislike(info)
}
+2
View File
@@ -299,6 +299,7 @@ export const playNext = async(isAutoToggle = false): Promise<void> => {
list: currentList,
playedList,
playerMusicInfo: currentList[playInfo.playerPlayIndex],
isNext: true,
})
if (!filteredList.length) {
@@ -398,6 +399,7 @@ export const playPrev = async(isAutoToggle = false): Promise<void> => {
list: currentList,
playedList,
playerMusicInfo: currentList[playInfo.playerPlayIndex],
isNext: false,
})
if (!filteredList.length) {
handleToggleStop()
+5 -1
View File
@@ -2,6 +2,7 @@ import { toRaw, markRawList } from '@common/utils/vueTools'
import { qualityList } from '@renderer/store'
import { clearPlayedList } from '@renderer/store/player/action'
import { appSetting } from '@renderer/store/setting'
import { dislikeInfo } from '@renderer/store/dislikeList'
export const getPlayType = (highQuality: boolean, musicInfo: LX.Music.MusicInfo | LX.Download.ListItem): LX.Quality | null => {
if ('progress' in musicInfo || musicInfo.source == 'local') return null
@@ -14,11 +15,12 @@ export const getPlayType = (highQuality: boolean, musicInfo: LX.Music.MusicInfo
/**
* 过滤列表中已播放的歌曲
*/
export const filterList = async({ playedList, listId, list, playerMusicInfo }: {
export const filterList = async({ playedList, listId, list, playerMusicInfo, isNext }: {
playedList: LX.Player.PlayMusicInfo[]
listId: string
list: Array<LX.Music.MusicInfo | LX.Download.ListItem>
playerMusicInfo?: LX.Music.MusicInfo | LX.Download.ListItem
isNext: boolean
}) => {
// if (this.list.listName === null) return
// console.log(isCheckFile)
@@ -28,6 +30,8 @@ export const filterList = async({ playedList, listId, list, playerMusicInfo }: {
playedList: toRaw(playedList),
savePath: appSetting['download.savePath'],
playerMusicInfo: toRaw(playerMusicInfo),
dislikeInfo: { names: toRaw(dislikeInfo.names), musicNames: toRaw(dislikeInfo.musicNames), singerNames: toRaw(dislikeInfo.singerNames) },
isNext,
})
if (!filteredList.length && playedList.length) {
+2
View File
@@ -9,6 +9,7 @@ import { play, playList } from '@renderer/core/player'
import { onBeforeUnmount } from '@common/utils/vueTools'
import { appSetting } from '@renderer/store/setting'
import { playMusicInfo } from '@renderer/store/player/state'
import { initDislikeInfo } from '@renderer/core/dislikeList'
const initPrevPlayInfo = async() => {
const info = await getPlayInfo()
@@ -48,6 +49,7 @@ export default () => {
window.app_event.myListUpdate(ids)
})
window.lxData.userLists = await getUserLists() // 获取用户列表
await initDislikeInfo() // 获取不喜欢列表
await initPrevPlayInfo().catch(err => {
log.error(err)
}) // 初始化上次的歌曲播放信息
@@ -32,6 +32,9 @@ import { HOTKEY_PLAYER } from '@common/hotKey'
import { playNext, pause, playPrev, togglePlay } from '@renderer/core/player'
import usePlaybackRate from './usePlaybackRate'
import useSoundEffect from './useSoundEffect'
import { addListMusics, removeListMusics } from '@renderer/store/list/action'
import { loveList } from '@renderer/store/list/state'
import { addDislikeInfo } from '@renderer/core/dislikeList'
export default () => {
@@ -90,6 +93,23 @@ export default () => {
setStop()
}
const collectMusic = () => {
if (!playMusicInfo.musicInfo) return
void addListMusics(loveList.id, ['progress' in playMusicInfo.musicInfo ? playMusicInfo.musicInfo.metadata.musicInfo : playMusicInfo.musicInfo])
}
const unCollectMusic = () => {
if (!playMusicInfo.musicInfo) return
void removeListMusics({ listId: loveList.id, ids: ['progress' in playMusicInfo.musicInfo ? playMusicInfo.musicInfo.metadata.musicInfo.id : playMusicInfo.musicInfo.id] })
}
const dislikeMusic = async() => {
if (!playMusicInfo.musicInfo) return
const minfo = 'progress' in playMusicInfo.musicInfo ? playMusicInfo.musicInfo.metadata.musicInfo : playMusicInfo.musicInfo
await addDislikeInfo([{ name: minfo.name, singer: minfo.singer }])
if (!playMusicInfo.isTempPlay) {
playNext(true)
}
}
watch(() => appSetting['player.togglePlayMethod'], newValue => {
// setLoopPlay(newValue == 'singleLoop')
if (playedList.length) clearPlayedList()
@@ -102,6 +122,9 @@ export default () => {
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.key_event.on(HOTKEY_PLAYER.music_love.action, collectMusic)
window.key_event.on(HOTKEY_PLAYER.music_unlove.action, unCollectMusic)
window.key_event.on(HOTKEY_PLAYER.music_dislike.action, dislikeMusic)
window.app_event.on('play', setPlayStatus)
window.app_event.on('pause', setPauseStatus)
@@ -119,6 +142,10 @@ export default () => {
// 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.key_event.off(HOTKEY_PLAYER.music_love.action, collectMusic)
window.key_event.off(HOTKEY_PLAYER.music_unlove.action, unCollectMusic)
window.key_event.off(HOTKEY_PLAYER.music_dislike.action, dislikeMusic)
window.app_event.off('play', setPlayStatus)
window.app_event.off('pause', setPauseStatus)
+83
View File
@@ -0,0 +1,83 @@
import { markRaw } from '@common/utils/vueTools'
import { dislikeInfo } from './state'
import { SPLIT_CHAR } from '@common/constants'
export const hasDislike = (info: LX.Music.MusicInfo) => {
const name = info.name?.replaceAll(SPLIT_CHAR.DISLIKE_NAME, SPLIT_CHAR.DISLIKE_NAME_ALIAS).toLocaleLowerCase().trim() ?? ''
const singer = info.singer?.replaceAll(SPLIT_CHAR.DISLIKE_NAME, SPLIT_CHAR.DISLIKE_NAME_ALIAS).toLocaleLowerCase().trim() ?? ''
return dislikeInfo.musicNames.has(name) || dislikeInfo.singerNames.has(singer) ||
dislikeInfo.names.has(`${name}${SPLIT_CHAR.DISLIKE_NAME}${singer}`)
}
export const initDislikeInfo = ({ musicNames, rules, names, singerNames }: LX.Dislike.DislikeInfo) => {
dislikeInfo.names = markRaw(names)
dislikeInfo.singerNames = markRaw(singerNames)
dislikeInfo.musicNames = markRaw(musicNames)
dislikeInfo.rules = rules
}
const initNameSet = () => {
dislikeInfo.names.clear()
dislikeInfo.musicNames.clear()
dislikeInfo.singerNames.clear()
const list: string[] = []
for (const item of dislikeInfo.rules.split('\n')) {
if (!item) continue
let [name, singer] = item.split(SPLIT_CHAR.DISLIKE_NAME)
if (name) {
name = name.replaceAll(SPLIT_CHAR.DISLIKE_NAME, SPLIT_CHAR.DISLIKE_NAME_ALIAS).toLocaleLowerCase().trim()
if (singer) {
singer = singer.replaceAll(SPLIT_CHAR.DISLIKE_NAME, SPLIT_CHAR.DISLIKE_NAME_ALIAS).toLocaleLowerCase().trim()
const rule = `${name}${SPLIT_CHAR.DISLIKE_NAME}${singer}`
dislikeInfo.names.add(rule)
list.push(rule)
} else {
dislikeInfo.musicNames.add(name)
list.push(name)
}
} else if (singer) {
singer = singer.replaceAll(SPLIT_CHAR.DISLIKE_NAME, SPLIT_CHAR.DISLIKE_NAME_ALIAS).toLocaleLowerCase().trim()
dislikeInfo.singerNames.add(singer)
list.push(`${SPLIT_CHAR.DISLIKE_NAME}${singer}`)
}
}
dislikeInfo.rules = list.join('\n') + '\n'
}
export const addDislikeInfo = (infos: LX.Dislike.DislikeMusicInfo[]) => {
dislikeInfo.rules += '\n' + infos.map(info => `${info.name ?? ''}${SPLIT_CHAR.DISLIKE_NAME}${info.singer ?? ''}`).join('\n')
initNameSet()
return dislikeInfo.rules
}
export const overwirteDislikeInfo = (rules: string) => {
dislikeInfo.rules = rules
initNameSet()
return dislikeInfo.rules
}
// export const updateDislikeInfo = (info: LX.Dislike.ListItem) => {
// const targetInfo = dislikeInfo.list.find(i => i.id == info.id)
// if (!targetInfo) return
// targetInfo.name = info.name
// targetInfo.singer = info.singer
// initNameSet()
// }
// export const removeDislikeInfo = (ids: string[]) => {
// for (const id of ids) {
// dislikeInfo.list.splice(dislikeInfo.list.findIndex(info => info.id == id), 1)
// }
// initNameSet()
// }
// export const clearDislikeInfo = () => {
// dislikeInfo.rules = ''
// initNameSet()
// }
+3
View File
@@ -0,0 +1,3 @@
export * as action from './action'
export * from './state'
+11
View File
@@ -0,0 +1,11 @@
import { markRaw } from '@common/utils/vueTools'
// import { deduplicationList } from '@common/utils/renderer'
export const dislikeInfo: LX.Dislike.DislikeInfo = markRaw({
names: markRaw(new Set()),
musicNames: markRaw(new Set()),
singerNames: markRaw(new Set()),
rules: '',
})
+1 -1
View File
@@ -73,7 +73,7 @@ export const setPlayListId = (listId: string | null) => {
playInfo.playerListId = listId
}
export const getList = (listId: string | null): LX.Music.MusicInfo[] | LX.Download.ListItem[] => {
export const getList = (listId: string | null): Array<LX.Music.MusicInfo | LX.Download.ListItem> => {
return listId == LIST_IDS.DOWNLOAD ? downloadList : getListMusicsFromCache(listId)
}
+1
View File
@@ -15,3 +15,4 @@ import '@common/types/ipc_renderer'
import '@common/types/config_files'
import '@common/types/music_metadata'
import '@common/types/sound_effect'
import '@common/types/dislike_list'
+38
View File
@@ -40,6 +40,24 @@ export const getOtherSourceCount = async() => {
return rendererInvoke<number>(WIN_MAIN_RENDERER_EVENT_NAME.get_other_source_count)
}
export const getDislikeListInfo = async(): Promise<LX.Dislike.DislikeInfo> => {
return rendererInvoke<LX.Dislike.DislikeInfo>(WIN_MAIN_RENDERER_EVENT_NAME.get_dislike_music_infos)
}
export const addDislikeInfo = async(dislikeInfo: LX.Dislike.DislikeMusicInfo[]) => {
return rendererInvoke<LX.Dislike.DislikeMusicInfo[]>(WIN_MAIN_RENDERER_EVENT_NAME.add_dislike_music_infos, dislikeInfo)
}
export const overwirteDislikeInfo = async(dislikeInfo: string) => {
return rendererInvoke<string>(WIN_MAIN_RENDERER_EVENT_NAME.overwrite_dislike_music_infos, dislikeInfo)
}
// export const updateDislikeInfo = async(dislikeInfo: LX.Dislike.ListItem[]) => {
// await rendererInvoke<LX.Dislike.ListItem[]>(WIN_MAIN_RENDERER_EVENT_NAME.update_dislike_music_infos, dislikeInfo)
// }
// export const removeDislikeInfo = async(ids: string[]) => {
// await rendererInvoke<string[]>(WIN_MAIN_RENDERER_EVENT_NAME.remove_dislike_music_infos, ids)
// }
// export const clearDislikeInfo = async() => {
// await rendererInvoke(WIN_MAIN_RENDERER_EVENT_NAME.clear_dislike_music_infos)
// }
export const getHotKeyConfig = async() => {
return rendererInvoke<LX.HotKeyConfigAll>(WIN_MAIN_RENDERER_EVENT_NAME.get_hot_key)
@@ -332,6 +350,11 @@ export const allHotKeys = markRaw({
action: hotKeys.HOTKEY_PLAYER.next.action,
type: APP_EVENT_NAMES.winMainName,
},
{
name: hotKeys.HOTKEY_PLAYER.music_dislike.name,
action: hotKeys.HOTKEY_PLAYER.music_dislike.action,
type: APP_EVENT_NAMES.winMainName,
},
{
name: hotKeys.HOTKEY_COMMON.focusSearchInput.name,
action: hotKeys.HOTKEY_COMMON.focusSearchInput.action,
@@ -394,6 +417,21 @@ export const allHotKeys = markRaw({
action: hotKeys.HOTKEY_PLAYER.volume_mute.action,
type: APP_EVENT_NAMES.winMainName,
},
{
name: hotKeys.HOTKEY_PLAYER.music_love.name,
action: hotKeys.HOTKEY_PLAYER.music_love.action,
type: APP_EVENT_NAMES.winMainName,
},
{
name: hotKeys.HOTKEY_PLAYER.music_unlove.name,
action: hotKeys.HOTKEY_PLAYER.music_unlove.action,
type: APP_EVENT_NAMES.winMainName,
},
{
name: hotKeys.HOTKEY_PLAYER.music_dislike.name,
action: hotKeys.HOTKEY_PLAYER.music_dislike.action,
type: APP_EVENT_NAMES.winMainName,
},
{
name: hotKeys.HOTKEY_DESKTOP_LYRIC.toggle_visible.name,
action: hotKeys.HOTKEY_DESKTOP_LYRIC.toggle_visible.action,
@@ -201,6 +201,7 @@ export default {
handleSearch,
handleOpenMusicDetail,
handleCopyName,
handleDislikeMusic,
handleRemoveMusic,
} = useMusicActions({ props, list, removeAllSelect, selectedList })
@@ -223,6 +224,7 @@ export default {
handleShowSortModal,
handleOpenMusicDetail,
handleCopyName,
handleDislikeMusic,
handleRemoveMusic,
})
@@ -1,6 +1,7 @@
import { computed, ref, shallowReactive, reactive, nextTick } from '@common/utils/vueTools'
import musicSdk from '@renderer/utils/musicSdk'
import { useI18n } from '@renderer/plugins/i18n'
import { hasDislike } from '@renderer/core/dislikeList'
export default ({
assertApiSupport,
@@ -15,6 +16,7 @@ export default ({
handleShowSortModal,
handleOpenMusicDetail,
handleCopyName,
handleDislikeMusic,
handleRemoveMusic,
}) => {
const itemMenuControl = reactive({
@@ -26,6 +28,7 @@ export default ({
sort: true,
download: true,
search: true,
dislike: true,
remove: true,
sourceDetail: true,
})
@@ -80,6 +83,11 @@ export default ({
action: 'search',
disabled: !itemMenuControl.search,
},
{
name: t('list__dislike'),
action: 'dislike',
disabled: !itemMenuControl.dislike,
},
{
name: t('list__remove'),
action: 'remove',
@@ -94,6 +102,8 @@ export default ({
// itemMenuControl.playLater =
itemMenuControl.download = assertApiSupport(musicInfo.source) && musicInfo.source != 'local'
itemMenuControl.dislike = !hasDislike(musicInfo)
menuLocation.x = event.pageX
menuLocation.y = event.pageY
@@ -138,6 +148,9 @@ export default ({
case 'search':
handleSearch(index)
break
case 'dislike':
handleDislikeMusic(index)
break
case 'remove':
handleRemoveMusic(index)
break
@@ -6,6 +6,9 @@ import { useI18n } from '@renderer/plugins/i18n'
import { removeListMusics } from '@renderer/store/list/action'
import { appSetting } from '@renderer/store/setting'
import { toOldMusicInfo } from '@renderer/utils/index'
import { addDislikeInfo, hasDislike } from '@renderer/core/dislikeList'
import { playNext } from '@renderer/core/player'
import { playMusicInfo } from '@renderer/store/player/state'
export default ({ props, list, selectedList, removeAllSelect }) => {
@@ -34,6 +37,14 @@ export default ({ props, list, selectedList, removeAllSelect }) => {
clipboardWriteText(appSetting['download.fileName'].replace('歌名', minfo.name).replace('歌手', minfo.singer))
}
const handleDislikeMusic = async(index) => {
const minfo = list.value[index]
await addDislikeInfo([{ name: minfo.name, singer: minfo.singer }])
if (!playMusicInfo.isTempPlay && hasDislike(playMusicInfo.musicInfo)) {
playNext(true)
}
}
const handleRemoveMusic = async(index, single) => {
if (selectedList.value.length && !single) {
const confirm = await (selectedList.value.length > 1
@@ -55,6 +66,7 @@ export default ({ props, list, selectedList, removeAllSelect }) => {
handleSearch,
handleOpenMusicDetail,
handleCopyName,
handleDislikeMusic,
handleRemoveMusic,
}
}
@@ -0,0 +1,112 @@
<template lang="pug">
material-modal(:show="modelValue" teleport="#view" height="80%" width="80%" @close="$emit('update:modelValue', false)")
main(:class="$style.main")
h2 {{ $t('setting__dislike_list_title') }}
div(:class="$style.content")
textarea(v-model="rules" :class="$style.textarea")
div(:class="$style.footer")
div(:class="$style.tips") {{ $t('setting__dislike_list_tips') }}
base-btn(:class="$style.btn" @click="handleSave") {{ $t('setting__dislike_list_save_btn') }}
</template>
<script>
import { watch, ref } from '@common/utils/vueTools'
import { overwirteDislikeInfo } from '@renderer/core/dislikeList'
import { dislikeInfo } from '@renderer/store/dislikeList'
export default {
props: {
modelValue: {
type: Boolean,
default: false,
},
},
emits: ['update:modelValue', 'onRuleUpdate'],
setup(props, { emit }) {
const rules = ref('')
const handleSave = async() => {
await overwirteDislikeInfo(rules.value)
emit('onRuleUpdate')
emit('update:modelValue', false)
}
watch(() => props.modelValue, (visible) => {
if (!visible) return
rules.value = dislikeInfo.rules
})
return {
rules,
handleSave,
}
},
}
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.main {
// padding: 15px;
// max-width: 400px;
// min-width: 460px;
// min-height: 200px;
// width: ;
flex: auto;
display: flex;
flex-flow: column nowrap;
justify-content: center;
// min-height: 0;
// max-height: 100%;
// overflow: hidden;
h2 {
margin: 20px;
font-size: 16px;
color: var(--color-font);
line-height: 1.3;
text-align: center;
}
}
.content {
flex: auto;
// min-height: 100px;
max-height: 100%;
display: flex;
padding: 0 15px;
}
.textarea {
width: 100%;
height: 100%;
border: none;
outline: none;
border-radius: 4px;
background-color: var(--color-primary-light-200-alpha-900);
box-sizing: border-box;
font-family: inherit;
resize: none;
}
.footer {
box-sizing: border-box;
flex: none;
// width: @width;
padding: 15px 15px;
// padding: 2px 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.tips {
// padding: 10px 15px;
font-size: 12px;
line-height: 1.25;
color: var(--color-550);
white-space: pre-wrap;
}
.btn {
min-width: 80px;
}
</style>
@@ -34,6 +34,16 @@ dd
base-btn.btn(min :disabled="isDisabledMusicUrlCacheClear" @click="handleClearMusicUrlCache") {{ $t('setting__other_music_url_clear_btn') }}
base-btn.btn(min :disabled="isDisabledLyricRawCacheClear" @click="handleClearLyricRawCache") {{ $t('setting__other_lyric_raw_clear_btn') }}
dd
h3#other_lyric_edited {{ $t('setting__other_dislike_list') }}
div
.p
| {{ $t('setting__other_dislike_list_label') }}
span.auto-hidden {{ dislikeRuleCount }}
.p
base-btn.btn(min @click="isShowDislikeList = true") {{ $t('setting__other_dislike_list_show_btn') }}
DislikeListModal(v-model="isShowDislikeList" @on-rule-update="handleCountRules")
dd
h3#other_lyric_edited {{ $t('setting__other_lyric_edited_cache') }}
div
@@ -65,9 +75,14 @@ import { dialog } from '@renderer/plugins/Dialog'
import { useI18n } from '@renderer/plugins/i18n'
import { appSetting, updateSetting } from '@renderer/store/setting'
import { overwriteListFull } from '@renderer/store/list/listManage'
import { dislikeInfo } from '@renderer/store/dislikeList'
import DislikeListModal from './DislikeListModal.vue'
export default {
name: 'SettingOther',
components: {
DislikeListModal,
},
setup() {
const t = useI18n()
@@ -135,6 +150,11 @@ export default {
}
refreshMusicUrlCount()
const dislikeRuleCount = ref(dislikeInfo.musicNames.size + dislikeInfo.singerNames.size + dislikeInfo.names.size)
const isShowDislikeList = ref(false)
const handleCountRules = () => {
dislikeRuleCount.value = dislikeInfo.musicNames.size + dislikeInfo.singerNames.size + dislikeInfo.names.size
}
const lyricRawCount = ref(0)
const isDisabledLyricRawCacheClear = ref(false)
@@ -204,6 +224,10 @@ export default {
isDisabledMusicUrlCacheClear,
handleClearMusicUrlCache,
dislikeRuleCount,
isShowDislikeList,
handleCountRules,
lyricRawCount,
isDisabledLyricRawCacheClear,
handleClearLyricRawCache,
+50 -3
View File
@@ -1,5 +1,6 @@
// import { throttle } from '@common/utils'
import { SPLIT_CHAR } from '@common/constants'
import { filterFileName, sortInsert, similar, arrPushByPosition, arrShuffle } from '@common/utils/common'
import { joinPath, saveStrToFile } from '@common/utils/nodejs'
import { createLocalMusicInfo } from '@renderer/utils/music'
@@ -8,7 +9,7 @@ import { createLocalMusicInfo } from '@renderer/utils/music'
/**
* 过滤列表中已播放的歌曲
*/
export const filterMusicList = async({ playedList, listId, list, savePath, playerMusicInfo }: {
export const filterMusicList = async({ playedList, listId, list, savePath, playerMusicInfo, dislikeInfo, isNext }: {
/**
* 已播放列表
*/
@@ -29,15 +30,34 @@ export const filterMusicList = async({ playedList, listId, list, savePath, playe
* 播放器内当前歌曲(`playInfo.playerPlayIndex`指向的歌曲)
*/
playerMusicInfo?: LX.Music.MusicInfo | LX.Download.ListItem
/**
* 不喜欢的歌曲名字列表
*/
dislikeInfo: Omit<LX.Dislike.DislikeInfo, 'rules'>
isNext: boolean
}) => {
let playerIndex = -1
let canPlayList: Array<LX.Music.MusicInfo | LX.Download.ListItem> = []
const filteredPlayedList = playedList.filter(pmInfo => pmInfo.listId == listId && !pmInfo.isTempPlay).map(({ musicInfo }) => musicInfo)
const hasDislike = (info: LX.Music.MusicInfo) => {
const name = info.name?.replaceAll(SPLIT_CHAR.DISLIKE_NAME, SPLIT_CHAR.DISLIKE_NAME_ALIAS).toLocaleLowerCase().trim() ?? ''
const singer = info.singer?.replaceAll(SPLIT_CHAR.DISLIKE_NAME, SPLIT_CHAR.DISLIKE_NAME_ALIAS).toLocaleLowerCase().trim() ?? ''
return dislikeInfo.musicNames.has(name) || dislikeInfo.singerNames.has(singer) ||
dislikeInfo.names.has(`${name}${SPLIT_CHAR.DISLIKE_NAME}${singer}`)
}
let isDislike = false
const filteredList: Array<LX.Music.MusicInfo | LX.Download.ListItem> = list.filter(s => {
// if (!assertApiSupport(s.source)) return false
if ('progress' in s && !s.isComplate) return false
if ('progress' in s) {
if (!s.isComplate) return false
} else if (hasDislike(s)) {
if (s.id != playerMusicInfo?.id) return false
isDislike = true
}
canPlayList.push(s)
@@ -49,7 +69,34 @@ export const filterMusicList = async({ playedList, listId, list, savePath, playe
return true
})
if (playerMusicInfo) {
playerIndex = (filteredList.length ? filteredList : canPlayList).findIndex(m => m.id == playerMusicInfo.id)
if (isDislike) {
if (filteredList.length <= 1) {
filteredList.splice(0, 1)
if (canPlayList.length > 1) {
let currentMusicIndex = canPlayList.findIndex(m => m.id == playerMusicInfo.id)
if (isNext) {
playerIndex = currentMusicIndex - 1
if (playerIndex < 0 && canPlayList.length > 1) playerIndex = canPlayList.length - 2
} else {
playerIndex = currentMusicIndex
if (canPlayList.length <= 1) playerIndex = -1
}
canPlayList.splice(currentMusicIndex, 1)
} else canPlayList.splice(0, 1)
} else {
let currentMusicIndex = filteredList.findIndex(m => m.id == playerMusicInfo.id)
if (isNext) {
playerIndex = currentMusicIndex - 1
if (playerIndex < 0 && filteredList.length > 1) playerIndex = filteredList.length - 2
} else {
playerIndex = currentMusicIndex
if (filteredList.length <= 1) playerIndex = -1
}
filteredList.splice(currentMusicIndex, 1)
}
} else {
playerIndex = (filteredList.length ? filteredList : canPlayList).findIndex(m => m.id == playerMusicInfo.id)
}
}
return {
filteredList,