Skip to content

Commit 4d24de5

Browse files
authored
#4 from docerium/next
2 parents 05b09ff + 9f8a99a commit 4d24de5

3 files changed

Lines changed: 296 additions & 120 deletions

File tree

‎src/app/notebook/page.tsx‎

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import React, { useMemo } from "react";
3+
import React, { useMemo, useEffect } from "react";
44
import { useAtom } from "jotai";
55
import { notebookAtom } from "@/store";
66
import katex from "katex";
@@ -74,6 +74,72 @@ const parseContent = (text: string) => {
7474
export default function NotebookPage() {
7575
const [content, setContent] = useAtom(notebookAtom);
7676

77+
useEffect(() => {
78+
const html = document.documentElement;
79+
80+
const apply = (enabled: boolean) => {
81+
html.classList.toggle("notebook--preview-only", enabled);
82+
};
83+
84+
// URL param fallback
85+
const params = new URLSearchParams(window.location.search);
86+
const forced =
87+
params.get("preview") === "1" || params.get("stream") === "right";
88+
if (forced) apply(true);
89+
90+
// Experimental Chromium capture detection
91+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
92+
const docAny = document as any;
93+
let cleanup: (() => void) | undefined;
94+
95+
const setup = async () => {
96+
try {
97+
// Variant A: document.hasCapture + capturestatechange
98+
if (typeof docAny.hasCapture === "boolean") {
99+
const updateA = () => {
100+
if (!forced) apply(!!docAny.hasCapture);
101+
};
102+
updateA();
103+
docAny.addEventListener?.("capturestatechange", updateA);
104+
cleanup = () =>
105+
docAny.removeEventListener?.("capturestatechange", updateA);
106+
return;
107+
}
108+
109+
// Variant B: document.getCaptureState() + capturestatechange
110+
if (typeof docAny.getCaptureState === "function") {
111+
const updateB = async () => {
112+
try {
113+
const state = await docAny.getCaptureState(); // { active, displaySurface? }
114+
const isBrowserTab =
115+
!!state?.active && state?.displaySurface === "browser";
116+
if (!forced) apply(isBrowserTab);
117+
} catch {
118+
// ignore
119+
}
120+
};
121+
await updateB();
122+
const handler = () => {
123+
void updateB();
124+
};
125+
docAny.addEventListener?.("capturestatechange", handler);
126+
cleanup = () =>
127+
docAny.removeEventListener?.("capturestatechange", handler);
128+
return;
129+
}
130+
} catch {
131+
// ignore
132+
}
133+
};
134+
135+
void setup();
136+
137+
return () => {
138+
cleanup?.();
139+
html.classList.remove("notebook--preview-only");
140+
};
141+
}, []);
142+
77143
const renderedContent = useMemo(() => parseContent(content), [content]);
78144

79145
return (

0 commit comments

Comments
 (0)