1919 </n-list >
2020 </n-checkbox-group >
2121 </n-scrollbar >
22- <n-flex align =" center" justify =" space-between" class =" footer" >
23- <n-flex align =" center" >
24- <n-checkbox-group v-model:value =" selectedFilters" >
25- <n-flex align =" center" >
26- <n-checkbox value =" translation" label =" 翻译" />
27- <n-checkbox value =" romaji" label =" 音译" />
28- <n-checkbox value =" emptyLine" label =" 空行" title =" 在每行歌词之间加入空行分隔" />
29- </n-flex >
30- </n-checkbox-group >
31- </n-flex >
32- <n-flex align =" center" >
33- <n-button @click =" selectAll" >全选</n-button >
22+ <n-divider />
23+ <n-flex vertical size =" small" class =" footer" >
24+ <n-text depth =" 2" class =" footer-title" >要复制的内容</n-text >
25+ <n-checkbox-group v-model:value =" selectedFilters" >
26+ <n-flex align =" center" wrap :size =" 12" class =" footer-options" >
27+ <n-checkbox value =" translation" label =" 翻译" />
28+ <n-checkbox value =" romaji" label =" 音译" />
29+ <n-checkbox value =" emptyLine" label =" 空行" title =" 在每行歌词之间加入空行分隔" />
30+ <n-checkbox value =" songName" label =" 歌名" />
31+ <n-checkbox value =" artist" label =" 歌手" />
32+ </n-flex >
33+ </n-checkbox-group >
34+ <n-flex justify =" end" align =" center" class =" footer-actions" >
35+ <n-button @click =" selectAll" >
36+ {{ isAllSelected ? "全不选" : "全选" }}
37+ </n-button >
3438 <n-button type =" primary" :disabled =" selectedLines.length === 0" @click =" handleCopy" >
3539 复制 ({{ selectedLines.length }})
3640 </n-button >
@@ -47,7 +51,7 @@ const props = defineProps<{ onClose: () => void }>();
4751
4852const musicStore = useMusicStore ();
4953
50- const selectedFilters = ref <string []>([" translation" , " romaji" , " emptyLine" ]);
54+ const selectedFilters = ref <string []>([" translation" , " romaji" , " emptyLine" , " songName " , " artist " ]);
5155const selectedLines = ref <number []>([]);
5256
5357const rawLyrics = computed (() => {
@@ -72,6 +76,10 @@ const displayLyrics = computed(() => {
7276const showTranslation = computed (() => selectedFilters .value .includes (" translation" ));
7377const showRomaji = computed (() => selectedFilters .value .includes (" romaji" ));
7478
79+ const isAllSelected = computed (
80+ () => displayLyrics .value .length > 0 && selectedLines .value .length === displayLyrics .value .length ,
81+ );
82+
7583const selectAll = () => {
7684 if (selectedLines .value .length === displayLyrics .value .length ) {
7785 selectedLines .value = [];
@@ -84,7 +92,7 @@ const selectAll = () => {
8492 * 复制歌词
8593 */
8694const handleCopy = async () => {
87- const linesToCopy = displayLyrics .value
95+ let linesToCopy = displayLyrics .value
8896 .filter ((l ) => selectedLines .value .includes (l .index ))
8997 .map ((l ) => {
9098 const parts: string [] = [];
@@ -96,6 +104,26 @@ const handleCopy = async () => {
96104 .filter ((s ) => s )
97105 .join (selectedFilters .value .includes (" emptyLine" ) ? " \n\n " : " \n " );
98106
107+ const showSongName = selectedFilters .value .includes (" songName" );
108+ const showArtist = selectedFilters .value .includes (" artist" );
109+
110+ if (showSongName || showArtist ) {
111+ const songName = musicStore .playSong .name ;
112+ const artistName = Array .isArray (musicStore .playSong .artists )
113+ ? musicStore .playSong .artists .map ((ar ) => ar .name ).join (" /" )
114+ : musicStore .playSong .artists ;
115+
116+ let suffix = " \n\n ——" ;
117+ if (showSongName && showArtist ) {
118+ suffix += ` 《${songName }》 - ${artistName } ` ;
119+ } else if (showSongName ) {
120+ suffix += ` 《${songName }》 ` ;
121+ } else if (showArtist ) {
122+ suffix += ` ${artistName } ` ;
123+ }
124+ linesToCopy += suffix ;
125+ }
126+
99127 if (linesToCopy ) {
100128 await copyData (linesToCopy );
101129 props .onClose ();
@@ -123,17 +151,34 @@ const handleCopy = async () => {
123151 .lyric-content {
124152 font-size : 14px ;
125153 line-height : 1.6 ;
154+
126155 .translation {
127156 font-size : 12px ;
128157 }
158+
129159 .romaji {
130160 font-size : 12px ;
131161 font-style : italic ;
132162 }
133163 }
134164}
135165
166+ .n-divider {
167+ margin : 16px 0 ;
168+ }
169+
136170.footer {
137- margin-top : 20px ;
171+ .footer-title {
172+ font-size : 13px ;
173+ margin-bottom : 4px ;
174+ }
175+
176+ .footer-options {
177+ margin-bottom : 8px ;
178+ }
179+
180+ .footer-actions {
181+ gap : 8px ;
182+ }
138183}
139184 </style >
0 commit comments