motorinc-gallery-picker-pro 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +236 -0
- package/android/build.gradle +22 -0
- package/android/src/main/AndroidManifest.xml +10 -0
- package/android/src/main/java/com/gallerypicker/imagepicker/ImagePickerModule.java +1968 -0
- package/android/src/main/java/com/gallerypicker/imagepicker/ImagePickerPackage.java +24 -0
- package/index.d.ts +129 -0
- package/index.js +18 -0
- package/ios/ImagePickerModule.h +8 -0
- package/ios/ImagePickerModule.m +876 -0
- package/motorinc-gallery-picker-pro.podspec +21 -0
- package/package.json +63 -0
- package/react-native.config.js +13 -0
- package/src/components/ImageCropper.tsx +433 -0
- package/src/components/MainPhotoGallery.tsx +2639 -0
- package/src/components/PhotoAssetImage.tsx +121 -0
- package/src/modules/ImagePickerModule.ts +117 -0
package/README.md
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# MotorInc Media Picker
|
|
2
|
+
|
|
3
|
+
A comprehensive React Native media gallery picker with smooth animations, multi-select/single-select modes, crop functionality, and native iOS/Android support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🖼️ **Modern UI** - Smooth scrolling with layered animations
|
|
8
|
+
- 📱 **Native Performance** - Built with native iOS and Android modules
|
|
9
|
+
- ✨ **Multi/Single Select** - Flexible selection modes
|
|
10
|
+
- ✂️ **Crop Functionality** - Built-in image cropping with aspect ratio controls
|
|
11
|
+
- 🎬 **Video Support** - Handle both images and videos
|
|
12
|
+
- 🎯 **Gesture Controls** - Intuitive touch gestures and animations
|
|
13
|
+
- 📐 **Aspect Ratios** - Support for multiple aspect ratios (0.8, 16:9, 1:1)
|
|
14
|
+
- 🔄 **Permission Handling** - Smart permission management
|
|
15
|
+
- 📤 **Export Options** - Base64, URI, and file data support
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install motorinc-media-picker
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### iOS Setup
|
|
24
|
+
|
|
25
|
+
1. Add to your `Podfile`:
|
|
26
|
+
```ruby
|
|
27
|
+
pod 'MotorincMediaPicker', :path => '../node_modules/motorinc-media-picker'
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
2. Run:
|
|
31
|
+
```bash
|
|
32
|
+
cd ios && pod install
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Android Setup
|
|
36
|
+
|
|
37
|
+
The Android module is automatically linked with React Native 0.60+.
|
|
38
|
+
|
|
39
|
+
## Dependencies
|
|
40
|
+
|
|
41
|
+
Make sure you have these peer dependencies installed:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install react-native-gesture-handler react-native-reanimated react-native-view-shot
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Follow the setup instructions for:
|
|
48
|
+
- [react-native-gesture-handler](https://docs.swmansion.com/react-native-gesture-handler/docs/installation)
|
|
49
|
+
- [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started)
|
|
50
|
+
|
|
51
|
+
## Usage
|
|
52
|
+
|
|
53
|
+
### Basic Usage
|
|
54
|
+
|
|
55
|
+
```jsx
|
|
56
|
+
import React from 'react';
|
|
57
|
+
import { View } from 'react-native';
|
|
58
|
+
import { MainPhotoGallery } from 'motorinc-media-picker';
|
|
59
|
+
|
|
60
|
+
export default function App() {
|
|
61
|
+
const handleAssetSelected = (asset) => {
|
|
62
|
+
console.log('Selected asset:', asset);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const handleSelectedAssetsChange = (assets) => {
|
|
66
|
+
console.log('Selected assets:', assets);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<View style={{ flex: 1 }}>
|
|
71
|
+
<MainPhotoGallery
|
|
72
|
+
mediaType="all"
|
|
73
|
+
multiSelect={true}
|
|
74
|
+
maxSelectionLimit={10}
|
|
75
|
+
onAssetSelected={handleAssetSelected}
|
|
76
|
+
onSelectedAssetsChange={handleSelectedAssetsChange}
|
|
77
|
+
/>
|
|
78
|
+
</View>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Advanced Usage with Crop
|
|
84
|
+
|
|
85
|
+
```jsx
|
|
86
|
+
import React, { useRef, useState } from 'react';
|
|
87
|
+
import { View, Button } from 'react-native';
|
|
88
|
+
import { MainPhotoGallery } from 'motorinc-media-picker';
|
|
89
|
+
|
|
90
|
+
export default function App() {
|
|
91
|
+
const galleryRef = useRef(null);
|
|
92
|
+
const [selectedAssets, setSelectedAssets] = useState([]);
|
|
93
|
+
const [cropParams, setCropParams] = useState(new Map());
|
|
94
|
+
|
|
95
|
+
const handleCroppedImagesReady = (croppedImages) => {
|
|
96
|
+
console.log('Cropped images:', croppedImages);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const handleCropCapture = async () => {
|
|
100
|
+
if (galleryRef.current) {
|
|
101
|
+
await galleryRef.current.triggerCropCapture();
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<View style={{ flex: 1 }}>
|
|
107
|
+
<MainPhotoGallery
|
|
108
|
+
ref={galleryRef}
|
|
109
|
+
mediaType="image"
|
|
110
|
+
multiSelect={true}
|
|
111
|
+
selectedAssets={selectedAssets}
|
|
112
|
+
onSelectedAssetsChange={setSelectedAssets}
|
|
113
|
+
showSelectedAssetsHeader={true}
|
|
114
|
+
onCropParamsChange={(assetId, params) => {
|
|
115
|
+
setCropParams(prev => new Map(prev.set(assetId, params)));
|
|
116
|
+
}}
|
|
117
|
+
existingCropParams={cropParams}
|
|
118
|
+
onCroppedImagesReady={handleCroppedImagesReady}
|
|
119
|
+
onAspectRatioChange={(ratio) => console.log('Aspect ratio:', ratio)}
|
|
120
|
+
/>
|
|
121
|
+
<Button title="Capture Cropped Images" onPress={handleCropCapture} />
|
|
122
|
+
</View>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Props
|
|
128
|
+
|
|
129
|
+
### MainPhotoGallery Props
|
|
130
|
+
|
|
131
|
+
| Prop | Type | Default | Description |
|
|
132
|
+
|------|------|---------|-------------|
|
|
133
|
+
| `mediaType` | `'image' \| 'video' \| 'all'` | `'all'` | Type of media to display |
|
|
134
|
+
| `multiSelect` | `boolean` | `false` | Enable multi-selection mode |
|
|
135
|
+
| `maxSelectionLimit` | `number` | `10` | Maximum number of assets that can be selected |
|
|
136
|
+
| `selectedAssets` | `PhotoAsset[]` | `[]` | Currently selected assets |
|
|
137
|
+
| `onAssetSelected` | `(asset: PhotoAsset) => void` | - | Callback when a single asset is selected |
|
|
138
|
+
| `onSelectedAssetsChange` | `(assets: PhotoAsset[]) => void` | - | Callback when selected assets change |
|
|
139
|
+
| `showSelectedAssetsHeader` | `boolean` | `false` | Show cropping header for selected assets |
|
|
140
|
+
| `hideSelectionHeader` | `boolean` | `false` | Hide the selection mode header |
|
|
141
|
+
| `onCropParamsChange` | `(assetId: string, params: CropParams \| null) => void` | - | Callback for crop parameter changes |
|
|
142
|
+
| `existingCropParams` | `Map<string, CropParams>` | - | Existing crop parameters |
|
|
143
|
+
| `onAspectRatioChange` | `(ratio: number) => void` | - | Callback for aspect ratio changes |
|
|
144
|
+
| `onCroppedImagesReady` | `(images: Array<{assetId: string, dataUri: string}>) => void` | - | Callback when cropped images are ready |
|
|
145
|
+
| `onCancel` | `() => void` | - | Cancel button callback |
|
|
146
|
+
| `onNext` | `(assets: PhotoAsset[]) => void` | - | Next button callback |
|
|
147
|
+
| `renderPermissionDeniedState` | `(onRequest?: () => void) => React.ReactNode` | - | Custom permission denied state |
|
|
148
|
+
|
|
149
|
+
## Types
|
|
150
|
+
|
|
151
|
+
### PhotoAsset
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
interface PhotoAsset {
|
|
155
|
+
id: string;
|
|
156
|
+
uri: string;
|
|
157
|
+
filename: string;
|
|
158
|
+
width: number;
|
|
159
|
+
height: number;
|
|
160
|
+
creationDate: number;
|
|
161
|
+
mediaType: 'image' | 'video';
|
|
162
|
+
duration?: number; // For videos
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### CropParams
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
interface CropParams {
|
|
170
|
+
x: number;
|
|
171
|
+
y: number;
|
|
172
|
+
width: number;
|
|
173
|
+
height: number;
|
|
174
|
+
scale: number;
|
|
175
|
+
aspectRatio: number;
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### SelectedImage
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
interface SelectedImage {
|
|
183
|
+
uri: string;
|
|
184
|
+
fileName: string;
|
|
185
|
+
fileSize: number;
|
|
186
|
+
width: number;
|
|
187
|
+
height: number;
|
|
188
|
+
type: string;
|
|
189
|
+
id: string;
|
|
190
|
+
base64: string;
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Layered Scroll Behavior
|
|
195
|
+
|
|
196
|
+
The gallery implements smooth layered scroll behavior:
|
|
197
|
+
|
|
198
|
+
- **Scroll Up**: First hides the header section, then allows grid scrolling
|
|
199
|
+
- **Scroll Down**: Grid scrolls down immediately, regardless of header position
|
|
200
|
+
- **Header Drag**: Can always drag header up/down to show/hide sections
|
|
201
|
+
- **Smooth Animations**: Cubic easing for natural feel
|
|
202
|
+
|
|
203
|
+
## Permissions
|
|
204
|
+
|
|
205
|
+
### iOS
|
|
206
|
+
|
|
207
|
+
Add to your `Info.plist`:
|
|
208
|
+
|
|
209
|
+
```xml
|
|
210
|
+
<key>NSPhotoLibraryUsageDescription</key>
|
|
211
|
+
<string>This app needs access to photo library to select images</string>
|
|
212
|
+
<key>NSPhotoLibraryAddUsageDescription</key>
|
|
213
|
+
<string>This app needs access to save images to photo library</string>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Android
|
|
217
|
+
|
|
218
|
+
Add to your `AndroidManifest.xml`:
|
|
219
|
+
|
|
220
|
+
```xml
|
|
221
|
+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
|
222
|
+
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
|
223
|
+
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Contributing
|
|
227
|
+
|
|
228
|
+
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
|
|
229
|
+
|
|
230
|
+
## License
|
|
231
|
+
|
|
232
|
+
MIT
|
|
233
|
+
|
|
234
|
+
## Support
|
|
235
|
+
|
|
236
|
+
If you like this project, please consider giving it a ⭐ on GitHub!
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
apply plugin: 'com.android.library'
|
|
2
|
+
|
|
3
|
+
android {
|
|
4
|
+
compileSdkVersion 34
|
|
5
|
+
|
|
6
|
+
defaultConfig {
|
|
7
|
+
minSdkVersion 21
|
|
8
|
+
targetSdkVersion 34
|
|
9
|
+
versionCode 1
|
|
10
|
+
versionName "1.0"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
compileOptions {
|
|
14
|
+
sourceCompatibility JavaVersion.VERSION_11
|
|
15
|
+
targetCompatibility JavaVersion.VERSION_11
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
dependencies {
|
|
20
|
+
implementation 'com.facebook.react:react-native:+'
|
|
21
|
+
implementation 'androidx.appcompat:appcompat:1.6.1'
|
|
22
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
package="com.motorinceditor.imagepicker">
|
|
3
|
+
|
|
4
|
+
<uses-permission android:name="android.permission.CAMERA" />
|
|
5
|
+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
|
6
|
+
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
|
7
|
+
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
|
8
|
+
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
|
|
9
|
+
|
|
10
|
+
</manifest>
|