@apps-in-toss/framework 1.0.1 → 1.0.3

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.js CHANGED
@@ -3,9 +3,10 @@ import { Analytics as InternalAnalytics } from "@apps-in-toss/analytics";
3
3
 
4
4
  // src/core/registerApp.tsx
5
5
  import { Analytics } from "@apps-in-toss/analytics";
6
- import { isMinVersionSupported, setIosSwipeGestureEnabled, eventLog } from "@apps-in-toss/native-modules";
7
- import { Granite as Granite3 } from "@granite-js/react-native";
6
+ import { isMinVersionSupported as isMinVersionSupported2, setIosSwipeGestureEnabled, eventLog } from "@apps-in-toss/native-modules";
7
+ import { Granite as Granite6 } from "@granite-js/react-native";
8
8
  import { TDSProvider } from "@toss-design-system/react-native";
9
+ import { AppRegistry } from "react-native";
9
10
 
10
11
  // src/core/components/AppEvent.tsx
11
12
  import { INTERNAL__module as INTERNAL__module2 } from "@apps-in-toss/native-modules";
@@ -148,10 +149,276 @@ function AppUpdate() {
148
149
  return /* @__PURE__ */ jsx(Fragment, {});
149
150
  }
150
151
 
151
- // src/core/hooks/useAppsInTossBridge.ts
152
+ // src/core/components/BuiltinNavigationBar/index.tsx
152
153
  import { appsInTossEvent } from "@apps-in-toss/native-modules";
153
- import { useBridge } from "@toss-design-system/react-native";
154
- import { useEffect as useEffect4 } from "react";
154
+ import { closeView, useBackEventContext, useNavigation } from "@granite-js/react-native";
155
+ import { useDialog as useDialog2 } from "@toss-design-system/react-native";
156
+ import { NavigationBackButton, NavigationLeft, TopNavigation } from "@toss-design-system/react-native/private";
157
+ import { josa } from "es-hangul";
158
+ import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef2 } from "react";
159
+ import { BackHandler } from "react-native";
160
+
161
+ // src/core/components/BuiltinNavigationBar/useBuiltinNavigationBarLogging.tsx
162
+ import { INTERNAL__module as INTERNAL__module3 } from "@apps-in-toss/native-modules";
163
+ import { Granite as Granite3 } from "@granite-js/react-native";
164
+ var NAVI_BAR_IMPRESSION_SCHEMA_ID = 1596837;
165
+ var NAVI_BAR_IMPRESSION_LOG_NAME = "appsintoss_app_visit__common_module::impression__navigation_bar";
166
+ var CLOSE_POPUP_SHOW_SCHEMA_ID = 1644490;
167
+ var CLOSE_POPUP_SHOW_LOG_NAME = "appsintoss_app_visit__common_module::popup__close_app";
168
+ var CLOSE_BUTTON_CLICK_SCHEMA_ID = 1596831;
169
+ var CLOSE_BUTTON_CLICK_LOG_NAME = "appsintoss_app_visit__common_module::click__icon_close";
170
+ var CLOSE_POPUP_CTA_CLICK_SCHEMA_ID = 1644492;
171
+ var CLOSE_POPUP_CTA_CLICK_LOG_NAME = "appsintoss_app_visit__common_module::popup__close_app::click__cta";
172
+ var HOME_BUTTON_CLICK_SCHEMA_ID = 1596839;
173
+ var HOME_BUTTON_CLICK_LOG_NAME = "appsintoss_app_visit__common_module::click__icon_home";
174
+ function useBuiltinNavigationBarLogging() {
175
+ const referrer = useReferrer();
176
+ const baseParams = {
177
+ referrer,
178
+ app_name: Granite3.appName
179
+ };
180
+ const logNavBarImpression = (naviBarConfig) => {
181
+ INTERNAL__module3.tossCoreEventLog({
182
+ log_name: NAVI_BAR_IMPRESSION_LOG_NAME,
183
+ log_type: "event",
184
+ params: {
185
+ ...naviBarConfig,
186
+ ...baseParams,
187
+ event_type: "impression",
188
+ schema_id: NAVI_BAR_IMPRESSION_SCHEMA_ID
189
+ }
190
+ });
191
+ };
192
+ const logHomeButtonClick = () => {
193
+ INTERNAL__module3.tossCoreEventLog({
194
+ log_name: HOME_BUTTON_CLICK_LOG_NAME,
195
+ log_type: "event",
196
+ params: {
197
+ ...baseParams,
198
+ event_type: "click",
199
+ schema_id: HOME_BUTTON_CLICK_SCHEMA_ID
200
+ }
201
+ });
202
+ };
203
+ const logCloseButtonClick = () => {
204
+ INTERNAL__module3.tossCoreEventLog({
205
+ log_name: CLOSE_BUTTON_CLICK_LOG_NAME,
206
+ log_type: "event",
207
+ params: {
208
+ ...baseParams,
209
+ event_type: "click",
210
+ schema_id: CLOSE_BUTTON_CLICK_SCHEMA_ID
211
+ }
212
+ });
213
+ };
214
+ const logClosePopupShow = () => {
215
+ INTERNAL__module3.tossCoreEventLog({
216
+ log_name: CLOSE_POPUP_SHOW_LOG_NAME,
217
+ log_type: "popup",
218
+ params: {
219
+ ...baseParams,
220
+ schema_id: CLOSE_POPUP_SHOW_SCHEMA_ID
221
+ }
222
+ });
223
+ };
224
+ const logClosePopupCtaClick = (confirm) => {
225
+ INTERNAL__module3.tossCoreEventLog({
226
+ log_name: CLOSE_POPUP_CTA_CLICK_LOG_NAME,
227
+ log_type: "event",
228
+ params: {
229
+ ...baseParams,
230
+ close_yn: confirm ? "Y" : "N",
231
+ schema_id: CLOSE_POPUP_CTA_CLICK_SCHEMA_ID,
232
+ event_type: "click"
233
+ }
234
+ });
235
+ };
236
+ return {
237
+ navBarImpression: logNavBarImpression,
238
+ closePopupShow: logClosePopupShow,
239
+ closePopupCtaClick: logClosePopupCtaClick,
240
+ closeButtonClick: logCloseButtonClick,
241
+ homeButtonClick: logHomeButtonClick
242
+ };
243
+ }
244
+
245
+ // src/core/hooks/useMoreButtonBottomSheet/index.tsx
246
+ import { INTERNAL__appBridgeHandler, isMinVersionSupported } from "@apps-in-toss/native-modules";
247
+ import { openURL as openURL3 } from "@granite-js/react-native";
248
+ import { BottomSheet, List, ListHeader, ListRow } from "@toss-design-system/react-native";
249
+ import { useAdaptive, useOverlay } from "@toss-design-system/react-native/private";
250
+ import { useEffect as useEffect4, useState } from "react";
251
+
252
+ // src/core/hooks/useMoreButtonBottomSheet/useMoreButtonBottomSheetLogging.tsx
253
+ import { INTERNAL__module as INTERNAL__module4 } from "@apps-in-toss/native-modules";
254
+ import { Granite as Granite4 } from "@granite-js/react-native";
255
+ var BOTTOM_SHEET_SCHEMA_ID = 1596825;
256
+ var BOTTOM_SHEET_LOG_NAME = "appsintoss_app_visit__common_module::bottomsheet__more";
257
+ var BOTTOM_SHEET_OPEN_SCHEMA_ID = 1596829;
258
+ var BOTTOM_SHEET_OPEN_LOG_NAME = "appsintoss_app_visit__common_module::click__icon_more";
259
+ var BOTTOM_SHEET_CLOSE_CLICK_SCHEMA_ID = 1596843;
260
+ var BOTTOM_SHEET_CLOSE_CLICK_LOG_NAME = "appsintoss_app_visit__common_module::bottomsheet__more::click__close";
261
+ var BOTTOM_SHEET_MENU_CLICK_SCHEMA_ID = 1596841;
262
+ var BOTTOM_SHEET_MENU_CLICK_LOG_NAME = "appsintoss_app_visit__common_module::bottomsheet__more::click__menu";
263
+ function useMoreButtonBottomSheetLogging() {
264
+ const referrer = useReferrer();
265
+ const baseParams = {
266
+ referrer,
267
+ app_name: Granite4.appName
268
+ };
269
+ const logBottomSheetShow = () => {
270
+ INTERNAL__module4.tossCoreEventLog({
271
+ log_name: BOTTOM_SHEET_LOG_NAME,
272
+ log_type: "popup",
273
+ params: {
274
+ ...baseParams,
275
+ schema_id: BOTTOM_SHEET_SCHEMA_ID
276
+ }
277
+ });
278
+ };
279
+ const logBottomSheetOpen = () => {
280
+ INTERNAL__module4.tossCoreEventLog({
281
+ log_name: BOTTOM_SHEET_OPEN_LOG_NAME,
282
+ log_type: "event",
283
+ params: {
284
+ ...baseParams,
285
+ schema_id: BOTTOM_SHEET_OPEN_SCHEMA_ID,
286
+ event_type: "click"
287
+ }
288
+ });
289
+ };
290
+ const logBottomSheetCloseClick = () => {
291
+ INTERNAL__module4.tossCoreEventLog({
292
+ log_name: BOTTOM_SHEET_CLOSE_CLICK_LOG_NAME,
293
+ log_type: "event",
294
+ params: {
295
+ ...baseParams,
296
+ schema_id: BOTTOM_SHEET_CLOSE_CLICK_SCHEMA_ID,
297
+ event_type: "click"
298
+ }
299
+ });
300
+ };
301
+ const logBottomSheetMenuClick = ({ title }) => {
302
+ INTERNAL__module4.tossCoreEventLog({
303
+ log_name: BOTTOM_SHEET_MENU_CLICK_LOG_NAME,
304
+ log_type: "event",
305
+ params: {
306
+ ...baseParams,
307
+ schema_id: BOTTOM_SHEET_MENU_CLICK_SCHEMA_ID,
308
+ event_type: "click",
309
+ item_title: title
310
+ }
311
+ });
312
+ };
313
+ return {
314
+ show: logBottomSheetShow,
315
+ open: logBottomSheetOpen,
316
+ close: logBottomSheetCloseClick,
317
+ menuClick: logBottomSheetMenuClick
318
+ };
319
+ }
320
+
321
+ // src/hooks/useAppUpdateDialog.tsx
322
+ import { INTERNAL__module as INTERNAL__module5 } from "@apps-in-toss/native-modules";
323
+ import { Granite as Granite5, openURL as openURL2 } from "@granite-js/react-native";
324
+ import { useDialog } from "@toss-design-system/react-native";
325
+ import { useCallback as useCallback2 } from "react";
326
+
327
+ // src/utils/market.ts
328
+ import { Platform } from "react-native";
329
+ var PLAYSTORE_LINK = "https://play.google.com/store/apps/details?id=viva.republica.toss";
330
+ var APPSTORE_LINK = "https://itunes.apple.com/app/id839333328";
331
+ var getMarketLink = () => {
332
+ return Platform.OS === "android" ? PLAYSTORE_LINK : APPSTORE_LINK;
333
+ };
334
+
335
+ // src/hooks/useAppUpdateDialog.tsx
336
+ function useAppUpdateDialog() {
337
+ const { openConfirm } = useDialog();
338
+ const logging = useAppUpdateDialogLogging();
339
+ const openAppUpdateDialog = useCallback2(
340
+ async ({
341
+ title,
342
+ description,
343
+ leftButton = "\uB2EB\uAE30",
344
+ rightButton = "\uC5C5\uB370\uC774\uD2B8\uD558\uAE30"
345
+ }) => {
346
+ logging.show();
347
+ const isConfirmed = await openConfirm({
348
+ title,
349
+ description,
350
+ leftButton,
351
+ rightButton,
352
+ closeOnDimmerClick: true
353
+ });
354
+ if (!isConfirmed) {
355
+ logging.close();
356
+ return;
357
+ }
358
+ logging.update();
359
+ const STORE_SCHEME = getMarketLink();
360
+ openURL2(`supertoss://web?url=${STORE_SCHEME}&external=browser`);
361
+ },
362
+ [logging, openConfirm]
363
+ );
364
+ return {
365
+ open: openAppUpdateDialog
366
+ };
367
+ }
368
+ var UPDATE_DIALOG_SCHEMA_ID = 1634992;
369
+ var UPDATE_DIALOG_LOG_NAME = "appsintoss_app_visit__common_module::bottomsheet__app_update";
370
+ var UPDATE_DIALOG_CTA_CLICK_SCHEMA_ID = 1634996;
371
+ var UPDATE_DIALOG_CTA_CLICK_LOG_NAME = "appsintoss_app_visit__common_module::bottomsheet__app_update::click__cta";
372
+ function useAppUpdateDialogLogging() {
373
+ const referrer = useReferrer();
374
+ const baseParams = {
375
+ referrer,
376
+ app_name: Granite5.appName
377
+ };
378
+ const logUpdateClick = () => {
379
+ INTERNAL__module5.tossCoreEventLog({
380
+ log_name: UPDATE_DIALOG_CTA_CLICK_LOG_NAME,
381
+ log_type: "event",
382
+ params: {
383
+ ...baseParams,
384
+ schema_id: UPDATE_DIALOG_CTA_CLICK_SCHEMA_ID,
385
+ event_type: "click",
386
+ button_type: "update"
387
+ }
388
+ });
389
+ };
390
+ const logCloseClick = () => {
391
+ INTERNAL__module5.tossCoreEventLog({
392
+ log_name: UPDATE_DIALOG_CTA_CLICK_LOG_NAME,
393
+ log_type: "event",
394
+ params: {
395
+ ...baseParams,
396
+ schema_id: UPDATE_DIALOG_CTA_CLICK_SCHEMA_ID,
397
+ event_type: "click",
398
+ button_type: "close"
399
+ }
400
+ });
401
+ };
402
+ const logDialogShow = () => {
403
+ INTERNAL__module5.tossCoreEventLog({
404
+ log_name: UPDATE_DIALOG_LOG_NAME,
405
+ log_type: "popup",
406
+ params: {
407
+ ...baseParams,
408
+ schema_id: UPDATE_DIALOG_SCHEMA_ID
409
+ }
410
+ });
411
+ };
412
+ return { update: logUpdateClick, close: logCloseClick, show: logDialogShow };
413
+ }
414
+
415
+ // src/core/utils/ensureValue.ts
416
+ function ensureValue(value, name) {
417
+ if (value === void 0) {
418
+ throw new Error(`${name} is required`);
419
+ }
420
+ return value;
421
+ }
155
422
 
156
423
  // src/core/utils/getAppsInTossGlobals.ts
157
424
  function getAppsInTossGlobals() {
@@ -161,73 +428,312 @@ function getAppsInTossGlobals() {
161
428
  return global.__appsInToss;
162
429
  }
163
430
 
431
+ // src/core/hooks/useMoreButtonBottomSheet/index.tsx
432
+ import { Fragment as Fragment2, jsx as jsx2 } from "react/jsx-runtime";
433
+ var APP_BRIDGE_METHOD_NAME = "getMiniAppsSupportContact";
434
+ function useMoreButtonBottomSheet() {
435
+ const globals = getAppsInTossGlobals();
436
+ const adaptive = useAdaptive();
437
+ const [itemList, setItemList] = useState([]);
438
+ const appUpdateDialog = useAppUpdateDialog();
439
+ const logging = useMoreButtonBottomSheetLogging();
440
+ const overlay = useOverlay();
441
+ const title = ensureValue(globals.brandDisplayName, "displayName");
442
+ const isSupported = isMinVersionSupported({
443
+ android: "5.226.0",
444
+ ios: "5.226.0"
445
+ });
446
+ useEffect4(() => {
447
+ if (!isSupported) {
448
+ return;
449
+ }
450
+ INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
451
+ APP_BRIDGE_METHOD_NAME,
452
+ {},
453
+ {
454
+ onSuccess: ({ items }) => setItemList(items),
455
+ onError: (error) => console.error("\uBA54\uB274 \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uB294 \uB370 \uC2E4\uD328\uD588\uC5B4\uC694:", error)
456
+ }
457
+ );
458
+ }, [isSupported]);
459
+ const onClickHandler = async () => {
460
+ logging.open();
461
+ if (!isSupported) {
462
+ await appUpdateDialog.open({
463
+ title: `\uC774 \uAE30\uB2A5\uC744 \uC4F0\uB824\uBA74 \uC571 \uC5C5\uB370\uC774\uD2B8\uAC00 \uD544\uC694\uD574\uC694`,
464
+ description: `\uBB38\uC758, \uAD8C\uD55C \uC124\uC815, \uC2E0\uACE0 \uB4F1 \uAE30\uB2A5\uC744 \uC4F8 \uC218 \uC788\uC5B4\uC694`
465
+ });
466
+ return;
467
+ }
468
+ overlay.open(({ isOpen, exit, close }) => {
469
+ const handleClose = () => {
470
+ logging.close();
471
+ close();
472
+ };
473
+ return /* @__PURE__ */ jsx2(BottomSheetImpressionArea, { children: /* @__PURE__ */ jsx2(
474
+ BottomSheet.Root,
475
+ {
476
+ header: /* @__PURE__ */ jsx2(
477
+ ListHeader,
478
+ {
479
+ title: /* @__PURE__ */ jsx2(ListHeader.TitleParagraph, { color: adaptive.grey800, fontWeight: "bold", typography: "t5", children: title })
480
+ }
481
+ ),
482
+ open: isOpen,
483
+ cta: /* @__PURE__ */ jsx2(
484
+ BottomSheet.CTA,
485
+ {
486
+ size: "large",
487
+ type: "dark",
488
+ style: "weak",
489
+ onPress: () => {
490
+ handleClose();
491
+ },
492
+ children: "\uB2EB\uAE30"
493
+ }
494
+ ),
495
+ onClose: handleClose,
496
+ onExited: exit,
497
+ children: /* @__PURE__ */ jsx2(List, { rowSeparator: "none", children: itemList.map((item) => {
498
+ return /* @__PURE__ */ jsx2(
499
+ ListRow,
500
+ {
501
+ left: /* @__PURE__ */ jsx2(
502
+ ListRow.Icon,
503
+ {
504
+ color: globals.brandPrimaryColor,
505
+ source: { uri: item.contactIconUrl },
506
+ type: "background"
507
+ }
508
+ ),
509
+ contents: /* @__PURE__ */ jsx2(
510
+ ListRow.Texts,
511
+ {
512
+ type: "1RowTypeA",
513
+ top: item.contactItemName,
514
+ topProps: { color: adaptive.grey700 }
515
+ }
516
+ ),
517
+ verticalPadding: "extraSmall",
518
+ onPress: () => {
519
+ logging.menuClick({ title: item.contactItemName });
520
+ openURL3(item.contactUri);
521
+ }
522
+ },
523
+ item.contactItemName
524
+ );
525
+ }) })
526
+ }
527
+ ) });
528
+ });
529
+ };
530
+ return { open: onClickHandler };
531
+ }
532
+ function BottomSheetImpressionArea({ children }) {
533
+ const logging = useMoreButtonBottomSheetLogging();
534
+ useEffect4(() => {
535
+ logging.show();
536
+ }, [logging]);
537
+ return /* @__PURE__ */ jsx2(Fragment2, { children });
538
+ }
539
+
540
+ // src/core/utils/safeParseNavigationBar.ts
541
+ function safeParseNavigationBar(navigationBar) {
542
+ if (typeof navigationBar === "object") {
543
+ return navigationBar;
544
+ }
545
+ try {
546
+ return JSON.parse(navigationBar);
547
+ } catch {
548
+ return null;
549
+ }
550
+ }
551
+
164
552
  // src/core/utils/toIcon.ts
165
553
  function toIcon(source) {
166
554
  return source.startsWith("http") ? { source: { uri: source } } : { name: source };
167
555
  }
168
556
 
557
+ // src/core/components/BuiltinNavigationBar/index.tsx
558
+ import { Fragment as Fragment3, jsx as jsx3 } from "react/jsx-runtime";
559
+ function BuiltinNavigationBar() {
560
+ const globals = getAppsInTossGlobals();
561
+ const { captureExitLog } = useCaptureExitLog();
562
+ const logging = useBuiltinNavigationBarLogging();
563
+ const { openConfirm } = useDialog2();
564
+ const { open: openMoreButtonBottomSheet } = useMoreButtonBottomSheet();
565
+ const parsedNavigationBar = globals.navigationBar != null ? safeParseNavigationBar(globals.navigationBar) : null;
566
+ const withHomeButton = parsedNavigationBar?.withHomeButton ?? false;
567
+ const withBackButton = parsedNavigationBar?.withBackButton ?? true;
568
+ const initialAccessoryButton = parsedNavigationBar?.initialAccessoryButton;
569
+ const isExternalWebView = globals.webViewType === "external";
570
+ const isGameWebView = globals.webViewType === "game";
571
+ const backEventContext = useBackEventContext();
572
+ const overrideCanGoBack = !backEventContext.hasBackEvent;
573
+ const handleBackOrClose = useBackOrCloseNavigation();
574
+ const navigation = useNavigation();
575
+ const handlePressTitle = useCallback3(() => {
576
+ logging.homeButtonClick();
577
+ if (globals.webViewType != null) {
578
+ appsInTossEvent.emit("homeIconButtonClickEvent", void 0);
579
+ return;
580
+ }
581
+ navigation.navigate("/");
582
+ }, [logging, globals.webViewType, navigation]);
583
+ const handleBack = useCallback3(() => {
584
+ if (!overrideCanGoBack) {
585
+ backEventContext.onBack();
586
+ return;
587
+ }
588
+ handleBackOrClose();
589
+ }, [overrideCanGoBack, handleBackOrClose, backEventContext]);
590
+ const handleClose = useCallback3(async () => {
591
+ logging.closeButtonClick();
592
+ const isConfirmed = await openConfirm({
593
+ title: `${josa(globals.brandDisplayName, "\uC744/\uB97C")} \uC885\uB8CC\uD560\uAE4C\uC694?`,
594
+ leftButton: "\uCDE8\uC18C",
595
+ rightButton: "\uC885\uB8CC\uD558\uAE30",
596
+ closeOnDimmerClick: true,
597
+ onEntered: logging.closePopupShow
598
+ });
599
+ logging.closePopupCtaClick(isConfirmed);
600
+ if (isConfirmed) {
601
+ captureExitLog(Date.now());
602
+ closeView();
603
+ }
604
+ }, [captureExitLog, globals.brandDisplayName, logging, openConfirm]);
605
+ useEffect5(() => {
606
+ const backHandler = () => {
607
+ handleClose();
608
+ return true;
609
+ };
610
+ BackHandler.addEventListener("hardwareBackPress", backHandler);
611
+ return () => {
612
+ BackHandler.removeEventListener("hardwareBackPress", backHandler);
613
+ };
614
+ }, [handleClose]);
615
+ if (isExternalWebView) {
616
+ return /* @__PURE__ */ jsx3(Fragment3, {});
617
+ }
618
+ return /* @__PURE__ */ jsx3(BuiltinNavigationBarImpressionArea, { withHomeButton, children: /* @__PURE__ */ jsx3(
619
+ TopNavigation,
620
+ {
621
+ title: globals.brandDisplayName,
622
+ icon: toIcon(globals.brandIcon),
623
+ onPressDots: openMoreButtonBottomSheet,
624
+ contentVisible: isGameWebView ? false : true,
625
+ onPressTitle: withHomeButton ? handlePressTitle : void 0,
626
+ onPressClose: handleClose,
627
+ withHome: withHomeButton,
628
+ fixedRightButton: initialAccessoryButton ? {
629
+ title: initialAccessoryButton.title,
630
+ icon: initialAccessoryButton.icon,
631
+ id: initialAccessoryButton.id
632
+ } : void 0,
633
+ children: isGameWebView === false ? /* @__PURE__ */ jsx3(NavigationLeft, { visible: withBackButton, children: /* @__PURE__ */ jsx3(NavigationBackButton, { onPress: handleBack, canGoBack: false }) }) : null
634
+ }
635
+ ) });
636
+ }
637
+ function useBackOrCloseNavigation() {
638
+ const navigation = useNavigation();
639
+ return useCallback3(() => {
640
+ if (navigation.canGoBack()) {
641
+ navigation.goBack();
642
+ } else {
643
+ closeView();
644
+ }
645
+ }, [navigation]);
646
+ }
647
+ function BuiltinNavigationBarImpressionArea({
648
+ children,
649
+ withHomeButton
650
+ }) {
651
+ const hasLogged = useRef2(false);
652
+ const logging = useBuiltinNavigationBarLogging();
653
+ useEffect5(() => {
654
+ if (hasLogged.current === false) {
655
+ logging.navBarImpression({ home_icon_yn: withHomeButton ? "Y" : "N" });
656
+ hasLogged.current = true;
657
+ }
658
+ }, []);
659
+ return /* @__PURE__ */ jsx3(Fragment3, { children });
660
+ }
661
+
169
662
  // src/core/hooks/useAppsInTossBridge.ts
663
+ import { appsInTossEvent as appsInTossEvent2 } from "@apps-in-toss/native-modules";
664
+ import { useBridge } from "@toss-design-system/react-native";
665
+ import { useEffect as useEffect6 } from "react";
170
666
  function useAppsInTossBridge() {
171
667
  const controller = useBridge();
172
- const appsInTossGlobals2 = getAppsInTossGlobals();
173
- useEffect4(() => {
668
+ const appsInTossGlobals = getAppsInTossGlobals();
669
+ useEffect6(() => {
174
670
  const commonProps = {
175
- serviceName: appsInTossGlobals2.brandDisplayName,
176
- icon: toIcon(appsInTossGlobals2.brandIcon),
177
- color: appsInTossGlobals2.brandPrimaryColor,
178
- colorMode: appsInTossGlobals2.brandBridgeColorMode
671
+ serviceName: appsInTossGlobals.brandDisplayName,
672
+ icon: toIcon(appsInTossGlobals.brandIcon),
673
+ color: appsInTossGlobals.brandPrimaryColor,
674
+ colorMode: appsInTossGlobals.brandBridgeColorMode
179
675
  };
180
676
  controller.open({
181
677
  ...commonProps,
182
678
  onExited: () => {
183
- appsInTossEvent.emit("entryMessageExited", void 0);
679
+ appsInTossEvent2.emit("entryMessageExited", void 0);
184
680
  }
185
681
  });
186
682
  }, []);
187
683
  }
188
684
 
189
685
  // src/core/registerApp.tsx
190
- import { Fragment as Fragment2, jsx as jsx2, jsxs } from "react/jsx-runtime";
686
+ import { Fragment as Fragment4, jsx as jsx4, jsxs } from "react/jsx-runtime";
191
687
  function AppsInTossContainer(Container, { children, ...initialProps }) {
192
- if (!isMinVersionSupported({
688
+ if (!isMinVersionSupported2({
193
689
  android: "5.220.0",
194
690
  ios: "5.221.0"
195
691
  })) {
196
- return /* @__PURE__ */ jsxs(Fragment2, { children: [
197
- /* @__PURE__ */ jsx2(AppEvent.Entry, {}),
198
- /* @__PURE__ */ jsx2(AppEvent.System, { ...initialProps }),
199
- /* @__PURE__ */ jsx2(AppUpdate, {})
692
+ return /* @__PURE__ */ jsxs(Fragment4, { children: [
693
+ /* @__PURE__ */ jsx4(AppEvent.Entry, {}),
694
+ /* @__PURE__ */ jsx4(AppEvent.System, { ...initialProps }),
695
+ /* @__PURE__ */ jsx4(AppUpdate, {})
200
696
  ] });
201
697
  }
202
- return /* @__PURE__ */ jsxs(Fragment2, { children: [
203
- /* @__PURE__ */ jsx2(AppEvent.StayTime, {}),
204
- /* @__PURE__ */ jsx2(AppEvent.Entry, {}),
205
- /* @__PURE__ */ jsx2(AppEvent.System, { ...initialProps }),
206
- /* @__PURE__ */ jsx2(Container, { ...initialProps, children: /* @__PURE__ */ jsx2(TDSProvider, { colorPreference: "light", token: { color: { primary: getAppsInTossGlobals().brandPrimaryColor } }, children: /* @__PURE__ */ jsx2(TDSContainer, { ...initialProps, children }) }) })
698
+ return /* @__PURE__ */ jsxs(Fragment4, { children: [
699
+ /* @__PURE__ */ jsx4(AppEvent.StayTime, {}),
700
+ /* @__PURE__ */ jsx4(AppEvent.Entry, {}),
701
+ /* @__PURE__ */ jsx4(AppEvent.System, { ...initialProps }),
702
+ /* @__PURE__ */ jsx4(Container, { ...initialProps, children: /* @__PURE__ */ jsx4(TDSProvider, { colorPreference: "light", token: { color: { primary: getAppsInTossGlobals().brandPrimaryColor } }, children: /* @__PURE__ */ jsx4(TDSContainer, { ...initialProps, children }) }) })
207
703
  ] });
208
704
  }
209
705
  function TDSContainer({ children }) {
210
706
  useAppsInTossBridge();
211
- return /* @__PURE__ */ jsx2(Fragment2, { children });
707
+ return /* @__PURE__ */ jsx4(Fragment4, { children });
212
708
  }
213
709
  function registerApp(container, { context, analytics }) {
214
- Analytics.init({
215
- logger: (params) => void eventLog(params),
216
- debug: analytics?.debug ?? __DEV__
217
- });
218
- const App = Granite3.registerApp(AppsInTossContainer.bind(null, container), {
219
- appName: getAppName(),
220
- context,
221
- setIosSwipeGestureEnabled,
222
- router: {
223
- screenContainer: Analytics.Screen,
224
- defaultScreenOption: {
225
- statusBarStyle: "dark"
710
+ const appName = getAppName();
711
+ const isRegistered = AppRegistry.getAppKeys().includes(appName);
712
+ if (!isRegistered) {
713
+ Analytics.init({
714
+ logger: (params) => void eventLog(params),
715
+ debug: analytics?.debug ?? __DEV__
716
+ });
717
+ const App = Granite6.registerApp(AppsInTossContainer.bind(null, container), {
718
+ appName,
719
+ context,
720
+ setIosSwipeGestureEnabled,
721
+ router: {
722
+ screenContainer: AppsInTossScreenContainer,
723
+ defaultScreenOption: {
724
+ statusBarStyle: "dark"
725
+ }
226
726
  }
227
- }
228
- });
229
- global.Page = App;
230
- return App;
727
+ });
728
+ global.Page = App;
729
+ }
730
+ return global.Page;
731
+ }
732
+ function AppsInTossScreenContainer({ children }) {
733
+ return /* @__PURE__ */ jsxs(Analytics.Screen, { children: [
734
+ /* @__PURE__ */ jsx4(BuiltinNavigationBar, {}),
735
+ children
736
+ ] });
231
737
  }
232
738
  function getAppName() {
233
739
  try {
@@ -244,38 +750,30 @@ var AppsInToss = {
244
750
  };
245
751
 
246
752
  // src/components/WebView.tsx
247
- import { GoogleAdMob, IAP, Storage, AppsInTossModule, appsInTossEvent as appsInTossEvent3 } from "@apps-in-toss/native-modules";
753
+ import { GoogleAdMob, IAP, Storage, AppsInTossModule, appsInTossEvent as appsInTossEvent4 } from "@apps-in-toss/native-modules";
248
754
  import * as appsInTossAsyncBridges from "@apps-in-toss/native-modules/async-bridges";
249
755
  import * as appsInTossConstantBridges from "@apps-in-toss/native-modules/constant-bridges";
250
756
  import * as appsInTossEventBridges from "@apps-in-toss/native-modules/event-bridges";
251
757
  import { getSchemeUri as getSchemeUri5, useGraniteEvent } from "@granite-js/react-native";
252
758
  import * as graniteAsyncBridges from "@granite-js/react-native/async-bridges";
253
759
  import * as graniteConstantBridges from "@granite-js/react-native/constant-bridges";
254
- import {
255
- ExternalWebViewScreen,
256
- PartnerWebViewScreen,
257
- tdsEvent,
258
- usePartnerNavigation
259
- } from "@toss-design-system/react-native";
260
- import { useSafeAreaBottom, useSafeAreaTop as useSafeAreaTop2 } from "@toss-design-system/react-native/private";
261
- import { useCallback as useCallback5, useEffect as useEffect8, useMemo as useMemo3, useState as useState4 } from "react";
262
- import { BackHandler as BackHandler2, Platform as Platform6 } from "react-native";
760
+ import { ExternalWebViewScreen, tdsEvent } from "@toss-design-system/react-native";
761
+ import { useSafeAreaBottom, useSafeAreaTop, useTopNavigation } from "@toss-design-system/react-native/private";
762
+ import { useCallback as useCallback6, useEffect as useEffect10, useMemo as useMemo3, useState as useState5 } from "react";
763
+ import { BackHandler as BackHandler2, Platform as Platform3 } from "react-native";
263
764
 
264
765
  // src/components/GameWebView.tsx
265
- import { setIosSwipeGestureEnabled as setIosSwipeGestureEnabled2, appsInTossEvent as appsInTossEvent2, getOperationalEnvironment } from "@apps-in-toss/native-modules";
766
+ import { setIosSwipeGestureEnabled as setIosSwipeGestureEnabled2, appsInTossEvent as appsInTossEvent3, getOperationalEnvironment } from "@apps-in-toss/native-modules";
266
767
  import {
267
768
  WebView as PlainWebView
268
769
  } from "@granite-js/native/react-native-webview";
269
- import { closeView as closeView2 } from "@granite-js/react-native";
270
- import { useDialog as useDialog2 } from "@toss-design-system/react-native";
271
- import { josa as josa2 } from "es-hangul";
272
- import { forwardRef, useCallback as useCallback3, useEffect as useEffect6, useState as useState2 } from "react";
273
- import { BackHandler, Platform as Platform5 } from "react-native";
770
+ import { forwardRef, useEffect as useEffect8, useState as useState3 } from "react";
771
+ import { Platform as Platform2 } from "react-native";
274
772
 
275
773
  // src/components/GameProfile.tsx
276
- import { getGameCenterGameProfile as getGameCenterGameProfile2, isMinVersionSupported as isMinVersionSupported2 } from "@apps-in-toss/native-modules";
774
+ import { getGameCenterGameProfile as getGameCenterGameProfile2, isMinVersionSupported as isMinVersionSupported3 } from "@apps-in-toss/native-modules";
277
775
  import { Loader } from "@toss-design-system/react-native";
278
- import { useEffect as useEffect5 } from "react";
776
+ import { useEffect as useEffect7 } from "react";
279
777
  import { Pressable, View } from "react-native";
280
778
 
281
779
  // src/constant/game-center.ts
@@ -287,21 +785,21 @@ var GAME_CENTER_MIN_VERSION = {
287
785
 
288
786
  // src/hooks/useGameCenterProfile.ts
289
787
  import { getGameCenterGameProfile } from "@apps-in-toss/native-modules";
290
- import { closeView, openURL as openURL3 } from "@granite-js/react-native";
291
- import { useDialog } from "@toss-design-system/react-native";
292
- import { josa } from "es-hangul";
293
- import { useCallback as useCallback2, useRef as useRef2, useState } from "react";
788
+ import { closeView as closeView2, openURL as openURL5 } from "@granite-js/react-native";
789
+ import { useDialog as useDialog3 } from "@toss-design-system/react-native";
790
+ import { josa as josa2 } from "es-hangul";
791
+ import { useCallback as useCallback4, useRef as useRef3, useState as useState2 } from "react";
294
792
 
295
793
  // src/components/GameProfileToast.tsx
296
794
  import { Asset, Toast } from "@toss-design-system/react-native";
297
- import { AdaptiveColorProvider, ColorPreferenceProvider, useOverlay } from "@toss-design-system/react-native/private";
298
- import { jsx as jsx3 } from "react/jsx-runtime";
795
+ import { AdaptiveColorProvider, ColorPreferenceProvider, useOverlay as useOverlay2 } from "@toss-design-system/react-native/private";
796
+ import { jsx as jsx5 } from "react/jsx-runtime";
299
797
  var useGameProfileToast = () => {
300
- const overlay = useOverlay();
798
+ const overlay = useOverlay2();
301
799
  const openGameProfileToast = (nickname, profileImageUri) => {
302
800
  return new Promise((resolve) => {
303
801
  overlay.open(({ isOpen, close, exit }) => {
304
- return /* @__PURE__ */ jsx3(ColorPreferenceProvider, { colorPreference: "dark", children: /* @__PURE__ */ jsx3(AdaptiveColorProvider, { children: /* @__PURE__ */ jsx3(
802
+ return /* @__PURE__ */ jsx5(ColorPreferenceProvider, { colorPreference: "dark", children: /* @__PURE__ */ jsx5(AdaptiveColorProvider, { children: /* @__PURE__ */ jsx5(
305
803
  Toast,
306
804
  {
307
805
  open: isOpen,
@@ -312,7 +810,7 @@ var useGameProfileToast = () => {
312
810
  onExited: exit,
313
811
  position: "top",
314
812
  text: `${nickname}\uB2D8 \uBC18\uAC00\uC6CC\uC694!`,
315
- icon: /* @__PURE__ */ jsx3(
813
+ icon: /* @__PURE__ */ jsx5(
316
814
  Asset.Image,
317
815
  {
318
816
  style: { borderRadius: 64, overflow: "hidden" },
@@ -334,16 +832,8 @@ var DEFAULT_ERROR = {
334
832
  description: "\uBB38\uC81C\uAC00 \uACC4\uC18D\uB418\uBA74 \uD1A0\uC2A4 \uACE0\uAC1D\uC13C\uD130(1599-4905)\uB85C \uBB38\uC758\uD574\uC8FC\uC138\uC694."
335
833
  };
336
834
 
337
- // src/utils/market.ts
338
- import { Platform } from "react-native";
339
- var PLAYSTORE_LINK = "https://play.google.com/store/apps/details?id=viva.republica.toss";
340
- var APPSTORE_LINK = "https://itunes.apple.com/app/id839333328";
341
- var getMarketLink = () => {
342
- return Platform.OS === "android" ? PLAYSTORE_LINK : APPSTORE_LINK;
343
- };
344
-
345
835
  // src/utils/openTransparentWebView.ts
346
- import { openURL as openURL2 } from "@granite-js/react-native";
836
+ import { openURL as openURL4 } from "@granite-js/react-native";
347
837
 
348
838
  // src/private.ts
349
839
  import { onVisibilityChangedByTransparentServiceWeb } from "@apps-in-toss/native-modules";
@@ -377,29 +867,29 @@ var openTransparentWebView = ({
377
867
  }
378
868
  }
379
869
  });
380
- openURL2(url.toString());
870
+ openURL4(url.toString());
381
871
  };
382
872
 
383
873
  // src/hooks/useGameCenterProfile.ts
384
874
  var useGameCenterProfile = (isReadyForProfileUI) => {
385
- const [profileData, setProfileData] = useState(void 0);
386
- const [isProfileDataLoading, setIsProfileDataLoading] = useState(true);
387
- const [isProfileDataRefetching, setIsProfileDataRefetching] = useState(false);
875
+ const [profileData, setProfileData] = useState2(void 0);
876
+ const [isProfileDataLoading, setIsProfileDataLoading] = useState2(true);
877
+ const [isProfileDataRefetching, setIsProfileDataRefetching] = useState2(false);
388
878
  const shouldShowLoadingOverlay = isProfileDataLoading && isReadyForProfileUI;
389
879
  const shouldShowProfileNotFoundOverlay = profileData?.statusCode === "PROFILE_NOT_FOUND" && isReadyForProfileUI && !isProfileDataRefetching;
390
880
  const canShowBottomSheetOrToast = !isProfileDataLoading && isReadyForProfileUI;
391
- const [isWebviewLoading, setIsWebviewLoading] = useState(false);
392
- const isCompletedProfileFlow = useRef2(false);
393
- const { openAlert, openConfirm } = useDialog();
881
+ const [isWebviewLoading, setIsWebviewLoading] = useState2(false);
882
+ const isCompletedProfileFlow = useRef3(false);
883
+ const { openAlert, openConfirm } = useDialog3();
394
884
  const { openGameProfileToast } = useGameProfileToast();
395
- const openErrorAlert = useCallback2(async () => {
885
+ const openErrorAlert = useCallback4(async () => {
396
886
  await openAlert({
397
887
  title: DEFAULT_ERROR.title,
398
888
  description: DEFAULT_ERROR.description
399
889
  });
400
- closeView();
890
+ closeView2();
401
891
  }, [openAlert]);
402
- const openProfileWebview = useCallback2(() => {
892
+ const openProfileWebview = useCallback4(() => {
403
893
  if (isWebviewLoading) {
404
894
  return;
405
895
  }
@@ -428,9 +918,9 @@ var useGameCenterProfile = (isReadyForProfileUI) => {
428
918
  }
429
919
  });
430
920
  }, [isWebviewLoading, openGameProfileToast, openErrorAlert]);
431
- const updateAppToSupportedMinVersion = useCallback2(async () => {
921
+ const updateAppToSupportedMinVersion = useCallback4(async () => {
432
922
  const upddateConfirmDialogLabel = {
433
- title: `${josa(getAppsInTossGlobals().brandDisplayName, "\uC744/\uB97C")} \uD558\uB824\uBA74
923
+ title: `${josa2(getAppsInTossGlobals().brandDisplayName, "\uC744/\uB97C")} \uD558\uB824\uBA74
434
924
  \uC571\uC744 \uC5C5\uB370\uC774\uD2B8\uD574\uC8FC\uC138\uC694`,
435
925
  leftButton: "\uB2EB\uAE30",
436
926
  rightButton: "\uC5C5\uB370\uC774\uD2B8\uD558\uAE30"
@@ -442,11 +932,11 @@ var useGameCenterProfile = (isReadyForProfileUI) => {
442
932
  closeOnDimmerClick: true
443
933
  });
444
934
  if (!isConfirmed) {
445
- closeView();
935
+ closeView2();
446
936
  return;
447
937
  }
448
938
  const STORE_SCHEME = getMarketLink();
449
- openURL3(`supertoss://web?url=${STORE_SCHEME}&external=browser`);
939
+ openURL5(`supertoss://web?url=${STORE_SCHEME}&external=browser`);
450
940
  }, [openConfirm]);
451
941
  return {
452
942
  profileData,
@@ -475,7 +965,7 @@ var Z_INDEX = {
475
965
  };
476
966
 
477
967
  // src/components/GameProfile.tsx
478
- import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
968
+ import { Fragment as Fragment5, jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
479
969
  var GameProfile = ({ children, isReadyForProfileUI }) => {
480
970
  const {
481
971
  profileData,
@@ -491,7 +981,7 @@ var GameProfile = ({ children, isReadyForProfileUI }) => {
491
981
  openErrorAlert,
492
982
  openGameProfileToast
493
983
  } = useGameCenterProfile(isReadyForProfileUI);
494
- useEffect5(() => {
984
+ useEffect7(() => {
495
985
  try {
496
986
  const getProfileData = async () => {
497
987
  const data = await getGameCenterGameProfile2();
@@ -504,7 +994,7 @@ var GameProfile = ({ children, isReadyForProfileUI }) => {
504
994
  setIsProfileDataLoading(false);
505
995
  }
506
996
  }, []);
507
- useEffect5(() => {
997
+ useEffect7(() => {
508
998
  const handleGameProfileFlow = async () => {
509
999
  if (!canShowBottomSheetOrToast) {
510
1000
  return;
@@ -513,7 +1003,7 @@ var GameProfile = ({ children, isReadyForProfileUI }) => {
513
1003
  return;
514
1004
  }
515
1005
  isCompletedProfileFlow.current = true;
516
- if (!isMinVersionSupported2(GAME_CENTER_MIN_VERSION)) {
1006
+ if (!isMinVersionSupported3(GAME_CENTER_MIN_VERSION)) {
517
1007
  updateAppToSupportedMinVersion();
518
1008
  return;
519
1009
  }
@@ -534,10 +1024,10 @@ var GameProfile = ({ children, isReadyForProfileUI }) => {
534
1024
  profileData,
535
1025
  updateAppToSupportedMinVersion
536
1026
  ]);
537
- if (!isMinVersionSupported2(GAME_CENTER_MIN_VERSION)) {
538
- return /* @__PURE__ */ jsxs2(Fragment3, { children: [
539
- /* @__PURE__ */ jsx4(View, { style: { flex: 1, position: "relative" }, children }),
540
- /* @__PURE__ */ jsx4(
1027
+ if (!isMinVersionSupported3(GAME_CENTER_MIN_VERSION)) {
1028
+ return /* @__PURE__ */ jsxs2(Fragment5, { children: [
1029
+ /* @__PURE__ */ jsx6(View, { style: { flex: 1, position: "relative" }, children }),
1030
+ /* @__PURE__ */ jsx6(
541
1031
  Pressable,
542
1032
  {
543
1033
  style: {
@@ -551,9 +1041,9 @@ var GameProfile = ({ children, isReadyForProfileUI }) => {
551
1041
  ] });
552
1042
  }
553
1043
  if (shouldShowLoadingOverlay || isProfileDataRefetching) {
554
- return /* @__PURE__ */ jsxs2(Fragment3, { children: [
555
- /* @__PURE__ */ jsx4(View, { style: { flex: 1, position: "relative" }, children }),
556
- /* @__PURE__ */ jsx4(
1044
+ return /* @__PURE__ */ jsxs2(Fragment5, { children: [
1045
+ /* @__PURE__ */ jsx6(View, { style: { flex: 1, position: "relative" }, children }),
1046
+ /* @__PURE__ */ jsx6(
557
1047
  View,
558
1048
  {
559
1049
  style: {
@@ -562,15 +1052,15 @@ var GameProfile = ({ children, isReadyForProfileUI }) => {
562
1052
  alignItems: "center",
563
1053
  backgroundColor: "rgba(0, 0, 0, 0.2)"
564
1054
  },
565
- children: /* @__PURE__ */ jsx4(Loader, { size: "large", type: "light" })
1055
+ children: /* @__PURE__ */ jsx6(Loader, { size: "large", type: "light" })
566
1056
  }
567
1057
  )
568
1058
  ] });
569
1059
  }
570
1060
  if (shouldShowProfileNotFoundOverlay) {
571
- return /* @__PURE__ */ jsxs2(Fragment3, { children: [
572
- /* @__PURE__ */ jsx4(View, { style: { flex: 1, position: "relative" }, children }),
573
- shouldShowProfileNotFoundOverlay && /* @__PURE__ */ jsx4(
1061
+ return /* @__PURE__ */ jsxs2(Fragment5, { children: [
1062
+ /* @__PURE__ */ jsx6(View, { style: { flex: 1, position: "relative" }, children }),
1063
+ shouldShowProfileNotFoundOverlay && /* @__PURE__ */ jsx6(
574
1064
  Pressable,
575
1065
  {
576
1066
  style: {
@@ -583,7 +1073,7 @@ var GameProfile = ({ children, isReadyForProfileUI }) => {
583
1073
  )
584
1074
  ] });
585
1075
  }
586
- return /* @__PURE__ */ jsx4(Fragment3, { children: /* @__PURE__ */ jsx4(View, { style: { flex: 1, position: "relative" }, children }) });
1076
+ return /* @__PURE__ */ jsx6(Fragment5, { children: /* @__PURE__ */ jsx6(View, { style: { flex: 1, position: "relative" }, children }) });
587
1077
  };
588
1078
  var overlayStyle = {
589
1079
  position: "absolute",
@@ -594,123 +1084,12 @@ var overlayStyle = {
594
1084
  zIndex: Z_INDEX.PROFILE_OVERLAY
595
1085
  };
596
1086
 
597
- // src/components/GameWebViewNavigationBar/GameNavigationBar.tsx
598
- import { SvgXml } from "@granite-js/native/react-native-svg";
599
- import { PageNavbar } from "@toss-design-system/react-native";
600
- import { Platform as Platform4, TouchableOpacity, View as View3 } from "react-native";
601
-
602
- // src/components/GameWebViewNavigationBar/HeaderRight.tsx
603
- import { StyleSheet, View as View2 } from "react-native";
604
-
605
- // src/components/GameWebViewNavigationBar/byPlatform.ts
606
- import { Platform as Platform2 } from "react-native";
607
- function byPlatform({
608
- ...props
609
- }) {
610
- return (props[Platform2.OS] ?? props.fallback)();
611
- }
612
-
613
- // src/components/GameWebViewNavigationBar/constants.ts
614
- var RIGHT_MARGIN = 24;
615
- var IOS_DEFAULT_MARGIN = 20;
616
-
617
- // src/components/GameWebViewNavigationBar/HeaderRight.tsx
618
- import { jsx as jsx5 } from "react/jsx-runtime";
619
- function IOSHeaderRight(props) {
620
- return /* @__PURE__ */ jsx5(View2, { style: styles.ios, ...props });
621
- }
622
- function AndroidHeaderRight(props) {
623
- return /* @__PURE__ */ jsx5(View2, { style: styles.android, ...props });
624
- }
625
- function HeaderRight(props) {
626
- return byPlatform({
627
- ios: () => /* @__PURE__ */ jsx5(IOSHeaderRight, { ...props }),
628
- android: () => /* @__PURE__ */ jsx5(AndroidHeaderRight, { ...props }),
629
- fallback: () => /* @__PURE__ */ jsx5(IOSHeaderRight, { ...props })
630
- });
631
- }
632
- var styles = StyleSheet.create({
633
- ios: {
634
- marginRight: -IOS_DEFAULT_MARGIN + RIGHT_MARGIN,
635
- flexDirection: "row"
636
- },
637
- android: {
638
- flexDirection: "row"
639
- }
640
- });
641
-
642
- // src/components/GameWebViewNavigationBar/useSafeAreaTop.ts
643
- import { useSafeAreaInsets } from "@granite-js/native/react-native-safe-area-context";
644
- import { Platform as Platform3 } from "react-native";
645
- function useSafeAreaTop() {
646
- const safeAreaInsets = useSafeAreaInsets();
647
- const hasDynamicIsland = Platform3.OS === "ios" && safeAreaInsets.top > 50;
648
- const safeAreaTop = hasDynamicIsland ? safeAreaInsets.top - 5 : safeAreaInsets.top;
649
- return safeAreaTop;
650
- }
651
-
652
- // src/components/GameWebViewNavigationBar/GameNavigationBar.tsx
653
- import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
654
- var originXML = '<svg fill="none" height="30" viewBox="0 0 30 30" width="30" xmlns="https://www.w3.org/2000/svg"><rect fill="#031832" fill-opacity=".46" height="30" rx="15" width="30"/><rect height="29.5" rx="14.75" stroke="#d9d9ff" stroke-opacity=".11" stroke-width=".5" width="29.5" x=".25" y=".25"/><path clip-rule="evenodd" d="m16.5119 15.0014 4.7092-4.7092c.0929-.0928.1666-.2031.2169-.32441.0503-.12134.0762-.25141.0762-.38276.0001-.13136-.0258-.26144-.076-.38281s-.1239-.23166-.2167-.32457c-.0929-.09291-.2031-.16662-.3245-.21692-.1213-.05031-.2514-.07622-.3827-.07626-.1314-.00004-.2615.0258-.3828.07603-.1214.05023-.2317.12388-.3246.21673l-4.7092 4.70997-4.71-4.70997c-.1897-.17718-.4408-.27373-.70034-.26927s-.5072.10959-.69069.2932c-.1835.1836-.28848.43132-.29279.69087-.00432.25954.09238.51057.26968.70017l4.71004 4.7092-4.71004 4.7092c-.1392.1401-.23385.3183-.27204.5121-.0382.1939-.01823.3946.05739.5771s.20351.3386.36759.4486.35702.169.55456.1697c.25583 0 .51164-.0975.70664-.2925l4.71-4.71 4.7092 4.71c.0927.093.2029.1668.3243.2172.1213.0504.2514.0763.3828.0763s.2614-.0259.3828-.0763c.1213-.0504.2315-.1242.3243-.2172.0929-.0929.1667-.2032.217-.3246s.0762-.2515.0762-.3829-.0259-.2616-.0762-.383-.1241-.2317-.217-.3245z" fill="#fdfdfe" fill-opacity=".89" fill-rule="evenodd"/></svg>';
655
- function GameNavigationBar({ onClose }) {
656
- const safeAreaTop = useSafeAreaTop();
657
- return /* @__PURE__ */ jsxs3(Fragment4, { children: [
658
- /* @__PURE__ */ jsx6(PageNavbar, { preference: { type: "none" } }),
659
- /* @__PURE__ */ jsx6(
660
- View3,
661
- {
662
- style: {
663
- width: "100%",
664
- height: Platform4.OS === "ios" ? 44 : 54,
665
- flexDirection: "row",
666
- alignItems: "center",
667
- justifyContent: "flex-end",
668
- position: "absolute",
669
- zIndex: Z_INDEX.CLOSE_BUTTON,
670
- marginTop: safeAreaTop,
671
- paddingRight: Platform4.OS === "ios" ? 10 : 8
672
- },
673
- pointerEvents: "box-none",
674
- children: /* @__PURE__ */ jsx6(HeaderRight, { children: /* @__PURE__ */ jsx6(
675
- TouchableOpacity,
676
- {
677
- hitSlop: { left: 8, right: 8 },
678
- accessibilityRole: "button",
679
- accessible: true,
680
- accessibilityLabel: "\uAC8C\uC784\uC885\uB8CC",
681
- style: {
682
- padding: Platform4.OS === "ios" ? 7 : 9
683
- },
684
- onPress: onClose,
685
- children: /* @__PURE__ */ jsx6(SvgXml, { xml: originXML, width: 30, height: 30 })
686
- }
687
- ) })
688
- }
689
- )
690
- ] });
691
- }
692
-
693
1087
  // src/components/GameWebView.tsx
694
- import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
1088
+ import { Fragment as Fragment6, jsx as jsx7 } from "react/jsx-runtime";
695
1089
  var GameWebView = forwardRef(function GameWebView2(props, ref) {
696
- const { openConfirm } = useDialog2();
697
- const { brandDisplayName } = getAppsInTossGlobals();
698
- const { captureExitLog } = useCaptureExitLog();
699
- const [isEntryMessageExited, setIsEntryMessageExited] = useState2(false);
700
- const handleClose = useCallback3(async () => {
701
- const isConfirmed = await openConfirm({
702
- title: `${josa2(brandDisplayName, "\uC744/\uB97C")} \uC885\uB8CC\uD560\uAE4C\uC694?`,
703
- leftButton: "\uCDE8\uC18C",
704
- rightButton: "\uC885\uB8CC\uD558\uAE30",
705
- closeOnDimmerClick: true
706
- });
707
- if (isConfirmed) {
708
- captureExitLog(Date.now());
709
- closeView2();
710
- }
711
- }, [brandDisplayName, captureExitLog, openConfirm]);
712
- useEffect6(() => {
713
- if (Platform5.OS === "ios") {
1090
+ const [isEntryMessageExited, setIsEntryMessageExited] = useState3(false);
1091
+ useEffect8(() => {
1092
+ if (Platform2.OS === "ios") {
714
1093
  setIosSwipeGestureEnabled2({ isEnabled: false });
715
1094
  return () => {
716
1095
  setIosSwipeGestureEnabled2({ isEnabled: true });
@@ -718,31 +1097,47 @@ var GameWebView = forwardRef(function GameWebView2(props, ref) {
718
1097
  }
719
1098
  return;
720
1099
  }, []);
721
- useEffect6(() => {
722
- const backHandler = () => {
723
- handleClose();
724
- return true;
725
- };
726
- BackHandler.addEventListener("hardwareBackPress", backHandler);
727
- return () => {
728
- BackHandler.removeEventListener("hardwareBackPress", backHandler);
729
- };
730
- }, [handleClose]);
731
- useEffect6(() => {
732
- appsInTossEvent2.addEventListener("entryMessageExited", {
1100
+ useEffect8(() => {
1101
+ appsInTossEvent3.addEventListener("entryMessageExited", {
733
1102
  onEvent: () => {
734
1103
  setIsEntryMessageExited(true);
735
1104
  }
736
1105
  });
737
1106
  }, []);
738
- return /* @__PURE__ */ jsxs4(Fragment5, { children: [
739
- /* @__PURE__ */ jsx7(GameNavigationBar, { onClose: handleClose }),
740
- getOperationalEnvironment() === "toss" ? /* @__PURE__ */ jsx7(GameProfile, { isReadyForProfileUI: isEntryMessageExited, children: /* @__PURE__ */ jsx7(PlainWebView, { ref, ...props }) }) : /* @__PURE__ */ jsx7(PlainWebView, { ref, ...props })
741
- ] });
1107
+ return /* @__PURE__ */ jsx7(Fragment6, { children: getOperationalEnvironment() === "toss" ? /* @__PURE__ */ jsx7(GameProfile, { isReadyForProfileUI: isEntryMessageExited, children: /* @__PURE__ */ jsx7(PlainWebView, { ref, ...props }) }) : /* @__PURE__ */ jsx7(PlainWebView, { ref, ...props }) });
742
1108
  });
743
1109
 
1110
+ // src/components/PartnerWebView.tsx
1111
+ import {
1112
+ WebView as PlainWebView2
1113
+ } from "@granite-js/native/react-native-webview";
1114
+ import { forwardRef as forwardRef2, useRef as useRef4 } from "react";
1115
+
1116
+ // src/core/utils/mergeRefs.ts
1117
+ function mergeRefs(...refs) {
1118
+ return (value) => {
1119
+ refs.forEach((ref) => {
1120
+ if (typeof ref === "function") {
1121
+ ref(value);
1122
+ } else if (ref != null) {
1123
+ ref.current = value;
1124
+ }
1125
+ });
1126
+ };
1127
+ }
1128
+
1129
+ // src/components/PartnerWebView.tsx
1130
+ import { jsx as jsx8 } from "react/jsx-runtime";
1131
+ var PartnerWebView = forwardRef2(
1132
+ function PartnerWebViewScreen(webViewProps, ref) {
1133
+ const webViewRef = useRef4(null);
1134
+ const refs = mergeRefs(ref, webViewRef);
1135
+ return /* @__PURE__ */ jsx8(PlainWebView2, { ref: refs, ...webViewProps, style: { flex: 1 } });
1136
+ }
1137
+ );
1138
+
744
1139
  // src/bridge-handler/useBridgeHandler.tsx
745
- import { useCallback as useCallback4, useMemo as useMemo2, useRef as useRef3 } from "react";
1140
+ import { useCallback as useCallback5, useMemo as useMemo2, useRef as useRef5 } from "react";
746
1141
  function serializeError(error) {
747
1142
  return JSON.stringify(error, (_, value) => {
748
1143
  if (value instanceof Error) {
@@ -791,7 +1186,7 @@ function useBridgeHandler({
791
1186
  eventListenerMap,
792
1187
  injectedJavaScript: originalInjectedJavaScript
793
1188
  }) {
794
- const ref = useRef3(null);
1189
+ const ref = useRef5(null);
795
1190
  const injectedJavaScript = useMemo2(
796
1191
  () => [
797
1192
  `window.__CONSTANT_HANDLER_MAP = ${JSON.stringify(
@@ -818,7 +1213,7 @@ function useBridgeHandler({
818
1213
  window.__GRANITE_NATIVE_EMITTER.emit('${functionName}/onError/${eventId}', ${JSON.stringify(error, null, 0)});
819
1214
  `);
820
1215
  };
821
- const $onMessage = useCallback4(
1216
+ const $onMessage = useCallback5(
822
1217
  async (e) => {
823
1218
  onMessage?.(e);
824
1219
  const data = JSON.parse(e.nativeEvent.data);
@@ -1027,11 +1422,11 @@ function useCreateUserAgent({
1027
1422
  // src/hooks/useGeolocation.ts
1028
1423
  import { startUpdateLocation } from "@apps-in-toss/native-modules";
1029
1424
  import { useVisibility as useVisibility3 } from "@granite-js/react-native";
1030
- import { useState as useState3, useEffect as useEffect7 } from "react";
1425
+ import { useState as useState4, useEffect as useEffect9 } from "react";
1031
1426
  function useGeolocation({ accuracy, distanceInterval, timeInterval }) {
1032
1427
  const isVisible = useVisibility3();
1033
- const [location, setLocation] = useState3(null);
1034
- useEffect7(() => {
1428
+ const [location, setLocation] = useState4(null);
1429
+ useEffect9(() => {
1035
1430
  if (!isVisible) {
1036
1431
  return;
1037
1432
  }
@@ -1098,12 +1493,11 @@ var trackScreen = (url) => {
1098
1493
  };
1099
1494
 
1100
1495
  // src/components/WebView.tsx
1101
- import { jsx as jsx8 } from "react/jsx-runtime";
1102
- var appsInTossGlobals = getAppsInTossGlobals();
1496
+ import { jsx as jsx9 } from "react/jsx-runtime";
1103
1497
  var operationalEnvironment = appsInTossConstantBridges.getOperationalEnvironment();
1104
1498
  var TYPES = ["partner", "external", "game"];
1105
1499
  var WEBVIEW_TYPES = {
1106
- partner: PartnerWebViewScreen,
1500
+ partner: PartnerWebView,
1107
1501
  external: ExternalWebViewScreen,
1108
1502
  game: GameWebView
1109
1503
  };
@@ -1135,10 +1529,10 @@ function WebView({ type, local, onMessage, ...props }) {
1135
1529
  }
1136
1530
  const graniteEvent = useGraniteEvent();
1137
1531
  const uri = useMemo3(() => getWebViewUri(local), [local]);
1138
- const top = useSafeAreaTop2();
1532
+ const top = useSafeAreaTop();
1139
1533
  const bottom = useSafeAreaBottom();
1140
1534
  const global2 = getAppsInTossGlobals();
1141
- const partner = usePartnerNavigation();
1535
+ const topNavigation = useTopNavigation();
1142
1536
  const disableTextSelectionCSS = `
1143
1537
  (function() {
1144
1538
  const style = document.createElement('style');
@@ -1146,7 +1540,7 @@ function WebView({ type, local, onMessage, ...props }) {
1146
1540
  document.head.appendChild(style);
1147
1541
  })();
1148
1542
  `;
1149
- const [allowsBackForwardNavigationGestures, setAllowsBackForwardNavigationGestures] = useState4(
1543
+ const [allowsBackForwardNavigationGestures, setAllowsBackForwardNavigationGestures] = useState5(
1150
1544
  props.allowsBackForwardNavigationGestures
1151
1545
  );
1152
1546
  const handler = useBridgeHandler({
@@ -1155,20 +1549,20 @@ function WebView({ type, local, onMessage, ...props }) {
1155
1549
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1156
1550
  eventListenerMap: {
1157
1551
  ...appsInTossEventBridges,
1158
- navigationAccessoryEvent: ({ onEvent, onError }) => tdsEvent.addEventListener("navigationAccessoryEvent", {
1159
- onEvent,
1160
- onError
1161
- }),
1552
+ navigationAccessoryEvent: ({ onEvent, onError }) => tdsEvent.addEventListener("navigationAccessoryEvent", { onEvent, onError }),
1162
1553
  backEvent: ({ onEvent, onError, options }) => graniteEvent.addEventListener("backEvent", { onEvent, onError, options }),
1163
- entryMessageExited: ({ onEvent, onError }) => appsInTossEvent3.addEventListener("entryMessageExited", { onEvent, onError }),
1164
- updateLocationEvent: ({ onEvent, onError, options }) => appsInTossEvent3.addEventListener("updateLocationEvent", { onEvent, onError, options }),
1554
+ entryMessageExited: ({ onEvent, onError }) => appsInTossEvent4.addEventListener("entryMessageExited", { onEvent, onError }),
1555
+ updateLocationEvent: ({ onEvent, onError, options }) => appsInTossEvent4.addEventListener("updateLocationEvent", { onEvent, onError, options }),
1165
1556
  /** @internal */
1166
- appBridgeCallbackEvent: ({ onEvent, onError, options }) => appsInTossEvent3.addEventListener("appBridgeCallbackEvent", { onEvent, onError, options }),
1557
+ appBridgeCallbackEvent: ({ onEvent, onError, options }) => appsInTossEvent4.addEventListener("appBridgeCallbackEvent", { onEvent, onError, options }),
1167
1558
  /** AdMob */
1168
1559
  loadAdMobInterstitialAd: GoogleAdMob.loadAdMobInterstitialAd,
1169
1560
  showAdMobInterstitialAd: GoogleAdMob.showAdMobInterstitialAd,
1170
1561
  loadAdMobRewardedAd: GoogleAdMob.loadAdMobRewardedAd,
1171
- showAdMobRewardedAd: GoogleAdMob.showAdMobRewardedAd
1562
+ showAdMobRewardedAd: GoogleAdMob.showAdMobRewardedAd,
1563
+ /** AdMobV2 */
1564
+ loadAppsInTossAdMob: GoogleAdMob.loadAppsInTossAdMob,
1565
+ showAppsInTossAdMob: GoogleAdMob.showAppsInTossAdMob
1172
1566
  },
1173
1567
  constantHandlerMap: {
1174
1568
  ...graniteConstantBridges,
@@ -1181,6 +1575,9 @@ function WebView({ type, local, onMessage, ...props }) {
1181
1575
  showAdMobInterstitialAd_isSupported: GoogleAdMob.showAdMobInterstitialAd.isSupported,
1182
1576
  loadAdMobRewardedAd_isSupported: GoogleAdMob.loadAdMobRewardedAd.isSupported,
1183
1577
  showAdMobRewardedAd_isSupported: GoogleAdMob.showAdMobRewardedAd.isSupported,
1578
+ /** AdMobV2 */
1579
+ loadAppsInTossAdMob_isSupported: GoogleAdMob.loadAppsInTossAdMob.isSupported,
1580
+ showAppsInTossAdMob_isSupported: GoogleAdMob.showAppsInTossAdMob.isSupported,
1184
1581
  /** env */
1185
1582
  getDeploymentId: env.getDeploymentId
1186
1583
  },
@@ -1191,8 +1588,8 @@ function WebView({ type, local, onMessage, ...props }) {
1191
1588
  setAllowsBackForwardNavigationGestures(options.isEnabled);
1192
1589
  return appsInTossAsyncBridges.setIosSwipeGestureEnabled(options);
1193
1590
  },
1194
- addAccessoryButton: async (params) => partner.addAccessoryButton(params),
1195
- removeAccessoryButton: async () => partner.removeAccessoryButton(),
1591
+ addAccessoryButton: async (params) => topNavigation.addAccessoryButton(params),
1592
+ removeAccessoryButton: async () => topNavigation.removeAccessoryButton(),
1196
1593
  /** internal */
1197
1594
  openPermissionDialog: AppsInTossModule.openPermissionDialog,
1198
1595
  /** Storage */
@@ -1205,37 +1602,25 @@ function WebView({ type, local, onMessage, ...props }) {
1205
1602
  iapGetProductItemList: IAP.getProductItemList
1206
1603
  }
1207
1604
  });
1208
- const baseProps = useMemo3(() => {
1209
- switch (type) {
1210
- case "partner": {
1211
- const headerOnlyProp = {
1212
- header: {
1213
- ..."header" in props ? props.header : {},
1214
- icon: toIcon(ensureValue(appsInTossGlobals.brandIcon, "icon")),
1215
- title: ensureValue(appsInTossGlobals.brandDisplayName, "displayName")
1216
- }
1217
- };
1218
- return headerOnlyProp;
1219
- }
1220
- case "external": {
1221
- const headerOnlyProp = {
1222
- header: {
1223
- ..."header" in props ? props.header : {},
1224
- icon: toIcon(ensureValue(appsInTossGlobals.brandIcon, "icon")),
1225
- title: ensureValue(appsInTossGlobals.brandDisplayName, "displayName")
1226
- }
1227
- };
1228
- return headerOnlyProp;
1229
- }
1230
- default: {
1231
- return {};
1232
- }
1605
+ const headerPropForExternalWebView = useMemo3(() => {
1606
+ const parsedNavigationBar = global2.navigationBar != null ? safeParseNavigationBar(global2.navigationBar) : null;
1607
+ const initialAccessoryButton = parsedNavigationBar?.initialAccessoryButton;
1608
+ const withBackButton = parsedNavigationBar?.withBackButton ?? true;
1609
+ if (type === "external" && initialAccessoryButton != null) {
1610
+ return {
1611
+ header: {
1612
+ withBackButton,
1613
+ title: initialAccessoryButton.title,
1614
+ icon: initialAccessoryButton.icon
1615
+ }
1616
+ };
1233
1617
  }
1234
- }, [type, props]);
1618
+ return {};
1619
+ }, [global2.navigationBar, type]);
1235
1620
  const BaseWebView = WEBVIEW_TYPES[type];
1236
1621
  const webViewDebuggingEnabled = operationalEnvironment === "sandbox";
1237
- const [canHistoryGoBack, setCanHistoryGoBack] = useState4(false);
1238
- const handleNavigationStateChange = useCallback5(
1622
+ const [canHistoryGoBack, setCanHistoryGoBack] = useState5(false);
1623
+ const handleNavigationStateChange = useCallback6(
1239
1624
  (event) => {
1240
1625
  if (event.url) {
1241
1626
  trackScreen(event.url);
@@ -1247,7 +1632,7 @@ function WebView({ type, local, onMessage, ...props }) {
1247
1632
  const userAgent = useCreateUserAgent({
1248
1633
  colorPreference: "light"
1249
1634
  });
1250
- const handleBackEvent = useCallback5(() => {
1635
+ const handleBackEvent = useCallback6(() => {
1251
1636
  if (canHistoryGoBack) {
1252
1637
  handler.ref.current?.goBack();
1253
1638
  return true;
@@ -1255,16 +1640,28 @@ function WebView({ type, local, onMessage, ...props }) {
1255
1640
  return false;
1256
1641
  }
1257
1642
  }, [canHistoryGoBack, handler]);
1258
- useEffect8(() => {
1643
+ useEffect10(() => {
1259
1644
  BackHandler2.addEventListener("hardwareBackPress", handleBackEvent);
1260
1645
  return () => BackHandler2.removeEventListener("hardwareBackPress", handleBackEvent);
1261
1646
  }, [handleBackEvent]);
1262
- return /* @__PURE__ */ jsx8(
1647
+ useEffect10(() => {
1648
+ return appsInTossEvent4.addEventListener("homeIconButtonClickEvent", {
1649
+ onEvent: () => {
1650
+ handler.ref?.current?.injectJavaScript(`
1651
+ (function() {
1652
+ window.history.replaceState(null, '', '/');
1653
+ true;
1654
+ })();
1655
+ `);
1656
+ }
1657
+ });
1658
+ }, [handler.ref]);
1659
+ return /* @__PURE__ */ jsx9(
1263
1660
  BaseWebView,
1264
1661
  {
1265
1662
  ref: handler.ref,
1266
1663
  ...props,
1267
- ...baseProps,
1664
+ ...headerPropForExternalWebView,
1268
1665
  source: {
1269
1666
  uri,
1270
1667
  // NOTE: https://github.com/react-native-webview/react-native-webview/pull/3133
@@ -1272,7 +1669,7 @@ function WebView({ type, local, onMessage, ...props }) {
1272
1669
  "User-Agent": userAgent
1273
1670
  }
1274
1671
  },
1275
- userAgent: Platform6.OS === "ios" ? userAgent : void 0,
1672
+ userAgent: Platform3.OS === "ios" ? userAgent : void 0,
1276
1673
  sharedCookiesEnabled: true,
1277
1674
  webviewDebuggingEnabled: webViewDebuggingEnabled,
1278
1675
  thirdPartyCookiesEnabled: true,
@@ -1280,20 +1677,15 @@ function WebView({ type, local, onMessage, ...props }) {
1280
1677
  onNavigationStateChange: handleNavigationStateChange,
1281
1678
  injectedJavaScript: handler.injectedJavaScript,
1282
1679
  injectedJavaScriptBeforeContentLoaded: handler.injectedJavaScript,
1283
- decelerationRate: Platform6.OS === "ios" ? 1 : void 0,
1680
+ decelerationRate: Platform3.OS === "ios" ? 1 : void 0,
1284
1681
  allowsBackForwardNavigationGestures
1285
1682
  }
1286
1683
  );
1287
1684
  }
1288
- function ensureValue(value, name) {
1289
- if (value === void 0) {
1290
- throw new Error(`${name} is required`);
1291
- }
1292
- return value;
1293
- }
1294
1685
 
1295
1686
  // src/index.ts
1296
1687
  export * from "@apps-in-toss/analytics";
1688
+ import { useTopNavigation as useTopNavigation2 } from "@toss-design-system/react-native/private";
1297
1689
  export * from "@apps-in-toss/native-modules";
1298
1690
  var Analytics2 = {
1299
1691
  init: InternalAnalytics.init,
@@ -1308,5 +1700,6 @@ export {
1308
1700
  WebView,
1309
1701
  env,
1310
1702
  useCreateUserAgent,
1311
- useGeolocation
1703
+ useGeolocation,
1704
+ useTopNavigation2 as useTopNavigation
1312
1705
  };