diff --git a/src/components/Home/Home.tsx b/src/components/Home/Home.tsx
index a5711c7..8770f4e 100644
--- a/src/components/Home/Home.tsx
+++ b/src/components/Home/Home.tsx
@@ -15,25 +15,45 @@ export interface ScanResult {
}
const Home = () => {
- const { send } = useAppBridge();
+ const { send, receive } = useAppBridge();
const { setScanData } = useScanDataStore();
const { navigateToReceiptEdit } = useRoute();
+ const handleScanResult = (jsonData: string) => {
+ try {
+ const data: ScanResult[] = JSON.parse(jsonData);
+
+ receive({
+ type: AppBridgeMessageType.RECEIVE_SCAN_RESULT,
+ payload: data,
+ });
+
+ setScanData(data);
+
+ navigateToReceiptEdit();
+ } catch (error) {
+ console.error("스캔 결과 JSON 파싱 오류:", error);
+ alert("스캔 데이터를 처리하는 중 오류가 발생했습니다. 다시 시도해 주세요.");
+ }
+ };
+
useEffect(() => {
- window.response = {
- receiveScanResult: (jsonData: string) => {
- try {
- const data: ScanResult[] = JSON.parse(jsonData);
- setScanData(data);
- navigateToReceiptEdit();
- } catch (error) {
- console.error("Error parsing scan result JSON:", error);
- }
- },
+ const responseHandler = {
+ receiveScanResult: handleScanResult,
};
- }, []);
+
+ if (typeof window !== "undefined") {
+ window.response = Object.assign({}, window.response, responseHandler);
+ }
+
+ return () => {
+ if (typeof window !== "undefined") {
+ delete window.response;
+ }
+ };
+ }, [receive, navigateToReceiptEdit, setScanData]);
return (
@@ -59,18 +79,6 @@ const Home = () => {
iconName="camera"
onClick={() => send({ type: AppBridgeMessageType.OPEN_CAMERA, payload: "" })}
/>
-
-
);
diff --git a/src/components/provider/AppBridgeProvider/AppBridgeMessage.types.ts b/src/components/provider/AppBridgeProvider/AppBridgeMessage.types.ts
index db83f86..8b8d7c2 100644
--- a/src/components/provider/AppBridgeProvider/AppBridgeMessage.types.ts
+++ b/src/components/provider/AppBridgeProvider/AppBridgeMessage.types.ts
@@ -4,6 +4,8 @@ export enum AppBridgeMessageType {
SHARE = "share",
CREATE_REVIEW = "createReview",
COPY = "copy",
+ RECEIVE_SCAN_RESULT = "receiveScanResult",
+ RECEIVE_GENERATED_REVIEW = "receiveGeneratedReview",
}
export type AppBridgeMessage =
@@ -11,7 +13,9 @@ export type AppBridgeMessage =
| OpenGalleryMessage
| ShareMessage
| CreateReviewMessage
- | CopyMessage;
+ | CopyMessage
+ | ReceiveScanResultMessage
+ | ReceiveGeneratedReviewMessage;
export interface OpenCameraMessage {
type: AppBridgeMessageType.OPEN_CAMERA;
@@ -43,3 +47,15 @@ export interface CopyMessage {
review: string;
};
}
+
+export interface ReceiveScanResultMessage {
+ type: AppBridgeMessageType.RECEIVE_SCAN_RESULT;
+ payload: Array<{ [key: string]: string }>;
+}
+
+export interface ReceiveGeneratedReviewMessage {
+ type: AppBridgeMessageType.RECEIVE_GENERATED_REVIEW;
+ payload: {
+ result: string;
+ };
+}
diff --git a/src/components/provider/AppBridgeProvider/AppBridgeProvider.tsx b/src/components/provider/AppBridgeProvider/AppBridgeProvider.tsx
index b109d02..eaa10c5 100644
--- a/src/components/provider/AppBridgeProvider/AppBridgeProvider.tsx
+++ b/src/components/provider/AppBridgeProvider/AppBridgeProvider.tsx
@@ -1,5 +1,5 @@
import type { ReactNode } from "react";
-import { createContext, useContext } from "react";
+import { createContext, useContext, useEffect } from "react";
import type { AppBridgeMessage } from "@/components/provider/AppBridgeProvider/AppBridgeMessage.types";
import {
@@ -8,17 +8,22 @@ import {
} from "@/components/provider/AppBridgeProvider/convertToNativeMessage";
import { useUserAgent } from "@/components/provider/UserAgentProvider";
+import { useScanDataStore } from "@/store/useScanDataStore";
+
interface AppBridgeProviderProps {
children: ReactNode;
}
interface AppBridge {
send: (message: AppBridgeMessage) => void;
+ receive: (message: AppBridgeMessage) => void;
}
export const AppBridgeContext = createContext(null);
export function AppBridgeProvider({ children }: AppBridgeProviderProps) {
+ const { setScanData } = useScanDataStore();
+
const userAgent = useUserAgent();
const isIOS = userAgent.isIOS;
@@ -32,7 +37,41 @@ export function AppBridgeProvider({ children }: AppBridgeProviderProps) {
}
};
- return {children};
+ const receive = (message: AppBridgeMessage) => {
+ try {
+ if (isIOS) return convertToIOSAppBridge(message);
+ return convertToAndroidAppBridge(message);
+ } catch {
+ alert("App Bridge API called: " + message.type);
+ }
+ };
+
+ useEffect(() => {
+ if (typeof window !== "undefined") {
+ window.response = {
+ receiveScanResult: (jsonData: string) => {
+ try {
+ const data = JSON.parse(jsonData);
+ setScanData(data);
+ } catch (error) {
+ console.error("Invalid JSON data for scan result:", error);
+ }
+ },
+ receiveGeneratedReview: (jsonData: string) => {
+ try {
+ const data = JSON.parse(jsonData);
+ alert(`Generated Review: ${data.review}`);
+ } catch (error) {
+ console.error("Invalid JSON data for generated review:", error);
+ }
+ },
+ };
+ }
+ }, []);
+
+ return (
+ {children}
+ );
}
export function useAppBridge() {
diff --git a/src/components/provider/AppBridgeProvider/convertToNativeMessage.ts b/src/components/provider/AppBridgeProvider/convertToNativeMessage.ts
index 4844dc2..4c5e8c4 100644
--- a/src/components/provider/AppBridgeProvider/convertToNativeMessage.ts
+++ b/src/components/provider/AppBridgeProvider/convertToNativeMessage.ts
@@ -12,6 +12,10 @@ const iosHandlers = {
window.webkit?.messageHandlers.createReview.postMessage(message.payload.json),
[AppBridgeMessageType.COPY]: (message: { payload: { json: string } }) =>
window.webkit?.messageHandlers.copy.postMessage(message.payload.json),
+ [AppBridgeMessageType.RECEIVE_SCAN_RESULT]: (message: { payload: { result: string } }) =>
+ window.response?.receiveScanResult(message.payload.result),
+ [AppBridgeMessageType.RECEIVE_GENERATED_REVIEW]: (message: { payload: { result: string } }) =>
+ window.response?.receiveGeneratedReview(message.payload.result),
};
const androidHandlers = {
@@ -22,6 +26,10 @@ const androidHandlers = {
window.AndroidBridge?.createReview(message.payload.json),
[AppBridgeMessageType.COPY]: (message: { payload: { json: string } }) =>
window.AndroidBridge?.copy(message.payload.json),
+ [AppBridgeMessageType.RECEIVE_SCAN_RESULT]: (message: { payload: { result: string } }) =>
+ window.response?.receiveScanResult(message.payload.result),
+ [AppBridgeMessageType.RECEIVE_GENERATED_REVIEW]: (message: { payload: { result: string } }) =>
+ window.response?.receiveGeneratedReview(message.payload.result),
};
export function convertToIOSAppBridge(message: AppBridgeMessage) {
diff --git a/src/components/provider/WebBridgeProvider/WebBridgeMessage.types.ts b/src/components/provider/WebBridgeProvider/WebBridgeMessage.types.ts
deleted file mode 100644
index 1bed8c0..0000000
--- a/src/components/provider/WebBridgeProvider/WebBridgeMessage.types.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-export enum WebBridgeMessageType {
- RECEIVE_SCAN_RESULT = "RECEIVE_SCAN_RESULT",
-}
-
-export type WebBridgeMessage = ReceiveScanResultMessage;
-
-export interface ReceiveScanResultMessage {
- type: WebBridgeMessageType.RECEIVE_SCAN_RESULT;
-}
diff --git a/src/components/provider/WebBridgeProvider/WebBridgeProvider.tsx b/src/components/provider/WebBridgeProvider/WebBridgeProvider.tsx
deleted file mode 100644
index b87b997..0000000
--- a/src/components/provider/WebBridgeProvider/WebBridgeProvider.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import type { ReactNode } from "react";
-import { createContext, useContext, useEffect } from "react";
-
-interface WebBridgeMessage {
- type: string;
- payload?: unknown;
-}
-
-interface WebBridge {
- receive: (message: WebBridgeMessage) => void;
-}
-
-interface WebBridgeProviderProps {
- children: ReactNode;
-}
-
-export const WebBridgeContext = createContext(null);
-
-export function WebBridgeProvider({ children }: WebBridgeProviderProps) {
- const receive = (message: WebBridgeMessage) => {
- try {
- if (typeof window !== "undefined" && window.response) {
- if (typeof window.response.receiveScanResult === "function") {
- window.response.receiveScanResult(JSON.stringify(message.payload));
- } else {
- console.warn("window.response.receiveScanResult is not available.");
- }
- }
- } catch (error) {
- console.error("WebBridge API call failed:", error);
- }
- };
-
- useEffect(() => {
- if (typeof window !== "undefined" && !window.response) {
- window.response = {
- receiveScanResult: (jsonData: string) => {
- console.log("Received scan result:", jsonData);
- },
- };
- }
- }, []);
-
- return {children};
-}
-
-export function useWebBridge() {
- const webBridge = useContext(WebBridgeContext);
-
- if (webBridge == null) {
- throw new Error("Wrap Web Bridge Provider");
- }
-
- return webBridge;
-}
diff --git a/src/main.tsx b/src/main.tsx
index 92ac95a..3a49d45 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -8,7 +8,6 @@ import AppRouter from "@/router/AppRouter";
import { AppBridgeProvider } from "@/components/provider/AppBridgeProvider/AppBridgeProvider";
import ReactQueryClientProvider from "@/components/provider/ReactQueryClientProvider";
import { UserAgentProvider } from "@/components/provider/UserAgentProvider";
-import { WebBridgeProvider } from "@/components/provider/WebBridgeProvider/WebBridgeProvider";
import "@/styles/reset.scss";
import "@/styles/global.scss";
@@ -18,10 +17,8 @@ ReactDom.createRoot(document.getElementById("root")!).render(
-
-
-
-
+
+
diff --git a/src/types/global.d.ts b/src/types/global.d.ts
index c8e9919..b3924ce 100644
--- a/src/types/global.d.ts
+++ b/src/types/global.d.ts
@@ -13,6 +13,7 @@ declare global {
interface Window {
response?: {
receiveScanResult: (jsonData: string) => void;
+ receiveGeneratedReview: (jsonData: string) => void;
};
webkit?: {
messageHandlers: {