@apps-in-toss/native-modules 1.0.2 → 1.1.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/VisibilityChangedByTransparentServiceWebEvent-D6XJvPVh.d.cts +20 -0
- package/dist/VisibilityChangedByTransparentServiceWebEvent-D6XJvPVh.d.ts +20 -0
- package/dist/bridges-meta.json +24 -12
- package/dist/chunk-YS54L7RG.js +209 -0
- package/dist/index.cjs +209 -150
- package/dist/index.d.cts +662 -592
- package/dist/index.d.ts +662 -592
- package/dist/index.js +186 -128
- package/dist/private.cjs +236 -0
- package/dist/private.d.cts +17 -0
- package/dist/private.d.ts +17 -0
- package/dist/private.js +11 -0
- package/package.json +3 -2
- package/src/AppsInTossModule/native-event-emitter/StartUpdateLocationPermissionError.ts +1 -0
- package/src/AppsInTossModule/native-event-emitter/appsInTossEvent.ts +2 -0
- package/src/AppsInTossModule/native-event-emitter/event-plugins/HomeIconButtonClickHandleEvent.ts +10 -0
- package/src/AppsInTossModule/native-event-emitter/event-plugins/UpdateLocationEvent.ts +3 -3
- package/src/AppsInTossModule/native-event-emitter/index.ts +2 -0
- package/src/AppsInTossModule/native-event-emitter/internal/appBridge.ts +7 -1
- package/src/AppsInTossModule/native-event-emitter/startUpdateLocation.ts +64 -44
- package/src/AppsInTossModule/native-modules/AppsInTossModule.ts +22 -27
- package/src/AppsInTossModule/native-modules/ads/googleAdMobV2.ts +3 -3
- package/src/AppsInTossModule/native-modules/ads/types.ts +1 -1
- package/src/AppsInTossModule/native-modules/getPermission.ts +1 -1
- package/src/AppsInTossModule/native-modules/index.ts +9 -6
- package/src/AppsInTossModule/native-modules/permissions/createPermissionFunction.ts +25 -0
- package/src/AppsInTossModule/native-modules/permissions/fetchAlbumPhotos/fetchAlbumPhotos.ts +109 -0
- package/src/AppsInTossModule/native-modules/{fetchContacts.ts → permissions/fetchContacts/fetchContacts.ts} +51 -40
- package/src/AppsInTossModule/native-modules/permissions/getClipboardText/getClipboardText.ts +87 -0
- package/src/AppsInTossModule/native-modules/permissions/getCurrentLocation/getCurrentLocation.ts +88 -0
- package/src/AppsInTossModule/native-modules/permissions/openCamera/openCamera.ts +99 -0
- package/src/AppsInTossModule/native-modules/{openPermissionDialog.ts → permissions/openPermissionDialog.ts} +3 -3
- package/src/AppsInTossModule/native-modules/{requestPermission.ts → permissions/requestPermission.ts} +2 -2
- package/src/AppsInTossModule/native-modules/permissions/setClipboardText/setClipboardText.ts +75 -0
- package/src/AppsInTossModule/native-modules/saveBase64Data.ts +1 -1
- package/src/async-bridges.ts +9 -6
- package/src/types.ts +0 -106
- package/src/AppsInTossModule/native-modules/fetchAlbumPhotos.ts +0 -88
- package/src/AppsInTossModule/native-modules/getClipboardText.ts +0 -47
- package/src/AppsInTossModule/native-modules/getCurrentLocation.ts +0 -65
- package/src/AppsInTossModule/native-modules/openCamera.ts +0 -81
- package/src/AppsInTossModule/native-modules/setClipboardText.ts +0 -39
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EmitterSubscription } from 'react-native';
|
|
2
|
+
import { E as EventEmitterSchema, a as VisibilityChangedByTransparentServiceWebOptions } from './VisibilityChangedByTransparentServiceWebEvent-D6XJvPVh.cjs';
|
|
3
|
+
import '@granite-js/react-native';
|
|
4
|
+
|
|
5
|
+
interface OnVisibilityChangedByTransparentServiceWebSubscription extends EmitterSubscription {
|
|
6
|
+
remove: () => void;
|
|
7
|
+
}
|
|
8
|
+
type OnVisibilityChangedByTransparentServiceWebEventEmitter = EventEmitterSchema<'visibilityChangedByTransparentServiceWeb', [
|
|
9
|
+
boolean
|
|
10
|
+
]>;
|
|
11
|
+
declare function onVisibilityChangedByTransparentServiceWeb(eventParams: {
|
|
12
|
+
options: VisibilityChangedByTransparentServiceWebOptions;
|
|
13
|
+
onEvent: (isVisible: boolean) => void;
|
|
14
|
+
onError: (error: unknown) => void;
|
|
15
|
+
}): () => void;
|
|
16
|
+
|
|
17
|
+
export { type OnVisibilityChangedByTransparentServiceWebEventEmitter, type OnVisibilityChangedByTransparentServiceWebSubscription, onVisibilityChangedByTransparentServiceWeb };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EmitterSubscription } from 'react-native';
|
|
2
|
+
import { E as EventEmitterSchema, a as VisibilityChangedByTransparentServiceWebOptions } from './VisibilityChangedByTransparentServiceWebEvent-D6XJvPVh.js';
|
|
3
|
+
import '@granite-js/react-native';
|
|
4
|
+
|
|
5
|
+
interface OnVisibilityChangedByTransparentServiceWebSubscription extends EmitterSubscription {
|
|
6
|
+
remove: () => void;
|
|
7
|
+
}
|
|
8
|
+
type OnVisibilityChangedByTransparentServiceWebEventEmitter = EventEmitterSchema<'visibilityChangedByTransparentServiceWeb', [
|
|
9
|
+
boolean
|
|
10
|
+
]>;
|
|
11
|
+
declare function onVisibilityChangedByTransparentServiceWeb(eventParams: {
|
|
12
|
+
options: VisibilityChangedByTransparentServiceWebOptions;
|
|
13
|
+
onEvent: (isVisible: boolean) => void;
|
|
14
|
+
onError: (error: unknown) => void;
|
|
15
|
+
}): () => void;
|
|
16
|
+
|
|
17
|
+
export { type OnVisibilityChangedByTransparentServiceWebEventEmitter, type OnVisibilityChangedByTransparentServiceWebSubscription, onVisibilityChangedByTransparentServiceWeb };
|
package/dist/private.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
appsInTossEvent
|
|
3
|
+
} from "./chunk-YS54L7RG.js";
|
|
4
|
+
|
|
5
|
+
// src/AppsInTossModule/native-event-emitter/internal/onVisibilityChangedByTransparentServiceWeb.ts
|
|
6
|
+
function onVisibilityChangedByTransparentServiceWeb(eventParams) {
|
|
7
|
+
return appsInTossEvent.addEventListener("onVisibilityChangedByTransparentServiceWeb", eventParams);
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
onVisibilityChangedByTransparentServiceWeb
|
|
11
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apps-in-toss/native-modules",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0
|
|
4
|
+
"version": "1.1.0",
|
|
5
5
|
"description": "Native Modules for Apps In Toss",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"prepack": "yarn build",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"vitest": "^3.2.4"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
+
"@apps-in-toss/types": "^1.1.0",
|
|
46
47
|
"es-toolkit": "^1.39.3"
|
|
47
48
|
},
|
|
48
49
|
"peerDependencies": {
|
|
@@ -53,5 +54,5 @@
|
|
|
53
54
|
"publishConfig": {
|
|
54
55
|
"access": "public"
|
|
55
56
|
},
|
|
56
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "614cfd1ee039b44cd6efeb94cefac18ed3c0e6c3"
|
|
57
58
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { StartUpdateLocationPermissionError } from '@apps-in-toss/types';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { GraniteEvent } from '@granite-js/react-native';
|
|
2
2
|
import { EntryMessageExitedEvent } from './event-plugins/EntryMessageExitedEvent';
|
|
3
|
+
import { HomeIconButtonClickHandleEvent } from './event-plugins/HomeIconButtonClickHandleEvent';
|
|
3
4
|
import { UpdateLocationEvent } from './event-plugins/UpdateLocationEvent';
|
|
4
5
|
import { AppBridgeCallbackEvent } from './internal/AppBridgeCallbackEvent';
|
|
5
6
|
import { VisibilityChangedByTransparentServiceWebEvent } from './internal/VisibilityChangedByTransparentServiceWebEvent';
|
|
@@ -7,6 +8,7 @@ import { VisibilityChangedByTransparentServiceWebEvent } from './internal/Visibi
|
|
|
7
8
|
export const appsInTossEvent = new GraniteEvent([
|
|
8
9
|
new UpdateLocationEvent(),
|
|
9
10
|
new EntryMessageExitedEvent(),
|
|
11
|
+
new HomeIconButtonClickHandleEvent(),
|
|
10
12
|
// Internal events
|
|
11
13
|
new AppBridgeCallbackEvent(),
|
|
12
14
|
new VisibilityChangedByTransparentServiceWebEvent(),
|
package/src/AppsInTossModule/native-event-emitter/event-plugins/HomeIconButtonClickHandleEvent.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { GraniteEventDefinition } from '@granite-js/react-native';
|
|
2
|
+
|
|
3
|
+
export class HomeIconButtonClickHandleEvent extends GraniteEventDefinition<undefined, undefined> {
|
|
4
|
+
name = 'homeIconButtonClickEvent' as const;
|
|
5
|
+
|
|
6
|
+
remove() {}
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
9
|
+
listener(_: undefined) {}
|
|
10
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { Accuracy, GetCurrentLocationPermissionError, Location } from '@apps-in-toss/types';
|
|
1
2
|
import { GraniteEventDefinition } from '@granite-js/react-native';
|
|
2
|
-
import { Accuracy, Location } from '../../../types';
|
|
3
3
|
import { AppsInTossModuleInstance } from '../../native-modules/AppsInTossModule';
|
|
4
|
-
import { requestPermission } from '../../native-modules/requestPermission';
|
|
4
|
+
import { requestPermission } from '../../native-modules/permissions/requestPermission';
|
|
5
5
|
import { nativeEventEmitter } from '../nativeEventEmitter';
|
|
6
6
|
|
|
7
7
|
export interface StartUpdateLocationOptions {
|
|
@@ -42,7 +42,7 @@ export class UpdateLocationEvent extends GraniteEventDefinition<StartUpdateLocat
|
|
|
42
42
|
requestPermission({ name: 'geolocation', access: 'access' })
|
|
43
43
|
.then((permissionStatus) => {
|
|
44
44
|
if (permissionStatus === 'denied') {
|
|
45
|
-
onError(new
|
|
45
|
+
onError(new GetCurrentLocationPermissionError());
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export * from './startUpdateLocation';
|
|
2
|
+
export * from './StartUpdateLocationPermissionError';
|
|
2
3
|
export * from './contactsViral';
|
|
3
4
|
|
|
4
5
|
export { appsInTossEvent } from './appsInTossEvent';
|
|
5
6
|
export { onVisibilityChangedByTransparentServiceWeb } from './internal/onVisibilityChangedByTransparentServiceWeb';
|
|
7
|
+
export { INTERNAL__appBridgeHandler } from './internal/appBridge';
|
|
@@ -27,8 +27,14 @@ function invokeAppBridgeMethod<Result = any, Params = any>(
|
|
|
27
27
|
) {
|
|
28
28
|
const { onSuccess, onError, ...appBridgeCallbacks } = callbacks;
|
|
29
29
|
const { callbackMap, unregisterAll } = registerCallbacks(appBridgeCallbacks);
|
|
30
|
+
const method = AppsInTossModuleInstance[methodName];
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
if (method == null) {
|
|
33
|
+
onError(new Error(`'${methodName}' is not defined in AppsInTossModule`));
|
|
34
|
+
return unregisterAll;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const promise = method({
|
|
32
38
|
params,
|
|
33
39
|
callbacks: callbackMap,
|
|
34
40
|
}) as Promise<Result>;
|
|
@@ -1,26 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Location, StartUpdateLocationEventParams } from '@apps-in-toss/types';
|
|
2
2
|
import { appsInTossEvent } from './appsInTossEvent';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
export interface StartUpdateLocationOptions {
|
|
7
|
-
/**
|
|
8
|
-
* 위치 정확도를 설정해요.
|
|
9
|
-
*/
|
|
10
|
-
accuracy: Accuracy;
|
|
11
|
-
/**
|
|
12
|
-
* 위치 업데이트 주기를 밀리초(ms) 단위로 설정해요.
|
|
13
|
-
*/
|
|
14
|
-
timeInterval: number;
|
|
15
|
-
/**
|
|
16
|
-
* 위치 변경 거리를 미터(m) 단위로 설정해요.
|
|
17
|
-
*/
|
|
18
|
-
distanceInterval: number;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface StartUpdateLocationSubscription extends EmitterSubscription {
|
|
22
|
-
remove: () => Promise<void>;
|
|
23
|
-
}
|
|
3
|
+
import { EventEmitterSchema } from './types';
|
|
4
|
+
import { getCurrentLocation } from '../native-modules';
|
|
24
5
|
|
|
25
6
|
/**
|
|
26
7
|
* @name UpdateLocationEventEmitter
|
|
@@ -38,26 +19,46 @@ export type UpdateLocationEventEmitter = EventEmitterSchema<'updateLocation', [L
|
|
|
38
19
|
* 실시간 위치 추적이 필요한 기능을 구현할 때 사용할 수 있어요. 예를 들어 지도 앱에서 사용자의 현재 위치를 실시간으로 업데이트할 때, 운동 앱에서 사용자의 이동 거리를 기록할 때 등이에요.
|
|
39
20
|
* 위치 업데이트 주기와 정확도를 조정해 배터리 소모를 최소화하면서도 필요한 정보를 얻을 수 있어요.
|
|
40
21
|
*
|
|
22
|
+
*
|
|
23
|
+
* @param {(error: unknown) => void} onError 위치 정보 감지에 실패했을 때 호출되는 콜백 함수예요.
|
|
24
|
+
* @param {(location: Location) => void} onEvent 위치 정보가 변경될 때 호출되는 콜백 함수예요. 자세한 내용은 [Location](/react-native/reference/native-modules/Types/Location.html)을 참고해주세요.
|
|
41
25
|
* @param {StartUpdateLocationOptions} options - 위치 정보 감지에 필요한 설정 객체에요.
|
|
42
26
|
* @param {number} [options.accuracy] 위치 정확도를 설정해요.
|
|
43
27
|
* @param {number} [options.timeInterval] 위치 정보를 업데이트하는 최소 주기로, 단위는 밀리초(ms)예요. 이 값은 위치 업데이트가 발생하는 가장 짧은 간격을 설정하지만, 시스템이나 환경의 영향을 받아 지정한 주기보다 더 긴 간격으로 업데이트될 수 있어요.
|
|
44
28
|
* @param {number} [options.distanceInterval] 위치 변경 거리를 미터(m) 단위로 설정해요.
|
|
45
|
-
*
|
|
29
|
+
*
|
|
30
|
+
* @property [openPermissionDialog] - 위치 정보 권한을 다시 요청하는 다이얼로그를 표시해요. 사용자는 "허용", "한 번만 허용", "안하기" 중 하나를 선택할 수 있어요. "허용"이나 "한 번만 허용"을 선택하면 `allowed`를 반환하고, "안하기"를 선택하면 `denied`를 반환해요.
|
|
31
|
+
* @property [getPermission] - 위치 정보 권한의 현재 상태를 반환해요. `allowed`는 사용자가 위치 정보 권한을 허용한 상태예요. `denied`는 사용자가 위치 정보 권한을 거부한 상태예요. `notDetermined`는 위치 정보 권한 요청을 한 번도 하지 않은 상태예요.
|
|
32
|
+
*
|
|
33
|
+
* @signature
|
|
34
|
+
* ```typescript
|
|
35
|
+
* function startUpdateLocation(options: {
|
|
36
|
+
* onError: (error: unknown) => void;
|
|
37
|
+
* onEvent: (location: Location) => void;
|
|
38
|
+
* options: StartUpdateLocationOptions;
|
|
39
|
+
* }): () => void;
|
|
40
|
+
* ```
|
|
46
41
|
*
|
|
47
42
|
* @example
|
|
48
43
|
* ### 위치 정보 변경 감지하기
|
|
49
44
|
*
|
|
45
|
+
* 위치 정보가 변경되는것을 감지하는 예제예요. "위치 정보 변경 감지하기"를 눌러서 감지할 수 있어요.
|
|
46
|
+
*
|
|
47
|
+
* "권한 확인하기"버튼을 눌러서 현재 위치 정보 변경 감지 권한을 확인해요.
|
|
48
|
+
* 사용자가 권한을 거부했거나 시스템에서 권한이 제한된 경우에는 [`StartUpdateLocationPermissionError`](/react-native/reference/types/권한/StartUpdateLocationPermissionError)를 반환해요.
|
|
49
|
+
* "권한 요청하기"버튼을 눌러서 위치 정보 변경 감지 권한을 요청할 수 있어요.
|
|
50
|
+
*
|
|
50
51
|
* ```tsx
|
|
51
|
-
* import
|
|
52
|
-
* import {
|
|
53
|
-
* import {
|
|
52
|
+
* import { Accuracy, Location, startUpdateLocation, StartUpdateLocationPermissionError } from '@apps-in-toss/framework';
|
|
53
|
+
* import { useCallback, useState } from 'react';
|
|
54
|
+
* import { Alert, Button, Text, View } from 'react-native';
|
|
54
55
|
*
|
|
55
56
|
* // 위치 정보 변경 감지하기
|
|
56
57
|
* function LocationWatcher() {
|
|
57
|
-
* const [location, setLocation] = useState(null);
|
|
58
|
+
* const [location, setLocation] = useState<Location | null>(null);
|
|
58
59
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
60
|
+
* const handlePress = useCallback(() => {
|
|
61
|
+
* startUpdateLocation({
|
|
61
62
|
* options: {
|
|
62
63
|
* accuracy: Accuracy.Balanced,
|
|
63
64
|
* timeInterval: 3000,
|
|
@@ -67,32 +68,51 @@ export type UpdateLocationEventEmitter = EventEmitterSchema<'updateLocation', [L
|
|
|
67
68
|
* setLocation(location);
|
|
68
69
|
* },
|
|
69
70
|
* onError: (error) => {
|
|
71
|
+
* if (error instanceof StartUpdateLocationPermissionError) {
|
|
72
|
+
* // 위치 정보 변경 감지 권한 없음
|
|
73
|
+
* }
|
|
70
74
|
* console.error('위치 정보를 가져오는데 실패했어요:', error);
|
|
71
75
|
* },
|
|
72
76
|
* });
|
|
73
77
|
* }, []);
|
|
74
78
|
*
|
|
75
|
-
* if (location == null) {
|
|
76
|
-
* return <Text>위치 정보를 가져오는 중이에요...</Text>;
|
|
77
|
-
* }
|
|
78
|
-
*
|
|
79
79
|
* return (
|
|
80
80
|
* <View>
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
81
|
+
* {location != null && (
|
|
82
|
+
* <>
|
|
83
|
+
* <Text>위도: {location.coords.latitude}</Text>
|
|
84
|
+
* <Text>경도: {location.coords.longitude}</Text>
|
|
85
|
+
* <Text>위치 정확도: {location.coords.accuracy}m</Text>
|
|
86
|
+
* <Text>높이: {location.coords.altitude}m</Text>
|
|
87
|
+
* <Text>고도 정확도: {location.coords.altitudeAccuracy}m</Text>
|
|
88
|
+
* <Text>방향: {location.coords.heading}°</Text>
|
|
89
|
+
* </>
|
|
90
|
+
* )}
|
|
91
|
+
*
|
|
92
|
+
* <Button title="위치 정보 변경 감지하기" onPress={handlePress} />
|
|
93
|
+
*
|
|
94
|
+
* <Button
|
|
95
|
+
* title="권한 확인하기"
|
|
96
|
+
* onPress={async () => {
|
|
97
|
+
* const permission = await startUpdateLocation.getPermission();
|
|
98
|
+
* Alert.alert(permission);
|
|
99
|
+
* }}
|
|
100
|
+
* />
|
|
101
|
+
* <Button
|
|
102
|
+
* title="권한 요청하기"
|
|
103
|
+
* onPress={async () => {
|
|
104
|
+
* const permission = await startUpdateLocation.openPermissionDialog();
|
|
105
|
+
* Alert.alert(permission);
|
|
106
|
+
* }}
|
|
107
|
+
* />
|
|
87
108
|
* </View>
|
|
88
109
|
* );
|
|
89
110
|
* }
|
|
90
111
|
* ```
|
|
91
112
|
*/
|
|
92
|
-
export function startUpdateLocation(eventParams: {
|
|
93
|
-
onEvent: (response: Location) => void;
|
|
94
|
-
onError: (error: unknown) => void;
|
|
95
|
-
options: StartUpdateLocationOptions;
|
|
96
|
-
}): () => void {
|
|
113
|
+
export function startUpdateLocation(eventParams: StartUpdateLocationEventParams): () => void {
|
|
97
114
|
return appsInTossEvent.addEventListener('updateLocationEvent', eventParams);
|
|
98
115
|
}
|
|
116
|
+
|
|
117
|
+
startUpdateLocation.openPermissionDialog = getCurrentLocation.openPermissionDialog;
|
|
118
|
+
startUpdateLocation.getPermission = getCurrentLocation.getPermission;
|
|
@@ -1,22 +1,29 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CompatiblePlaceholderArgument,
|
|
3
|
+
ContactResult,
|
|
4
|
+
FetchAlbumPhotosOptions,
|
|
5
|
+
FetchContactsOptions,
|
|
6
|
+
GetCurrentLocationOptions,
|
|
7
|
+
ImageResponse,
|
|
8
|
+
Location,
|
|
9
|
+
OpenCameraOptions,
|
|
10
|
+
PermissionAccess,
|
|
11
|
+
PermissionName,
|
|
12
|
+
PermissionStatus,
|
|
13
|
+
SetClipboardTextOptions,
|
|
14
|
+
} from '@apps-in-toss/types';
|
|
1
15
|
import { TurboModuleRegistry, type TurboModule as __TurboModule } from 'react-native';
|
|
2
16
|
import type { CheckoutPaymentOptions, CheckoutPaymentResult } from './checkoutPayment';
|
|
3
|
-
import type { FetchAlbumPhotosOptions } from './fetchAlbumPhotos';
|
|
4
|
-
import type { ContactEntity } from './fetchContacts';
|
|
5
|
-
import type { GetCurrentLocationOptions } from './getCurrentLocation';
|
|
6
17
|
import type { GameCenterGameProfileResponse } from './getGameCenterGameProfile';
|
|
7
18
|
import type {
|
|
8
19
|
IapCreateOneTimePurchaseOrderOptions,
|
|
9
20
|
IapCreateOneTimePurchaseOrderResult,
|
|
10
21
|
IapProductListItem,
|
|
11
22
|
} from './iap';
|
|
12
|
-
import type { OpenCameraOptions } from './openCamera';
|
|
13
23
|
import type { SaveBase64DataParams } from './saveBase64Data';
|
|
14
24
|
import type { SubmitGameCenterLeaderBoardScoreResponse } from './submitGameCenterLeaderBoardScore';
|
|
15
|
-
import type { ImageResponse, Location, PermissionAccess, PermissionName, PermissionStatus } from '../../types';
|
|
16
25
|
import type { ContactsViralParams } from '../native-event-emitter/contactsViral';
|
|
17
26
|
|
|
18
|
-
type CompatiblePlaceholderArgument = object;
|
|
19
|
-
|
|
20
27
|
/**
|
|
21
28
|
* TurboModule 타입 별칭 사용하는 이유?
|
|
22
29
|
* React Native Codegen 에 의해 코드젠 되는 것이 아니라 추후 내부 모듈 체계에 의해 처리될 것이기 때문에 RN Codegen에 본 파일을 코드젠 하지 않도록 함
|
|
@@ -27,32 +34,20 @@ interface Spec extends __TurboModule {
|
|
|
27
34
|
operationalEnvironment: 'sandbox' | 'toss';
|
|
28
35
|
tossAppVersion: string;
|
|
29
36
|
deviceId: string;
|
|
30
|
-
|
|
37
|
+
|
|
31
38
|
getClipboardText: (arg: CompatiblePlaceholderArgument) => Promise<string>;
|
|
32
|
-
setClipboardText: (option:
|
|
39
|
+
setClipboardText: (option: SetClipboardTextOptions) => Promise<void>;
|
|
40
|
+
fetchContacts: (option: FetchContactsOptions) => Promise<ContactResult>;
|
|
41
|
+
fetchAlbumPhotos: (options: FetchAlbumPhotosOptions) => Promise<ImageResponse[]>;
|
|
42
|
+
getCurrentLocation: (options: GetCurrentLocationOptions) => Promise<Location>;
|
|
43
|
+
openCamera: (options: OpenCameraOptions) => Promise<ImageResponse>;
|
|
44
|
+
|
|
45
|
+
getWebBundleURL: (arg: CompatiblePlaceholderArgument) => { url: string };
|
|
33
46
|
getPermission: (permission: { name: PermissionName; access: PermissionAccess }) => Promise<PermissionStatus>;
|
|
34
47
|
openPermissionDialog: (permission: {
|
|
35
48
|
name: PermissionName;
|
|
36
49
|
access: PermissionAccess;
|
|
37
50
|
}) => Promise<Exclude<PermissionStatus, 'notDetermined'>>;
|
|
38
|
-
fetchContacts: ({
|
|
39
|
-
size,
|
|
40
|
-
offset,
|
|
41
|
-
query,
|
|
42
|
-
}: {
|
|
43
|
-
size: number;
|
|
44
|
-
offset: number;
|
|
45
|
-
query?: {
|
|
46
|
-
contains?: string;
|
|
47
|
-
};
|
|
48
|
-
}) => Promise<{
|
|
49
|
-
result: ContactEntity[];
|
|
50
|
-
nextOffset: number | undefined;
|
|
51
|
-
done: boolean;
|
|
52
|
-
}>;
|
|
53
|
-
fetchAlbumPhotos: (options: FetchAlbumPhotosOptions) => Promise<ImageResponse[]>;
|
|
54
|
-
getCurrentLocation: (options: GetCurrentLocationOptions) => Promise<Location>;
|
|
55
|
-
openCamera: (options: OpenCameraOptions) => Promise<ImageResponse>;
|
|
56
51
|
appLogin: (
|
|
57
52
|
arg: CompatiblePlaceholderArgument
|
|
58
53
|
) => Promise<{ authorizationCode: string; referrer: 'DEFAULT' | 'SANDBOX' }>;
|
|
@@ -17,7 +17,7 @@ export interface LoadAdMobOptions {
|
|
|
17
17
|
* @public
|
|
18
18
|
* @category 광고
|
|
19
19
|
* @name LoadAdMobEvent
|
|
20
|
-
* @description 광고를 불러오는 함수에서 발생하는 이벤트 타입이에요. `loaded` 이벤트가 발생하면 광고를 성공적으로 불러온 거예요. 이때 [AdMobLoadResult](/react-native/reference/
|
|
20
|
+
* @description 광고를 불러오는 함수에서 발생하는 이벤트 타입이에요. `loaded` 이벤트가 발생하면 광고를 성공적으로 불러온 거예요. 이때 [AdMobLoadResult](/react-native/reference/native-modules/광고/AdMobLoadResult.html) 객체가 함께 반환돼요.
|
|
21
21
|
*/
|
|
22
22
|
export type LoadAdMobEvent = {
|
|
23
23
|
type: 'loaded';
|
|
@@ -40,7 +40,7 @@ export type LoadAdMobParams = AdMobHandlerParams<LoadAdMobOptions, LoadAdMobEven
|
|
|
40
40
|
* @param {LoadAdMobParams} params 광고를 불러올 때 사용할 설정 값이에요. 광고 그룹 ID와 광고의 동작에 대한 콜백을 설정할 수 있어요.
|
|
41
41
|
* @param {LoadAdMobOptions} params.options 광고를 불러올 때 전달할 옵션 객체예요.
|
|
42
42
|
* @param {string} params.options.adGroupId 광고 그룹 단위 ID예요. 콘솔에서 발급받은 ID를 입력해요.
|
|
43
|
-
* @param {(event: LoadAdMobEvent) => void} [params.onEvent] 광고 관련 이벤트가 발생했을 때 호출돼요. (예시: 광고가 닫히거나 클릭됐을 때). 자세한 이벤트 타입은 [LoadAdMobEvent](/react-native/reference/
|
|
43
|
+
* @param {(event: LoadAdMobEvent) => void} [params.onEvent] 광고 관련 이벤트가 발생했을 때 호출돼요. (예시: 광고가 닫히거나 클릭됐을 때). 자세한 이벤트 타입은 [LoadAdMobEvent](/react-native/reference/native-modules/광고/LoadAdMobEvent.html)를 참고하세요.
|
|
44
44
|
* @param {(reason: unknown) => void} [params.onError] 광고를 불러오지 못했을 때 호출돼요. (예시: 네트워크 오류나 지원하지 않는 환경일 때)
|
|
45
45
|
* @property {() => boolean} [isSupported] 현재 실행 중인 앱(예: 토스 앱, 개발용 샌드박스 앱 등)에서 Google AdMob 광고 기능을 지원하는지 확인하는 함수예요. 기능을 사용하기 전에 지원 여부를 확인해야 해요.
|
|
46
46
|
*
|
|
@@ -197,7 +197,7 @@ export type ShowAdMobParams = AdMobHandlerParams<ShowAdMobOptions, ShowAdMobEven
|
|
|
197
197
|
* @param {ShowAdMobParams} params 광고를 보여주기 위해 사용할 설정 값이에요. 광고 그룹 ID와과 광고의 동작에 대한 콜백을 설정할 수 있어요.
|
|
198
198
|
* @param {ShowAdMobOptions} params.options 광고를 보여줄 때 전달할 옵션 객체예요.
|
|
199
199
|
* @param {string} params.options.adUnitId 광고 그룹 단위 ID예요. `loadAppsInTossAdMob` 로 불러온 광고용 그룹 ID를 입력해요.
|
|
200
|
-
* @param {(event: ShowAdMobEvent) => void} [params.onEvent] 광고 관련 이벤트가 발생했을 때 호출돼요. (예시: 광고 노출을 요청했을 때). 자세한 이벤트 타입은 [ShowAdMobEvent](/react-native/reference/
|
|
200
|
+
* @param {(event: ShowAdMobEvent) => void} [params.onEvent] 광고 관련 이벤트가 발생했을 때 호출돼요. (예시: 광고 노출을 요청했을 때). 자세한 이벤트 타입은 [ShowAdMobEvent](/react-native/reference/native-modules/광고/ShowAdMobEvent.html)를 참고하세요.
|
|
201
201
|
* @param {(reason: unknown) => void} [params.onError] 광고를 노출하지 못했을 때 호출돼요. (예시: 네트워크 오류나 지원하지 않는 환경일 때)
|
|
202
202
|
* @property {() => boolean} [isSupported] 현재 실행 중인 앱(예: 토스 앱, 개발용 샌드박스 앱 등)에서 Google AdMob 광고 기능을 지원하는지 확인하는 함수예요. 기능을 사용하기 전에 지원 여부를 확인해야 해요.
|
|
203
203
|
*
|
|
@@ -114,7 +114,7 @@ export interface RewardedAd {
|
|
|
114
114
|
* @description 광고의 ID와 응답 정보를 담고 있는 객체예요. 광고를 로드한 뒤, 관련 정보를 확인할 때 유용해요.
|
|
115
115
|
* @property {string} adGroupId 광고 그룹 ID예요.
|
|
116
116
|
* @property {string} adUnitId 광고 ID예요.
|
|
117
|
-
* @property {ResponseInfo} responseInfo 광고 로드 응답 정보예요. 자세한 내용은 [ResponseInfo](/react-native/reference/
|
|
117
|
+
* @property {ResponseInfo} responseInfo 광고 로드 응답 정보예요. 자세한 내용은 [ResponseInfo](/react-native/reference/native-modules/광고/ResponseInfo.html)를 참고하세요.
|
|
118
118
|
*/
|
|
119
119
|
export interface AdMobLoadResult {
|
|
120
120
|
adGroupId: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { PermissionAccess, PermissionName, PermissionStatus } from '@apps-in-toss/types';
|
|
1
2
|
import { AppsInTossModule } from './AppsInTossModule';
|
|
2
|
-
import { PermissionAccess, PermissionName, PermissionStatus } from '../../types';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @category AppsInTossModules
|
|
@@ -32,19 +32,22 @@ export { AppsInTossModule } from './AppsInTossModule';
|
|
|
32
32
|
|
|
33
33
|
export * from './appLogin';
|
|
34
34
|
export * from './eventLog';
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
export * from './
|
|
38
|
-
export * from './
|
|
35
|
+
|
|
36
|
+
/** permission functions */
|
|
37
|
+
export * from './permissions/fetchAlbumPhotos/fetchAlbumPhotos';
|
|
38
|
+
export * from './permissions/fetchContacts/fetchContacts';
|
|
39
|
+
export * from './permissions/getClipboardText/getClipboardText';
|
|
40
|
+
export * from './permissions/getCurrentLocation/getCurrentLocation';
|
|
41
|
+
export * from './permissions/setClipboardText/setClipboardText';
|
|
42
|
+
export * from './permissions/openCamera/openCamera';
|
|
43
|
+
|
|
39
44
|
export * from './getDeviceId';
|
|
40
45
|
export * from './getOperationalEnvironment';
|
|
41
46
|
export * from './getTossAppVersion';
|
|
42
47
|
export * from './getTossShareLink';
|
|
43
48
|
export * from './iap';
|
|
44
49
|
export * from './isMinVersionSupported';
|
|
45
|
-
export * from './openCamera';
|
|
46
50
|
export * from './saveBase64Data';
|
|
47
|
-
export * from './setClipboardText';
|
|
48
51
|
export * from './setDeviceOrientation';
|
|
49
52
|
export * from './storage';
|
|
50
53
|
export * from './openGameCenterLeaderboard';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CreatePermissionFunctionOptions, PermissionFunctionWithDialog } from '@apps-in-toss/types';
|
|
2
|
+
import { openPermissionDialog } from './openPermissionDialog';
|
|
3
|
+
import { requestPermission } from './requestPermission';
|
|
4
|
+
import { getPermission } from '../getPermission';
|
|
5
|
+
|
|
6
|
+
export function createPermissionFunction<T extends (...args: any[]) => any>({
|
|
7
|
+
handler,
|
|
8
|
+
permission,
|
|
9
|
+
error,
|
|
10
|
+
}: CreatePermissionFunctionOptions<T>): PermissionFunctionWithDialog<T> {
|
|
11
|
+
const permissionFunction = async (...args: Parameters<T>): Promise<Awaited<ReturnType<T>>> => {
|
|
12
|
+
const permissionStatus = await requestPermission(permission);
|
|
13
|
+
|
|
14
|
+
if (permissionStatus === 'denied') {
|
|
15
|
+
throw new error();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return handler(...args);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
permissionFunction.getPermission = () => getPermission(permission);
|
|
22
|
+
permissionFunction.openPermissionDialog = () => openPermissionDialog(permission);
|
|
23
|
+
|
|
24
|
+
return permissionFunction as any;
|
|
25
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { FetchAlbumPhotos, FetchAlbumPhotosPermissionError } from '@apps-in-toss/types';
|
|
2
|
+
import { AppsInTossModule } from '../../AppsInTossModule';
|
|
3
|
+
import { createPermissionFunction } from '../createPermissionFunction';
|
|
4
|
+
|
|
5
|
+
const DEFAULT_MAX_COUNT = 10;
|
|
6
|
+
const DEFAULT_MAX_WIDTH = 1024;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @public
|
|
10
|
+
* @category 사진
|
|
11
|
+
* @name fetchAlbumPhotos
|
|
12
|
+
* @description
|
|
13
|
+
* 사용자의 앨범에서 사진 목록을 불러오는 함수예요.
|
|
14
|
+
* 최대 개수와 해상도를 설정할 수 있고 갤러리 미리보기, 이미지 선택 기능 등에 활용할 수 있어요.
|
|
15
|
+
*
|
|
16
|
+
* @param options - 조회 옵션을 담은 객체예요.
|
|
17
|
+
* @param {number} [options.maxCount=10] 가져올 사진의 최대 개수를 설정해요. 숫자로 입력하며 기본값은 10이에요.
|
|
18
|
+
* @param {number} [options.maxWidth=1024] 사진의 최대 폭을 제한해요. 단위는 픽셀이며 기본값은 `1024`이에요.
|
|
19
|
+
* @param {boolean} [options.base64=false] 이미지를 base64 형식으로 반환할지 설정해요. 기본값은 `false`예요.
|
|
20
|
+
* @property [openPermissionDialog] - 사진첩 읽기 권한을 다시 요청하는 다이얼로그를 표시해요. 사용자는 "허용", "한 번만 허용", "안하기" 중 하나를 선택할 수 있어요. "허용"이나 "한 번만 허용"을 선택하면 `allowed`를 반환하고, "안하기"를 선택하면 `denied`를 반환해요.
|
|
21
|
+
* @property [getPermission] - 사진첩 읽기 권한의 현재 상태를 반환해요. `allowed`는 사용자가 사진첩 읽기 권한을 허용한 상태예요. `denied`는 사용자가 사진첩 읽기 권한을 거부한 상태예요. `notDetermined`는 사진첩 읽기 권한 요청을 한 번도 하지 않은 상태예요.
|
|
22
|
+
* @returns {Promise<ImageResponse[]>}
|
|
23
|
+
* 앨범 사진의 고유 ID와 데이터 URI를 포함한 배열을 반환해요.
|
|
24
|
+
*
|
|
25
|
+
* @signature
|
|
26
|
+
* ```typescript
|
|
27
|
+
* function fetchAlbumPhotos(options: {
|
|
28
|
+
* maxCount: number;
|
|
29
|
+
* maxWidth: number;
|
|
30
|
+
* base64: boolean;
|
|
31
|
+
* }): Promise<ImageResponse[]>;
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ### 사진의 최대 폭을 360px로 제한하여 가져오기
|
|
36
|
+
*
|
|
37
|
+
* 사진을 가져오는 예제예요.
|
|
38
|
+
* "권한 확인하기"버튼을 눌러서 현재 사진첩 읽기 권한을 확인해요.
|
|
39
|
+
* 사용자가 권한을 거부했거나 시스템에서 권한이 제한된 경우에는 [`FetchAlbumPhotosPermissionError`](/react-native/reference/types/권한/FetchAlbumPhotosPermissionError)를 반환해요.
|
|
40
|
+
* "권한 요청하기"버튼을 눌러서 사진첩 읽기 권한을 요청할 수 있어요.
|
|
41
|
+
*
|
|
42
|
+
* ```tsx
|
|
43
|
+
* import { fetchAlbumPhotos, FetchAlbumPhotosPermissionError, ImageResponse } from '@apps-in-toss/framework';
|
|
44
|
+
* import { useState } from 'react';
|
|
45
|
+
* import { Alert, Button, Image, View } from 'react-native';
|
|
46
|
+
*
|
|
47
|
+
* const base64 = true;
|
|
48
|
+
*
|
|
49
|
+
* // 앨범 사진 목록을 가져와 화면에 표시하는 컴포넌트
|
|
50
|
+
* function AlbumPhotoList() {
|
|
51
|
+
* const [albumPhotos, setAlbumPhotos] = useState<ImageResponse[]>([]);
|
|
52
|
+
*
|
|
53
|
+
* const handlePress = async () => {
|
|
54
|
+
* try {
|
|
55
|
+
* const response = await fetchAlbumPhotos({
|
|
56
|
+
* base64,
|
|
57
|
+
* maxWidth: 360,
|
|
58
|
+
* });
|
|
59
|
+
* setAlbumPhotos((prev) => [...prev, ...response]);
|
|
60
|
+
* } catch (error) {
|
|
61
|
+
* if (error instanceof FetchAlbumPhotosPermissionError) {
|
|
62
|
+
* // 앨범 읽기 권한 없음
|
|
63
|
+
* }
|
|
64
|
+
* console.error('앨범을 가져오는 데 실패했어요:', error);
|
|
65
|
+
* }
|
|
66
|
+
* };
|
|
67
|
+
*
|
|
68
|
+
* return (
|
|
69
|
+
* <View>
|
|
70
|
+
* {albumPhotos.map((image) => {
|
|
71
|
+
* // base64 형식으로 반환된 이미지를 표시하려면 데이터 URL 스키마 Prefix를 붙여야해요.
|
|
72
|
+
* const imageUri = base64 ? 'data:image/jpeg;base64,' + image.dataUri : image.dataUri;
|
|
73
|
+
*
|
|
74
|
+
* return <Image source={{ uri: imageUri }} key={image.id} />;
|
|
75
|
+
* })}
|
|
76
|
+
* <Button title="앨범 가져오기" onPress={handlePress} />
|
|
77
|
+
* <Button
|
|
78
|
+
* title="권한 확인하기"
|
|
79
|
+
* onPress={async () => {
|
|
80
|
+
* const permission = await fetchAlbumPhotos.getPermission();
|
|
81
|
+
* Alert.alert(permission);
|
|
82
|
+
* }}
|
|
83
|
+
* />
|
|
84
|
+
* <Button
|
|
85
|
+
* title="권한 요청하기"
|
|
86
|
+
* onPress={async () => {
|
|
87
|
+
* const permission = await fetchAlbumPhotos.openPermissionDialog();
|
|
88
|
+
* Alert.alert(permission);
|
|
89
|
+
* }}
|
|
90
|
+
* />
|
|
91
|
+
* </View>
|
|
92
|
+
* );
|
|
93
|
+
* }
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export const fetchAlbumPhotos = createPermissionFunction<FetchAlbumPhotos>({
|
|
97
|
+
handler: async (options) => {
|
|
98
|
+
return AppsInTossModule.fetchAlbumPhotos({
|
|
99
|
+
...options,
|
|
100
|
+
maxCount: options?.maxCount ?? DEFAULT_MAX_COUNT,
|
|
101
|
+
maxWidth: options?.maxWidth ?? DEFAULT_MAX_WIDTH,
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
permission: {
|
|
105
|
+
name: 'photos',
|
|
106
|
+
access: 'read',
|
|
107
|
+
},
|
|
108
|
+
error: FetchAlbumPhotosPermissionError,
|
|
109
|
+
});
|