Skip to content

Commit

Permalink
player: 修改对插件的用词并更名为扩展程序,优化加载和卸载逻辑,允许注入组件到更多位置
Browse files Browse the repository at this point in the history
  • Loading branch information
Steve-xmh committed Oct 12, 2024
1 parent 025140b commit 5195d46
Show file tree
Hide file tree
Showing 21 changed files with 889 additions and 631 deletions.
54 changes: 30 additions & 24 deletions packages/player/locales/zh-CN/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@
"noResults": "无结果"
}
},
"extension": {
"inject": {
"error": {
"calloutText": "扩展程序 {id} 在注入组件 / 功能到 {injectPointName} 槽位时发生错误:",
"toastText": "扩展程序 {id} 在注入组件 / 功能到 {injectPointName} 槽位时发生错误:\n{error}"
}
},
"error": {
"invaildPluginFile": "无效插件文件",
"missingDependency": "缺失依赖项",
"missingMetadata": "缺失必需元数据",
"pluginIdConflict": "插件 ID 冲突"
}
},
"newPlaylist": {
"buttonLabel": "新建播放列表",
"dialog": {
Expand Down Expand Up @@ -106,6 +120,15 @@
"shufflePlayAll": "随机播放"
},
"settings": {
"others": {
"restartProgram": "重启程序",
"subtitle": "杂项",
"showStatJSFrame": {
"label": "显示性能统计信息",
"description": "可以看到帧率、帧时间、内存占用(仅 Chromuim 系)等信息,对性能影响较小。"
},
"enterAmllDevPage": "歌词页面开发用工具"
},
"lyricFont": {
"fontPreview": {
"defaultText": "字体预览 Font Preview",
Expand Down Expand Up @@ -238,15 +261,6 @@
"label": "启用音译歌词与翻译歌词互换",
"description": "仅上面两者启用后有效"
}
},
"others": {
"subtitle": "杂项",
"showStatJSFrame": {
"label": "显示性能统计信息",
"description": "可以看到帧率、帧时间、内存占用(仅 Chromuim 系)等信息,对性能影响较小。"
},
"restartProgram": "重启程序",
"enterAmllDevPage": "歌词页面开发用工具"
}
},
"about": {
Expand Down Expand Up @@ -305,27 +319,19 @@
}
},
"settings": {
"player": {
"tab": "AMLL Player 设置"
},
"plugin": {
"tab": "插件管理",
"extension": {
"safetyWarning": "插件将可以访问并操作你的所有数据,包括你的歌单、播放信息等数据,请务必确保插件来源可靠安全,并只安装你信任的插件!作者不承担使用任何插件后产生的一切后果!",
"wipWarning": "插件接口功能仍在开发中,其插件接口有可能随时变更,敬请留意!",
"install": {
"title": "请选择需要载入的 JavaScript 插件文件"
},
"installPlugins": "安装插件",
"openPluginDirectory": "打开插件文件夹"
"openPluginDirectory": "打开插件文件夹",
"tab": "扩展程序管理"
},
"player": {
"tab": "AMLL Player 设置"
}
},
"name": "",
"plugin": {
"error": {
"invaildPluginFile": "无效插件文件",
"missingDependency": "缺失依赖项",
"missingMetadata": "缺失必需元数据",
"pluginIdConflict": "插件 ID 冲突"
}
}
"name": ""
}
1 change: 1 addition & 0 deletions packages/player/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"@tauri-apps/plugin-os": "2.0.0",
"@tauri-apps/plugin-shell": "2.0.0",
"@tauri-apps/plugin-updater": "2.0.0",
"chalk": "^5.3.0",
"classnames": "^2.5.1",
"convert-source-map": "^2.0.0",
"dexie": "^4.0.8",
Expand Down
8 changes: 5 additions & 3 deletions packages/player/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import { ToastContainer } from "react-toastify";
import Stats from "stats.js";
import styles from "./App.module.css";
import { AMLLWrapper } from "./components/AMLLWrapper";
import { ExtensionContext } from "./components/ExtensionContext";
import { ExtensionInjectPoint } from "./components/ExtensionInjectPoint";
import { LocalMusicContext } from "./components/LocalMusicContext";
import { NowPlayingBar } from "./components/NowPlayingBar";
import { PluginContext } from "./components/PluginContext";
import { UpdateContext } from "./components/UpdateContext";
import { WSProtocolMusicContext } from "./components/WSProtocolMusicContext";
import "./i18n";
Expand Down Expand Up @@ -60,15 +61,16 @@ function App() {

return (
<>
{/* 上下文组件均不建议被 StrictMode 包含,以免重复加载插件发生问题 */}
{/* 上下文组件均不建议被 StrictMode 包含,以免重复加载扩展程序发生问题 */}
{musicContextMode === MusicContextMode.Local && <LocalMusicContext />}
{musicContextMode === MusicContextMode.WSProtocol && (
<WSProtocolMusicContext />
)}
<UpdateContext />
<Suspense>
<PluginContext />
<ExtensionContext />
</Suspense>
<ExtensionInjectPoint injectPointName="context" hideErrorCallout />
<StrictMode>
<Theme
appearance="dark"
Expand Down
85 changes: 85 additions & 0 deletions packages/player/src/components/ExtensionContext/ext-ctx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { fromObject, fromSource, removeComments } from "convert-source-map";
import type { ComponentType } from "react";
import { SourceMapConsumer, SourceMapGenerator } from "source-map-js";
import type { db } from "../../dexie";
import type ExtensionEnv from "../../extension-env";
import i18n from "../../i18n";
import type { ExtensionMetaState } from "../../states/extension";

export async function sourceMapOffsetLines(
code: string,
sourceRoot: string,
lineOffset: number,
): Promise<[string, string]> {
const incomingSourceConv = fromSource(code);
if (!incomingSourceConv) return [code, ""];
const incomingSourceMap = incomingSourceConv.toObject();
const consumer = await new SourceMapConsumer(incomingSourceMap);
const generator = new SourceMapGenerator({
file: incomingSourceMap.file,
sourceRoot: sourceRoot,
});
consumer.eachMapping((m) => {
// skip invalid (not-connected) mapping
// refs: https://github.com/mozilla/source-map/blob/182f4459415de309667845af2b05716fcf9c59ad/lib/source-map-generator.js#L268-L275
if (
typeof m.originalLine === "number" &&
0 < m.originalLine &&
typeof m.originalColumn === "number" &&
0 <= m.originalColumn &&
m.source
) {
generator.addMapping({
source:
m.source &&
`${location.origin}/extensions/${sourceRoot}/${m.source.replace(/^(\.*\/)+/, "")}`,
name: m.name,
original: { line: m.originalLine, column: m.originalColumn },
generated: {
line: m.generatedLine + lineOffset,
column: m.generatedColumn,
},
});
}
});
const outgoingSourceMap = JSON.parse(generator.toString());
if (typeof incomingSourceMap.sourcesContent !== "undefined") {
outgoingSourceMap.sourcesContent = incomingSourceMap.sourcesContent;
}
return [removeComments(code), fromObject(outgoingSourceMap).toComment()];
}

export class PlayerExtensionContext
extends EventTarget
implements ExtensionEnv.ExtensionContext
{
/**
* @internal
*/
registeredInjectPointComponent: {
[injectPointName: string]: ComponentType | undefined;
} = {};
constructor(
readonly playerStates: ExtensionEnv.ExtensionContext["playerStates"],
readonly amllStates: ExtensionEnv.ExtensionContext["amllStates"],
readonly i18n: ExtensionEnv.ExtensionContext["i18n"],
readonly jotaiStore: ExtensionEnv.ExtensionContext["jotaiStore"],
readonly extensionMeta: Readonly<ExtensionMetaState>,
readonly lyric: typeof import("@applemusic-like-lyrics/lyric"),
readonly playerDB: typeof db,
) {
super();
}
extensionApiNumber = 1;
registerLocale<T>(localeData: { [langId: string]: T }) {
for (const [lng, data] of Object.entries(localeData)) {
i18n.addResourceBundle(lng, this.extensionMeta.id, data);
}
}
registerComponent(injectPointName: string, injectComponent: ComponentType) {
this.registeredInjectPointComponent[injectPointName] = injectComponent;
}
registerPlayerSource(_idPrefix: string) {
console.warn("Unimplemented");
}
}
Loading

0 comments on commit 5195d46

Please sign in to comment.