Skip to content

Commit

Permalink
fix: remove the need for users to use callback
Browse files Browse the repository at this point in the history
  • Loading branch information
phanshiyu committed May 12, 2024
1 parent 093c12b commit 7a6707c
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 90 deletions.
17 changes: 6 additions & 11 deletions example/application/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,6 @@ const Viewer: React.FunctionComponent<ViewerProps> = ({ document }): React.React
const [selectedTemplate, setSelectedTemplate] = useState<string>("");
const [rendererResults, setRendererResults] = useState<ConnectedResults>();

const onConnected = useCallback((results) => {
setRendererResults(results);
setSelectedTemplate(results.templates?.[0]?.id ?? "");
}, []);

const onError = useCallback((error) => {
console.error(error);
}, []);

return (
<div
css={css`
Expand Down Expand Up @@ -174,8 +165,12 @@ const Viewer: React.FunctionComponent<ViewerProps> = ({ document }): React.React
>
<TheRenderer
document={document.document}
onConnected={onConnected}
onError={onError}
onConnected={(results) => {
console.log(results);
setRendererResults(results);
if (results.type === "EMBEDDED_RENDERER") setSelectedTemplate(results.templates?.[0]?.id ?? "");
}}
onError={console.error}
loadingComponent={<>loading...</>}
/>
</div>
Expand Down
170 changes: 91 additions & 79 deletions src/components/TheRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useRef, useState } from "react";
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";

Check warning on line 1 in src/components/TheRenderer.tsx

View workflow job for this annotation

GitHub Actions / Test

'useMemo' is defined but never used
import { isActionOf } from "typesafe-actions";

import { HostActionsHandler } from "./frame/host.actions";
Expand Down Expand Up @@ -149,39 +149,43 @@ const TheSvgRenderer: React.FunctionComponent<TheSvgRendererProps> = ({
...rest
}) => {
const svgRef = useRef<HTMLImageElement>(null);
const onSvgRendererResult = useCallback(
(displayResult: DisplayResult) => {
if (displayResult.status === "OK") {
onConnected({
type: "SVG_RENDERER",
print() {
if (!svgRef.current) return;
printImageElement(svgRef.current);
},
});
} else {
let rendererError: RendererError = { type: "UNKNOWN_ERROR" };
switch (displayResult.status) {
case "DIGEST_ERROR": {
rendererError = { type: "SVG_INVALID_MULTIBASE_DIGEST_ERROR" };
break;
}
case "FETCH_SVG_ERROR": {
rendererError = { type: "SVG_FETCH_ERROR", error: displayResult.error };
break;
}
case "SVG_LOAD_ERROR": {
rendererError = { type: "SVG_LOAD_ERROR" };
break;
}
default:
rendererError = { type: "UNKNOWN_ERROR" };

const onConnectedRef = useRef(onConnected);
onConnectedRef.current = onConnected;

const onErrorRef = useRef(onError);
onErrorRef.current = onError;

const onSvgRendererResult = useCallback((displayResult: DisplayResult) => {
if (displayResult.status === "OK") {
onConnectedRef.current({
type: "SVG_RENDERER",
print() {
if (!svgRef.current) return;
printImageElement(svgRef.current);
},
});
} else {
let rendererError: RendererError = { type: "UNKNOWN_ERROR" };
switch (displayResult.status) {
case "DIGEST_ERROR": {
rendererError = { type: "SVG_INVALID_MULTIBASE_DIGEST_ERROR" };
break;
}
case "FETCH_SVG_ERROR": {
rendererError = { type: "SVG_FETCH_ERROR", error: displayResult.error };
break;
}
onError(rendererError);
case "SVG_LOAD_ERROR": {
rendererError = { type: "SVG_LOAD_ERROR" };
break;
}
default:
rendererError = { type: "UNKNOWN_ERROR" };
}
},
[onConnected, onError]
);
onErrorRef.current?.(rendererError);
}
}, []);

if (versionedDocument.version === "2.0") {
return (
Expand Down Expand Up @@ -221,6 +225,15 @@ const TheEmbeddedRenderer: React.FunctionComponent<TheEmbeddedRendererProps> = (
const [isFrameLoading, setFrameLoading] = useState(true);
const dispatchToFrameRef = useRef<HostActionsHandler>();

const onConnectedRef = useRef(onConnected);
onConnectedRef.current = onConnected;

const onErrorRef = useRef(onError);
onErrorRef.current = onError;

const onObfuscateFieldRef = useRef(onObfuscateField);
onObfuscateFieldRef.current = onObfuscateField;

const handleFrameConnected = useCallback((dispatchToFrame: HostActionsHandler) => {
dispatchToFrameRef.current = (...params) => {
try {
Expand Down Expand Up @@ -251,50 +264,47 @@ const TheEmbeddedRenderer: React.FunctionComponent<TheEmbeddedRendererProps> = (
}
}, [versionedDocument, isFrameLoading]);

const handleFrameActions = useCallback(
(action: FrameActions): void => {
if (isActionOf(updateHeight, action)) {
setIframeHeight(action.payload);
}
if (isActionOf(obfuscateField, action)) {
onObfuscateField?.(action.payload);
}
if (isActionOf(updateTemplates, action)) {
const templates = action.payload;
if (!dispatchToFrameRef.current) throw new Error("This should not happen");
dispatchToFrameRef.current({
type: "SELECT_TEMPLATE",
payload: templates[0].id,
});

// call on connected here
onConnected({
type: "EMBEDDED_RENDERER",
templates,
selectTemplate(props) {
dispatchToFrameRef.current?.({
type: "SELECT_TEMPLATE",
payload: props.id,
});
},
print() {
dispatchToFrameRef.current?.({
type: "PRINT",
});
},
});
}
const handleFrameActions = useCallback((action: FrameActions): void => {
if (isActionOf(updateHeight, action)) {
setIframeHeight(action.payload);
}
if (isActionOf(obfuscateField, action)) {
onObfuscateFieldRef.current?.(action.payload);
}
if (isActionOf(updateTemplates, action)) {
const templates = action.payload;
if (!dispatchToFrameRef.current) throw new Error("This should not happen");
dispatchToFrameRef.current({
type: "SELECT_TEMPLATE",
payload: templates[0].id,
});

if (isActionOf(timeout, action)) {
setFrameLoading(false);
// call on connected here
onConnectedRef.current({
type: "EMBEDDED_RENDERER",
templates,
selectTemplate(props) {
dispatchToFrameRef.current?.({
type: "SELECT_TEMPLATE",
payload: props.id,
});
},
print() {
dispatchToFrameRef.current?.({
type: "PRINT",
});
},
});
}

onError({
type: "CONNECTION_TIMEOUT",
});
}
},
[onConnected, onError, onObfuscateField]
);
if (isActionOf(timeout, action)) {
setFrameLoading(false);

onErrorRef.current?.({
type: "CONNECTION_TIMEOUT",
});
}
}, []);

return (
<>
Expand Down Expand Up @@ -324,22 +334,25 @@ type TheRendererProps = {
document: v2.OpenAttestationDocument | v2.WrappedDocument | v4.Document;
loadingComponent?: React.ReactNode;
onConnected: (results: ConnectedResults) => void;
onError: (error: RendererError) => void;
onError?: (error: RendererError) => void;
onObfuscateField?: (field: string) => void;
};
export const TheRenderer: React.FunctionComponent<TheRendererProps> = ({ document, ...props }) => {
const onErrorRef = useRef(props.onError);
onErrorRef.current = props.onError;

const parsed = React.useMemo(() => {
const versionedDocument = getVersionedDocument(document);
if (versionedDocument.version === null) {
props?.onError({
onErrorRef.current?.({
type: "UNSUPPORTED_DOCUMENT_VERSION",
});
return null;
}

const renderMethod = getRenderMethod(versionedDocument);
if (renderMethod.type === "NONE") {
props?.onError({
onErrorRef.current?.({
type: "NO_RENDER_METHOD_FOUND",
});
}
Expand All @@ -348,7 +361,7 @@ export const TheRenderer: React.FunctionComponent<TheRendererProps> = ({ documen
renderMethod,
versionedDocument,
};
}, [document, props]);
}, [document]);

if (!parsed) {
return (
Expand All @@ -367,7 +380,6 @@ export const TheRenderer: React.FunctionComponent<TheRendererProps> = ({ documen

const { renderMethod, versionedDocument } = parsed;

// TODO: can render default renderer here
if (renderMethod.type === "NONE")
return (
<div className={props.className} style={props.style}>
Expand Down

0 comments on commit 7a6707c

Please sign in to comment.