diff --git a/src/components/list/SongList.vue b/src/components/list/SongList.vue index 0f44e5dc1..1290b69ce 100644 --- a/src/components/list/SongList.vue +++ b/src/components/list/SongList.vue @@ -306,6 +306,7 @@ const emit = defineEmits<{ onActivated(batch.exit); defineExpose({ + sortedItems, /** 进入批量管理模式 */ enterBatch: batch.enter, }); diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 5da28c18f..bf1da913b 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -610,6 +610,7 @@ }, "liked": { "title": "Liked Songs", + "copyToClipboard": "Copy to Clipboard", "tabs": { "local": "Local", "online": "Online" diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index ab69e6023..c903955ac 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -610,6 +610,7 @@ }, "liked": { "title": "我喜欢的音乐", + "copyToClipboard": "复制到剪贴板", "tabs": { "local": "本地", "online": "在线" diff --git a/src/pages/Liked.vue b/src/pages/Liked.vue index 3062a9161..2ef790ea4 100644 --- a/src/pages/Liked.vue +++ b/src/pages/Liked.vue @@ -7,8 +7,10 @@ import type { DropdownMenuItem } from "@/components/ui/SDropdownMenu.vue"; import { useLibraryStore } from "@/stores/library"; import { useUserStore } from "@/stores/user"; import { useStatusStore } from "@/stores/status"; +import { useCopyText } from "@/composables/useCopyText"; import SongList from "@/components/list/SongList.vue"; import * as player from "@/core/player"; +import IconLucideCopy from "~icons/lucide/copy"; import IconLucideListChecks from "~icons/lucide/list-checks"; import IconLucideRefreshCw from "~icons/lucide/refresh-cw"; @@ -16,6 +18,7 @@ const { t } = useI18n(); const library = useLibraryStore(); const user = useUserStore(); const status = useStatusStore(); +const { copy } = useCopyText(); /** 当前 tab */ const tab = computed({ @@ -98,14 +101,34 @@ const moreMenuItems = computed(() => { label: t("songList.batch.manage"), icon: markRaw(IconLucideListChecks), }); + items.push({ + key: "copy", + label: t("liked.copyToClipboard"), + icon: markRaw(IconLucideCopy), + disabled: !songListRef.value?.sortedItems.length, + }); return items; }); -const handleMoreMenu = (key: string): void => { +/** + * 处理喜欢列表的刷新、批量管理与复制操作 + * @param key - 所选菜单操作 + */ +const handleMoreMenu = async (key: string): Promise => { if (key === "refresh") { user.ensureLikedPlaylist(true); } else if (key === "batch") { songListRef.value?.enterBatch(); + } else if (key === "copy") { + const tracks = songListRef.value?.sortedItems; + if (!tracks?.length) return; + await copy( + tracks + .map( + (track) => `${track.title} - ${track.artists.map((artist) => artist.name).join(" / ")}`, + ) + .join("\n"), + ); } };