From 346aab25a305a319607df18b64f80beda619803d Mon Sep 17 00:00:00 2001 From: Sakura520222 Date: Sun, 18 Oct 2026 21:16:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=A4=8D=E5=88=B6?= =?UTF-8?q?=E5=96=9C=E6=AC=A2=E5=88=97=E8=A1=A8=E7=9A=84=E5=BD=93=E5=89=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/list/SongList.vue | 1 + src/i18n/locales/en-US.json | 1 + src/i18n/locales/zh-CN.json | 1 + src/pages/Liked.vue | 25 ++++++++++++++++++++++++- 4 files changed, 27 insertions(+), 1 deletion(-) 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"), + ); } };