tailwind-nextjs-blog/components/comments/commento/ReactCommento.tsx

94 lines
1.8 KiB
TypeScript
Raw Normal View History

2022-10-17 23:37:01 +08:00
import { createRef } from 'preact';
import React, { useLayoutEffect, useMemo, useRef } from 'react';
interface DataAttributes {
2022-10-17 23:37:01 +08:00
[key: string]: string | boolean | undefined;
}
const insertScript = (
src: string,
id: string,
dataAttributes: DataAttributes,
onload = () => {}
) => {
2022-10-17 23:37:01 +08:00
const script = window.document.createElement('script');
script.async = true;
script.src = src;
script.id = id;
if (document.getElementById(id)) {
2022-10-17 23:37:01 +08:00
return;
}
2022-10-17 23:37:01 +08:00
script.addEventListener('load', onload, { capture: true, once: true });
Object.entries(dataAttributes).forEach(([key, value]) => {
if (value === undefined) {
2022-10-17 23:37:01 +08:00
return;
}
2022-10-17 23:37:01 +08:00
script.setAttribute(`data-${key}`, value.toString());
});
2022-10-17 23:37:01 +08:00
document.body.appendChild(script);
return () => {
2022-10-17 23:37:01 +08:00
script.remove();
};
};
const ReactCommento = ({
url,
cssOverride,
autoInit,
noFonts,
hideDeleted,
pageId,
}: {
2022-10-17 23:37:01 +08:00
url: string;
cssOverride?: string;
autoInit?: boolean;
noFonts?: boolean;
hideDeleted?: boolean;
pageId?: string;
}) => {
2022-10-17 23:37:01 +08:00
const containerId = useMemo(
() => `commento-${Math.random().toString().slice(2, 8)}`,
[]
);
const container = createRef<HTMLDivElement>();
useLayoutEffect(() => {
if (!window) {
2022-10-17 23:37:01 +08:00
return;
}
2022-10-17 23:37:01 +08:00
window['commento'] = container.current;
const removeScript = insertScript(
url,
`${containerId}-script`,
{
'css-override': cssOverride,
'auto-init': autoInit,
'no-fonts': noFonts,
'hide-deleted': hideDeleted,
'page-id': pageId,
'id-root': containerId,
},
() => {
2022-10-17 23:37:01 +08:00
removeScript();
}
2022-10-17 23:37:01 +08:00
);
}, [
autoInit,
cssOverride,
hideDeleted,
noFonts,
pageId,
url,
containerId,
container,
]);
2022-10-17 23:37:01 +08:00
return <div ref={container} id={containerId} />;
};
export default ReactCommento;