Skip to content

Commit 4419180

Browse files
committed
✨ feat: 添加默认的规则集以便和自定义分开
1 parent b0776fb commit 4419180

5 files changed

Lines changed: 117 additions & 56 deletions

File tree

src/components/Modal/Setting/ExcludeLyrics.vue

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,68 +2,65 @@
22
<div class="exclude">
33
<n-alert :show-icon="false">请勿添加过多,以免影响歌词的正常显示</n-alert>
44

5-
<n-tabs type="line" v-model:value="page" animated>
5+
<n-tabs v-model:value="page" animated>
66
<n-tab-pane name="keywords" tab="关键词">
7-
<n-dynamic-tags v-model:value="settingStore.excludeKeywords" />
7+
<n-scrollbar style="max-height: 70vh">
8+
<n-flex vertical :size="12">
9+
<n-dynamic-tags v-model:value="settingStore.excludeUserKeywords" />
10+
<n-button type="primary" strong secondary size="small" @click="resetUserKeywords">
11+
重置规则
12+
</n-button>
13+
</n-flex>
14+
</n-scrollbar>
815
</n-tab-pane>
16+
917
<n-tab-pane name="regexes" tab="正则表达式">
10-
<n-dynamic-tags v-model:value="settingStore.excludeRegexes" />
18+
<n-scrollbar style="max-height: 70vh">
19+
<n-flex vertical :size="12">
20+
<n-dynamic-tags v-model:value="settingStore.excludeUserRegexes" />
21+
<n-button type="primary" strong secondary size="small" @click="resetUserRegexes">
22+
重置规则
23+
</n-button>
24+
</n-flex>
25+
</n-scrollbar>
1126
</n-tab-pane>
12-
13-
<template #suffix>
14-
<n-flex>
15-
<n-button type="primary" strong secondary @click="clear">清空此页</n-button>
16-
<n-button type="primary" strong secondary @click="reset">重置此页</n-button>
17-
</n-flex>
18-
</template>
1927
</n-tabs>
2028
</div>
2129
</template>
2230

2331
<script setup lang="ts">
2432
import { useSettingStore } from "@/stores";
25-
import { keywords, regexes } from "@/assets/data/exclude";
2633
2734
const settingStore = useSettingStore();
2835
2936
const page = ref("keywords");
3037
31-
const pageConfig = {
32-
keywords: {
33-
name: "关键词",
34-
storeKey: "excludeKeywords",
35-
defaultValue: keywords,
36-
},
37-
regexes: {
38-
name: "正则表达式",
39-
storeKey: "excludeRegexes",
40-
defaultValue: regexes,
41-
},
42-
} as const;
43-
44-
const handleAction = (action: "clear" | "reset") => {
45-
const pageKey = page.value as keyof typeof pageConfig;
46-
const { name, storeKey, defaultValue } = pageConfig[pageKey];
47-
const isClear = action === "clear";
48-
49-
const actionText = isClear ? "清空" : "重置";
50-
const contentDetail = isClear ? "" : "为默认值";
51-
const successMessage = isClear ? "列表已清空" : "列表已重置为默认值";
52-
38+
// 重置规则
39+
const resetUserKeywords = () => {
5340
window.$dialog.warning({
54-
title: `${actionText}确认`,
55-
content: `确认${actionText}${name}列表${contentDetail}?该操作不可撤销!`,
41+
title: "重置确认",
42+
content: "确认清空所有关键词规则?该操作不可撤销!",
5643
positiveText: "确认",
5744
negativeText: "取消",
5845
onPositiveClick: () => {
59-
settingStore[storeKey] = isClear ? [] : defaultValue;
60-
window.$message.success(`${name}${successMessage}`);
46+
settingStore.excludeUserKeywords = [];
47+
window.$message.success("关键词规则已清空");
6148
},
6249
});
6350
};
6451
65-
const clear = () => handleAction("clear");
66-
const reset = () => handleAction("reset");
52+
const resetUserRegexes = () => {
53+
window.$dialog.warning({
54+
title: "重置确认",
55+
content: "确认清空所有正则表达式规则?该操作不可撤销!",
56+
positiveText: "确认",
57+
negativeText: "取消",
58+
onPositiveClick: () => {
59+
settingStore.excludeUserRegexes = [];
60+
window.$message.success("正则表达式规则已清空");
61+
},
62+
});
63+
};
6764
</script>
6865

6966
<style lang="scss" scoped>

src/core/player/LyricManager.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -324,17 +324,13 @@ class LyricManager {
324324
const settingStore = useSettingStore();
325325
const musicStore = useMusicStore();
326326

327-
const { enableExcludeLyrics, excludeKeywords, excludeRegexes } = settingStore;
327+
const { enableExcludeLyrics, excludeUserKeywords, excludeUserRegexes } = settingStore;
328328

329329
if (!enableExcludeLyrics) return lyricData;
330330

331-
// 将设置中和默认的预定义的关键字和正则表达式合并在一起给 stripLyricMetadata,方便之后更新默认的列表
332-
// TODO: 建议在设置界面加一个默认的规则集以便和用户自己加的关键字分开,也方便更新默认列表
333-
const userKeywords = excludeKeywords || [];
334-
const userRegexes = excludeRegexes || [];
335-
336-
const mergedKeywords = [...new Set([...userKeywords, ...defaultKeywords])];
337-
const mergedRegexes = [...new Set([...userRegexes, ...defaultRegexes])];
331+
// 合并默认规则和用户自定义规则
332+
const mergedKeywords = [...new Set([...defaultKeywords, ...(excludeUserKeywords ?? [])])];
333+
const mergedRegexes = [...new Set([...defaultRegexes, ...(excludeUserRegexes ?? [])])];
338334

339335
const { name, artists } = musicStore.playSong;
340336
const songMetadataRegexes: string[] = [];

src/stores/migrations/settingMigrations.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { SongUnlockServer } from "@/core/player/SongManager";
22
import type { SettingState } from "../setting";
33
import { defaultAMLLDbServer } from "@/utils/meta";
4+
import { keywords, regexes } from "@/assets/data/exclude";
45

56
/**
67
* 当前设置 Schema 版本号
78
*/
8-
export const CURRENT_SETTING_SCHEMA_VERSION = 4;
9+
export const CURRENT_SETTING_SCHEMA_VERSION = 5;
910

1011
/**
1112
* 迁移函数类型
@@ -36,5 +37,45 @@ export const settingMigrations: Record<number, MigrationFunction> = {
3637
],
3738
};
3839
},
40+
5: (state) => {
41+
// 迁移排除歌词关键字和正则表达式到用户自定义字段
42+
// 如果旧字段存在且不为空,则迁移到新字段
43+
// 定义旧版本的设置状态类型(包含已废弃的字段)
44+
interface OldSettingState extends Partial<SettingState> {
45+
excludeKeywords?: string[];
46+
excludeRegexes?: string[];
47+
}
48+
49+
const oldState = state as OldSettingState;
50+
const oldKeywords = oldState.excludeKeywords;
51+
const oldRegexes = oldState.excludeRegexes;
52+
53+
// 如果旧字段包含默认值,则只保留用户自定义的部分
54+
const userKeywords: string[] = [];
55+
const userRegexes: string[] = [];
56+
57+
if (oldKeywords && Array.isArray(oldKeywords)) {
58+
// 过滤掉默认关键字,只保留用户自定义的
59+
oldKeywords.forEach((keyword) => {
60+
if (!keywords.includes(keyword)) {
61+
userKeywords.push(keyword);
62+
}
63+
});
64+
}
65+
66+
if (oldRegexes && Array.isArray(oldRegexes)) {
67+
// 过滤掉默认正则,只保留用户自定义的
68+
oldRegexes.forEach((regex) => {
69+
if (!regexes.includes(regex)) {
70+
userRegexes.push(regex);
71+
}
72+
});
73+
}
74+
75+
return {
76+
excludeUserKeywords: userKeywords,
77+
excludeUserRegexes: userRegexes,
78+
};
79+
},
3980
};
4081

src/stores/setting.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { defineStore } from "pinia";
2-
import { keywords, regexes } from "@/assets/data/exclude";
32
import { SongUnlockServer } from "@/core/player/SongManager";
43
import type { SongLevelType } from "@/types/main";
54
import { defaultAMLLDbServer } from "@/utils/meta";
@@ -212,10 +211,10 @@ export interface SettingState {
212211
enableExcludeTTML: boolean;
213212
/** 「排除歌词」是否适用于本地歌词 */
214213
enableExcludeLocalLyrics: boolean;
215-
/** 排除歌词关键字 */
216-
excludeKeywords: string[];
217-
/** 排除歌词正则表达式 */
218-
excludeRegexes: string[];
214+
/** 用户自定义的排除歌词关键字 */
215+
excludeUserKeywords: string[];
216+
/** 用户自定义的排除歌词正则表达式 */
217+
excludeUserRegexes: string[];
219218
/** 显示默认本地路径 */
220219
showDefaultLocalPath: boolean;
221220
/** 本地文件夹显示模式 */
@@ -373,8 +372,8 @@ export const useSettingStore = defineStore("setting", {
373372
enableExcludeLyrics: true,
374373
enableExcludeTTML: false,
375374
enableExcludeLocalLyrics: false,
376-
excludeKeywords: keywords,
377-
excludeRegexes: regexes,
375+
excludeUserKeywords: [],
376+
excludeUserRegexes: [],
378377
localFilesPath: [],
379378
localLyricPath: [],
380379
showDefaultLocalPath: true,

src/utils/lyricStripper.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,26 @@
2121

2222
import { type LyricLine } from "@applemusic-like-lyrics/lyric";
2323

24+
const STRICT_MATCH_SEPARATORS = [
25+
":",
26+
":",
27+
",",
28+
",",
29+
".",
30+
"。",
31+
"!",
32+
"!",
33+
"-",
34+
"_",
35+
"(",
36+
"(",
37+
"[",
38+
"【",
39+
"{",
40+
"『",
41+
"「",
42+
];
43+
2444
/**
2545
* 扫描限制配置
2646
*/
@@ -149,7 +169,15 @@ function isStrictMatch(text: string, keywords: string[], regexes: RegExp[]): boo
149169
if (normalizedText.startsWith(normalizedKw)) {
150170
const remainder = normalizedText.slice(normalizedKw.length);
151171

152-
if (remainder.startsWith(":") || remainder.startsWith(":")) {
172+
// 如果剩余部分为空,说明完全匹配
173+
if (remainder.length === 0) {
174+
return true;
175+
}
176+
177+
// 检查分隔符
178+
// 允许的分隔符包括:冒号、逗号、句号、感叹号、连字符、括号等
179+
// 注意:normalizedText 已经移除了空格
180+
if (STRICT_MATCH_SEPARATORS.includes(remainder.charAt(0))) {
153181
return true;
154182
}
155183
}

0 commit comments

Comments
 (0)