Skip to content

Commit 1926144

Browse files
authored
Merge pull request #954 from imsyy/dev-lrc
给任务栏歌词支持了TTML的BG 然后给阿姨倒一杯卡布奇诺
2 parents d99e074 + 00d7c48 commit 1926144

26 files changed

Lines changed: 1246 additions & 662 deletions

electron/main/ipc/ipc-taskbar.ts

Lines changed: 30 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -8,56 +8,26 @@ import taskbarLyricManager from "../utils/taskbar-lyric-manager";
88

99
let cachedIsPlaying = false;
1010

11+
/** 读取完整任务栏配置 */
1112
const getTaskbarConfig = (): TaskbarConfig => {
12-
const store = useStore();
13-
return {
14-
mode: store.get("taskbar.mode", "taskbar"),
15-
maxWidth: store.get("taskbar.maxWidth", 300),
16-
position: store.get("taskbar.position", "automatic"),
17-
autoShrink: store.get("taskbar.autoShrink", false),
18-
margin: store.get("taskbar.margin", 10),
19-
minWidth: store.get("taskbar.minWidth", 10),
20-
enabled: store.get("taskbar.enabled", false),
21-
floatingAlign: store.get("taskbar.floatingAlign", "right"),
22-
floatingAutoWidth: store.get("taskbar.floatingAutoWidth", true),
23-
floatingWidth: store.get("taskbar.floatingWidth", 300),
24-
floatingHeight: store.get("taskbar.floatingHeight", 48),
25-
floatingAlwaysOnTop: store.get("taskbar.floatingAlwaysOnTop", false),
26-
27-
showWhenPaused: store.get("taskbar.showWhenPaused", true),
28-
showCover: store.get("taskbar.showCover", true),
29-
themeMode: store.get("taskbar.themeMode", "auto"),
30-
fontFamily: store.get("taskbar.fontFamily", ""),
31-
globalFont: store.get("taskbar.globalFont", ""),
32-
fontWeight: store.get("taskbar.fontWeight", 0),
33-
animationMode: store.get("taskbar.animationMode", "slide-blur"),
34-
singleLineMode: store.get("taskbar.singleLineMode", false),
35-
showTranslation: store.get("taskbar.showTranslation", true),
36-
showRomaji: store.get("taskbar.showRomaji", true),
37-
showWordLyrics: store.get("taskbar.showWordLyrics", true),
38-
};
13+
return useStore().get("taskbar");
3914
};
4015

16+
/** 根据配置更新窗口可见性 */
4117
const updateWindowVisibility = (config: TaskbarConfig) => {
4218
const tray = getMainTray();
43-
44-
if (tray) {
45-
tray.setTaskbarLyricShow(config.enabled);
19+
if (tray) tray.setTaskbarLyricShow(config.enabled);
20+
if (!config.enabled) {
21+
taskbarLyricManager.close(false);
22+
return;
4623
}
47-
48-
const shouldBeVisible = config.enabled && (cachedIsPlaying || config.showWhenPaused);
49-
24+
taskbarLyricManager.create(config.mode);
25+
const shouldBeVisible = cachedIsPlaying || config.showWhenPaused;
5026
taskbarLyricManager.setVisibility(shouldBeVisible);
5127
};
5228

53-
const updateWindowLayout = (animate: boolean = true) => {
54-
taskbarLyricManager.updateLayout(animate);
55-
};
56-
5729
const initTaskbarIpc = () => {
58-
// 在函数内部获取 store,确保在 app ready 事件之后
5930
const store = useStore();
60-
6131
const initialConfig = getTaskbarConfig();
6232
if (initialConfig.enabled) {
6333
taskbarLyricManager.create(initialConfig.mode);
@@ -68,67 +38,30 @@ const initTaskbarIpc = () => {
6838
taskbarLyricManager.setContentWidth(width);
6939
});
7040

71-
ipcMain.on(
72-
TASKBAR_IPC_CHANNELS.UPDATE_CONFIG,
73-
(_event, partialConfig: Partial<TaskbarConfig>) => {
74-
const oldConfig = getTaskbarConfig();
41+
ipcMain.handle(TASKBAR_IPC_CHANNELS.GET_OPTION, () => getTaskbarConfig());
7542

76-
Object.entries(partialConfig).forEach(([key, value]) => {
43+
// 设置配置(增量合并)
44+
ipcMain.on(
45+
TASKBAR_IPC_CHANNELS.SET_OPTION,
46+
(_event, option: Partial<TaskbarConfig>, pushToWindow = true) => {
47+
if (!option) return;
48+
// 增量更新
49+
const prev = getTaskbarConfig();
50+
const next = { ...prev, ...option };
51+
Object.entries(option).forEach(([key, value]) => {
7752
store.set(`taskbar.${key}`, value);
7853
});
79-
80-
const newConfig = getTaskbarConfig();
81-
82-
const modeChanged = newConfig.mode !== oldConfig.mode;
83-
84-
if (modeChanged) {
85-
taskbarLyricManager.close(false);
54+
// 推送到歌词窗口
55+
if (pushToWindow) {
56+
taskbarLyricManager.send(TASKBAR_IPC_CHANNELS.SYNC_STATE, {
57+
type: "config-update",
58+
data: option,
59+
} as SyncStatePayload);
8660
}
87-
88-
if (newConfig.enabled && (!oldConfig.enabled || modeChanged)) {
89-
taskbarLyricManager.create(newConfig.mode);
61+
updateWindowVisibility(next);
62+
if (next.enabled) {
63+
taskbarLyricManager.updateLayout(false);
9064
}
91-
92-
if (
93-
newConfig.enabled !== oldConfig.enabled ||
94-
newConfig.showWhenPaused !== oldConfig.showWhenPaused ||
95-
modeChanged
96-
) {
97-
updateWindowVisibility(newConfig);
98-
}
99-
100-
if (newConfig.enabled) {
101-
if (newConfig.mode === "taskbar") {
102-
if (
103-
newConfig.maxWidth !== oldConfig.maxWidth ||
104-
newConfig.position !== oldConfig.position ||
105-
newConfig.autoShrink !== oldConfig.autoShrink ||
106-
newConfig.margin !== oldConfig.margin ||
107-
newConfig.minWidth !== oldConfig.minWidth
108-
) {
109-
updateWindowLayout(true);
110-
}
111-
} else {
112-
const floatingWidthChanged =
113-
newConfig.floatingAutoWidth === false && newConfig.floatingWidth !== oldConfig.floatingWidth;
114-
if (
115-
newConfig.maxWidth !== oldConfig.maxWidth ||
116-
newConfig.floatingAlign !== oldConfig.floatingAlign ||
117-
newConfig.floatingAutoWidth !== oldConfig.floatingAutoWidth ||
118-
floatingWidthChanged ||
119-
newConfig.floatingHeight !== oldConfig.floatingHeight ||
120-
newConfig.floatingAlwaysOnTop !== oldConfig.floatingAlwaysOnTop ||
121-
modeChanged
122-
) {
123-
updateWindowLayout(false);
124-
}
125-
}
126-
}
127-
128-
taskbarLyricManager.send(TASKBAR_IPC_CHANNELS.SYNC_STATE, {
129-
type: "config-update",
130-
data: partialConfig,
131-
} as SyncStatePayload);
13265
},
13366
);
13467

@@ -174,9 +107,8 @@ const initTaskbarIpc = () => {
174107
// 把事件发射到 app 里不太好,但是我觉得也没有必要为了这一个事件创建一个事件总线
175108
// TODO: 如果有了事件总线,通过那个事件总线发射这个事件
176109
(app as EventEmitter).on("explorer-restarted", () => {
177-
const currentEnabled = store.get("taskbar.enabled");
178-
const currentMode = store.get("taskbar.mode", "taskbar");
179-
if (currentEnabled && currentMode === "taskbar") {
110+
const currentConfig = getTaskbarConfig();
111+
if (currentConfig.enabled && currentConfig.mode === "taskbar") {
180112
taskbarLyricManager.close(false);
181113
setTimeout(() => {
182114
taskbarLyricManager.create("taskbar");

electron/main/store/index.ts

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { DEFAULT_TASKBAR_CONFIG, type TaskbarConfig } from "@shared";
12
import { app, screen } from "electron";
23
import Store from "electron-store";
34
import { join } from "path";
@@ -40,32 +41,9 @@ export interface StoreType {
4041
config?: LyricConfig;
4142
};
4243
/** 任务栏歌词 */
43-
taskbar: {
44-
/** 是否启用 */
45-
enabled: boolean;
46-
/** 模式 */
47-
mode?: "taskbar" | "floating";
48-
/** 最大宽度 */
49-
maxWidth?: number;
50-
/** 显示封面 */
51-
showCover?: boolean;
52-
/** 位置 */
53-
position?: "automatic" | "left" | "right";
54-
/** 暂停时显示 */
55-
showWhenPaused?: boolean;
56-
/** 自动收缩 */
57-
autoShrink?: boolean;
58-
/** 边距 */
59-
margin?: number;
60-
/** 最小宽度 (百分比) */
61-
minWidth?: number;
44+
taskbar: TaskbarConfig & {
6245
floatingX?: number;
6346
floatingY?: number;
64-
floatingAlign?: "left" | "right";
65-
floatingAutoWidth?: boolean;
66-
floatingWidth?: number;
67-
floatingHeight?: number;
68-
floatingAlwaysOnTop?: boolean;
6947
};
7048
/** 代理 */
7149
proxy: string;
@@ -120,22 +98,9 @@ export const useStore = () => {
12098
config: defaultLyricConfig,
12199
},
122100
taskbar: {
123-
enabled: false,
124-
mode: "taskbar",
125-
maxWidth: 30,
126-
showCover: true,
127-
position: "automatic",
128-
showWhenPaused: true,
129-
autoShrink: false,
130-
margin: 10,
131-
minWidth: 10,
101+
...DEFAULT_TASKBAR_CONFIG,
132102
floatingX: screenData.workArea.x + screenData.workArea.width / 2 - 150,
133103
floatingY: screenData.workArea.y + screenData.workArea.height - 120,
134-
floatingAlign: "right",
135-
floatingAutoWidth: true,
136-
floatingWidth: 300,
137-
floatingHeight: 48,
138-
floatingAlwaysOnTop: false,
139104
},
140105
macos: {
141106
statusBarLyric: {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ class FloatingTaskbarLyricWindow {
209209
bounds.y !== nextY ||
210210
bounds.width !== nextWidth ||
211211
bounds.height !== nextHeight;
212-
if (shouldUpdate) this.win.setBounds({ x: nextX, y: nextY, width: nextWidth, height: nextHeight });
212+
if (shouldUpdate)
213+
this.win.setBounds({ x: nextX, y: nextY, width: nextWidth, height: nextHeight });
213214

214215
this.applyAlwaysOnTop(false);
215216
this.sendFloatingAlign(false);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type {
55
TrayWatcher,
66
UiaWatcher,
77
} from "@native/taskbar-lyric";
8-
import { TASKBAR_IPC_CHANNELS } from "@shared";
8+
import { TASKBAR_IPC_CHANNELS, type TaskbarConfig } from "@shared";
99
import { app, type BrowserWindow, nativeTheme, screen } from "electron";
1010
import { debounce } from "lodash-es";
1111
import { join } from "node:path";
@@ -259,7 +259,7 @@ class TaskbarLyricWindow {
259259
const maxWidthSetting = Math.round(
260260
(primaryDisplay.workAreaSize.width * this.maxWidthPercent) / 100,
261261
);
262-
const positionSetting = store.get("taskbar.position", "automatic");
262+
const positionSetting = store.get("taskbar.position", "automatic") as TaskbarConfig["position"];
263263
const autoShrink = store.get("taskbar.autoShrink", false);
264264
const MAX_WIDTH_PHYSICAL = autoShrink
265265
? Math.min(maxWidthSetting, this.contentWidth) * scaleFactor

src/components/List/ListDetail.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,11 @@
216216
</n-tab>
217217
<n-tab name="comments">
218218
评论
219-
<n-text v-if="settingStore.showCommentCount !== 'off' && detailData?.commentCount" class="count" depth="3">
219+
<n-text
220+
v-if="detailData?.commentCount"
221+
class="count"
222+
depth="3"
223+
>
220224
{{ formatCommentCount(detailData.commentCount) }}
221225
</n-text>
222226
</n-tab>

src/components/Modal/Setting/FontManager.vue

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,55 @@
144144
/>
145145
</n-flex>
146146
</n-card>
147+
<n-card class="set-item" :class="{ 'input-mode': isInputMode }">
148+
<div class="label">
149+
<div class="label-header">
150+
<div class="info" style="display: flex; flex-direction: column">
151+
<n-text class="name">任务栏歌词字体</n-text>
152+
<n-text class="tip" :depth="3"> 任务栏歌词使用的字体 </n-text>
153+
</div>
154+
<Transition name="fade" mode="out-in">
155+
<n-button
156+
:disabled="taskbarFontFamily === 'system-ui'"
157+
type="primary"
158+
strong
159+
secondary
160+
@click="saveTaskbarLyricFont('system-ui')"
161+
>
162+
恢复默认
163+
</n-button>
164+
</Transition>
165+
</div>
166+
</div>
167+
<n-flex align="center">
168+
<s-input
169+
v-if="settingStore.fontSettingStyle === 'custom'"
170+
:value="taskbarFontFamily"
171+
:update-value-on-input="false"
172+
placeholder="输入字体名称"
173+
class="set"
174+
@update:value="(val) => saveTaskbarLyricFont(val)"
175+
/>
176+
<n-select
177+
v-else-if="settingStore.fontSettingStyle === 'multi'"
178+
:value="fontFamilyToArray(taskbarFontFamily)"
179+
:options="getOptions('desktop')"
180+
class="set"
181+
filterable
182+
multiple
183+
tag
184+
@update:value="(val: string[]) => saveTaskbarLyricFont(fontArrayToFamily(val))"
185+
/>
186+
<n-select
187+
v-else-if="settingStore.fontSettingStyle === 'single'"
188+
:value="fontFamilyToDisplay(taskbarFontFamily)"
189+
:options="getOptions('desktop')"
190+
class="set"
191+
filterable
192+
@update:value="(val) => saveTaskbarLyricFont(fontDisplayToFamily(val))"
193+
/>
194+
</n-flex>
195+
</n-card>
147196
</div>
148197
<div class="set-list">
149198
<n-h3 prefix="bar">歌词字体</n-h3>
@@ -208,6 +257,7 @@
208257

209258
<script setup lang="ts">
210259
import { useSettingStore } from "@/stores";
260+
import { TASKBAR_IPC_CHANNELS } from "@/types/shared";
211261
import { isElectron } from "@/utils/env";
212262
import type { SelectOption } from "naive-ui";
213263
import { lyricFontConfigs } from "@/utils/lyric/lyricFontConfig";
@@ -217,9 +267,10 @@ import { cloneDeep, isEqual } from "lodash-es";
217267
218268
const settingStore = useSettingStore();
219269
270+
// 任务栏歌词字体
271+
const taskbarFontFamily = ref("system-ui");
220272
// 系统字体选项
221273
const systemFonts = ref<SelectOption[]>([]);
222-
223274
// 桌面歌词配置
224275
const desktopLyricConfig = reactive<LyricConfig>({ ...defaultDesktopLyricConfig });
225276
@@ -342,6 +393,18 @@ const fontArrayToFamily = (fontArray: string[]): string => {
342393
};
343394
344395
// 获取桌面歌词配置
396+
const getTaskbarLyricConfig = async () => {
397+
if (!isElectron) return;
398+
const config = await window.electron.ipcRenderer.invoke(TASKBAR_IPC_CHANNELS.GET_OPTION);
399+
if (config?.fontFamily) taskbarFontFamily.value = config.fontFamily;
400+
};
401+
402+
const saveTaskbarLyricFont = (fontFamily: string) => {
403+
if (!isElectron) return;
404+
taskbarFontFamily.value = fontFamily;
405+
window.electron.ipcRenderer.send(TASKBAR_IPC_CHANNELS.SET_OPTION, { fontFamily }, true);
406+
};
407+
345408
const getDesktopLyricConfig = async () => {
346409
if (!isElectron) return;
347410
const config = await window.electron.ipcRenderer.invoke("desktop-lyric:get-option");
@@ -375,6 +438,7 @@ const saveDesktopLyricConfig = (val?: string) => {
375438
onMounted(() => {
376439
getAllSystemFonts();
377440
getDesktopLyricConfig();
441+
getTaskbarLyricConfig();
378442
window.electron.ipcRenderer.on("desktop-lyric:update-option", onLyricConfigUpdate);
379443
});
380444

src/components/Modal/Setting/FullscreenPlayerManager.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const items: Item[] = [
4242
{ label: "显示复制歌词", key: "copyLyric" },
4343
{ label: "显示歌词调整", key: "lyricOffset" },
4444
{ label: "显示歌词设置", key: "lyricSettings" },
45+
{ label: "显示评论数量", key: "commentCount" },
4546
];
4647
4748
const updateSetting = (key: FullscreenPlayerElementKey, val: boolean) => {

src/components/Player/FullPlayer.vue

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,7 @@ const noLrc = computed<boolean>(() => {
121121
});
122122
123123
/** 是否处于纯净模式 */
124-
const pureLyricMode = computed<boolean>(
125-
() => statusStore.pureLyricMode && musicStore.isHasLrc,
126-
);
124+
const pureLyricMode = computed<boolean>(() => statusStore.pureLyricMode && musicStore.isHasLrc);
127125
128126
/* 是否显示全屏封面 */
129127
const showFullScreenCover = computed<boolean>(
@@ -293,7 +291,7 @@ onBeforeUnmount(() => {
293291
height: 100%;
294292
display: flex;
295293
flex-direction: column;
296-
mix-blend-mode: v-bind('settingStore.lyricsBlendMode');
294+
mix-blend-mode: v-bind("settingStore.lyricsBlendMode");
297295
transition:
298296
width 0.5s cubic-bezier(0.34, 1.56, 0.64, 1),
299297
opacity 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);

0 commit comments

Comments
 (0)