fix(lyric): 桌面歌词三处 UI 问题(主题色重置/延迟控件遮挡/锁图标淡出)

- 主题色面板新增'恢复默认'按钮,接入已有 resetThemeColor(此前设置自定义
  主题色后无任何入口可关闭,#591)
- 全屏歌词页的歌词延迟调整控件 bottom 从 16px 提至 96px,越过钉底的
  PlayBar(80px, z-index 9999),不再被遮挡无法点击(#592)
- 锁定态锁图标增加空闲淡出:无鼠标活动 2.5s 后隐藏并恢复点击穿透,
  mousemove(forward:true 转发)即重新唤出,移出窗口立即隐藏(#606)

Closes #591
Closes #592
Closes #606
This commit is contained in:
alger
2026-07-05 15:13:58 +08:00
parent b50f69a65b
commit 9618cb9521
8 changed files with 103 additions and 7 deletions
+1
View File
@@ -400,6 +400,7 @@ export default {
themeColor: {
title: 'Lyric Theme Color',
presetColors: 'Preset Colors',
reset: 'Reset to Default',
customColor: 'Custom Color',
preview: 'Preview',
previewText: 'Lyric Effect',
+1
View File
@@ -399,6 +399,7 @@ export default {
themeColor: {
title: '歌詞テーマカラー',
presetColors: 'プリセットカラー',
reset: 'デフォルトに戻す',
customColor: 'カスタムカラー',
preview: 'プレビュー効果',
previewText: '歌詞効果',
+1
View File
@@ -400,6 +400,7 @@ export default {
themeColor: {
title: '가사 테마 색상',
presetColors: '미리 설정된 색상',
reset: '기본값으로 복원',
customColor: '사용자 정의 색상',
preview: '미리보기 효과',
previewText: '가사 효과',
+1
View File
@@ -396,6 +396,7 @@ export default {
themeColor: {
title: '歌词主题色',
presetColors: '预设颜色',
reset: '恢复默认',
customColor: '自定义颜色',
preview: '预览效果',
previewText: '歌词效果',
+1
View File
@@ -387,6 +387,7 @@ export default {
themeColor: {
title: '歌詞主題色',
presetColors: '預設顏色',
reset: '恢復預設',
customColor: '自訂顏色',
preview: '預覽效果',
previewText: '歌詞效果',
@@ -48,7 +48,8 @@ const { t } = useI18n();
<style scoped lang="scss">
.lyric-correction {
@apply absolute right-0 bottom-4 flex flex-col items-center space-y-1 z-50 select-none transition-opacity duration-200 opacity-0 pointer-events-none;
/* bottom 需越过全屏态下钉底的 PlayBarh-20=80px, z-index:9999),否则被遮挡无法点击(#592) */
@apply absolute right-0 bottom-24 flex flex-col items-center space-y-1 z-50 select-none transition-opacity duration-200 opacity-0 pointer-events-none;
}
.lyric-correction-btn {
@@ -7,8 +7,14 @@
>
<div class="panel-header">
<span class="panel-title">{{ t('settings.themeColor.title') }}</span>
<div class="close-button" @click="handleClose">
<i class="ri-close-line"></i>
<div class="header-actions">
<div class="reset-button" :title="t('settings.themeColor.reset')" @click="handleReset">
<i class="ri-arrow-go-back-line"></i>
<span>{{ t('settings.themeColor.reset') }}</span>
</div>
<div class="close-button" @click="handleClose">
<i class="ri-close-line"></i>
</div>
</div>
</div>
@@ -111,6 +117,7 @@ interface Props {
interface Emits {
(e: 'colorChange', _color: string): void;
(e: 'close'): void;
(e: 'reset'): void;
}
const props = withDefaults(defineProps<Props>(), {
@@ -160,6 +167,12 @@ const handleClose = () => {
emit('close');
};
// 恢复默认:关闭自定义主题色(#591 此前设置后无任何入口可关闭)
const handleReset = () => {
showColorPicker.value = false;
emit('reset');
};
const handlePresetColorSelect = (color: LyricThemeColor) => {
const colorValue = getColorValue(color);
const optimizedColor = optimizeColorForTheme(colorValue, props.theme);
@@ -301,6 +314,35 @@ watch(
opacity: 0.9;
}
.header-actions {
display: flex;
align-items: center;
gap: 6px;
}
.reset-button {
display: flex;
align-items: center;
gap: 4px;
height: 24px;
padding: 0 8px;
cursor: pointer;
border-radius: 6px;
color: var(--text-color);
font-size: 11px;
opacity: 0.8;
transition: all 0.2s ease;
&:hover {
background: rgba(255, 255, 255, 0.15);
opacity: 1;
}
i {
font-size: 12px;
}
}
.close-button {
width: 24px;
height: 24px;
+52 -4
View File
@@ -95,6 +95,7 @@
:theme="lyricSetting.theme"
@color-change="handleColorChange"
@close="handleThemeColorPanelClose"
@reset="handleThemeColorReset"
/>
<!-- 歌词显示区域 -->
@@ -365,6 +366,36 @@ const clearHideTimer = () => {
}
};
// 锁定态下锁图标空闲自动淡出(#606):
// 光标在窗口内且无活动 2.5s 后隐藏并恢复点击穿透;再次移动鼠标即重新唤出
const LOCKED_CONTROLS_HIDE_DELAY = 2500;
const scheduleLockedControlsHide = () => {
clearHideTimer();
hideControlsTimer = window.setTimeout(() => {
hideControlsTimer = null;
if (lyricSetting.value.isLock) {
isHovering.value = false;
windowData.electron.ipcRenderer.send('set-ignore-mouse', true);
}
}, LOCKED_CONTROLS_HIDE_DELAY);
};
const showLockedControls = () => {
if (!lyricSetting.value.isLock) return;
if (!isHovering.value) {
isHovering.value = true;
windowData.electron.ipcRenderer.send('set-ignore-mouse', false);
}
scheduleLockedControlsHide();
};
// 点击穿透开启时主进程以 forward:true 转发 mousemove,可用于重新唤出锁图标
const handleLockedMouseMove = () => {
if (!lyricSetting.value.isLock) return;
showLockedControls();
};
// 处理鼠标进入窗口
const handleMouseEnter = () => {
if (lyricSetting.value.isLock) {
@@ -396,6 +427,7 @@ const handleMouseLeave = () => {
watch(
() => lyricSetting.value.isLock,
(newLock: boolean) => {
clearHideTimer();
if (newLock) {
isHovering.value = false;
// 锁定时自动关闭主题色面板
@@ -410,10 +442,12 @@ onMounted(() => {
if (lyricSetting.value.isLock) {
isHovering.value = false;
}
document.addEventListener('mousemove', handleLockedMouseMove);
});
onUnmounted(() => {
clearHideTimer();
document.removeEventListener('mousemove', handleLockedMouseMove);
});
// 计算歌词滚动位置
@@ -788,10 +822,18 @@ onMounted(() => {
removeMousePresenceListener = window.ipcRenderer.on(
'lyric-mouse-presence',
(isInside: boolean) => {
isHovering.value = isInside;
if (lyricSetting.value.isLock) {
windowData.electron.ipcRenderer.send('set-ignore-mouse', !isInside);
if (isInside) {
// 进入窗口:显示锁图标并启动空闲淡出定时器(#606)
showLockedControls();
} else {
// 离开窗口:立即隐藏并恢复点击穿透
clearHideTimer();
isHovering.value = false;
windowData.electron.ipcRenderer.send('set-ignore-mouse', true);
}
} else {
isHovering.value = isInside;
}
}
);
@@ -849,7 +891,13 @@ const handleThemeColorPanelClose = () => {
showThemeColorPanel.value = false;
};
// 导出重置函数以供将来使用
// 面板"恢复默认":关闭自定义主题色并收起面板(#591)
const handleThemeColorReset = () => {
resetThemeColor();
showThemeColorPanel.value = false;
};
// 重置主题色到默认(主题色面板"恢复默认"按钮调用)
const resetThemeColor = () => {
// 重置到默认颜色
const defaultColor = getCurrentLyricThemeColor(lyricSetting.value.theme);