Skip to content
This repository was archived by the owner on Jul 17, 2026. It is now read-only.

✨ feat: 增加复制歌词功能 - #610

Merged
imsyy merged 3 commits into
devfrom
dev-player
Dec 5, 2025
Merged

imsyy merged 3 commits into
devfrom
dev-player

Conversation

@kazukokawagawa

Copy link
Copy Markdown
Collaborator

No description provided.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @kazukokawagawa, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求引入了一个全新的歌词复制功能,使用户能够方便地选择、过滤并复制当前播放歌曲的歌词。通过在歌词菜单中添加一个直观的复制按钮,用户可以打开一个模态框,在该模态框中,他们可以精确控制要复制的歌词内容,包括选择特定行以及决定是否包含原词、翻译或音译。这极大地提升了用户与歌词互动的灵活性和便利性。

Highlights

  • 新增歌词复制功能: 引入了一个新的模态框组件,允许用户选择并复制当前播放歌曲的歌词。
  • 歌词选择与过滤: 用户可以逐行选择歌词,并根据“原词”、“翻译”和“音译”进行过滤,以自定义复制内容。
  • 界面集成: 在播放器歌词菜单中添加了一个新的“复制”图标,用于快速访问歌词复制模态框。
  • Naive UI组件集成: 利用了Naive UI的NCheckboxGroup、NSpace等组件来构建复制歌词的用户界面,确保了良好的用户体验和视觉一致性。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

这个 PR 增加了复制歌词的功能,这是一个非常实用的新特性。整体实现很不错,包含了一个新的模态框组件、触发按钮以及处理歌词选择和格式化的逻辑。代码大体上写得很好。我发现了一些可以改进的地方,主要涉及处理不同歌词格式的逻辑以及模态框关闭时的一个潜在问题。具体请看我的详细评论。

Comment thread src/components/Modal/CopyLyrics.vue Outdated

const displayLyrics = computed(() => {
return rawLyrics.value.map((line, index) => {
const text = line.words?.map((w) => w.word).join("") || "";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

当前 displayLyrics 的实现中,当处理 lrcData (普通歌词) 时,text 字段会是空字符串,因为 lrcData 的歌词行对象没有 words 属性。这会导致普通歌词无法被复制。lrcData 的歌词内容通常在 content 属性中。建议修改 text 的取值逻辑,以兼容 lrcData 和 yrcData 两种格式。

    const text = line.words?.map((w) => w.word).join("") || line.content || "";

Comment thread src/components/Modal/CopyLyrics.vue Outdated

<n-scrollbar class="lyrics-list">
<n-checkbox-group v-model:value="selectedLines">
<div v-for="(line, index) in displayLyrics" :key="index" class="lyric-item">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

在 v-for 循环中,建议使用 line.index 作为 :key。line.index 是每行歌词的唯一且稳定的标识符,而 v-for 的 index 在列表项重排时可能会改变。使用 line.index 作为 key 有助于 Vue 更高效地更新 DOM,并避免潜在的渲染问题。

        <div v-for="line in displayLyrics" :key="line.index" class="lyric-item">

Comment thread src/utils/modal.ts
Comment on lines +389 to +402
export const openCopyLyrics = () => {
window.$modal.create({
preset: "card",
transformOrigin: "center",
autoFocus: false,
style: { width: "500px" },
title: "复制歌词",
content: () => {
return h(CopyLyrics, {
onClose: () => window.$modal.destroyAll(),
});
},
});
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

onClose 回调中使用了 window.$modal.destroyAll(),这会关闭所有当前打开的模态框,可能会导致意外行为。建议只关闭当前的模态框。可以像此文件中的其他 open... 函数一样,获取 create 方法返回的 modal 实例,然后在 onClose 中调用 modal.destroy()。

Suggested change
export const openCopyLyrics = () => {
window.$modal.create({
preset: "card",
transformOrigin: "center",
autoFocus: false,
style: { width: "500px" },
title: "复制歌词",
content: () => {
return h(CopyLyrics, {
onClose: () => window.$modal.destroyAll(),
});
},
});
};
export const openCopyLyrics = () => {
const modal = window.$modal.create({
preset: "card",
transformOrigin: "center",
autoFocus: false,
style: { width: "500px" },
title: "复制歌词",
content: () => {
return h(CopyLyrics, {
onClose: () => modal.destroy(),
});
},
});
};

@imsyy
imsyy merged commit a7a6108 into dev Dec 5, 2025
3 checks passed
apoint123 added a commit to apoint123/SPlayer that referenced this pull request Dec 5, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants