react-native-attachment-kit 1.0.2 → 1.0.6
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/CHANGELOG.md +121 -0
- package/README.md +446 -206
- package/android/build.gradle +17 -0
- package/android/src/main/libs/rnattachmentkit-release.aar +0 -0
- package/android/src/newarch/java/com/rnattachmentkit/RNAttachmentKitModule.kt +587 -22
- package/android/src/oldarch/java/com/rnattachmentkit/RNAttachmentKitModule.kt +592 -21
- package/ios/RNAttachmentKit.m +62 -0
- package/ios/RNAttachmentKit.swift +725 -29
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/Assets.car +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/Headers/RNAttachmentKit-Swift.h +51 -5
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/Info.plist +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios.abi.json +51876 -18835
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios.private.swiftinterface +310 -5
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios.swiftinterface +310 -5
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/RNAttachmentKit +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_crop_reflect~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_crop_reflect~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_crop_rotate~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_crop_rotate~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_delete~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_delete~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_forward~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_forward~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_reward~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_reward~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_back~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_back~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_blur~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_blur~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check_small~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check_small~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_close~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_close~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_crop~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_crop~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_drawing~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_drawing~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_effect~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_effect~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_emoji~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_emoji~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_eraser~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_eraser~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_mosaic~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_mosaic~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_text~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_text~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_text_add~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_text_add~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/_CodeSignature/CodeDirectory +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/_CodeSignature/CodeResources +195 -63
- package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/_CodeSignature/CodeSignature +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Assets.car +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Headers/RNAttachmentKit-Swift.h +102 -10
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Info.plist +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios-simulator.abi.json +51876 -18835
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +310 -5
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios-simulator.swiftinterface +310 -5
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/x86_64-apple-ios-simulator.abi.json +51876 -18835
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +310 -5
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +310 -5
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/RNAttachmentKit +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_crop_reflect~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_crop_reflect~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_crop_rotate~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_crop_rotate~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_delete~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_delete~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_forward~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_forward~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_reward~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_reward~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_back~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_back~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_blur~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_blur~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check_small~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check_small~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_close~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_close~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_crop~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_crop~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_drawing~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_drawing~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_effect~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_effect~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_emoji~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_emoji~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_eraser~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_eraser~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_mosaic~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_mosaic~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_text~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_text~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_text_add~dark.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_text_add~light.webp +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/_CodeSignature/CodeDirectory +0 -0
- package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/_CodeSignature/CodeResources +205 -73
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_crop_reflect~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_crop_reflect~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_crop_rotate~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_crop_rotate~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_drawing_delete~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_drawing_delete~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_drawing_forward~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_drawing_forward~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_drawing_reward~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_drawing_reward~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_back~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_back~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_blur~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_blur~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_check_small~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_check_small~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_check~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_check~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_close~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_close~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_crop~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_crop~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_drawing~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_drawing~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_effect~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_effect~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_emoji~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_emoji~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_eraser~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_eraser~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_mosaic~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_mosaic~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_text~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_text~light.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_text_add~dark.webp +0 -0
- package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_text_add~light.webp +0 -0
- package/package.json +1 -1
- package/react-native-attachment-kit.podspec +1 -1
- package/src/NativeAttachmentKit.ts +15 -0
- package/src/index.d.ts +5 -56
- package/src/index.ts +301 -37
- package/src/types.ts +380 -11
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-attachment-kit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Native attachment kit for React Native — gallery picker, editor, image viewer and media gallery (Turbo Module)",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -26,7 +26,7 @@ Pod::Spec.new do |s|
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
s.vendored_frameworks = "ios/RNAttachmentKit.xcframework"
|
|
29
|
-
s.frameworks = "MapKit", "CoreLocation", "UniformTypeIdentifiers" #
|
|
29
|
+
s.frameworks = "MapKit", "CoreLocation", "UniformTypeIdentifiers", "Vision", "CryptoKit", "CoreMotion" # 위치·파일 탭 / AI 편집 사진 분석·캐시 / 카메라 기기 방향
|
|
30
30
|
|
|
31
31
|
# s.dependency "SDWebImageWebPCoder"
|
|
32
32
|
|
|
@@ -7,6 +7,8 @@ export interface Spec extends TurboModule {
|
|
|
7
7
|
openEditor(options: Object): Promise<Object>;
|
|
8
8
|
openViewer(options: Object): Promise<void>;
|
|
9
9
|
closeGallery(): Promise<boolean>;
|
|
10
|
+
/** 동영상 변환 취소. index -1 = 남은 동영상 전부, processingId "" = 가장 최근 처리 */
|
|
11
|
+
cancelVideoProcessing(index: number, processingId: string): Promise<boolean>;
|
|
10
12
|
|
|
11
13
|
// RCTEventEmitter 필수 규격 (Turbo Module에서 이벤트 방출 시 필수)
|
|
12
14
|
addListener(eventName: string): void;
|
|
@@ -16,6 +18,19 @@ export interface Spec extends TurboModule {
|
|
|
16
18
|
|
|
17
19
|
getDefaultAnimationConfig(): Promise<Object>;
|
|
18
20
|
|
|
21
|
+
// 지도 뷰어 (위치 메시지)
|
|
22
|
+
openMapViewer(options: Object): Promise<void>;
|
|
23
|
+
updateMapViewerSourceRect(rect: Object): Promise<void>;
|
|
24
|
+
// 위치 메시지 지도 썸네일 (이 기기에서 그려 캐시)
|
|
25
|
+
renderLocationThumbnail(options: Object): Promise<Object>;
|
|
26
|
+
clearLocationThumbnailCache(): Promise<void>;
|
|
27
|
+
// 좌표 → 주소 (기기 지오코더, 디스크 캐시)
|
|
28
|
+
reverseGeocode(options: Object): Promise<Object>;
|
|
29
|
+
clearReverseGeocodeCache(): Promise<void>;
|
|
30
|
+
|
|
31
|
+
// AI 기능 설정·잔액 (넘긴 값만 바뀜). 사용·충전 요청은 onAIUsage / onAIChargeRequired 이벤트
|
|
32
|
+
setAIConfig(config: Object): Promise<void>;
|
|
33
|
+
|
|
19
34
|
// 미디어 갤러리 (사진 모아보기)
|
|
20
35
|
openMediaGallery(options: Object): Promise<Object>;
|
|
21
36
|
closeMediaGallery(galleryId: string): Promise<void>;
|
package/src/index.d.ts
CHANGED
|
@@ -1,56 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface GalleryOptions {
|
|
9
|
-
maxSelection?: number
|
|
10
|
-
mediaType?: "photo" | "video" | "all"
|
|
11
|
-
quality?: number
|
|
12
|
-
allItemsText?: string
|
|
13
|
-
selectedItemsText?: string
|
|
14
|
-
doneButtonText?: string
|
|
15
|
-
recentsAlbumText?: string
|
|
16
|
-
languageCode?: string
|
|
17
|
-
autoCloseOnSelect?: boolean
|
|
18
|
-
/**
|
|
19
|
-
* 선택 방식.
|
|
20
|
-
* - 'single': 한 장 즉시 선택형 (기존 maxSelection 0/1 동작 — 탭하면 바로 반환, 편집 ON 이면 탭 → 편집 → 전송)
|
|
21
|
-
* - 'multi' : 체크(번호 배지) → (필요하면 편집) → 완료. maxSelection 이 1 이어도 멀티와 똑같이 동작하고,
|
|
22
|
-
* 1장일 때 다른 사진을 고르면 기존 선택과 교체됩니다. autoCloseOnSelect 는 무시되며 maxSelection 생략/1 미만이면 1장.
|
|
23
|
-
* 생략 시 기존 규칙으로 판단: autoCloseOnSelect 또는 maxSelection <= 1 → 단일, 그 외 멀티 (하위 호환)
|
|
24
|
-
*/
|
|
25
|
-
selectionMode?: "single" | "multi"
|
|
26
|
-
enableEditor?: boolean // 단일 이미지 선택 시 편집기 활성화 여부
|
|
27
|
-
themeColor?: string // 테마 컬러 지정 (ex: "#FFEB3B")
|
|
28
|
-
onSelectionChange?: (event: SelectionChangeEvent) => void
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface SelectionChangeEvent {
|
|
32
|
-
selectedCount: number
|
|
33
|
-
maxSelection: number
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface RNAttachmentKit {
|
|
37
|
-
init(licenseKey: string): Promise<boolean>;
|
|
38
|
-
openGallery(options?: GalleryOptions): Promise<ImageResult[]>;
|
|
39
|
-
openEditor(options: EditorOptions): Promise<ImageResult>;
|
|
40
|
-
closeGallery(): Promise<boolean>
|
|
41
|
-
addSelectionChangeListener(listener: (event: SelectionChangeEvent) => void): () => void
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Returns true if using Turbo Module (New Architecture)
|
|
46
|
-
*/
|
|
47
|
-
export const isUsingTurboModule: boolean
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Returns true if using Legacy Native Module (Old Architecture)
|
|
51
|
-
*/
|
|
52
|
-
export const isUsingLegacyModule: boolean
|
|
53
|
-
|
|
54
|
-
declare const AttachmentKit: RNAttachmentKit
|
|
55
|
-
|
|
56
|
-
export default AttachmentKit
|
|
1
|
+
// package.json 의 "types" 는 src/index.ts 를 가리키므로 이 파일은 소비자에게 쓰이지 않습니다.
|
|
2
|
+
// 예전엔 손으로 관리하던 복사본이 index.ts / types.ts 와 어긋나 있었기 때문에, 이제는 실제 export 를 그대로 재노출만 합니다.
|
|
3
|
+
export * from "./types"
|
|
4
|
+
export { default } from "./index"
|
|
5
|
+
export * from "./index"
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { NativeModules, Platform, TurboModuleRegistry, NativeEventEmitter } from "react-native"
|
|
2
|
-
import type { ImageResult, GalleryOptions, EditorOptions, SelectionChangeEvent, ViewerOptions, MediaGalleryOptions, MediaGalleryAppendPayload, MediaGalleryRemovePayload, Appearance } from "./types"
|
|
1
|
+
import { NativeModules, Platform, TurboModuleRegistry, NativeEventEmitter, DeviceEventEmitter } from "react-native"
|
|
2
|
+
import type { ImageResult, GalleryOptions, EditorOptions, SelectionChangeEvent, ViewerOptions, MediaGalleryOptions, MediaGalleryAppendPayload, MediaGalleryRemovePayload, Appearance, AIConfig, AIUsageEvent, AIChargeRequiredEvent } from "./types"
|
|
3
3
|
|
|
4
4
|
const LINKING_ERROR = `The package 'react-native-attachment-kit' doesn't seem to be linked. Make sure: \n\n` + Platform.select({ ios: "- You have run 'pod install'\n", default: "" }) + "- You rebuilt the app after installing the package\n" + "- You are not using Expo Go\n"
|
|
5
5
|
|
|
@@ -15,6 +15,8 @@ try {
|
|
|
15
15
|
|
|
16
16
|
let _defaultThemeColor = "#10b981";
|
|
17
17
|
let _defaultLanguageCode = "en";
|
|
18
|
+
/** setDefaults/init 에 넘긴 언어 코드 그대로 (예: "zh-Hans", "pt-BR") — 주소(역지오코딩)는 UI 언어 목록으로 줄이지 않음 */
|
|
19
|
+
let _rawLanguageCode: string | null = null;
|
|
18
20
|
let _defaultAppearance: Appearance = "system";
|
|
19
21
|
|
|
20
22
|
/** "light" | "dark" 외의 값(생략·오타 포함)은 "system" */
|
|
@@ -64,7 +66,31 @@ if (!RNAttachmentKitModule) {
|
|
|
64
66
|
// Create event emitter
|
|
65
67
|
const eventEmitter = new NativeEventEmitter(RNAttachmentKitModule)
|
|
66
68
|
|
|
67
|
-
|
|
69
|
+
/** 같은 화면을 중복으로 열려고 할 때 reject 하는 Error (code: "E_ALREADY_OPEN") */
|
|
70
|
+
function alreadyOpenError(what: string): Error {
|
|
71
|
+
const err = new Error(`${what} is already open`)
|
|
72
|
+
;(err as any).code = "E_ALREADY_OPEN"
|
|
73
|
+
return err
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* openGallery 가 아직 끝나지 않았는지. 네이티브는 갤러리 Promise 를 하나만 보관하므로(iOS currentGalleryVC,
|
|
78
|
+
* Android pickImagesPromise) 중복 호출하면 앞 호출의 Promise 가 영영 끝나지 않습니다 → JS 에서 먼저 막습니다.
|
|
79
|
+
*/
|
|
80
|
+
let _galleryOpen = false
|
|
81
|
+
/** 어느 openGallery 호출이 _galleryOpen 을 잡고 있는지 — 처리 시작(onProcessingStart)에 먼저 풀고, 늦게 끝난 앞 호출이 새 호출의 잠금을 풀지 않게 */
|
|
82
|
+
let _galleryOpenToken = 0
|
|
83
|
+
/** openEditor 도 Android 가 editImagePromise 하나만 보관하므로 같은 보호가 필요 */
|
|
84
|
+
let _editorOpen = false
|
|
85
|
+
/**
|
|
86
|
+
* asyncProcessing 모드의 onImageProcessed 구독. 이 모드에선 openGallery 가 끝난 뒤에도 이벤트가 오므로
|
|
87
|
+
* finally 에서 제거하지 않고, 다음 openGallery(asyncProcessing) 호출 때 이전 구독만 제거합니다 (최대 1개 유지).
|
|
88
|
+
*/
|
|
89
|
+
let _asyncImgProcessedSub: { remove: () => void } | null = null
|
|
90
|
+
|
|
91
|
+
export type { AIConfig, AIUsageEvent, AIChargeRequiredEvent } from "./types"
|
|
92
|
+
export type { VideoOptions, VideoProgressEvent, ViewerVideo, ProcessingStartEvent, ProcessingStartItem } from "./types"
|
|
93
|
+
export type { SelectionChangeEvent, Appearance, AttachLocationResult, MapViewerOptions, ReverseGeocodeOptions, ReverseGeocodeResult, ReverseGeocodeErrorCode, AttachFileResult, AttachFileFailure, LocationThumbnailOptions, LocationThumbnailResult } from "./types"
|
|
68
94
|
export type { MediaGalleryItem, MediaGalleryOptions, MediaGalleryGridSize, MediaGalleryGridSizeChangedEvent, MediaGalleryTheme, MediaGalleryViewerOptions, MediaGalleryDeleteOption, MediaGalleryItemDeletedEvent, MediaGalleryNeedPageEvent, MediaGalleryClosedEvent, MediaGalleryAppendPayload, MediaGalleryRemovePayload } from "./types"
|
|
69
95
|
|
|
70
96
|
export interface RNAttachmentKit {
|
|
@@ -77,7 +103,39 @@ export interface RNAttachmentKit {
|
|
|
77
103
|
openEditor(options: EditorOptions): Promise<ImageResult>
|
|
78
104
|
openViewer(options: ViewerOptions): Promise<void>
|
|
79
105
|
updateSourceRect(rect: import("./types").SourceRect): Promise<void>
|
|
106
|
+
/** 지도 뷰어. 닫히면 resolve */
|
|
107
|
+
openMapViewer(options: import("./types").MapViewerOptions): Promise<void>
|
|
108
|
+
/** 지도 뷰어가 열린 동안 말풍선 위치가 바뀌었을 때 (닫힐 때 돌아갈 자리) */
|
|
109
|
+
updateMapViewerSourceRect(rect: import("./types").SourceRect | null): Promise<void>
|
|
110
|
+
/** 위치 메시지 말풍선 지도 썸네일을 이 기기에서 그려 캐시 (같은 요청이면 캐시에서 바로) */
|
|
111
|
+
renderLocationThumbnail(options: import("./types").LocationThumbnailOptions): Promise<import("./types").LocationThumbnailResult>
|
|
112
|
+
/** renderLocationThumbnail 캐시 비우기 */
|
|
113
|
+
clearLocationThumbnailCache(): Promise<void>
|
|
114
|
+
/**
|
|
115
|
+
* 좌표 → 주소 (기기 지오코더, 무료). 언어는 languageCode 그대로 (생략하면 setDefaults 의 languageCode).
|
|
116
|
+
* 결과("결과 없음" 포함)는 디스크에 캐시. 오류는 ReverseGeocodeErrorCode 로 reject (캐시 안 함)
|
|
117
|
+
*/
|
|
118
|
+
reverseGeocode(options: import("./types").ReverseGeocodeOptions): Promise<import("./types").ReverseGeocodeResult>
|
|
119
|
+
/** reverseGeocode 캐시 비우기 */
|
|
120
|
+
clearReverseGeocodeCache(): Promise<void>
|
|
80
121
|
closeGallery(): Promise<boolean>
|
|
122
|
+
/**
|
|
123
|
+
* processingId: 어느 보내기인지 (onProcessingStart 의 값). 생략하면 가장 최근 보내기
|
|
124
|
+
*
|
|
125
|
+
* 보내는 중인 동영상 변환 취소 (HUD 없이 말풍선에서 취소할 때). index 생략 = 남은 동영상 전부.
|
|
126
|
+
* 취소된 동영상은 onImageProcessed·결과에 { error: "CANCELLED", cancelled: true } 로 오고 나머지는 계속 처리됩니다.
|
|
127
|
+
* 진행 중인 처리가 없으면 false
|
|
128
|
+
*/
|
|
129
|
+
cancelVideoProcessing(index?: number, processingId?: string): Promise<boolean>
|
|
130
|
+
/**
|
|
131
|
+
* AI 기능 on/off · 포인트 · 무료 횟수 · 1회 차감 포인트 (넘긴 값만 바뀜). 앱 시작 때 한 번, 잔액이 바뀔 때마다(충전·서버 동기화) 다시 호출.
|
|
132
|
+
* AI 화면이 열려 있으면 바로 반영됩니다.
|
|
133
|
+
*/
|
|
134
|
+
setAIConfig(config: AIConfig): Promise<void>
|
|
135
|
+
/** AI 를 한 번 쓸 때마다 (무료 횟수 사용 또는 포인트 차감) — 앱이 서버에 반영. 해제 함수를 돌려줌 */
|
|
136
|
+
addAIUsageListener(listener: (event: AIUsageEvent) => void): () => void
|
|
137
|
+
/** 포인트가 모자라 사용자가 '충전하기'를 눌렀을 때 — 앱이 충전 화면으로 안내 (필요하면 closeGallery() 로 시트도 닫기). 해제 함수를 돌려줌 */
|
|
138
|
+
addAIChargeRequiredListener(listener: (event: AIChargeRequiredEvent) => void): () => void
|
|
81
139
|
addSelectionChangeListener(listener: (event: SelectionChangeEvent) => void): () => void
|
|
82
140
|
getDefaultAnimationConfig(): Promise<{ galleryOpen: number, galleryClose: number, editorOpen: number, editorClose: number, viewerOpen: number, viewerClose: number }>
|
|
83
141
|
injectImageCache(urlString: string, localPath: string): Promise<boolean>
|
|
@@ -99,6 +157,7 @@ const AttachmentKit: RNAttachmentKit = {
|
|
|
99
157
|
}
|
|
100
158
|
if (options?.languageCode) {
|
|
101
159
|
_defaultLanguageCode = normalizeLanguageCode(options.languageCode);
|
|
160
|
+
_rawLanguageCode = options.languageCode;
|
|
102
161
|
}
|
|
103
162
|
if (options?.appearance) {
|
|
104
163
|
_defaultAppearance = normalizeAppearance(options.appearance);
|
|
@@ -111,7 +170,10 @@ const AttachmentKit: RNAttachmentKit = {
|
|
|
111
170
|
|
|
112
171
|
setDefaults: (options: DefaultOptions): void => {
|
|
113
172
|
if (options?.themeColor) _defaultThemeColor = options.themeColor
|
|
114
|
-
if (options?.languageCode)
|
|
173
|
+
if (options?.languageCode) {
|
|
174
|
+
_defaultLanguageCode = normalizeLanguageCode(options.languageCode)
|
|
175
|
+
_rawLanguageCode = options.languageCode
|
|
176
|
+
}
|
|
115
177
|
if (options?.appearance) _defaultAppearance = normalizeAppearance(options.appearance)
|
|
116
178
|
},
|
|
117
179
|
|
|
@@ -121,36 +183,115 @@ const AttachmentKit: RNAttachmentKit = {
|
|
|
121
183
|
if (!RNAttachmentKitModule) {
|
|
122
184
|
throw new Error(LINKING_ERROR)
|
|
123
185
|
}
|
|
186
|
+
// 이미 열려 있으면 네이티브를 건드리지 않고 바로 reject (앞 호출의 Promise 를 지키기 위해)
|
|
187
|
+
if (_galleryOpen) {
|
|
188
|
+
throw alreadyOpenError("Gallery")
|
|
189
|
+
}
|
|
190
|
+
_galleryOpen = true
|
|
191
|
+
const myToken = ++_galleryOpenToken
|
|
192
|
+
// 갤러리 화면이 닫히고 처리가 시작되면(onProcessingStart) 바로 잠금을 풂 — 동영상을 변환하는 동안에도
|
|
193
|
+
// 다시 열어 보낼 수 있게. Promise 는 지금처럼 처리가 다 끝나야 resolve
|
|
194
|
+
let myProcessingId: string | null = null
|
|
195
|
+
const subscriptionOpenLock = eventEmitter.addListener("onProcessingStart", (e: any) => {
|
|
196
|
+
if (myProcessingId) return
|
|
197
|
+
myProcessingId = typeof e?.processingId === "string" ? e.processingId : ""
|
|
198
|
+
if (_galleryOpenToken === myToken) _galleryOpen = false
|
|
199
|
+
})
|
|
200
|
+
/** 이 호출의 이벤트인지 — processingId 가 붙은 이벤트는 내 처리의 것만, 안 붙은(옛 네이티브·사진 1장 편집) 이벤트는 처리 ID 를 모를 때만 */
|
|
201
|
+
const isMine = (e: any) => {
|
|
202
|
+
const id = e?.processingId
|
|
203
|
+
if (typeof id !== "string" || id === "") return !myProcessingId
|
|
204
|
+
return myProcessingId === id
|
|
205
|
+
}
|
|
206
|
+
const mine = <T,>(fn?: (e: T) => void) => fn ? (e: T) => { if (isMine(e)) fn(e) } : undefined
|
|
124
207
|
|
|
125
208
|
// 콜백 이벤트 임시 리스너 등록
|
|
126
209
|
let subscriptionSelChange: any = null
|
|
127
210
|
let subscriptionImgProcessed: any = null
|
|
128
|
-
|
|
211
|
+
|
|
129
212
|
if (options.onSelectionChange) {
|
|
130
213
|
subscriptionSelChange = eventEmitter.addListener("onSelectionChange", options.onSelectionChange)
|
|
131
214
|
}
|
|
132
215
|
if (options.onImageProcessed) {
|
|
133
|
-
|
|
216
|
+
if (options.asyncProcessing) {
|
|
217
|
+
// async 모드: 이전 호출이 남겨 둔 구독을 먼저 제거해서 리스너가 쌓이지 않게 함
|
|
218
|
+
if (_asyncImgProcessedSub) {
|
|
219
|
+
try { _asyncImgProcessedSub.remove() } catch (e) { /* noop */ }
|
|
220
|
+
_asyncImgProcessedSub = null
|
|
221
|
+
}
|
|
222
|
+
subscriptionImgProcessed = eventEmitter.addListener("onImageProcessed", mine(options.onImageProcessed)!)
|
|
223
|
+
_asyncImgProcessedSub = subscriptionImgProcessed
|
|
224
|
+
} else {
|
|
225
|
+
subscriptionImgProcessed = eventEmitter.addListener("onImageProcessed", mine(options.onImageProcessed)!)
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
let subscriptionLocation: any = null
|
|
229
|
+
if (options.onLocationSelected) {
|
|
230
|
+
subscriptionLocation = eventEmitter.addListener("onLocationSelected", options.onLocationSelected)
|
|
231
|
+
}
|
|
232
|
+
// 동영상 변환 진행률 (video.onProgress)
|
|
233
|
+
let subscriptionVideoProgress: any = null
|
|
234
|
+
if (options.video?.onProgress) {
|
|
235
|
+
subscriptionVideoProgress = eventEmitter.addListener("onVideoProgress", mine(options.video.onProgress)!)
|
|
236
|
+
}
|
|
237
|
+
// 처리 시작 (보낸 직후 한 번, 결과보다 먼저)
|
|
238
|
+
let subscriptionProcessingStart: any = null
|
|
239
|
+
if (options.onProcessingStart) {
|
|
240
|
+
// 내 처리 시작만 (앞 보내기의 시작 이벤트는 이 호출 전에 이미 지나감)
|
|
241
|
+
const onStart = options.onProcessingStart
|
|
242
|
+
let started = false
|
|
243
|
+
subscriptionProcessingStart = eventEmitter.addListener("onProcessingStart", (e: any) => {
|
|
244
|
+
if (started) return
|
|
245
|
+
started = true
|
|
246
|
+
onStart(e)
|
|
247
|
+
})
|
|
248
|
+
}
|
|
249
|
+
let subscriptionFiles: any = null
|
|
250
|
+
if (options.onFilesSelected) {
|
|
251
|
+
const onFiles = options.onFilesSelected
|
|
252
|
+
// failed: 복사에 실패한 파일 목록 [{ name, error }] (없으면 undefined)
|
|
253
|
+
subscriptionFiles = eventEmitter.addListener("onFilesSelected", (e: any) => onFiles(e?.files ?? [], e?.failed ?? undefined))
|
|
134
254
|
}
|
|
135
255
|
|
|
136
256
|
try {
|
|
137
257
|
// 이벤트 콜백은 네이티브로 전달하지 않음
|
|
138
|
-
const { onSelectionChange, onImageProcessed, ...restOptions } = options
|
|
139
|
-
const nativeOptions = {
|
|
258
|
+
const { onSelectionChange, onImageProcessed, onLocationSelected, onFilesSelected, onProcessingStart, video, ...restOptions } = options
|
|
259
|
+
const nativeOptions: any = {
|
|
140
260
|
themeColor: _defaultThemeColor,
|
|
141
261
|
languageCode: _defaultLanguageCode,
|
|
142
262
|
appearance: _defaultAppearance,
|
|
143
263
|
...restOptions,
|
|
144
264
|
}
|
|
265
|
+
if (video) {
|
|
266
|
+
// onProgress 콜백은 네이티브로 넘기지 않음
|
|
267
|
+
const { onProgress, ...videoRest } = video
|
|
268
|
+
nativeOptions.video = videoRest
|
|
269
|
+
}
|
|
145
270
|
nativeOptions.languageCode = normalizeLanguageCode(nativeOptions.languageCode)
|
|
146
271
|
nativeOptions.appearance = normalizeAppearance(nativeOptions.appearance)
|
|
147
272
|
const result = await RNAttachmentKitModule.openGallery(nativeOptions)
|
|
148
273
|
return result
|
|
149
274
|
} finally {
|
|
275
|
+
// 처리 시작 때 이미 풀었고 그 뒤 새 호출이 잡았을 수 있음 → 내 잠금일 때만
|
|
276
|
+
if (_galleryOpenToken === myToken) _galleryOpen = false
|
|
277
|
+
subscriptionOpenLock.remove()
|
|
150
278
|
// 갤러리가 닫히면 onSelectionChange 리스너 제거
|
|
151
279
|
if (subscriptionSelChange) {
|
|
152
280
|
subscriptionSelChange.remove()
|
|
153
281
|
}
|
|
282
|
+
// 위치 이벤트는 openGallery 가 끝나기 전에 오므로 여기서 바로 제거
|
|
283
|
+
if (subscriptionLocation) {
|
|
284
|
+
subscriptionLocation.remove()
|
|
285
|
+
}
|
|
286
|
+
if (subscriptionFiles) {
|
|
287
|
+
subscriptionFiles.remove()
|
|
288
|
+
}
|
|
289
|
+
if (subscriptionVideoProgress) {
|
|
290
|
+
subscriptionVideoProgress.remove()
|
|
291
|
+
}
|
|
292
|
+
if (subscriptionProcessingStart) {
|
|
293
|
+
subscriptionProcessingStart.remove()
|
|
294
|
+
}
|
|
154
295
|
// asyncProcessing 모드가 아닐 때만 onImageProcessed 리스너 제거 (async 모드에선 백그라운드 처리를 위해 유지해야 함)
|
|
155
296
|
// 호출부에서 수동으로 제거하거나, 최종 완료 시 정리하는 구조가 필요할 수 있음
|
|
156
297
|
if (!options.asyncProcessing && subscriptionImgProcessed) {
|
|
@@ -163,6 +304,11 @@ const AttachmentKit: RNAttachmentKit = {
|
|
|
163
304
|
if (!RNAttachmentKitModule) {
|
|
164
305
|
throw new Error(LINKING_ERROR)
|
|
165
306
|
}
|
|
307
|
+
// Android 는 editImagePromise 를 하나만 보관해서 중복 호출 시 앞 Promise 가 끝나지 않음 → JS 에서 막음
|
|
308
|
+
if (_editorOpen) {
|
|
309
|
+
throw alreadyOpenError("Editor")
|
|
310
|
+
}
|
|
311
|
+
_editorOpen = true
|
|
166
312
|
const mergedOptions = {
|
|
167
313
|
themeColor: _defaultThemeColor,
|
|
168
314
|
languageCode: _defaultLanguageCode,
|
|
@@ -171,7 +317,11 @@ const AttachmentKit: RNAttachmentKit = {
|
|
|
171
317
|
}
|
|
172
318
|
mergedOptions.languageCode = normalizeLanguageCode(mergedOptions.languageCode)
|
|
173
319
|
mergedOptions.appearance = normalizeAppearance(mergedOptions.appearance)
|
|
174
|
-
|
|
320
|
+
try {
|
|
321
|
+
return await RNAttachmentKitModule.openEditor(mergedOptions)
|
|
322
|
+
} finally {
|
|
323
|
+
_editorOpen = false
|
|
324
|
+
}
|
|
175
325
|
},
|
|
176
326
|
|
|
177
327
|
openViewer: async (options: ViewerOptions): Promise<void> => {
|
|
@@ -225,34 +375,34 @@ const AttachmentKit: RNAttachmentKit = {
|
|
|
225
375
|
})
|
|
226
376
|
}
|
|
227
377
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
378
|
+
// 네이티브 "onViewerWillClose"(iOS sendEvent / Android RCTDeviceEventEmitter) 는 앱이 콜백을 넘기지 않아도
|
|
379
|
+
// 항상 구독합니다 — 이 이벤트가 와야 onPageSelected / onImageDeleted 구독을 정리할 수 있기 때문입니다
|
|
380
|
+
// (예전엔 options.onViewerWillClose 가 없으면 구독을 안 해서 뷰어를 열 때마다 리스너가 누수됐음).
|
|
381
|
+
const closeHandler = () => {
|
|
382
|
+
if (options.onViewerWillClose) {
|
|
383
|
+
options.onViewerWillClose()
|
|
384
|
+
}
|
|
385
|
+
if (subscriptionPageSelected) {
|
|
386
|
+
subscriptionPageSelected.remove()
|
|
387
|
+
}
|
|
388
|
+
if (subscriptionViewerOpened) {
|
|
389
|
+
subscriptionViewerOpened.remove()
|
|
390
|
+
}
|
|
391
|
+
if (subscriptionViewerWillClose) {
|
|
392
|
+
subscriptionViewerWillClose.remove()
|
|
393
|
+
}
|
|
394
|
+
if (deviceSubscriptionViewerWillClose) {
|
|
395
|
+
deviceSubscriptionViewerWillClose.remove()
|
|
396
|
+
}
|
|
397
|
+
if (subscriptionImageDeleted) {
|
|
398
|
+
subscriptionImageDeleted.remove()
|
|
399
|
+
}
|
|
400
|
+
};
|
|
249
401
|
|
|
250
|
-
|
|
402
|
+
subscriptionViewerWillClose = eventEmitter.addListener("onViewerWillClose", closeHandler);
|
|
251
403
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
deviceSubscriptionViewerWillClose = DeviceEventEmitter.addListener("onViewerWillClose", closeHandler);
|
|
255
|
-
}
|
|
404
|
+
if (Platform.OS === "android") {
|
|
405
|
+
deviceSubscriptionViewerWillClose = DeviceEventEmitter.addListener("onViewerWillClose", closeHandler);
|
|
256
406
|
}
|
|
257
407
|
|
|
258
408
|
try {
|
|
@@ -266,9 +416,14 @@ const AttachmentKit: RNAttachmentKit = {
|
|
|
266
416
|
mergedOptions.languageCode = normalizeLanguageCode(mergedOptions.languageCode)
|
|
267
417
|
mergedOptions.appearance = normalizeAppearance(mergedOptions.appearance)
|
|
268
418
|
return await RNAttachmentKitModule.openViewer(mergedOptions)
|
|
269
|
-
}
|
|
270
|
-
//
|
|
419
|
+
} catch (e) {
|
|
420
|
+
// 뷰어가 아예 안 떴으면(reject) onViewerWillClose 가 오지 않으므로 여기서 구독 정리 (앱 콜백은 호출 안 함)
|
|
421
|
+
for (const sub of [subscriptionPageSelected, subscriptionViewerOpened, subscriptionImageDeleted, subscriptionViewerWillClose, deviceSubscriptionViewerWillClose]) {
|
|
422
|
+
try { sub?.remove() } catch (err) { /* noop */ }
|
|
423
|
+
}
|
|
424
|
+
throw e
|
|
271
425
|
}
|
|
426
|
+
// 정상적으로 열렸으면 리스너는 onViewerWillClose 콜백 안에서 제거됨
|
|
272
427
|
},
|
|
273
428
|
|
|
274
429
|
updateSourceRect: async (rect: import("./types").SourceRect): Promise<void> => {
|
|
@@ -278,6 +433,86 @@ const AttachmentKit: RNAttachmentKit = {
|
|
|
278
433
|
return RNAttachmentKitModule.updateSourceRect(rect)
|
|
279
434
|
},
|
|
280
435
|
|
|
436
|
+
openMapViewer: async (options: import("./types").MapViewerOptions): Promise<void> => {
|
|
437
|
+
if (!RNAttachmentKitModule) {
|
|
438
|
+
throw new Error(LINKING_ERROR)
|
|
439
|
+
}
|
|
440
|
+
const mergedOptions: Record<string, any> = {
|
|
441
|
+
themeColor: _defaultThemeColor,
|
|
442
|
+
languageCode: _defaultLanguageCode,
|
|
443
|
+
appearance: _defaultAppearance,
|
|
444
|
+
...options,
|
|
445
|
+
}
|
|
446
|
+
// 주소를 안 넘기면 네이티브가 채움 — reverseGeocode 와 같은 캐시를 쓰도록 같은 언어(넘긴 그대로)
|
|
447
|
+
mergedOptions.addressLanguageCode = options.languageCode || _rawLanguageCode || _defaultLanguageCode
|
|
448
|
+
mergedOptions.languageCode = normalizeLanguageCode(mergedOptions.languageCode)
|
|
449
|
+
mergedOptions.appearance = normalizeAppearance(mergedOptions.appearance)
|
|
450
|
+
// 함수는 네이티브로 못 넘김 — 닫기 시작은 이벤트로 받음 (Android 는 RCTDeviceEventEmitter 로도 올 수 있어 둘 다 듣고 한 번만)
|
|
451
|
+
const onWillClose = options.onViewerWillClose
|
|
452
|
+
delete mergedOptions.onViewerWillClose
|
|
453
|
+
let willCloseSent = false
|
|
454
|
+
const willCloseHandler = (e: any) => {
|
|
455
|
+
if (willCloseSent) return
|
|
456
|
+
willCloseSent = true
|
|
457
|
+
onWillClose?.({ durationMs: typeof e?.durationMs === 'number' ? e.durationMs : 0 })
|
|
458
|
+
}
|
|
459
|
+
const subs: any[] = [eventEmitter.addListener("onMapViewerWillClose", willCloseHandler)]
|
|
460
|
+
if (Platform.OS === "android") subs.push(DeviceEventEmitter.addListener("onMapViewerWillClose", willCloseHandler))
|
|
461
|
+
try {
|
|
462
|
+
await RNAttachmentKitModule.openMapViewer(mergedOptions)
|
|
463
|
+
} finally {
|
|
464
|
+
subs.forEach(s => s.remove())
|
|
465
|
+
}
|
|
466
|
+
},
|
|
467
|
+
|
|
468
|
+
updateMapViewerSourceRect: async (rect: import("./types").SourceRect | null): Promise<void> => {
|
|
469
|
+
if (!RNAttachmentKitModule) {
|
|
470
|
+
throw new Error(LINKING_ERROR)
|
|
471
|
+
}
|
|
472
|
+
return RNAttachmentKitModule.updateMapViewerSourceRect(rect ?? {})
|
|
473
|
+
},
|
|
474
|
+
|
|
475
|
+
renderLocationThumbnail: async (options: import("./types").LocationThumbnailOptions): Promise<import("./types").LocationThumbnailResult> => {
|
|
476
|
+
if (!RNAttachmentKitModule) {
|
|
477
|
+
throw new Error(LINKING_ERROR)
|
|
478
|
+
}
|
|
479
|
+
const mergedOptions = {
|
|
480
|
+
themeColor: _defaultThemeColor,
|
|
481
|
+
appearance: _defaultAppearance,
|
|
482
|
+
...options,
|
|
483
|
+
}
|
|
484
|
+
mergedOptions.appearance = normalizeAppearance(mergedOptions.appearance)
|
|
485
|
+
// 내 위치는 둘 다 있을 때만
|
|
486
|
+
if (typeof mergedOptions.myLatitude !== "number" || typeof mergedOptions.myLongitude !== "number") {
|
|
487
|
+
delete mergedOptions.myLatitude
|
|
488
|
+
delete mergedOptions.myLongitude
|
|
489
|
+
}
|
|
490
|
+
return RNAttachmentKitModule.renderLocationThumbnail(mergedOptions)
|
|
491
|
+
},
|
|
492
|
+
|
|
493
|
+
clearLocationThumbnailCache: async (): Promise<void> => {
|
|
494
|
+
if (!RNAttachmentKitModule) {
|
|
495
|
+
throw new Error(LINKING_ERROR)
|
|
496
|
+
}
|
|
497
|
+
return RNAttachmentKitModule.clearLocationThumbnailCache()
|
|
498
|
+
},
|
|
499
|
+
|
|
500
|
+
reverseGeocode: async (options: import("./types").ReverseGeocodeOptions): Promise<import("./types").ReverseGeocodeResult> => {
|
|
501
|
+
if (!RNAttachmentKitModule) {
|
|
502
|
+
throw new Error(LINKING_ERROR)
|
|
503
|
+
}
|
|
504
|
+
const languageCode = options.languageCode || _rawLanguageCode || _defaultLanguageCode
|
|
505
|
+
const r = await RNAttachmentKitModule.reverseGeocode({ latitude: options.latitude, longitude: options.longitude, languageCode })
|
|
506
|
+
return { address: r?.address ?? null, shortAddress: r?.shortAddress ?? null, cached: !!r?.cached }
|
|
507
|
+
},
|
|
508
|
+
|
|
509
|
+
clearReverseGeocodeCache: async (): Promise<void> => {
|
|
510
|
+
if (!RNAttachmentKitModule) {
|
|
511
|
+
throw new Error(LINKING_ERROR)
|
|
512
|
+
}
|
|
513
|
+
return RNAttachmentKitModule.clearReverseGeocodeCache()
|
|
514
|
+
},
|
|
515
|
+
|
|
281
516
|
closeGallery: async (): Promise<boolean> => {
|
|
282
517
|
if (!RNAttachmentKitModule) {
|
|
283
518
|
throw new Error(LINKING_ERROR)
|
|
@@ -286,6 +521,35 @@ const AttachmentKit: RNAttachmentKit = {
|
|
|
286
521
|
return RNAttachmentKitModule.closeGallery()
|
|
287
522
|
},
|
|
288
523
|
|
|
524
|
+
cancelVideoProcessing: async (index?: number, processingId?: string): Promise<boolean> => {
|
|
525
|
+
if (!RNAttachmentKitModule) {
|
|
526
|
+
throw new Error(LINKING_ERROR)
|
|
527
|
+
}
|
|
528
|
+
if (typeof RNAttachmentKitModule.cancelVideoProcessing !== "function") return false // 옛 네이티브 빌드
|
|
529
|
+
return RNAttachmentKitModule.cancelVideoProcessing(typeof index === "number" && index >= 0 ? index : -1, processingId ?? "")
|
|
530
|
+
},
|
|
531
|
+
|
|
532
|
+
setAIConfig: async (config: AIConfig): Promise<void> => {
|
|
533
|
+
if (!RNAttachmentKitModule) {
|
|
534
|
+
throw new Error(LINKING_ERROR)
|
|
535
|
+
}
|
|
536
|
+
if (typeof RNAttachmentKitModule.setAIConfig !== "function") return // 옛 네이티브 빌드
|
|
537
|
+
// undefined 는 "바꾸지 않음" 이므로 빼고 보냄 (null 은 "비움")
|
|
538
|
+
const payload: Record<string, unknown> = {}
|
|
539
|
+
Object.entries(config ?? {}).forEach(([k, v]) => { if (v !== undefined) payload[k] = v })
|
|
540
|
+
return RNAttachmentKitModule.setAIConfig(payload)
|
|
541
|
+
},
|
|
542
|
+
|
|
543
|
+
addAIUsageListener: (listener: (event: AIUsageEvent) => void) => {
|
|
544
|
+
const subscription = eventEmitter.addListener("onAIUsage", listener as any)
|
|
545
|
+
return () => subscription.remove()
|
|
546
|
+
},
|
|
547
|
+
|
|
548
|
+
addAIChargeRequiredListener: (listener: (event: AIChargeRequiredEvent) => void) => {
|
|
549
|
+
const subscription = eventEmitter.addListener("onAIChargeRequired", listener as any)
|
|
550
|
+
return () => subscription.remove()
|
|
551
|
+
},
|
|
552
|
+
|
|
289
553
|
addSelectionChangeListener: (listener: (event: SelectionChangeEvent) => void) => {
|
|
290
554
|
const subscription = eventEmitter.addListener("onSelectionChange", listener)
|
|
291
555
|
|