Skip to content

Commit

Permalink
fix(transcript): fix bilibili transcript fetching in new window
Browse files Browse the repository at this point in the history
close #359
  • Loading branch information
aidenlx committed May 13, 2024
1 parent 51201c0 commit 3dce5db
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 24 deletions.
4 changes: 3 additions & 1 deletion apps/app/src/media-view/menu/transcript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ export function transcriptMenu(menu: Menu, ctx: PlayerContext) {
}
} else if (t._type === "local") {
if (t.src instanceof TFile) {
ctx.plugin.app.workspace.openLinkText(t.src.path, "", "split");
if (ctx.plugin.app.vault.getFileByPath(t.src.path)) {
ctx.plugin.app.workspace.openLinkText(t.src.path, "", "split");
}
} else {
new Notice("Remote track not yet supported");
}
Expand Down
30 changes: 29 additions & 1 deletion apps/app/src/web/bili-req/channel.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,35 @@
export function channelId(storeId: string) {
import type { IpcRenderer } from "electron/renderer";

interface Channels {
enable: string;
disable: string;
preload: string;
}

export function channelId(storeId: string): Channels {
return {
enable: `mx-enable-preload-${storeId}`,
disable: `mx-disable-preload-${storeId}`,
preload: `file:///mx-preload-${storeId}`,
};
}

type PreloadEnableInvoke = (script: string) => Promise<void>;
export type PreloadEnableHandler = (
evt: Electron.IpcMainInvokeEvent,
...args: Parameters<PreloadEnableInvoke>
) => any;

export function buildPreloadLoader(ctx: {
ipcRenderer: IpcRenderer;
channel: Channels;
}): { enable: PreloadEnableInvoke; disable: () => Promise<void> } {
return {
enable: (script) => {
return ctx.ipcRenderer.invoke(ctx.channel.enable, script);
},
disable: () => {
return ctx.ipcRenderer.invoke(ctx.channel.disable);
},
};
}
38 changes: 32 additions & 6 deletions apps/app/src/web/bili-req/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import preloadScript from "inline:./scripts/preload";
import preloadLoader from "inline:./scripts/preload-patch";
import userScript from "inline:./scripts/userscript";
import { Component, Platform } from "obsidian";
import { Component, Platform, WorkspaceWindow } from "obsidian";
import path from "@/lib/path";
import type MxPlugin from "@/mx-main";
import { evalInMainPs, getFsPromise, getUserDataPath } from "../session/utils";
import { channelId } from "./channel";
import { buildPreloadLoader, channelId } from "./channel";
import { BILI_REQ_STORE, replaceEnv } from "./const";

const preloadLoaderCode = replaceEnv(preloadLoader);
Expand All @@ -29,6 +29,11 @@ declare module "obsidian" {
trigger(name: "mx:preload-ready"): void;
trigger(name: "mx:preload-error", err: unknown): void;
}
interface Workspace {
floatingSplit: {
children: WorkspaceWindow[];
};
}
}

export class BilibiliRequestHacker extends Component {
Expand Down Expand Up @@ -114,13 +119,34 @@ export class BilibiliRequestHacker extends Component {
console.warn("Failed to remove hack script", preloadLoaderPath, e),
);
}
const { ipcRenderer } = require("electron");
await ipcRenderer.invoke(channel.enable, preloadScriptPath);
this.register(() => {
ipcRenderer.invoke(channel.disable);
const { enable, disable } = buildPreloadLoader({
ipcRenderer: require("electron").ipcRenderer,
channel,
});

await enable(preloadScriptPath);
this.app.workspace.onLayoutReady(() => {
this.app.workspace.floatingSplit.children.forEach((workspaceWin) => {
if (workspaceWin instanceof WorkspaceWindow) {
this.enablePreload(preloadScriptPath, workspaceWin.win);
}
});
this.registerEvent(
this.app.workspace.on("window-open", async (_, win) => {
await this.enablePreload(preloadScriptPath, win);
}),
);
});

this.register(disable);
console.log("mx-player-hack loaded");
this.onReady();
})().catch((e) => this.onError(e));
}

async enablePreload(scriptPath: string, win: Window) {
const { ipcRenderer } = (win as any).require("electron");
const { enable } = buildPreloadLoader({ ipcRenderer, channel });
await enable(scriptPath);
}
}
42 changes: 28 additions & 14 deletions apps/app/src/web/bili-req/scripts/preload-patch.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,40 @@
import { ipcMain } from "electron";
import type { WebContents } from "electron/main";
import { webContents } from "electron/main";
import type { PreloadEnableHandler } from "../channel";
import { channelId } from "../channel";
import { storeId } from "./store-id";
const channels = channelId(storeId);
let preloadHandler:
| ((
event: { preventDefault: () => void; readonly defaultPrevented: boolean },
webPreferences: Electron.WebPreferences,
params: Record<string, string>,
) => void)
| null = null;

ipcMain.handle(channels.enable, ({ sender }, script: string) => {
preloadHandler = (_evt, pref, params) => {
type PreloadHandler = (
event: { preventDefault: () => void; readonly defaultPrevented: boolean },
webPreferences: Electron.WebPreferences,
params: Record<string, string>,
) => void;

const modified = new WeakMap<WebContents, PreloadHandler>();

const handleEnable: PreloadEnableHandler = ({ sender: target }, script) => {
const preloadHandler: PreloadHandler = (_evt, pref, params) => {
console.log("preloadHandler", params.preload, channels.preload);
if (params.preload !== channels.preload) return;
pref.preload = script;
};
sender.on("will-attach-webview", preloadHandler);
console.log("bili-req preload handler enabled");
});
ipcMain.handle(channels.disable, ({ sender }) => {
preloadHandler && sender.off("will-attach-webview", preloadHandler);
if (!modified.has(target)) {
target.on("will-attach-webview", preloadHandler);
modified.set(target, preloadHandler);
console.log(`bili-req preload handler registered on ${target.id}`);
}
};

ipcMain.handle(channels.enable, handleEnable);
ipcMain.handle(channels.disable, () => {
for (const target of webContents.getAllWebContents()) {
const handler = modified.get(target);
if (!handler) continue;
target.off("will-attach-webview", handler);
console.log(`bili-req preload handler removed on ${target.id}`);
}
ipcMain.removeHandler(channels.enable);
ipcMain.removeHandler(channels.disable);
console.log("bili-req preload handler unloaded");
Expand Down
4 changes: 2 additions & 2 deletions apps/app/src/web/userscript/bilibili.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ export default class BilibiliPlugin extends MediaPlugin {
ID: id,
};
return {
cues: json.body.map((sub) => ({
id: sub.sid.toString(),
cues: json.body.map((sub, idx) => ({
id: `${sub.sid ?? idx}`,
startTime: sub.from,
endTime: sub.to,
text: sub.content,
Expand Down

0 comments on commit 3dce5db

Please sign in to comment.