From 22a4cfc1def941d6a555643bb4f438f4c006e695 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Thu, 11 Jan 2024 19:57:33 +0800 Subject: [PATCH] INIT --- LICENSE | 21 + README.md | 9 + betterncm-plugin/base.js | 185 ++++++++ betterncm-plugin/config.html | 753 +++++++++++++++++++++++++++++++++ betterncm-plugin/func.js | 275 ++++++++++++ betterncm-plugin/lyric.js | 230 ++++++++++ betterncm-plugin/manifest.json | 38 ++ betterncm-plugin/style.css | 191 +++++++++ betterncm-plugin/view.js | 390 +++++++++++++++++ 9 files changed, 2092 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 betterncm-plugin/base.js create mode 100644 betterncm-plugin/config.html create mode 100644 betterncm-plugin/func.js create mode 100644 betterncm-plugin/lyric.js create mode 100644 betterncm-plugin/manifest.json create mode 100644 betterncm-plugin/style.css create mode 100644 betterncm-plugin/view.js diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b8fa0c1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 沫烬染 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..b7651b4 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# NCMLyrics Frontend + +> Thanks https://github.com/mo-jinran/Taskbar-Lyrics + +## Installing + +1. Install betterNCM +2. Download the plugin +3. Put the plugin into \betterncm\plugins diff --git a/betterncm-plugin/base.js b/betterncm-plugin/base.js new file mode 100644 index 0000000..578273f --- /dev/null +++ b/betterncm-plugin/base.js @@ -0,0 +1,185 @@ +"use strict"; + + +plugin.onLoad(async () => { + const TaskbarLyricsPort = 10123; + + const TaskbarLyricsFetch = (path, params) => fetch( + `http://127.0.0.1:${TaskbarLyricsPort}${path}`, + { + method: "POST", + body: JSON.stringify(params), + headers: { + "Content-Type": "application/json" + } + } + ); + + const TaskbarLyricsAPI = { + // 字体设置 + font: { + font: params => TaskbarLyricsFetch("/font/font", params), + color: params => TaskbarLyricsFetch("/font/color", params), + style: params => TaskbarLyricsFetch("/font/style", params), + }, + + // 歌词设置 + lyrics: { + lyrics: params => TaskbarLyricsFetch("/lyrics/lyrics", params), + align: params => TaskbarLyricsFetch("/lyrics/align", params), + }, + + // 窗口设置 + window: { + position: params => TaskbarLyricsFetch("/window/position", params), + margin: params => TaskbarLyricsFetch("/window/margin", params), + screen: params => TaskbarLyricsFetch("/window/screen", params), + }, + + // 关闭 + close: params => TaskbarLyricsFetch("/close", params) + }; + + + // 对应Windows的枚举 + const WindowsEnum = { + WindowAlignment: { + WindowAlignmentAdaptive: 0, + WindowAlignmentLeft: 1, + WindowAlignmentCenter: 2, + WindowAlignmentRight: 3 + }, + DWRITE_TEXT_ALIGNMENT: { + DWRITE_TEXT_ALIGNMENT_LEADING: 0, + DWRITE_TEXT_ALIGNMENT_TRAILING: 1, + DWRITE_TEXT_ALIGNMENT_CENTER: 2, + DWRITE_TEXT_ALIGNMENT_JUSTIFIED: 3 + }, + DWRITE_FONT_WEIGHT: { + DWRITE_FONT_WEIGHT_THIN: 100, + DWRITE_FONT_WEIGHT_EXTRA_LIGHT: 200, + DWRITE_FONT_WEIGHT_ULTRA_LIGHT: 200, + DWRITE_FONT_WEIGHT_LIGHT: 300, + DWRITE_FONT_WEIGHT_SEMI_LIGHT: 350, + DWRITE_FONT_WEIGHT_NORMAL: 400, + DWRITE_FONT_WEIGHT_REGULAR: 400, + DWRITE_FONT_WEIGHT_MEDIUM: 500, + DWRITE_FONT_WEIGHT_DEMI_BOLD: 600, + DWRITE_FONT_WEIGHT_SEMI_BOLD: 600, + DWRITE_FONT_WEIGHT_BOLD: 700, + DWRITE_FONT_WEIGHT_EXTRA_BOLD: 800, + DWRITE_FONT_WEIGHT_ULTRA_BOLD: 800, + DWRITE_FONT_WEIGHT_BLACK: 900, + DWRITE_FONT_WEIGHT_HEAVY: 900, + DWRITE_FONT_WEIGHT_EXTRA_BLACK: 950, + DWRITE_FONT_WEIGHT_ULTRA_BLACK: 950 + }, + DWRITE_FONT_STYLE: { + DWRITE_FONT_STYLE_NORMAL: 0, + DWRITE_FONT_STYLE_OBLIQUE: 1, + DWRITE_FONT_STYLE_ITALIC: 2 + } + }; + + + // 默认的配置 + const defaultConfig = { + "font": { + "font_family": "Microsoft YaHei UI" + }, + "color": { + "basic": { + "light": { + "hex_color": 0x000000, + "opacity": 1.0 + }, + "dark": { + "hex_color": 0xFFFFFF, + "opacity": 1.0 + } + }, + "extra": { + "light": { + "hex_color": 0x000000, + "opacity": 1.0 + }, + "dark": { + "hex_color": 0xFFFFFF, + "opacity": 1.0 + } + } + }, + "style": { + "basic": { + "weight": { + "value": WindowsEnum.DWRITE_FONT_WEIGHT.DWRITE_FONT_WEIGHT_NORMAL, + "textContent": "Normal (400)" + }, + "slope": WindowsEnum.DWRITE_FONT_STYLE.DWRITE_FONT_STYLE_NORMAL, + "underline": false, + "strikethrough": false + }, + "extra": { + "weight": { + "value": WindowsEnum.DWRITE_FONT_WEIGHT.DWRITE_FONT_WEIGHT_NORMAL, + "textContent": "Normal (400)" + }, + "slope": WindowsEnum.DWRITE_FONT_STYLE.DWRITE_FONT_STYLE_NORMAL, + "underline": false, + "strikethrough": false + } + }, + "lyrics": { + "retrieval_method": { + "value": 1, + "textContent": "使用LibLyric解析获取歌词", + } + }, + "effect": { + "next_line_lyrics_position": { + "value": 0, + "textContent": "副歌词,下句歌词显示在这" + }, + "extra_show": { + "value": 2, + "textContent": "当前翻译,没则用上个选项" + }, + "adjust": 0.0 + }, + "align": { + "basic": WindowsEnum.DWRITE_TEXT_ALIGNMENT.DWRITE_TEXT_ALIGNMENT_LEADING, + "extra": WindowsEnum.DWRITE_TEXT_ALIGNMENT.DWRITE_TEXT_ALIGNMENT_LEADING + }, + "position": { + "position": { + "value": WindowsEnum.WindowAlignment.WindowAlignmentAdaptive, + "textContent": "自动,自适应选择左或右" + } + }, + "margin": { + "left": 0, + "right": 0 + }, + "screen": { + "parent_taskbar": { + "value": "Shell_TrayWnd", + "textContent": "主屏幕任务栏" + } + } + }; + + + const pluginConfig = { + get: name => Object.assign({}, defaultConfig[name], plugin.getConfig(name, defaultConfig[name])), + set: (name, value) => plugin.setConfig(name, value) + }; + + + this.base = { + TaskbarLyricsPort, + TaskbarLyricsAPI, + WindowsEnum, + defaultConfig, + pluginConfig + }; +}); diff --git a/betterncm-plugin/config.html b/betterncm-plugin/config.html new file mode 100644 index 0000000..4e224fc --- /dev/null +++ b/betterncm-plugin/config.html @@ -0,0 +1,753 @@ +
+ +
+ + + + + +
+ + +
+ +
+ +
+

+ 更换字体: + + +

+
+ 字体名称: + +
+
+ +
+ + +
+

+ 字体颜色: + + +

+
+ 主歌词-浅色模式: + + 透明度: + +
+
+ 主歌词-深色模式: + + 透明度: + +
+
+ 副歌词-浅色模式: + + 透明度: + +
+
+ 副歌词-深色模式: + + 透明度: + +
+
+ +
+ + +
+

+ 字体样式: + +

+
+ 主歌词-字体字重: +
+
Normal (400)
+
+
    +
  • Thin (100)
  • +
  • Extra-light (200)
  • +
  • Ultra-light (200)
  • +
  • Light (300)
  • +
  • Semi-light (350)
  • +
  • Normal (400)
  • +
  • Regular (400)
  • +
  • Medium (500)
  • +
  • Demi-bold (600)
  • +
  • Semi-bold (600)
  • +
  • Bold (700)
  • +
  • Extra-bold (800)
  • +
  • Ultra-bold (800)
  • +
  • Black (900)
  • +
  • Heavy (900)
  • +
  • Extra-black (950)
  • +
  • Ultra-black (950)
  • +
+
+
+
+
+ 主歌词-字体斜体: + + + +
+
+ 主歌词-下划线: + +
+
+ 主歌词-删除线: + +
+
+ 副歌词-字体字重: +
+
Normal (400)
+
+
    +
  • Thin (100)
  • +
  • Extra-light (200)
  • +
  • Ultra-light (200)
  • +
  • Light (300)
  • +
  • Semi-light (350)
  • +
  • Normal (400)
  • +
  • Regular (400)
  • +
  • Medium (500)
  • +
  • Demi-bold (600)
  • +
  • Semi-bold (600)
  • +
  • Bold (700)
  • +
  • Extra-bold (800)
  • +
  • Ultra-bold (800)
  • +
  • Black (900)
  • +
  • Heavy (900)
  • +
  • Extra-black (950)
  • +
  • Ultra-black (950)
  • +
+
+
+
+
+ 副歌词-字体斜体: + + + +
+
+ 副歌词-下划线: + +
+
+ 副歌词-删除线: + +
+
+
+ + +
+ +
+

+ 歌词设置: + +

+
+ 歌词开关: + +
+
+ 获取方法: +
+
使用LibLyric解析获取歌词
+
+
    +
  • 使用软件内词栏监听获取歌词
  • +
  • 使用LibLyric解析获取歌词
  • +
  • 使用RefinedNowPlaying歌词
  • +
+
+
+
+
+ +
+ + +
+

+ 显示效果: + + +

+
+ 延迟调整: + +
+
+ 下句歌词位置: +
+
副歌词,下句歌词显示在这
+
+
    +
  • 副歌词,下句歌词显示在这
  • +
  • 主歌词,下句歌词显示在这
  • +
  • 交错式,就跟桌面歌词一样
  • +
+
+
+
+
+ 副歌词显示: +
+
+
+
    +
  • 隐藏歌词,让歌词独占两行
  • +
  • 下句歌词,没则用上个选项
  • +
  • 当前翻译,没则用上个选项
  • +
  • 当前音译,没则用上个选项
  • +
+
+
+
+
+ +
+ + +
+

+ 对齐方式: + +

+
+ 主歌词: + + + +
+
+ 副歌词: + + + +
+
+
+ + +
+ +
+

+ 修改位置: + +

+
+ 窗口位置: +
+
靠左,占满剩余空间宽度
+
+
    +
  • 自动,自适应选择左或右
  • +
  • 靠左,占满剩余空间宽度
  • +
  • 中间,基于任务栏的宽度
  • +
  • 靠右,占满剩余空间宽度
  • +
+
+
+
+
+ +
+ + +
+

+ 修改边距: + + +

+
+ 左边距: + +
+
+ 右边距: + +
+
+ +
+ + +
+

+ 切换屏幕:(实验性功能,目前在副屏有BUG) + +

+
+ 父任务栏: +
+
主屏幕任务栏
+
+
    +
  • 主屏幕任务栏
  • +
  • 副屏幕任务栏
  • +
+
+
+
+
+
+ + +
+ +
+

+ 关于插件: +

+
+

+ 作者名称: + 🌈沫烬染🐾 +

+

+ 仓库链接: + Taskbar-Lyrics +

+

==================================================

+

以上链接均为Github,喜欢就来点个Star吧~

+

如有BUG或建议欢迎前来发Issue

+

有大佬感兴趣来Fork本项目提交PR

+

来帮助我们将此插件变得更好!

+
+
+ +
+ + +
+

+ 注意事项: +

+
+

本插件适用于Windows 11,且任务栏没用第三方软件重度修改

+

如遇到某些选项不生效,请尝试点击选项旁边的“恢复默认”按钮

+

如遇到不显示歌词,并且没有个性化的效果,请尝试“重载网易云”

+
+
+ +
+ + +
+

+ 杂七杂八: +

+
+

插件名称是“Taskbar-Lyrics”,“任务栏歌词”,不是状态栏呀

+

插件并非为BetterNCM提供的Native Plugin(DLL形式注入)

+

插件会启动任务栏歌词程序,并嵌入到任务栏中和开启HTTP服务器

+

插件端负责获取播放状态与歌词和一些个性化配置提供给软件端

+
+
+
+ + +
+
+

+ 1.6.3 +

+
+

-> | 优化代码,移除没必要的代码

+

-> | 修复打开下拉选择框后,点击其他区域无法收起的问题

+

-> | 修复使用RefinedNowPlaying歌词可能对不上的问题

+

-> | 将API的端口号从BetterNCM API的端口号+2改成-2

+
+
+ +
+ +
+

+ 1.6.2 +

+
+

-> | 修复一些选项失效的BUG

+

-> | 添加插件更新日志(之前的日志的会有些差错

+

-> | 添加新的歌词获取方式,使用RefinedNowPlaying歌词

+
+
+ +
+ +
+

+ 1.6.1 +

+
+

-> | 琐事调整,优化代码,统一风格

+

-> | 将一些选项换成下拉式选择框

+

-> | 添加窗口位置自适应

+

-> | 修复程序某些情况崩溃问题

+
+
+ +
+ +
+

+ 1.6.0 +

+
+

-> | 优化代码,区分API与设置的类别

+

-> | 添加显示效果设置,下句歌词位置

+

-> | 将副歌词显示与延迟调整移动到显示效果内

+

-> | 修改默认字体为:Microsoft YaHei UI

+
+
+ +
+ +
+

+ 1.5.7 +

+
+

-> | 纯音乐显示歌曲名与作曲家

+

-> | 修改设置界面分类

+
+
+ +
+ +
+

+ 1.5.6 +

+
+

-> | 修复获取的路径不标准导致无法启动软件的问题

+
+
+ +
+ +
+

+ 1.5.5 +

+
+

-> | 尝试解决软件不会启动的问题

+

-> | 优化代码,移除没用到的引入

+

-> | 解决刚打开软件时获取不到数据而报错的问题

+
+
+ +
+ +
+

+ 1.5.4 +

+
+

-> | 优化代码,删除无用的调试语句与注释

+

-> | 调整配置界面样式,配置界面适配亮暗主题

+

-> | 重写文字排版,修复文字右对齐后最后一个字只剩一半,修复文字超出部分没有被隐藏

+
+
+ +
+ +
+

+ 1.5.3 +

+
+

-> | 优化代码,调整配置界面,调整代码位置,删除调试语句

+

-> | 读取配置时,没有或无效的将使用默认值

+

-> | 解决切换歌曲后再切换到新的歌词获取方式时无法重新获取歌词的问题

+
+
+ +
+ +
+

+ 1.5.2 +

+
+

-> | 移除对libsonginfo的依赖

+

-> | 解决插件占用文件夹,复制软件到其他目录后运行

+

-> | 添加切换歌词获取方式选项

+

-> | 修改注意事项

+

-> | 优化代码,调整配置界面布局

+
+
+ +
+ +
+

+ 1.5.1 +

+
+

-> | 优化代码,调整配置界面

+

-> | 添加歌词时间调整

+
+
+ +
+ +
+

+ 1.5.0 +

+
+

-> | 重构/优化代码,重构配置界面,移除软件的互斥锁,修改一部分API

+

-> | 添加libsonginfo与liblyric依赖

+

-> | 添加通过liblyric获取歌词,并设为默认方式

+

-> | 添加修改副歌词的选项

+

-> | 修复下拉式选择框只能显示值的问题

+
+
+ +
+ +
+

+ 1.4.3 +

+
+

-> | 优化代码,修改函数导出导入,拆分代码

+

-> | 修复样式设置不生效的问题

+
+
+ +
+ +
+

+ 1.4.2 +

+
+

-> | 优化代码

+

-> | 添加回字体样式功能

+

-> | 修复样式设置不生效的问题

+

-> | 修复读取到不兼容的配置导致无法使用的问题

+
+
+ +
+ +
+

+ 1.4.1 +

+
+

-> | 优化代码,删除无用代码

+

-> | 修复第一次打开某些输入框不显示默认值

+

-> | 关闭歌词时停止对歌词变动的监控

+
+
+ +
+ +
+

+ 1.4.0 +

+
+

-> | 优化代码,删除无用代码

+

-> | 重构代码,从GDI+切换为Direct2D与DirectWrite

+

-> | 重构代码,插件端,将单文件拆分代码为多文件并注入

+

-> | 修复第一次打开某些输入框不显示默认值

+

-> | 关闭歌词时停止对歌词变动的监控

+

-> | 修复歌词位置无法设置在左边的问题

+
+
+ +
+ +
+

+ 1.3.1 +

+
+

-> | 微调歌词的字体大小与边距

+

-> | 优化代码,优化设置界面

+

-> | 更改为使用JSON传输数据

+

-> | 添加基于整个任务栏宽度居中的按钮

+
+
+ +
+ +
+

+ 1.3.0 +

+
+

-> | 添加修改边距选项

+

-> | 添加字体样式选项

+

-> | 修复歌词在手动关闭后再开启设置不生效的问题

+
+
+ +
+ +
+

+ 1.2.4 +

+
+

-> | 优化代码

+

-> | 添加歌词开关选项

+

-> | 修复关闭程序后本地http服务线程不会立刻结束的问题

+
+
+ +
+ +
+

+ 1.2.3 +

+
+

-> | 重构代码,软件端,优化代码

+

-> | 微调歌词的字体渲染与边距

+

-> | 更新插件预览图

+

-> | 修复修改位置某些情况下失效的问题

+

-> | 支持更多版本的任务栏

+
+
+ +
+ +
+

+ 1.2.2 +

+
+

-> | 修复了会显示控制台的问题

+
+
+ +
+ +
+

+ 1.2.1 +

+
+

-> | 修复了插件商店安装插件后无法启动的问题

+
+
+ +
+ +
+

+ 1.2.0 +

+
+

-> | 重构代码,优化代码,将软件端单文件拆分代码为多文件

+

-> | 添加启动,连接,关闭的提示

+

-> | 兼容Windows 11 21H2版本任务栏

+

-> | 修复页面刷新后不会关闭程序

+

-> | 修复歌词过长导致换行的问题

+
+
+ +
+ +
+

+ 1.1.0 +

+
+

-> | 重构项目结构

+
+
+ +
+ +
+

+ 1.0.4 +

+
+

-> | 优化代码

+

-> | 添加配置界面

+

-> | 自适应任务栏剩余宽度

+

-> | 添加切换屏幕选项

+

-> | 添加更换字体选项

+

-> | 添加字体颜色选项

+
+
+ +
+ +
+

+ 1.0.3 +

+
+

-> | 修复歌词带问号导致不显示

+

-> | 添加互斥锁,修复重复启动软件导致重叠多个窗口

+

-> | 监听网易云进程关闭

+

-> | 移除心跳检测机制

+

-> | 移除Worker

+

-> | 移除Hijack

+
+
+ +
+ +
+

+ 1.0.2 +

+
+

-> | 自适应windows深浅色模式

+

-> | 单行歌词放大居中占满双行

+

-> | 修复歌词上右键卡住的问题

+
+
+ +
+ +
+

+ 1.0.1 +

+
+

-> | 修复软件路径问题

+
+
+ +
+ +
+

+ 1.0.0 +

+
+

-> | 添加任务栏歌词插件

+
+
+
+
+
\ No newline at end of file diff --git a/betterncm-plugin/func.js b/betterncm-plugin/func.js new file mode 100644 index 0000000..78f1585 --- /dev/null +++ b/betterncm-plugin/func.js @@ -0,0 +1,275 @@ +"use strict"; + + +plugin.onLoad(async () => { + const { + TaskbarLyricsPort, + TaskbarLyricsAPI, + WindowsEnum, + defaultConfig, + pluginConfig + } = { ...this.base }; + const { startGetLyric, stopGetLyric } = { ...this.lyric }; + + + // 启动任务栏歌词软件 + const TaskbarLyricsStart = async () => { + TaskbarLyricsAPI.font.font(pluginConfig.get("font")); + TaskbarLyricsAPI.font.color(pluginConfig.get("color")); + TaskbarLyricsAPI.font.style(pluginConfig.get("style")); + TaskbarLyricsAPI.window.position(pluginConfig.get("position")); + TaskbarLyricsAPI.window.margin(pluginConfig.get("margin")); + TaskbarLyricsAPI.lyrics.align(pluginConfig.get("align")); + TaskbarLyricsAPI.window.screen(pluginConfig.get("screen")); + startGetLyric(); + }; + + + // 关闭任务栏歌词软件 + const TaskbarLyricsClose = async () => { + TaskbarLyricsAPI.close({}); + stopGetLyric(); + }; + + + addEventListener("beforeunload", TaskbarLyricsClose); + TaskbarLyricsStart(); + + + // 更换字体 + const font = { + apply: elements => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("font"))); + config["font_family"] = elements.fontFamily.value; + pluginConfig.set("font", config); + TaskbarLyricsAPI.font.font(config); + }, + reset: elements => { + pluginConfig.set("font", undefined); + TaskbarLyricsAPI.font.font(defaultConfig["font"]); + elements.fontFamily.value = defaultConfig["font"]["font_family"]; + } + } + + + // 字体颜色 + const color = { + apply: elements => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("color"))); + config["basic"]["light"]["hex_color"] = parseInt(elements.basicLightColor.value.slice(1), 16); + config["basic"]["light"]["opacity"] = Number(elements.basicLightOpacity.value); + config["basic"]["dark"]["hex_color"] = parseInt(elements.basicDarkColor.value.slice(1), 16); + config["basic"]["dark"]["opacity"] = Number(elements.basicDarkOpacity.value); + config["extra"]["light"]["hex_color"] = parseInt(elements.extraLightColor.value.slice(1), 16); + config["extra"]["light"]["opacity"] = Number(elements.extraLightOpacity.value); + config["extra"]["dark"]["hex_color"] = parseInt(elements.extraDarkColor.value.slice(1), 16); + config["extra"]["dark"]["opacity"] = Number(elements.extraDarkOpacity.value); + pluginConfig.set("color", config); + TaskbarLyricsAPI.font.color(config); + }, + reset: elements => { + elements.basicLightColor.value = `#${defaultConfig["color"]["basic"]["light"]["hex_color"].toString(16).padStart(6, "0")}`; + elements.basicLightOpacity.value = defaultConfig["color"]["basic"]["light"]["opacity"]; + elements.basicDarkColor.value = `#${defaultConfig["color"]["basic"]["dark"]["hex_color"].toString(16).padStart(6, "0")}`; + elements.basicDarkOpacity.value = defaultConfig["color"]["basic"]["dark"]["opacity"]; + elements.extraLightColor.value = `#${defaultConfig["color"]["extra"]["light"]["hex_color"].toString(16).padStart(6, "0")}`; + elements.extraLightOpacity.value = defaultConfig["color"]["extra"]["light"]["opacity"]; + elements.extraDarkColor.value = `#${defaultConfig["color"]["extra"]["dark"]["hex_color"].toString(16).padStart(6, "0")}`; + elements.extraDarkOpacity.value = defaultConfig["color"]["extra"]["dark"]["opacity"]; + pluginConfig.set("color", undefined); + TaskbarLyricsAPI.font.color(defaultConfig["color"]); + } + } + + + // 字体样式 + const style = { + setWeight: (name, value, textContent) => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("style"))); + config[name].weight.value = Number(value); + config[name].weight.textContent = textContent; + pluginConfig.set("style", config); + TaskbarLyricsAPI.font.style(config); + }, + setSlopeNormal: event => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("style"))); + config[event.target.dataset.type].slope = WindowsEnum.DWRITE_FONT_STYLE.DWRITE_FONT_STYLE_NORMAL; + pluginConfig.set("style", config); + TaskbarLyricsAPI.font.style(config); + }, + setSlopeOblique: event => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("style"))); + config[event.target.dataset.type].slope = WindowsEnum.DWRITE_FONT_STYLE.DWRITE_FONT_STYLE_OBLIQUE; + pluginConfig.set("style", config); + TaskbarLyricsAPI.font.style(config); + }, + setSlopeItalic: event => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("style"))); + config[event.target.dataset.type].slope = WindowsEnum.DWRITE_FONT_STYLE.DWRITE_FONT_STYLE_ITALIC; + pluginConfig.set("style", config); + TaskbarLyricsAPI.font.style(config); + }, + setUnderline: event => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("style"))); + config[event.target.dataset.type].underline = event.target.checked; + pluginConfig.set("style", config); + TaskbarLyricsAPI.font.style(config); + }, + setStrikethrough: event => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("style"))); + config[event.target.dataset.type].strikethrough = event.target.checked; + pluginConfig.set("style", config); + TaskbarLyricsAPI.font.style(config); + }, + reset: elements => { + pluginConfig.set("style", undefined); + TaskbarLyricsAPI.font.style(defaultConfig["style"]); + elements.basicWeightValue.textContent = defaultConfig["style"]["basic"]["weight"]["textContent"]; + elements.basicUnderline.checked = defaultConfig["style"]["basic"]["underline"]; + elements.basicStrikethrough.checked = defaultConfig["style"]["basic"]["strikethrough"]; + elements.extraWeightValue.textContent = defaultConfig["style"]["extra"]["weight"]["textContent"]; + elements.extraUnderline.checked = defaultConfig["style"]["extra"]["underline"]; + elements.extraStrikethrough.checked = defaultConfig["style"]["extra"]["strikethrough"]; + } + } + + + // 歌词设置 + const lyrics = { + lyricsSwitch: event => event.target.checked ? TaskbarLyricsStart() : TaskbarLyricsClose(), + setRetrievalMethod: (value, textContent) => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("lyrics"))); + config["retrieval_method"]["value"] = Number(value); + config["retrieval_method"]["textContent"] = textContent; + stopGetLyric(); + pluginConfig.set("lyrics", config); + startGetLyric(); + }, + reset: elements => { + elements.retrievalMethodValue.textContent = defaultConfig["lyrics"]["retrieval_method"]["textContent"]; + stopGetLyric(); + pluginConfig.set("lyrics", undefined); + startGetLyric(); + } + } + + + // 显示效果 + const effect = { + setNextLineLyricsPosition: (value, textContent) => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("effect"))); + config["next_line_lyrics_position"]["value"] = Number(value); + config["next_line_lyrics_position"]["textContent"] = textContent; + pluginConfig.set("effect", config); + }, + setExtraShow: (value, textContent) => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("effect"))); + config["extra_show"]["value"] = Number(value); + config["extra_show"]["textContent"] = textContent; + pluginConfig.set("effect", config); + }, + apply: elements => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("effect"))); + config["adjust"] = Number(elements.adjust.value); + pluginConfig.set("effect", config); + }, + reset: elements => { + elements.nextLineLyricsPositionValue.textContent = defaultConfig["effect"]["next_line_lyrics_position"]["textContent"]; + elements.extraShowValue.textContent = defaultConfig["effect"]["extra_show"]["textContent"]; + elements.adjust.value = defaultConfig["effect"]["adjust"]; + pluginConfig.set("effect", undefined); + } + } + + + // 对齐方式 + const align = { + setLeft: event => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("align"))); + config[event.target.dataset.type] = WindowsEnum.DWRITE_TEXT_ALIGNMENT.DWRITE_TEXT_ALIGNMENT_LEADING; + pluginConfig.set("align", config); + TaskbarLyricsAPI.lyrics.align(config); + }, + setCenter: event => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("align"))); + config[event.target.dataset.type] = WindowsEnum.DWRITE_TEXT_ALIGNMENT.DWRITE_TEXT_ALIGNMENT_CENTER; + pluginConfig.set("align", config); + TaskbarLyricsAPI.lyrics.align(config); + }, + setRight: event => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("align"))); + config[event.target.dataset.type] = WindowsEnum.DWRITE_TEXT_ALIGNMENT.DWRITE_TEXT_ALIGNMENT_TRAILING; + pluginConfig.set("align", config); + TaskbarLyricsAPI.lyrics.align(config); + }, + reset: () => { + pluginConfig.set("align", undefined); + TaskbarLyricsAPI.lyrics.align(defaultConfig["align"]); + } + } + + + // 修改位置 + const position = { + setWindowPosition: (value, textContent) => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("position"))); + config["position"]["value"] = Number(value); + config["position"]["textContent"] = textContent; + pluginConfig.set("position", config); + TaskbarLyricsAPI.window.position(config); + }, + reset: elements => { + elements.windowPositionValue.textContent = defaultConfig["position"]["position"]["textContent"]; + pluginConfig.set("position", undefined); + TaskbarLyricsAPI.window.position(defaultConfig["position"]); + } + } + + + // 修改边距 + const margin = { + apply: elements => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("margin"))); + config["left"] = Number(elements.left.value); + config["right"] = Number(elements.right.value); + pluginConfig.set("margin", config); + TaskbarLyricsAPI.window.margin(config); + }, + reset: elements => { + pluginConfig.set("margin", undefined); + TaskbarLyricsAPI.window.margin(defaultConfig["margin"]); + elements.left.value = defaultConfig["margin"]["left"]; + elements.right.value = defaultConfig["margin"]["right"]; + } + } + + + // 切换屏幕 + const screen = { + setParentTaskbar: (value, textContent) => { + const config = JSON.parse(JSON.stringify(pluginConfig.get("screen"))); + config["parent_taskbar"]["value"] = value; + config["parent_taskbar"]["textContent"] = textContent; + pluginConfig.set("screen", config); + TaskbarLyricsAPI.window.screen(config); + }, + reset: elements => { + elements.parentTaskbarValue.textContent = defaultConfig["screen"]["parent_taskbar"]["textContent"]; + pluginConfig.set("screen", undefined); + TaskbarLyricsAPI.window.screen(defaultConfig["screen"]); + } + } + + + this.func = { + font, + color, + style, + lyrics, + effect, + align, + position, + margin, + screen + }; +}); diff --git a/betterncm-plugin/lyric.js b/betterncm-plugin/lyric.js new file mode 100644 index 0000000..5c8e60e --- /dev/null +++ b/betterncm-plugin/lyric.js @@ -0,0 +1,230 @@ +"use strict"; + + +plugin.onLoad(async () => { + const { TaskbarLyricsAPI, pluginConfig } = { ...this.base }; + const liblyric = loadedPlugins.liblyric; + + + let observer = null; + let parsedLyric = null; + let currentIndex = 0; + let musicId = 0; + let currentLine = 0; + + + // 监视软件内歌词变动 + const watchLyricsChange = async () => { + const mLyric = await betterncm.utils.waitForElement("#x-g-mn .m-lyric"); + const MutationCallback = mutations => { + for (const mutation of mutations) { + let lyrics = { + basic: "", + extra: "" + }; + + if (mutation.addedNodes[2]) { + lyrics.basic = mutation.addedNodes[0].firstChild.textContent; + lyrics.extra = mutation.addedNodes[2].firstChild ? mutation.addedNodes[2].firstChild.textContent : ""; + } else { + lyrics.basic = mutation.addedNodes[0].textContent; + } + + TaskbarLyricsAPI.lyrics.lyrics(lyrics); + } + } + + observer = new MutationObserver(MutationCallback); + observer.observe(mLyric, { childList: true, subtree: true }); + } + + + // 音乐ID发生变化时 + const play_load = async () => { + // 获取歌曲信息 + const playingSong = betterncm.ncm.getPlayingSong(); + musicId = playingSong.data.id ?? 0; + const name = playingSong.data.name ?? ""; + const artists = playingSong.data.artists ?? ""; + + // 解析歌手名称 + let artistName = ""; + artists.forEach(item => artistName += ` / ${item.name}`); + artistName = artistName.slice(3); + + // 发送歌曲信息 + TaskbarLyricsAPI.lyrics.lyrics({ + "basic": name, + "extra": artistName + }); + + + // 解析歌词 + const config = pluginConfig.get("lyrics"); + if ((config["retrieval_method"]["value"] == "2") && window.currentLyrics) { + // 解决RNP歌词对不上的问题 + while (true) { + if (window.currentLyrics.hash.includes(musicId)) { + parsedLyric = window.currentLyrics.lyrics; + break; + } else { + await betterncm.utils.delay(100); + } + } + } else { + const lyricData = await liblyric.getLyricData(musicId); + parsedLyric = liblyric.parseLyric( + lyricData?.lrc?.lyric ?? "", + lyricData?.tlyric?.lyric ?? "", + lyricData?.romalrc?.lyric ?? "" + ); + } + + + // 清除歌词空白行 + parsedLyric = parsedLyric.filter(item => item.originalLyric != ""); + + + // 纯音乐只显示歌曲名与作曲家 + if ( + (parsedLyric.length == 1) + && (parsedLyric[0].time == 0) + && (parsedLyric[0].duration != 0) + ) { + parsedLyric = []; + } + + currentIndex = 0; + } + + + // 音乐进度发生变化时 + const play_progress = async (_, time) => { + const adjust = Number(pluginConfig.get("effect")["adjust"]); + if (parsedLyric) { + let nextIndex = parsedLyric.findIndex(item => item.time > (time + adjust) * 1000); + nextIndex = (nextIndex <= -1) ? parsedLyric.length : nextIndex; + + if (nextIndex != currentIndex) { + const currentLyric = parsedLyric[nextIndex - 1] ?? ""; + const nextLyric = parsedLyric[nextIndex] ?? ""; + + const lyrics = { + "basic": currentLyric?.originalLyric ?? "", + "extra": currentLyric?.translatedLyric ?? nextLyric?.originalLyric ?? "" + }; + + const extra_show_value = pluginConfig.get("effect")["extra_show"]["value"]; + switch (extra_show_value) { + case 0: { + lyrics.extra = ""; + } break; + + case 1: { + const next_line_lyrics_position_value = pluginConfig.get("effect")["next_line_lyrics_position"]["value"]; + switch (next_line_lyrics_position_value) { + case 0: { + lyrics.extra = nextLyric?.originalLyric ?? ""; + } break; + + case 1: { + lyrics.basic = nextLyric?.originalLyric ?? ""; + lyrics.extra = currentLyric?.originalLyric ?? ""; + } break; + + case 2: { + if (currentLine == 0) { + lyrics.basic = currentLyric?.originalLyric ?? ""; + lyrics.extra = nextLyric?.originalLyric ?? ""; + currentLine = 1; + } else { + lyrics.basic = nextLyric?.originalLyric ?? ""; + lyrics.extra = currentLyric?.originalLyric ?? ""; + currentLine = 0; + } + } break; + } + } break; + + case 2: { + lyrics.extra = currentLyric?.translatedLyric + ?? nextLyric?.originalLyric + ?? ""; + } break; + + case 3: { + lyrics.extra = currentLyric?.romanLyric + ?? currentLyric?.translatedLyric + ?? nextLyric?.originalLyric + ?? ""; + } break; + } + + TaskbarLyricsAPI.lyrics.lyrics(lyrics); + currentIndex = nextIndex; + } + } + } + + + + // 开始获取歌词 + function startGetLyric() { + const config = pluginConfig.get("lyrics"); + switch (config["retrieval_method"]["value"]) { + // 软件内词栏 + case 0: { + watchLyricsChange(); + } break; + + // LibLyric + case 1: { + legacyNativeCmder.appendRegisterCall("Load", "audioplayer", play_load); + legacyNativeCmder.appendRegisterCall("PlayProgress", "audioplayer", play_progress); + const playingSong = betterncm.ncm.getPlayingSong(); + if (playingSong && playingSong.data.id != musicId) { + play_load(); + } + } break; + + // RefinedNowPlaying + case 2: { + legacyNativeCmder.appendRegisterCall("Load", "audioplayer", play_load); + legacyNativeCmder.appendRegisterCall("PlayProgress", "audioplayer", play_progress); + } break; + } + } + + + // 停止获取歌词 + function stopGetLyric() { + const config = pluginConfig.get("lyrics"); + switch (config["retrieval_method"]["value"]) { + // 软件内词栏 + case 0: { + if (observer) { + observer.disconnect(); + observer = null; + } + } break; + + // LibLyric + case 1: { + legacyNativeCmder.removeRegisterCall("Load", "audioplayer", play_load); + legacyNativeCmder.removeRegisterCall("PlayProgress", "audioplayer", play_progress); + } break; + + // RefinedNowPlaying + case 2: { + legacyNativeCmder.removeRegisterCall("Load", "audioplayer", play_load); + legacyNativeCmder.removeRegisterCall("PlayProgress", "audioplayer", play_progress); + } break; + } + } + + + this.lyric = { + startGetLyric, + stopGetLyric + } +}); diff --git a/betterncm-plugin/manifest.json b/betterncm-plugin/manifest.json new file mode 100644 index 0000000..4b14345 --- /dev/null +++ b/betterncm-plugin/manifest.json @@ -0,0 +1,38 @@ +{ + "manifest_version": 1, + "name": "MC游戏内歌词", + "slug": "Minecraft-Lyrics", + "description": "在Minecraft上显示歌词,部分代码来源于mo-jinran/Taskbar-Lyrics", + "preview": "preview.png", + "version": "1.6.3", + "author": "CubeWhy, mo-jinran", + "author_links": [ + "https://github.com/cubewhy/", + "https://github.com/XiaoHeiPa", + "https://www.lunarclient.top/" + ], + "type": "extension", + "loadAfter": [ + "liblyric", + "RefinedNowPlaying" + ], + "requirements": [ + "liblyric" + ], + "injects": { + "Main": [ + { + "file": "base.js" + }, + { + "file": "lyric.js" + }, + { + "file": "func.js" + }, + { + "file": "view.js" + } + ] + } +} \ No newline at end of file diff --git a/betterncm-plugin/style.css b/betterncm-plugin/style.css new file mode 100644 index 0000000..91d6950 --- /dev/null +++ b/betterncm-plugin/style.css @@ -0,0 +1,191 @@ +/* 根标签 */ +#taskbar-lyrics-dom { + width: 100%; + height: 100%; + overflow: hidden; + display: flex; + flex-direction: column; + gap: 16px; +} + + + +/* 上边的tab区域 */ +#taskbar-lyrics-dom .tab_box { + width: 100%; + height: 40px; + display: flex; +} + +/* tab选项卡按钮 */ +#taskbar-lyrics-dom .tab_button { + width: 60px; + height: 100%; + border: none; + outline: none; + background: none; + margin: 0; + font-size: 1rem; +} + +/* tab选项卡按钮 激活效果 */ +#taskbar-lyrics-dom .tab_button.active { + position: relative; + font-weight: bold; +} + +/* tab选项卡按钮 激活后底部黑白条 */ +#taskbar-lyrics-dom .tab_button.active::after { + content: ""; + height: 5px; + border-radius: 5px; + background-color: rgba(255, 255, 255, 0.5); + position: absolute; + left: 10px; + right: 10px; + bottom: 0px; + backdrop-filter: blur(4px); +} + +body.s-theme-white #taskbar-lyrics-dom .tab_button.active::after { + background-color: rgba(0, 0, 0, 0.5); +} + + + +/* 下边的内容区域 */ +#taskbar-lyrics-dom .content_box { + overflow: auto; + flex: 1; +} + +/* 所有内容隐藏 */ +#taskbar-lyrics-dom .content { + display: none; +} + +/* 指定内容显示 */ +#taskbar-lyrics-dom .content.show { + display: block; +} + + + +#taskbar-lyrics-dom .content h1 { + height: 30px; + display: flex; + align-items: center; + margin: 10px 0; + gap: 10px; +} + +#taskbar-lyrics-dom .content h1 strong { + font-size: 1.25rem; + font-weight: bold; +} + +#taskbar-lyrics-dom .content hr { + margin: 20px 0; + border: none; + height: 1px; + background-color: rgba(255, 255, 255, 0.2); +} + +body.s-theme-white #taskbar-lyrics-dom .content hr { + background-color: rgba(0, 0, 0, 0.2); +} + +#taskbar-lyrics-dom .content section>div { + display: flex; + min-height: 30px; + margin: 5px 0; + gap: 10px; +} + +#taskbar-lyrics-dom .content .item_container { + flex-direction: row; + align-items: center; +} + +#taskbar-lyrics-dom .content .text_container { + flex-direction: column; + align-items: start; +} + +#taskbar-lyrics-dom .content p { + font-size: 14px; +} + +#taskbar-lyrics-dom .content a { + font-weight: bold; +} + + + +#taskbar-lyrics-dom .content input.color-input { + width: 150px; + padding: unset; +} + +#taskbar-lyrics-dom .content input.number-input { + width: 150px; +} + +#taskbar-lyrics-dom .content input.switch-btn { + width: 44px; + height: 22px; + appearance: none; + border-radius: 20px; + border: 1px solid rgba(255, 255, 255, 0.15); + position: relative; +} + +#taskbar-lyrics-dom .content input.switch-btn::before { + content: "关"; + text-align: center; + line-height: 18px; + font-size: 12px; + position: absolute; + top: 1px; + left: 1px; + height: 18px; + width: 18px; + background-color: rgba(255, 255, 255, 0.3); + border-radius: 50%; + transition: all 0.1s ease-out; +} + +#taskbar-lyrics-dom .content input.switch-btn:checked { + background-color: rgba(255, 255, 255, 0.1); +} + +#taskbar-lyrics-dom .content input.switch-btn:checked::before { + content: "开"; + text-align: center; + line-height: 18px; + font-size: 12px; + left: calc(100% - 19px); +} + +body.s-theme-white #taskbar-lyrics-dom .content input.switch-btn { + border: 1px solid rgba(0, 0, 0, 0.15); +} + +body.s-theme-white #taskbar-lyrics-dom .content input.switch-btn::before { + background-color: rgba(0, 0, 0, 0.3); +} + +body.s-theme-white #taskbar-lyrics-dom .content input.switch-btn:checked { + background-color: rgba(0, 0, 0, 0.1); +} + + + +#taskbar-lyrics-dom .u-select { + display: inline-block; + width: 200px; +} + +#taskbar-lyrics-dom input.u-txt { + border-radius: 4px; +} \ No newline at end of file diff --git a/betterncm-plugin/view.js b/betterncm-plugin/view.js new file mode 100644 index 0000000..ec5957c --- /dev/null +++ b/betterncm-plugin/view.js @@ -0,0 +1,390 @@ +"use strict"; + + +// 创建根视图 +const configView = document.createElement("div"); +configView.style.overflow = "hidden"; +configView.style.height = "100%"; +configView.style.width = "100%"; + + +plugin.onConfig(tools => configView); + + +plugin.onLoad(async () => { + const pluginConfig = this.base.pluginConfig; + const { + font, + color, + style, + lyrics, + effect, + align, + position, + margin, + screen, + } = { ...this.func }; + + + // 加载结构 + { + const path = `${this.pluginPath}/config.html`; + const text = await betterncm.fs.readFileText(path); + const parser = new DOMParser(); + const dom = parser.parseFromString(text, "text/html"); + const element = dom.querySelector("#taskbar-lyrics-dom"); + configView.appendChild(element); + } + + + // 加载样式 + { + const path = `${this.pluginPath}/style.css`; + const text = await betterncm.fs.readFileText(path); + const element = document.createElement("style"); + element.textContent = text; + configView.appendChild(element); + } + + + // 页面切换 + { + const tab_box = configView.querySelector(".tab_box"); + const content_box = configView.querySelector(".content_box") + + const all_tab_button = tab_box.querySelectorAll(".tab_button"); + const all_content = content_box.querySelectorAll(".content"); + + all_tab_button.forEach((tab, index) => { + tab.addEventListener("click", () => { + // 激活标签 + const active_tab = tab_box.querySelector(".active"); + active_tab.classList.remove("active"); + tab.classList.add("active"); + // 显示内容 + const show_content = content_box.querySelector(".show"); + show_content.classList.remove("show"); + all_content[index].classList.add("show"); + }); + }); + } + + + // 通用的下拉选择框控制函数 + function selectController(event) { + const open = event.target.parentElement.classList.contains("z-open"); + if (open) event.target.parentElement.classList.remove("z-open"); + else event.target.parentElement.classList.add("z-open"); + } + + + // 点击其他地方收起下拉选择框 + addEventListener("pointerup", event => { + if (!event.target.classList.contains("value")) { + const open = configView.querySelectorAll(".u-select.z-open"); + open.forEach(value => value.classList.remove("z-open")); + } + }); + + + // 更换字体 + { + const apply = configView.querySelector(".content.font .font-settings .apply"); + const reset = configView.querySelector(".content.font .font-settings .reset"); + + const fontFamily = configView.querySelector(".content.font .font-settings .font-family"); + + const elements = { + fontFamily + }; + + apply.addEventListener("click", () => font.apply(elements)); + reset.addEventListener("click", () => font.reset(elements)); + + fontFamily.value = pluginConfig.get("font")["font_family"]; + } + + + // 字体颜色 + { + const apply = configView.querySelector(".content.font .color-settings .apply"); + const reset = configView.querySelector(".content.font .color-settings .reset"); + + const basicLightColor = configView.querySelector(".content.font .color-settings .basic-light-color"); + const basicLightOpacity = configView.querySelector(".content.font .color-settings .basic-light-opacity"); + const basicDarkColor = configView.querySelector(".content.font .color-settings .basic-dark-color"); + const basicDarkOpacity = configView.querySelector(".content.font .color-settings .basic-dark-opacity"); + const extraLightColor = configView.querySelector(".content.font .color-settings .extra-light-color"); + const extraLightOpacity = configView.querySelector(".content.font .color-settings .extra-light-opacity"); + const extraDarkColor = configView.querySelector(".content.font .color-settings .extra-dark-color"); + const extraDarkOpacity = configView.querySelector(".content.font .color-settings .extra-dark-opacity"); + + const elements = { + basicLightColor, + basicLightOpacity, + basicDarkColor, + basicDarkOpacity, + extraLightColor, + extraLightOpacity, + extraDarkColor, + extraDarkOpacity + } + + apply.addEventListener("click", () => color.apply(elements)); + reset.addEventListener("click", () => color.reset(elements)); + + basicLightColor.value = `#${pluginConfig.get("color")["basic"]["light"]["hex_color"].toString(16)}`; + basicLightOpacity.value = pluginConfig.get("color")["basic"]["light"]["opacity"]; + basicDarkColor.value = `#${pluginConfig.get("color")["basic"]["dark"]["hex_color"].toString(16)}`; + basicDarkOpacity.value = pluginConfig.get("color")["basic"]["dark"]["opacity"]; + extraLightColor.value = `#${pluginConfig.get("color")["extra"]["light"]["hex_color"].toString(16)}`; + extraLightOpacity.value = pluginConfig.get("color")["extra"]["light"]["opacity"]; + extraDarkColor.value = `#${pluginConfig.get("color")["extra"]["dark"]["hex_color"].toString(16)}`; + extraDarkOpacity.value = pluginConfig.get("color")["extra"]["dark"]["opacity"]; + } + + + // 字体样式 + { + const reset = configView.querySelector(".content.font .style-settings .reset"); + + const basicWeightValue = configView.querySelector(".content.font .style-settings .basic-weight .value"); + const basicWeightSelect = configView.querySelector(".content.font .style-settings .basic-weight .select"); + const basicNormal = configView.querySelector(".content.font .style-settings .basic-normal"); + const basicOblique = configView.querySelector(".content.font .style-settings .basic-oblique"); + const basicItalic = configView.querySelector(".content.font .style-settings .basic-italic"); + const basicUnderline = configView.querySelector(".content.font .style-settings .basic-underline"); + const basicStrikethrough = configView.querySelector(".content.font .style-settings .basic-strikethrough"); + const extraWeightValue = configView.querySelector(".content.font .style-settings .extra-weight .value"); + const extraWeightSelect = configView.querySelector(".content.font .style-settings .extra-weight .select"); + const extraNormal = configView.querySelector(".content.font .style-settings .extra-normal"); + const extraOblique = configView.querySelector(".content.font .style-settings .extra-oblique"); + const extraItalic = configView.querySelector(".content.font .style-settings .extra-italic"); + const extraUnderline = configView.querySelector(".content.font .style-settings .extra-underline"); + const extraStrikethrough = configView.querySelector(".content.font .style-settings .extra-strikethrough"); + + const elements = { + basicWeightValue, + basicUnderline, + basicStrikethrough, + extraWeightValue, + extraUnderline, + extraStrikethrough + } + + reset.addEventListener("click", () => style.reset(elements)); + + basicNormal.addEventListener("click", event => style.setSlopeNormal(event)); + basicOblique.addEventListener("click", event => style.setSlopeOblique(event)); + basicItalic.addEventListener("click", event => style.setSlopeItalic(event)); + basicUnderline.addEventListener("change", event => style.setUnderline(event)); + basicStrikethrough.addEventListener("change", event => style.setStrikethrough(event)); + extraNormal.addEventListener("click", event => style.setSlopeNormal(event)); + extraOblique.addEventListener("click", event => style.setSlopeOblique(event)); + extraItalic.addEventListener("click", event => style.setSlopeItalic(event)); + extraUnderline.addEventListener("change", event => style.setUnderline(event)); + extraStrikethrough.addEventListener("change", event => style.setStrikethrough(event)); + + basicWeightValue.addEventListener("click", selectController); + basicWeightSelect.addEventListener("click", event => { + const name = event.target.parentElement.dataset.type; + const value = event.target.dataset.value; + const textContent = event.target.textContent; + style.setWeight(name, value, textContent); + basicWeightValue.textContent = textContent; + }); + + extraWeightValue.addEventListener("click", selectController); + extraWeightSelect.addEventListener("click", event => { + const name = event.target.parentElement.dataset.type; + const value = event.target.dataset.value; + const textContent = event.target.textContent; + style.setWeight(name, value, textContent); + extraWeightValue.textContent = textContent; + }); + + basicWeightValue.textContent = pluginConfig.get("style")["basic"]["weight"]["textContent"]; + basicUnderline.checked = pluginConfig.get("style")["basic"]["underline"]; + basicStrikethrough.checked = pluginConfig.get("style")["basic"]["strikethrough"]; + extraWeightValue.textContent = pluginConfig.get("style")["extra"]["weight"]["textContent"]; + extraUnderline.checked = pluginConfig.get("style")["extra"]["underline"]; + extraStrikethrough.checked = pluginConfig.get("style")["extra"]["strikethrough"]; + } + + + // 歌词设置 + { + const reset = configView.querySelector(".content.lyrics .lyrics-settings .reset"); + + const lyricsSwitch = configView.querySelector(".content.lyrics .lyrics-settings .lyrics-switch"); + const retrievalMethodValue = configView.querySelector(".content.lyrics .lyrics-settings .retrieval-method .value"); + const retrievalMethodSelect = configView.querySelector(".content.lyrics .lyrics-settings .retrieval-method .select"); + + const elements = { + retrievalMethodValue + } + + reset.addEventListener("click", () => lyrics.reset(elements)); + + lyricsSwitch.addEventListener("change", event => lyrics.lyricsSwitch(event)); + + retrievalMethodValue.addEventListener("click", selectController); + retrievalMethodSelect.addEventListener("click", event => { + const value = event.target.dataset.value; + const textContent = event.target.textContent; + if ((value == "2") && (!window.currentLyrics)) { + channel.call( + "trayicon.popBalloon", + () => { }, + [{ + title: "任务栏歌词", + text: "无法使用RefinedNowPlaying歌词!\n是否安装RefinedNowPlaying插件?\n将回退到使用LibLyric解析获取歌词", + icon: "path", + hasSound: true, + delayTime: 2e3 + }] + ); + return; + } + lyrics.setRetrievalMethod(value, textContent); + retrievalMethodValue.textContent = textContent; + }); + + retrievalMethodValue.textContent = pluginConfig.get("lyrics")["retrieval_method"]["textContent"]; + } + + + // 显示效果 + { + const apply = configView.querySelector(".content.lyrics .effect-settings .apply"); + const reset = configView.querySelector(".content.lyrics .effect-settings .reset"); + + const nextLineLyricsPositionValue = configView.querySelector(".content.lyrics .effect-settings .next-line-lyrics-position .value"); + const nextLineLyricsPositionSelect = configView.querySelector(".content.lyrics .effect-settings .next-line-lyrics-position .select"); + const extraShowValue = configView.querySelector(".content.lyrics .effect-settings .extra-show .value"); + const extraShowSelect = configView.querySelector(".content.lyrics .effect-settings .extra-show .select"); + const adjust = configView.querySelector(".content.lyrics .effect-settings .adjust"); + + const elements = { + nextLineLyricsPositionValue, + extraShowValue, + adjust + } + + apply.addEventListener("click", () => effect.apply(elements)); + reset.addEventListener("click", () => effect.reset(elements)); + + nextLineLyricsPositionValue.addEventListener("click", selectController); + nextLineLyricsPositionSelect.addEventListener("click", event => { + const value = event.target.dataset.value; + const textContent = event.target.textContent; + effect.setNextLineLyricsPosition(value, textContent); + nextLineLyricsPositionValue.textContent = textContent; + }); + + extraShowValue.addEventListener("click", selectController); + extraShowSelect.addEventListener("click", event => { + const value = event.target.dataset.value; + const textContent = event.target.textContent; + effect.setExtraShow(value, textContent); + extraShowValue.textContent = textContent; + }); + + nextLineLyricsPositionValue.textContent = pluginConfig.get("effect")["next_line_lyrics_position"]["textContent"]; + extraShowValue.textContent = pluginConfig.get("effect")["extra_show"]["textContent"]; + adjust.value = pluginConfig.get("effect")["adjust"]; + } + + + // 对齐方式 + { + const reset = configView.querySelector(".content.lyrics .align-settings .reset"); + + const basicLeft = configView.querySelector(".content.lyrics .align-settings .basic-left"); + const basicCenter = configView.querySelector(".content.lyrics .align-settings .basic-center"); + const basicRight = configView.querySelector(".content.lyrics .align-settings .basic-right"); + const extraLeft = configView.querySelector(".content.lyrics .align-settings .extra-left"); + const extraCenter = configView.querySelector(".content.lyrics .align-settings .extra-center"); + const extraRight = configView.querySelector(".content.lyrics .align-settings .extra-right"); + + reset.addEventListener("click", () => align.reset()); + + basicLeft.addEventListener("click", event => align.setLeft(event)); + basicCenter.addEventListener("click", event => align.setCenter(event)); + basicRight.addEventListener("click", event => align.setRight(event)); + extraLeft.addEventListener("click", event => align.setLeft(event)); + extraCenter.addEventListener("click", event => align.setCenter(event)); + extraRight.addEventListener("click", event => align.setRight(event)); + } + + + // 修改位置 + { + const reset = configView.querySelector(".content.window .position-settings .reset"); + + const windowPositionValue = configView.querySelector(".content.window .position-settings .window-position .value"); + const windowPositionSelect = configView.querySelector(".content.window .position-settings .window-position .select"); + + const elements = { + windowPositionValue + } + + reset.addEventListener("click", () => position.reset(elements)); + + windowPositionValue.addEventListener("click", selectController); + windowPositionSelect.addEventListener("click", event => { + const value = event.target.dataset.value; + const textContent = event.target.textContent; + position.setWindowPosition(value, textContent); + windowPositionValue.textContent = textContent; + }); + + windowPositionValue.textContent = pluginConfig.get("position")["position"]["textContent"]; + } + + + // 修改边距 + { + const apply = configView.querySelector(".content.window .margin-settings .apply"); + const reset = configView.querySelector(".content.window .margin-settings .reset"); + + const left = configView.querySelector(".content.window .margin-settings .left"); + const right = configView.querySelector(".content.window .margin-settings .right"); + + const elements = { + left, + right + } + + apply.addEventListener("click", () => margin.apply(elements)); + reset.addEventListener("click", () => margin.reset(elements)); + + left.value = pluginConfig.get("margin")["left"]; + right.value = pluginConfig.get("margin")["right"]; + } + + + // 切换屏幕 + { + const reset = configView.querySelector(".content.window .screen-settings .reset"); + + const parentTaskbarValue = configView.querySelector(".content.window .screen-settings .parent-taskbar .value"); + const parentTaskbarSelect = configView.querySelector(".content.window .screen-settings .parent-taskbar .select"); + + const elements = { + parentTaskbarValue + } + + reset.addEventListener("click", () => screen.reset(elements)); + + parentTaskbarValue.addEventListener("click", selectController); + parentTaskbarSelect.addEventListener("click", event => { + const value = event.target.dataset.value; + const textContent = event.target.textContent; + screen.setParentTaskbar(value, textContent); + parentTaskbarValue.textContent = textContent; + }); + + parentTaskbarValue.textContent = pluginConfig.get("screen")["parent_taskbar"]["textContent"]; + } +}); \ No newline at end of file