Skip to content

Commit

Permalink
fix(webpage): improve webpage plugin timeout notice; optimize load sp…
Browse files Browse the repository at this point in the history
…eed; add reload command
  • Loading branch information
aidenlx committed Feb 17, 2024
1 parent d375c89 commit e74053b
Show file tree
Hide file tree
Showing 15 changed files with 127 additions and 55 deletions.
5 changes: 5 additions & 0 deletions apps/app/src/components/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ export const MediaViewContext = createContext<{
store: MediaViewStoreApi;
plugin: MediaExtended;
embed: boolean;
reload: () => void;
onScreenshot?: (info: ScreenshotInfo) => any;
onTimestamp?: (timestamp: number) => any;
}>(null as any);
Expand All @@ -198,6 +199,10 @@ export function useMediaViewStoreInst() {
return store;
}

export function useReload() {
return useContext(MediaViewContext).reload;
}

export function useApp(): App;
export function useApp<U>(selector: (state: App) => U): U;
export function useApp<U>(selector?: (state: App) => U): U | App {
Expand Down
3 changes: 3 additions & 0 deletions apps/app/src/components/player/menus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
useMediaViewStore,
useMediaViewStoreInst,
usePlugin,
useReload,
} from "../context";
import { dataLpPassthrough } from "./buttons";

Expand Down Expand Up @@ -76,6 +77,7 @@ export function MoreOptions() {
const workspace = useApp((app) => app.workspace);
const plugin = usePlugin();
const isEmbed = useIsEmbed();
const reload = useReload();
const source = useMediaViewStore((state) => state.source?.url);
const store = useMediaViewStoreInst();
const onClick = useMenu((menu) => {
Expand All @@ -93,6 +95,7 @@ export function MoreOptions() {
menu,
{
player,
reload,
source,
toggleControls,
controls,
Expand Down
2 changes: 1 addition & 1 deletion apps/app/src/components/provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export function MediaProviderEnhanced({
<WebView
aria-hidden
className={cn(
"data-[play-ready]:opacity-100 opacity-0 transition-opacity",
"data-[play-ready]:blur-none blur-lg transition-opacity",
controls && "pointer-events-none",
)}
webpreferences="autoplayPolicy=user-gesture-required"
Expand Down
32 changes: 14 additions & 18 deletions apps/app/src/lib/remote-player/lib/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,28 +39,24 @@ export default class MediaPlugin extends LifeCycle {
await super.load();
const isNativePlayer = this.media.controls === true;
if (isNativePlayer) this.media.controls = false;
this.untilMediaReady("canplay").then(() => {
this.register(
this.controller.on("mx-toggle-controls", ({ payload: showWebsite }) => {
document.body.classList.toggle("mx-show-controls", showWebsite);
}),
);
if (isNativePlayer) {
this.register(
this.controller.on("mx-toggle-controls", ({ payload: showWebsite }) => {
document.body.classList.toggle("mx-show-controls", showWebsite);
this.media.controls = showWebsite;
}),
);
if (isNativePlayer) {
this.register(
this.controller.on(
"mx-toggle-controls",
({ payload: showWebsite }) => {
this.media.controls = showWebsite;
},
),
);
}
this.register(
this.controller.on("mx-toggle-webfs", ({ payload: enableWebFs }) => {
document.body.classList.toggle("mx-fs-enable", enableWebFs);
}),
);
});
}
this.register(
this.controller.on("mx-toggle-webfs", ({ payload: enableWebFs }) => {
document.body.classList.toggle("mx-fs-enable", enableWebFs);
}),
);
document.body.classList.add("mx-play-ready");
this.controller.send("mx-play-ready", void 0);
console.log("sent play ready");
}
Expand Down
38 changes: 35 additions & 3 deletions apps/app/src/lib/remote-player/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { WebviewTag } from "electron";
import init from "inline:./scripts/initialize";

import { isString } from "maverick.js/std";
import { Notice } from "obsidian";
import { ButtonComponent, Notice } from "obsidian";
import type { WebviewElement } from "@/components/webview";
import { GET_PORT_TIMEOUT, PORT_MESSAGE } from "@/lib/remote-player/const";
import { plugins } from "@/web/plugin";
Expand Down Expand Up @@ -195,14 +195,17 @@ export class WebiviewMediaProvider implements MediaProviderAdapter {
});
});

const timeoutLimit = 10e3;
finishLoad
.then(() => Promise.race([playReady, timeout(10e3)]))
.then(() => {
return Promise.race([playReady, timeout(timeoutLimit)]);
})
.then(() => {
this.togglePlayReady(true);
})
.catch((err) => {
if (err instanceof TimeoutError) {
new Notice("Webview failed to load plugin in time");
timeoutNotice(timeoutLimit);
} else if (err instanceof WebviewLoadError) {
new Notice("Webview failed to load website: " + err.message);
} else {
Expand Down Expand Up @@ -314,3 +317,32 @@ function notifyLogin() {
);
localStorage.setItem(label, "1");
}

function timeoutNotice(timeout: number) {
const label = "mx:webview-timeout-ignore";
const ignore = localStorage.getItem(label);
if (ignore) return;
const timeoutLabel = (timeout / 1e3).toFixed(1);
const notice = new Notice(
createFragment((e) => {
e.createDiv({
text: `Webpage not fully loaded within ${timeoutLabel}s. You can still try to play.`,
});
e.createDiv({}, (div) => {
div.style.display = "flex";
div.style.justifyContent = "flex-end";
div.style.gap = "1em";
div.style.marginTop = "1em";
new ButtonComponent(div).setButtonText("OK");
new ButtonComponent(div)
.setButtonText("Don't show again")
.onClick(() => {
console.log("ignore webview timeout notice");
localStorage.setItem(label, "1");
notice.hide();
});
});
}),
5e3,
);
}
1 change: 1 addition & 0 deletions apps/app/src/lib/remote-player/ua.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export function getUserAgent(ua: string) {
return "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36";
return ua.replaceAll(/(?:Electron|obsidian)\/\S+ ?/g, "");
}
2 changes: 2 additions & 0 deletions apps/app/src/media-view/base.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ function noticeNotetaking(action: string) {
export function onPaneMenu<
T extends PlayerComponent & {
getViewType(): MediaViewType;
render(): void;
} & View,
>(
view: T,
Expand Down Expand Up @@ -122,6 +123,7 @@ export function onPaneMenu<
plugin: view.plugin,
disableWebFullscreen,
toggleWebFullscreen,
reload: () => view.render(),
},
menuSource,
view.leaf,
Expand Down
8 changes: 7 additions & 1 deletion apps/app/src/media-view/file-embed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,27 @@ export class MediaFileEmbed
};
}

onload(): void {
// eslint-disable-next-line react/require-render-return
render() {
this.root?.unmount();
this.root = ReactDOM.createRoot(this.info.containerEl);
this.root.render(
<MediaViewContext.Provider
value={{
plugin: this.plugin,
store: this.store,
reload: () => this.render(),
embed: true,
}}
>
<Player />
</MediaViewContext.Provider>,
);
}
onload(): void {
super.onload();
this.render();
}

async loadFile() {
await this.store
Expand Down
1 change: 1 addition & 0 deletions apps/app/src/media-view/file-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ abstract class MediaFileView
value={{
plugin: this.plugin,
store: this.store,
reload: () => this.render(),
embed: false,
}}
>
Expand Down
17 changes: 17 additions & 0 deletions apps/app/src/media-view/menu/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface PlayerContext {
player: MediaPlayerInstance;
source: MediaURL;
plugin: MxPlugin;
reload: () => void;
setTransform: MediaViewState["setTransform"];
transform: MediaViewState["transform"];
controls: boolean | undefined;
Expand Down Expand Up @@ -59,6 +60,22 @@ export default function registerMediaMenu(this: MxPlugin) {
handleExternalLinkMenu(this);
this.registerEvent(
this.app.workspace.on("mx-media-menu", (menu, ctx, source) => {
if (
source === "more-options" ||
source === "sidebar-context-menu" ||
source === "tab-header" ||
source === "player-menu-embed"
) {
menu.addItem((item) =>
item
.setTitle("Refresh")
.setSection("view")
.setIcon("reset")
.onClick(() => {
ctx.reload();
}),
);
}
if (source !== "sidebar-context-menu" && source !== "tab-header") {
menu.addItem((item) => speedMenu(item, ctx.player));
if (ctx.player.state.viewType === "video") {
Expand Down
1 change: 1 addition & 0 deletions apps/app/src/media-view/remote-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ export abstract class MediaRemoteView
value={{
plugin: this.plugin,
store: this.store,
reload: () => this.render(),
embed: false,
}}
>
Expand Down
7 changes: 6 additions & 1 deletion apps/app/src/media-view/url-embed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,26 @@ export class MediaRenderChild
return this.store.getState().setSource;
}

onload(): void {
render() {
this.root?.unmount();
this.root = ReactDOM.createRoot(this.containerEl);
this.root.render(
<MediaViewContext.Provider
value={{
plugin: this.plugin,
store: this.store,
reload: () => this.render(),
embed: true,
}}
>
<Player />
</MediaViewContext.Provider>,
);
}
onload(): void {
super.onload();
this.render();
}

onunload() {
// unmount before detach from DOM
Expand Down
2 changes: 1 addition & 1 deletion apps/app/src/switcher/modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export class MediaSwitcherModal extends SuggestModal<MediaURL> {
} else {
assertNever(item);
}
if (!item.inferredType) {
if (item.isFileUrl && !item.inferredType) {
new Notice("Unsupported file type: " + item.pathname);
return;
}
Expand Down
18 changes: 9 additions & 9 deletions apps/app/src/web/userscript/bilibili.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export default class BilibiliPlugin extends MediaPlugin {
);
await super.onload();
this.revertAutoSeek();
await this.untilMediaReady("canplay");
await Promise.all([this.toggleDanmaku(false), this.untilWebFullscreen()]);
Promise.all([this.toggleDanmaku(false)]);
await this.untilWebFullscreen();
}

get player() {
Expand Down Expand Up @@ -91,20 +91,20 @@ export default class BilibiliPlugin extends MediaPlugin {
return this.player.classList.contains("mode-webscreen");
}

async enterWebFullscreen() {
enterWebFullscreen() {
if (this.isWebFullscreen()) {
console.log("Already in web fullscreen");
return;
}
const fsButton = await waitForSelector<HTMLDivElement>(
".bpx-player-ctrl-web",
this.player,
waitForSelector<HTMLDivElement>(".bpx-player-ctrl-web", this.player).then(
(fsButton) => {
console.log("Clicking fullscreen button");
fsButton.click();
},
);
console.log("Clicking fullscreen button");
fsButton.click();
}

async revertAutoSeek() {
revertAutoSeek() {
const plyaer = this.player;
const toastContainer = plyaer.querySelector<HTMLDivElement>(
".bpx-player-toast-auto",
Expand Down
45 changes: 24 additions & 21 deletions apps/app/src/web/userscript/youtube.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// hugely inspired by https://greasyfork.org/zh-CN/scripts/4870-maximize-video

const css = `
body:not(.mx-player-ready) #movie_player,
ytd-watch-flexy[theater] #movie_player {
position: fixed !important;
top: 0 !important;
Expand Down Expand Up @@ -91,12 +92,12 @@ export default class BilibiliPlugin extends MediaPlugin {
}
async onload(): Promise<void> {
await super.onload();

waitForSelector<HTMLElement>(".video-ads.ytp-ad-module", this.app).then(
(adModule) => this.removePlayerAD(adModule),
);

await Promise.all([this.disableAutoPlay()]);
Promise.all([
waitForSelector<HTMLElement>(".video-ads.ytp-ad-module", this.app).then(
(adModule) => this.removePlayerAD(adModule),
),
this.disableAutoPlay(),
]);
}

get app() {
Expand Down Expand Up @@ -182,23 +183,25 @@ export default class BilibiliPlugin extends MediaPlugin {
}
}

async enterWebFullscreen() {
enterWebFullscreen() {
this.assignParentClass(this.moviePlayer);

const fsButton = await waitForSelector<HTMLButtonElement>(
"#movie_player .ytp-size-button",
);
const isCinematicsMode = () =>
!!this.app.querySelector("ytd-watch-flexy[theater]");
if (!isCinematicsMode()) {
console.log("Entering cinema mode");
do {
fsButton.click();
await sleep(200);
} while (!isCinematicsMode());
console.log("Entered cinema mode");
}
window.dispatchEvent(new Event("resize"));
(async () => {
const fsButton = await waitForSelector<HTMLButtonElement>(
"#movie_player .ytp-size-button",
);
const isCinematicsMode = () =>
!!this.app.querySelector("ytd-watch-flexy[theater]");
if (!isCinematicsMode()) {
console.log("Entering cinema mode");
do {
fsButton.click();
await sleep(200);
} while (!isCinematicsMode());
console.log("Entered cinema mode");
}
window.dispatchEvent(new Event("resize"));
})();
}
}

Expand Down

0 comments on commit e74053b

Please sign in to comment.