@apps-in-toss/framework 1.2.2 → 1.4.0
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 +1037 -892
- package/dist/index.js +800 -638
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __copyProps = (to, from, except, desc) => {
|
|
6
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
+
for (let key of __getOwnPropNames(from))
|
|
8
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
10
|
+
}
|
|
11
|
+
return to;
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
14
|
+
|
|
1
15
|
// src/index.ts
|
|
2
16
|
import { Analytics as InternalAnalytics } from "@apps-in-toss/analytics";
|
|
3
17
|
|
|
4
18
|
// src/core/registerApp.tsx
|
|
5
19
|
import { Analytics } from "@apps-in-toss/analytics";
|
|
6
|
-
import { isMinVersionSupported as
|
|
20
|
+
import { isMinVersionSupported as isMinVersionSupported3, setIosSwipeGestureEnabled as setIosSwipeGestureEnabled2, eventLog } from "@apps-in-toss/native-modules";
|
|
7
21
|
import { Granite as Granite6 } from "@granite-js/react-native";
|
|
8
22
|
import { TDSProvider } from "@toss/tds-react-native";
|
|
9
23
|
import { AppRegistry } from "react-native";
|
|
@@ -172,14 +186,12 @@ function useAppsInTossBridge() {
|
|
|
172
186
|
const controller = useBridge();
|
|
173
187
|
const appsInTossGlobals = getAppsInTossGlobals();
|
|
174
188
|
useEffect4(() => {
|
|
175
|
-
const
|
|
189
|
+
const isGameApp = appsInTossGlobals.webViewType === "game" || appsInTossGlobals.appType === "game";
|
|
190
|
+
controller.open({
|
|
176
191
|
serviceName: appsInTossGlobals.brandDisplayName,
|
|
177
192
|
icon: toIcon(appsInTossGlobals.brandIcon),
|
|
178
193
|
color: appsInTossGlobals.brandPrimaryColor,
|
|
179
|
-
colorMode: appsInTossGlobals.brandBridgeColorMode
|
|
180
|
-
};
|
|
181
|
-
controller.open({
|
|
182
|
-
...commonProps,
|
|
194
|
+
colorMode: isGameApp ? "inverted" : appsInTossGlobals.brandBridgeColorMode,
|
|
183
195
|
onExited: () => {
|
|
184
196
|
appsInTossEvent.emit("entryMessageExited", void 0);
|
|
185
197
|
}
|
|
@@ -187,20 +199,494 @@ function useAppsInTossBridge() {
|
|
|
187
199
|
}, []);
|
|
188
200
|
}
|
|
189
201
|
|
|
190
|
-
// src/components/
|
|
191
|
-
import {
|
|
192
|
-
import {
|
|
193
|
-
import {
|
|
202
|
+
// src/components/RNAppContainer.tsx
|
|
203
|
+
import { appsInTossEvent as appsInTossEvent2, setIosSwipeGestureEnabled } from "@apps-in-toss/native-modules";
|
|
204
|
+
import { useEffect as useEffect9, useState as useState4 } from "react";
|
|
205
|
+
import { Platform as Platform3 } from "react-native";
|
|
206
|
+
|
|
207
|
+
// src/components/GameInitializer.tsx
|
|
208
|
+
import { isMinVersionSupported } from "@apps-in-toss/native-modules";
|
|
209
|
+
import { closeView as closeView2 } from "@granite-js/react-native";
|
|
210
|
+
import { Loader } from "@toss/tds-react-native";
|
|
194
211
|
import { josa } from "es-hangul";
|
|
195
|
-
import {
|
|
212
|
+
import { useEffect as useEffect5, useRef as useRef2 } from "react";
|
|
213
|
+
import { Pressable, View } from "react-native";
|
|
214
|
+
|
|
215
|
+
// src/constant/game-center.ts
|
|
216
|
+
var GAME_PROFILE_WEBVIEW_URL = "servicetoss://game-center/profile";
|
|
217
|
+
var GAME_MIN_VERSION = {
|
|
218
|
+
android: "5.232.0",
|
|
219
|
+
ios: "5.232.0"
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// src/hooks/useAppUpdateDialog.tsx
|
|
223
|
+
import { INTERNAL__module as INTERNAL__module3 } from "@apps-in-toss/native-modules";
|
|
224
|
+
import { Granite as Granite3, openURL as openURL2 } from "@granite-js/react-native";
|
|
225
|
+
import { useDialog } from "@toss/tds-react-native";
|
|
226
|
+
import { useCallback as useCallback2 } from "react";
|
|
227
|
+
|
|
228
|
+
// src/utils/market.ts
|
|
229
|
+
import { Platform } from "react-native";
|
|
230
|
+
var PLAYSTORE_LINK = "https://play.google.com/store/apps/details?id=viva.republica.toss";
|
|
231
|
+
var APPSTORE_LINK = "https://itunes.apple.com/app/id839333328";
|
|
232
|
+
var getMarketLink = () => {
|
|
233
|
+
return Platform.OS === "android" ? PLAYSTORE_LINK : APPSTORE_LINK;
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
// src/hooks/useAppUpdateDialog.tsx
|
|
237
|
+
function useAppUpdateDialog() {
|
|
238
|
+
const { openConfirm } = useDialog();
|
|
239
|
+
const logging = useAppUpdateDialogLogging();
|
|
240
|
+
const openAppUpdateDialog = useCallback2(
|
|
241
|
+
async ({
|
|
242
|
+
title,
|
|
243
|
+
description,
|
|
244
|
+
leftButton = "\uB2EB\uAE30",
|
|
245
|
+
rightButton = "\uC5C5\uB370\uC774\uD2B8\uD558\uAE30",
|
|
246
|
+
onDismiss
|
|
247
|
+
}) => {
|
|
248
|
+
logging.show();
|
|
249
|
+
const isConfirmed = await openConfirm({
|
|
250
|
+
title,
|
|
251
|
+
description,
|
|
252
|
+
leftButton,
|
|
253
|
+
rightButton,
|
|
254
|
+
closeOnDimmerClick: true
|
|
255
|
+
});
|
|
256
|
+
if (!isConfirmed) {
|
|
257
|
+
logging.close();
|
|
258
|
+
onDismiss?.();
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
logging.update();
|
|
262
|
+
const STORE_SCHEME = getMarketLink();
|
|
263
|
+
openURL2(`supertoss://web?url=${STORE_SCHEME}&external=browser`);
|
|
264
|
+
},
|
|
265
|
+
[logging, openConfirm]
|
|
266
|
+
);
|
|
267
|
+
return {
|
|
268
|
+
open: openAppUpdateDialog
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
var UPDATE_DIALOG_SCHEMA_ID = 1634992;
|
|
272
|
+
var UPDATE_DIALOG_LOG_NAME = "appsintoss_app_visit__common_module::bottomsheet__app_update";
|
|
273
|
+
var UPDATE_DIALOG_CTA_CLICK_SCHEMA_ID = 1634996;
|
|
274
|
+
var UPDATE_DIALOG_CTA_CLICK_LOG_NAME = "appsintoss_app_visit__common_module::bottomsheet__app_update::click__cta";
|
|
275
|
+
function useAppUpdateDialogLogging() {
|
|
276
|
+
const referrer = useReferrer();
|
|
277
|
+
const baseParams = {
|
|
278
|
+
referrer,
|
|
279
|
+
app_name: Granite3.appName
|
|
280
|
+
};
|
|
281
|
+
const logUpdateClick = () => {
|
|
282
|
+
INTERNAL__module3.tossCoreEventLog({
|
|
283
|
+
log_name: UPDATE_DIALOG_CTA_CLICK_LOG_NAME,
|
|
284
|
+
log_type: "event",
|
|
285
|
+
params: {
|
|
286
|
+
...baseParams,
|
|
287
|
+
schema_id: UPDATE_DIALOG_CTA_CLICK_SCHEMA_ID,
|
|
288
|
+
event_type: "click",
|
|
289
|
+
button_type: "update"
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
};
|
|
293
|
+
const logCloseClick = () => {
|
|
294
|
+
INTERNAL__module3.tossCoreEventLog({
|
|
295
|
+
log_name: UPDATE_DIALOG_CTA_CLICK_LOG_NAME,
|
|
296
|
+
log_type: "event",
|
|
297
|
+
params: {
|
|
298
|
+
...baseParams,
|
|
299
|
+
schema_id: UPDATE_DIALOG_CTA_CLICK_SCHEMA_ID,
|
|
300
|
+
event_type: "click",
|
|
301
|
+
button_type: "close"
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
};
|
|
305
|
+
const logDialogShow = () => {
|
|
306
|
+
INTERNAL__module3.tossCoreEventLog({
|
|
307
|
+
log_name: UPDATE_DIALOG_LOG_NAME,
|
|
308
|
+
log_type: "popup",
|
|
309
|
+
params: {
|
|
310
|
+
...baseParams,
|
|
311
|
+
schema_id: UPDATE_DIALOG_SCHEMA_ID
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
};
|
|
315
|
+
return { update: logUpdateClick, close: logCloseClick, show: logDialogShow };
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// src/hooks/useGameCenterProfile.ts
|
|
319
|
+
import { getGameCenterGameProfile } from "@apps-in-toss/native-modules";
|
|
320
|
+
import { useCallback as useCallback6, useState as useState2 } from "react";
|
|
321
|
+
|
|
322
|
+
// src/hooks/useErrorAlert.ts
|
|
323
|
+
import { closeView } from "@granite-js/react-native";
|
|
324
|
+
import { useDialog as useDialog2 } from "@toss/tds-react-native";
|
|
325
|
+
import { useCallback as useCallback3 } from "react";
|
|
326
|
+
|
|
327
|
+
// src/utils/error.ts
|
|
328
|
+
var DEFAULT_ERROR = {
|
|
329
|
+
title: "\uC7A0\uC2DC \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694",
|
|
330
|
+
description: "\uBB38\uC81C\uAC00 \uACC4\uC18D\uB418\uBA74 \uD1A0\uC2A4 \uACE0\uAC1D\uC13C\uD130(1599-4905)\uB85C \uBB38\uC758\uD574\uC8FC\uC138\uC694."
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
// src/hooks/useErrorAlert.ts
|
|
334
|
+
var useErrorAlert = () => {
|
|
335
|
+
const { openAlert } = useDialog2();
|
|
336
|
+
const openErrorAlert = useCallback3(async () => {
|
|
337
|
+
await openAlert({
|
|
338
|
+
title: DEFAULT_ERROR.title,
|
|
339
|
+
description: DEFAULT_ERROR.description
|
|
340
|
+
});
|
|
341
|
+
closeView();
|
|
342
|
+
}, [openAlert]);
|
|
343
|
+
return { open: openErrorAlert };
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
// src/hooks/useTransparentWebview.tsx
|
|
347
|
+
import { useCallback as useCallback4, useState } from "react";
|
|
348
|
+
|
|
349
|
+
// src/utils/openTransparentWebView.ts
|
|
350
|
+
import { openURL as openURL3 } from "@granite-js/react-native";
|
|
351
|
+
|
|
352
|
+
// src/private.ts
|
|
353
|
+
import { onVisibilityChangedByTransparentServiceWeb } from "@apps-in-toss/native-modules";
|
|
354
|
+
var INTERNAL__onVisibilityChangedByTransparentServiceWeb = onVisibilityChangedByTransparentServiceWeb;
|
|
355
|
+
|
|
356
|
+
// src/utils/openTransparentWebView.ts
|
|
357
|
+
var openTransparentWebView = ({
|
|
358
|
+
webUrl,
|
|
359
|
+
cleanupWhenDismissed = true,
|
|
360
|
+
onEvent,
|
|
361
|
+
onError,
|
|
362
|
+
callbackId = "fn",
|
|
363
|
+
params
|
|
364
|
+
}) => {
|
|
365
|
+
const url = new URL("supertoss://transparent-service-web");
|
|
366
|
+
url.searchParams.set("url", webUrl);
|
|
367
|
+
url.searchParams.set("onVisibilityChangeCallback", callbackId);
|
|
368
|
+
Object.entries(params ?? {}).forEach(([key, value]) => {
|
|
369
|
+
url.searchParams.set(key, value);
|
|
370
|
+
});
|
|
371
|
+
const cleanup = INTERNAL__onVisibilityChangedByTransparentServiceWeb({
|
|
372
|
+
options: { callbackId },
|
|
373
|
+
onError: (error) => {
|
|
374
|
+
onError(error);
|
|
375
|
+
cleanup();
|
|
376
|
+
},
|
|
377
|
+
onEvent: (value) => {
|
|
378
|
+
onEvent(value);
|
|
379
|
+
if (cleanupWhenDismissed && value === true) {
|
|
380
|
+
cleanup();
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
openURL3(url.toString());
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
// src/hooks/useTransparentWebview.tsx
|
|
388
|
+
var useTransparentWebview = () => {
|
|
389
|
+
const [isWebviewLoading, setIsWebviewLoading] = useState(false);
|
|
390
|
+
const { open: openErrorAlert } = useErrorAlert();
|
|
391
|
+
const _openTransparentWebview = useCallback4(
|
|
392
|
+
({ webUrl, onClose, onError }) => {
|
|
393
|
+
if (isWebviewLoading) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
setIsWebviewLoading(true);
|
|
397
|
+
openTransparentWebView({
|
|
398
|
+
webUrl,
|
|
399
|
+
onEvent: async (isClosedTransparentWebView) => {
|
|
400
|
+
if (isClosedTransparentWebView) {
|
|
401
|
+
setIsWebviewLoading(false);
|
|
402
|
+
onClose?.();
|
|
403
|
+
}
|
|
404
|
+
},
|
|
405
|
+
onError: (error) => {
|
|
406
|
+
setIsWebviewLoading(false);
|
|
407
|
+
if (onError) {
|
|
408
|
+
onError(error);
|
|
409
|
+
} else {
|
|
410
|
+
openErrorAlert();
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
},
|
|
415
|
+
[isWebviewLoading, openErrorAlert]
|
|
416
|
+
);
|
|
417
|
+
return {
|
|
418
|
+
open: _openTransparentWebview
|
|
419
|
+
};
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
// src/components/GameProfileToast.tsx
|
|
423
|
+
import { Asset, Toast } from "@toss/tds-react-native";
|
|
424
|
+
import { AdaptiveColorProvider, ColorPreferenceProvider, useOverlay } from "@toss/tds-react-native/private";
|
|
425
|
+
import { useCallback as useCallback5 } from "react";
|
|
426
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
427
|
+
var useGameProfileToast = () => {
|
|
428
|
+
const overlay = useOverlay();
|
|
429
|
+
const openGameProfileToast = useCallback5(
|
|
430
|
+
(nickname, profileImageUri) => {
|
|
431
|
+
return new Promise((resolve) => {
|
|
432
|
+
overlay.open(({ isOpen, close, exit }) => {
|
|
433
|
+
return /* @__PURE__ */ jsx2(ColorPreferenceProvider, { colorPreference: "dark", children: /* @__PURE__ */ jsx2(AdaptiveColorProvider, { children: /* @__PURE__ */ jsx2(
|
|
434
|
+
Toast,
|
|
435
|
+
{
|
|
436
|
+
open: isOpen,
|
|
437
|
+
onClose: () => {
|
|
438
|
+
resolve();
|
|
439
|
+
close();
|
|
440
|
+
},
|
|
441
|
+
onExited: exit,
|
|
442
|
+
position: "top",
|
|
443
|
+
text: `${nickname}\uB2D8 \uBC18\uAC00\uC6CC\uC694!`,
|
|
444
|
+
icon: /* @__PURE__ */ jsx2(
|
|
445
|
+
Asset.Image,
|
|
446
|
+
{
|
|
447
|
+
style: { borderRadius: 64, overflow: "hidden" },
|
|
448
|
+
frameShape: Asset.frameShape.CleanW32,
|
|
449
|
+
source: { uri: profileImageUri }
|
|
450
|
+
}
|
|
451
|
+
)
|
|
452
|
+
}
|
|
453
|
+
) }) });
|
|
454
|
+
});
|
|
455
|
+
});
|
|
456
|
+
},
|
|
457
|
+
[overlay]
|
|
458
|
+
);
|
|
459
|
+
return { openGameProfileToast };
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
// src/hooks/useGameCenterProfile.ts
|
|
463
|
+
var useGameCenterProfile = (isReadyForProfileUI) => {
|
|
464
|
+
const [profileData, setProfileData] = useState2(void 0);
|
|
465
|
+
const [isProfileDataLoading, setIsProfileDataLoading] = useState2(true);
|
|
466
|
+
const [isProfileDataRefetching, setIsProfileDataRefetching] = useState2(false);
|
|
467
|
+
const shouldShowProfileLoadingOverlay = isProfileDataLoading && isReadyForProfileUI || isProfileDataRefetching;
|
|
468
|
+
const shouldShowProfileNotFoundOverlay = profileData?.statusCode === "PROFILE_NOT_FOUND" && isReadyForProfileUI && !isProfileDataRefetching;
|
|
469
|
+
const canShowBottomSheetOrToast = !isProfileDataLoading && isReadyForProfileUI;
|
|
470
|
+
const { openGameProfileToast } = useGameProfileToast();
|
|
471
|
+
const { open: openErrorAlert } = useErrorAlert();
|
|
472
|
+
const { open: openTransparentWebView2 } = useTransparentWebview();
|
|
473
|
+
const fetchProfileData = useCallback6(async () => {
|
|
474
|
+
try {
|
|
475
|
+
const data = await getGameCenterGameProfile();
|
|
476
|
+
setProfileData(data);
|
|
477
|
+
setIsProfileDataLoading(false);
|
|
478
|
+
} catch (_) {
|
|
479
|
+
openErrorAlert();
|
|
480
|
+
setIsProfileDataLoading(false);
|
|
481
|
+
}
|
|
482
|
+
}, [openErrorAlert]);
|
|
483
|
+
const refetchProfileData = useCallback6(async () => {
|
|
484
|
+
try {
|
|
485
|
+
setIsProfileDataRefetching(true);
|
|
486
|
+
const data = await getGameCenterGameProfile();
|
|
487
|
+
setProfileData(data);
|
|
488
|
+
setIsProfileDataRefetching(false);
|
|
489
|
+
if (data?.statusCode === "SUCCESS") {
|
|
490
|
+
openGameProfileToast(data.nickname, data.profileImageUri);
|
|
491
|
+
}
|
|
492
|
+
} catch (_) {
|
|
493
|
+
setIsProfileDataRefetching(false);
|
|
494
|
+
openErrorAlert();
|
|
495
|
+
}
|
|
496
|
+
}, [openErrorAlert, openGameProfileToast]);
|
|
497
|
+
const openProfileWebview = useCallback6(() => {
|
|
498
|
+
openTransparentWebView2({
|
|
499
|
+
webUrl: `${GAME_PROFILE_WEBVIEW_URL}?appName=${getAppName()}&referrer=appsintoss.${getAppName()}`,
|
|
500
|
+
onClose: async () => {
|
|
501
|
+
refetchProfileData();
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
}, [openTransparentWebView2, refetchProfileData]);
|
|
505
|
+
return {
|
|
506
|
+
profileData,
|
|
507
|
+
isProfileDataLoading,
|
|
508
|
+
shouldShowProfileLoadingOverlay,
|
|
509
|
+
shouldShowProfileNotFoundOverlay,
|
|
510
|
+
canShowBottomSheetOrToast,
|
|
511
|
+
setIsProfileDataLoading,
|
|
512
|
+
openProfileWebview,
|
|
513
|
+
setProfileData,
|
|
514
|
+
openErrorAlert,
|
|
515
|
+
openGameProfileToast,
|
|
516
|
+
fetchProfileData
|
|
517
|
+
};
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
// src/utils/zIndex.ts
|
|
521
|
+
var Z_INDEX = {
|
|
522
|
+
/* 게임 프로필을 위한 overlay
|
|
523
|
+
*/
|
|
524
|
+
PROFILE_OVERLAY: 9998,
|
|
525
|
+
// 게임을 종료할 수 있는 X 버튼
|
|
526
|
+
CLOSE_BUTTON: 9999
|
|
527
|
+
};
|
|
528
|
+
|
|
529
|
+
// src/components/GameInitializer.tsx
|
|
530
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
531
|
+
var GameInitializer = ({ children, isReadyForProfileUI }) => {
|
|
532
|
+
const {
|
|
533
|
+
profileData,
|
|
534
|
+
shouldShowProfileLoadingOverlay,
|
|
535
|
+
shouldShowProfileNotFoundOverlay,
|
|
536
|
+
canShowBottomSheetOrToast,
|
|
537
|
+
openProfileWebview,
|
|
538
|
+
openGameProfileToast,
|
|
539
|
+
fetchProfileData
|
|
540
|
+
} = useGameCenterProfile(isReadyForProfileUI);
|
|
541
|
+
const isCompletedFlow = useRef2(false);
|
|
542
|
+
const { open: openAppUpdateDialog } = useAppUpdateDialog();
|
|
543
|
+
useEffect5(() => {
|
|
544
|
+
fetchProfileData();
|
|
545
|
+
}, []);
|
|
546
|
+
useEffect5(() => {
|
|
547
|
+
const handleGameProfileFlow = async () => {
|
|
548
|
+
if (!canShowBottomSheetOrToast) {
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
if (isCompletedFlow.current) {
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
isCompletedFlow.current = true;
|
|
555
|
+
if (!isMinVersionSupported(GAME_MIN_VERSION)) {
|
|
556
|
+
openAppUpdateDialog({
|
|
557
|
+
title: `${josa(getAppsInTossGlobals().brandDisplayName, "\uC744/\uB97C")} \uD558\uB824\uBA74
|
|
558
|
+
\uC571\uC744 \uC5C5\uB370\uC774\uD2B8\uD574\uC8FC\uC138\uC694`,
|
|
559
|
+
onDismiss: () => {
|
|
560
|
+
closeView2();
|
|
561
|
+
}
|
|
562
|
+
});
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
if (profileData?.statusCode === "SUCCESS") {
|
|
566
|
+
openGameProfileToast(profileData.nickname, profileData.profileImageUri);
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
if (profileData?.statusCode === "PROFILE_NOT_FOUND") {
|
|
570
|
+
openProfileWebview();
|
|
571
|
+
}
|
|
572
|
+
};
|
|
573
|
+
handleGameProfileFlow();
|
|
574
|
+
}, [
|
|
575
|
+
canShowBottomSheetOrToast,
|
|
576
|
+
isCompletedFlow,
|
|
577
|
+
openAppUpdateDialog,
|
|
578
|
+
openGameProfileToast,
|
|
579
|
+
openProfileWebview,
|
|
580
|
+
profileData
|
|
581
|
+
]);
|
|
582
|
+
if (!isMinVersionSupported(GAME_MIN_VERSION)) {
|
|
583
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
584
|
+
/* @__PURE__ */ jsx3(View, { style: { flex: 1, position: "relative" }, children }),
|
|
585
|
+
/* @__PURE__ */ jsx3(
|
|
586
|
+
Pressable,
|
|
587
|
+
{
|
|
588
|
+
style: {
|
|
589
|
+
...overlayStyle
|
|
590
|
+
},
|
|
591
|
+
onPress: () => {
|
|
592
|
+
openAppUpdateDialog({
|
|
593
|
+
title: `${josa(getAppsInTossGlobals().brandDisplayName, "\uC744/\uB97C")} \uD558\uB824\uBA74
|
|
594
|
+
\uC571\uC744 \uC5C5\uB370\uC774\uD2B8\uD574\uC8FC\uC138\uC694`,
|
|
595
|
+
onDismiss: () => {
|
|
596
|
+
closeView2();
|
|
597
|
+
}
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
)
|
|
602
|
+
] });
|
|
603
|
+
}
|
|
604
|
+
if (shouldShowProfileLoadingOverlay) {
|
|
605
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
606
|
+
/* @__PURE__ */ jsx3(View, { style: { flex: 1, position: "relative" }, children }),
|
|
607
|
+
/* @__PURE__ */ jsx3(
|
|
608
|
+
View,
|
|
609
|
+
{
|
|
610
|
+
style: {
|
|
611
|
+
...overlayStyle,
|
|
612
|
+
justifyContent: "center",
|
|
613
|
+
alignItems: "center",
|
|
614
|
+
backgroundColor: "rgba(0, 0, 0, 0.2)"
|
|
615
|
+
},
|
|
616
|
+
children: /* @__PURE__ */ jsx3(Loader, { size: "large", type: "light" })
|
|
617
|
+
}
|
|
618
|
+
)
|
|
619
|
+
] });
|
|
620
|
+
}
|
|
621
|
+
if (shouldShowProfileNotFoundOverlay) {
|
|
622
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
623
|
+
/* @__PURE__ */ jsx3(View, { style: { flex: 1, position: "relative" }, children }),
|
|
624
|
+
shouldShowProfileNotFoundOverlay && /* @__PURE__ */ jsx3(
|
|
625
|
+
Pressable,
|
|
626
|
+
{
|
|
627
|
+
style: {
|
|
628
|
+
...overlayStyle
|
|
629
|
+
},
|
|
630
|
+
onPress: () => {
|
|
631
|
+
openProfileWebview();
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
)
|
|
635
|
+
] });
|
|
636
|
+
}
|
|
637
|
+
return /* @__PURE__ */ jsx3(Fragment2, { children: /* @__PURE__ */ jsx3(View, { style: { flex: 1, position: "relative" }, children }) });
|
|
638
|
+
};
|
|
639
|
+
var overlayStyle = {
|
|
640
|
+
position: "absolute",
|
|
641
|
+
top: 0,
|
|
642
|
+
left: 0,
|
|
643
|
+
right: 0,
|
|
644
|
+
bottom: 0,
|
|
645
|
+
zIndex: Z_INDEX.PROFILE_OVERLAY
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
// src/components/NavigationBar/RNNavigationBar/Default.tsx
|
|
649
|
+
import { NavigationBackButton, NavigationLeft, TopNavigation } from "@toss/tds-react-native/private";
|
|
650
|
+
|
|
651
|
+
// src/components/NavigationBar/RNNavigationBar/hooks/useHardwareBackPress.ts
|
|
652
|
+
import { useEffect as useEffect6 } from "react";
|
|
196
653
|
import { BackHandler } from "react-native";
|
|
654
|
+
function useHardwareBackPress(handler) {
|
|
655
|
+
useEffect6(() => {
|
|
656
|
+
const handleBackPress = () => {
|
|
657
|
+
handler();
|
|
658
|
+
return true;
|
|
659
|
+
};
|
|
660
|
+
BackHandler.addEventListener("hardwareBackPress", handleBackPress);
|
|
661
|
+
return () => BackHandler.removeEventListener("hardwareBackPress", handleBackPress);
|
|
662
|
+
}, [handler]);
|
|
663
|
+
}
|
|
197
664
|
|
|
198
|
-
// src/components/NavigationBar/
|
|
199
|
-
import {
|
|
665
|
+
// src/components/NavigationBar/RNNavigationBar/hooks/useNavigationEvent.ts
|
|
666
|
+
import { closeView as closeView3, useBackEventContext, useNavigation } from "@granite-js/react-native";
|
|
667
|
+
import { useMemo as useMemo2 } from "react";
|
|
668
|
+
|
|
669
|
+
// src/components/NavigationBar/RNNavigationBar/hooks/useCloseConfirm.ts
|
|
670
|
+
import { useDialog as useDialog3 } from "@toss/tds-react-native";
|
|
671
|
+
import { josa as josa2 } from "es-hangul";
|
|
672
|
+
import { useCallback as useCallback7 } from "react";
|
|
673
|
+
function useCloseConfirm() {
|
|
674
|
+
const { brandDisplayName } = getAppsInTossGlobals();
|
|
675
|
+
const { openConfirm } = useDialog3();
|
|
676
|
+
return useCallback7(async ({ onEntered }) => {
|
|
677
|
+
return await openConfirm({
|
|
678
|
+
title: `${josa2(brandDisplayName, "\uC744/\uB97C")} \uC885\uB8CC\uD560\uAE4C\uC694?`,
|
|
679
|
+
leftButton: "\uCDE8\uC18C",
|
|
680
|
+
rightButton: "\uC885\uB8CC\uD558\uAE30",
|
|
681
|
+
closeOnDimmerClick: true,
|
|
682
|
+
onEntered
|
|
683
|
+
});
|
|
684
|
+
}, [brandDisplayName, openConfirm]);
|
|
685
|
+
}
|
|
200
686
|
|
|
201
687
|
// src/components/NavigationBar/common/useNavigationBarLogging.tsx
|
|
202
|
-
import { INTERNAL__module as
|
|
203
|
-
import { Granite as
|
|
688
|
+
import { INTERNAL__module as INTERNAL__module4 } from "@apps-in-toss/native-modules";
|
|
689
|
+
import { Granite as Granite4 } from "@granite-js/react-native";
|
|
204
690
|
var NAVI_BAR_IMPRESSION_SCHEMA_ID = 1596837;
|
|
205
691
|
var NAVI_BAR_IMPRESSION_LOG_NAME = "appsintoss_app_visit__common_module::impression__navigation_bar";
|
|
206
692
|
var CLOSE_POPUP_SHOW_SCHEMA_ID = 1644490;
|
|
@@ -215,10 +701,10 @@ function useNavigationBarLogging() {
|
|
|
215
701
|
const referrer = useReferrer();
|
|
216
702
|
const baseParams = {
|
|
217
703
|
referrer,
|
|
218
|
-
app_name:
|
|
704
|
+
app_name: Granite4.appName
|
|
219
705
|
};
|
|
220
706
|
const logNavBarImpression = (naviBarConfig) => {
|
|
221
|
-
|
|
707
|
+
INTERNAL__module4.tossCoreEventLog({
|
|
222
708
|
log_name: NAVI_BAR_IMPRESSION_LOG_NAME,
|
|
223
709
|
log_type: "event",
|
|
224
710
|
params: {
|
|
@@ -230,7 +716,7 @@ function useNavigationBarLogging() {
|
|
|
230
716
|
});
|
|
231
717
|
};
|
|
232
718
|
const logHomeButtonClick = () => {
|
|
233
|
-
|
|
719
|
+
INTERNAL__module4.tossCoreEventLog({
|
|
234
720
|
log_name: HOME_BUTTON_CLICK_LOG_NAME,
|
|
235
721
|
log_type: "event",
|
|
236
722
|
params: {
|
|
@@ -241,7 +727,7 @@ function useNavigationBarLogging() {
|
|
|
241
727
|
});
|
|
242
728
|
};
|
|
243
729
|
const logCloseButtonClick = () => {
|
|
244
|
-
|
|
730
|
+
INTERNAL__module4.tossCoreEventLog({
|
|
245
731
|
log_name: CLOSE_BUTTON_CLICK_LOG_NAME,
|
|
246
732
|
log_type: "event",
|
|
247
733
|
params: {
|
|
@@ -252,7 +738,7 @@ function useNavigationBarLogging() {
|
|
|
252
738
|
});
|
|
253
739
|
};
|
|
254
740
|
const logClosePopupShow = () => {
|
|
255
|
-
|
|
741
|
+
INTERNAL__module4.tossCoreEventLog({
|
|
256
742
|
log_name: CLOSE_POPUP_SHOW_LOG_NAME,
|
|
257
743
|
log_type: "popup",
|
|
258
744
|
params: {
|
|
@@ -262,7 +748,7 @@ function useNavigationBarLogging() {
|
|
|
262
748
|
});
|
|
263
749
|
};
|
|
264
750
|
const logClosePopupCtaClick = (confirm) => {
|
|
265
|
-
|
|
751
|
+
INTERNAL__module4.tossCoreEventLog({
|
|
266
752
|
log_name: CLOSE_POPUP_CTA_CLICK_LOG_NAME,
|
|
267
753
|
log_type: "event",
|
|
268
754
|
params: {
|
|
@@ -282,40 +768,63 @@ function useNavigationBarLogging() {
|
|
|
282
768
|
};
|
|
283
769
|
}
|
|
284
770
|
|
|
285
|
-
// src/components/NavigationBar/
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
children,
|
|
289
|
-
withHomeButton
|
|
290
|
-
}) {
|
|
291
|
-
const hasLogged = useRef2(false);
|
|
771
|
+
// src/components/NavigationBar/RNNavigationBar/hooks/useNavigationEvent.ts
|
|
772
|
+
function useNavigationEvent() {
|
|
773
|
+
const backEventContext = useBackEventContext();
|
|
292
774
|
const logging = useNavigationBarLogging();
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
775
|
+
const navigation = useNavigation();
|
|
776
|
+
const closeConfirm = useCloseConfirm();
|
|
777
|
+
const { captureExitLog } = useCaptureExitLog();
|
|
778
|
+
return useMemo2(() => {
|
|
779
|
+
const close = async () => {
|
|
780
|
+
const hasConfirmed = await closeConfirm({
|
|
781
|
+
onEntered: logging.closePopupShow
|
|
782
|
+
});
|
|
783
|
+
logging.closePopupCtaClick(hasConfirmed);
|
|
784
|
+
if (hasConfirmed) {
|
|
785
|
+
captureExitLog(Date.now());
|
|
786
|
+
closeView3();
|
|
787
|
+
}
|
|
788
|
+
};
|
|
789
|
+
return {
|
|
790
|
+
handleBack: () => {
|
|
791
|
+
if (backEventContext.hasBackEvent) {
|
|
792
|
+
backEventContext.onBack();
|
|
793
|
+
} else if (navigation.canGoBack()) {
|
|
794
|
+
navigation.goBack();
|
|
795
|
+
} else {
|
|
796
|
+
close();
|
|
797
|
+
}
|
|
798
|
+
},
|
|
799
|
+
handleHomeButtonClick: () => {
|
|
800
|
+
logging.homeButtonClick();
|
|
801
|
+
navigation.navigate("/");
|
|
802
|
+
},
|
|
803
|
+
handleCloseButtonClick: () => {
|
|
804
|
+
logging.closeButtonClick();
|
|
805
|
+
close();
|
|
806
|
+
}
|
|
807
|
+
};
|
|
808
|
+
}, [backEventContext, navigation, closeConfirm, logging, captureExitLog]);
|
|
300
809
|
}
|
|
301
810
|
|
|
302
811
|
// src/core/hooks/useMoreButtonBottomSheet/index.tsx
|
|
303
|
-
import { INTERNAL__appBridgeHandler, isMinVersionSupported } from "@apps-in-toss/native-modules";
|
|
304
|
-
import { openURL as
|
|
812
|
+
import { INTERNAL__appBridgeHandler, isMinVersionSupported as isMinVersionSupported2 } from "@apps-in-toss/native-modules";
|
|
813
|
+
import { openURL as openURL4 } from "@granite-js/react-native";
|
|
305
814
|
import { BottomSheet, List, ListHeader, ListRow as ListRow2 } from "@toss/tds-react-native";
|
|
306
|
-
import { useAdaptive as useAdaptive2, useOverlay } from "@toss/tds-react-native/private";
|
|
307
|
-
import { useEffect as
|
|
815
|
+
import { useAdaptive as useAdaptive2, useOverlay as useOverlay2 } from "@toss/tds-react-native/private";
|
|
816
|
+
import { useEffect as useEffect7, useState as useState3 } from "react";
|
|
308
817
|
|
|
309
818
|
// src/core/hooks/useMoreButtonBottomSheet/AppShareListMenu.tsx
|
|
310
819
|
import { getOperationalEnvironment } from "@apps-in-toss/native-modules";
|
|
311
820
|
import { getSchemeUri as getSchemeUri4 } from "@granite-js/react-native";
|
|
312
|
-
import { ListRow, useDialog } from "@toss/tds-react-native";
|
|
821
|
+
import { ListRow, useDialog as useDialog4 } from "@toss/tds-react-native";
|
|
313
822
|
import { useAdaptive } from "@toss/tds-react-native/private";
|
|
314
823
|
import { NativeModules } from "react-native";
|
|
315
824
|
|
|
316
825
|
// src/core/hooks/useMoreButtonBottomSheet/useMoreButtonBottomSheetLogging.tsx
|
|
317
|
-
import { INTERNAL__module as
|
|
318
|
-
import { Granite as
|
|
826
|
+
import { INTERNAL__module as INTERNAL__module5 } from "@apps-in-toss/native-modules";
|
|
827
|
+
import { Granite as Granite5 } from "@granite-js/react-native";
|
|
319
828
|
var BOTTOM_SHEET_SCHEMA_ID = 1596825;
|
|
320
829
|
var BOTTOM_SHEET_LOG_NAME = "appsintoss_app_visit__common_module::bottomsheet__more";
|
|
321
830
|
var BOTTOM_SHEET_OPEN_SCHEMA_ID = 1596829;
|
|
@@ -328,10 +837,10 @@ function useMoreButtonBottomSheetLogging() {
|
|
|
328
837
|
const referrer = useReferrer();
|
|
329
838
|
const baseParams = {
|
|
330
839
|
referrer,
|
|
331
|
-
app_name:
|
|
840
|
+
app_name: Granite5.appName
|
|
332
841
|
};
|
|
333
842
|
const logBottomSheetShow = () => {
|
|
334
|
-
|
|
843
|
+
INTERNAL__module5.tossCoreEventLog({
|
|
335
844
|
log_name: BOTTOM_SHEET_LOG_NAME,
|
|
336
845
|
log_type: "popup",
|
|
337
846
|
params: {
|
|
@@ -341,7 +850,7 @@ function useMoreButtonBottomSheetLogging() {
|
|
|
341
850
|
});
|
|
342
851
|
};
|
|
343
852
|
const logBottomSheetOpen = () => {
|
|
344
|
-
|
|
853
|
+
INTERNAL__module5.tossCoreEventLog({
|
|
345
854
|
log_name: BOTTOM_SHEET_OPEN_LOG_NAME,
|
|
346
855
|
log_type: "event",
|
|
347
856
|
params: {
|
|
@@ -352,7 +861,7 @@ function useMoreButtonBottomSheetLogging() {
|
|
|
352
861
|
});
|
|
353
862
|
};
|
|
354
863
|
const logBottomSheetCloseClick = () => {
|
|
355
|
-
|
|
864
|
+
INTERNAL__module5.tossCoreEventLog({
|
|
356
865
|
log_name: BOTTOM_SHEET_CLOSE_CLICK_LOG_NAME,
|
|
357
866
|
log_type: "event",
|
|
358
867
|
params: {
|
|
@@ -363,7 +872,7 @@ function useMoreButtonBottomSheetLogging() {
|
|
|
363
872
|
});
|
|
364
873
|
};
|
|
365
874
|
const logBottomSheetMenuClick = ({ title }) => {
|
|
366
|
-
|
|
875
|
+
INTERNAL__module5.tossCoreEventLog({
|
|
367
876
|
log_name: BOTTOM_SHEET_MENU_CLICK_LOG_NAME,
|
|
368
877
|
log_type: "event",
|
|
369
878
|
params: {
|
|
@@ -392,7 +901,7 @@ function addParamsToUrl(url, params) {
|
|
|
392
901
|
}
|
|
393
902
|
|
|
394
903
|
// src/core/hooks/useMoreButtonBottomSheet/AppShareListMenu.tsx
|
|
395
|
-
import { jsx as
|
|
904
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
396
905
|
var SHARE_SCHEME_REFERRER = "appsintoss.common_module_share";
|
|
397
906
|
var APP_SHARE_MENU_INFO = {
|
|
398
907
|
contactItemName: "\uACF5\uC720\uD558\uAE30",
|
|
@@ -404,14 +913,14 @@ function AppShareListMenu() {
|
|
|
404
913
|
const logging = useMoreButtonBottomSheetLogging();
|
|
405
914
|
const initialScheme = getSchemeUri4();
|
|
406
915
|
const isSandbox = getOperationalEnvironment() === "sandbox";
|
|
407
|
-
const { openConfirm } =
|
|
916
|
+
const { openConfirm } = useDialog4();
|
|
408
917
|
const schemeForShare = addParamsToUrl(initialScheme, {
|
|
409
918
|
referrer: SHARE_SCHEME_REFERRER
|
|
410
919
|
});
|
|
411
|
-
return /* @__PURE__ */
|
|
920
|
+
return /* @__PURE__ */ jsx4(
|
|
412
921
|
ListRow,
|
|
413
922
|
{
|
|
414
|
-
left: /* @__PURE__ */
|
|
923
|
+
left: /* @__PURE__ */ jsx4(
|
|
415
924
|
ListRow.Icon,
|
|
416
925
|
{
|
|
417
926
|
color: globals.brandPrimaryColor,
|
|
@@ -419,7 +928,7 @@ function AppShareListMenu() {
|
|
|
419
928
|
type: "background"
|
|
420
929
|
}
|
|
421
930
|
),
|
|
422
|
-
contents: /* @__PURE__ */
|
|
931
|
+
contents: /* @__PURE__ */ jsx4(
|
|
423
932
|
ListRow.Texts,
|
|
424
933
|
{
|
|
425
934
|
type: "1RowTypeA",
|
|
@@ -449,100 +958,6 @@ function AppShareListMenu() {
|
|
|
449
958
|
);
|
|
450
959
|
}
|
|
451
960
|
|
|
452
|
-
// src/hooks/useAppUpdateDialog.tsx
|
|
453
|
-
import { INTERNAL__module as INTERNAL__module5 } from "@apps-in-toss/native-modules";
|
|
454
|
-
import { Granite as Granite5, openURL as openURL2 } from "@granite-js/react-native";
|
|
455
|
-
import { useDialog as useDialog2 } from "@toss/tds-react-native";
|
|
456
|
-
import { useCallback as useCallback2 } from "react";
|
|
457
|
-
|
|
458
|
-
// src/utils/market.ts
|
|
459
|
-
import { Platform } from "react-native";
|
|
460
|
-
var PLAYSTORE_LINK = "https://play.google.com/store/apps/details?id=viva.republica.toss";
|
|
461
|
-
var APPSTORE_LINK = "https://itunes.apple.com/app/id839333328";
|
|
462
|
-
var getMarketLink = () => {
|
|
463
|
-
return Platform.OS === "android" ? PLAYSTORE_LINK : APPSTORE_LINK;
|
|
464
|
-
};
|
|
465
|
-
|
|
466
|
-
// src/hooks/useAppUpdateDialog.tsx
|
|
467
|
-
function useAppUpdateDialog() {
|
|
468
|
-
const { openConfirm } = useDialog2();
|
|
469
|
-
const logging = useAppUpdateDialogLogging();
|
|
470
|
-
const openAppUpdateDialog = useCallback2(
|
|
471
|
-
async ({
|
|
472
|
-
title,
|
|
473
|
-
description,
|
|
474
|
-
leftButton = "\uB2EB\uAE30",
|
|
475
|
-
rightButton = "\uC5C5\uB370\uC774\uD2B8\uD558\uAE30"
|
|
476
|
-
}) => {
|
|
477
|
-
logging.show();
|
|
478
|
-
const isConfirmed = await openConfirm({
|
|
479
|
-
title,
|
|
480
|
-
description,
|
|
481
|
-
leftButton,
|
|
482
|
-
rightButton,
|
|
483
|
-
closeOnDimmerClick: true
|
|
484
|
-
});
|
|
485
|
-
if (!isConfirmed) {
|
|
486
|
-
logging.close();
|
|
487
|
-
return;
|
|
488
|
-
}
|
|
489
|
-
logging.update();
|
|
490
|
-
const STORE_SCHEME = getMarketLink();
|
|
491
|
-
openURL2(`supertoss://web?url=${STORE_SCHEME}&external=browser`);
|
|
492
|
-
},
|
|
493
|
-
[logging, openConfirm]
|
|
494
|
-
);
|
|
495
|
-
return {
|
|
496
|
-
open: openAppUpdateDialog
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
|
-
var UPDATE_DIALOG_SCHEMA_ID = 1634992;
|
|
500
|
-
var UPDATE_DIALOG_LOG_NAME = "appsintoss_app_visit__common_module::bottomsheet__app_update";
|
|
501
|
-
var UPDATE_DIALOG_CTA_CLICK_SCHEMA_ID = 1634996;
|
|
502
|
-
var UPDATE_DIALOG_CTA_CLICK_LOG_NAME = "appsintoss_app_visit__common_module::bottomsheet__app_update::click__cta";
|
|
503
|
-
function useAppUpdateDialogLogging() {
|
|
504
|
-
const referrer = useReferrer();
|
|
505
|
-
const baseParams = {
|
|
506
|
-
referrer,
|
|
507
|
-
app_name: Granite5.appName
|
|
508
|
-
};
|
|
509
|
-
const logUpdateClick = () => {
|
|
510
|
-
INTERNAL__module5.tossCoreEventLog({
|
|
511
|
-
log_name: UPDATE_DIALOG_CTA_CLICK_LOG_NAME,
|
|
512
|
-
log_type: "event",
|
|
513
|
-
params: {
|
|
514
|
-
...baseParams,
|
|
515
|
-
schema_id: UPDATE_DIALOG_CTA_CLICK_SCHEMA_ID,
|
|
516
|
-
event_type: "click",
|
|
517
|
-
button_type: "update"
|
|
518
|
-
}
|
|
519
|
-
});
|
|
520
|
-
};
|
|
521
|
-
const logCloseClick = () => {
|
|
522
|
-
INTERNAL__module5.tossCoreEventLog({
|
|
523
|
-
log_name: UPDATE_DIALOG_CTA_CLICK_LOG_NAME,
|
|
524
|
-
log_type: "event",
|
|
525
|
-
params: {
|
|
526
|
-
...baseParams,
|
|
527
|
-
schema_id: UPDATE_DIALOG_CTA_CLICK_SCHEMA_ID,
|
|
528
|
-
event_type: "click",
|
|
529
|
-
button_type: "close"
|
|
530
|
-
}
|
|
531
|
-
});
|
|
532
|
-
};
|
|
533
|
-
const logDialogShow = () => {
|
|
534
|
-
INTERNAL__module5.tossCoreEventLog({
|
|
535
|
-
log_name: UPDATE_DIALOG_LOG_NAME,
|
|
536
|
-
log_type: "popup",
|
|
537
|
-
params: {
|
|
538
|
-
...baseParams,
|
|
539
|
-
schema_id: UPDATE_DIALOG_SCHEMA_ID
|
|
540
|
-
}
|
|
541
|
-
});
|
|
542
|
-
};
|
|
543
|
-
return { update: logUpdateClick, close: logCloseClick, show: logDialogShow };
|
|
544
|
-
}
|
|
545
|
-
|
|
546
961
|
// src/core/utils/ensureValue.ts
|
|
547
962
|
function ensureValue(value, name) {
|
|
548
963
|
if (value === void 0) {
|
|
@@ -552,7 +967,7 @@ function ensureValue(value, name) {
|
|
|
552
967
|
}
|
|
553
968
|
|
|
554
969
|
// src/core/hooks/useMoreButtonBottomSheet/index.tsx
|
|
555
|
-
import { Fragment as Fragment3, jsx as
|
|
970
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
556
971
|
var APP_BRIDGE_METHOD_NAME = "getMiniAppsSupportContact";
|
|
557
972
|
var MIN_VERSION = {
|
|
558
973
|
BOTTOM_SHEET: {
|
|
@@ -567,14 +982,14 @@ var MIN_VERSION = {
|
|
|
567
982
|
function useMoreButtonBottomSheet() {
|
|
568
983
|
const globals = getAppsInTossGlobals();
|
|
569
984
|
const adaptive = useAdaptive2();
|
|
570
|
-
const [itemList, setItemList] =
|
|
985
|
+
const [itemList, setItemList] = useState3([]);
|
|
571
986
|
const appUpdateDialog = useAppUpdateDialog();
|
|
572
987
|
const logging = useMoreButtonBottomSheetLogging();
|
|
573
|
-
const overlay =
|
|
988
|
+
const overlay = useOverlay2();
|
|
574
989
|
const title = ensureValue(globals.brandDisplayName, "displayName");
|
|
575
|
-
const isBottomSheetSupported =
|
|
576
|
-
const isShareListMenuSupported =
|
|
577
|
-
|
|
990
|
+
const isBottomSheetSupported = isMinVersionSupported2(MIN_VERSION.BOTTOM_SHEET);
|
|
991
|
+
const isShareListMenuSupported = isMinVersionSupported2(MIN_VERSION.SHARE_LIST_MENU);
|
|
992
|
+
useEffect7(() => {
|
|
578
993
|
if (!isBottomSheetSupported) {
|
|
579
994
|
return;
|
|
580
995
|
}
|
|
@@ -601,17 +1016,17 @@ function useMoreButtonBottomSheet() {
|
|
|
601
1016
|
logging.close();
|
|
602
1017
|
close();
|
|
603
1018
|
};
|
|
604
|
-
return /* @__PURE__ */
|
|
1019
|
+
return /* @__PURE__ */ jsx5(BottomSheetImpressionArea, { children: /* @__PURE__ */ jsx5(
|
|
605
1020
|
BottomSheet.Root,
|
|
606
1021
|
{
|
|
607
|
-
header: /* @__PURE__ */
|
|
1022
|
+
header: /* @__PURE__ */ jsx5(
|
|
608
1023
|
ListHeader,
|
|
609
1024
|
{
|
|
610
|
-
title: /* @__PURE__ */
|
|
1025
|
+
title: /* @__PURE__ */ jsx5(ListHeader.TitleParagraph, { color: adaptive.grey800, fontWeight: "bold", typography: "t5", children: title })
|
|
611
1026
|
}
|
|
612
1027
|
),
|
|
613
1028
|
open: isOpen,
|
|
614
|
-
cta: /* @__PURE__ */
|
|
1029
|
+
cta: /* @__PURE__ */ jsx5(
|
|
615
1030
|
BottomSheet.CTA,
|
|
616
1031
|
{
|
|
617
1032
|
size: "large",
|
|
@@ -625,12 +1040,12 @@ function useMoreButtonBottomSheet() {
|
|
|
625
1040
|
),
|
|
626
1041
|
onClose: handleClose,
|
|
627
1042
|
onExited: exit,
|
|
628
|
-
children: /* @__PURE__ */
|
|
1043
|
+
children: /* @__PURE__ */ jsxs2(List, { rowSeparator: "none", children: [
|
|
629
1044
|
itemList.map((item) => {
|
|
630
|
-
return /* @__PURE__ */
|
|
1045
|
+
return /* @__PURE__ */ jsx5(
|
|
631
1046
|
ListRow2,
|
|
632
1047
|
{
|
|
633
|
-
left: /* @__PURE__ */
|
|
1048
|
+
left: /* @__PURE__ */ jsx5(
|
|
634
1049
|
ListRow2.Icon,
|
|
635
1050
|
{
|
|
636
1051
|
color: globals.brandPrimaryColor,
|
|
@@ -638,7 +1053,7 @@ function useMoreButtonBottomSheet() {
|
|
|
638
1053
|
type: "background"
|
|
639
1054
|
}
|
|
640
1055
|
),
|
|
641
|
-
contents: /* @__PURE__ */
|
|
1056
|
+
contents: /* @__PURE__ */ jsx5(
|
|
642
1057
|
ListRow2.Texts,
|
|
643
1058
|
{
|
|
644
1059
|
type: "1RowTypeA",
|
|
@@ -649,13 +1064,13 @@ function useMoreButtonBottomSheet() {
|
|
|
649
1064
|
verticalPadding: "extraSmall",
|
|
650
1065
|
onPress: () => {
|
|
651
1066
|
logging.menuClick({ title: item.contactItemName });
|
|
652
|
-
|
|
1067
|
+
openURL4(item.contactUri);
|
|
653
1068
|
}
|
|
654
1069
|
},
|
|
655
1070
|
item.contactItemName
|
|
656
1071
|
);
|
|
657
1072
|
}),
|
|
658
|
-
isShareListMenuSupported && /* @__PURE__ */
|
|
1073
|
+
isShareListMenuSupported && /* @__PURE__ */ jsx5(AppShareListMenu, {})
|
|
659
1074
|
] })
|
|
660
1075
|
}
|
|
661
1076
|
) });
|
|
@@ -665,10 +1080,10 @@ function useMoreButtonBottomSheet() {
|
|
|
665
1080
|
}
|
|
666
1081
|
function BottomSheetImpressionArea({ children }) {
|
|
667
1082
|
const logging = useMoreButtonBottomSheetLogging();
|
|
668
|
-
|
|
1083
|
+
useEffect7(() => {
|
|
669
1084
|
logging.show();
|
|
670
1085
|
}, [logging]);
|
|
671
|
-
return /* @__PURE__ */
|
|
1086
|
+
return /* @__PURE__ */ jsx5(Fragment3, { children });
|
|
672
1087
|
}
|
|
673
1088
|
|
|
674
1089
|
// src/core/utils/safeParseNavigationBar.ts
|
|
@@ -683,112 +1098,176 @@ function safeParseNavigationBar(navigationBar) {
|
|
|
683
1098
|
}
|
|
684
1099
|
}
|
|
685
1100
|
|
|
686
|
-
// src/components/NavigationBar/
|
|
687
|
-
import {
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
1101
|
+
// src/components/NavigationBar/common/NavigationBarImpressionArea.tsx
|
|
1102
|
+
import { useEffect as useEffect8, useRef as useRef3 } from "react";
|
|
1103
|
+
import { Fragment as Fragment4, jsx as jsx6 } from "react/jsx-runtime";
|
|
1104
|
+
function NavigationBarImpressionArea({
|
|
1105
|
+
children,
|
|
1106
|
+
withHomeButton
|
|
1107
|
+
}) {
|
|
1108
|
+
const hasLogged = useRef3(false);
|
|
691
1109
|
const logging = useNavigationBarLogging();
|
|
692
|
-
|
|
1110
|
+
useEffect8(() => {
|
|
1111
|
+
if (hasLogged.current === false) {
|
|
1112
|
+
logging.navBarImpression({ home_icon_yn: withHomeButton ? "Y" : "N" });
|
|
1113
|
+
hasLogged.current = true;
|
|
1114
|
+
}
|
|
1115
|
+
}, [logging, withHomeButton]);
|
|
1116
|
+
return /* @__PURE__ */ jsx6(Fragment4, { children });
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
// src/components/NavigationBar/RNNavigationBar/Default.tsx
|
|
1120
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1121
|
+
function DefaultNavigationBar() {
|
|
1122
|
+
const globals = getAppsInTossGlobals();
|
|
693
1123
|
const { open: openMoreButtonBottomSheet } = useMoreButtonBottomSheet();
|
|
694
1124
|
const parsedNavigationBar = globals.navigationBar != null ? safeParseNavigationBar(globals.navigationBar) : null;
|
|
695
1125
|
const withHomeButton = parsedNavigationBar?.withHomeButton ?? false;
|
|
696
1126
|
const withBackButton = parsedNavigationBar?.withBackButton ?? true;
|
|
697
1127
|
const initialAccessoryButton = parsedNavigationBar?.initialAccessoryButton;
|
|
698
|
-
const
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
const handlePressTitle = useCallback3(() => {
|
|
702
|
-
logging.homeButtonClick();
|
|
703
|
-
navigation.navigate("/");
|
|
704
|
-
}, [logging, navigation]);
|
|
705
|
-
const handleClose = useCallback3(async () => {
|
|
706
|
-
logging.closeButtonClick();
|
|
707
|
-
const isConfirmed = await openConfirm({
|
|
708
|
-
title: `${josa(globals.brandDisplayName, "\uC744/\uB97C")} \uC885\uB8CC\uD560\uAE4C\uC694?`,
|
|
709
|
-
leftButton: "\uCDE8\uC18C",
|
|
710
|
-
rightButton: "\uC885\uB8CC\uD558\uAE30",
|
|
711
|
-
closeOnDimmerClick: true,
|
|
712
|
-
onEntered: logging.closePopupShow
|
|
713
|
-
});
|
|
714
|
-
logging.closePopupCtaClick(isConfirmed);
|
|
715
|
-
if (isConfirmed) {
|
|
716
|
-
captureExitLog(Date.now());
|
|
717
|
-
closeView();
|
|
718
|
-
}
|
|
719
|
-
}, [captureExitLog, globals.brandDisplayName, logging, openConfirm]);
|
|
720
|
-
const handleBack = useCallback3(() => {
|
|
721
|
-
if (backEventContext.hasBackEvent) {
|
|
722
|
-
backEventContext.onBack();
|
|
723
|
-
return;
|
|
724
|
-
}
|
|
725
|
-
handleBackOrClose();
|
|
726
|
-
}, [backEventContext, handleBackOrClose]);
|
|
727
|
-
useEffect7(() => {
|
|
728
|
-
const handleAndroidBackEvent = () => {
|
|
729
|
-
handleBack();
|
|
730
|
-
return true;
|
|
731
|
-
};
|
|
732
|
-
BackHandler.addEventListener("hardwareBackPress", handleAndroidBackEvent);
|
|
733
|
-
return () => {
|
|
734
|
-
BackHandler.removeEventListener("hardwareBackPress", handleAndroidBackEvent);
|
|
735
|
-
};
|
|
736
|
-
}, [handleBack]);
|
|
737
|
-
return /* @__PURE__ */ jsx5(NavigationBarImpressionArea, { withHomeButton, children: /* @__PURE__ */ jsx5(
|
|
1128
|
+
const navigationEvent = useNavigationEvent();
|
|
1129
|
+
useHardwareBackPress(navigationEvent.handleBack);
|
|
1130
|
+
return /* @__PURE__ */ jsx7(NavigationBarImpressionArea, { withHomeButton, children: /* @__PURE__ */ jsx7(
|
|
738
1131
|
TopNavigation,
|
|
739
1132
|
{
|
|
740
1133
|
title: globals.brandDisplayName,
|
|
741
1134
|
icon: toIcon(globals.brandIcon),
|
|
742
1135
|
onPressDots: openMoreButtonBottomSheet,
|
|
743
1136
|
contentVisible: true,
|
|
744
|
-
onPressTitle: withHomeButton ?
|
|
745
|
-
onPressClose:
|
|
1137
|
+
onPressTitle: withHomeButton ? navigationEvent.handleHomeButtonClick : void 0,
|
|
1138
|
+
onPressClose: navigationEvent.handleCloseButtonClick,
|
|
746
1139
|
withHome: withHomeButton,
|
|
747
|
-
fixedRightButton: initialAccessoryButton
|
|
748
|
-
|
|
749
|
-
icon: initialAccessoryButton.icon,
|
|
750
|
-
id: initialAccessoryButton.id
|
|
751
|
-
} : void 0,
|
|
752
|
-
children: /* @__PURE__ */ jsx5(NavigationLeft, { visible: withBackButton, children: /* @__PURE__ */ jsx5(NavigationBackButton, { onPress: handleBack, canGoBack: false }) })
|
|
1140
|
+
fixedRightButton: initialAccessoryButton,
|
|
1141
|
+
children: /* @__PURE__ */ jsx7(NavigationLeft, { visible: withBackButton, children: /* @__PURE__ */ jsx7(NavigationBackButton, { onPress: navigationEvent.handleBack, canGoBack: false }) })
|
|
753
1142
|
}
|
|
754
1143
|
) });
|
|
755
1144
|
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
1145
|
+
|
|
1146
|
+
// src/components/NavigationBar/RNNavigationBar/Game.tsx
|
|
1147
|
+
import { PageNavbar } from "@toss/tds-react-native";
|
|
1148
|
+
import { NavigationRightContent, useSafeAreaTop } from "@toss/tds-react-native/private";
|
|
1149
|
+
import { Platform as Platform2, View as View2 } from "react-native";
|
|
1150
|
+
import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1151
|
+
function GameNavigationBar() {
|
|
1152
|
+
const safeAreaTop = useSafeAreaTop();
|
|
1153
|
+
const global2 = getAppsInTossGlobals();
|
|
1154
|
+
const { open: openMoreButtonBottomSheet } = useMoreButtonBottomSheet();
|
|
1155
|
+
const navigationEvent = useNavigationEvent();
|
|
1156
|
+
useHardwareBackPress(navigationEvent.handleBack);
|
|
1157
|
+
const parsedNavigationBar = global2.navigationBar != null ? safeParseNavigationBar(global2.navigationBar) : null;
|
|
1158
|
+
const initialAccessoryButton = parsedNavigationBar?.initialAccessoryButton;
|
|
1159
|
+
return /* @__PURE__ */ jsxs3(Fragment5, { children: [
|
|
1160
|
+
/* @__PURE__ */ jsx8(PageNavbar, { preference: { type: "none" } }),
|
|
1161
|
+
/* @__PURE__ */ jsx8(
|
|
1162
|
+
View2,
|
|
1163
|
+
{
|
|
1164
|
+
style: {
|
|
1165
|
+
width: "100%",
|
|
1166
|
+
// TODO: UI관련 스타일 설정은 TDS로 이관
|
|
1167
|
+
height: Platform2.OS === "ios" ? 44 : 54,
|
|
1168
|
+
flexDirection: "row",
|
|
1169
|
+
alignItems: "center",
|
|
1170
|
+
justifyContent: "flex-end",
|
|
1171
|
+
position: "absolute",
|
|
1172
|
+
zIndex: Z_INDEX.CLOSE_BUTTON,
|
|
1173
|
+
marginTop: safeAreaTop,
|
|
1174
|
+
paddingRight: 10
|
|
1175
|
+
},
|
|
1176
|
+
pointerEvents: "box-none",
|
|
1177
|
+
children: /* @__PURE__ */ jsx8(
|
|
1178
|
+
NavigationRightContent,
|
|
1179
|
+
{
|
|
1180
|
+
fixedRightButton: initialAccessoryButton,
|
|
1181
|
+
onPressDots: openMoreButtonBottomSheet,
|
|
1182
|
+
onPressClose: navigationEvent.handleCloseButtonClick,
|
|
1183
|
+
theme: "dark"
|
|
1184
|
+
}
|
|
1185
|
+
)
|
|
1186
|
+
}
|
|
1187
|
+
)
|
|
1188
|
+
] });
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
// src/components/NavigationBar/RNNavigationBar/index.tsx
|
|
1192
|
+
var RNNavigationBar = {
|
|
1193
|
+
Default: DefaultNavigationBar,
|
|
1194
|
+
Game: GameNavigationBar
|
|
1195
|
+
};
|
|
1196
|
+
|
|
1197
|
+
// src/bridge-entry.ts
|
|
1198
|
+
var bridge_entry_exports = {};
|
|
1199
|
+
__reExport(bridge_entry_exports, async_bridges_star);
|
|
1200
|
+
__reExport(bridge_entry_exports, constant_bridges_star);
|
|
1201
|
+
__reExport(bridge_entry_exports, event_bridges_star);
|
|
1202
|
+
import * as async_bridges_star from "@apps-in-toss/native-modules/async-bridges";
|
|
1203
|
+
import * as constant_bridges_star from "@apps-in-toss/native-modules/constant-bridges";
|
|
1204
|
+
import * as event_bridges_star from "@apps-in-toss/native-modules/event-bridges";
|
|
1205
|
+
|
|
1206
|
+
// src/components/RNAppContainer.tsx
|
|
1207
|
+
import { Fragment as Fragment6, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1208
|
+
function RNAppContainer({ children }) {
|
|
1209
|
+
const global2 = getAppsInTossGlobals();
|
|
1210
|
+
switch (global2.appType) {
|
|
1211
|
+
case "game":
|
|
1212
|
+
return /* @__PURE__ */ jsx9(GameAppContainer, { children });
|
|
1213
|
+
case "general":
|
|
1214
|
+
default:
|
|
1215
|
+
return /* @__PURE__ */ jsx9(GeneralAppContainer, { children });
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
function GameAppContainer({ children }) {
|
|
1219
|
+
const [isEntryMessageExited, setIsEntryMessageExited] = useState4(false);
|
|
1220
|
+
useEffect9(() => {
|
|
1221
|
+
if (Platform3.OS === "ios") {
|
|
1222
|
+
setIosSwipeGestureEnabled({ isEnabled: false });
|
|
1223
|
+
return () => {
|
|
1224
|
+
setIosSwipeGestureEnabled({ isEnabled: true });
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
return;
|
|
1228
|
+
}, []);
|
|
1229
|
+
useEffect9(() => {
|
|
1230
|
+
appsInTossEvent2.addEventListener("entryMessageExited", {
|
|
1231
|
+
onEvent: () => {
|
|
1232
|
+
setIsEntryMessageExited(true);
|
|
1233
|
+
}
|
|
1234
|
+
});
|
|
1235
|
+
}, []);
|
|
1236
|
+
return /* @__PURE__ */ jsxs4(Fragment6, { children: [
|
|
1237
|
+
/* @__PURE__ */ jsx9(RNNavigationBar.Game, {}),
|
|
1238
|
+
(0, bridge_entry_exports.getOperationalEnvironment)() === "toss" ? /* @__PURE__ */ jsx9(GameInitializer, { isReadyForProfileUI: isEntryMessageExited, children }) : children
|
|
1239
|
+
] });
|
|
1240
|
+
}
|
|
1241
|
+
function GeneralAppContainer({ children }) {
|
|
1242
|
+
return /* @__PURE__ */ jsxs4(Fragment6, { children: [
|
|
1243
|
+
/* @__PURE__ */ jsx9(RNNavigationBar.Default, {}),
|
|
1244
|
+
children
|
|
1245
|
+
] });
|
|
767
1246
|
}
|
|
768
1247
|
|
|
769
1248
|
// src/core/registerApp.tsx
|
|
770
|
-
import { Fragment as
|
|
1249
|
+
import { Fragment as Fragment7, jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
771
1250
|
function AppsInTossContainer(Container, { children, ...initialProps }) {
|
|
772
|
-
if (!
|
|
1251
|
+
if (!isMinVersionSupported3({
|
|
773
1252
|
android: "5.220.0",
|
|
774
1253
|
ios: "5.221.0"
|
|
775
1254
|
})) {
|
|
776
|
-
return /* @__PURE__ */
|
|
777
|
-
/* @__PURE__ */
|
|
778
|
-
/* @__PURE__ */
|
|
779
|
-
/* @__PURE__ */
|
|
1255
|
+
return /* @__PURE__ */ jsxs5(Fragment7, { children: [
|
|
1256
|
+
/* @__PURE__ */ jsx10(AppEvent.Entry, {}),
|
|
1257
|
+
/* @__PURE__ */ jsx10(AppEvent.System, { ...initialProps }),
|
|
1258
|
+
/* @__PURE__ */ jsx10(AppUpdate, {})
|
|
780
1259
|
] });
|
|
781
1260
|
}
|
|
782
|
-
return /* @__PURE__ */
|
|
783
|
-
/* @__PURE__ */
|
|
784
|
-
/* @__PURE__ */
|
|
785
|
-
/* @__PURE__ */
|
|
786
|
-
/* @__PURE__ */
|
|
1261
|
+
return /* @__PURE__ */ jsxs5(Fragment7, { children: [
|
|
1262
|
+
/* @__PURE__ */ jsx10(AppEvent.StayTime, {}),
|
|
1263
|
+
/* @__PURE__ */ jsx10(AppEvent.Entry, {}),
|
|
1264
|
+
/* @__PURE__ */ jsx10(AppEvent.System, { ...initialProps }),
|
|
1265
|
+
/* @__PURE__ */ jsx10(Container, { ...initialProps, children: /* @__PURE__ */ jsx10(TDSProvider, { colorPreference: "light", token: { color: { primary: getAppsInTossGlobals().brandPrimaryColor } }, children: /* @__PURE__ */ jsx10(TDSContainer, { ...initialProps, children }) }) })
|
|
787
1266
|
] });
|
|
788
1267
|
}
|
|
789
1268
|
function TDSContainer({ children }) {
|
|
790
1269
|
useAppsInTossBridge();
|
|
791
|
-
return /* @__PURE__ */
|
|
1270
|
+
return /* @__PURE__ */ jsx10(Fragment7, { children });
|
|
792
1271
|
}
|
|
793
1272
|
function registerApp(container, { context, analytics }) {
|
|
794
1273
|
const appName = getAppName();
|
|
@@ -801,7 +1280,7 @@ function registerApp(container, { context, analytics }) {
|
|
|
801
1280
|
const App = Granite6.registerApp(AppsInTossContainer.bind(null, container), {
|
|
802
1281
|
appName,
|
|
803
1282
|
context,
|
|
804
|
-
setIosSwipeGestureEnabled,
|
|
1283
|
+
setIosSwipeGestureEnabled: setIosSwipeGestureEnabled2,
|
|
805
1284
|
router: {
|
|
806
1285
|
screenContainer: AppsInTossScreenContainer,
|
|
807
1286
|
defaultScreenOption: {
|
|
@@ -814,11 +1293,8 @@ function registerApp(container, { context, analytics }) {
|
|
|
814
1293
|
return global.Page;
|
|
815
1294
|
}
|
|
816
1295
|
function AppsInTossScreenContainer({ children }) {
|
|
817
|
-
const
|
|
818
|
-
return /* @__PURE__ */
|
|
819
|
-
isReactNativeService && /* @__PURE__ */ jsx6(RNNavigationBar, {}),
|
|
820
|
-
children
|
|
821
|
-
] });
|
|
1296
|
+
const isRNApp = getAppsInTossGlobals().webViewType == null;
|
|
1297
|
+
return /* @__PURE__ */ jsx10(Analytics.Screen, { children: isRNApp ? /* @__PURE__ */ jsx10(RNAppContainer, { children }) : children });
|
|
822
1298
|
}
|
|
823
1299
|
function getAppName() {
|
|
824
1300
|
try {
|
|
@@ -840,7 +1316,7 @@ import {
|
|
|
840
1316
|
IAP,
|
|
841
1317
|
Storage,
|
|
842
1318
|
AppsInTossModule,
|
|
843
|
-
appsInTossEvent as
|
|
1319
|
+
appsInTossEvent as appsInTossEvent4,
|
|
844
1320
|
iapCreateOneTimePurchaseOrder,
|
|
845
1321
|
processProductGrant,
|
|
846
1322
|
requestOneTimePurchase
|
|
@@ -850,342 +1326,28 @@ import * as appsInTossConstantBridges from "@apps-in-toss/native-modules/constan
|
|
|
850
1326
|
import * as appsInTossEventBridges from "@apps-in-toss/native-modules/event-bridges";
|
|
851
1327
|
import { getSchemeUri as getSchemeUri6 } from "@granite-js/react-native";
|
|
852
1328
|
import { ExternalWebViewScreen, tdsEvent } from "@toss/tds-react-native";
|
|
853
|
-
import { useSafeAreaBottom, useSafeAreaTop as
|
|
854
|
-
import { useEffect as
|
|
855
|
-
import { BackHandler as BackHandler2, Platform as
|
|
1329
|
+
import { useSafeAreaBottom, useSafeAreaTop as useSafeAreaTop3, useTopNavigation } from "@toss/tds-react-native/private";
|
|
1330
|
+
import { useEffect as useEffect12, useMemo as useMemo6, useRef as useRef6, useState as useState7 } from "react";
|
|
1331
|
+
import { BackHandler as BackHandler2, Platform as Platform6 } from "react-native";
|
|
856
1332
|
|
|
857
1333
|
// src/components/GameWebView.tsx
|
|
858
|
-
import { setIosSwipeGestureEnabled as
|
|
1334
|
+
import { setIosSwipeGestureEnabled as setIosSwipeGestureEnabled3, appsInTossEvent as appsInTossEvent3, getOperationalEnvironment as getOperationalEnvironment3 } from "@apps-in-toss/native-modules";
|
|
859
1335
|
import {
|
|
860
1336
|
WebView as PlainWebView
|
|
861
1337
|
} from "@granite-js/native/react-native-webview";
|
|
862
|
-
import { forwardRef, useEffect as
|
|
863
|
-
import { Platform as
|
|
864
|
-
|
|
865
|
-
// src/components/GameProfile.tsx
|
|
866
|
-
import { getGameCenterGameProfile as getGameCenterGameProfile2, isMinVersionSupported as isMinVersionSupported3 } from "@apps-in-toss/native-modules";
|
|
867
|
-
import { Loader } from "@toss/tds-react-native";
|
|
868
|
-
import { useEffect as useEffect8 } from "react";
|
|
869
|
-
import { Pressable, View } from "react-native";
|
|
870
|
-
|
|
871
|
-
// src/constant/game-center.ts
|
|
872
|
-
var GAME_PROFILE_WEBVIEW_URL = "servicetoss://game-center/profile";
|
|
873
|
-
var GAME_CENTER_MIN_VERSION = {
|
|
874
|
-
android: "5.221.0",
|
|
875
|
-
ios: "5.221.0"
|
|
876
|
-
};
|
|
877
|
-
|
|
878
|
-
// src/hooks/useGameCenterProfile.ts
|
|
879
|
-
import { getGameCenterGameProfile } from "@apps-in-toss/native-modules";
|
|
880
|
-
import { closeView as closeView2, openURL as openURL5 } from "@granite-js/react-native";
|
|
881
|
-
import { useDialog as useDialog4 } from "@toss/tds-react-native";
|
|
882
|
-
import { josa as josa2 } from "es-hangul";
|
|
883
|
-
import { useCallback as useCallback4, useRef as useRef3, useState as useState2 } from "react";
|
|
884
|
-
|
|
885
|
-
// src/components/GameProfileToast.tsx
|
|
886
|
-
import { Asset, Toast } from "@toss/tds-react-native";
|
|
887
|
-
import { AdaptiveColorProvider, ColorPreferenceProvider, useOverlay as useOverlay2 } from "@toss/tds-react-native/private";
|
|
888
|
-
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
889
|
-
var useGameProfileToast = () => {
|
|
890
|
-
const overlay = useOverlay2();
|
|
891
|
-
const openGameProfileToast = (nickname, profileImageUri) => {
|
|
892
|
-
return new Promise((resolve) => {
|
|
893
|
-
overlay.open(({ isOpen, close, exit }) => {
|
|
894
|
-
return /* @__PURE__ */ jsx7(ColorPreferenceProvider, { colorPreference: "dark", children: /* @__PURE__ */ jsx7(AdaptiveColorProvider, { children: /* @__PURE__ */ jsx7(
|
|
895
|
-
Toast,
|
|
896
|
-
{
|
|
897
|
-
open: isOpen,
|
|
898
|
-
onClose: () => {
|
|
899
|
-
resolve();
|
|
900
|
-
close();
|
|
901
|
-
},
|
|
902
|
-
onExited: exit,
|
|
903
|
-
position: "top",
|
|
904
|
-
text: `${nickname}\uB2D8 \uBC18\uAC00\uC6CC\uC694!`,
|
|
905
|
-
icon: /* @__PURE__ */ jsx7(
|
|
906
|
-
Asset.Image,
|
|
907
|
-
{
|
|
908
|
-
style: { borderRadius: 64, overflow: "hidden" },
|
|
909
|
-
frameShape: Asset.frameShape.CleanW32,
|
|
910
|
-
source: { uri: profileImageUri }
|
|
911
|
-
}
|
|
912
|
-
)
|
|
913
|
-
}
|
|
914
|
-
) }) });
|
|
915
|
-
});
|
|
916
|
-
});
|
|
917
|
-
};
|
|
918
|
-
return { openGameProfileToast };
|
|
919
|
-
};
|
|
920
|
-
|
|
921
|
-
// src/utils/error.ts
|
|
922
|
-
var DEFAULT_ERROR = {
|
|
923
|
-
title: "\uC7A0\uC2DC \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694",
|
|
924
|
-
description: "\uBB38\uC81C\uAC00 \uACC4\uC18D\uB418\uBA74 \uD1A0\uC2A4 \uACE0\uAC1D\uC13C\uD130(1599-4905)\uB85C \uBB38\uC758\uD574\uC8FC\uC138\uC694."
|
|
925
|
-
};
|
|
926
|
-
|
|
927
|
-
// src/utils/openTransparentWebView.ts
|
|
928
|
-
import { openURL as openURL4 } from "@granite-js/react-native";
|
|
929
|
-
|
|
930
|
-
// src/private.ts
|
|
931
|
-
import { onVisibilityChangedByTransparentServiceWeb } from "@apps-in-toss/native-modules";
|
|
932
|
-
var INTERNAL__onVisibilityChangedByTransparentServiceWeb = onVisibilityChangedByTransparentServiceWeb;
|
|
933
|
-
|
|
934
|
-
// src/utils/openTransparentWebView.ts
|
|
935
|
-
var openTransparentWebView = ({
|
|
936
|
-
webUrl,
|
|
937
|
-
cleanupWhenDismissed = true,
|
|
938
|
-
onEvent,
|
|
939
|
-
onError,
|
|
940
|
-
callbackId = "fn",
|
|
941
|
-
params
|
|
942
|
-
}) => {
|
|
943
|
-
const url = new URL("supertoss://transparent-service-web");
|
|
944
|
-
url.searchParams.set("url", webUrl);
|
|
945
|
-
url.searchParams.set("onVisibilityChangeCallback", callbackId);
|
|
946
|
-
Object.entries(params ?? {}).forEach(([key, value]) => {
|
|
947
|
-
url.searchParams.set(key, value);
|
|
948
|
-
});
|
|
949
|
-
const cleanup = INTERNAL__onVisibilityChangedByTransparentServiceWeb({
|
|
950
|
-
options: { callbackId },
|
|
951
|
-
onError: (error) => {
|
|
952
|
-
onError(error);
|
|
953
|
-
cleanup();
|
|
954
|
-
},
|
|
955
|
-
onEvent: (value) => {
|
|
956
|
-
onEvent(value);
|
|
957
|
-
if (cleanupWhenDismissed && value === true) {
|
|
958
|
-
cleanup();
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
});
|
|
962
|
-
openURL4(url.toString());
|
|
963
|
-
};
|
|
964
|
-
|
|
965
|
-
// src/hooks/useGameCenterProfile.ts
|
|
966
|
-
var useGameCenterProfile = (isReadyForProfileUI) => {
|
|
967
|
-
const [profileData, setProfileData] = useState2(void 0);
|
|
968
|
-
const [isProfileDataLoading, setIsProfileDataLoading] = useState2(true);
|
|
969
|
-
const [isProfileDataRefetching, setIsProfileDataRefetching] = useState2(false);
|
|
970
|
-
const shouldShowLoadingOverlay = isProfileDataLoading && isReadyForProfileUI;
|
|
971
|
-
const shouldShowProfileNotFoundOverlay = profileData?.statusCode === "PROFILE_NOT_FOUND" && isReadyForProfileUI && !isProfileDataRefetching;
|
|
972
|
-
const canShowBottomSheetOrToast = !isProfileDataLoading && isReadyForProfileUI;
|
|
973
|
-
const [isWebviewLoading, setIsWebviewLoading] = useState2(false);
|
|
974
|
-
const isCompletedProfileFlow = useRef3(false);
|
|
975
|
-
const { openAlert, openConfirm } = useDialog4();
|
|
976
|
-
const { openGameProfileToast } = useGameProfileToast();
|
|
977
|
-
const openErrorAlert = useCallback4(async () => {
|
|
978
|
-
await openAlert({
|
|
979
|
-
title: DEFAULT_ERROR.title,
|
|
980
|
-
description: DEFAULT_ERROR.description
|
|
981
|
-
});
|
|
982
|
-
closeView2();
|
|
983
|
-
}, [openAlert]);
|
|
984
|
-
const openProfileWebview = useCallback4(() => {
|
|
985
|
-
if (isWebviewLoading) {
|
|
986
|
-
return;
|
|
987
|
-
}
|
|
988
|
-
setIsWebviewLoading(true);
|
|
989
|
-
openTransparentWebView({
|
|
990
|
-
webUrl: `${GAME_PROFILE_WEBVIEW_URL}?appName=${getAppName()}&referrer=appsintoss.${getAppName()}`,
|
|
991
|
-
onEvent: async (isClosedTransparentWebView) => {
|
|
992
|
-
if (isClosedTransparentWebView) {
|
|
993
|
-
try {
|
|
994
|
-
setIsWebviewLoading(false);
|
|
995
|
-
setIsProfileDataRefetching(true);
|
|
996
|
-
const data = await getGameCenterGameProfile();
|
|
997
|
-
setProfileData(data);
|
|
998
|
-
setIsProfileDataRefetching(false);
|
|
999
|
-
if (data?.statusCode === "SUCCESS") {
|
|
1000
|
-
openGameProfileToast(data.nickname, data.profileImageUri);
|
|
1001
|
-
}
|
|
1002
|
-
} catch (_) {
|
|
1003
|
-
setIsProfileDataRefetching(false);
|
|
1004
|
-
openErrorAlert();
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
},
|
|
1008
|
-
onError: () => {
|
|
1009
|
-
openErrorAlert();
|
|
1010
|
-
}
|
|
1011
|
-
});
|
|
1012
|
-
}, [isWebviewLoading, openGameProfileToast, openErrorAlert]);
|
|
1013
|
-
const updateAppToSupportedMinVersion = useCallback4(async () => {
|
|
1014
|
-
const upddateConfirmDialogLabel = {
|
|
1015
|
-
title: `${josa2(getAppsInTossGlobals().brandDisplayName, "\uC744/\uB97C")} \uD558\uB824\uBA74
|
|
1016
|
-
\uC571\uC744 \uC5C5\uB370\uC774\uD2B8\uD574\uC8FC\uC138\uC694`,
|
|
1017
|
-
leftButton: "\uB2EB\uAE30",
|
|
1018
|
-
rightButton: "\uC5C5\uB370\uC774\uD2B8\uD558\uAE30"
|
|
1019
|
-
};
|
|
1020
|
-
const isConfirmed = await openConfirm({
|
|
1021
|
-
title: upddateConfirmDialogLabel.title,
|
|
1022
|
-
leftButton: upddateConfirmDialogLabel.leftButton,
|
|
1023
|
-
rightButton: upddateConfirmDialogLabel.rightButton,
|
|
1024
|
-
closeOnDimmerClick: true
|
|
1025
|
-
});
|
|
1026
|
-
if (!isConfirmed) {
|
|
1027
|
-
closeView2();
|
|
1028
|
-
return;
|
|
1029
|
-
}
|
|
1030
|
-
const STORE_SCHEME = getMarketLink();
|
|
1031
|
-
openURL5(`supertoss://web?url=${STORE_SCHEME}&external=browser`);
|
|
1032
|
-
}, [openConfirm]);
|
|
1033
|
-
return {
|
|
1034
|
-
profileData,
|
|
1035
|
-
isProfileDataLoading,
|
|
1036
|
-
isProfileDataRefetching,
|
|
1037
|
-
shouldShowLoadingOverlay,
|
|
1038
|
-
shouldShowProfileNotFoundOverlay,
|
|
1039
|
-
canShowBottomSheetOrToast,
|
|
1040
|
-
isCompletedProfileFlow,
|
|
1041
|
-
updateAppToSupportedMinVersion,
|
|
1042
|
-
setIsProfileDataLoading,
|
|
1043
|
-
openProfileWebview,
|
|
1044
|
-
setProfileData,
|
|
1045
|
-
openErrorAlert,
|
|
1046
|
-
openGameProfileToast
|
|
1047
|
-
};
|
|
1048
|
-
};
|
|
1049
|
-
|
|
1050
|
-
// src/utils/zIndex.ts
|
|
1051
|
-
var Z_INDEX = {
|
|
1052
|
-
/* 게임 프로필을 위한 overlay
|
|
1053
|
-
*/
|
|
1054
|
-
PROFILE_OVERLAY: 9998,
|
|
1055
|
-
// 게임을 종료할 수 있는 X 버튼
|
|
1056
|
-
CLOSE_BUTTON: 9999
|
|
1057
|
-
};
|
|
1058
|
-
|
|
1059
|
-
// src/components/GameProfile.tsx
|
|
1060
|
-
import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1061
|
-
var GameProfile = ({ children, isReadyForProfileUI }) => {
|
|
1062
|
-
const {
|
|
1063
|
-
profileData,
|
|
1064
|
-
isProfileDataRefetching,
|
|
1065
|
-
shouldShowLoadingOverlay,
|
|
1066
|
-
shouldShowProfileNotFoundOverlay,
|
|
1067
|
-
canShowBottomSheetOrToast,
|
|
1068
|
-
isCompletedProfileFlow,
|
|
1069
|
-
openProfileWebview,
|
|
1070
|
-
updateAppToSupportedMinVersion,
|
|
1071
|
-
setIsProfileDataLoading,
|
|
1072
|
-
setProfileData,
|
|
1073
|
-
openErrorAlert,
|
|
1074
|
-
openGameProfileToast
|
|
1075
|
-
} = useGameCenterProfile(isReadyForProfileUI);
|
|
1076
|
-
useEffect8(() => {
|
|
1077
|
-
try {
|
|
1078
|
-
const getProfileData = async () => {
|
|
1079
|
-
const data = await getGameCenterGameProfile2();
|
|
1080
|
-
setProfileData(data);
|
|
1081
|
-
setIsProfileDataLoading(false);
|
|
1082
|
-
};
|
|
1083
|
-
getProfileData();
|
|
1084
|
-
} catch (_) {
|
|
1085
|
-
openErrorAlert();
|
|
1086
|
-
setIsProfileDataLoading(false);
|
|
1087
|
-
}
|
|
1088
|
-
}, []);
|
|
1089
|
-
useEffect8(() => {
|
|
1090
|
-
const handleGameProfileFlow = async () => {
|
|
1091
|
-
if (!canShowBottomSheetOrToast) {
|
|
1092
|
-
return;
|
|
1093
|
-
}
|
|
1094
|
-
if (isCompletedProfileFlow.current) {
|
|
1095
|
-
return;
|
|
1096
|
-
}
|
|
1097
|
-
isCompletedProfileFlow.current = true;
|
|
1098
|
-
if (!isMinVersionSupported3(GAME_CENTER_MIN_VERSION)) {
|
|
1099
|
-
updateAppToSupportedMinVersion();
|
|
1100
|
-
return;
|
|
1101
|
-
}
|
|
1102
|
-
if (profileData?.statusCode === "SUCCESS") {
|
|
1103
|
-
openGameProfileToast(profileData.nickname, profileData.profileImageUri);
|
|
1104
|
-
return;
|
|
1105
|
-
}
|
|
1106
|
-
if (profileData?.statusCode === "PROFILE_NOT_FOUND") {
|
|
1107
|
-
openProfileWebview();
|
|
1108
|
-
}
|
|
1109
|
-
};
|
|
1110
|
-
handleGameProfileFlow();
|
|
1111
|
-
}, [
|
|
1112
|
-
canShowBottomSheetOrToast,
|
|
1113
|
-
isCompletedProfileFlow,
|
|
1114
|
-
openGameProfileToast,
|
|
1115
|
-
openProfileWebview,
|
|
1116
|
-
profileData,
|
|
1117
|
-
updateAppToSupportedMinVersion
|
|
1118
|
-
]);
|
|
1119
|
-
if (!isMinVersionSupported3(GAME_CENTER_MIN_VERSION)) {
|
|
1120
|
-
return /* @__PURE__ */ jsxs3(Fragment5, { children: [
|
|
1121
|
-
/* @__PURE__ */ jsx8(View, { style: { flex: 1, position: "relative" }, children }),
|
|
1122
|
-
/* @__PURE__ */ jsx8(
|
|
1123
|
-
Pressable,
|
|
1124
|
-
{
|
|
1125
|
-
style: {
|
|
1126
|
-
...overlayStyle
|
|
1127
|
-
},
|
|
1128
|
-
onPress: () => {
|
|
1129
|
-
updateAppToSupportedMinVersion();
|
|
1130
|
-
}
|
|
1131
|
-
}
|
|
1132
|
-
)
|
|
1133
|
-
] });
|
|
1134
|
-
}
|
|
1135
|
-
if (shouldShowLoadingOverlay || isProfileDataRefetching) {
|
|
1136
|
-
return /* @__PURE__ */ jsxs3(Fragment5, { children: [
|
|
1137
|
-
/* @__PURE__ */ jsx8(View, { style: { flex: 1, position: "relative" }, children }),
|
|
1138
|
-
/* @__PURE__ */ jsx8(
|
|
1139
|
-
View,
|
|
1140
|
-
{
|
|
1141
|
-
style: {
|
|
1142
|
-
...overlayStyle,
|
|
1143
|
-
justifyContent: "center",
|
|
1144
|
-
alignItems: "center",
|
|
1145
|
-
backgroundColor: "rgba(0, 0, 0, 0.2)"
|
|
1146
|
-
},
|
|
1147
|
-
children: /* @__PURE__ */ jsx8(Loader, { size: "large", type: "light" })
|
|
1148
|
-
}
|
|
1149
|
-
)
|
|
1150
|
-
] });
|
|
1151
|
-
}
|
|
1152
|
-
if (shouldShowProfileNotFoundOverlay) {
|
|
1153
|
-
return /* @__PURE__ */ jsxs3(Fragment5, { children: [
|
|
1154
|
-
/* @__PURE__ */ jsx8(View, { style: { flex: 1, position: "relative" }, children }),
|
|
1155
|
-
shouldShowProfileNotFoundOverlay && /* @__PURE__ */ jsx8(
|
|
1156
|
-
Pressable,
|
|
1157
|
-
{
|
|
1158
|
-
style: {
|
|
1159
|
-
...overlayStyle
|
|
1160
|
-
},
|
|
1161
|
-
onPress: () => {
|
|
1162
|
-
openProfileWebview();
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
)
|
|
1166
|
-
] });
|
|
1167
|
-
}
|
|
1168
|
-
return /* @__PURE__ */ jsx8(Fragment5, { children: /* @__PURE__ */ jsx8(View, { style: { flex: 1, position: "relative" }, children }) });
|
|
1169
|
-
};
|
|
1170
|
-
var overlayStyle = {
|
|
1171
|
-
position: "absolute",
|
|
1172
|
-
top: 0,
|
|
1173
|
-
left: 0,
|
|
1174
|
-
right: 0,
|
|
1175
|
-
bottom: 0,
|
|
1176
|
-
zIndex: Z_INDEX.PROFILE_OVERLAY
|
|
1177
|
-
};
|
|
1338
|
+
import { forwardRef, useEffect as useEffect10, useState as useState5 } from "react";
|
|
1339
|
+
import { Platform as Platform5 } from "react-native";
|
|
1178
1340
|
|
|
1179
1341
|
// src/components/NavigationBar/GameWebviewNavigationBar.tsx
|
|
1180
|
-
import { closeView as
|
|
1181
|
-
import { PageNavbar, useDialog as useDialog5 } from "@toss/tds-react-native";
|
|
1182
|
-
import { NavigationRightContent, useSafeAreaTop } from "@toss/tds-react-native/private";
|
|
1342
|
+
import { closeView as closeView4 } from "@granite-js/react-native";
|
|
1343
|
+
import { PageNavbar as PageNavbar2, useDialog as useDialog5 } from "@toss/tds-react-native";
|
|
1344
|
+
import { NavigationRightContent as NavigationRightContent2, useSafeAreaTop as useSafeAreaTop2 } from "@toss/tds-react-native/private";
|
|
1183
1345
|
import { josa as josa3 } from "es-hangul";
|
|
1184
|
-
import { useCallback as
|
|
1185
|
-
import { Platform as
|
|
1186
|
-
import { Fragment as
|
|
1346
|
+
import { useCallback as useCallback8 } from "react";
|
|
1347
|
+
import { Platform as Platform4, View as View3 } from "react-native";
|
|
1348
|
+
import { Fragment as Fragment8, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1187
1349
|
function GameWebviewNavigationBar() {
|
|
1188
|
-
const safeAreaTop =
|
|
1350
|
+
const safeAreaTop = useSafeAreaTop2();
|
|
1189
1351
|
const { openConfirm } = useDialog5();
|
|
1190
1352
|
const { captureExitLog } = useCaptureExitLog();
|
|
1191
1353
|
const global2 = getAppsInTossGlobals();
|
|
@@ -1193,7 +1355,7 @@ function GameWebviewNavigationBar() {
|
|
|
1193
1355
|
const { open: openMoreButtonBottomSheet } = useMoreButtonBottomSheet();
|
|
1194
1356
|
const parsedNavigationBar = global2.navigationBar != null ? safeParseNavigationBar(global2.navigationBar) : null;
|
|
1195
1357
|
const initialAccessoryButton = parsedNavigationBar?.initialAccessoryButton;
|
|
1196
|
-
const handleGameWebviewClose =
|
|
1358
|
+
const handleGameWebviewClose = useCallback8(async () => {
|
|
1197
1359
|
logging.closeButtonClick();
|
|
1198
1360
|
const isConfirmed = await openConfirm({
|
|
1199
1361
|
title: `${josa3(global2.brandDisplayName, "\uC744/\uB97C")} \uC885\uB8CC\uD560\uAE4C\uC694?`,
|
|
@@ -1205,18 +1367,18 @@ function GameWebviewNavigationBar() {
|
|
|
1205
1367
|
logging.closePopupCtaClick(isConfirmed);
|
|
1206
1368
|
if (isConfirmed) {
|
|
1207
1369
|
captureExitLog(Date.now());
|
|
1208
|
-
|
|
1370
|
+
closeView4();
|
|
1209
1371
|
}
|
|
1210
1372
|
}, [captureExitLog, global2.brandDisplayName, logging, openConfirm]);
|
|
1211
|
-
return /* @__PURE__ */
|
|
1212
|
-
/* @__PURE__ */
|
|
1213
|
-
/* @__PURE__ */
|
|
1214
|
-
|
|
1373
|
+
return /* @__PURE__ */ jsxs6(Fragment8, { children: [
|
|
1374
|
+
/* @__PURE__ */ jsx11(PageNavbar2, { preference: { type: "none" } }),
|
|
1375
|
+
/* @__PURE__ */ jsx11(
|
|
1376
|
+
View3,
|
|
1215
1377
|
{
|
|
1216
1378
|
style: {
|
|
1217
1379
|
width: "100%",
|
|
1218
1380
|
// TODO: UI관련 스타일 설정은 TDS로 이관
|
|
1219
|
-
height:
|
|
1381
|
+
height: Platform4.OS === "ios" ? 44 : 54,
|
|
1220
1382
|
flexDirection: "row",
|
|
1221
1383
|
alignItems: "center",
|
|
1222
1384
|
justifyContent: "flex-end",
|
|
@@ -1226,8 +1388,8 @@ function GameWebviewNavigationBar() {
|
|
|
1226
1388
|
paddingRight: 10
|
|
1227
1389
|
},
|
|
1228
1390
|
pointerEvents: "box-none",
|
|
1229
|
-
children: /* @__PURE__ */
|
|
1230
|
-
|
|
1391
|
+
children: /* @__PURE__ */ jsx11(
|
|
1392
|
+
NavigationRightContent2,
|
|
1231
1393
|
{
|
|
1232
1394
|
fixedRightButton: initialAccessoryButton,
|
|
1233
1395
|
onPressDots: openMoreButtonBottomSheet,
|
|
@@ -1243,28 +1405,28 @@ function GameWebviewNavigationBar() {
|
|
|
1243
1405
|
}
|
|
1244
1406
|
|
|
1245
1407
|
// src/components/GameWebView.tsx
|
|
1246
|
-
import { Fragment as
|
|
1408
|
+
import { Fragment as Fragment9, jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1247
1409
|
var GameWebView = forwardRef(function GameWebView2(props, ref) {
|
|
1248
|
-
const [isEntryMessageExited, setIsEntryMessageExited] =
|
|
1249
|
-
|
|
1250
|
-
if (
|
|
1251
|
-
|
|
1410
|
+
const [isEntryMessageExited, setIsEntryMessageExited] = useState5(false);
|
|
1411
|
+
useEffect10(() => {
|
|
1412
|
+
if (Platform5.OS === "ios") {
|
|
1413
|
+
setIosSwipeGestureEnabled3({ isEnabled: false });
|
|
1252
1414
|
return () => {
|
|
1253
|
-
|
|
1415
|
+
setIosSwipeGestureEnabled3({ isEnabled: true });
|
|
1254
1416
|
};
|
|
1255
1417
|
}
|
|
1256
1418
|
return;
|
|
1257
1419
|
}, []);
|
|
1258
|
-
|
|
1259
|
-
|
|
1420
|
+
useEffect10(() => {
|
|
1421
|
+
appsInTossEvent3.addEventListener("entryMessageExited", {
|
|
1260
1422
|
onEvent: () => {
|
|
1261
1423
|
setIsEntryMessageExited(true);
|
|
1262
1424
|
}
|
|
1263
1425
|
});
|
|
1264
1426
|
}, []);
|
|
1265
|
-
return /* @__PURE__ */
|
|
1266
|
-
/* @__PURE__ */
|
|
1267
|
-
|
|
1427
|
+
return /* @__PURE__ */ jsxs7(Fragment9, { children: [
|
|
1428
|
+
/* @__PURE__ */ jsx12(GameWebviewNavigationBar, {}),
|
|
1429
|
+
getOperationalEnvironment3() === "toss" ? /* @__PURE__ */ jsx12(GameInitializer, { isReadyForProfileUI: isEntryMessageExited, children: /* @__PURE__ */ jsx12(PlainWebView, { ref, ...props }) }) : /* @__PURE__ */ jsx12(PlainWebView, { ref, ...props })
|
|
1268
1430
|
] });
|
|
1269
1431
|
});
|
|
1270
1432
|
|
|
@@ -1275,12 +1437,12 @@ import {
|
|
|
1275
1437
|
import { forwardRef as forwardRef2 } from "react";
|
|
1276
1438
|
|
|
1277
1439
|
// src/components/NavigationBar/PartnerWebviewNavigationBar.tsx
|
|
1278
|
-
import { closeView as
|
|
1440
|
+
import { closeView as closeView5 } from "@granite-js/react-native";
|
|
1279
1441
|
import { useDialog as useDialog6 } from "@toss/tds-react-native";
|
|
1280
1442
|
import { NavigationBackButton as NavigationBackButton2, NavigationLeft as NavigationLeft2, TopNavigation as TopNavigation2 } from "@toss/tds-react-native/private";
|
|
1281
1443
|
import { josa as josa4 } from "es-hangul";
|
|
1282
|
-
import { useCallback as
|
|
1283
|
-
import { jsx as
|
|
1444
|
+
import { useCallback as useCallback9 } from "react";
|
|
1445
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1284
1446
|
function PartnerWebviewNavigationBar({ onBackButtonClick, onHomeButtonClick }) {
|
|
1285
1447
|
const globals = getAppsInTossGlobals();
|
|
1286
1448
|
const { captureExitLog } = useCaptureExitLog();
|
|
@@ -1291,7 +1453,7 @@ function PartnerWebviewNavigationBar({ onBackButtonClick, onHomeButtonClick }) {
|
|
|
1291
1453
|
const withHomeButton = parsedNavigationBar?.withHomeButton ?? false;
|
|
1292
1454
|
const withBackButton = parsedNavigationBar?.withBackButton ?? true;
|
|
1293
1455
|
const initialAccessoryButton = parsedNavigationBar?.initialAccessoryButton;
|
|
1294
|
-
const handleClose =
|
|
1456
|
+
const handleClose = useCallback9(async () => {
|
|
1295
1457
|
logging.closeButtonClick();
|
|
1296
1458
|
const isConfirmed = await openConfirm({
|
|
1297
1459
|
title: `${josa4(globals.brandDisplayName, "\uC744/\uB97C")} \uC885\uB8CC\uD560\uAE4C\uC694?`,
|
|
@@ -1303,10 +1465,10 @@ function PartnerWebviewNavigationBar({ onBackButtonClick, onHomeButtonClick }) {
|
|
|
1303
1465
|
logging.closePopupCtaClick(isConfirmed);
|
|
1304
1466
|
if (isConfirmed) {
|
|
1305
1467
|
captureExitLog(Date.now());
|
|
1306
|
-
|
|
1468
|
+
closeView5();
|
|
1307
1469
|
}
|
|
1308
1470
|
}, [captureExitLog, globals.brandDisplayName, logging, openConfirm]);
|
|
1309
|
-
return /* @__PURE__ */
|
|
1471
|
+
return /* @__PURE__ */ jsx13(NavigationBarImpressionArea, { withHomeButton, children: /* @__PURE__ */ jsx13(
|
|
1310
1472
|
TopNavigation2,
|
|
1311
1473
|
{
|
|
1312
1474
|
title: globals.brandDisplayName,
|
|
@@ -1317,22 +1479,22 @@ function PartnerWebviewNavigationBar({ onBackButtonClick, onHomeButtonClick }) {
|
|
|
1317
1479
|
onPressClose: handleClose,
|
|
1318
1480
|
withHome: withHomeButton,
|
|
1319
1481
|
fixedRightButton: initialAccessoryButton,
|
|
1320
|
-
children: /* @__PURE__ */
|
|
1482
|
+
children: /* @__PURE__ */ jsx13(NavigationLeft2, { visible: withBackButton, children: /* @__PURE__ */ jsx13(NavigationBackButton2, { onPress: onBackButtonClick, canGoBack: false }) })
|
|
1321
1483
|
}
|
|
1322
1484
|
) });
|
|
1323
1485
|
}
|
|
1324
1486
|
|
|
1325
1487
|
// src/components/PartnerWebView.tsx
|
|
1326
|
-
import { Fragment as
|
|
1488
|
+
import { Fragment as Fragment10, jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1327
1489
|
var PartnerWebView = forwardRef2(function PartnerWebViewScreen({ onBackButtonClick, onHomeButtonClick, ...webViewProps }, ref) {
|
|
1328
|
-
return /* @__PURE__ */
|
|
1329
|
-
/* @__PURE__ */
|
|
1330
|
-
/* @__PURE__ */
|
|
1490
|
+
return /* @__PURE__ */ jsxs8(Fragment10, { children: [
|
|
1491
|
+
/* @__PURE__ */ jsx14(PartnerWebviewNavigationBar, { onBackButtonClick, onHomeButtonClick }),
|
|
1492
|
+
/* @__PURE__ */ jsx14(PlainWebView2, { ref, ...webViewProps, style: { flex: 1 } })
|
|
1331
1493
|
] });
|
|
1332
1494
|
});
|
|
1333
1495
|
|
|
1334
1496
|
// src/bridge-handler/useBridgeHandler.tsx
|
|
1335
|
-
import { useCallback as
|
|
1497
|
+
import { useCallback as useCallback10, useMemo as useMemo3, useRef as useRef4 } from "react";
|
|
1336
1498
|
function serializeError(error) {
|
|
1337
1499
|
return JSON.stringify(error, (_, value) => {
|
|
1338
1500
|
if (value instanceof Error) {
|
|
@@ -1386,7 +1548,7 @@ function useBridgeHandler({
|
|
|
1386
1548
|
injectedJavaScript: originalInjectedJavaScript
|
|
1387
1549
|
}) {
|
|
1388
1550
|
const ref = useRef4(null);
|
|
1389
|
-
const injectedJavaScript =
|
|
1551
|
+
const injectedJavaScript = useMemo3(
|
|
1390
1552
|
() => [
|
|
1391
1553
|
`window.__CONSTANT_HANDLER_MAP = ${JSON.stringify(
|
|
1392
1554
|
Object.entries(constantHandlerMap).reduce(
|
|
@@ -1413,7 +1575,7 @@ function useBridgeHandler({
|
|
|
1413
1575
|
window.__GRANITE_NATIVE_EMITTER.emit('${functionName}/onError/${eventId}', ${serializedError});
|
|
1414
1576
|
`);
|
|
1415
1577
|
};
|
|
1416
|
-
const $onMessage =
|
|
1578
|
+
const $onMessage = useCallback10(
|
|
1417
1579
|
async (e) => {
|
|
1418
1580
|
onMessage?.(e);
|
|
1419
1581
|
const data = JSON.parse(e.nativeEvent.data);
|
|
@@ -1464,13 +1626,13 @@ function useBridgeHandler({
|
|
|
1464
1626
|
}
|
|
1465
1627
|
|
|
1466
1628
|
// src/core/hooks/useWebBackHandler.tsx
|
|
1467
|
-
import { closeView as
|
|
1629
|
+
import { closeView as closeView6, useBackEventState } from "@granite-js/react-native";
|
|
1468
1630
|
import { useDialog as useDialog7 } from "@toss/tds-react-native";
|
|
1469
1631
|
import { josa as josa5 } from "es-hangul";
|
|
1470
|
-
import { useCallback as
|
|
1632
|
+
import { useCallback as useCallback12, useMemo as useMemo5 } from "react";
|
|
1471
1633
|
|
|
1472
1634
|
// src/hooks/useWebviewHistoryStack.tsx
|
|
1473
|
-
import { useCallback as
|
|
1635
|
+
import { useCallback as useCallback11, useMemo as useMemo4, useReducer } from "react";
|
|
1474
1636
|
var INITIAL_STATE = { stack: [], index: -1 };
|
|
1475
1637
|
function reducer(state, action) {
|
|
1476
1638
|
switch (action.type) {
|
|
@@ -1502,10 +1664,10 @@ function reducer(state, action) {
|
|
|
1502
1664
|
}
|
|
1503
1665
|
function useWebViewHistory() {
|
|
1504
1666
|
const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
|
|
1505
|
-
const onNavigationStateChange =
|
|
1667
|
+
const onNavigationStateChange = useCallback11(({ url, canGoForward: canGoForward2 }) => {
|
|
1506
1668
|
dispatch({ type: "NAVIGATION_CHANGE", url, canGoForward: canGoForward2 });
|
|
1507
1669
|
}, []);
|
|
1508
|
-
const { canGoBack, canGoForward } =
|
|
1670
|
+
const { canGoBack, canGoForward } = useMemo4(() => {
|
|
1509
1671
|
const canBack = state.index > 0;
|
|
1510
1672
|
const canFwd = state.index >= 0 && state.index < state.stack.length - 1;
|
|
1511
1673
|
return { canGoBack: canBack, canGoForward: canFwd };
|
|
@@ -1538,19 +1700,19 @@ function useWebBackHandler(webViewRef) {
|
|
|
1538
1700
|
const logging = useNavigationBarLogging();
|
|
1539
1701
|
const { openConfirm } = useDialog7();
|
|
1540
1702
|
const global2 = getAppsInTossGlobals();
|
|
1541
|
-
const addEventListener =
|
|
1703
|
+
const addEventListener = useCallback12(
|
|
1542
1704
|
(handler) => {
|
|
1543
1705
|
addWebBackEventListener(handler);
|
|
1544
1706
|
},
|
|
1545
1707
|
[addWebBackEventListener]
|
|
1546
1708
|
);
|
|
1547
|
-
const removeEventListener =
|
|
1709
|
+
const removeEventListener = useCallback12(
|
|
1548
1710
|
(handler) => {
|
|
1549
1711
|
removeWebBackEventListener(handler);
|
|
1550
1712
|
},
|
|
1551
1713
|
[removeWebBackEventListener]
|
|
1552
1714
|
);
|
|
1553
|
-
const handleWebBack =
|
|
1715
|
+
const handleWebBack = useCallback12(async () => {
|
|
1554
1716
|
if (hasWebBackEvent) {
|
|
1555
1717
|
for (const handler of webBackHandlersRef) {
|
|
1556
1718
|
handler();
|
|
@@ -1570,7 +1732,7 @@ function useWebBackHandler(webViewRef) {
|
|
|
1570
1732
|
logging.closePopupCtaClick(isConfirmed);
|
|
1571
1733
|
if (isConfirmed) {
|
|
1572
1734
|
captureExitLog(Date.now());
|
|
1573
|
-
|
|
1735
|
+
closeView6();
|
|
1574
1736
|
}
|
|
1575
1737
|
}
|
|
1576
1738
|
}, [
|
|
@@ -1583,7 +1745,7 @@ function useWebBackHandler(webViewRef) {
|
|
|
1583
1745
|
openConfirm,
|
|
1584
1746
|
webViewRef
|
|
1585
1747
|
]);
|
|
1586
|
-
const handleWebHome =
|
|
1748
|
+
const handleWebHome = useCallback12(() => {
|
|
1587
1749
|
logging.homeButtonClick();
|
|
1588
1750
|
if (hasWebBackEvent) {
|
|
1589
1751
|
for (const handler of webBackHandlersRef) {
|
|
@@ -1593,7 +1755,7 @@ function useWebBackHandler(webViewRef) {
|
|
|
1593
1755
|
}
|
|
1594
1756
|
webViewRef.current?.injectJavaScript(HISTORY_HOME_SCRIPT);
|
|
1595
1757
|
}, [hasWebBackEvent, webBackHandlersRef, logging, webViewRef]);
|
|
1596
|
-
return
|
|
1758
|
+
return useMemo5(
|
|
1597
1759
|
() => ({ addEventListener, removeEventListener, handleWebBack, handleWebHome, onNavigationStateChange }),
|
|
1598
1760
|
[addEventListener, removeEventListener, handleWebBack, handleWebHome, onNavigationStateChange]
|
|
1599
1761
|
);
|
|
@@ -1771,11 +1933,11 @@ function useCreateUserAgent({
|
|
|
1771
1933
|
// src/hooks/useGeolocation.ts
|
|
1772
1934
|
import { startUpdateLocation } from "@apps-in-toss/native-modules";
|
|
1773
1935
|
import { useVisibility as useVisibility3 } from "@granite-js/react-native";
|
|
1774
|
-
import { useEffect as
|
|
1936
|
+
import { useEffect as useEffect11, useState as useState6 } from "react";
|
|
1775
1937
|
function useGeolocation({ accuracy, distanceInterval, timeInterval }) {
|
|
1776
1938
|
const isVisible = useVisibility3();
|
|
1777
|
-
const [location, setLocation] =
|
|
1778
|
-
|
|
1939
|
+
const [location, setLocation] = useState6(null);
|
|
1940
|
+
useEffect11(() => {
|
|
1779
1941
|
if (!isVisible) {
|
|
1780
1942
|
return;
|
|
1781
1943
|
}
|
|
@@ -1794,11 +1956,11 @@ function useGeolocation({ accuracy, distanceInterval, timeInterval }) {
|
|
|
1794
1956
|
|
|
1795
1957
|
// src/hooks/useWaitForReturnNavigator.tsx
|
|
1796
1958
|
import { useNavigation as useNavigation2, useVisibilityChange } from "@granite-js/react-native";
|
|
1797
|
-
import { useCallback as
|
|
1959
|
+
import { useCallback as useCallback13, useRef as useRef5 } from "react";
|
|
1798
1960
|
function useWaitForReturnNavigator() {
|
|
1799
1961
|
const callbacks = useRef5([]).current;
|
|
1800
1962
|
const navigation = useNavigation2();
|
|
1801
|
-
const startNavigating =
|
|
1963
|
+
const startNavigating = useCallback13(
|
|
1802
1964
|
(route, params) => {
|
|
1803
1965
|
return new Promise((resolve) => {
|
|
1804
1966
|
callbacks.push(resolve);
|
|
@@ -1807,7 +1969,7 @@ function useWaitForReturnNavigator() {
|
|
|
1807
1969
|
},
|
|
1808
1970
|
[callbacks, navigation]
|
|
1809
1971
|
);
|
|
1810
|
-
const handleVisibilityChange =
|
|
1972
|
+
const handleVisibilityChange = useCallback13(
|
|
1811
1973
|
(state) => {
|
|
1812
1974
|
if (state === "visible" && callbacks.length > 0) {
|
|
1813
1975
|
for (const callback of callbacks) {
|
|
@@ -1872,7 +2034,7 @@ var trackScreen = (url) => {
|
|
|
1872
2034
|
};
|
|
1873
2035
|
|
|
1874
2036
|
// src/components/WebView.tsx
|
|
1875
|
-
import { jsx as
|
|
2037
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1876
2038
|
var operationalEnvironment = appsInTossConstantBridges.getOperationalEnvironment();
|
|
1877
2039
|
var TYPES = ["partner", "external", "game"];
|
|
1878
2040
|
var WEBVIEW_TYPES = {
|
|
@@ -1908,8 +2070,8 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
1908
2070
|
}
|
|
1909
2071
|
const webViewRef = useRef6(null);
|
|
1910
2072
|
const webBackHandler = useWebBackHandler(webViewRef);
|
|
1911
|
-
const uri =
|
|
1912
|
-
const top =
|
|
2073
|
+
const uri = useMemo6(() => getWebViewUri(local), [local]);
|
|
2074
|
+
const top = useSafeAreaTop3();
|
|
1913
2075
|
const bottom = useSafeAreaBottom();
|
|
1914
2076
|
const global2 = getAppsInTossGlobals();
|
|
1915
2077
|
const topNavigation = useTopNavigation();
|
|
@@ -1920,7 +2082,7 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
1920
2082
|
document.head.appendChild(style);
|
|
1921
2083
|
})();
|
|
1922
2084
|
`;
|
|
1923
|
-
const [allowsBackForwardNavigationGestures, setAllowsBackForwardNavigationGestures] =
|
|
2085
|
+
const [allowsBackForwardNavigationGestures, setAllowsBackForwardNavigationGestures] = useState7(
|
|
1924
2086
|
props.allowsBackForwardNavigationGestures
|
|
1925
2087
|
);
|
|
1926
2088
|
const handler = useBridgeHandler({
|
|
@@ -1936,10 +2098,10 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
1936
2098
|
webBackHandler.removeEventListener(onEvent);
|
|
1937
2099
|
};
|
|
1938
2100
|
},
|
|
1939
|
-
entryMessageExited: ({ onEvent, onError }) =>
|
|
1940
|
-
updateLocationEvent: ({ onEvent, onError, options }) =>
|
|
2101
|
+
entryMessageExited: ({ onEvent, onError }) => appsInTossEvent4.addEventListener("entryMessageExited", { onEvent, onError }),
|
|
2102
|
+
updateLocationEvent: ({ onEvent, onError, options }) => appsInTossEvent4.addEventListener("updateLocationEvent", { onEvent, onError, options }),
|
|
1941
2103
|
/** @internal */
|
|
1942
|
-
appBridgeCallbackEvent: ({ onEvent, onError, options }) =>
|
|
2104
|
+
appBridgeCallbackEvent: ({ onEvent, onError, options }) => appsInTossEvent4.addEventListener("appBridgeCallbackEvent", { onEvent, onError, options }),
|
|
1943
2105
|
/** AdMob */
|
|
1944
2106
|
loadAdMobInterstitialAd: GoogleAdMob.loadAdMobInterstitialAd,
|
|
1945
2107
|
showAdMobInterstitialAd: GoogleAdMob.showAdMobInterstitialAd,
|
|
@@ -2000,7 +2162,7 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
2000
2162
|
completeProductGrant: IAP.completeProductGrant
|
|
2001
2163
|
}
|
|
2002
2164
|
});
|
|
2003
|
-
const headerPropForExternalWebView =
|
|
2165
|
+
const headerPropForExternalWebView = useMemo6(() => {
|
|
2004
2166
|
const parsedNavigationBar = global2.navigationBar != null ? safeParseNavigationBar(global2.navigationBar) : null;
|
|
2005
2167
|
const initialAccessoryButton = parsedNavigationBar?.initialAccessoryButton;
|
|
2006
2168
|
const withBackButton = parsedNavigationBar?.withBackButton ?? true;
|
|
@@ -2021,7 +2183,7 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
2021
2183
|
colorPreference: "light"
|
|
2022
2184
|
});
|
|
2023
2185
|
const refs = mergeRefs(handler.ref, webViewRef);
|
|
2024
|
-
|
|
2186
|
+
useEffect12(() => {
|
|
2025
2187
|
const callback = () => {
|
|
2026
2188
|
webBackHandler.handleWebBack();
|
|
2027
2189
|
return true;
|
|
@@ -2029,7 +2191,7 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
2029
2191
|
BackHandler2.addEventListener("hardwareBackPress", callback);
|
|
2030
2192
|
return () => BackHandler2.removeEventListener("hardwareBackPress", callback);
|
|
2031
2193
|
}, [webBackHandler]);
|
|
2032
|
-
return /* @__PURE__ */
|
|
2194
|
+
return /* @__PURE__ */ jsx15(
|
|
2033
2195
|
BaseWebView,
|
|
2034
2196
|
{
|
|
2035
2197
|
ref: refs,
|
|
@@ -2051,14 +2213,14 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
2051
2213
|
props.onNavigationStateChange?.(event);
|
|
2052
2214
|
webBackHandler.onNavigationStateChange(event);
|
|
2053
2215
|
},
|
|
2054
|
-
userAgent:
|
|
2216
|
+
userAgent: Platform6.OS === "ios" ? userAgent : void 0,
|
|
2055
2217
|
sharedCookiesEnabled: true,
|
|
2056
2218
|
webviewDebuggingEnabled: webViewDebuggingEnabled,
|
|
2057
2219
|
thirdPartyCookiesEnabled: true,
|
|
2058
2220
|
onMessage: handler.onMessage,
|
|
2059
2221
|
injectedJavaScript: handler.injectedJavaScript,
|
|
2060
2222
|
injectedJavaScriptBeforeContentLoaded: handler.injectedJavaScript,
|
|
2061
|
-
decelerationRate:
|
|
2223
|
+
decelerationRate: Platform6.OS === "ios" ? 1 : void 0,
|
|
2062
2224
|
allowsBackForwardNavigationGestures
|
|
2063
2225
|
}
|
|
2064
2226
|
);
|