@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 CHANGED
@@ -34,11 +34,14 @@ __export(src_exports, {
34
34
  Analytics: () => Analytics2,
35
35
  AppsInToss: () => AppsInToss,
36
36
  INTERNAL__onVisibilityChangedByTransparentServiceWeb: () => INTERNAL__onVisibilityChangedByTransparentServiceWeb,
37
+ OverlayProvider: () => import_private9.OverlayProvider,
37
38
  WebView: () => WebView,
38
39
  env: () => env,
39
40
  useCreateUserAgent: () => useCreateUserAgent,
40
41
  useGeolocation: () => useGeolocation,
41
- useTopNavigation: () => import_private9.useTopNavigation
42
+ useOverlay: () => import_private9.useOverlay,
43
+ useTopNavigation: () => import_private9.useTopNavigation,
44
+ useWaitForReturnNavigator: () => useWaitForReturnNavigator
42
45
  });
43
46
  module.exports = __toCommonJS(src_exports);
44
47
  var import_analytics2 = require("@apps-in-toss/analytics");
@@ -877,15 +880,15 @@ var AppsInToss = {
877
880
  };
878
881
 
879
882
  // src/components/WebView.tsx
880
- var import_native_modules18 = require("@apps-in-toss/native-modules");
883
+ var import_native_modules17 = require("@apps-in-toss/native-modules");
881
884
  var appsInTossAsyncBridges = __toESM(require("@apps-in-toss/native-modules/async-bridges"), 1);
882
885
  var appsInTossConstantBridges = __toESM(require("@apps-in-toss/native-modules/constant-bridges"), 1);
883
886
  var appsInTossEventBridges = __toESM(require("@apps-in-toss/native-modules/event-bridges"), 1);
884
- var import_react_native28 = require("@granite-js/react-native");
885
- var import_tds_react_native12 = require("@toss/tds-react-native");
887
+ var import_react_native29 = require("@granite-js/react-native");
888
+ var import_tds_react_native13 = require("@toss/tds-react-native");
886
889
  var import_private8 = require("@toss/tds-react-native/private");
887
- var import_react19 = require("react");
888
- var import_react_native29 = require("react-native");
890
+ var import_react21 = require("react");
891
+ var import_react_native30 = require("react-native");
889
892
 
890
893
  // src/components/GameWebView.tsx
891
894
  var import_native_modules13 = require("@apps-in-toss/native-modules");
@@ -1225,6 +1228,7 @@ function GameWebviewNavigationBar() {
1225
1228
  const parsedNavigationBar = global2.navigationBar != null ? safeParseNavigationBar(global2.navigationBar) : null;
1226
1229
  const initialAccessoryButton = parsedNavigationBar?.initialAccessoryButton;
1227
1230
  const handleGameWebviewClose = (0, import_react12.useCallback)(async () => {
1231
+ logging.closeButtonClick();
1228
1232
  const isConfirmed = await openConfirm({
1229
1233
  title: `${(0, import_es_hangul3.josa)(global2.brandDisplayName, "\uC744/\uB97C")} \uC885\uB8CC\uD560\uAE4C\uC694?`,
1230
1234
  leftButton: "\uCDE8\uC18C",
@@ -1238,14 +1242,6 @@ function GameWebviewNavigationBar() {
1238
1242
  (0, import_react_native20.closeView)();
1239
1243
  }
1240
1244
  }, [captureExitLog, global2.brandDisplayName, logging, openConfirm]);
1241
- (0, import_react12.useEffect)(() => {
1242
- const handleAndroidBackEvent = () => {
1243
- handleGameWebviewClose();
1244
- return true;
1245
- };
1246
- import_react_native21.BackHandler.addEventListener("hardwareBackPress", handleAndroidBackEvent);
1247
- return () => import_react_native21.BackHandler.removeEventListener("hardwareBackPress", handleAndroidBackEvent);
1248
- }, [handleGameWebviewClose]);
1249
1245
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1250
1246
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_tds_react_native10.PageNavbar, { preference: { type: "none" } }),
1251
1247
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
@@ -1270,7 +1266,6 @@ function GameWebviewNavigationBar() {
1270
1266
  fixedRightButton: initialAccessoryButton,
1271
1267
  onPressDots: openMoreButtonBottomSheet,
1272
1268
  onPressClose: () => {
1273
- logging.closeButtonClick();
1274
1269
  handleGameWebviewClose();
1275
1270
  },
1276
1271
  theme: "dark"
@@ -1308,10 +1303,8 @@ var GameWebView = (0, import_react13.forwardRef)(function GameWebView2(props, re
1308
1303
  });
1309
1304
 
1310
1305
  // src/components/PartnerWebView.tsx
1311
- var import_native_modules15 = require("@apps-in-toss/native-modules");
1312
1306
  var import_react_native_webview2 = require("@granite-js/native/react-native-webview");
1313
- var import_react16 = require("react");
1314
- var import_react_native25 = require("react-native");
1307
+ var import_react15 = require("react");
1315
1308
 
1316
1309
  // src/components/NavigationBar/PartnerWebviewNavigationBar.tsx
1317
1310
  var import_react_native23 = require("@granite-js/react-native");
@@ -1320,7 +1313,7 @@ var import_private7 = require("@toss/tds-react-native/private");
1320
1313
  var import_es_hangul4 = require("es-hangul");
1321
1314
  var import_react14 = require("react");
1322
1315
  var import_jsx_runtime11 = require("react/jsx-runtime");
1323
- function PartnerWebviewNavigationBar({ handleBackEvent, handleHomeIconButtonClick }) {
1316
+ function PartnerWebviewNavigationBar({ onBackButtonClick, onHomeButtonClick }) {
1324
1317
  const globals = getAppsInTossGlobals();
1325
1318
  const { captureExitLog } = useCaptureExitLog();
1326
1319
  const logging = useNavigationBarLogging();
@@ -1330,10 +1323,6 @@ function PartnerWebviewNavigationBar({ handleBackEvent, handleHomeIconButtonClic
1330
1323
  const withHomeButton = parsedNavigationBar?.withHomeButton ?? false;
1331
1324
  const withBackButton = parsedNavigationBar?.withBackButton ?? true;
1332
1325
  const initialAccessoryButton = parsedNavigationBar?.initialAccessoryButton;
1333
- const handlePressTitle = (0, import_react14.useCallback)(() => {
1334
- logging.homeButtonClick();
1335
- handleHomeIconButtonClick();
1336
- }, [handleHomeIconButtonClick, logging]);
1337
1326
  const handleClose = (0, import_react14.useCallback)(async () => {
1338
1327
  logging.closeButtonClick();
1339
1328
  const isConfirmed = await openConfirm({
@@ -1356,200 +1345,26 @@ function PartnerWebviewNavigationBar({ handleBackEvent, handleHomeIconButtonClic
1356
1345
  icon: toIcon(globals.brandIcon),
1357
1346
  onPressDots: openMoreButtonBottomSheet,
1358
1347
  contentVisible: true,
1359
- onPressTitle: withHomeButton ? handlePressTitle : void 0,
1348
+ onPressTitle: withHomeButton ? onHomeButtonClick : void 0,
1360
1349
  onPressClose: handleClose,
1361
1350
  withHome: withHomeButton,
1362
1351
  fixedRightButton: initialAccessoryButton,
1363
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_private7.NavigationLeft, { visible: withBackButton, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_private7.NavigationBackButton, { onPress: handleBackEvent, canGoBack: false }) })
1352
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_private7.NavigationLeft, { visible: withBackButton, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_private7.NavigationBackButton, { onPress: onBackButtonClick, canGoBack: false }) })
1364
1353
  }
1365
1354
  ) });
1366
1355
  }
1367
1356
 
1368
- // src/core/utils/mergeRefs.ts
1369
- function mergeRefs(...refs) {
1370
- return (value) => {
1371
- refs.forEach((ref) => {
1372
- if (typeof ref === "function") {
1373
- ref(value);
1374
- } else if (ref != null) {
1375
- ref.current = value;
1376
- }
1377
- });
1378
- };
1379
- }
1380
-
1381
- // src/hooks/useWebviewHistoryStack.tsx
1382
- var import_react15 = require("react");
1383
- var INITIAL_STATE = { stack: [], index: -1 };
1384
- function reducer(state, action) {
1385
- switch (action.type) {
1386
- case "NAVIGATION_CHANGE": {
1387
- const { url, canGoForward } = action;
1388
- if (state.stack.length === 0) {
1389
- return { stack: [url], index: 0 };
1390
- }
1391
- const { stack, index } = state;
1392
- const cur = stack[index];
1393
- if (url === cur) {
1394
- return state;
1395
- }
1396
- const prev = index > 0 ? stack[index - 1] : void 0;
1397
- const next = index < stack.length - 1 ? stack[index + 1] : void 0;
1398
- if (prev && url === prev && canGoForward) {
1399
- return { ...state, index: index - 1 };
1400
- }
1401
- if (next && url === next) {
1402
- return { ...state, index: index + 1 };
1403
- }
1404
- const base = stack.slice(0, index + 1);
1405
- const nextStack = [...base, url];
1406
- return { stack: nextStack, index: nextStack.length - 1 };
1407
- }
1408
- default:
1409
- return state;
1410
- }
1411
- }
1412
- function useWebViewHistory() {
1413
- const [state, dispatch] = (0, import_react15.useReducer)(reducer, INITIAL_STATE);
1414
- const onNavigationStateChange = (0, import_react15.useCallback)(({ url, canGoForward: canGoForward2 }) => {
1415
- dispatch({ type: "NAVIGATION_CHANGE", url, canGoForward: canGoForward2 });
1416
- }, []);
1417
- const { canGoBack, canGoForward } = (0, import_react15.useMemo)(() => {
1418
- const canBack = state.index > 0;
1419
- const canFwd = state.index >= 0 && state.index < state.stack.length - 1;
1420
- return { canGoBack: canBack, canGoForward: canFwd };
1421
- }, [state.index, state.stack.length]);
1422
- return { onNavigationStateChange, canGoBack, canGoForward };
1423
- }
1424
-
1425
- // src/utils/log.ts
1426
- var import_native_modules14 = require("@apps-in-toss/native-modules");
1427
- var import_react_native24 = require("@granite-js/react-native");
1428
-
1429
- // src/utils/extractDateFromUUIDv7.ts
1430
- var extractDateFromUUIDv7 = (uuid) => {
1431
- const timestampHex = uuid.split("-").join("").slice(0, 12);
1432
- const timestamp = Number.parseInt(timestampHex, 16);
1433
- return new Date(timestamp);
1434
- };
1435
-
1436
- // src/utils/log.ts
1437
- var getGroupId = (url) => {
1438
- try {
1439
- const urlObject = new URL(url);
1440
- return {
1441
- groupId: urlObject.pathname,
1442
- search: urlObject.search.startsWith("?") ? urlObject.search.substring(1) : urlObject.search
1443
- };
1444
- } catch {
1445
- return {
1446
- groupId: "unknown",
1447
- search: "unknown"
1448
- };
1449
- }
1450
- };
1451
- var getReferrer = () => {
1452
- try {
1453
- const referrer = new URL((0, import_react_native24.getSchemeUri)());
1454
- return referrer.searchParams.get("referrer");
1455
- } catch {
1456
- return "";
1457
- }
1458
- };
1459
- var trackScreen = (url) => {
1460
- const { groupId, search } = getGroupId(url);
1461
- const log = {
1462
- log_type: "screen",
1463
- log_name: `${groupId}::screen`,
1464
- params: {
1465
- search,
1466
- referrer: getReferrer(),
1467
- deployment_id: env.getDeploymentId(),
1468
- deployment_timestamp: extractDateFromUUIDv7(env.getDeploymentId()).getTime()
1469
- }
1470
- };
1471
- return (0, import_native_modules14.eventLog)(log);
1472
- };
1473
-
1474
1357
  // src/components/PartnerWebView.tsx
1475
1358
  var import_jsx_runtime12 = require("react/jsx-runtime");
1476
- var PartnerWebView = (0, import_react16.forwardRef)(
1477
- function PartnerWebViewScreen(webViewProps, ref) {
1478
- const webViewRef = (0, import_react16.useRef)(null);
1479
- const refs = mergeRefs(ref, webViewRef);
1480
- const { captureExitLog } = useCaptureExitLog();
1481
- const { canGoBack, onNavigationStateChange } = useWebViewHistory();
1482
- const historyBackScript = `
1483
- (function() {
1484
- window.history.back();
1485
- true;
1486
- })();
1487
- `;
1488
- const historyHomeScript = `
1489
- (function() {
1490
- window.location.href = '/';
1491
- true;
1492
- })();
1493
- `;
1494
- const handleBackEvent = (0, import_react16.useCallback)(() => {
1495
- if (canGoBack) {
1496
- webViewRef.current?.injectJavaScript(historyBackScript);
1497
- } else {
1498
- captureExitLog(Date.now());
1499
- (0, import_native_modules15.closeView)();
1500
- }
1501
- }, [canGoBack, captureExitLog, historyBackScript]);
1502
- (0, import_react16.useEffect)(() => {
1503
- const handleAndroidBackEvent = () => {
1504
- if (canGoBack) {
1505
- webViewRef.current?.injectJavaScript(historyBackScript);
1506
- return true;
1507
- } else {
1508
- captureExitLog(Date.now());
1509
- return false;
1510
- }
1511
- };
1512
- import_react_native25.BackHandler.addEventListener("hardwareBackPress", handleAndroidBackEvent);
1513
- return () => import_react_native25.BackHandler.removeEventListener("hardwareBackPress", handleAndroidBackEvent);
1514
- }, [canGoBack, captureExitLog, historyBackScript]);
1515
- const handleHomeIconButtonClick = (0, import_react16.useCallback)(() => {
1516
- webViewRef.current?.injectJavaScript(historyHomeScript);
1517
- }, [historyHomeScript]);
1518
- const handleNavigationStateChange = (0, import_react16.useCallback)(
1519
- (event) => {
1520
- if (event.url) {
1521
- trackScreen(event.url);
1522
- }
1523
- onNavigationStateChange(event);
1524
- },
1525
- [onNavigationStateChange]
1526
- );
1527
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1528
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1529
- PartnerWebviewNavigationBar,
1530
- {
1531
- handleBackEvent,
1532
- handleHomeIconButtonClick
1533
- }
1534
- ),
1535
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1536
- import_react_native_webview2.WebView,
1537
- {
1538
- ref: refs,
1539
- ...webViewProps,
1540
- style: { flex: 1 },
1541
- onNavigationStateChange: (event) => {
1542
- webViewProps?.onNavigationStateChange?.(event);
1543
- handleNavigationStateChange(event);
1544
- }
1545
- }
1546
- )
1547
- ] });
1548
- }
1549
- );
1359
+ var PartnerWebView = (0, import_react15.forwardRef)(function PartnerWebViewScreen({ onBackButtonClick, onHomeButtonClick, ...webViewProps }, ref) {
1360
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1361
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PartnerWebviewNavigationBar, { onBackButtonClick, onHomeButtonClick }),
1362
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_webview2.WebView, { ref, ...webViewProps, style: { flex: 1 } })
1363
+ ] });
1364
+ });
1550
1365
 
1551
1366
  // src/bridge-handler/useBridgeHandler.tsx
1552
- var import_react17 = require("react");
1367
+ var import_react16 = require("react");
1553
1368
  function serializeError(error) {
1554
1369
  return JSON.stringify(error, (_, value) => {
1555
1370
  if (value instanceof Error) {
@@ -1602,8 +1417,8 @@ function useBridgeHandler({
1602
1417
  eventListenerMap,
1603
1418
  injectedJavaScript: originalInjectedJavaScript
1604
1419
  }) {
1605
- const ref = (0, import_react17.useRef)(null);
1606
- const injectedJavaScript = (0, import_react17.useMemo)(
1420
+ const ref = (0, import_react16.useRef)(null);
1421
+ const injectedJavaScript = (0, import_react16.useMemo)(
1607
1422
  () => [
1608
1423
  `window.__CONSTANT_HANDLER_MAP = ${JSON.stringify(
1609
1424
  Object.entries(constantHandlerMap).reduce(
@@ -1630,7 +1445,7 @@ function useBridgeHandler({
1630
1445
  window.__GRANITE_NATIVE_EMITTER.emit('${functionName}/onError/${eventId}', ${serializedError});
1631
1446
  `);
1632
1447
  };
1633
- const $onMessage = (0, import_react17.useCallback)(
1448
+ const $onMessage = (0, import_react16.useCallback)(
1634
1449
  async (e) => {
1635
1450
  onMessage?.(e);
1636
1451
  const data = JSON.parse(e.nativeEvent.data);
@@ -1680,9 +1495,158 @@ function useBridgeHandler({
1680
1495
  };
1681
1496
  }
1682
1497
 
1498
+ // src/core/hooks/useWebBackHandler.tsx
1499
+ var import_react_native24 = require("@granite-js/react-native");
1500
+ var import_tds_react_native12 = require("@toss/tds-react-native");
1501
+ var import_es_hangul5 = require("es-hangul");
1502
+ var import_react18 = require("react");
1503
+
1504
+ // src/hooks/useWebviewHistoryStack.tsx
1505
+ var import_react17 = require("react");
1506
+ var INITIAL_STATE = { stack: [], index: -1 };
1507
+ function reducer(state, action) {
1508
+ switch (action.type) {
1509
+ case "NAVIGATION_CHANGE": {
1510
+ const { url, canGoForward } = action;
1511
+ if (state.stack.length === 0) {
1512
+ return { stack: [url], index: 0 };
1513
+ }
1514
+ const { stack, index } = state;
1515
+ const cur = stack[index];
1516
+ if (url === cur) {
1517
+ return state;
1518
+ }
1519
+ const prev = index > 0 ? stack[index - 1] : void 0;
1520
+ const next = index < stack.length - 1 ? stack[index + 1] : void 0;
1521
+ if (prev && url === prev && canGoForward) {
1522
+ return { ...state, index: index - 1 };
1523
+ }
1524
+ if (next && url === next) {
1525
+ return { ...state, index: index + 1 };
1526
+ }
1527
+ const base = stack.slice(0, index + 1);
1528
+ const nextStack = [...base, url];
1529
+ return { stack: nextStack, index: nextStack.length - 1 };
1530
+ }
1531
+ default:
1532
+ return state;
1533
+ }
1534
+ }
1535
+ function useWebViewHistory() {
1536
+ const [state, dispatch] = (0, import_react17.useReducer)(reducer, INITIAL_STATE);
1537
+ const onNavigationStateChange = (0, import_react17.useCallback)(({ url, canGoForward: canGoForward2 }) => {
1538
+ dispatch({ type: "NAVIGATION_CHANGE", url, canGoForward: canGoForward2 });
1539
+ }, []);
1540
+ const { canGoBack, canGoForward } = (0, import_react17.useMemo)(() => {
1541
+ const canBack = state.index > 0;
1542
+ const canFwd = state.index >= 0 && state.index < state.stack.length - 1;
1543
+ return { canGoBack: canBack, canGoForward: canFwd };
1544
+ }, [state.index, state.stack.length]);
1545
+ return { onNavigationStateChange, hasHistory: canGoBack, canGoForward };
1546
+ }
1547
+
1548
+ // src/core/hooks/useWebBackHandler.tsx
1549
+ var HISTORY_BACK_SCRIPT = `
1550
+ (function() {
1551
+ window.history.back();
1552
+ true;
1553
+ })();
1554
+ `;
1555
+ var HISTORY_HOME_SCRIPT = `
1556
+ (function() {
1557
+ window.location.href = '/';
1558
+ true;
1559
+ })();
1560
+ `;
1561
+ function useWebBackHandler(webViewRef) {
1562
+ const { captureExitLog } = useCaptureExitLog();
1563
+ const { hasHistory, onNavigationStateChange } = useWebViewHistory();
1564
+ const {
1565
+ handlersRef: webBackHandlersRef,
1566
+ hasBackEvent: hasWebBackEvent,
1567
+ addEventListener: addWebBackEventListener,
1568
+ removeEventListener: removeWebBackEventListener
1569
+ } = (0, import_react_native24.useBackEventState)();
1570
+ const logging = useNavigationBarLogging();
1571
+ const { openConfirm } = (0, import_tds_react_native12.useDialog)();
1572
+ const global2 = getAppsInTossGlobals();
1573
+ const addEventListener = (0, import_react18.useCallback)(
1574
+ (handler) => {
1575
+ addWebBackEventListener(handler);
1576
+ },
1577
+ [addWebBackEventListener]
1578
+ );
1579
+ const removeEventListener = (0, import_react18.useCallback)(
1580
+ (handler) => {
1581
+ removeWebBackEventListener(handler);
1582
+ },
1583
+ [removeWebBackEventListener]
1584
+ );
1585
+ const handleWebBack = (0, import_react18.useCallback)(async () => {
1586
+ if (hasWebBackEvent) {
1587
+ for (const handler of webBackHandlersRef) {
1588
+ handler();
1589
+ }
1590
+ return;
1591
+ }
1592
+ if (hasHistory) {
1593
+ webViewRef.current?.injectJavaScript(HISTORY_BACK_SCRIPT);
1594
+ } else {
1595
+ const isConfirmed = await openConfirm({
1596
+ title: `${(0, import_es_hangul5.josa)(global2.brandDisplayName, "\uC744/\uB97C")} \uC885\uB8CC\uD560\uAE4C\uC694?`,
1597
+ leftButton: "\uCDE8\uC18C",
1598
+ rightButton: "\uC885\uB8CC\uD558\uAE30",
1599
+ closeOnDimmerClick: true,
1600
+ onEntered: logging.closePopupShow
1601
+ });
1602
+ logging.closePopupCtaClick(isConfirmed);
1603
+ if (isConfirmed) {
1604
+ captureExitLog(Date.now());
1605
+ (0, import_react_native24.closeView)();
1606
+ }
1607
+ }
1608
+ }, [
1609
+ captureExitLog,
1610
+ global2.brandDisplayName,
1611
+ hasHistory,
1612
+ hasWebBackEvent,
1613
+ webBackHandlersRef,
1614
+ logging,
1615
+ openConfirm,
1616
+ webViewRef
1617
+ ]);
1618
+ const handleWebHome = (0, import_react18.useCallback)(() => {
1619
+ logging.homeButtonClick();
1620
+ if (hasWebBackEvent) {
1621
+ for (const handler of webBackHandlersRef) {
1622
+ handler();
1623
+ }
1624
+ return;
1625
+ }
1626
+ webViewRef.current?.injectJavaScript(HISTORY_HOME_SCRIPT);
1627
+ }, [hasWebBackEvent, webBackHandlersRef, logging, webViewRef]);
1628
+ return (0, import_react18.useMemo)(
1629
+ () => ({ addEventListener, removeEventListener, handleWebBack, handleWebHome, onNavigationStateChange }),
1630
+ [addEventListener, removeEventListener, handleWebBack, handleWebHome, onNavigationStateChange]
1631
+ );
1632
+ }
1633
+
1634
+ // src/core/utils/mergeRefs.ts
1635
+ function mergeRefs(...refs) {
1636
+ return (value) => {
1637
+ refs.forEach((ref) => {
1638
+ if (typeof ref === "function") {
1639
+ ref(value);
1640
+ } else if (ref != null) {
1641
+ ref.current = value;
1642
+ }
1643
+ });
1644
+ };
1645
+ }
1646
+
1683
1647
  // src/hooks/useCreateUserAgent.ts
1684
- var import_native_modules16 = require("@apps-in-toss/native-modules");
1685
- var import_react_native26 = require("react-native");
1648
+ var import_native_modules14 = require("@apps-in-toss/native-modules");
1649
+ var import_react_native25 = require("react-native");
1686
1650
  var FontA11yCategory = {
1687
1651
  Large: "Large",
1688
1652
  xLarge: "xLarge",
@@ -1815,9 +1779,9 @@ function useCreateUserAgent({
1815
1779
  safeArea,
1816
1780
  safeAreaBottomTransparency
1817
1781
  }) {
1818
- const platform = (0, import_native_modules16.getPlatformOS)();
1819
- const appVersion = (0, import_native_modules16.getTossAppVersion)();
1820
- const { fontScale } = (0, import_react_native26.useWindowDimensions)();
1782
+ const platform = (0, import_native_modules14.getPlatformOS)();
1783
+ const appVersion = (0, import_native_modules14.getTossAppVersion)();
1784
+ const { fontScale } = (0, import_react_native25.useWindowDimensions)();
1821
1785
  const platformString = platform === "ios" ? "iPhone" : "Android";
1822
1786
  const fontA11y = mapFontScaleToCategory(fontScale, platform);
1823
1787
  const normalizedFontScale = convertToAndroidStyleScale(fontScale, platform);
@@ -1837,17 +1801,17 @@ function useCreateUserAgent({
1837
1801
  }
1838
1802
 
1839
1803
  // src/hooks/useGeolocation.ts
1840
- var import_native_modules17 = require("@apps-in-toss/native-modules");
1841
- var import_react_native27 = require("@granite-js/react-native");
1842
- var import_react18 = require("react");
1804
+ var import_native_modules15 = require("@apps-in-toss/native-modules");
1805
+ var import_react_native26 = require("@granite-js/react-native");
1806
+ var import_react19 = require("react");
1843
1807
  function useGeolocation({ accuracy, distanceInterval, timeInterval }) {
1844
- const isVisible = (0, import_react_native27.useVisibility)();
1845
- const [location, setLocation] = (0, import_react18.useState)(null);
1846
- (0, import_react18.useEffect)(() => {
1808
+ const isVisible = (0, import_react_native26.useVisibility)();
1809
+ const [location, setLocation] = (0, import_react19.useState)(null);
1810
+ (0, import_react19.useEffect)(() => {
1847
1811
  if (!isVisible) {
1848
1812
  return;
1849
1813
  }
1850
- return (0, import_native_modules17.startUpdateLocation)({
1814
+ return (0, import_native_modules15.startUpdateLocation)({
1851
1815
  options: {
1852
1816
  accuracy,
1853
1817
  distanceInterval,
@@ -1860,18 +1824,97 @@ function useGeolocation({ accuracy, distanceInterval, timeInterval }) {
1860
1824
  return location;
1861
1825
  }
1862
1826
 
1827
+ // src/hooks/useWaitForReturnNavigator.tsx
1828
+ var import_react_native27 = require("@granite-js/react-native");
1829
+ var import_react20 = require("react");
1830
+ function useWaitForReturnNavigator() {
1831
+ const callbacks = (0, import_react20.useRef)([]).current;
1832
+ const navigation = (0, import_react_native27.useNavigation)();
1833
+ const startNavigating = (0, import_react20.useCallback)(
1834
+ (route, params) => {
1835
+ return new Promise((resolve) => {
1836
+ callbacks.push(resolve);
1837
+ navigation.navigate(route, params);
1838
+ });
1839
+ },
1840
+ [callbacks, navigation]
1841
+ );
1842
+ const handleVisibilityChange = (0, import_react20.useCallback)(
1843
+ (state) => {
1844
+ if (state === "visible" && callbacks.length > 0) {
1845
+ for (const callback of callbacks) {
1846
+ callback();
1847
+ }
1848
+ callbacks.splice(0, callbacks.length);
1849
+ }
1850
+ },
1851
+ [callbacks]
1852
+ );
1853
+ (0, import_react_native27.useVisibilityChange)(handleVisibilityChange);
1854
+ return startNavigating;
1855
+ }
1856
+
1857
+ // src/utils/log.ts
1858
+ var import_native_modules16 = require("@apps-in-toss/native-modules");
1859
+ var import_react_native28 = require("@granite-js/react-native");
1860
+
1861
+ // src/utils/extractDateFromUUIDv7.ts
1862
+ var extractDateFromUUIDv7 = (uuid) => {
1863
+ const timestampHex = uuid.split("-").join("").slice(0, 12);
1864
+ const timestamp = Number.parseInt(timestampHex, 16);
1865
+ return new Date(timestamp);
1866
+ };
1867
+
1868
+ // src/utils/log.ts
1869
+ var getGroupId = (url) => {
1870
+ try {
1871
+ const urlObject = new URL(url);
1872
+ return {
1873
+ groupId: urlObject.pathname,
1874
+ search: urlObject.search.startsWith("?") ? urlObject.search.substring(1) : urlObject.search
1875
+ };
1876
+ } catch {
1877
+ return {
1878
+ groupId: "unknown",
1879
+ search: "unknown"
1880
+ };
1881
+ }
1882
+ };
1883
+ var getReferrer = () => {
1884
+ try {
1885
+ const referrer = new URL((0, import_react_native28.getSchemeUri)());
1886
+ return referrer.searchParams.get("referrer");
1887
+ } catch {
1888
+ return "";
1889
+ }
1890
+ };
1891
+ var trackScreen = (url) => {
1892
+ const { groupId, search } = getGroupId(url);
1893
+ const log = {
1894
+ log_type: "screen",
1895
+ log_name: `${groupId}::screen`,
1896
+ params: {
1897
+ search,
1898
+ referrer: getReferrer(),
1899
+ deployment_id: env.getDeploymentId(),
1900
+ deployment_timestamp: extractDateFromUUIDv7(env.getDeploymentId()).getTime()
1901
+ }
1902
+ };
1903
+ return (0, import_native_modules16.eventLog)(log);
1904
+ };
1905
+
1863
1906
  // src/components/WebView.tsx
1864
1907
  var import_jsx_runtime13 = require("react/jsx-runtime");
1865
1908
  var operationalEnvironment = appsInTossConstantBridges.getOperationalEnvironment();
1866
1909
  var TYPES = ["partner", "external", "game"];
1867
1910
  var WEBVIEW_TYPES = {
1868
1911
  partner: PartnerWebView,
1869
- external: import_tds_react_native12.ExternalWebViewScreen,
1912
+ external: import_tds_react_native13.ExternalWebViewScreen,
1870
1913
  game: GameWebView
1871
1914
  };
1872
1915
  function mergeSchemeQueryParamsInto(url) {
1873
1916
  const baseUrl = new URL(url);
1874
- const schemeUrl = new URL((0, import_react_native28.getSchemeUri)());
1917
+ const schemeUrl = new URL((0, import_react_native29.getSchemeUri)());
1875
1918
  baseUrl.pathname = schemeUrl.pathname;
1876
1919
  for (const [key, value] of schemeUrl.searchParams.entries()) {
1877
1920
  baseUrl.searchParams.set(key, value);
@@ -1883,7 +1926,7 @@ function getWebViewUri(local) {
1883
1926
  const devUrl = `http://${local.host}:${local.port}`;
1884
1927
  return mergeSchemeQueryParamsInto(devUrl).toString();
1885
1928
  }
1886
- const { url: rawUrl } = import_native_modules18.AppsInTossModule.getWebBundleURL({});
1929
+ const { url: rawUrl } = import_native_modules17.AppsInTossModule.getWebBundleURL({});
1887
1930
  const url = mergeSchemeQueryParamsInto(rawUrl);
1888
1931
  const deploymentId = env.getDeploymentId();
1889
1932
  if (deploymentId) {
@@ -1895,8 +1938,9 @@ function WebView({ type, local, onMessage, ...props }) {
1895
1938
  if (!TYPES.includes(type)) {
1896
1939
  throw new Error(`Invalid WebView type: '${type}'`);
1897
1940
  }
1898
- const graniteEvent = (0, import_react_native28.useGraniteEvent)();
1899
- const uri = (0, import_react19.useMemo)(() => getWebViewUri(local), [local]);
1941
+ const webViewRef = (0, import_react21.useRef)(null);
1942
+ const webBackHandler = useWebBackHandler(webViewRef);
1943
+ const uri = (0, import_react21.useMemo)(() => getWebViewUri(local), [local]);
1900
1944
  const top = (0, import_private8.useSafeAreaTop)();
1901
1945
  const bottom = (0, import_private8.useSafeAreaBottom)();
1902
1946
  const global2 = getAppsInTossGlobals();
@@ -1908,7 +1952,7 @@ function WebView({ type, local, onMessage, ...props }) {
1908
1952
  document.head.appendChild(style);
1909
1953
  })();
1910
1954
  `;
1911
- const [allowsBackForwardNavigationGestures, setAllowsBackForwardNavigationGestures] = (0, import_react19.useState)(
1955
+ const [allowsBackForwardNavigationGestures, setAllowsBackForwardNavigationGestures] = (0, import_react21.useState)(
1912
1956
  props.allowsBackForwardNavigationGestures
1913
1957
  );
1914
1958
  const handler = useBridgeHandler({
@@ -1917,23 +1961,28 @@ function WebView({ type, local, onMessage, ...props }) {
1917
1961
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1918
1962
  eventListenerMap: {
1919
1963
  ...appsInTossEventBridges,
1920
- navigationAccessoryEvent: ({ onEvent, onError }) => import_tds_react_native12.tdsEvent.addEventListener("navigationAccessoryEvent", { onEvent, onError }),
1921
- backEvent: ({ onEvent, onError, options }) => graniteEvent.addEventListener("backEvent", { onEvent, onError, options }),
1922
- entryMessageExited: ({ onEvent, onError }) => import_native_modules18.appsInTossEvent.addEventListener("entryMessageExited", { onEvent, onError }),
1923
- updateLocationEvent: ({ onEvent, onError, options }) => import_native_modules18.appsInTossEvent.addEventListener("updateLocationEvent", { onEvent, onError, options }),
1964
+ navigationAccessoryEvent: ({ onEvent, onError }) => import_tds_react_native13.tdsEvent.addEventListener("navigationAccessoryEvent", { onEvent, onError }),
1965
+ backEvent: ({ onEvent }) => {
1966
+ webBackHandler.addEventListener(onEvent);
1967
+ return () => {
1968
+ webBackHandler.removeEventListener(onEvent);
1969
+ };
1970
+ },
1971
+ entryMessageExited: ({ onEvent, onError }) => import_native_modules17.appsInTossEvent.addEventListener("entryMessageExited", { onEvent, onError }),
1972
+ updateLocationEvent: ({ onEvent, onError, options }) => import_native_modules17.appsInTossEvent.addEventListener("updateLocationEvent", { onEvent, onError, options }),
1924
1973
  /** @internal */
1925
- appBridgeCallbackEvent: ({ onEvent, onError, options }) => import_native_modules18.appsInTossEvent.addEventListener("appBridgeCallbackEvent", { onEvent, onError, options }),
1974
+ appBridgeCallbackEvent: ({ onEvent, onError, options }) => import_native_modules17.appsInTossEvent.addEventListener("appBridgeCallbackEvent", { onEvent, onError, options }),
1926
1975
  /** AdMob */
1927
- loadAdMobInterstitialAd: import_native_modules18.GoogleAdMob.loadAdMobInterstitialAd,
1928
- showAdMobInterstitialAd: import_native_modules18.GoogleAdMob.showAdMobInterstitialAd,
1929
- loadAdMobRewardedAd: import_native_modules18.GoogleAdMob.loadAdMobRewardedAd,
1930
- showAdMobRewardedAd: import_native_modules18.GoogleAdMob.showAdMobRewardedAd,
1976
+ loadAdMobInterstitialAd: import_native_modules17.GoogleAdMob.loadAdMobInterstitialAd,
1977
+ showAdMobInterstitialAd: import_native_modules17.GoogleAdMob.showAdMobInterstitialAd,
1978
+ loadAdMobRewardedAd: import_native_modules17.GoogleAdMob.loadAdMobRewardedAd,
1979
+ showAdMobRewardedAd: import_native_modules17.GoogleAdMob.showAdMobRewardedAd,
1931
1980
  /** AdMobV2 */
1932
- loadAppsInTossAdMob: import_native_modules18.GoogleAdMob.loadAppsInTossAdMob,
1933
- showAppsInTossAdMob: import_native_modules18.GoogleAdMob.showAppsInTossAdMob,
1981
+ loadAppsInTossAdMob: import_native_modules17.GoogleAdMob.loadAppsInTossAdMob,
1982
+ showAppsInTossAdMob: import_native_modules17.GoogleAdMob.showAppsInTossAdMob,
1934
1983
  /** IAP */
1935
- iapCreateOneTimePurchaseOrder: import_native_modules18.IAP.createOneTimePurchaseOrder,
1936
- requestOneTimePurchase: import_native_modules18.requestOneTimePurchase
1984
+ iapCreateOneTimePurchaseOrder: import_native_modules17.IAP.createOneTimePurchaseOrder,
1985
+ requestOneTimePurchase: import_native_modules17.requestOneTimePurchase
1937
1986
  },
1938
1987
  constantHandlerMap: {
1939
1988
  ...appsInTossConstantBridges,
@@ -1941,13 +1990,13 @@ function WebView({ type, local, onMessage, ...props }) {
1941
1990
  getSafeAreaBottom: () => bottom,
1942
1991
  ...Object.fromEntries(Object.entries(global2).map(([key, value]) => [key, () => value])),
1943
1992
  /** AdMob */
1944
- loadAdMobInterstitialAd_isSupported: import_native_modules18.GoogleAdMob.loadAdMobInterstitialAd.isSupported,
1945
- showAdMobInterstitialAd_isSupported: import_native_modules18.GoogleAdMob.showAdMobInterstitialAd.isSupported,
1946
- loadAdMobRewardedAd_isSupported: import_native_modules18.GoogleAdMob.loadAdMobRewardedAd.isSupported,
1947
- showAdMobRewardedAd_isSupported: import_native_modules18.GoogleAdMob.showAdMobRewardedAd.isSupported,
1993
+ loadAdMobInterstitialAd_isSupported: import_native_modules17.GoogleAdMob.loadAdMobInterstitialAd.isSupported,
1994
+ showAdMobInterstitialAd_isSupported: import_native_modules17.GoogleAdMob.showAdMobInterstitialAd.isSupported,
1995
+ loadAdMobRewardedAd_isSupported: import_native_modules17.GoogleAdMob.loadAdMobRewardedAd.isSupported,
1996
+ showAdMobRewardedAd_isSupported: import_native_modules17.GoogleAdMob.showAdMobRewardedAd.isSupported,
1948
1997
  /** AdMobV2 */
1949
- loadAppsInTossAdMob_isSupported: import_native_modules18.GoogleAdMob.loadAppsInTossAdMob.isSupported,
1950
- showAppsInTossAdMob_isSupported: import_native_modules18.GoogleAdMob.showAppsInTossAdMob.isSupported,
1998
+ loadAppsInTossAdMob_isSupported: import_native_modules17.GoogleAdMob.loadAppsInTossAdMob.isSupported,
1999
+ showAppsInTossAdMob_isSupported: import_native_modules17.GoogleAdMob.showAppsInTossAdMob.isSupported,
1951
2000
  /** env */
1952
2001
  getDeploymentId: env.getDeploymentId
1953
2002
  },
@@ -1970,19 +2019,20 @@ function WebView({ type, local, onMessage, ...props }) {
1970
2019
  getCurrentLocation: appsInTossAsyncBridges.getCurrentLocation,
1971
2020
  openCamera: appsInTossAsyncBridges.openCamera,
1972
2021
  /** Storage */
1973
- getStorageItem: import_native_modules18.Storage.getItem,
1974
- setStorageItem: import_native_modules18.Storage.setItem,
1975
- removeStorageItem: import_native_modules18.Storage.removeItem,
1976
- clearItems: import_native_modules18.Storage.clearItems,
2022
+ getStorageItem: import_native_modules17.Storage.getItem,
2023
+ setStorageItem: import_native_modules17.Storage.setItem,
2024
+ removeStorageItem: import_native_modules17.Storage.removeItem,
2025
+ clearItems: import_native_modules17.Storage.clearItems,
1977
2026
  /** IAP */
1978
- iapGetProductItemList: import_native_modules18.IAP.getProductItemList,
1979
- iapCreateOneTimePurchaseOrder: import_native_modules18.iapCreateOneTimePurchaseOrder,
1980
- processProductGrant: import_native_modules18.processProductGrant,
1981
- getPendingOrders: import_native_modules18.IAP.getPendingOrders,
1982
- getCompletedOrRefundedOrders: import_native_modules18.IAP.getCompletedOrRefundedOrders
2027
+ iapGetProductItemList: import_native_modules17.IAP.getProductItemList,
2028
+ iapCreateOneTimePurchaseOrder: import_native_modules17.iapCreateOneTimePurchaseOrder,
2029
+ processProductGrant: import_native_modules17.processProductGrant,
2030
+ getPendingOrders: import_native_modules17.IAP.getPendingOrders,
2031
+ getCompletedOrRefundedOrders: import_native_modules17.IAP.getCompletedOrRefundedOrders,
2032
+ completeProductGrant: import_native_modules17.IAP.completeProductGrant
1983
2033
  }
1984
2034
  });
1985
- const headerPropForExternalWebView = (0, import_react19.useMemo)(() => {
2035
+ const headerPropForExternalWebView = (0, import_react21.useMemo)(() => {
1986
2036
  const parsedNavigationBar = global2.navigationBar != null ? safeParseNavigationBar(global2.navigationBar) : null;
1987
2037
  const initialAccessoryButton = parsedNavigationBar?.initialAccessoryButton;
1988
2038
  const withBackButton = parsedNavigationBar?.withBackButton ?? true;
@@ -2002,10 +2052,19 @@ function WebView({ type, local, onMessage, ...props }) {
2002
2052
  const userAgent = useCreateUserAgent({
2003
2053
  colorPreference: "light"
2004
2054
  });
2055
+ const refs = mergeRefs(handler.ref, webViewRef);
2056
+ (0, import_react21.useEffect)(() => {
2057
+ const callback = () => {
2058
+ webBackHandler.handleWebBack();
2059
+ return true;
2060
+ };
2061
+ import_react_native30.BackHandler.addEventListener("hardwareBackPress", callback);
2062
+ return () => import_react_native30.BackHandler.removeEventListener("hardwareBackPress", callback);
2063
+ }, [webBackHandler]);
2005
2064
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2006
2065
  BaseWebView,
2007
2066
  {
2008
- ref: handler.ref,
2067
+ ref: refs,
2009
2068
  ...props,
2010
2069
  ...headerPropForExternalWebView,
2011
2070
  source: {
@@ -2015,14 +2074,23 @@ function WebView({ type, local, onMessage, ...props }) {
2015
2074
  "User-Agent": userAgent
2016
2075
  }
2017
2076
  },
2018
- userAgent: import_react_native29.Platform.OS === "ios" ? userAgent : void 0,
2077
+ onHomeButtonClick: webBackHandler.handleWebHome,
2078
+ onBackButtonClick: webBackHandler.handleWebBack,
2079
+ onNavigationStateChange: (event) => {
2080
+ if (event.url) {
2081
+ trackScreen(event.url);
2082
+ }
2083
+ props.onNavigationStateChange?.(event);
2084
+ webBackHandler.onNavigationStateChange(event);
2085
+ },
2086
+ userAgent: import_react_native30.Platform.OS === "ios" ? userAgent : void 0,
2019
2087
  sharedCookiesEnabled: true,
2020
2088
  webviewDebuggingEnabled: webViewDebuggingEnabled,
2021
2089
  thirdPartyCookiesEnabled: true,
2022
2090
  onMessage: handler.onMessage,
2023
2091
  injectedJavaScript: handler.injectedJavaScript,
2024
2092
  injectedJavaScriptBeforeContentLoaded: handler.injectedJavaScript,
2025
- decelerationRate: import_react_native29.Platform.OS === "ios" ? 1 : void 0,
2093
+ decelerationRate: import_react_native30.Platform.OS === "ios" ? 1 : void 0,
2026
2094
  allowsBackForwardNavigationGestures
2027
2095
  }
2028
2096
  );
@@ -2044,11 +2112,14 @@ var Analytics2 = {
2044
2112
  Analytics,
2045
2113
  AppsInToss,
2046
2114
  INTERNAL__onVisibilityChangedByTransparentServiceWeb,
2115
+ OverlayProvider,
2047
2116
  WebView,
2048
2117
  env,
2049
2118
  useCreateUserAgent,
2050
2119
  useGeolocation,
2120
+ useOverlay,
2051
2121
  useTopNavigation,
2122
+ useWaitForReturnNavigator,
2052
2123
  ...require("@apps-in-toss/analytics"),
2053
2124
  ...require("@apps-in-toss/native-modules"),
2054
2125
  ...require("@apps-in-toss/types")