@apps-in-toss/framework 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +330 -259
- package/dist/index.d.cts +42 -2
- package/dist/index.d.ts +42 -2
- package/dist/index.js +289 -221
- package/package.json +13 -13
package/dist/index.js
CHANGED
|
@@ -848,18 +848,18 @@ import {
|
|
|
848
848
|
import * as appsInTossAsyncBridges from "@apps-in-toss/native-modules/async-bridges";
|
|
849
849
|
import * as appsInTossConstantBridges from "@apps-in-toss/native-modules/constant-bridges";
|
|
850
850
|
import * as appsInTossEventBridges from "@apps-in-toss/native-modules/event-bridges";
|
|
851
|
-
import { getSchemeUri as getSchemeUri6
|
|
851
|
+
import { getSchemeUri as getSchemeUri6 } from "@granite-js/react-native";
|
|
852
852
|
import { ExternalWebViewScreen, tdsEvent } from "@toss/tds-react-native";
|
|
853
853
|
import { useSafeAreaBottom, useSafeAreaTop as useSafeAreaTop2, useTopNavigation } from "@toss/tds-react-native/private";
|
|
854
|
-
import { useMemo as
|
|
855
|
-
import { Platform as Platform4 } from "react-native";
|
|
854
|
+
import { useEffect as useEffect11, useMemo as useMemo5, useRef as useRef6, useState as useState5 } from "react";
|
|
855
|
+
import { BackHandler as BackHandler2, Platform as Platform4 } from "react-native";
|
|
856
856
|
|
|
857
857
|
// src/components/GameWebView.tsx
|
|
858
858
|
import { setIosSwipeGestureEnabled as setIosSwipeGestureEnabled2, appsInTossEvent as appsInTossEvent2, getOperationalEnvironment as getOperationalEnvironment2 } from "@apps-in-toss/native-modules";
|
|
859
859
|
import {
|
|
860
860
|
WebView as PlainWebView
|
|
861
861
|
} from "@granite-js/native/react-native-webview";
|
|
862
|
-
import { forwardRef, useEffect as
|
|
862
|
+
import { forwardRef, useEffect as useEffect9, useState as useState3 } from "react";
|
|
863
863
|
import { Platform as Platform3 } from "react-native";
|
|
864
864
|
|
|
865
865
|
// src/components/GameProfile.tsx
|
|
@@ -1181,8 +1181,8 @@ import { closeView as closeView3 } from "@granite-js/react-native";
|
|
|
1181
1181
|
import { PageNavbar, useDialog as useDialog5 } from "@toss/tds-react-native";
|
|
1182
1182
|
import { NavigationRightContent, useSafeAreaTop } from "@toss/tds-react-native/private";
|
|
1183
1183
|
import { josa as josa3 } from "es-hangul";
|
|
1184
|
-
import { useCallback as useCallback5
|
|
1185
|
-
import {
|
|
1184
|
+
import { useCallback as useCallback5 } from "react";
|
|
1185
|
+
import { Platform as Platform2, View as View2 } from "react-native";
|
|
1186
1186
|
import { Fragment as Fragment6, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1187
1187
|
function GameWebviewNavigationBar() {
|
|
1188
1188
|
const safeAreaTop = useSafeAreaTop();
|
|
@@ -1194,6 +1194,7 @@ function GameWebviewNavigationBar() {
|
|
|
1194
1194
|
const parsedNavigationBar = global2.navigationBar != null ? safeParseNavigationBar(global2.navigationBar) : null;
|
|
1195
1195
|
const initialAccessoryButton = parsedNavigationBar?.initialAccessoryButton;
|
|
1196
1196
|
const handleGameWebviewClose = useCallback5(async () => {
|
|
1197
|
+
logging.closeButtonClick();
|
|
1197
1198
|
const isConfirmed = await openConfirm({
|
|
1198
1199
|
title: `${josa3(global2.brandDisplayName, "\uC744/\uB97C")} \uC885\uB8CC\uD560\uAE4C\uC694?`,
|
|
1199
1200
|
leftButton: "\uCDE8\uC18C",
|
|
@@ -1207,14 +1208,6 @@ function GameWebviewNavigationBar() {
|
|
|
1207
1208
|
closeView3();
|
|
1208
1209
|
}
|
|
1209
1210
|
}, [captureExitLog, global2.brandDisplayName, logging, openConfirm]);
|
|
1210
|
-
useEffect9(() => {
|
|
1211
|
-
const handleAndroidBackEvent = () => {
|
|
1212
|
-
handleGameWebviewClose();
|
|
1213
|
-
return true;
|
|
1214
|
-
};
|
|
1215
|
-
BackHandler2.addEventListener("hardwareBackPress", handleAndroidBackEvent);
|
|
1216
|
-
return () => BackHandler2.removeEventListener("hardwareBackPress", handleAndroidBackEvent);
|
|
1217
|
-
}, [handleGameWebviewClose]);
|
|
1218
1211
|
return /* @__PURE__ */ jsxs4(Fragment6, { children: [
|
|
1219
1212
|
/* @__PURE__ */ jsx9(PageNavbar, { preference: { type: "none" } }),
|
|
1220
1213
|
/* @__PURE__ */ jsx9(
|
|
@@ -1239,7 +1232,6 @@ function GameWebviewNavigationBar() {
|
|
|
1239
1232
|
fixedRightButton: initialAccessoryButton,
|
|
1240
1233
|
onPressDots: openMoreButtonBottomSheet,
|
|
1241
1234
|
onPressClose: () => {
|
|
1242
|
-
logging.closeButtonClick();
|
|
1243
1235
|
handleGameWebviewClose();
|
|
1244
1236
|
},
|
|
1245
1237
|
theme: "dark"
|
|
@@ -1254,7 +1246,7 @@ function GameWebviewNavigationBar() {
|
|
|
1254
1246
|
import { Fragment as Fragment7, jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1255
1247
|
var GameWebView = forwardRef(function GameWebView2(props, ref) {
|
|
1256
1248
|
const [isEntryMessageExited, setIsEntryMessageExited] = useState3(false);
|
|
1257
|
-
|
|
1249
|
+
useEffect9(() => {
|
|
1258
1250
|
if (Platform3.OS === "ios") {
|
|
1259
1251
|
setIosSwipeGestureEnabled2({ isEnabled: false });
|
|
1260
1252
|
return () => {
|
|
@@ -1263,7 +1255,7 @@ var GameWebView = forwardRef(function GameWebView2(props, ref) {
|
|
|
1263
1255
|
}
|
|
1264
1256
|
return;
|
|
1265
1257
|
}, []);
|
|
1266
|
-
|
|
1258
|
+
useEffect9(() => {
|
|
1267
1259
|
appsInTossEvent2.addEventListener("entryMessageExited", {
|
|
1268
1260
|
onEvent: () => {
|
|
1269
1261
|
setIsEntryMessageExited(true);
|
|
@@ -1277,12 +1269,10 @@ var GameWebView = forwardRef(function GameWebView2(props, ref) {
|
|
|
1277
1269
|
});
|
|
1278
1270
|
|
|
1279
1271
|
// src/components/PartnerWebView.tsx
|
|
1280
|
-
import { closeView as closeView5 } from "@apps-in-toss/native-modules";
|
|
1281
1272
|
import {
|
|
1282
1273
|
WebView as PlainWebView2
|
|
1283
1274
|
} from "@granite-js/native/react-native-webview";
|
|
1284
|
-
import { forwardRef as forwardRef2
|
|
1285
|
-
import { BackHandler as BackHandler3 } from "react-native";
|
|
1275
|
+
import { forwardRef as forwardRef2 } from "react";
|
|
1286
1276
|
|
|
1287
1277
|
// src/components/NavigationBar/PartnerWebviewNavigationBar.tsx
|
|
1288
1278
|
import { closeView as closeView4 } from "@granite-js/react-native";
|
|
@@ -1291,7 +1281,7 @@ import { NavigationBackButton as NavigationBackButton2, NavigationLeft as Naviga
|
|
|
1291
1281
|
import { josa as josa4 } from "es-hangul";
|
|
1292
1282
|
import { useCallback as useCallback6 } from "react";
|
|
1293
1283
|
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1294
|
-
function PartnerWebviewNavigationBar({
|
|
1284
|
+
function PartnerWebviewNavigationBar({ onBackButtonClick, onHomeButtonClick }) {
|
|
1295
1285
|
const globals = getAppsInTossGlobals();
|
|
1296
1286
|
const { captureExitLog } = useCaptureExitLog();
|
|
1297
1287
|
const logging = useNavigationBarLogging();
|
|
@@ -1301,10 +1291,6 @@ function PartnerWebviewNavigationBar({ handleBackEvent, handleHomeIconButtonClic
|
|
|
1301
1291
|
const withHomeButton = parsedNavigationBar?.withHomeButton ?? false;
|
|
1302
1292
|
const withBackButton = parsedNavigationBar?.withBackButton ?? true;
|
|
1303
1293
|
const initialAccessoryButton = parsedNavigationBar?.initialAccessoryButton;
|
|
1304
|
-
const handlePressTitle = useCallback6(() => {
|
|
1305
|
-
logging.homeButtonClick();
|
|
1306
|
-
handleHomeIconButtonClick();
|
|
1307
|
-
}, [handleHomeIconButtonClick, logging]);
|
|
1308
1294
|
const handleClose = useCallback6(async () => {
|
|
1309
1295
|
logging.closeButtonClick();
|
|
1310
1296
|
const isConfirmed = await openConfirm({
|
|
@@ -1327,200 +1313,26 @@ function PartnerWebviewNavigationBar({ handleBackEvent, handleHomeIconButtonClic
|
|
|
1327
1313
|
icon: toIcon(globals.brandIcon),
|
|
1328
1314
|
onPressDots: openMoreButtonBottomSheet,
|
|
1329
1315
|
contentVisible: true,
|
|
1330
|
-
onPressTitle: withHomeButton ?
|
|
1316
|
+
onPressTitle: withHomeButton ? onHomeButtonClick : void 0,
|
|
1331
1317
|
onPressClose: handleClose,
|
|
1332
1318
|
withHome: withHomeButton,
|
|
1333
1319
|
fixedRightButton: initialAccessoryButton,
|
|
1334
|
-
children: /* @__PURE__ */ jsx11(NavigationLeft2, { visible: withBackButton, children: /* @__PURE__ */ jsx11(NavigationBackButton2, { onPress:
|
|
1320
|
+
children: /* @__PURE__ */ jsx11(NavigationLeft2, { visible: withBackButton, children: /* @__PURE__ */ jsx11(NavigationBackButton2, { onPress: onBackButtonClick, canGoBack: false }) })
|
|
1335
1321
|
}
|
|
1336
1322
|
) });
|
|
1337
1323
|
}
|
|
1338
1324
|
|
|
1339
|
-
// src/core/utils/mergeRefs.ts
|
|
1340
|
-
function mergeRefs(...refs) {
|
|
1341
|
-
return (value) => {
|
|
1342
|
-
refs.forEach((ref) => {
|
|
1343
|
-
if (typeof ref === "function") {
|
|
1344
|
-
ref(value);
|
|
1345
|
-
} else if (ref != null) {
|
|
1346
|
-
ref.current = value;
|
|
1347
|
-
}
|
|
1348
|
-
});
|
|
1349
|
-
};
|
|
1350
|
-
}
|
|
1351
|
-
|
|
1352
|
-
// src/hooks/useWebviewHistoryStack.tsx
|
|
1353
|
-
import { useCallback as useCallback7, useMemo as useMemo2, useReducer } from "react";
|
|
1354
|
-
var INITIAL_STATE = { stack: [], index: -1 };
|
|
1355
|
-
function reducer(state, action) {
|
|
1356
|
-
switch (action.type) {
|
|
1357
|
-
case "NAVIGATION_CHANGE": {
|
|
1358
|
-
const { url, canGoForward } = action;
|
|
1359
|
-
if (state.stack.length === 0) {
|
|
1360
|
-
return { stack: [url], index: 0 };
|
|
1361
|
-
}
|
|
1362
|
-
const { stack, index } = state;
|
|
1363
|
-
const cur = stack[index];
|
|
1364
|
-
if (url === cur) {
|
|
1365
|
-
return state;
|
|
1366
|
-
}
|
|
1367
|
-
const prev = index > 0 ? stack[index - 1] : void 0;
|
|
1368
|
-
const next = index < stack.length - 1 ? stack[index + 1] : void 0;
|
|
1369
|
-
if (prev && url === prev && canGoForward) {
|
|
1370
|
-
return { ...state, index: index - 1 };
|
|
1371
|
-
}
|
|
1372
|
-
if (next && url === next) {
|
|
1373
|
-
return { ...state, index: index + 1 };
|
|
1374
|
-
}
|
|
1375
|
-
const base = stack.slice(0, index + 1);
|
|
1376
|
-
const nextStack = [...base, url];
|
|
1377
|
-
return { stack: nextStack, index: nextStack.length - 1 };
|
|
1378
|
-
}
|
|
1379
|
-
default:
|
|
1380
|
-
return state;
|
|
1381
|
-
}
|
|
1382
|
-
}
|
|
1383
|
-
function useWebViewHistory() {
|
|
1384
|
-
const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
|
|
1385
|
-
const onNavigationStateChange = useCallback7(({ url, canGoForward: canGoForward2 }) => {
|
|
1386
|
-
dispatch({ type: "NAVIGATION_CHANGE", url, canGoForward: canGoForward2 });
|
|
1387
|
-
}, []);
|
|
1388
|
-
const { canGoBack, canGoForward } = useMemo2(() => {
|
|
1389
|
-
const canBack = state.index > 0;
|
|
1390
|
-
const canFwd = state.index >= 0 && state.index < state.stack.length - 1;
|
|
1391
|
-
return { canGoBack: canBack, canGoForward: canFwd };
|
|
1392
|
-
}, [state.index, state.stack.length]);
|
|
1393
|
-
return { onNavigationStateChange, canGoBack, canGoForward };
|
|
1394
|
-
}
|
|
1395
|
-
|
|
1396
|
-
// src/utils/log.ts
|
|
1397
|
-
import { eventLog as eventLogNative } from "@apps-in-toss/native-modules";
|
|
1398
|
-
import { getSchemeUri as getSchemeUri5 } from "@granite-js/react-native";
|
|
1399
|
-
|
|
1400
|
-
// src/utils/extractDateFromUUIDv7.ts
|
|
1401
|
-
var extractDateFromUUIDv7 = (uuid) => {
|
|
1402
|
-
const timestampHex = uuid.split("-").join("").slice(0, 12);
|
|
1403
|
-
const timestamp = Number.parseInt(timestampHex, 16);
|
|
1404
|
-
return new Date(timestamp);
|
|
1405
|
-
};
|
|
1406
|
-
|
|
1407
|
-
// src/utils/log.ts
|
|
1408
|
-
var getGroupId = (url) => {
|
|
1409
|
-
try {
|
|
1410
|
-
const urlObject = new URL(url);
|
|
1411
|
-
return {
|
|
1412
|
-
groupId: urlObject.pathname,
|
|
1413
|
-
search: urlObject.search.startsWith("?") ? urlObject.search.substring(1) : urlObject.search
|
|
1414
|
-
};
|
|
1415
|
-
} catch {
|
|
1416
|
-
return {
|
|
1417
|
-
groupId: "unknown",
|
|
1418
|
-
search: "unknown"
|
|
1419
|
-
};
|
|
1420
|
-
}
|
|
1421
|
-
};
|
|
1422
|
-
var getReferrer = () => {
|
|
1423
|
-
try {
|
|
1424
|
-
const referrer = new URL(getSchemeUri5());
|
|
1425
|
-
return referrer.searchParams.get("referrer");
|
|
1426
|
-
} catch {
|
|
1427
|
-
return "";
|
|
1428
|
-
}
|
|
1429
|
-
};
|
|
1430
|
-
var trackScreen = (url) => {
|
|
1431
|
-
const { groupId, search } = getGroupId(url);
|
|
1432
|
-
const log = {
|
|
1433
|
-
log_type: "screen",
|
|
1434
|
-
log_name: `${groupId}::screen`,
|
|
1435
|
-
params: {
|
|
1436
|
-
search,
|
|
1437
|
-
referrer: getReferrer(),
|
|
1438
|
-
deployment_id: env.getDeploymentId(),
|
|
1439
|
-
deployment_timestamp: extractDateFromUUIDv7(env.getDeploymentId()).getTime()
|
|
1440
|
-
}
|
|
1441
|
-
};
|
|
1442
|
-
return eventLogNative(log);
|
|
1443
|
-
};
|
|
1444
|
-
|
|
1445
1325
|
// src/components/PartnerWebView.tsx
|
|
1446
1326
|
import { Fragment as Fragment8, jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1447
|
-
var PartnerWebView = forwardRef2(
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
const historyBackScript = `
|
|
1454
|
-
(function() {
|
|
1455
|
-
window.history.back();
|
|
1456
|
-
true;
|
|
1457
|
-
})();
|
|
1458
|
-
`;
|
|
1459
|
-
const historyHomeScript = `
|
|
1460
|
-
(function() {
|
|
1461
|
-
window.location.href = '/';
|
|
1462
|
-
true;
|
|
1463
|
-
})();
|
|
1464
|
-
`;
|
|
1465
|
-
const handleBackEvent = useCallback8(() => {
|
|
1466
|
-
if (canGoBack) {
|
|
1467
|
-
webViewRef.current?.injectJavaScript(historyBackScript);
|
|
1468
|
-
} else {
|
|
1469
|
-
captureExitLog(Date.now());
|
|
1470
|
-
closeView5();
|
|
1471
|
-
}
|
|
1472
|
-
}, [canGoBack, captureExitLog, historyBackScript]);
|
|
1473
|
-
useEffect11(() => {
|
|
1474
|
-
const handleAndroidBackEvent = () => {
|
|
1475
|
-
if (canGoBack) {
|
|
1476
|
-
webViewRef.current?.injectJavaScript(historyBackScript);
|
|
1477
|
-
return true;
|
|
1478
|
-
} else {
|
|
1479
|
-
captureExitLog(Date.now());
|
|
1480
|
-
return false;
|
|
1481
|
-
}
|
|
1482
|
-
};
|
|
1483
|
-
BackHandler3.addEventListener("hardwareBackPress", handleAndroidBackEvent);
|
|
1484
|
-
return () => BackHandler3.removeEventListener("hardwareBackPress", handleAndroidBackEvent);
|
|
1485
|
-
}, [canGoBack, captureExitLog, historyBackScript]);
|
|
1486
|
-
const handleHomeIconButtonClick = useCallback8(() => {
|
|
1487
|
-
webViewRef.current?.injectJavaScript(historyHomeScript);
|
|
1488
|
-
}, [historyHomeScript]);
|
|
1489
|
-
const handleNavigationStateChange = useCallback8(
|
|
1490
|
-
(event) => {
|
|
1491
|
-
if (event.url) {
|
|
1492
|
-
trackScreen(event.url);
|
|
1493
|
-
}
|
|
1494
|
-
onNavigationStateChange(event);
|
|
1495
|
-
},
|
|
1496
|
-
[onNavigationStateChange]
|
|
1497
|
-
);
|
|
1498
|
-
return /* @__PURE__ */ jsxs6(Fragment8, { children: [
|
|
1499
|
-
/* @__PURE__ */ jsx12(
|
|
1500
|
-
PartnerWebviewNavigationBar,
|
|
1501
|
-
{
|
|
1502
|
-
handleBackEvent,
|
|
1503
|
-
handleHomeIconButtonClick
|
|
1504
|
-
}
|
|
1505
|
-
),
|
|
1506
|
-
/* @__PURE__ */ jsx12(
|
|
1507
|
-
PlainWebView2,
|
|
1508
|
-
{
|
|
1509
|
-
ref: refs,
|
|
1510
|
-
...webViewProps,
|
|
1511
|
-
style: { flex: 1 },
|
|
1512
|
-
onNavigationStateChange: (event) => {
|
|
1513
|
-
webViewProps?.onNavigationStateChange?.(event);
|
|
1514
|
-
handleNavigationStateChange(event);
|
|
1515
|
-
}
|
|
1516
|
-
}
|
|
1517
|
-
)
|
|
1518
|
-
] });
|
|
1519
|
-
}
|
|
1520
|
-
);
|
|
1327
|
+
var PartnerWebView = forwardRef2(function PartnerWebViewScreen({ onBackButtonClick, onHomeButtonClick, ...webViewProps }, ref) {
|
|
1328
|
+
return /* @__PURE__ */ jsxs6(Fragment8, { children: [
|
|
1329
|
+
/* @__PURE__ */ jsx12(PartnerWebviewNavigationBar, { onBackButtonClick, onHomeButtonClick }),
|
|
1330
|
+
/* @__PURE__ */ jsx12(PlainWebView2, { ref, ...webViewProps, style: { flex: 1 } })
|
|
1331
|
+
] });
|
|
1332
|
+
});
|
|
1521
1333
|
|
|
1522
1334
|
// src/bridge-handler/useBridgeHandler.tsx
|
|
1523
|
-
import { useCallback as
|
|
1335
|
+
import { useCallback as useCallback7, useMemo as useMemo2, useRef as useRef4 } from "react";
|
|
1524
1336
|
function serializeError(error) {
|
|
1525
1337
|
return JSON.stringify(error, (_, value) => {
|
|
1526
1338
|
if (value instanceof Error) {
|
|
@@ -1573,8 +1385,8 @@ function useBridgeHandler({
|
|
|
1573
1385
|
eventListenerMap,
|
|
1574
1386
|
injectedJavaScript: originalInjectedJavaScript
|
|
1575
1387
|
}) {
|
|
1576
|
-
const ref =
|
|
1577
|
-
const injectedJavaScript =
|
|
1388
|
+
const ref = useRef4(null);
|
|
1389
|
+
const injectedJavaScript = useMemo2(
|
|
1578
1390
|
() => [
|
|
1579
1391
|
`window.__CONSTANT_HANDLER_MAP = ${JSON.stringify(
|
|
1580
1392
|
Object.entries(constantHandlerMap).reduce(
|
|
@@ -1601,7 +1413,7 @@ function useBridgeHandler({
|
|
|
1601
1413
|
window.__GRANITE_NATIVE_EMITTER.emit('${functionName}/onError/${eventId}', ${serializedError});
|
|
1602
1414
|
`);
|
|
1603
1415
|
};
|
|
1604
|
-
const $onMessage =
|
|
1416
|
+
const $onMessage = useCallback7(
|
|
1605
1417
|
async (e) => {
|
|
1606
1418
|
onMessage?.(e);
|
|
1607
1419
|
const data = JSON.parse(e.nativeEvent.data);
|
|
@@ -1651,6 +1463,155 @@ function useBridgeHandler({
|
|
|
1651
1463
|
};
|
|
1652
1464
|
}
|
|
1653
1465
|
|
|
1466
|
+
// src/core/hooks/useWebBackHandler.tsx
|
|
1467
|
+
import { closeView as closeView5, useBackEventState } from "@granite-js/react-native";
|
|
1468
|
+
import { useDialog as useDialog7 } from "@toss/tds-react-native";
|
|
1469
|
+
import { josa as josa5 } from "es-hangul";
|
|
1470
|
+
import { useCallback as useCallback9, useMemo as useMemo4 } from "react";
|
|
1471
|
+
|
|
1472
|
+
// src/hooks/useWebviewHistoryStack.tsx
|
|
1473
|
+
import { useCallback as useCallback8, useMemo as useMemo3, useReducer } from "react";
|
|
1474
|
+
var INITIAL_STATE = { stack: [], index: -1 };
|
|
1475
|
+
function reducer(state, action) {
|
|
1476
|
+
switch (action.type) {
|
|
1477
|
+
case "NAVIGATION_CHANGE": {
|
|
1478
|
+
const { url, canGoForward } = action;
|
|
1479
|
+
if (state.stack.length === 0) {
|
|
1480
|
+
return { stack: [url], index: 0 };
|
|
1481
|
+
}
|
|
1482
|
+
const { stack, index } = state;
|
|
1483
|
+
const cur = stack[index];
|
|
1484
|
+
if (url === cur) {
|
|
1485
|
+
return state;
|
|
1486
|
+
}
|
|
1487
|
+
const prev = index > 0 ? stack[index - 1] : void 0;
|
|
1488
|
+
const next = index < stack.length - 1 ? stack[index + 1] : void 0;
|
|
1489
|
+
if (prev && url === prev && canGoForward) {
|
|
1490
|
+
return { ...state, index: index - 1 };
|
|
1491
|
+
}
|
|
1492
|
+
if (next && url === next) {
|
|
1493
|
+
return { ...state, index: index + 1 };
|
|
1494
|
+
}
|
|
1495
|
+
const base = stack.slice(0, index + 1);
|
|
1496
|
+
const nextStack = [...base, url];
|
|
1497
|
+
return { stack: nextStack, index: nextStack.length - 1 };
|
|
1498
|
+
}
|
|
1499
|
+
default:
|
|
1500
|
+
return state;
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
function useWebViewHistory() {
|
|
1504
|
+
const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
|
|
1505
|
+
const onNavigationStateChange = useCallback8(({ url, canGoForward: canGoForward2 }) => {
|
|
1506
|
+
dispatch({ type: "NAVIGATION_CHANGE", url, canGoForward: canGoForward2 });
|
|
1507
|
+
}, []);
|
|
1508
|
+
const { canGoBack, canGoForward } = useMemo3(() => {
|
|
1509
|
+
const canBack = state.index > 0;
|
|
1510
|
+
const canFwd = state.index >= 0 && state.index < state.stack.length - 1;
|
|
1511
|
+
return { canGoBack: canBack, canGoForward: canFwd };
|
|
1512
|
+
}, [state.index, state.stack.length]);
|
|
1513
|
+
return { onNavigationStateChange, hasHistory: canGoBack, canGoForward };
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
// src/core/hooks/useWebBackHandler.tsx
|
|
1517
|
+
var HISTORY_BACK_SCRIPT = `
|
|
1518
|
+
(function() {
|
|
1519
|
+
window.history.back();
|
|
1520
|
+
true;
|
|
1521
|
+
})();
|
|
1522
|
+
`;
|
|
1523
|
+
var HISTORY_HOME_SCRIPT = `
|
|
1524
|
+
(function() {
|
|
1525
|
+
window.location.href = '/';
|
|
1526
|
+
true;
|
|
1527
|
+
})();
|
|
1528
|
+
`;
|
|
1529
|
+
function useWebBackHandler(webViewRef) {
|
|
1530
|
+
const { captureExitLog } = useCaptureExitLog();
|
|
1531
|
+
const { hasHistory, onNavigationStateChange } = useWebViewHistory();
|
|
1532
|
+
const {
|
|
1533
|
+
handlersRef: webBackHandlersRef,
|
|
1534
|
+
hasBackEvent: hasWebBackEvent,
|
|
1535
|
+
addEventListener: addWebBackEventListener,
|
|
1536
|
+
removeEventListener: removeWebBackEventListener
|
|
1537
|
+
} = useBackEventState();
|
|
1538
|
+
const logging = useNavigationBarLogging();
|
|
1539
|
+
const { openConfirm } = useDialog7();
|
|
1540
|
+
const global2 = getAppsInTossGlobals();
|
|
1541
|
+
const addEventListener = useCallback9(
|
|
1542
|
+
(handler) => {
|
|
1543
|
+
addWebBackEventListener(handler);
|
|
1544
|
+
},
|
|
1545
|
+
[addWebBackEventListener]
|
|
1546
|
+
);
|
|
1547
|
+
const removeEventListener = useCallback9(
|
|
1548
|
+
(handler) => {
|
|
1549
|
+
removeWebBackEventListener(handler);
|
|
1550
|
+
},
|
|
1551
|
+
[removeWebBackEventListener]
|
|
1552
|
+
);
|
|
1553
|
+
const handleWebBack = useCallback9(async () => {
|
|
1554
|
+
if (hasWebBackEvent) {
|
|
1555
|
+
for (const handler of webBackHandlersRef) {
|
|
1556
|
+
handler();
|
|
1557
|
+
}
|
|
1558
|
+
return;
|
|
1559
|
+
}
|
|
1560
|
+
if (hasHistory) {
|
|
1561
|
+
webViewRef.current?.injectJavaScript(HISTORY_BACK_SCRIPT);
|
|
1562
|
+
} else {
|
|
1563
|
+
const isConfirmed = await openConfirm({
|
|
1564
|
+
title: `${josa5(global2.brandDisplayName, "\uC744/\uB97C")} \uC885\uB8CC\uD560\uAE4C\uC694?`,
|
|
1565
|
+
leftButton: "\uCDE8\uC18C",
|
|
1566
|
+
rightButton: "\uC885\uB8CC\uD558\uAE30",
|
|
1567
|
+
closeOnDimmerClick: true,
|
|
1568
|
+
onEntered: logging.closePopupShow
|
|
1569
|
+
});
|
|
1570
|
+
logging.closePopupCtaClick(isConfirmed);
|
|
1571
|
+
if (isConfirmed) {
|
|
1572
|
+
captureExitLog(Date.now());
|
|
1573
|
+
closeView5();
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
}, [
|
|
1577
|
+
captureExitLog,
|
|
1578
|
+
global2.brandDisplayName,
|
|
1579
|
+
hasHistory,
|
|
1580
|
+
hasWebBackEvent,
|
|
1581
|
+
webBackHandlersRef,
|
|
1582
|
+
logging,
|
|
1583
|
+
openConfirm,
|
|
1584
|
+
webViewRef
|
|
1585
|
+
]);
|
|
1586
|
+
const handleWebHome = useCallback9(() => {
|
|
1587
|
+
logging.homeButtonClick();
|
|
1588
|
+
if (hasWebBackEvent) {
|
|
1589
|
+
for (const handler of webBackHandlersRef) {
|
|
1590
|
+
handler();
|
|
1591
|
+
}
|
|
1592
|
+
return;
|
|
1593
|
+
}
|
|
1594
|
+
webViewRef.current?.injectJavaScript(HISTORY_HOME_SCRIPT);
|
|
1595
|
+
}, [hasWebBackEvent, webBackHandlersRef, logging, webViewRef]);
|
|
1596
|
+
return useMemo4(
|
|
1597
|
+
() => ({ addEventListener, removeEventListener, handleWebBack, handleWebHome, onNavigationStateChange }),
|
|
1598
|
+
[addEventListener, removeEventListener, handleWebBack, handleWebHome, onNavigationStateChange]
|
|
1599
|
+
);
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
// src/core/utils/mergeRefs.ts
|
|
1603
|
+
function mergeRefs(...refs) {
|
|
1604
|
+
return (value) => {
|
|
1605
|
+
refs.forEach((ref) => {
|
|
1606
|
+
if (typeof ref === "function") {
|
|
1607
|
+
ref(value);
|
|
1608
|
+
} else if (ref != null) {
|
|
1609
|
+
ref.current = value;
|
|
1610
|
+
}
|
|
1611
|
+
});
|
|
1612
|
+
};
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1654
1615
|
// src/hooks/useCreateUserAgent.ts
|
|
1655
1616
|
import { getPlatformOS, getTossAppVersion } from "@apps-in-toss/native-modules";
|
|
1656
1617
|
import { useWindowDimensions } from "react-native";
|
|
@@ -1810,11 +1771,11 @@ function useCreateUserAgent({
|
|
|
1810
1771
|
// src/hooks/useGeolocation.ts
|
|
1811
1772
|
import { startUpdateLocation } from "@apps-in-toss/native-modules";
|
|
1812
1773
|
import { useVisibility as useVisibility3 } from "@granite-js/react-native";
|
|
1813
|
-
import { useEffect as
|
|
1774
|
+
import { useEffect as useEffect10, useState as useState4 } from "react";
|
|
1814
1775
|
function useGeolocation({ accuracy, distanceInterval, timeInterval }) {
|
|
1815
1776
|
const isVisible = useVisibility3();
|
|
1816
1777
|
const [location, setLocation] = useState4(null);
|
|
1817
|
-
|
|
1778
|
+
useEffect10(() => {
|
|
1818
1779
|
if (!isVisible) {
|
|
1819
1780
|
return;
|
|
1820
1781
|
}
|
|
@@ -1831,6 +1792,85 @@ function useGeolocation({ accuracy, distanceInterval, timeInterval }) {
|
|
|
1831
1792
|
return location;
|
|
1832
1793
|
}
|
|
1833
1794
|
|
|
1795
|
+
// src/hooks/useWaitForReturnNavigator.tsx
|
|
1796
|
+
import { useNavigation as useNavigation2, useVisibilityChange } from "@granite-js/react-native";
|
|
1797
|
+
import { useCallback as useCallback10, useRef as useRef5 } from "react";
|
|
1798
|
+
function useWaitForReturnNavigator() {
|
|
1799
|
+
const callbacks = useRef5([]).current;
|
|
1800
|
+
const navigation = useNavigation2();
|
|
1801
|
+
const startNavigating = useCallback10(
|
|
1802
|
+
(route, params) => {
|
|
1803
|
+
return new Promise((resolve) => {
|
|
1804
|
+
callbacks.push(resolve);
|
|
1805
|
+
navigation.navigate(route, params);
|
|
1806
|
+
});
|
|
1807
|
+
},
|
|
1808
|
+
[callbacks, navigation]
|
|
1809
|
+
);
|
|
1810
|
+
const handleVisibilityChange = useCallback10(
|
|
1811
|
+
(state) => {
|
|
1812
|
+
if (state === "visible" && callbacks.length > 0) {
|
|
1813
|
+
for (const callback of callbacks) {
|
|
1814
|
+
callback();
|
|
1815
|
+
}
|
|
1816
|
+
callbacks.splice(0, callbacks.length);
|
|
1817
|
+
}
|
|
1818
|
+
},
|
|
1819
|
+
[callbacks]
|
|
1820
|
+
);
|
|
1821
|
+
useVisibilityChange(handleVisibilityChange);
|
|
1822
|
+
return startNavigating;
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
// src/utils/log.ts
|
|
1826
|
+
import { eventLog as eventLogNative } from "@apps-in-toss/native-modules";
|
|
1827
|
+
import { getSchemeUri as getSchemeUri5 } from "@granite-js/react-native";
|
|
1828
|
+
|
|
1829
|
+
// src/utils/extractDateFromUUIDv7.ts
|
|
1830
|
+
var extractDateFromUUIDv7 = (uuid) => {
|
|
1831
|
+
const timestampHex = uuid.split("-").join("").slice(0, 12);
|
|
1832
|
+
const timestamp = Number.parseInt(timestampHex, 16);
|
|
1833
|
+
return new Date(timestamp);
|
|
1834
|
+
};
|
|
1835
|
+
|
|
1836
|
+
// src/utils/log.ts
|
|
1837
|
+
var getGroupId = (url) => {
|
|
1838
|
+
try {
|
|
1839
|
+
const urlObject = new URL(url);
|
|
1840
|
+
return {
|
|
1841
|
+
groupId: urlObject.pathname,
|
|
1842
|
+
search: urlObject.search.startsWith("?") ? urlObject.search.substring(1) : urlObject.search
|
|
1843
|
+
};
|
|
1844
|
+
} catch {
|
|
1845
|
+
return {
|
|
1846
|
+
groupId: "unknown",
|
|
1847
|
+
search: "unknown"
|
|
1848
|
+
};
|
|
1849
|
+
}
|
|
1850
|
+
};
|
|
1851
|
+
var getReferrer = () => {
|
|
1852
|
+
try {
|
|
1853
|
+
const referrer = new URL(getSchemeUri5());
|
|
1854
|
+
return referrer.searchParams.get("referrer");
|
|
1855
|
+
} catch {
|
|
1856
|
+
return "";
|
|
1857
|
+
}
|
|
1858
|
+
};
|
|
1859
|
+
var trackScreen = (url) => {
|
|
1860
|
+
const { groupId, search } = getGroupId(url);
|
|
1861
|
+
const log = {
|
|
1862
|
+
log_type: "screen",
|
|
1863
|
+
log_name: `${groupId}::screen`,
|
|
1864
|
+
params: {
|
|
1865
|
+
search,
|
|
1866
|
+
referrer: getReferrer(),
|
|
1867
|
+
deployment_id: env.getDeploymentId(),
|
|
1868
|
+
deployment_timestamp: extractDateFromUUIDv7(env.getDeploymentId()).getTime()
|
|
1869
|
+
}
|
|
1870
|
+
};
|
|
1871
|
+
return eventLogNative(log);
|
|
1872
|
+
};
|
|
1873
|
+
|
|
1834
1874
|
// src/components/WebView.tsx
|
|
1835
1875
|
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1836
1876
|
var operationalEnvironment = appsInTossConstantBridges.getOperationalEnvironment();
|
|
@@ -1866,8 +1906,9 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
1866
1906
|
if (!TYPES.includes(type)) {
|
|
1867
1907
|
throw new Error(`Invalid WebView type: '${type}'`);
|
|
1868
1908
|
}
|
|
1869
|
-
const
|
|
1870
|
-
const
|
|
1909
|
+
const webViewRef = useRef6(null);
|
|
1910
|
+
const webBackHandler = useWebBackHandler(webViewRef);
|
|
1911
|
+
const uri = useMemo5(() => getWebViewUri(local), [local]);
|
|
1871
1912
|
const top = useSafeAreaTop2();
|
|
1872
1913
|
const bottom = useSafeAreaBottom();
|
|
1873
1914
|
const global2 = getAppsInTossGlobals();
|
|
@@ -1889,7 +1930,12 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
1889
1930
|
eventListenerMap: {
|
|
1890
1931
|
...appsInTossEventBridges,
|
|
1891
1932
|
navigationAccessoryEvent: ({ onEvent, onError }) => tdsEvent.addEventListener("navigationAccessoryEvent", { onEvent, onError }),
|
|
1892
|
-
backEvent: ({ onEvent
|
|
1933
|
+
backEvent: ({ onEvent }) => {
|
|
1934
|
+
webBackHandler.addEventListener(onEvent);
|
|
1935
|
+
return () => {
|
|
1936
|
+
webBackHandler.removeEventListener(onEvent);
|
|
1937
|
+
};
|
|
1938
|
+
},
|
|
1893
1939
|
entryMessageExited: ({ onEvent, onError }) => appsInTossEvent3.addEventListener("entryMessageExited", { onEvent, onError }),
|
|
1894
1940
|
updateLocationEvent: ({ onEvent, onError, options }) => appsInTossEvent3.addEventListener("updateLocationEvent", { onEvent, onError, options }),
|
|
1895
1941
|
/** @internal */
|
|
@@ -1950,10 +1996,11 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
1950
1996
|
iapCreateOneTimePurchaseOrder,
|
|
1951
1997
|
processProductGrant,
|
|
1952
1998
|
getPendingOrders: IAP.getPendingOrders,
|
|
1953
|
-
getCompletedOrRefundedOrders: IAP.getCompletedOrRefundedOrders
|
|
1999
|
+
getCompletedOrRefundedOrders: IAP.getCompletedOrRefundedOrders,
|
|
2000
|
+
completeProductGrant: IAP.completeProductGrant
|
|
1954
2001
|
}
|
|
1955
2002
|
});
|
|
1956
|
-
const headerPropForExternalWebView =
|
|
2003
|
+
const headerPropForExternalWebView = useMemo5(() => {
|
|
1957
2004
|
const parsedNavigationBar = global2.navigationBar != null ? safeParseNavigationBar(global2.navigationBar) : null;
|
|
1958
2005
|
const initialAccessoryButton = parsedNavigationBar?.initialAccessoryButton;
|
|
1959
2006
|
const withBackButton = parsedNavigationBar?.withBackButton ?? true;
|
|
@@ -1973,10 +2020,19 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
1973
2020
|
const userAgent = useCreateUserAgent({
|
|
1974
2021
|
colorPreference: "light"
|
|
1975
2022
|
});
|
|
2023
|
+
const refs = mergeRefs(handler.ref, webViewRef);
|
|
2024
|
+
useEffect11(() => {
|
|
2025
|
+
const callback = () => {
|
|
2026
|
+
webBackHandler.handleWebBack();
|
|
2027
|
+
return true;
|
|
2028
|
+
};
|
|
2029
|
+
BackHandler2.addEventListener("hardwareBackPress", callback);
|
|
2030
|
+
return () => BackHandler2.removeEventListener("hardwareBackPress", callback);
|
|
2031
|
+
}, [webBackHandler]);
|
|
1976
2032
|
return /* @__PURE__ */ jsx13(
|
|
1977
2033
|
BaseWebView,
|
|
1978
2034
|
{
|
|
1979
|
-
ref:
|
|
2035
|
+
ref: refs,
|
|
1980
2036
|
...props,
|
|
1981
2037
|
...headerPropForExternalWebView,
|
|
1982
2038
|
source: {
|
|
@@ -1986,6 +2042,15 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
1986
2042
|
"User-Agent": userAgent
|
|
1987
2043
|
}
|
|
1988
2044
|
},
|
|
2045
|
+
onHomeButtonClick: webBackHandler.handleWebHome,
|
|
2046
|
+
onBackButtonClick: webBackHandler.handleWebBack,
|
|
2047
|
+
onNavigationStateChange: (event) => {
|
|
2048
|
+
if (event.url) {
|
|
2049
|
+
trackScreen(event.url);
|
|
2050
|
+
}
|
|
2051
|
+
props.onNavigationStateChange?.(event);
|
|
2052
|
+
webBackHandler.onNavigationStateChange(event);
|
|
2053
|
+
},
|
|
1989
2054
|
userAgent: Platform4.OS === "ios" ? userAgent : void 0,
|
|
1990
2055
|
sharedCookiesEnabled: true,
|
|
1991
2056
|
webviewDebuggingEnabled: webViewDebuggingEnabled,
|
|
@@ -2001,7 +2066,7 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
2001
2066
|
|
|
2002
2067
|
// src/index.ts
|
|
2003
2068
|
export * from "@apps-in-toss/analytics";
|
|
2004
|
-
import { useTopNavigation as useTopNavigation2 } from "@toss/tds-react-native/private";
|
|
2069
|
+
import { useTopNavigation as useTopNavigation2, useOverlay as useOverlay3, OverlayProvider } from "@toss/tds-react-native/private";
|
|
2005
2070
|
export * from "@apps-in-toss/native-modules";
|
|
2006
2071
|
export * from "@apps-in-toss/types";
|
|
2007
2072
|
var Analytics2 = {
|
|
@@ -2014,9 +2079,12 @@ export {
|
|
|
2014
2079
|
Analytics2 as Analytics,
|
|
2015
2080
|
AppsInToss,
|
|
2016
2081
|
INTERNAL__onVisibilityChangedByTransparentServiceWeb,
|
|
2082
|
+
OverlayProvider,
|
|
2017
2083
|
WebView,
|
|
2018
2084
|
env,
|
|
2019
2085
|
useCreateUserAgent,
|
|
2020
2086
|
useGeolocation,
|
|
2021
|
-
|
|
2087
|
+
useOverlay3 as useOverlay,
|
|
2088
|
+
useTopNavigation2 as useTopNavigation,
|
|
2089
|
+
useWaitForReturnNavigator
|
|
2022
2090
|
};
|