@apps-in-toss/framework 1.12.0 → 1.14.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/README.md +20 -1
- package/dist/index.cjs +69 -59
- package/dist/index.d.cts +17 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.js +75 -67
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
# @apps-in-toss/framework
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
react-native framework for building [apps in toss](https://toss.im/apps-in-toss) services.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# yarn
|
|
9
|
+
yarn add @apps-in-toss/framework
|
|
10
|
+
|
|
11
|
+
# npm
|
|
12
|
+
npm install @apps-in-toss/framework
|
|
13
|
+
|
|
14
|
+
# pnpm
|
|
15
|
+
pnpm add @apps-in-toss/framework
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Links
|
|
19
|
+
|
|
20
|
+
- [Document](https://developers-apps-in-toss.toss.im)
|
|
21
|
+
- [Support](https://techchat-apps-in-toss.toss.im)
|
|
22
|
+
- [Examples](https://github.com/toss/apps-in-toss-examples)
|
|
4
23
|
|
|
5
24
|
## License
|
|
6
25
|
|
package/dist/index.cjs
CHANGED
|
@@ -38,7 +38,9 @@ __export(src_exports, {
|
|
|
38
38
|
OverlayProvider: () => import_private10.OverlayProvider,
|
|
39
39
|
WebView: () => WebView,
|
|
40
40
|
env: () => env,
|
|
41
|
+
homeEvent: () => homeEvent,
|
|
41
42
|
loadFullScreenAd: () => loadFullScreenAd,
|
|
43
|
+
safeAreaInsetsChange: () => safeAreaInsetsChange,
|
|
42
44
|
showFullScreenAd: () => showFullScreenAd,
|
|
43
45
|
useCreateUserAgent: () => useCreateUserAgent,
|
|
44
46
|
useGeolocation: () => useGeolocation,
|
|
@@ -741,6 +743,46 @@ function useCloseConfirm() {
|
|
|
741
743
|
);
|
|
742
744
|
}
|
|
743
745
|
|
|
746
|
+
// src/utils/eventEmitter.ts
|
|
747
|
+
var EventEmitter = class {
|
|
748
|
+
listeners = {};
|
|
749
|
+
subscribe(event, listener) {
|
|
750
|
+
if (!this.listeners[event]) {
|
|
751
|
+
this.listeners[event] = [];
|
|
752
|
+
}
|
|
753
|
+
this.listeners[event].push(listener);
|
|
754
|
+
return () => {
|
|
755
|
+
this.listeners[event] = this.listeners[event]?.filter((l) => l !== listener) ?? [];
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
hasSubscriptions(event) {
|
|
759
|
+
return this.listeners[event] != null && this.listeners[event].length > 0;
|
|
760
|
+
}
|
|
761
|
+
clearSubscriptions(event) {
|
|
762
|
+
this.listeners[event] = [];
|
|
763
|
+
}
|
|
764
|
+
emit(event, ...args) {
|
|
765
|
+
if (!this.listeners[event]) {
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
this.listeners[event].forEach((listener) => listener(...args));
|
|
769
|
+
}
|
|
770
|
+
};
|
|
771
|
+
var eventEmitter = new EventEmitter();
|
|
772
|
+
function createEvent(event) {
|
|
773
|
+
return {
|
|
774
|
+
name: event,
|
|
775
|
+
subscribe: (listener) => eventEmitter.subscribe(event, listener),
|
|
776
|
+
hasSubscriptions: () => eventEmitter.hasSubscriptions(event),
|
|
777
|
+
clearSubscriptions: () => eventEmitter.clearSubscriptions(event),
|
|
778
|
+
emit: (data) => eventEmitter.emit(event, data)
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
// src/events.ts
|
|
783
|
+
var homeEvent = createEvent("homeEvent");
|
|
784
|
+
var safeAreaInsetsChange = createEvent("safeAreaInsetsChange");
|
|
785
|
+
|
|
744
786
|
// src/components/NavigationBar/common/useNavigationBarLogging.tsx
|
|
745
787
|
var import_native_modules7 = require("@apps-in-toss/native-modules");
|
|
746
788
|
var import_react_native13 = require("@granite-js/react-native");
|
|
@@ -855,7 +897,11 @@ function useNavigationEvent() {
|
|
|
855
897
|
},
|
|
856
898
|
handleHomeButtonClick: () => {
|
|
857
899
|
logging.homeButtonClick();
|
|
858
|
-
|
|
900
|
+
if (homeEvent.hasSubscriptions()) {
|
|
901
|
+
homeEvent.emit({});
|
|
902
|
+
} else {
|
|
903
|
+
navigation.navigate("/");
|
|
904
|
+
}
|
|
859
905
|
},
|
|
860
906
|
handleCloseButtonClick: () => {
|
|
861
907
|
logging.closeButtonClick();
|
|
@@ -1083,11 +1129,11 @@ function HomeShortcutMenu() {
|
|
|
1083
1129
|
);
|
|
1084
1130
|
}
|
|
1085
1131
|
|
|
1086
|
-
// src/core/hooks/useMoreButtonBottomSheet/
|
|
1132
|
+
// src/core/hooks/useMoreButtonBottomSheet/SettingsMenu.tsx
|
|
1087
1133
|
var import_native_modules11 = require("@apps-in-toss/native-modules");
|
|
1088
1134
|
var import_react_native20 = require("@granite-js/react-native");
|
|
1089
1135
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1090
|
-
function
|
|
1136
|
+
function SettingsMenu() {
|
|
1091
1137
|
const globals = getAppsInTossGlobals();
|
|
1092
1138
|
if ((0, import_native_modules11.getOperationalEnvironment)() === "sandbox") {
|
|
1093
1139
|
return null;
|
|
@@ -1095,10 +1141,10 @@ function PermissionsMenu() {
|
|
|
1095
1141
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1096
1142
|
Menu,
|
|
1097
1143
|
{
|
|
1098
|
-
title: "\
|
|
1144
|
+
title: "\uC124\uC815",
|
|
1099
1145
|
iconURL: "https://static.toss.im/icons/png/4x/icon-setting-mono.png",
|
|
1100
1146
|
onPress: () => (0, import_react_native20.openURL)(
|
|
1101
|
-
`servicetoss://apps-in-toss-menu/
|
|
1147
|
+
`servicetoss://apps-in-toss-menu/settings?appName=${import_react_native20.Granite.appName}&displayAppName=${globals.brandDisplayName}`
|
|
1102
1148
|
)
|
|
1103
1149
|
}
|
|
1104
1150
|
);
|
|
@@ -1128,7 +1174,7 @@ var MIN_VERSION = {
|
|
|
1128
1174
|
android: "5.246.0",
|
|
1129
1175
|
ios: "5.246.0"
|
|
1130
1176
|
},
|
|
1131
|
-
|
|
1177
|
+
SETTINGS_MENU: {
|
|
1132
1178
|
android: "5.238.0",
|
|
1133
1179
|
ios: "5.237.0"
|
|
1134
1180
|
}
|
|
@@ -1144,7 +1190,7 @@ function useMoreButtonBottomSheet() {
|
|
|
1144
1190
|
const isHomeShortcutSupported = (0, import_native_modules12.isMinVersionSupported)(MIN_VERSION.HOME_SHORTCUT_MENU);
|
|
1145
1191
|
const isBottomSheetSupported = (0, import_native_modules12.isMinVersionSupported)(MIN_VERSION.BOTTOM_SHEET);
|
|
1146
1192
|
const isShareListMenuSupported = (0, import_native_modules12.isMinVersionSupported)(MIN_VERSION.SHARE_LIST_MENU);
|
|
1147
|
-
const
|
|
1193
|
+
const isSettingsMenuSupported = (0, import_native_modules12.isMinVersionSupported)(MIN_VERSION.SETTINGS_MENU);
|
|
1148
1194
|
(0, import_react15.useEffect)(() => {
|
|
1149
1195
|
if (!isBottomSheetSupported) {
|
|
1150
1196
|
return;
|
|
@@ -1157,16 +1203,6 @@ function useMoreButtonBottomSheet() {
|
|
|
1157
1203
|
onError: (error) => console.error("\uBA54\uB274 \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uB294 \uB370 \uC2E4\uD328\uD588\uC5B4\uC694:", error)
|
|
1158
1204
|
}
|
|
1159
1205
|
);
|
|
1160
|
-
if ((0, import_native_modules12.isMinVersionSupported)(MIN_VERSION.PERMISSIONS_MENU)) {
|
|
1161
|
-
import_native_modules12.INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
|
|
1162
|
-
"getAllPermission",
|
|
1163
|
-
{},
|
|
1164
|
-
{
|
|
1165
|
-
onSuccess: (permissions) => setIsPermissionsMenuSupported(permissions.length > 0),
|
|
1166
|
-
onError: (error) => console.error("\uAD8C\uD55C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uB294 \uB370 \uC2E4\uD328\uD588\uC5B4\uC694:", error)
|
|
1167
|
-
}
|
|
1168
|
-
);
|
|
1169
|
-
}
|
|
1170
1206
|
}, [isBottomSheetSupported]);
|
|
1171
1207
|
const onClickHandler = async () => {
|
|
1172
1208
|
logging.open();
|
|
@@ -1218,7 +1254,7 @@ function useMoreButtonBottomSheet() {
|
|
|
1218
1254
|
)),
|
|
1219
1255
|
isHomeShortcutSupported && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HomeShortcutMenu, {}),
|
|
1220
1256
|
isShareListMenuSupported && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AppShareListMenu, {}),
|
|
1221
|
-
|
|
1257
|
+
isSettingsMenuSupported && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SettingsMenu, {})
|
|
1222
1258
|
] })
|
|
1223
1259
|
}
|
|
1224
1260
|
) });
|
|
@@ -2105,40 +2141,18 @@ function parseNativeEventData(data) {
|
|
|
2105
2141
|
}
|
|
2106
2142
|
}
|
|
2107
2143
|
|
|
2108
|
-
// src/core/hooks/
|
|
2144
|
+
// src/core/hooks/useSafeAreaInsetsEvent.tsx
|
|
2109
2145
|
var import_react_native_safe_area_context3 = require("@granite-js/native/react-native-safe-area-context");
|
|
2110
2146
|
var import_react23 = require("react");
|
|
2111
|
-
|
|
2112
|
-
listeners = {};
|
|
2113
|
-
on(event, listener) {
|
|
2114
|
-
if (!this.listeners[event]) {
|
|
2115
|
-
this.listeners[event] = [];
|
|
2116
|
-
}
|
|
2117
|
-
this.listeners[event].push(listener);
|
|
2118
|
-
}
|
|
2119
|
-
emit(event, ...args) {
|
|
2120
|
-
if (!this.listeners[event]) {
|
|
2121
|
-
return;
|
|
2122
|
-
}
|
|
2123
|
-
this.listeners[event].forEach((listener) => listener(...args));
|
|
2124
|
-
}
|
|
2125
|
-
off(event, listener) {
|
|
2126
|
-
if (!this.listeners[event]) {
|
|
2127
|
-
return;
|
|
2128
|
-
}
|
|
2129
|
-
this.listeners[event] = this.listeners[event].filter((l) => l !== listener);
|
|
2130
|
-
}
|
|
2131
|
-
};
|
|
2132
|
-
function useSafeAreaInsetsEmitter() {
|
|
2147
|
+
function useSafeAreaInsetsEvent() {
|
|
2133
2148
|
const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
|
|
2134
|
-
const emitter = (0, import_react23.useMemo)(() => new EventEmitter(), []);
|
|
2135
2149
|
(0, import_react23.useEffect)(() => {
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
}, [
|
|
2141
|
-
return
|
|
2150
|
+
safeAreaInsetsChange.emit(insets);
|
|
2151
|
+
}, [insets]);
|
|
2152
|
+
(0, import_react23.useEffect)(() => {
|
|
2153
|
+
return () => safeAreaInsetsChange.clearSubscriptions();
|
|
2154
|
+
}, []);
|
|
2155
|
+
return safeAreaInsetsChange;
|
|
2142
2156
|
}
|
|
2143
2157
|
|
|
2144
2158
|
// src/core/hooks/useWebBackHandler.tsx
|
|
@@ -2251,10 +2265,8 @@ function useWebBackHandler(webViewInitialURL, webViewRef) {
|
|
|
2251
2265
|
]);
|
|
2252
2266
|
const handleWebHome = (0, import_react25.useCallback)(() => {
|
|
2253
2267
|
logging.homeButtonClick();
|
|
2254
|
-
if (
|
|
2255
|
-
|
|
2256
|
-
handler();
|
|
2257
|
-
}
|
|
2268
|
+
if (homeEvent.hasSubscriptions()) {
|
|
2269
|
+
homeEvent.emit({});
|
|
2258
2270
|
return;
|
|
2259
2271
|
}
|
|
2260
2272
|
webViewRef.current?.injectJavaScript(`
|
|
@@ -2631,7 +2643,7 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
2631
2643
|
const insets = (0, import_react_native_safe_area_context4.useSafeAreaInsets)();
|
|
2632
2644
|
const global2 = getAppsInTossGlobals();
|
|
2633
2645
|
const navigationBarContext = useNavigationBarContext();
|
|
2634
|
-
const
|
|
2646
|
+
const safeAreaInsetsEvent = useSafeAreaInsetsEvent();
|
|
2635
2647
|
const [allowsBackForwardNavigationGestures, setAllowsBackForwardNavigationGestures] = (0, import_react28.useState)(
|
|
2636
2648
|
props.allowsBackForwardNavigationGestures
|
|
2637
2649
|
);
|
|
@@ -2646,13 +2658,9 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
2646
2658
|
webBackHandler.removeEventListener(onEvent);
|
|
2647
2659
|
};
|
|
2648
2660
|
},
|
|
2661
|
+
homeEvent: ({ onEvent }) => homeEvent.subscribe(onEvent),
|
|
2649
2662
|
updateLocationEvent: ({ onEvent, onError, options }) => import_native_modules24.appsInTossEvent.addEventListener("updateLocationEvent", { onEvent, onError, options }),
|
|
2650
|
-
safeAreaInsetsChange: ({ onEvent }) =>
|
|
2651
|
-
safeAreaInsetsEmitter.on("safeAreaInsetsChange", onEvent);
|
|
2652
|
-
return () => {
|
|
2653
|
-
safeAreaInsetsEmitter.off("safeAreaInsetsChange", onEvent);
|
|
2654
|
-
};
|
|
2655
|
-
},
|
|
2663
|
+
safeAreaInsetsChange: ({ onEvent }) => safeAreaInsetsEvent.subscribe(onEvent),
|
|
2656
2664
|
/** @internal */
|
|
2657
2665
|
appBridgeCallbackEvent: ({ onEvent, onError, options }) => import_native_modules24.appsInTossEvent.addEventListener("appBridgeCallbackEvent", { onEvent, onError, options }),
|
|
2658
2666
|
/** AdMobV2 */
|
|
@@ -4096,7 +4104,9 @@ var Analytics2 = {
|
|
|
4096
4104
|
OverlayProvider,
|
|
4097
4105
|
WebView,
|
|
4098
4106
|
env,
|
|
4107
|
+
homeEvent,
|
|
4099
4108
|
loadFullScreenAd,
|
|
4109
|
+
safeAreaInsetsChange,
|
|
4100
4110
|
showFullScreenAd,
|
|
4101
4111
|
useCreateUserAgent,
|
|
4102
4112
|
useGeolocation,
|
package/dist/index.d.cts
CHANGED
|
@@ -9,6 +9,7 @@ import { ExternalWebViewScreenProps } from '@toss/tds-react-native';
|
|
|
9
9
|
import { StartUpdateLocationOptions, Location, LoadFullScreenAdParams, ShowFullScreenAdParams } from '@apps-in-toss/types';
|
|
10
10
|
export * from '@apps-in-toss/types';
|
|
11
11
|
export { FetchTossAdOptions, LoadFullScreenAdEvent, LoadFullScreenAdOptions, LoadFullScreenAdParams, ShowFullScreenAdEvent, ShowFullScreenAdOptions, ShowFullScreenAdParams, TossAdEventLogParams } from '@apps-in-toss/types';
|
|
12
|
+
import { EdgeInsets } from '@granite-js/native/react-native-safe-area-context';
|
|
12
13
|
import { onVisibilityChangedByTransparentServiceWeb } from '@apps-in-toss/native-modules';
|
|
13
14
|
export * from '@apps-in-toss/native-modules';
|
|
14
15
|
export { OverlayProvider, useOverlay } from '@toss/tds-react-native/private';
|
|
@@ -171,6 +172,21 @@ declare const env: {
|
|
|
171
172
|
getAppName: () => string;
|
|
172
173
|
};
|
|
173
174
|
|
|
175
|
+
declare const homeEvent: {
|
|
176
|
+
name: string;
|
|
177
|
+
subscribe: (listener: (data: any) => void) => () => void;
|
|
178
|
+
hasSubscriptions: () => boolean;
|
|
179
|
+
clearSubscriptions: () => void;
|
|
180
|
+
emit: (data: any) => void;
|
|
181
|
+
};
|
|
182
|
+
declare const safeAreaInsetsChange: {
|
|
183
|
+
name: string;
|
|
184
|
+
subscribe: (listener: (data: EdgeInsets) => void) => () => void;
|
|
185
|
+
hasSubscriptions: () => boolean;
|
|
186
|
+
clearSubscriptions: () => void;
|
|
187
|
+
emit: (data: EdgeInsets) => void;
|
|
188
|
+
};
|
|
189
|
+
|
|
174
190
|
declare const INTERNAL__onVisibilityChangedByTransparentServiceWeb: typeof onVisibilityChangedByTransparentServiceWeb;
|
|
175
191
|
|
|
176
192
|
declare const loadFullScreenAd: {
|
|
@@ -238,4 +254,4 @@ declare const Analytics: {
|
|
|
238
254
|
Area: ({ children, params: _params, ...props }: _apps_in_toss_analytics.LoggingAreaProps) => react_jsx_runtime.JSX.Element;
|
|
239
255
|
};
|
|
240
256
|
|
|
241
|
-
export { type AdError, Analytics, AppsInToss, type BannerSlotCallbacks, type BannerSlotErrorPayload, type BannerSlotEventPayload, type ExternalWebViewProps, type GameWebViewProps, INTERNAL__onVisibilityChangedByTransparentServiceWeb, InlineAd, type InlineAdProps, type InlineAdTheme, type InlineAdTone, type InlineAdVariant, type PartnerWebViewProps, type UseGeolocationOptions, WebView, type WebViewProps, env, loadFullScreenAd, showFullScreenAd, useCreateUserAgent, useGeolocation, useTopNavigation, useWaitForReturnNavigator };
|
|
257
|
+
export { type AdError, Analytics, AppsInToss, type BannerSlotCallbacks, type BannerSlotErrorPayload, type BannerSlotEventPayload, type ExternalWebViewProps, type GameWebViewProps, INTERNAL__onVisibilityChangedByTransparentServiceWeb, InlineAd, type InlineAdProps, type InlineAdTheme, type InlineAdTone, type InlineAdVariant, type PartnerWebViewProps, type UseGeolocationOptions, WebView, type WebViewProps, env, homeEvent, loadFullScreenAd, safeAreaInsetsChange, showFullScreenAd, useCreateUserAgent, useGeolocation, useTopNavigation, useWaitForReturnNavigator };
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { ExternalWebViewScreenProps } from '@toss/tds-react-native';
|
|
|
9
9
|
import { StartUpdateLocationOptions, Location, LoadFullScreenAdParams, ShowFullScreenAdParams } from '@apps-in-toss/types';
|
|
10
10
|
export * from '@apps-in-toss/types';
|
|
11
11
|
export { FetchTossAdOptions, LoadFullScreenAdEvent, LoadFullScreenAdOptions, LoadFullScreenAdParams, ShowFullScreenAdEvent, ShowFullScreenAdOptions, ShowFullScreenAdParams, TossAdEventLogParams } from '@apps-in-toss/types';
|
|
12
|
+
import { EdgeInsets } from '@granite-js/native/react-native-safe-area-context';
|
|
12
13
|
import { onVisibilityChangedByTransparentServiceWeb } from '@apps-in-toss/native-modules';
|
|
13
14
|
export * from '@apps-in-toss/native-modules';
|
|
14
15
|
export { OverlayProvider, useOverlay } from '@toss/tds-react-native/private';
|
|
@@ -171,6 +172,21 @@ declare const env: {
|
|
|
171
172
|
getAppName: () => string;
|
|
172
173
|
};
|
|
173
174
|
|
|
175
|
+
declare const homeEvent: {
|
|
176
|
+
name: string;
|
|
177
|
+
subscribe: (listener: (data: any) => void) => () => void;
|
|
178
|
+
hasSubscriptions: () => boolean;
|
|
179
|
+
clearSubscriptions: () => void;
|
|
180
|
+
emit: (data: any) => void;
|
|
181
|
+
};
|
|
182
|
+
declare const safeAreaInsetsChange: {
|
|
183
|
+
name: string;
|
|
184
|
+
subscribe: (listener: (data: EdgeInsets) => void) => () => void;
|
|
185
|
+
hasSubscriptions: () => boolean;
|
|
186
|
+
clearSubscriptions: () => void;
|
|
187
|
+
emit: (data: EdgeInsets) => void;
|
|
188
|
+
};
|
|
189
|
+
|
|
174
190
|
declare const INTERNAL__onVisibilityChangedByTransparentServiceWeb: typeof onVisibilityChangedByTransparentServiceWeb;
|
|
175
191
|
|
|
176
192
|
declare const loadFullScreenAd: {
|
|
@@ -238,4 +254,4 @@ declare const Analytics: {
|
|
|
238
254
|
Area: ({ children, params: _params, ...props }: _apps_in_toss_analytics.LoggingAreaProps) => react_jsx_runtime.JSX.Element;
|
|
239
255
|
};
|
|
240
256
|
|
|
241
|
-
export { type AdError, Analytics, AppsInToss, type BannerSlotCallbacks, type BannerSlotErrorPayload, type BannerSlotEventPayload, type ExternalWebViewProps, type GameWebViewProps, INTERNAL__onVisibilityChangedByTransparentServiceWeb, InlineAd, type InlineAdProps, type InlineAdTheme, type InlineAdTone, type InlineAdVariant, type PartnerWebViewProps, type UseGeolocationOptions, WebView, type WebViewProps, env, loadFullScreenAd, showFullScreenAd, useCreateUserAgent, useGeolocation, useTopNavigation, useWaitForReturnNavigator };
|
|
257
|
+
export { type AdError, Analytics, AppsInToss, type BannerSlotCallbacks, type BannerSlotErrorPayload, type BannerSlotEventPayload, type ExternalWebViewProps, type GameWebViewProps, INTERNAL__onVisibilityChangedByTransparentServiceWeb, InlineAd, type InlineAdProps, type InlineAdTheme, type InlineAdTone, type InlineAdVariant, type PartnerWebViewProps, type UseGeolocationOptions, WebView, type WebViewProps, env, homeEvent, loadFullScreenAd, safeAreaInsetsChange, showFullScreenAd, useCreateUserAgent, useGeolocation, useTopNavigation, useWaitForReturnNavigator };
|
package/dist/index.js
CHANGED
|
@@ -707,6 +707,46 @@ function useCloseConfirm() {
|
|
|
707
707
|
);
|
|
708
708
|
}
|
|
709
709
|
|
|
710
|
+
// src/utils/eventEmitter.ts
|
|
711
|
+
var EventEmitter = class {
|
|
712
|
+
listeners = {};
|
|
713
|
+
subscribe(event, listener) {
|
|
714
|
+
if (!this.listeners[event]) {
|
|
715
|
+
this.listeners[event] = [];
|
|
716
|
+
}
|
|
717
|
+
this.listeners[event].push(listener);
|
|
718
|
+
return () => {
|
|
719
|
+
this.listeners[event] = this.listeners[event]?.filter((l) => l !== listener) ?? [];
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
hasSubscriptions(event) {
|
|
723
|
+
return this.listeners[event] != null && this.listeners[event].length > 0;
|
|
724
|
+
}
|
|
725
|
+
clearSubscriptions(event) {
|
|
726
|
+
this.listeners[event] = [];
|
|
727
|
+
}
|
|
728
|
+
emit(event, ...args) {
|
|
729
|
+
if (!this.listeners[event]) {
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
this.listeners[event].forEach((listener) => listener(...args));
|
|
733
|
+
}
|
|
734
|
+
};
|
|
735
|
+
var eventEmitter = new EventEmitter();
|
|
736
|
+
function createEvent(event) {
|
|
737
|
+
return {
|
|
738
|
+
name: event,
|
|
739
|
+
subscribe: (listener) => eventEmitter.subscribe(event, listener),
|
|
740
|
+
hasSubscriptions: () => eventEmitter.hasSubscriptions(event),
|
|
741
|
+
clearSubscriptions: () => eventEmitter.clearSubscriptions(event),
|
|
742
|
+
emit: (data) => eventEmitter.emit(event, data)
|
|
743
|
+
};
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
// src/events.ts
|
|
747
|
+
var homeEvent = createEvent("homeEvent");
|
|
748
|
+
var safeAreaInsetsChange = createEvent("safeAreaInsetsChange");
|
|
749
|
+
|
|
710
750
|
// src/components/NavigationBar/common/useNavigationBarLogging.tsx
|
|
711
751
|
import { INTERNAL__module as INTERNAL__module4 } from "@apps-in-toss/native-modules";
|
|
712
752
|
import { Granite as Granite4 } from "@granite-js/react-native";
|
|
@@ -821,7 +861,11 @@ function useNavigationEvent() {
|
|
|
821
861
|
},
|
|
822
862
|
handleHomeButtonClick: () => {
|
|
823
863
|
logging.homeButtonClick();
|
|
824
|
-
|
|
864
|
+
if (homeEvent.hasSubscriptions()) {
|
|
865
|
+
homeEvent.emit({});
|
|
866
|
+
} else {
|
|
867
|
+
navigation.navigate("/");
|
|
868
|
+
}
|
|
825
869
|
},
|
|
826
870
|
handleCloseButtonClick: () => {
|
|
827
871
|
logging.closeButtonClick();
|
|
@@ -1049,11 +1093,11 @@ function HomeShortcutMenu() {
|
|
|
1049
1093
|
);
|
|
1050
1094
|
}
|
|
1051
1095
|
|
|
1052
|
-
// src/core/hooks/useMoreButtonBottomSheet/
|
|
1096
|
+
// src/core/hooks/useMoreButtonBottomSheet/SettingsMenu.tsx
|
|
1053
1097
|
import { getOperationalEnvironment as getOperationalEnvironment3 } from "@apps-in-toss/native-modules";
|
|
1054
1098
|
import { Granite as Granite6, openURL as openURL4 } from "@granite-js/react-native";
|
|
1055
1099
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1056
|
-
function
|
|
1100
|
+
function SettingsMenu() {
|
|
1057
1101
|
const globals = getAppsInTossGlobals();
|
|
1058
1102
|
if (getOperationalEnvironment3() === "sandbox") {
|
|
1059
1103
|
return null;
|
|
@@ -1061,10 +1105,10 @@ function PermissionsMenu() {
|
|
|
1061
1105
|
return /* @__PURE__ */ jsx8(
|
|
1062
1106
|
Menu,
|
|
1063
1107
|
{
|
|
1064
|
-
title: "\
|
|
1108
|
+
title: "\uC124\uC815",
|
|
1065
1109
|
iconURL: "https://static.toss.im/icons/png/4x/icon-setting-mono.png",
|
|
1066
1110
|
onPress: () => openURL4(
|
|
1067
|
-
`servicetoss://apps-in-toss-menu/
|
|
1111
|
+
`servicetoss://apps-in-toss-menu/settings?appName=${Granite6.appName}&displayAppName=${globals.brandDisplayName}`
|
|
1068
1112
|
)
|
|
1069
1113
|
}
|
|
1070
1114
|
);
|
|
@@ -1094,7 +1138,7 @@ var MIN_VERSION = {
|
|
|
1094
1138
|
android: "5.246.0",
|
|
1095
1139
|
ios: "5.246.0"
|
|
1096
1140
|
},
|
|
1097
|
-
|
|
1141
|
+
SETTINGS_MENU: {
|
|
1098
1142
|
android: "5.238.0",
|
|
1099
1143
|
ios: "5.237.0"
|
|
1100
1144
|
}
|
|
@@ -1110,7 +1154,7 @@ function useMoreButtonBottomSheet() {
|
|
|
1110
1154
|
const isHomeShortcutSupported = isMinVersionSupported2(MIN_VERSION.HOME_SHORTCUT_MENU);
|
|
1111
1155
|
const isBottomSheetSupported = isMinVersionSupported2(MIN_VERSION.BOTTOM_SHEET);
|
|
1112
1156
|
const isShareListMenuSupported = isMinVersionSupported2(MIN_VERSION.SHARE_LIST_MENU);
|
|
1113
|
-
const
|
|
1157
|
+
const isSettingsMenuSupported = isMinVersionSupported2(MIN_VERSION.SETTINGS_MENU);
|
|
1114
1158
|
useEffect6(() => {
|
|
1115
1159
|
if (!isBottomSheetSupported) {
|
|
1116
1160
|
return;
|
|
@@ -1123,16 +1167,6 @@ function useMoreButtonBottomSheet() {
|
|
|
1123
1167
|
onError: (error) => console.error("\uBA54\uB274 \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uB294 \uB370 \uC2E4\uD328\uD588\uC5B4\uC694:", error)
|
|
1124
1168
|
}
|
|
1125
1169
|
);
|
|
1126
|
-
if (isMinVersionSupported2(MIN_VERSION.PERMISSIONS_MENU)) {
|
|
1127
|
-
INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
|
|
1128
|
-
"getAllPermission",
|
|
1129
|
-
{},
|
|
1130
|
-
{
|
|
1131
|
-
onSuccess: (permissions) => setIsPermissionsMenuSupported(permissions.length > 0),
|
|
1132
|
-
onError: (error) => console.error("\uAD8C\uD55C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uB294 \uB370 \uC2E4\uD328\uD588\uC5B4\uC694:", error)
|
|
1133
|
-
}
|
|
1134
|
-
);
|
|
1135
|
-
}
|
|
1136
1170
|
}, [isBottomSheetSupported]);
|
|
1137
1171
|
const onClickHandler = async () => {
|
|
1138
1172
|
logging.open();
|
|
@@ -1184,7 +1218,7 @@ function useMoreButtonBottomSheet() {
|
|
|
1184
1218
|
)),
|
|
1185
1219
|
isHomeShortcutSupported && /* @__PURE__ */ jsx9(HomeShortcutMenu, {}),
|
|
1186
1220
|
isShareListMenuSupported && /* @__PURE__ */ jsx9(AppShareListMenu, {}),
|
|
1187
|
-
|
|
1221
|
+
isSettingsMenuSupported && /* @__PURE__ */ jsx9(SettingsMenu, {})
|
|
1188
1222
|
] })
|
|
1189
1223
|
}
|
|
1190
1224
|
) });
|
|
@@ -1426,7 +1460,7 @@ import { useSafeAreaInsets as useSafeAreaInsets4 } from "@granite-js/native/reac
|
|
|
1426
1460
|
import { getSchemeUri as getSchemeUri8 } from "@granite-js/react-native";
|
|
1427
1461
|
import { ExternalWebViewScreen, tdsEvent } from "@toss/tds-react-native";
|
|
1428
1462
|
import { useSafeAreaBottom, useSafeAreaTop as useSafeAreaTop3 } from "@toss/tds-react-native/private";
|
|
1429
|
-
import { useEffect as useEffect13, useMemo as
|
|
1463
|
+
import { useEffect as useEffect13, useMemo as useMemo6, useRef as useRef6, useState as useState6 } from "react";
|
|
1430
1464
|
import { BackHandler as BackHandler2, Linking, NativeModules as NativeModules3, Platform as Platform6 } from "react-native";
|
|
1431
1465
|
|
|
1432
1466
|
// src/components/GameWebView.tsx
|
|
@@ -2092,50 +2126,28 @@ function parseNativeEventData(data) {
|
|
|
2092
2126
|
}
|
|
2093
2127
|
}
|
|
2094
2128
|
|
|
2095
|
-
// src/core/hooks/
|
|
2129
|
+
// src/core/hooks/useSafeAreaInsetsEvent.tsx
|
|
2096
2130
|
import { useSafeAreaInsets as useSafeAreaInsets3 } from "@granite-js/native/react-native-safe-area-context";
|
|
2097
|
-
import { useEffect as useEffect11
|
|
2098
|
-
|
|
2099
|
-
listeners = {};
|
|
2100
|
-
on(event, listener) {
|
|
2101
|
-
if (!this.listeners[event]) {
|
|
2102
|
-
this.listeners[event] = [];
|
|
2103
|
-
}
|
|
2104
|
-
this.listeners[event].push(listener);
|
|
2105
|
-
}
|
|
2106
|
-
emit(event, ...args) {
|
|
2107
|
-
if (!this.listeners[event]) {
|
|
2108
|
-
return;
|
|
2109
|
-
}
|
|
2110
|
-
this.listeners[event].forEach((listener) => listener(...args));
|
|
2111
|
-
}
|
|
2112
|
-
off(event, listener) {
|
|
2113
|
-
if (!this.listeners[event]) {
|
|
2114
|
-
return;
|
|
2115
|
-
}
|
|
2116
|
-
this.listeners[event] = this.listeners[event].filter((l) => l !== listener);
|
|
2117
|
-
}
|
|
2118
|
-
};
|
|
2119
|
-
function useSafeAreaInsetsEmitter() {
|
|
2131
|
+
import { useEffect as useEffect11 } from "react";
|
|
2132
|
+
function useSafeAreaInsetsEvent() {
|
|
2120
2133
|
const insets = useSafeAreaInsets3();
|
|
2121
|
-
const emitter = useMemo4(() => new EventEmitter(), []);
|
|
2122
2134
|
useEffect11(() => {
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
}, [
|
|
2128
|
-
return
|
|
2135
|
+
safeAreaInsetsChange.emit(insets);
|
|
2136
|
+
}, [insets]);
|
|
2137
|
+
useEffect11(() => {
|
|
2138
|
+
return () => safeAreaInsetsChange.clearSubscriptions();
|
|
2139
|
+
}, []);
|
|
2140
|
+
return safeAreaInsetsChange;
|
|
2129
2141
|
}
|
|
2130
2142
|
|
|
2131
2143
|
// src/core/hooks/useWebBackHandler.tsx
|
|
2132
2144
|
import { closeView as closeView6, useBackEventState } from "@granite-js/react-native";
|
|
2133
2145
|
import { useDialog as useDialog7 } from "@toss/tds-react-native";
|
|
2134
2146
|
import { josa as josa5 } from "es-hangul";
|
|
2135
|
-
import { useCallback as useCallback12, useMemo as
|
|
2147
|
+
import { useCallback as useCallback12, useMemo as useMemo5 } from "react";
|
|
2136
2148
|
|
|
2137
2149
|
// src/hooks/useWebviewHistoryStack.tsx
|
|
2138
|
-
import { useCallback as useCallback11, useMemo as
|
|
2150
|
+
import { useCallback as useCallback11, useMemo as useMemo4, useReducer } from "react";
|
|
2139
2151
|
var INITIAL_STATE = { stack: [], index: -1 };
|
|
2140
2152
|
function reducer(state, action) {
|
|
2141
2153
|
switch (action.type) {
|
|
@@ -2170,7 +2182,7 @@ function useWebViewHistory() {
|
|
|
2170
2182
|
const onNavigationStateChange = useCallback11(({ url, canGoForward: canGoForward2 }) => {
|
|
2171
2183
|
dispatch({ type: "NAVIGATION_CHANGE", url, canGoForward: canGoForward2 });
|
|
2172
2184
|
}, []);
|
|
2173
|
-
const { canGoBack, canGoForward } =
|
|
2185
|
+
const { canGoBack, canGoForward } = useMemo4(() => {
|
|
2174
2186
|
const canBack = state.index > 0;
|
|
2175
2187
|
const canFwd = state.index >= 0 && state.index < state.stack.length - 1;
|
|
2176
2188
|
return { canGoBack: canBack, canGoForward: canFwd };
|
|
@@ -2238,10 +2250,8 @@ function useWebBackHandler(webViewInitialURL, webViewRef) {
|
|
|
2238
2250
|
]);
|
|
2239
2251
|
const handleWebHome = useCallback12(() => {
|
|
2240
2252
|
logging.homeButtonClick();
|
|
2241
|
-
if (
|
|
2242
|
-
|
|
2243
|
-
handler();
|
|
2244
|
-
}
|
|
2253
|
+
if (homeEvent.hasSubscriptions()) {
|
|
2254
|
+
homeEvent.emit({});
|
|
2245
2255
|
return;
|
|
2246
2256
|
}
|
|
2247
2257
|
webViewRef.current?.injectJavaScript(`
|
|
@@ -2251,7 +2261,7 @@ function useWebBackHandler(webViewInitialURL, webViewRef) {
|
|
|
2251
2261
|
})();
|
|
2252
2262
|
`);
|
|
2253
2263
|
}, [hasWebBackEvent, webBackHandlersRef, logging, webViewInitialURL, webViewRef]);
|
|
2254
|
-
return
|
|
2264
|
+
return useMemo5(
|
|
2255
2265
|
() => ({ addEventListener, removeEventListener, handleWebBack, handleWebHome, onNavigationStateChange }),
|
|
2256
2266
|
[addEventListener, removeEventListener, handleWebBack, handleWebHome, onNavigationStateChange]
|
|
2257
2267
|
);
|
|
@@ -2611,14 +2621,14 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
2611
2621
|
throw new Error(`Invalid WebView type: '${type}'`);
|
|
2612
2622
|
}
|
|
2613
2623
|
const webViewRef = useRef6(null);
|
|
2614
|
-
const url =
|
|
2624
|
+
const url = useMemo6(() => getWebViewURL(local), [local]);
|
|
2615
2625
|
const webBackHandler = useWebBackHandler(url, webViewRef);
|
|
2616
2626
|
const top = useSafeAreaTop3();
|
|
2617
2627
|
const bottom = useSafeAreaBottom();
|
|
2618
2628
|
const insets = useSafeAreaInsets4();
|
|
2619
2629
|
const global2 = getAppsInTossGlobals();
|
|
2620
2630
|
const navigationBarContext = useNavigationBarContext();
|
|
2621
|
-
const
|
|
2631
|
+
const safeAreaInsetsEvent = useSafeAreaInsetsEvent();
|
|
2622
2632
|
const [allowsBackForwardNavigationGestures, setAllowsBackForwardNavigationGestures] = useState6(
|
|
2623
2633
|
props.allowsBackForwardNavigationGestures
|
|
2624
2634
|
);
|
|
@@ -2633,13 +2643,9 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
2633
2643
|
webBackHandler.removeEventListener(onEvent);
|
|
2634
2644
|
};
|
|
2635
2645
|
},
|
|
2646
|
+
homeEvent: ({ onEvent }) => homeEvent.subscribe(onEvent),
|
|
2636
2647
|
updateLocationEvent: ({ onEvent, onError, options }) => appsInTossEvent.addEventListener("updateLocationEvent", { onEvent, onError, options }),
|
|
2637
|
-
safeAreaInsetsChange: ({ onEvent }) =>
|
|
2638
|
-
safeAreaInsetsEmitter.on("safeAreaInsetsChange", onEvent);
|
|
2639
|
-
return () => {
|
|
2640
|
-
safeAreaInsetsEmitter.off("safeAreaInsetsChange", onEvent);
|
|
2641
|
-
};
|
|
2642
|
-
},
|
|
2648
|
+
safeAreaInsetsChange: ({ onEvent }) => safeAreaInsetsEvent.subscribe(onEvent),
|
|
2643
2649
|
/** @internal */
|
|
2644
2650
|
appBridgeCallbackEvent: ({ onEvent, onError, options }) => appsInTossEvent.addEventListener("appBridgeCallbackEvent", { onEvent, onError, options }),
|
|
2645
2651
|
/** AdMobV2 */
|
|
@@ -2722,7 +2728,7 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
2722
2728
|
}
|
|
2723
2729
|
}
|
|
2724
2730
|
});
|
|
2725
|
-
const headerPropForExternalWebView =
|
|
2731
|
+
const headerPropForExternalWebView = useMemo6(() => {
|
|
2726
2732
|
const parsedNavigationBar = global2.navigationBar != null ? safeParseNavigationBar(global2.navigationBar) : null;
|
|
2727
2733
|
const initialAccessoryButton = parsedNavigationBar?.initialAccessoryButton;
|
|
2728
2734
|
const withBackButton = parsedNavigationBar?.withBackButton ?? true;
|
|
@@ -4090,7 +4096,9 @@ export {
|
|
|
4090
4096
|
OverlayProvider,
|
|
4091
4097
|
WebView,
|
|
4092
4098
|
env,
|
|
4099
|
+
homeEvent,
|
|
4093
4100
|
loadFullScreenAd,
|
|
4101
|
+
safeAreaInsetsChange,
|
|
4094
4102
|
showFullScreenAd,
|
|
4095
4103
|
useCreateUserAgent,
|
|
4096
4104
|
useGeolocation,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apps-in-toss/framework",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.14.0",
|
|
5
5
|
"description": "The framework for Apps In Toss",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"typecheck": "tsc --noEmit",
|
|
@@ -55,12 +55,12 @@
|
|
|
55
55
|
"ait": "./bin/ait.js"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@apps-in-toss/analytics": "1.
|
|
59
|
-
"@apps-in-toss/cli": "1.
|
|
60
|
-
"@apps-in-toss/native-modules": "1.
|
|
61
|
-
"@apps-in-toss/plugins": "1.
|
|
62
|
-
"@apps-in-toss/types": "1.
|
|
63
|
-
"@apps-in-toss/user-scripts": "^1.
|
|
58
|
+
"@apps-in-toss/analytics": "1.14.0",
|
|
59
|
+
"@apps-in-toss/cli": "1.14.0",
|
|
60
|
+
"@apps-in-toss/native-modules": "1.14.0",
|
|
61
|
+
"@apps-in-toss/plugins": "1.14.0",
|
|
62
|
+
"@apps-in-toss/types": "1.14.0",
|
|
63
|
+
"@apps-in-toss/user-scripts": "^1.14.0",
|
|
64
64
|
"es-hangul": "^2.3.2"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|