react-native-attachment-kit 1.0.2 → 1.0.5

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.
Files changed (143) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/README.md +356 -213
  3. package/android/build.gradle +3 -0
  4. package/android/src/main/libs/rnattachmentkit-release.aar +0 -0
  5. package/android/src/newarch/java/com/rnattachmentkit/RNAttachmentKitModule.kt +308 -10
  6. package/android/src/oldarch/java/com/rnattachmentkit/RNAttachmentKitModule.kt +311 -9
  7. package/ios/RNAttachmentKit.m +44 -0
  8. package/ios/RNAttachmentKit.swift +307 -23
  9. package/ios/RNAttachmentKit.xcframework/Info.plist +5 -5
  10. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/Headers/RNAttachmentKit-Swift.h +30 -0
  11. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios.abi.json +20349 -13021
  12. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios.private.swiftinterface +118 -1
  13. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  14. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios.swiftinterface +118 -1
  15. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/RNAttachmentKit +0 -0
  16. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_crop_reflect~dark.webp +0 -0
  17. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_crop_reflect~light.webp +0 -0
  18. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_crop_rotate~dark.webp +0 -0
  19. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_crop_rotate~light.webp +0 -0
  20. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_delete~dark.webp +0 -0
  21. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_delete~light.webp +0 -0
  22. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_forward~dark.webp +0 -0
  23. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_forward~light.webp +0 -0
  24. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_reward~dark.webp +0 -0
  25. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_reward~light.webp +0 -0
  26. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_back~dark.webp +0 -0
  27. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_back~light.webp +0 -0
  28. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_blur~dark.webp +0 -0
  29. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_blur~light.webp +0 -0
  30. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check_small~dark.webp +0 -0
  31. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check_small~light.webp +0 -0
  32. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check~dark.webp +0 -0
  33. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check~light.webp +0 -0
  34. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_close~dark.webp +0 -0
  35. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_close~light.webp +0 -0
  36. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_crop~dark.webp +0 -0
  37. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_crop~light.webp +0 -0
  38. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_drawing~dark.webp +0 -0
  39. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_drawing~light.webp +0 -0
  40. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_effect~dark.webp +0 -0
  41. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_effect~light.webp +0 -0
  42. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_emoji~dark.webp +0 -0
  43. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_emoji~light.webp +0 -0
  44. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_eraser~dark.webp +0 -0
  45. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_eraser~light.webp +0 -0
  46. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_mosaic~dark.webp +0 -0
  47. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_mosaic~light.webp +0 -0
  48. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_text~dark.webp +0 -0
  49. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_editor_text~light.webp +0 -0
  50. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_text_add~dark.webp +0 -0
  51. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/ToolbarIcons/ic_text_add~light.webp +0 -0
  52. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/_CodeSignature/CodeDirectory +0 -0
  53. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/_CodeSignature/CodeResources +192 -60
  54. package/ios/RNAttachmentKit.xcframework/ios-arm64/RNAttachmentKit.framework/_CodeSignature/CodeSignature +0 -0
  55. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Headers/RNAttachmentKit-Swift.h +60 -0
  56. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios-simulator.abi.json +20349 -13021
  57. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +118 -1
  58. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  59. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/arm64-apple-ios-simulator.swiftinterface +118 -1
  60. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/x86_64-apple-ios-simulator.abi.json +20349 -13021
  61. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +118 -1
  62. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  63. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/Modules/RNAttachmentKit.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +118 -1
  64. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/RNAttachmentKit +0 -0
  65. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_crop_reflect~dark.webp +0 -0
  66. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_crop_reflect~light.webp +0 -0
  67. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_crop_rotate~dark.webp +0 -0
  68. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_crop_rotate~light.webp +0 -0
  69. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_delete~dark.webp +0 -0
  70. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_delete~light.webp +0 -0
  71. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_forward~dark.webp +0 -0
  72. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_forward~light.webp +0 -0
  73. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_reward~dark.webp +0 -0
  74. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_drawing_reward~light.webp +0 -0
  75. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_back~dark.webp +0 -0
  76. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_back~light.webp +0 -0
  77. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_blur~dark.webp +0 -0
  78. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_blur~light.webp +0 -0
  79. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check_small~dark.webp +0 -0
  80. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check_small~light.webp +0 -0
  81. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check~dark.webp +0 -0
  82. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_check~light.webp +0 -0
  83. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_close~dark.webp +0 -0
  84. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_close~light.webp +0 -0
  85. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_crop~dark.webp +0 -0
  86. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_crop~light.webp +0 -0
  87. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_drawing~dark.webp +0 -0
  88. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_drawing~light.webp +0 -0
  89. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_effect~dark.webp +0 -0
  90. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_effect~light.webp +0 -0
  91. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_emoji~dark.webp +0 -0
  92. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_emoji~light.webp +0 -0
  93. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_eraser~dark.webp +0 -0
  94. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_eraser~light.webp +0 -0
  95. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_mosaic~dark.webp +0 -0
  96. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_mosaic~light.webp +0 -0
  97. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_text~dark.webp +0 -0
  98. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_editor_text~light.webp +0 -0
  99. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_text_add~dark.webp +0 -0
  100. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/ToolbarIcons/ic_text_add~light.webp +0 -0
  101. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/_CodeSignature/CodeDirectory +0 -0
  102. package/ios/RNAttachmentKit.xcframework/ios-arm64_x86_64-simulator/RNAttachmentKit.framework/_CodeSignature/CodeResources +202 -70
  103. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_crop_reflect~dark.webp +0 -0
  104. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_crop_reflect~light.webp +0 -0
  105. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_crop_rotate~dark.webp +0 -0
  106. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_crop_rotate~light.webp +0 -0
  107. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_drawing_delete~dark.webp +0 -0
  108. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_drawing_delete~light.webp +0 -0
  109. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_drawing_forward~dark.webp +0 -0
  110. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_drawing_forward~light.webp +0 -0
  111. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_drawing_reward~dark.webp +0 -0
  112. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_drawing_reward~light.webp +0 -0
  113. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_back~dark.webp +0 -0
  114. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_back~light.webp +0 -0
  115. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_blur~dark.webp +0 -0
  116. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_blur~light.webp +0 -0
  117. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_check_small~dark.webp +0 -0
  118. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_check_small~light.webp +0 -0
  119. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_check~dark.webp +0 -0
  120. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_check~light.webp +0 -0
  121. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_close~dark.webp +0 -0
  122. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_close~light.webp +0 -0
  123. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_crop~dark.webp +0 -0
  124. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_crop~light.webp +0 -0
  125. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_drawing~dark.webp +0 -0
  126. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_drawing~light.webp +0 -0
  127. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_effect~dark.webp +0 -0
  128. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_effect~light.webp +0 -0
  129. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_emoji~dark.webp +0 -0
  130. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_emoji~light.webp +0 -0
  131. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_eraser~dark.webp +0 -0
  132. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_eraser~light.webp +0 -0
  133. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_mosaic~dark.webp +0 -0
  134. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_mosaic~light.webp +0 -0
  135. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_text~dark.webp +0 -0
  136. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_editor_text~light.webp +0 -0
  137. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_text_add~dark.webp +0 -0
  138. package/ios/RNAttachmentKitAssets/ToolbarIcons/ic_text_add~light.webp +0 -0
  139. package/package.json +1 -1
  140. package/src/NativeAttachmentKit.ts +10 -0
  141. package/src/index.d.ts +5 -56
  142. package/src/index.ts +188 -35
  143. package/src/types.ts +207 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-attachment-kit",
3
- "version": "1.0.2",
3
+ "version": "1.0.5",
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",
@@ -16,6 +16,16 @@ export interface Spec extends TurboModule {
16
16
 
17
17
  getDefaultAnimationConfig(): Promise<Object>;
18
18
 
19
+ // 지도 뷰어 (위치 메시지)
20
+ openMapViewer(options: Object): Promise<void>;
21
+ updateMapViewerSourceRect(rect: Object): Promise<void>;
22
+ // 위치 메시지 지도 썸네일 (이 기기에서 그려 캐시)
23
+ renderLocationThumbnail(options: Object): Promise<Object>;
24
+ clearLocationThumbnailCache(): Promise<void>;
25
+ // 좌표 → 주소 (기기 지오코더, 디스크 캐시)
26
+ reverseGeocode(options: Object): Promise<Object>;
27
+ clearReverseGeocodeCache(): Promise<void>;
28
+
19
29
  // 미디어 갤러리 (사진 모아보기)
20
30
  openMediaGallery(options: Object): Promise<Object>;
21
31
  closeMediaGallery(galleryId: string): Promise<void>;
package/src/index.d.ts CHANGED
@@ -1,56 +1,5 @@
1
- export interface ImageResult {
2
- uri: string
3
- width: number
4
- height: number
5
- type: string
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,4 +1,4 @@
1
- import { NativeModules, Platform, TurboModuleRegistry, NativeEventEmitter } from "react-native"
1
+ import { NativeModules, Platform, TurboModuleRegistry, NativeEventEmitter, DeviceEventEmitter } from "react-native"
2
2
  import type { ImageResult, GalleryOptions, EditorOptions, SelectionChangeEvent, ViewerOptions, MediaGalleryOptions, MediaGalleryAppendPayload, MediaGalleryRemovePayload, Appearance } 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"
@@ -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,27 @@ if (!RNAttachmentKitModule) {
64
66
  // Create event emitter
65
67
  const eventEmitter = new NativeEventEmitter(RNAttachmentKitModule)
66
68
 
67
- export type { SelectionChangeEvent, Appearance } from "./types"
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
+ /** openEditor 도 Android 가 editImagePromise 하나만 보관하므로 같은 보호가 필요 */
82
+ let _editorOpen = false
83
+ /**
84
+ * asyncProcessing 모드의 onImageProcessed 구독. 이 모드에선 openGallery 가 끝난 뒤에도 이벤트가 오므로
85
+ * finally 에서 제거하지 않고, 다음 openGallery(asyncProcessing) 호출 때 이전 구독만 제거합니다 (최대 1개 유지).
86
+ */
87
+ let _asyncImgProcessedSub: { remove: () => void } | null = null
88
+
89
+ export type { SelectionChangeEvent, Appearance, AttachLocationResult, MapViewerOptions, ReverseGeocodeOptions, ReverseGeocodeResult, ReverseGeocodeErrorCode, AttachFileResult, AttachFileFailure, LocationThumbnailOptions, LocationThumbnailResult } from "./types"
68
90
  export type { MediaGalleryItem, MediaGalleryOptions, MediaGalleryGridSize, MediaGalleryGridSizeChangedEvent, MediaGalleryTheme, MediaGalleryViewerOptions, MediaGalleryDeleteOption, MediaGalleryItemDeletedEvent, MediaGalleryNeedPageEvent, MediaGalleryClosedEvent, MediaGalleryAppendPayload, MediaGalleryRemovePayload } from "./types"
69
91
 
70
92
  export interface RNAttachmentKit {
@@ -77,6 +99,21 @@ export interface RNAttachmentKit {
77
99
  openEditor(options: EditorOptions): Promise<ImageResult>
78
100
  openViewer(options: ViewerOptions): Promise<void>
79
101
  updateSourceRect(rect: import("./types").SourceRect): Promise<void>
102
+ /** 지도 뷰어. 닫히면 resolve */
103
+ openMapViewer(options: import("./types").MapViewerOptions): Promise<void>
104
+ /** 지도 뷰어가 열린 동안 말풍선 위치가 바뀌었을 때 (닫힐 때 돌아갈 자리) */
105
+ updateMapViewerSourceRect(rect: import("./types").SourceRect | null): Promise<void>
106
+ /** 위치 메시지 말풍선 지도 썸네일을 이 기기에서 그려 캐시 (같은 요청이면 캐시에서 바로) */
107
+ renderLocationThumbnail(options: import("./types").LocationThumbnailOptions): Promise<import("./types").LocationThumbnailResult>
108
+ /** renderLocationThumbnail 캐시 비우기 */
109
+ clearLocationThumbnailCache(): Promise<void>
110
+ /**
111
+ * 좌표 → 주소 (기기 지오코더, 무료). 언어는 languageCode 그대로 (생략하면 setDefaults 의 languageCode).
112
+ * 결과("결과 없음" 포함)는 디스크에 캐시. 오류는 ReverseGeocodeErrorCode 로 reject (캐시 안 함)
113
+ */
114
+ reverseGeocode(options: import("./types").ReverseGeocodeOptions): Promise<import("./types").ReverseGeocodeResult>
115
+ /** reverseGeocode 캐시 비우기 */
116
+ clearReverseGeocodeCache(): Promise<void>
80
117
  closeGallery(): Promise<boolean>
81
118
  addSelectionChangeListener(listener: (event: SelectionChangeEvent) => void): () => void
82
119
  getDefaultAnimationConfig(): Promise<{ galleryOpen: number, galleryClose: number, editorOpen: number, editorClose: number, viewerOpen: number, viewerClose: number }>
@@ -99,6 +136,7 @@ const AttachmentKit: RNAttachmentKit = {
99
136
  }
100
137
  if (options?.languageCode) {
101
138
  _defaultLanguageCode = normalizeLanguageCode(options.languageCode);
139
+ _rawLanguageCode = options.languageCode;
102
140
  }
103
141
  if (options?.appearance) {
104
142
  _defaultAppearance = normalizeAppearance(options.appearance);
@@ -111,7 +149,10 @@ const AttachmentKit: RNAttachmentKit = {
111
149
 
112
150
  setDefaults: (options: DefaultOptions): void => {
113
151
  if (options?.themeColor) _defaultThemeColor = options.themeColor
114
- if (options?.languageCode) _defaultLanguageCode = normalizeLanguageCode(options.languageCode)
152
+ if (options?.languageCode) {
153
+ _defaultLanguageCode = normalizeLanguageCode(options.languageCode)
154
+ _rawLanguageCode = options.languageCode
155
+ }
115
156
  if (options?.appearance) _defaultAppearance = normalizeAppearance(options.appearance)
116
157
  },
117
158
 
@@ -121,21 +162,46 @@ const AttachmentKit: RNAttachmentKit = {
121
162
  if (!RNAttachmentKitModule) {
122
163
  throw new Error(LINKING_ERROR)
123
164
  }
165
+ // 이미 열려 있으면 네이티브를 건드리지 않고 바로 reject (앞 호출의 Promise 를 지키기 위해)
166
+ if (_galleryOpen) {
167
+ throw alreadyOpenError("Gallery")
168
+ }
169
+ _galleryOpen = true
124
170
 
125
171
  // 콜백 이벤트 임시 리스너 등록
126
172
  let subscriptionSelChange: any = null
127
173
  let subscriptionImgProcessed: any = null
128
-
174
+
129
175
  if (options.onSelectionChange) {
130
176
  subscriptionSelChange = eventEmitter.addListener("onSelectionChange", options.onSelectionChange)
131
177
  }
132
178
  if (options.onImageProcessed) {
133
- subscriptionImgProcessed = eventEmitter.addListener("onImageProcessed", options.onImageProcessed)
179
+ if (options.asyncProcessing) {
180
+ // async 모드: 이전 호출이 남겨 둔 구독을 먼저 제거해서 리스너가 쌓이지 않게 함
181
+ if (_asyncImgProcessedSub) {
182
+ try { _asyncImgProcessedSub.remove() } catch (e) { /* noop */ }
183
+ _asyncImgProcessedSub = null
184
+ }
185
+ subscriptionImgProcessed = eventEmitter.addListener("onImageProcessed", options.onImageProcessed)
186
+ _asyncImgProcessedSub = subscriptionImgProcessed
187
+ } else {
188
+ subscriptionImgProcessed = eventEmitter.addListener("onImageProcessed", options.onImageProcessed)
189
+ }
190
+ }
191
+ let subscriptionLocation: any = null
192
+ if (options.onLocationSelected) {
193
+ subscriptionLocation = eventEmitter.addListener("onLocationSelected", options.onLocationSelected)
194
+ }
195
+ let subscriptionFiles: any = null
196
+ if (options.onFilesSelected) {
197
+ const onFiles = options.onFilesSelected
198
+ // failed: 복사에 실패한 파일 목록 [{ name, error }] (없으면 undefined)
199
+ subscriptionFiles = eventEmitter.addListener("onFilesSelected", (e: any) => onFiles(e?.files ?? [], e?.failed ?? undefined))
134
200
  }
135
201
 
136
202
  try {
137
203
  // 이벤트 콜백은 네이티브로 전달하지 않음
138
- const { onSelectionChange, onImageProcessed, ...restOptions } = options
204
+ const { onSelectionChange, onImageProcessed, onLocationSelected, onFilesSelected, ...restOptions } = options
139
205
  const nativeOptions = {
140
206
  themeColor: _defaultThemeColor,
141
207
  languageCode: _defaultLanguageCode,
@@ -147,10 +213,18 @@ const AttachmentKit: RNAttachmentKit = {
147
213
  const result = await RNAttachmentKitModule.openGallery(nativeOptions)
148
214
  return result
149
215
  } finally {
216
+ _galleryOpen = false
150
217
  // 갤러리가 닫히면 onSelectionChange 리스너 제거
151
218
  if (subscriptionSelChange) {
152
219
  subscriptionSelChange.remove()
153
220
  }
221
+ // 위치 이벤트는 openGallery 가 끝나기 전에 오므로 여기서 바로 제거
222
+ if (subscriptionLocation) {
223
+ subscriptionLocation.remove()
224
+ }
225
+ if (subscriptionFiles) {
226
+ subscriptionFiles.remove()
227
+ }
154
228
  // asyncProcessing 모드가 아닐 때만 onImageProcessed 리스너 제거 (async 모드에선 백그라운드 처리를 위해 유지해야 함)
155
229
  // 호출부에서 수동으로 제거하거나, 최종 완료 시 정리하는 구조가 필요할 수 있음
156
230
  if (!options.asyncProcessing && subscriptionImgProcessed) {
@@ -163,6 +237,11 @@ const AttachmentKit: RNAttachmentKit = {
163
237
  if (!RNAttachmentKitModule) {
164
238
  throw new Error(LINKING_ERROR)
165
239
  }
240
+ // Android 는 editImagePromise 를 하나만 보관해서 중복 호출 시 앞 Promise 가 끝나지 않음 → JS 에서 막음
241
+ if (_editorOpen) {
242
+ throw alreadyOpenError("Editor")
243
+ }
244
+ _editorOpen = true
166
245
  const mergedOptions = {
167
246
  themeColor: _defaultThemeColor,
168
247
  languageCode: _defaultLanguageCode,
@@ -171,7 +250,11 @@ const AttachmentKit: RNAttachmentKit = {
171
250
  }
172
251
  mergedOptions.languageCode = normalizeLanguageCode(mergedOptions.languageCode)
173
252
  mergedOptions.appearance = normalizeAppearance(mergedOptions.appearance)
174
- return RNAttachmentKitModule.openEditor(mergedOptions)
253
+ try {
254
+ return await RNAttachmentKitModule.openEditor(mergedOptions)
255
+ } finally {
256
+ _editorOpen = false
257
+ }
175
258
  },
176
259
 
177
260
  openViewer: async (options: ViewerOptions): Promise<void> => {
@@ -225,34 +308,34 @@ const AttachmentKit: RNAttachmentKit = {
225
308
  })
226
309
  }
227
310
 
228
- if (options.onViewerWillClose) {
229
- const closeHandler = () => {
230
- if (options.onViewerWillClose) {
231
- options.onViewerWillClose()
232
- }
233
- if (subscriptionPageSelected) {
234
- subscriptionPageSelected.remove()
235
- }
236
- if (subscriptionViewerOpened) {
237
- subscriptionViewerOpened.remove()
238
- }
239
- if (subscriptionViewerWillClose) {
240
- subscriptionViewerWillClose.remove()
241
- }
242
- if (deviceSubscriptionViewerWillClose) {
243
- deviceSubscriptionViewerWillClose.remove()
244
- }
245
- if (subscriptionImageDeleted) {
246
- subscriptionImageDeleted.remove()
247
- }
248
- };
311
+ // 네이티브 "onViewerWillClose"(iOS sendEvent / Android RCTDeviceEventEmitter) 는 앱이 콜백을 넘기지 않아도
312
+ // 항상 구독합니다 — 이 이벤트가 와야 onPageSelected / onImageDeleted 구독을 정리할 수 있기 때문입니다
313
+ // (예전엔 options.onViewerWillClose 가 없으면 구독을 안 해서 뷰어를 열 때마다 리스너가 누수됐음).
314
+ const closeHandler = () => {
315
+ if (options.onViewerWillClose) {
316
+ options.onViewerWillClose()
317
+ }
318
+ if (subscriptionPageSelected) {
319
+ subscriptionPageSelected.remove()
320
+ }
321
+ if (subscriptionViewerOpened) {
322
+ subscriptionViewerOpened.remove()
323
+ }
324
+ if (subscriptionViewerWillClose) {
325
+ subscriptionViewerWillClose.remove()
326
+ }
327
+ if (deviceSubscriptionViewerWillClose) {
328
+ deviceSubscriptionViewerWillClose.remove()
329
+ }
330
+ if (subscriptionImageDeleted) {
331
+ subscriptionImageDeleted.remove()
332
+ }
333
+ };
249
334
 
250
- subscriptionViewerWillClose = eventEmitter.addListener("onViewerWillClose", closeHandler);
335
+ subscriptionViewerWillClose = eventEmitter.addListener("onViewerWillClose", closeHandler);
251
336
 
252
- if (Platform.OS === "android") {
253
- const { DeviceEventEmitter } = require("react-native");
254
- deviceSubscriptionViewerWillClose = DeviceEventEmitter.addListener("onViewerWillClose", closeHandler);
255
- }
337
+ if (Platform.OS === "android") {
338
+ deviceSubscriptionViewerWillClose = DeviceEventEmitter.addListener("onViewerWillClose", closeHandler);
256
339
  }
257
340
 
258
341
  try {
@@ -266,9 +349,14 @@ const AttachmentKit: RNAttachmentKit = {
266
349
  mergedOptions.languageCode = normalizeLanguageCode(mergedOptions.languageCode)
267
350
  mergedOptions.appearance = normalizeAppearance(mergedOptions.appearance)
268
351
  return await RNAttachmentKitModule.openViewer(mergedOptions)
269
- } finally {
270
- // Listeners are now removed inside the onViewerWillClose callback
352
+ } catch (e) {
353
+ // 뷰어가 아예 안 떴으면(reject) onViewerWillClose 가 오지 않으므로 여기서 구독 정리 (앱 콜백은 호출 안 함)
354
+ for (const sub of [subscriptionPageSelected, subscriptionViewerOpened, subscriptionImageDeleted, subscriptionViewerWillClose, deviceSubscriptionViewerWillClose]) {
355
+ try { sub?.remove() } catch (err) { /* noop */ }
356
+ }
357
+ throw e
271
358
  }
359
+ // 정상적으로 열렸으면 리스너는 onViewerWillClose 콜백 안에서 제거됨
272
360
  },
273
361
 
274
362
  updateSourceRect: async (rect: import("./types").SourceRect): Promise<void> => {
@@ -278,6 +366,71 @@ const AttachmentKit: RNAttachmentKit = {
278
366
  return RNAttachmentKitModule.updateSourceRect(rect)
279
367
  },
280
368
 
369
+ openMapViewer: async (options: import("./types").MapViewerOptions): Promise<void> => {
370
+ if (!RNAttachmentKitModule) {
371
+ throw new Error(LINKING_ERROR)
372
+ }
373
+ const mergedOptions: Record<string, any> = {
374
+ themeColor: _defaultThemeColor,
375
+ languageCode: _defaultLanguageCode,
376
+ appearance: _defaultAppearance,
377
+ ...options,
378
+ }
379
+ // 주소를 안 넘기면 네이티브가 채움 — reverseGeocode 와 같은 캐시를 쓰도록 같은 언어(넘긴 그대로)
380
+ mergedOptions.addressLanguageCode = options.languageCode || _rawLanguageCode || _defaultLanguageCode
381
+ mergedOptions.languageCode = normalizeLanguageCode(mergedOptions.languageCode)
382
+ mergedOptions.appearance = normalizeAppearance(mergedOptions.appearance)
383
+ await RNAttachmentKitModule.openMapViewer(mergedOptions)
384
+ },
385
+
386
+ updateMapViewerSourceRect: async (rect: import("./types").SourceRect | null): Promise<void> => {
387
+ if (!RNAttachmentKitModule) {
388
+ throw new Error(LINKING_ERROR)
389
+ }
390
+ return RNAttachmentKitModule.updateMapViewerSourceRect(rect ?? {})
391
+ },
392
+
393
+ renderLocationThumbnail: async (options: import("./types").LocationThumbnailOptions): Promise<import("./types").LocationThumbnailResult> => {
394
+ if (!RNAttachmentKitModule) {
395
+ throw new Error(LINKING_ERROR)
396
+ }
397
+ const mergedOptions = {
398
+ themeColor: _defaultThemeColor,
399
+ appearance: _defaultAppearance,
400
+ ...options,
401
+ }
402
+ mergedOptions.appearance = normalizeAppearance(mergedOptions.appearance)
403
+ // 내 위치는 둘 다 있을 때만
404
+ if (typeof mergedOptions.myLatitude !== "number" || typeof mergedOptions.myLongitude !== "number") {
405
+ delete mergedOptions.myLatitude
406
+ delete mergedOptions.myLongitude
407
+ }
408
+ return RNAttachmentKitModule.renderLocationThumbnail(mergedOptions)
409
+ },
410
+
411
+ clearLocationThumbnailCache: async (): Promise<void> => {
412
+ if (!RNAttachmentKitModule) {
413
+ throw new Error(LINKING_ERROR)
414
+ }
415
+ return RNAttachmentKitModule.clearLocationThumbnailCache()
416
+ },
417
+
418
+ reverseGeocode: async (options: import("./types").ReverseGeocodeOptions): Promise<import("./types").ReverseGeocodeResult> => {
419
+ if (!RNAttachmentKitModule) {
420
+ throw new Error(LINKING_ERROR)
421
+ }
422
+ const languageCode = options.languageCode || _rawLanguageCode || _defaultLanguageCode
423
+ const r = await RNAttachmentKitModule.reverseGeocode({ latitude: options.latitude, longitude: options.longitude, languageCode })
424
+ return { address: r?.address ?? null, shortAddress: r?.shortAddress ?? null, cached: !!r?.cached }
425
+ },
426
+
427
+ clearReverseGeocodeCache: async (): Promise<void> => {
428
+ if (!RNAttachmentKitModule) {
429
+ throw new Error(LINKING_ERROR)
430
+ }
431
+ return RNAttachmentKitModule.clearReverseGeocodeCache()
432
+ },
433
+
281
434
  closeGallery: async (): Promise<boolean> => {
282
435
  if (!RNAttachmentKitModule) {
283
436
  throw new Error(LINKING_ERROR)
package/src/types.ts CHANGED
@@ -61,10 +61,217 @@ export interface GalleryOptions {
61
61
  asyncProcessing?: boolean // 완전 비동기 이벤트 리턴 여부
62
62
  onSelectionChange?: (event: SelectionChangeEvent) => void
63
63
  onImageProcessed?: (event: any) => void
64
+ /**
65
+ * 갤러리 아래에 첨부 메뉴(갤러리 / 위치 / 파일)를 보여줍니다. 기본 false.
66
+ * 위치 탭: iOS 는 Apple 지도(키 필요 없음), Android 는 Google 지도 — 앱의 AndroidManifest 에
67
+ * `com.google.android.geo.API_KEY` meta-data 가 있어야 지도가 그려집니다 (주소 변환은 기기 내장 Geocoder).
68
+ */
69
+ showAttachMenu?: boolean
70
+ /**
71
+ * 위치 보내기 때 지도 캡처 이미지를 만들지 (기본 true = 예전과 같음).
72
+ * false 면 캡처 없이 위치 정보만 바로 보냅니다 — AttachLocationResult 에 imageUri/imagePath/imageWidth/imageHeight 가 없고,
73
+ * imageSpanMeters 는 캡처했을 때와 같은 값이 옵니다. 받는 쪽은 renderLocationThumbnail 로 썸네일을 그립니다.
74
+ */
75
+ captureLocationImage?: boolean
76
+ /**
77
+ * (Android) 첨부 메뉴 바의 아래 여백 조정 (dp).
78
+ * attachMenuSinkIntoNav: 바가 내비게이션 바 영역으로 내려앉는 정도. 기본 12 (지금 모양). 0 이면 내비게이션 바 바로 위.
79
+ * attachMenuMinBottomMargin: 화면 아래와의 최소 간격. 기본 8.
80
+ * iOS 는 무시.
81
+ */
82
+ attachMenuSinkIntoNav?: number
83
+ attachMenuMinBottomMargin?: number
84
+ /**
85
+ * 위치 탭에서 위치를 보냈을 때 호출됩니다. 이때 openGallery 는 빈 배열로 끝납니다.
86
+ */
87
+ onLocationSelected?: (location: AttachLocationResult) => void
88
+ /**
89
+ * 파일 탭에서 파일을 보냈을 때 호출됩니다 (앱 캐시/임시 폴더로 복사된 파일). 이때 openGallery 는 빈 배열로 끝납니다.
90
+ * Android 는 시스템 파일 선택기(내부 저장 공간 탐색), iOS 는 파일 앱 선택기를 씁니다.
91
+ * 복사에 실패한 파일이 있으면 두 번째 인자 failed 로 { name, error } 목록이 옵니다 (없으면 undefined).
92
+ * 복사본은 iOS tmp/AttachmentKitFiles, Android cache/AttachmentKitFiles 에 있고 24시간이 지난 것은 다음 갤러리 열기 때 지워지므로 바로 옮기거나 업로드하세요.
93
+ */
94
+ onFilesSelected?: (files: AttachFileResult[], failed?: AttachFileFailure[]) => void
64
95
  openDuration?: number
65
96
  closeDuration?: number
66
97
  }
67
98
 
99
+ /** 첨부 메뉴 > 파일 에서 복사에 실패한 파일 */
100
+ export interface AttachFileFailure {
101
+ /** 원래 파일 이름 */
102
+ name: string
103
+ /** 실패 사유 (네이티브 오류 메시지) */
104
+ error: string
105
+ }
106
+
107
+ /** 첨부 메뉴 > 파일 에서 보낸 파일 (앱 캐시/임시 폴더로 복사본) */
108
+ export interface AttachFileResult {
109
+ /** file:// URI */
110
+ uri: string
111
+ /** 파일 경로 */
112
+ path: string
113
+ /** 원래 파일 이름 */
114
+ name: string
115
+ /** 바이트 */
116
+ size: number
117
+ mimeType: string
118
+ }
119
+
120
+ /** 첨부 메뉴 > 위치 에서 보낸 위치 */
121
+ export interface AttachLocationResult {
122
+ latitude: number
123
+ longitude: number
124
+ /** 정확도(m). 내 현재 위치를 보낼 때만 */
125
+ accuracy?: number
126
+ /** 장소 이름 (장소를 골랐을 때) */
127
+ title?: string
128
+ /** 주소 */
129
+ address?: string
130
+ /** 내 현재 위치를 보냈는지 (false = 지도에서 옮긴 위치 또는 장소) */
131
+ isCurrentLocation: boolean
132
+ /** 보낸 지점의 지도 캡처 (세로형 480×1040 webp (9:19.5), 내 위치 점 없이 핀만). 캡처 실패 시 없음 */
133
+ imageUri?: string
134
+ imagePath?: string
135
+ imageWidth?: number
136
+ imageHeight?: number
137
+ /** 보낸 위치와 별개로, 보낸 순간의 내 현재 위치 (권한이 있고 위치를 알 때만) */
138
+ currentLatitude?: number
139
+ currentLongitude?: number
140
+ /** 내 현재 위치 정확도(m) */
141
+ currentAccuracy?: number
142
+ /** 지도 이미지에 내 위치 점을 그렸는지 ("내 위치 공유" 토글 — 기본 끔, 선택은 기기에 기억) */
143
+ includesMyLocation?: boolean
144
+ /** 마커 종류 (지도 뷰어가 같은 아이콘을 그리도록): "current" 내 위치 / "pin" 지도에서 옮긴 지점 / "place" 장소 */
145
+ markerType?: 'current' | 'pin' | 'place'
146
+ /** (iOS) 장소 종류 — MKPointOfInterestCategory rawValue. 장소일 때만 */
147
+ placeCategory?: string
148
+ /** 보낸 이미지 가로가 덮는 실제 거리(m) — 지도 뷰어를 같은 축척으로 열 때 (captureLocationImage: false 여도 옴) */
149
+ imageSpanMeters?: number
150
+ }
151
+
152
+ /**
153
+ * 위치 메시지 말풍선 지도 썸네일 — 이 기기에서 위치 정보만으로 그려 캐시합니다.
154
+ * AttachLocationResult 값을 그대로 넘기면 보낸 화면과 같은 마커·축척으로 그립니다.
155
+ */
156
+ export interface LocationThumbnailOptions {
157
+ latitude: number
158
+ longitude: number
159
+ /** 썸네일 가로 (dp/pt). 결과 이미지는 기기 배율을 곱한 px */
160
+ width: number
161
+ /** 썸네일 세로 (dp/pt). aspect 를 주면 생략 (aspect 가 우선) */
162
+ height?: number
163
+ /**
164
+ * 세로를 가로에서 계산: "square" 1:1 / "portrait" 9:19.5 (보내는 지도 이미지와 같은 비율) /
165
+ * "device" 이 기기 화면 세로 비율 (지도 뷰어를 열 때 말풍선 이미지가 화면을 꼭 맞게 채움).
166
+ * 생략하면 height 를 그대로 씁니다.
167
+ */
168
+ aspect?: 'square' | 'portrait' | 'device'
169
+ /**
170
+ * 결과 이미지 최대 크기 (px). 비율을 유지한 채 이 안에 들어가게 줄입니다.
171
+ * 둘 다 생략하면 512 × 512, 하나만 주면 다른 쪽은 제한하지 않습니다.
172
+ * 예: width 170 + aspect "device" + maxWidth 512 + maxHeight 1152 → 3배 기기에서 약 510×1105 px (세로가 512 로 잘리지 않음)
173
+ */
174
+ maxWidth?: number
175
+ /** 결과 이미지 최대 세로 (px). maxWidth 참고 */
176
+ maxHeight?: number
177
+ /** AttachLocationResult.markerType — 마커 아이콘 */
178
+ markerType?: 'current' | 'pin' | 'place'
179
+ /** (iOS 아이콘) AttachLocationResult.placeCategory */
180
+ placeCategory?: string
181
+ /** 썸네일 가로가 덮는 실제 거리(m). AttachLocationResult.imageSpanMeters. 없으면 400 */
182
+ spanMeters?: number
183
+ /**
184
+ * 보낸 쪽이 "내 위치 공유"를 켰을 때(includesMyLocation)의 내 위치 — 있으면 파란 점을 그리고
185
+ * 두 점이 다 들어오게 범위를 넓힙니다. 공유를 안 켰으면 넘기지 마세요.
186
+ */
187
+ myLatitude?: number
188
+ myLongitude?: number
189
+ /** 마커 색 (기본: setDefaults 의 themeColor) */
190
+ themeColor?: string
191
+ /** 지도 모드. "system" 은 지금 기기/앱 화면 모드. 생략하면 setDefaults 의 appearance */
192
+ appearance?: Appearance
193
+ }
194
+
195
+ export interface LocationThumbnailResult {
196
+ /** file:// (캐시 파일, webp) */
197
+ uri: string
198
+ path: string
199
+ /** 픽셀 크기 */
200
+ width: number
201
+ height: number
202
+ /** 캐시에서 바로 꺼냈는지 */
203
+ cached: boolean
204
+ }
205
+
206
+ /**
207
+ * 지도 뷰어 (위치 메시지를 눌렀을 때). AttachLocationResult 의 값을 그대로 넘기면 보낸 화면과 같은 마커·축척으로 열립니다.
208
+ * sourceRect + sourceImageUri 를 주면 말풍선 이미지가 화면을 채우며 지도로 바뀌고(스티키), 닫을 땐 반대로 돌아갑니다.
209
+ */
210
+ /** 좌표 → 주소 (기기 지오코더, 무료). 결과는 디스크에 캐시됩니다 */
211
+ export interface ReverseGeocodeOptions {
212
+ latitude: number
213
+ longitude: number
214
+ /**
215
+ * 주소 언어. 앱 언어 코드 그대로 ('ko', 'en', 'ja', 'zh-Hans', 'zh-TW', 'pt-BR' …) — 모듈 UI 언어 목록으로 줄이지 않습니다.
216
+ * 생략하면 setDefaults / init 의 languageCode (넘긴 그대로)
217
+ */
218
+ languageCode?: string
219
+ }
220
+
221
+ export interface ReverseGeocodeResult {
222
+ /** 전체 주소. 위치 탭 address 와 같은 형식 (시·도 시·군·구 동 도로 번지, 국가명 없음). 결과가 없으면 null */
223
+ address: string | null
224
+ /** 목록용 짧은 주소 (동/도로 + 번지). 없으면 null */
225
+ shortAddress: string | null
226
+ /** 디스크(또는 메모리) 캐시에서 바로 꺼냈는지 */
227
+ cached: boolean
228
+ }
229
+
230
+ /**
231
+ * reverseGeocode reject 코드
232
+ * - E_INVALID_COORDINATE: 범위를 벗어난 좌표 / NaN
233
+ * - E_GEOCODE_UNAVAILABLE: (Android) 기기에 Geocoder 가 없음
234
+ * - E_GEOCODE_THROTTLED: 요청 제한(iOS 앱당 분당 약 50건 등) — 잠시 뒤 다시 시도
235
+ * - E_GEOCODE_TIMEOUT: 지오코더가 8초 안에 답하지 않음
236
+ * - E_GEOCODE_NETWORK: 오프라인
237
+ * - E_GEOCODE_FAILED: 그 밖의 오류
238
+ * 오류는 캐시하지 않습니다
239
+ */
240
+ export type ReverseGeocodeErrorCode =
241
+ | 'E_INVALID_COORDINATE' | 'E_GEOCODE_UNAVAILABLE' | 'E_GEOCODE_THROTTLED'
242
+ | 'E_GEOCODE_TIMEOUT' | 'E_GEOCODE_NETWORK' | 'E_GEOCODE_FAILED'
243
+
244
+ export interface MapViewerOptions {
245
+ latitude: number
246
+ longitude: number
247
+ /** 장소 이름 */
248
+ title?: string
249
+ /** 주소. 생략하면 기기 지오코더로 채움 (reverseGeocode 와 같은 캐시, 언어는 languageCode ?? setDefaults 의 languageCode) */
250
+ address?: string
251
+ /** AttachLocationResult.markerType — 보낸 화면과 같은 마커 */
252
+ markerType?: 'current' | 'pin' | 'place'
253
+ /** (iOS) AttachLocationResult.placeCategory */
254
+ placeCategory?: string
255
+ /** AttachLocationResult.imageSpanMeters — 처음 축척을 말풍선 이미지와 맞춤 */
256
+ spanMeters?: number
257
+ /** "길찾기" 버튼 표시 (기본 true) */
258
+ showDirections?: boolean
259
+ /** 말풍선 이미지 위치 (measureInWindow 값 그대로, dp/pt). 있으면 스티키 애니메이션 */
260
+ sourceRect?: SourceRect
261
+ /**
262
+ * 말풍선 이미지 (https:// 또는 file://). 못 불러오면 이미지 없이 지도만 엶.
263
+ * sourceRect 와 비율이 달라도 됩니다 (예: 4:3 칸 + 화면 비율 이미지) — 칸 안에 가운데 크롭(cover)으로 그려
264
+ * 첫 프레임이 말풍선(resizeMode="cover")과 같고, 열리며 잘린 위아래가 펼쳐집니다 (닫을 땐 반대)
265
+ */
266
+ sourceImageUri?: string
267
+ /** 말풍선 이미지 라운드 (dp/pt, 기본 12) */
268
+ sourceCornerRadius?: number
269
+ /** 마커·버튼 색 (기본: setDefaults 의 themeColor) */
270
+ themeColor?: string
271
+ languageCode?: LanguageCode
272
+ appearance?: Appearance
273
+ }
274
+
68
275
  export interface ViewerOptions {
69
276
  images: string[]
70
277
  placeholderImages?: string[]
@@ -187,17 +394,6 @@ export interface EditorOptions {
187
394
  closeDuration?: number
188
395
  }
189
396
 
190
- export interface RNAttachmentKit {
191
- init(licenseKey: string): Promise<boolean>
192
- openGallery(options?: GalleryOptions): Promise<ImageResult[]>
193
- openEditor(options: EditorOptions): Promise<ImageResult>
194
- openViewer(options: ViewerOptions): Promise<void>
195
- updateViewerSourceRect(rect: SourceRect): Promise<void>
196
- closeGallery(): Promise<boolean>
197
- addSelectionChangeListener(listener: (event: SelectionChangeEvent) => void): () => void
198
- getDefaultAnimationConfig(): Promise<{ galleryOpen: number, galleryClose: number, editorOpen: number, editorClose: number, viewerOpen: number, viewerClose: number }>
199
- }
200
-
201
397
  // MARK: - Media gallery (사진 모아보기)
202
398
 
203
399
  /** 갤러리 항목. 썸네일은 파일 경로만 주고받습니다(base64 금지). */