Skip to content

Commit 9e793da

Browse files
Merge pull request #858 from imsyy/dev
1
2 parents 4d3d8a6 + 67c2221 commit 9e793da

8 files changed

Lines changed: 94 additions & 15 deletions

File tree

electron/main/windows/taskbar-lyric-window.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import { app, type BrowserWindow, ipcMain, nativeTheme, screen } from "electron"
99
import { debounce } from "lodash-es";
1010
import { join } from "node:path";
1111
import { processLog } from "../logger";
12+
import { useStore } from "../store";
1213
import { isDev, port } from "../utils/config";
1314
import { loadNativeModule } from "../utils/native-loader";
1415
import { createWindow } from "./index";
15-
import { useStore } from "../store";
1616

1717
type taskbarLyricModule = typeof import("@native/taskbar-lyric");
1818

@@ -113,6 +113,19 @@ class TaskbarLyricWindow {
113113

114114
this.win.loadURL(taskbarLyricUrl);
115115

116+
// 因为任务栏窗口非常小,默认嵌入的开发者工具完全无法使用,
117+
// 所以监听 F12 并按分离模式打开开发者工具
118+
this.win.webContents.on("before-input-event", (event, input) => {
119+
if (input.key === "F12" && input.type === "keyDown") {
120+
if (this.win?.webContents.isDevToolsOpened()) {
121+
this.win?.webContents.closeDevTools();
122+
} else {
123+
this.win?.webContents.openDevTools({ mode: "detach" });
124+
}
125+
event.preventDefault();
126+
}
127+
});
128+
116129
const sendTheme = () => {
117130
if (this.win && !this.win.isDestroyed()) {
118131
const isDark = nativeTheme.shouldUseDarkColors;

src/components/Player/PlayerLyric/AMLyric.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
:wordFadeWidth="settingStore.wordFadeWidth"
4040
:style="{
4141
'--display-count-down-show': settingStore.countDownShow ? 'flex' : 'none',
42-
'--amll-lp-font-size': settingStore.lyricFontSize + 'px',
42+
'--amll-lp-font-size': getFontSize(settingStore.lyricFontSize, settingStore.lyricFontSizeMode),
4343
'font-weight': settingStore.lyricFontWeight,
4444
'font-family': settingStore.LyricFont !== 'follow' ? settingStore.LyricFont : '',
4545
...lyricLangFontStyle(settingStore),
@@ -58,6 +58,7 @@ import { getLyricLanguage } from "@/utils/format";
5858
import { usePlayerController } from "@/core/player/PlayerController";
5959
import { cloneDeep } from "lodash-es";
6060
import { lyricLangFontStyle } from "@/utils/lyric/lyricFontConfig";
61+
import { getFontSize } from "@/utils/style";
6162
6263
defineProps({
6364
currentTime: {

src/components/Player/PlayerLyric/DefaultLyric.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
<div
33
:key="`lyric-${musicStore.playSong.id}`"
44
:style="{
5-
'--lrc-size': settingStore.lyricFontSize + 'px',
6-
'--lrc-tran-size': settingStore.lyricTranFontSize + 'px',
7-
'--lrc-roma-size': settingStore.lyricRomaFontSize + 'px',
5+
'--lrc-size': getFontSize(settingStore.lyricFontSize, settingStore.lyricFontSizeMode),
6+
'--lrc-tran-size': getFontSize(settingStore.lyricTranFontSize, settingStore.lyricFontSizeMode),
7+
'--lrc-roma-size': getFontSize(settingStore.lyricRomaFontSize, settingStore.lyricFontSizeMode),
88
'--lrc-bold': settingStore.lyricFontWeight,
99
'--lrc-left-padding': `${settingStore.lyricHorizontalOffset}px`,
1010
'font-family': settingStore.LyricFont !== 'follow' ? settingStore.LyricFont : '',
@@ -133,6 +133,7 @@ import { usePlayerController } from "@/core/player/PlayerController";
133133
import { getLyricLanguage } from "@/utils/format";
134134
import { isElectron } from "@/utils/env";
135135
import { lyricLangFontStyle } from "@/utils/lyric/lyricFontConfig";
136+
import { getFontSize } from "@/utils/style";
136137
137138
const props = defineProps({
138139
currentTime: {

src/components/Setting/components/LyricPreview.vue

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
'flex-direction': 'column',
66
'align-items': settingStore.lyricsPosition,
77
'--font-weight': settingStore.lyricFontWeight,
8-
'--font-size': settingStore.lyricFontSize,
9-
'--font-tran-size': tranFontSize,
10-
'--font-roma-size': romaFontSize,
8+
'--font-size': getFontSize(settingStore.lyricFontSize, settingStore.lyricFontSizeMode),
9+
'--font-tran-size': getFontSize(tranFontSize, settingStore.lyricFontSizeMode),
10+
'--font-roma-size': getFontSize(romaFontSize, settingStore.lyricFontSizeMode),
1111
'--transform-origin':
1212
settingStore.lyricsPosition === 'center'
1313
? 'center'
@@ -37,6 +37,7 @@
3737

3838
<script setup lang="ts">
3939
import { useSettingStore } from "@/stores";
40+
import { getFontSize } from "@/utils/style";
4041
4142
const settingStore = useSettingStore();
4243
@@ -72,15 +73,15 @@ const romaFontSize = fontSizeComputed("lyricRomaFontSize");
7273
7374
&:nth-of-type(1) {
7475
font-weight: var(--font-weight);
75-
font-size: calc(var(--font-size) * 1px);
76+
font-size: var(--font-size);
7677
}
7778
&:nth-of-type(2) {
7879
opacity: 0.6;
79-
font-size: calc(var(--font-tran-size) * 1px);
80+
font-size: var(--font-tran-size);
8081
}
8182
&:nth-of-type(3) {
8283
opacity: 0.6;
83-
font-size: calc(var(--font-roma-size) * 1px);
84+
font-size: var(--font-roma-size);
8485
}
8586
}
8687
}

src/components/Setting/config/lyric.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,25 @@ export const useLyricSettings = (): SettingConfig => {
9393
noWrapper: true,
9494
component: markRaw(LyricPreview),
9595
},
96+
{
97+
key: "lyricFontSizeMode",
98+
label: "自适应歌词大小",
99+
type: "switch",
100+
description: "开启后歌词大小将根据窗口高度自动缩放,避免全屏时过小或窗口时过大",
101+
value: computed({
102+
get: () => settingStore.lyricFontSizeMode === "adaptive",
103+
set: (v) => (settingStore.lyricFontSizeMode = v ? "adaptive" : "fixed"),
104+
}),
105+
},
96106
{
97107
key: "lyricFontSize",
98108
label: "歌词字体大小",
99109
type: "input-number",
100-
description: "单位 px,最小 12,最大 60",
110+
description: computed(() =>
111+
settingStore.lyricFontSizeMode === "adaptive"
112+
? "作为基准大小 (以 1080p 高度为准)"
113+
: "单位 px,最小 12,最大 60",
114+
),
101115
min: 12,
102116
max: 60,
103117
suffix: "px",
@@ -111,7 +125,11 @@ export const useLyricSettings = (): SettingConfig => {
111125
key: "lyricTranFontSize",
112126
label: "翻译歌词大小",
113127
type: "input-number",
114-
description: "单位 px,最小 5,最大 40",
128+
description: computed(() =>
129+
settingStore.lyricFontSizeMode === "adaptive"
130+
? "作为基准大小 (以 1080p 高度为准)"
131+
: "单位 px,最小 5,最大 40",
132+
),
115133
min: 5,
116134
max: 40,
117135
suffix: "px",
@@ -130,7 +148,11 @@ export const useLyricSettings = (): SettingConfig => {
130148
key: "lyricRomaFontSize",
131149
label: "音译歌词大小",
132150
type: "input-number",
133-
description: "单位 px,最小 5,最大 40",
151+
description: computed(() =>
152+
settingStore.lyricFontSizeMode === "adaptive"
153+
? "作为基准大小 (以 1080p 高度为准)"
154+
: "单位 px,最小 5,最大 40",
155+
),
134156
min: 5,
135157
max: 40,
136158
suffix: "px",

src/stores/setting.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ export interface SettingState {
7070
updateChannel: "stable" | "nightly";
7171
/** 隐藏 VIP 标签 */
7272
hideVipTag: boolean;
73+
/** 歌词字体大小模式 */
74+
lyricFontSizeMode: "fixed" | "adaptive";
7375
/** 歌词字体大小 */
7476
lyricFontSize: number;
7577
/** 歌词翻译字体大小 */
@@ -549,6 +551,7 @@ export const useSettingStore = defineStore("setting", {
549551
playSongDemo: false,
550552
scrobbleSong: false,
551553
dynamicCover: false,
554+
lyricFontSizeMode: "adaptive",
552555
lyricFontSize: 46,
553556
lyricTranFontSize: 22,
554557
lyricRomaFontSize: 18,

src/utils/lyric/qrc-parser.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,37 @@ const domParser: QRCParserFn = (xmlStr) => {
2626
}
2727
};
2828

29+
const decodeXml = (str: string) => {
30+
return str
31+
.replace(/&quot;/g, '"')
32+
.replace(/&apos;/g, "'")
33+
.replace(/&lt;/g, "<")
34+
.replace(/&gt;/g, ">")
35+
.replace(/&amp;/g, "&");
36+
};
37+
2938
// 实现正则策略
3039
const regexParser: QRCParserFn = (xmlStr) => {
3140
if (!xmlStr) return "";
41+
42+
// 尝试贪婪匹配 (处理 LyricContent="... "..." ..." 这种非标准 XML 引号未转义的情况)
43+
// 匹配从 LyricContent=" 开始,直到标签结束前的最后一个引号
44+
const greedyMatch = /LyricContent\s*=\s*"([\s\S]*)"\s*\/?>/.exec(xmlStr);
45+
if (greedyMatch) {
46+
const content = greedyMatch[1];
47+
// 启发式检查:如果提取的内容中包含类似 ` Attribute="` 的结构,说明贪婪匹配吃掉了其他属性
48+
// 这种情况下回退到非贪婪匹配
49+
if (!/\s+\w+\s*=\s*"/.test(content)) {
50+
return decodeXml(content);
51+
}
52+
}
53+
54+
// 标准非贪婪匹配 (兼容标准 XML 属性)
3255
const match = /LyricContent\s*=\s*"([^"]*)"/.exec(xmlStr);
56+
3357
// 如果没有匹配到 XML 结构,假设输入本身就是内容 (保持原有逻辑的兼容性)
34-
return match?.[1] || xmlStr;
58+
const result = match?.[1] || xmlStr;
59+
return decodeXml(result);
3560
};
3661

3762
// 避免每次调用时的运行时检查

src/utils/style.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
/**
3+
* 获取自适应或固定像素的字体大小
4+
* @param size 字体大小数值
5+
* @param mode 字体大小模式 ('adaptive' | 'fixed')
6+
* @returns CSS font-size 字符串
7+
*/
8+
export const getFontSize = (size: number, mode: string) => {
9+
if (mode === "adaptive") {
10+
return `calc(${size} / 1080 * 100vh)`;
11+
}
12+
return `${size}px`;
13+
};

0 commit comments

Comments
 (0)