Skip to content

Commit dffd34b

Browse files
committed
refactor: receive 핸들러 공통화 수정
1 parent 60898ab commit dffd34b

File tree

8 files changed

+99
-128
lines changed

8 files changed

+99
-128
lines changed

src/components/Home/Home.tsx

Lines changed: 30 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import { useEffect } from "react";
33
import styles from "@/components/Home/Home.module.scss";
44
import { AppBridgeMessageType } from "@/components/provider/AppBridgeProvider/AppBridgeMessage.types";
55
import { useAppBridge } from "@/components/provider/AppBridgeProvider/AppBridgeProvider";
6-
import { WebBridgeMessageType } from "@/components/provider/WebBridgeProvider/WebBridgeProvider";
7-
import { useWebBridge } from "@/components/provider/WebBridgeProvider/WebBridgeProvider";
86
import IconButton from "@/components/ui/IconButton/IconButton";
97
import Text from "@/components/ui/Text/Text";
108

@@ -17,37 +15,46 @@ export interface ScanResult {
1715
}
1816

1917
const Home = () => {
20-
const { send } = useAppBridge();
21-
22-
const { receive } = useWebBridge();
23-
18+
const { send, receive } = useAppBridge();
2419
const { setScanData } = useScanDataStore();
25-
2620
const { navigateToReceiptEdit } = useRoute();
2721

22+
const handleScanResult = (jsonData: string) => {
23+
try {
24+
const data: ScanResult[] = JSON.parse(jsonData);
25+
receive({
26+
type: AppBridgeMessageType.RECEIVE_SCAN_RESULT,
27+
payload: data,
28+
});
29+
setScanData(data);
30+
navigateToReceiptEdit();
31+
} catch (error) {
32+
console.error("스캔 결과 JSON 파싱 오류:", error);
33+
alert("스캔 데이터를 처리하는 중 오류가 발생했습니다. 다시 시도해 주세요.");
34+
}
35+
};
36+
2837
useEffect(() => {
2938
if (typeof window !== "undefined" && !window.response) {
3039
window.response = {
31-
receiveScanResult: (jsonData: string) => {
32-
try {
33-
const data: ScanResult[] = JSON.parse(jsonData);
34-
receive({
35-
type: WebBridgeMessageType.RECEIVE_SCAN_RESULT,
36-
payload: data,
37-
});
38-
39-
setScanData(data);
40-
setTimeout(() => {
41-
navigateToReceiptEdit();
42-
}, 0);
43-
} catch (error) {
44-
console.error("Error parsing scan result JSON:", error);
45-
}
40+
receiveScanResult: handleScanResult,
41+
receiveGeneratedReview: (jsonData: string) => {
42+
console.log("Generated review received:", jsonData);
4643
},
4744
};
4845
}
46+
47+
return () => {
48+
if (typeof window !== "undefined") {
49+
delete window.response;
50+
}
51+
};
4952
}, [receive, navigateToReceiptEdit, setScanData]);
5053

54+
const handleCameraClick = () => {
55+
send({ type: AppBridgeMessageType.OPEN_CAMERA, payload: "" });
56+
};
57+
5158
return (
5259
<div className={styles.Home}>
5360
<div className={styles.HomeTitle}>
@@ -67,33 +74,7 @@ const Home = () => {
6774
iconName="gallery"
6875
onClick={() => send({ type: AppBridgeMessageType.OPEN_GALLERY, payload: "" })}
6976
/>
70-
<IconButton
71-
text="카메라"
72-
iconName="camera"
73-
onClick={() => {
74-
send({ type: AppBridgeMessageType.OPEN_CAMERA, payload: "" });
75-
if (typeof window !== "undefined" && !window.response) {
76-
window.response = {
77-
receiveScanResult: (jsonData: string) => {
78-
try {
79-
const data: ScanResult[] = JSON.parse(jsonData);
80-
receive({
81-
type: WebBridgeMessageType.RECEIVE_SCAN_RESULT,
82-
payload: data,
83-
});
84-
85-
setScanData(data);
86-
setTimeout(() => {
87-
navigateToReceiptEdit();
88-
}, 0);
89-
} catch (error) {
90-
console.error("Error parsing scan result JSON:", error);
91-
}
92-
},
93-
};
94-
}
95-
}}
96-
/>
77+
<IconButton text="카메라" iconName="camera" onClick={handleCameraClick} />
9778
</div>
9879
</div>
9980
);

src/components/provider/AppBridgeProvider/AppBridgeMessage.types.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@ export enum AppBridgeMessageType {
44
SHARE = "share",
55
CREATE_REVIEW = "createReview",
66
COPY = "copy",
7+
RECEIVE_SCAN_RESULT = "receiveScanResult",
8+
RECEIVE_GENERATED_REVIEW = "receiveGeneratedReview",
79
}
810

911
export type AppBridgeMessage =
1012
| OpenCameraMessage
1113
| OpenGalleryMessage
1214
| ShareMessage
1315
| CreateReviewMessage
14-
| CopyMessage;
16+
| CopyMessage
17+
| ReceiveScanResultMessage
18+
| ReceiveGeneratedReviewMessage;
1519

1620
export interface OpenCameraMessage {
1721
type: AppBridgeMessageType.OPEN_CAMERA;
@@ -43,3 +47,15 @@ export interface CopyMessage {
4347
review: string;
4448
};
4549
}
50+
51+
export interface ReceiveScanResultMessage {
52+
type: AppBridgeMessageType.RECEIVE_SCAN_RESULT;
53+
payload: Array<{ [key: string]: string }>;
54+
}
55+
56+
export interface ReceiveGeneratedReviewMessage {
57+
type: AppBridgeMessageType.RECEIVE_GENERATED_REVIEW;
58+
payload: {
59+
result: string;
60+
};
61+
}

src/components/provider/AppBridgeProvider/AppBridgeProvider.tsx

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { ReactNode } from "react";
2-
import { createContext, useContext } from "react";
2+
import { createContext, useContext, useEffect } from "react";
33

44
import type { AppBridgeMessage } from "@/components/provider/AppBridgeProvider/AppBridgeMessage.types";
55
import {
@@ -8,17 +8,22 @@ import {
88
} from "@/components/provider/AppBridgeProvider/convertToNativeMessage";
99
import { useUserAgent } from "@/components/provider/UserAgentProvider";
1010

11+
import { useScanDataStore } from "@/store/useScanDataStore";
12+
1113
interface AppBridgeProviderProps {
1214
children: ReactNode;
1315
}
1416

1517
interface AppBridge {
1618
send: (message: AppBridgeMessage) => void;
19+
receive: (message: AppBridgeMessage) => void;
1720
}
1821

1922
export const AppBridgeContext = createContext<null | AppBridge>(null);
2023

2124
export function AppBridgeProvider({ children }: AppBridgeProviderProps) {
25+
const { setScanData } = useScanDataStore();
26+
2227
const userAgent = useUserAgent();
2328

2429
const isIOS = userAgent.isIOS;
@@ -32,7 +37,41 @@ export function AppBridgeProvider({ children }: AppBridgeProviderProps) {
3237
}
3338
};
3439

35-
return <AppBridgeContext.Provider value={{ send }}>{children}</AppBridgeContext.Provider>;
40+
const receive = (message: AppBridgeMessage) => {
41+
try {
42+
if (isIOS) return convertToIOSAppBridge(message);
43+
return convertToAndroidAppBridge(message);
44+
} catch {
45+
alert("App Bridge API called: " + message.type);
46+
}
47+
};
48+
49+
useEffect(() => {
50+
if (typeof window !== "undefined") {
51+
window.response = {
52+
receiveScanResult: (jsonData: string) => {
53+
try {
54+
const data = JSON.parse(jsonData);
55+
setScanData(data);
56+
} catch (error) {
57+
console.error("Invalid JSON data for scan result:", error);
58+
}
59+
},
60+
receiveGeneratedReview: (jsonData: string) => {
61+
try {
62+
const data = JSON.parse(jsonData);
63+
alert(`Generated Review: ${data.review}`);
64+
} catch (error) {
65+
console.error("Invalid JSON data for generated review:", error);
66+
}
67+
},
68+
};
69+
}
70+
}, []);
71+
72+
return (
73+
<AppBridgeContext.Provider value={{ send, receive }}>{children}</AppBridgeContext.Provider>
74+
);
3675
}
3776

3877
export function useAppBridge() {

src/components/provider/AppBridgeProvider/convertToNativeMessage.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ const iosHandlers = {
1212
window.webkit?.messageHandlers.createReview.postMessage(message.payload.json),
1313
[AppBridgeMessageType.COPY]: (message: { payload: { json: string } }) =>
1414
window.webkit?.messageHandlers.copy.postMessage(message.payload.json),
15+
[AppBridgeMessageType.RECEIVE_SCAN_RESULT]: (message: { payload: { result: string } }) =>
16+
window.response?.receiveScanResult(message.payload.result),
17+
[AppBridgeMessageType.RECEIVE_GENERATED_REVIEW]: (message: { payload: { result: string } }) =>
18+
window.response?.receiveGeneratedReview(message.payload.result),
1519
};
1620

1721
const androidHandlers = {
@@ -22,6 +26,10 @@ const androidHandlers = {
2226
window.AndroidBridge?.createReview(message.payload.json),
2327
[AppBridgeMessageType.COPY]: (message: { payload: { json: string } }) =>
2428
window.AndroidBridge?.copy(message.payload.json),
29+
[AppBridgeMessageType.RECEIVE_SCAN_RESULT]: (message: { payload: { result: string } }) =>
30+
window.response?.receiveScanResult(message.payload.result),
31+
[AppBridgeMessageType.RECEIVE_GENERATED_REVIEW]: (message: { payload: { result: string } }) =>
32+
window.response?.receiveGeneratedReview(message.payload.result),
2533
};
2634

2735
export function convertToIOSAppBridge(message: AppBridgeMessage) {

src/components/provider/WebBridgeProvider/WebBridgeMessage.types.ts

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/components/provider/WebBridgeProvider/WebBridgeProvider.tsx

Lines changed: 0 additions & 62 deletions
This file was deleted.

src/main.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import AppRouter from "@/router/AppRouter";
88
import { AppBridgeProvider } from "@/components/provider/AppBridgeProvider/AppBridgeProvider";
99
import ReactQueryClientProvider from "@/components/provider/ReactQueryClientProvider";
1010
import { UserAgentProvider } from "@/components/provider/UserAgentProvider";
11-
import { WebBridgeProvider } from "@/components/provider/WebBridgeProvider/WebBridgeProvider";
1211

1312
import "@/styles/reset.scss";
1413
import "@/styles/global.scss";
@@ -18,10 +17,8 @@ ReactDom.createRoot(document.getElementById("root")!).render(
1817
<ReactQueryClientProvider>
1918
<UserAgentProvider>
2019
<AppBridgeProvider>
21-
<WebBridgeProvider>
22-
<AppRouter />
23-
<ReactQueryDevtools initialIsOpen={false} />
24-
</WebBridgeProvider>
20+
<AppRouter />
21+
<ReactQueryDevtools initialIsOpen={false} />
2522
</AppBridgeProvider>
2623
</UserAgentProvider>
2724
</ReactQueryClientProvider>

src/types/global.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ declare global {
1313
interface Window {
1414
response?: {
1515
receiveScanResult: (jsonData: string) => void;
16+
receiveGeneratedReview: (jsonData: string) => void;
1617
};
1718
webkit?: {
1819
messageHandlers: {

0 commit comments

Comments
 (0)