@hotta/react-native-imagepicker 0.1.8 → 0.2.2
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/android/src/main/java/com/htreactnative/imagepicker/NativeImagePickerModule.kt +19 -3
- package/android/src/main/res/layout/image_picker_fragment_selector.xml +71 -0
- package/android/src/main/res/layout/image_picker_item_grid_video.xml +37 -0
- package/ios/NativeImagePicker.mm +27 -29
- package/lib/module/index.js +7 -9
- package/package.json +1 -1
|
@@ -10,6 +10,7 @@ import com.facebook.react.bridge.WritableNativeArray
|
|
|
10
10
|
import com.facebook.react.bridge.WritableNativeMap
|
|
11
11
|
import com.facebook.react.module.annotations.ReactModule
|
|
12
12
|
import com.luck.picture.lib.basic.PictureSelector
|
|
13
|
+
import com.luck.picture.lib.config.InjectResourceSource
|
|
13
14
|
import com.luck.picture.lib.config.SelectMimeType
|
|
14
15
|
import com.luck.picture.lib.config.SelectModeConfig
|
|
15
16
|
import com.luck.picture.lib.entity.LocalMedia
|
|
@@ -69,6 +70,15 @@ class NativeImagePickerModule(reactContext: ReactApplicationContext) :
|
|
|
69
70
|
.setMaxSelectNum(1)
|
|
70
71
|
.isDisplayCamera(isCamera)
|
|
71
72
|
.setSelectorUIStyle(getNoCountStyle())
|
|
73
|
+
.setInjectLayoutResourceListener { _, resourceSource ->
|
|
74
|
+
when (resourceSource) {
|
|
75
|
+
InjectResourceSource.MAIN_SELECTOR_LAYOUT_RESOURCE ->
|
|
76
|
+
R.layout.image_picker_fragment_selector
|
|
77
|
+
InjectResourceSource.MAIN_ITEM_VIDEO_LAYOUT_RESOURCE ->
|
|
78
|
+
R.layout.image_picker_item_grid_video
|
|
79
|
+
else -> InjectResourceSource.DEFAULT_LAYOUT_RESOURCE
|
|
80
|
+
}
|
|
81
|
+
}
|
|
72
82
|
.setImageEngine(imageEngine)
|
|
73
83
|
.forResult(object : OnResultCallbackListener<LocalMedia> {
|
|
74
84
|
override fun onResult(localMediaList: ArrayList<LocalMedia?>?) {
|
|
@@ -92,9 +102,15 @@ class NativeImagePickerModule(reactContext: ReactApplicationContext) :
|
|
|
92
102
|
// 隐藏选择后的数字/角标索引
|
|
93
103
|
isSelectNumberStyle = false
|
|
94
104
|
isPreviewSelectNumberStyle = false
|
|
95
|
-
//
|
|
105
|
+
// 预览页点击“下一步”时,自动选择当前视频并返回
|
|
106
|
+
isCompleteSelectRelativeTop = true
|
|
107
|
+
// 隐藏列表页和预览页的勾选按钮
|
|
108
|
+
selectBackground = android.R.color.transparent
|
|
109
|
+
previewSelectBackground = android.R.color.transparent
|
|
96
110
|
selectText = "下一步"
|
|
97
111
|
selectTextColor = Color.WHITE
|
|
112
|
+
selectNormalText = "下一步"
|
|
113
|
+
selectNormalTextColor = Color.WHITE
|
|
98
114
|
}
|
|
99
115
|
bottomBarStyle = BottomNavBarStyle().apply {
|
|
100
116
|
isCompleteCountTips = false
|
|
@@ -102,8 +118,8 @@ class NativeImagePickerModule(reactContext: ReactApplicationContext) :
|
|
|
102
118
|
bottomPreviewSelectText = "" // 选中文件后的文字设为空
|
|
103
119
|
|
|
104
120
|
// (可选保障)为了防止有默认的点击态背景,你可以顺手把它的颜色也设为透明
|
|
105
|
-
bottomPreviewNormalTextColor =
|
|
106
|
-
bottomPreviewSelectTextColor =
|
|
121
|
+
bottomPreviewNormalTextColor = Color.WHITE
|
|
122
|
+
bottomPreviewSelectTextColor = Color.WHITE
|
|
107
123
|
}
|
|
108
124
|
|
|
109
125
|
titleBarStyle = TitleBarStyle().apply {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
4
|
+
android:layout_width="match_parent"
|
|
5
|
+
android:layout_height="match_parent">
|
|
6
|
+
|
|
7
|
+
<com.luck.picture.lib.widget.RecyclerPreloadView
|
|
8
|
+
android:id="@+id/recycler"
|
|
9
|
+
android:layout_width="match_parent"
|
|
10
|
+
android:layout_height="0dp"
|
|
11
|
+
android:overScrollMode="never"
|
|
12
|
+
app:layout_constraintBottom_toTopOf="@+id/bottom_nar_bar"
|
|
13
|
+
app:layout_constraintEnd_toEndOf="parent"
|
|
14
|
+
app:layout_constraintStart_toStartOf="parent"
|
|
15
|
+
app:layout_constraintTop_toBottomOf="@+id/title_bar" />
|
|
16
|
+
|
|
17
|
+
<com.luck.picture.lib.widget.MediumBoldTextView
|
|
18
|
+
android:id="@+id/tv_current_data_time"
|
|
19
|
+
android:layout_width="match_parent"
|
|
20
|
+
android:layout_height="wrap_content"
|
|
21
|
+
android:alpha="0"
|
|
22
|
+
android:background="@color/ps_color_99_black"
|
|
23
|
+
android:gravity="center_vertical"
|
|
24
|
+
android:paddingStart="10dp"
|
|
25
|
+
android:paddingTop="3dp"
|
|
26
|
+
android:paddingBottom="3dp"
|
|
27
|
+
android:textColor="@color/ps_color_white"
|
|
28
|
+
android:textSize="12sp"
|
|
29
|
+
app:layout_constraintEnd_toEndOf="parent"
|
|
30
|
+
app:layout_constraintStart_toStartOf="parent"
|
|
31
|
+
app:layout_constraintTop_toBottomOf="@+id/title_bar" />
|
|
32
|
+
|
|
33
|
+
<com.luck.picture.lib.widget.TitleBar
|
|
34
|
+
android:id="@+id/title_bar"
|
|
35
|
+
android:layout_width="0dp"
|
|
36
|
+
android:layout_height="wrap_content"
|
|
37
|
+
app:layout_constraintEnd_toEndOf="parent"
|
|
38
|
+
app:layout_constraintStart_toStartOf="parent"
|
|
39
|
+
app:layout_constraintTop_toTopOf="parent" />
|
|
40
|
+
|
|
41
|
+
<com.luck.picture.lib.widget.BottomNavBar
|
|
42
|
+
android:id="@+id/bottom_nar_bar"
|
|
43
|
+
android:layout_width="0dp"
|
|
44
|
+
android:layout_height="wrap_content"
|
|
45
|
+
app:layout_constraintBottom_toBottomOf="parent"
|
|
46
|
+
app:layout_constraintEnd_toEndOf="parent"
|
|
47
|
+
app:layout_constraintStart_toStartOf="parent" />
|
|
48
|
+
|
|
49
|
+
<!-- The list page only needs Cancel; Next is shown on the preview page. -->
|
|
50
|
+
<com.luck.picture.lib.widget.CompleteSelectView
|
|
51
|
+
android:id="@+id/ps_complete_select"
|
|
52
|
+
android:layout_width="wrap_content"
|
|
53
|
+
android:layout_height="wrap_content"
|
|
54
|
+
android:visibility="gone" />
|
|
55
|
+
|
|
56
|
+
<com.luck.picture.lib.widget.MediumBoldTextView
|
|
57
|
+
android:id="@+id/tv_data_empty"
|
|
58
|
+
android:layout_width="wrap_content"
|
|
59
|
+
android:layout_height="wrap_content"
|
|
60
|
+
android:gravity="center"
|
|
61
|
+
android:lineSpacingExtra="3dp"
|
|
62
|
+
android:text="@string/ps_empty"
|
|
63
|
+
android:textColor="@color/ps_color_aab2bd"
|
|
64
|
+
android:textSize="14sp"
|
|
65
|
+
android:visibility="gone"
|
|
66
|
+
app:layout_constraintBottom_toBottomOf="parent"
|
|
67
|
+
app:layout_constraintEnd_toEndOf="parent"
|
|
68
|
+
app:layout_constraintStart_toStartOf="parent"
|
|
69
|
+
app:layout_constraintTop_toTopOf="parent" />
|
|
70
|
+
|
|
71
|
+
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<com.luck.picture.lib.widget.SquareRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
android:layout_width="match_parent"
|
|
4
|
+
android:layout_height="wrap_content">
|
|
5
|
+
|
|
6
|
+
<ImageView
|
|
7
|
+
android:id="@+id/ivPicture"
|
|
8
|
+
android:layout_width="match_parent"
|
|
9
|
+
android:layout_height="match_parent"
|
|
10
|
+
android:scaleType="centerCrop" />
|
|
11
|
+
|
|
12
|
+
<!-- PictureSelector requires these views, but zero size removes the select control and hit area. -->
|
|
13
|
+
<com.luck.picture.lib.widget.MediumBoldTextView
|
|
14
|
+
android:id="@+id/tvCheck"
|
|
15
|
+
android:layout_width="0dp"
|
|
16
|
+
android:layout_height="0dp" />
|
|
17
|
+
|
|
18
|
+
<View
|
|
19
|
+
android:id="@+id/btnCheck"
|
|
20
|
+
android:layout_width="0dp"
|
|
21
|
+
android:layout_height="0dp" />
|
|
22
|
+
|
|
23
|
+
<com.luck.picture.lib.widget.MediumBoldTextView
|
|
24
|
+
android:id="@+id/tv_duration"
|
|
25
|
+
android:layout_width="match_parent"
|
|
26
|
+
android:layout_height="wrap_content"
|
|
27
|
+
android:layout_alignParentBottom="true"
|
|
28
|
+
android:background="@drawable/ps_ic_shadow_bg"
|
|
29
|
+
android:drawableLeft="@drawable/ps_ic_video"
|
|
30
|
+
android:drawablePadding="5dp"
|
|
31
|
+
android:gravity="center_vertical"
|
|
32
|
+
android:paddingLeft="5dp"
|
|
33
|
+
android:text="00:00"
|
|
34
|
+
android:textColor="@color/ps_color_white"
|
|
35
|
+
android:textSize="11sp" />
|
|
36
|
+
|
|
37
|
+
</com.luck.picture.lib.widget.SquareRelativeLayout>
|
package/ios/NativeImagePicker.mm
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
@interface NativeImagePicker ()
|
|
8
8
|
|
|
9
9
|
@property (nonatomic, strong) UIImagePickerController *imagePickerVc;
|
|
10
|
+
|
|
11
|
+
@property (nonatomic, strong) NSDictionary *pickOptions;
|
|
10
12
|
/**
|
|
11
13
|
保存Promise的resolve block
|
|
12
14
|
*/
|
|
@@ -25,9 +27,6 @@
|
|
|
25
27
|
@property (nonatomic, strong) NSMutableArray *selectedAssets;
|
|
26
28
|
@end
|
|
27
29
|
@implementation NativeImagePicker
|
|
28
|
-
{
|
|
29
|
-
std::optional<JS::NativeImagePicker::ImagePickerOption> _cameraOptions;
|
|
30
|
-
}
|
|
31
30
|
|
|
32
31
|
- (instancetype)init {
|
|
33
32
|
self = [super init];
|
|
@@ -52,26 +51,26 @@
|
|
|
52
51
|
_selectedAssets = nil;
|
|
53
52
|
}
|
|
54
53
|
|
|
55
|
-
- (void)asyncShowImagePicker:(
|
|
56
|
-
|
|
54
|
+
- (void)asyncShowImagePicker:(NSDictionary *)options resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
|
|
55
|
+
self.pickOptions = options;
|
|
57
56
|
self.resolveBlock = resolve;
|
|
58
57
|
self.rejectBlock = reject;
|
|
59
58
|
self.callback = nil;
|
|
60
59
|
[self openImagePicker];
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
- (void)asyncShowVideoPicker:(
|
|
62
|
+
- (void)asyncShowVideoPicker:(NSDictionary *)options resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
|
|
64
63
|
self.resolveBlock = resolve;
|
|
65
64
|
self.rejectBlock = reject;
|
|
66
65
|
self.callback = nil;
|
|
67
66
|
[self openVideoPickerWithOptions:options];
|
|
68
67
|
}
|
|
69
68
|
|
|
70
|
-
- (void)openVideoPickerWithOptions:(
|
|
71
|
-
NSInteger videoCount = options
|
|
72
|
-
BOOL isCamera = options
|
|
73
|
-
BOOL sortAscendingByModificationDate = options
|
|
74
|
-
BOOL showSelectedIndex = options
|
|
69
|
+
- (void)openVideoPickerWithOptions:(NSDictionary *)options {
|
|
70
|
+
NSInteger videoCount = [options sy_integerForKey:@"videoCount"];
|
|
71
|
+
BOOL isCamera = [options sy_boolForKey:@"isCamera"];
|
|
72
|
+
BOOL sortAscendingByModificationDate = [options sy_boolForKey:@"sortAscendingByModificationDate"];
|
|
73
|
+
BOOL showSelectedIndex = [options sy_boolForKey:@"showSelectedIndex"];
|
|
75
74
|
|
|
76
75
|
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:videoCount delegate:self];
|
|
77
76
|
imagePickerVc.iconThemeColor = [UIColor colorWithRed:255.0/255.0 green:177.0/255.0 blue:82.0/255.0 alpha:1.0];
|
|
@@ -91,22 +90,21 @@
|
|
|
91
90
|
}
|
|
92
91
|
|
|
93
92
|
__weak TZImagePickerController *weakPickerVc = imagePickerVc;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
[
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
93
|
+
// 使用专门的视频回调
|
|
94
|
+
[imagePickerVc setDidFinishPickingVideoHandle:^(UIImage *coverImage, PHAsset *asset) {
|
|
95
|
+
|
|
96
|
+
[[TZImageManager manager] getVideoOutputPathWithAsset:asset presetName:AVAssetExportPresetPassthrough success:^(NSString *outputPath) {
|
|
97
|
+
// 构建单个结果
|
|
98
|
+
NSDictionary *result = [self handleVideoPickerData:outputPath asset:asset];
|
|
99
|
+
|
|
100
|
+
// 隐藏 HUD 并回调
|
|
101
|
+
[self invokeSuccessWithResult:@[result]];
|
|
102
|
+
[weakPickerVc dismissViewControllerAnimated:YES completion:nil];
|
|
103
|
+
|
|
104
|
+
} failure:^(NSString *errorMessage, NSError *error) {
|
|
105
|
+
[self invokeError];
|
|
106
|
+
[weakPickerVc dismissViewControllerAnimated:YES completion:nil];
|
|
108
107
|
}];
|
|
109
|
-
[weakPickerVc hideProgressHUD];
|
|
110
108
|
}];
|
|
111
109
|
|
|
112
110
|
[imagePickerVc setImagePickerControllerDidCancelHandle:^{
|
|
@@ -119,7 +117,7 @@
|
|
|
119
117
|
|
|
120
118
|
- (void)openImagePicker {
|
|
121
119
|
// 照片最大可选张数
|
|
122
|
-
NSInteger imageCount =
|
|
120
|
+
NSInteger imageCount = [self.pickOptions sy_integerForKey:@"imageCount"];
|
|
123
121
|
// 显示内部拍照按钮
|
|
124
122
|
BOOL isCamera = [self.pickOptions sy_boolForKey:@"isCamera"];
|
|
125
123
|
BOOL isCrop = [self.pickOptions sy_boolForKey:@"isCrop"];
|
|
@@ -408,7 +406,7 @@
|
|
|
408
406
|
NSData *writeData = nil;
|
|
409
407
|
NSMutableString *filePath = [NSMutableString string];
|
|
410
408
|
BOOL isPNG = [fileExtension hasSuffix:@"PNG"] || [fileExtension hasSuffix:@"png"];
|
|
411
|
-
BOOL compressFocusAlpha =
|
|
409
|
+
BOOL compressFocusAlpha = [self.pickOptions sy_boolForKey:@"compressFocusAlpha"];
|
|
412
410
|
|
|
413
411
|
if (isGIF) {
|
|
414
412
|
image = [UIImage sd_tz_animatedGIFWithData:data];
|
|
@@ -470,7 +468,7 @@
|
|
|
470
468
|
video[@"size"] = @([[[NSFileManager defaultManager] attributesOfItemAtPath:outputPath error:nil] fileSize]);
|
|
471
469
|
video[@"width"] = @(asset.pixelWidth);
|
|
472
470
|
video[@"height"] = @(asset.pixelHeight);
|
|
473
|
-
video[@"duration"] = @((long long)(asset.duration
|
|
471
|
+
video[@"duration"] = @((long long)(asset.duration));
|
|
474
472
|
video[@"mime"] = @"video/mp4";
|
|
475
473
|
video[@"filename"] = [asset valueForKey:@"filename"];
|
|
476
474
|
video[@"localIdentifier"] = asset.localIdentifier;
|
package/lib/module/index.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import NativeImagePicker
|
|
3
|
+
import NativeImagePicker from "./NativeImagePicker.js";
|
|
4
4
|
const HTNativeImagePicker = (() => {
|
|
5
5
|
return {
|
|
6
|
-
asyncShowImagePicker:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
},
|
|
13
|
-
asyncShowVideoPicker: options => {
|
|
6
|
+
asyncShowImagePicker: NativeImagePicker.asyncShowImagePicker,
|
|
7
|
+
asyncShowVideoPicker: NativeImagePicker.asyncShowVideoPicker
|
|
8
|
+
};
|
|
9
|
+
})();
|
|
10
|
+
export default HTNativeImagePicker;
|
|
11
|
+
//# sourceMappingURL=index.js.map asyncShowVideoPicker: options => {
|
|
14
12
|
const _options = {
|
|
15
13
|
...defaultOptions,
|
|
16
14
|
...options
|