mirror of
https://github.com/stefanpejcic/openpanel
synced 2025-06-26 18:28:26 +00:00
packages
This commit is contained in:
100
packages/live-previews/src/utils/use-code.ts
Normal file
100
packages/live-previews/src/utils/use-code.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import React from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import { decompressFromEncodedURIComponent } from "lz-string";
|
||||
import base64url from "base64url";
|
||||
|
||||
type UseCodeReturn = {
|
||||
code: string | null;
|
||||
css: string | null;
|
||||
isReady: boolean;
|
||||
hasQuery: boolean;
|
||||
disableScroll: boolean;
|
||||
useTailwind: boolean;
|
||||
isLoading: boolean;
|
||||
};
|
||||
|
||||
export const useCode = (): UseCodeReturn => {
|
||||
const { query, isReady } = useRouter();
|
||||
const {
|
||||
code: encoded,
|
||||
hash,
|
||||
disableScroll,
|
||||
tailwind,
|
||||
css: cssCompressed,
|
||||
} = query ?? {};
|
||||
|
||||
const [isLoading, setIsLoading] = React.useState<boolean>(true);
|
||||
const [compressed, setCompressed] = React.useState<string | undefined>();
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!isReady) return;
|
||||
if (compressed) return;
|
||||
|
||||
if (encoded) {
|
||||
setCompressed(encoded as string);
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hash) {
|
||||
fetch(
|
||||
`https://${process.env.NEXT_PUBLIC_PREVIEWS_BUCKET_NAME}.fra1.cdn.digitaloceanspaces.com/preview-strings/${hash}`,
|
||||
)
|
||||
.then((body) =>
|
||||
body.text().then((data) => {
|
||||
setCompressed(data);
|
||||
setIsLoading(false);
|
||||
}),
|
||||
)
|
||||
.catch((e) => {
|
||||
setIsLoading(false);
|
||||
});
|
||||
}
|
||||
}, [isReady, compressed, encoded, hash]);
|
||||
|
||||
const code = React.useMemo(() => {
|
||||
if (!isReady) return "";
|
||||
if (!compressed) return "";
|
||||
const decompressed = decompressFromEncodedURIComponent(
|
||||
compressed as string,
|
||||
);
|
||||
const fixed = decompressed?.replace(/React\$1/g, "React");
|
||||
|
||||
const shouldChangeEntrypoint =
|
||||
fixed.match(/render\(<App \/>\);?/) &&
|
||||
fixed.match(/createRoot\(container\);?/);
|
||||
|
||||
let content = fixed;
|
||||
|
||||
if (shouldChangeEntrypoint) {
|
||||
content = fixed.replace(/render\(<App \/>\);?/, "");
|
||||
content = content.replace(
|
||||
/createRoot\(container\);?/,
|
||||
"{ render: (children) => render(<RefineCore.ExternalNavigationProvider>{children}</RefineCore.ExternalNavigationProvider>) };",
|
||||
);
|
||||
}
|
||||
|
||||
return content;
|
||||
}, [compressed, isReady]);
|
||||
|
||||
const css = React.useMemo(() => {
|
||||
if (!isReady) return "";
|
||||
if (!cssCompressed) return "";
|
||||
try {
|
||||
return base64url.decode(cssCompressed as string);
|
||||
} catch (err) {
|
||||
console.log("CSS Decode Error", { err });
|
||||
return "";
|
||||
}
|
||||
}, [cssCompressed, isReady]);
|
||||
|
||||
return {
|
||||
code,
|
||||
css,
|
||||
isReady,
|
||||
hasQuery: !!encoded || !!hash,
|
||||
disableScroll: !!disableScroll,
|
||||
useTailwind: !!tailwind,
|
||||
isLoading,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user