mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-03 14:20:50 +08:00
Merge branch 'main' into fix/downloadurl
This commit is contained in:
@@ -6,7 +6,9 @@ export default {
|
|||||||
addToPlaylist: 'Add to Playlist',
|
addToPlaylist: 'Add to Playlist',
|
||||||
favorite: 'Like',
|
favorite: 'Like',
|
||||||
unfavorite: 'Unlike',
|
unfavorite: 'Unlike',
|
||||||
removeFromPlaylist: 'Remove from Playlist'
|
removeFromPlaylist: 'Remove from Playlist',
|
||||||
|
dislike: 'Dislike',
|
||||||
|
undislike: 'Undislike',
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
downloading: 'Downloading, please wait...',
|
downloading: 'Downloading, please wait...',
|
||||||
@@ -14,5 +16,13 @@ export default {
|
|||||||
downloadQueued: 'Added to download queue',
|
downloadQueued: 'Added to download queue',
|
||||||
addedToNextPlay: 'Added to play next',
|
addedToNextPlay: 'Added to play next',
|
||||||
getUrlFailed: 'Failed to get music download URL, please check if logged in'
|
getUrlFailed: 'Failed to get music download URL, please check if logged in'
|
||||||
|
},
|
||||||
|
dialog: {
|
||||||
|
dislike:{
|
||||||
|
title: 'Dislike',
|
||||||
|
content: 'Are you sure you want to dislike this song?',
|
||||||
|
positiveText: 'Dislike',
|
||||||
|
negativeText: 'Cancel'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ export default {
|
|||||||
addToPlaylist: '添加到歌单',
|
addToPlaylist: '添加到歌单',
|
||||||
favorite: '喜欢',
|
favorite: '喜欢',
|
||||||
unfavorite: '取消喜欢',
|
unfavorite: '取消喜欢',
|
||||||
removeFromPlaylist: '从歌单中删除'
|
removeFromPlaylist: '从歌单中删除',
|
||||||
|
dislike: '不喜欢',
|
||||||
|
undislike: '取消不喜欢',
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
downloading: '正在下载中,请稍候...',
|
downloading: '正在下载中,请稍候...',
|
||||||
@@ -14,5 +16,13 @@ export default {
|
|||||||
downloadQueued: '已加入下载队列',
|
downloadQueued: '已加入下载队列',
|
||||||
addedToNextPlay: '已添加到下一首播放',
|
addedToNextPlay: '已添加到下一首播放',
|
||||||
getUrlFailed: '获取音乐下载地址失败,请检查是否登录'
|
getUrlFailed: '获取音乐下载地址失败,请检查是否登录'
|
||||||
|
},
|
||||||
|
dialog: {
|
||||||
|
dislike: {
|
||||||
|
title: '提示!',
|
||||||
|
content: '确认不喜欢这首歌吗?再次进入将从每日推荐中排除。',
|
||||||
|
positiveText: '不喜欢',
|
||||||
|
negativeText: '取消'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -134,7 +134,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import type { MenuOption } from 'naive-ui';
|
import type { MenuOption } from 'naive-ui';
|
||||||
import { NEllipsis, NImage, useMessage } from 'naive-ui';
|
import { NEllipsis, NImage, useMessage, useDialog } from 'naive-ui';
|
||||||
import { computed, h, inject, ref, useTemplateRef } from 'vue';
|
import { computed, h, inject, ref, useTemplateRef } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
@@ -306,7 +306,13 @@ const dropdownOptions = computed<MenuOption[]>(() => {
|
|||||||
h('i', {
|
h('i', {
|
||||||
class: `iconfont ${isFavorite.value ? 'ri-heart-fill text-red-500' : 'ri-heart-line'}`
|
class: `iconfont ${isFavorite.value ? 'ri-heart-fill text-red-500' : 'ri-heart-line'}`
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
|
// 不喜欢
|
||||||
|
{
|
||||||
|
label: isDislike.value ? t('songItem.menu.undislike') : t('songItem.menu.dislike'),
|
||||||
|
key: 'dislike',
|
||||||
|
icon: () => h('i', { class: `iconfont ${isDislike.value ? 'ri-dislike-fill text-green-500': 'ri-dislike-line'}` })
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
if (props.canRemove) {
|
if (props.canRemove) {
|
||||||
@@ -342,18 +348,30 @@ const handleMenuClick = (e: MouseEvent) => {
|
|||||||
|
|
||||||
const handleSelect = (key: string | number) => {
|
const handleSelect = (key: string | number) => {
|
||||||
showDropdown.value = false;
|
showDropdown.value = false;
|
||||||
if (key === 'download') {
|
switch (key) {
|
||||||
downloadMusic(props.item);
|
case 'download':
|
||||||
} else if (key === 'playNext') {
|
downloadMusic();
|
||||||
handlePlayNext();
|
break;
|
||||||
} else if (key === 'addToPlaylist') {
|
case 'playNext':
|
||||||
openPlaylistDrawer?.(props.item.id);
|
handlePlayNext();
|
||||||
} else if (key === 'favorite') {
|
break;
|
||||||
toggleFavorite(new Event('click'));
|
case 'addToPlaylist':
|
||||||
} else if (key === 'play') {
|
openPlaylistDrawer?.(props.item.id);
|
||||||
playMusicEvent(props.item);
|
break;
|
||||||
} else if (key === 'remove') {
|
case 'favorite':
|
||||||
emits('remove-song', props.item.id);
|
toggleFavorite(new Event('click'));
|
||||||
|
break;
|
||||||
|
case 'play':
|
||||||
|
playMusicEvent(props.item);
|
||||||
|
break;
|
||||||
|
case 'remove':
|
||||||
|
emits('remove-song', props.item.id);
|
||||||
|
break;
|
||||||
|
case 'dislike':
|
||||||
|
toggleDislike(new Event('click'));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -395,6 +413,12 @@ const isFavorite = computed(() => {
|
|||||||
return playerStore.favoriteList.includes(numericId);
|
return playerStore.favoriteList.includes(numericId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isDislike = computed(() => {
|
||||||
|
// 将id转换为number,兼容B站视频ID
|
||||||
|
const numericId = typeof props.item.id ==='string'? parseInt(props.item.id, 10) : props.item.id;
|
||||||
|
return playerStore.dislikeList.includes(numericId);
|
||||||
|
})
|
||||||
|
|
||||||
// 切换收藏状态
|
// 切换收藏状态
|
||||||
const toggleFavorite = async (e: Event) => {
|
const toggleFavorite = async (e: Event) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -407,6 +431,24 @@ const toggleFavorite = async (e: Event) => {
|
|||||||
playerStore.addToFavorite(numericId);
|
playerStore.addToFavorite(numericId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const dialog = useDialog();
|
||||||
|
const toggleDislike = async (e: Event) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
if (isDislike.value) {
|
||||||
|
playerStore.removeFromDislikeList(props.item.id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dialog.warning({
|
||||||
|
title: t('songItem.dialog.dislike.title'),
|
||||||
|
content: t('songItem.dialog.dislike.content'),
|
||||||
|
positiveText: t('songItem.dialog.dislike.positiveText'),
|
||||||
|
negativeText: t('songItem.dialog.dislike.negativeText'),
|
||||||
|
onPositiveClick: () => {
|
||||||
|
playerStore.addToDislikeList(props.item.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// 切换选择状态
|
// 切换选择状态
|
||||||
const toggleSelect = () => {
|
const toggleSelect = () => {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<p
|
<p
|
||||||
v-for="item in dayRecommendData?.dailySongs.slice(0, 5)"
|
v-for="item in getDisplayDaySongs.slice(0, 5)"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
class="text-el"
|
class="text-el"
|
||||||
>
|
>
|
||||||
@@ -250,13 +250,16 @@ const loadArtistData = async () => {
|
|||||||
// 加载不需要登录的数据
|
// 加载不需要登录的数据
|
||||||
const loadNonUserData = async () => {
|
const loadNonUserData = async () => {
|
||||||
try {
|
try {
|
||||||
|
// 获取每日推荐
|
||||||
// 获取每日推荐
|
try {
|
||||||
try {
|
|
||||||
const {
|
const {
|
||||||
data: { data: dayRecommend }
|
data: { data: dayRecommend }
|
||||||
} = await getDayRecommend();
|
} = await getDayRecommend();
|
||||||
dayRecommendData.value = dayRecommend as unknown as IDayRecommend;
|
const dayRecommendSource = dayRecommend as unknown as IDayRecommend;
|
||||||
|
dayRecommendData.value = {
|
||||||
|
...dayRecommendSource,
|
||||||
|
dailySongs: dayRecommendSource.dailySongs.filter((song: any) =>!playerStore.dislikeList.includes(song.id))
|
||||||
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取每日推荐失败:', error);
|
console.error('获取每日推荐失败:', error);
|
||||||
}
|
}
|
||||||
@@ -288,6 +291,12 @@ const loadUserData = async () => {
|
|||||||
const handleArtistClick = (id: number) => {
|
const handleArtistClick = (id: number) => {
|
||||||
navigateToArtist(id);
|
navigateToArtist(id);
|
||||||
};
|
};
|
||||||
|
const getDisplayDaySongs = computed(() => {
|
||||||
|
if(!dayRecommendData.value){
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return dayRecommendData.value.dailySongs.filter((song) => !playerStore.dislikeList.includes(song.id));
|
||||||
|
})
|
||||||
|
|
||||||
const showDayRecommend = () => {
|
const showDayRecommend = () => {
|
||||||
if (!dayRecommendData.value?.dailySongs) return;
|
if (!dayRecommendData.value?.dailySongs) return;
|
||||||
@@ -295,7 +304,7 @@ const showDayRecommend = () => {
|
|||||||
navigateToMusicList(router, {
|
navigateToMusicList(router, {
|
||||||
type: 'dailyRecommend',
|
type: 'dailyRecommend',
|
||||||
name: t('comp.recommendSinger.songlist'),
|
name: t('comp.recommendSinger.songlist'),
|
||||||
songList: dayRecommendData.value.dailySongs,
|
songList: getDisplayDaySongs.value,
|
||||||
canRemove: false
|
canRemove: false
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -394,6 +394,7 @@ export const usePlayerStore = defineStore('player', () => {
|
|||||||
const playMode = ref(getLocalStorageItem('playMode', 0));
|
const playMode = ref(getLocalStorageItem('playMode', 0));
|
||||||
const musicFull = ref(false);
|
const musicFull = ref(false);
|
||||||
const favoriteList = ref<Array<number | string>>(getLocalStorageItem('favoriteList', []));
|
const favoriteList = ref<Array<number | string>>(getLocalStorageItem('favoriteList', []));
|
||||||
|
const dislikeList = ref<Array<number | string>>(getLocalStorageItem('dislikeList', []));
|
||||||
const savedPlayProgress = ref<number | undefined>();
|
const savedPlayProgress = ref<number | undefined>();
|
||||||
const showSleepTimer = ref(false); // 定时弹窗
|
const showSleepTimer = ref(false); // 定时弹窗
|
||||||
// 添加播放列表抽屉状态
|
// 添加播放列表抽屉状态
|
||||||
@@ -1037,6 +1038,16 @@ export const usePlayerStore = defineStore('player', () => {
|
|||||||
localStorage.setItem('favoriteList', JSON.stringify(favoriteList.value));
|
localStorage.setItem('favoriteList', JSON.stringify(favoriteList.value));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const addToDislikeList = (id: number | string) => {
|
||||||
|
dislikeList.value.push(id);
|
||||||
|
localStorage.setItem('dislikeList', JSON.stringify(dislikeList.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeFromDislikeList = (id: number | string) => {
|
||||||
|
dislikeList.value = dislikeList.value.filter(existingId => existingId!== id);
|
||||||
|
localStorage.setItem('dislikeList', JSON.stringify(dislikeList.value));
|
||||||
|
}
|
||||||
|
|
||||||
const removeFromPlayList = (id: number | string) => {
|
const removeFromPlayList = (id: number | string) => {
|
||||||
const index = playList.value.findIndex((item) => item.id === id);
|
const index = playList.value.findIndex((item) => item.id === id);
|
||||||
if (index === -1) return;
|
if (index === -1) return;
|
||||||
@@ -1330,6 +1341,7 @@ export const usePlayerStore = defineStore('player', () => {
|
|||||||
musicFull,
|
musicFull,
|
||||||
savedPlayProgress,
|
savedPlayProgress,
|
||||||
favoriteList,
|
favoriteList,
|
||||||
|
dislikeList,
|
||||||
playListDrawerVisible,
|
playListDrawerVisible,
|
||||||
|
|
||||||
// 定时关闭相关
|
// 定时关闭相关
|
||||||
@@ -1364,6 +1376,8 @@ export const usePlayerStore = defineStore('player', () => {
|
|||||||
addToFavorite,
|
addToFavorite,
|
||||||
removeFromFavorite,
|
removeFromFavorite,
|
||||||
removeFromPlayList,
|
removeFromPlayList,
|
||||||
|
addToDislikeList,
|
||||||
|
removeFromDislikeList,
|
||||||
playAudio,
|
playAudio,
|
||||||
reparseCurrentSong,
|
reparseCurrentSong,
|
||||||
setPlayListDrawerVisible,
|
setPlayListDrawerVisible,
|
||||||
|
|||||||
@@ -238,6 +238,11 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 从 pinia 或路由参数获取数据
|
// 从 pinia 或路由参数获取数据
|
||||||
|
|
||||||
|
// 从路由参数获取
|
||||||
|
const routeId = route.params.id as string;
|
||||||
|
const routeType = route.query.type as string;
|
||||||
|
|
||||||
const initData = () => {
|
const initData = () => {
|
||||||
// 优先从 pinia 获取数据
|
// 优先从 pinia 获取数据
|
||||||
if (musicStore.currentMusicList) {
|
if (musicStore.currentMusicList) {
|
||||||
@@ -251,9 +256,7 @@ const initData = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从路由参数获取
|
|
||||||
const routeId = route.params.id as string;
|
|
||||||
const routeType = route.query.type as string;
|
|
||||||
|
|
||||||
if (routeId) {
|
if (routeId) {
|
||||||
// 这里根据 type 和 id 加载数据
|
// 这里根据 type 和 id 加载数据
|
||||||
@@ -323,14 +326,22 @@ const getCoverImgUrl = computed(() => {
|
|||||||
return '';
|
return '';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const getDisplaySongs = computed(() => {
|
||||||
|
if(routeType === 'dailyRecommend') {
|
||||||
|
return displayedSongs.value.filter((song) => !playerStore.dislikeList.includes(song.id));
|
||||||
|
}else {
|
||||||
|
return displayedSongs.value;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// 过滤歌曲列表
|
// 过滤歌曲列表
|
||||||
const filteredSongs = computed(() => {
|
const filteredSongs = computed(() => {
|
||||||
if (!searchKeyword.value) {
|
if (!searchKeyword.value) {
|
||||||
return displayedSongs.value;
|
return getDisplaySongs.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const keyword = searchKeyword.value.toLowerCase().trim();
|
const keyword = searchKeyword.value.toLowerCase().trim();
|
||||||
return displayedSongs.value.filter((song) => {
|
return getDisplaySongs.value.filter((song) => {
|
||||||
const songName = song.name?.toLowerCase() || '';
|
const songName = song.name?.toLowerCase() || '';
|
||||||
const albumName = song.al?.name?.toLowerCase() || '';
|
const albumName = song.al?.name?.toLowerCase() || '';
|
||||||
const artists = song.ar || song.artists || [];
|
const artists = song.ar || song.artists || [];
|
||||||
|
|||||||
Reference in New Issue
Block a user