Skip to content

Commit bd8b219

Browse files
committed
✨ feat: doing handle open camera capture
1 parent 383fa30 commit bd8b219

34 files changed

+1087
-47
lines changed

MultipleImagePicker.podspec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ Pod::Spec.new do |s|
2828

2929

3030
s.dependency "HXPhotoPicker/Picker", "4.2.3"
31-
s.dependency "HXPhotoPicker/Editor/Lite", "4.2.3"
31+
s.dependency "HXPhotoPicker/Editor", "4.2.3"
32+
s.dependency "HXPhotoPicker/Camera", "4.2.3"
3233

3334
s.pod_target_xcconfig = {
3435
# C++ compiler flags, mainly for folly.

android/src/main/java/com/margelo/nitro/multipleimagepicker/MultipleImagePicker.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,12 @@ class MultipleImagePicker : HybridMultipleImagePickerSpec() {
3434
pickerModule.openPreview(media, index.toInt(), config)
3535
}
3636

37+
override fun openCamera(
38+
config: NitroCameraConfig,
39+
resolved: (result: CameraResult) -> Unit,
40+
rejected: (reject: Double) -> Unit
41+
) {
42+
pickerModule.openCamera(config, resolved, rejected)
43+
}
44+
3745
}

android/src/main/java/com/margelo/nitro/multipleimagepicker/MultipleImagePickerImp.kt

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,7 @@ class MultipleImagePickerImp(reactContext: ReactApplicationContext?) :
7373
setStyle() // set style for UI
7474
handleSelectedAssets(config)
7575

76-
val chooseMode = when (config.mediaType) {
77-
MediaType.VIDEO -> SelectMimeType.ofVideo()
78-
MediaType.IMAGE -> SelectMimeType.ofImage()
79-
else -> SelectMimeType.ofAll()
80-
}
76+
val chooseMode = getChooseMode(config.mediaType)
8177

8278
val maxSelect = config.maxSelect?.toInt() ?: 20
8379
val maxVideo = config.maxVideo?.toInt() ?: 20
@@ -312,6 +308,45 @@ class MultipleImagePickerImp(reactContext: ReactApplicationContext?) :
312308
return OnCustomLoadingListener { context -> LoadingDialog(context) }
313309
}
314310

311+
@ReactMethod
312+
fun openCamera(
313+
config: NitroCameraConfig,
314+
resolved: (result: CameraResult) -> Unit,
315+
rejected: (reject: Double) -> Unit
316+
) {
317+
val chooseMode = getChooseMode(config.mediaType)
318+
val cameraConfig = PickerCameraConfig(
319+
cameraDevice = config.cameraDevice,
320+
videoMaximumDuration = config.videoMaximumDuration
321+
)
322+
323+
PictureSelector
324+
.create(currentActivity)
325+
.openCamera(chooseMode)
326+
// .setLanguage(getLanguage(config.language))
327+
.isQuickCapture(true)
328+
.setCameraInterceptListener(CameraEngine(appContext, cameraConfig))
329+
.forResult(object : OnResultCallbackListener<LocalMedia?> {
330+
override fun onResult(result: java.util.ArrayList<LocalMedia?>?) {
331+
println("camera: $result")
332+
}
333+
334+
override fun onCancel() {
335+
TODO("Not yet implemented")
336+
}
337+
338+
})
339+
340+
}
341+
342+
private fun getChooseMode(mediaType: MediaType): Int {
343+
return when (mediaType) {
344+
MediaType.VIDEO -> SelectMimeType.ofVideo()
345+
MediaType.IMAGE -> SelectMimeType.ofImage()
346+
else -> SelectMimeType.ofAll()
347+
}
348+
}
349+
315350

316351
private fun getLanguage(language: Language): Int {
317352
return when (language) {

example/src/components/Button.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,35 @@ import { Text } from './Text'
99

1010
interface Props extends TouchableOpacityProps {
1111
children: React.ReactNode | string
12+
type?: 'full' | 'outline'
1213
}
1314

14-
export function Button({ children, style: containerStyle, onPress }: Props) {
15+
export function Button({
16+
children,
17+
style: containerStyle,
18+
onPress,
19+
type = 'full',
20+
}: Props) {
1521
const { foreground, background } = useTheme()
22+
const isFull = type === 'full'
1623

1724
return (
1825
<TouchableOpacity
19-
style={[style.button, containerStyle, { backgroundColor: foreground }]}
26+
style={[
27+
style.button,
28+
containerStyle,
29+
// eslint-disable-next-line react-native/no-inline-styles
30+
{
31+
backgroundColor: isFull ? foreground : 'transparent',
32+
borderColor: isFull ? 'transparent' : foreground,
33+
},
34+
]}
2035
onPress={onPress}
2136
>
2237
{typeof children === 'string' ? (
23-
<Text style={[style.text, { color: background }]}>{children}</Text>
38+
<Text style={[style.text, { color: isFull ? background : foreground }]}>
39+
{children}
40+
</Text>
2441
) : (
2542
children
2643
)}
@@ -32,6 +49,7 @@ const style = StyleSheet.create({
3249
button: {
3350
padding: 12,
3451
alignItems: 'center',
52+
borderWidth: 1.5,
3553
},
3654
text: {
3755
fontFamily: 'Avenir',

example/src/components/Row.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react'
2-
import { StyleSheet, ViewProps, ViewStyle } from 'react-native'
3-
import { View } from './View'
2+
import { StyleSheet, ViewStyle } from 'react-native'
3+
import { View, ViewProps } from './View'
44

55
export interface RowProps extends ViewProps {
66
alignItems?: ViewStyle['alignItems']

example/src/components/View.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import React from 'react'
2-
import { View as RNView, ViewProps } from 'react-native'
2+
import { View as RNView, ViewProps as RNViewProps } from 'react-native'
33
import useTheme from '../hook/useTheme'
44

5-
interface Props extends ViewProps {
5+
export interface ViewProps extends RNViewProps {
66
level?: 0 | 1 | 2 | 3
77
flex?: number
88
}
@@ -12,7 +12,7 @@ export function View({
1212
style: containerStyle,
1313
level = 0,
1414
flex,
15-
}: Props) {
15+
}: ViewProps) {
1616
const theme = useTheme()
1717
const backgroundColor = !level
1818
? theme.background

example/src/index.tsx

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
Config,
2323
openCropper,
2424
openPreview,
25+
openCamera,
2526
} from '@baronha/react-native-multiple-image-picker'
2627
import { useImmer } from 'use-immer'
2728
import { StatusBar } from 'expo-status-bar'
@@ -92,6 +93,18 @@ export default function App() {
9293
}
9394
}
9495

96+
const onCamera = async () => {
97+
try {
98+
const response = await openCamera()
99+
100+
console.log('response: ', response)
101+
102+
layoutEffect()
103+
} catch (e) {
104+
console.log('e: ', e)
105+
}
106+
}
107+
95108
const onCrop = async () => {
96109
try {
97110
console.log('images: ', images)
@@ -550,9 +563,14 @@ export default function App() {
550563
</KeyboardAvoidingView>
551564

552565
<View level={2}>
553-
<Button style={style.buttonOpen} onPress={onPicker}>
554-
Open Picker
555-
</Button>
566+
<Row style={style.bottom} level={2} gap={12}>
567+
<Button type="outline" onPress={onCamera}>
568+
Open Camera
569+
</Button>
570+
<Button style={style.openPicker} onPress={onPicker}>
571+
Open Picker
572+
</Button>
573+
</Row>
556574
<SafeAreaView />
557575
</View>
558576
</Container>
@@ -643,4 +661,11 @@ const style = StyleSheet.create({
643661
borderRadius: 6,
644662
borderWidth: 1,
645663
},
664+
bottom: {
665+
padding: 16,
666+
paddingHorizontal: 24,
667+
},
668+
openPicker: {
669+
flex: 1,
670+
},
646671
})

ios/HybridMultipleImagePicker+Camera.swift

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,55 @@
88
import HXPhotoPicker
99

1010
extension HybridMultipleImagePicker {
11-
// func setCameraConfig(config: Camera) {
12-
// //
13-
// }
11+
func openCamera(config: NitroCameraConfig, resolved: @escaping ((CameraResult) -> Void), rejected: @escaping ((Double) -> Void)) throws {
12+
var cameraConfig = CameraConfiguration()
13+
14+
cameraConfig.videoMaximumDuration = config.videoMaximumDuration ?? 60
15+
16+
cameraConfig.modalPresentationStyle = self.setPresentation(config.presentation)
17+
18+
cameraConfig.editor.modalPresentationStyle = .fullScreen
19+
20+
if let crop = config.crop {
21+
let editor = PickerCropConfig(circle: crop.circle, ratio: crop.ratio, defaultRatio: crop.defaultRatio, freeStyle: crop.freeStyle)
22+
cameraConfig.editor = setCropConfig(editor)
23+
} else {
24+
cameraConfig.allowsEditing = false
25+
}
26+
27+
cameraConfig.languageType = setLocale(language: config.language)
28+
cameraConfig.isSaveSystemAlbum = config.isSaveSystemAlbum ?? false
29+
cameraConfig.allowLocation = config.allowLocation ?? true
30+
31+
switch Int(config.cameraDevice.rawValue) {
32+
case 0:
33+
cameraConfig.position = .front
34+
default:
35+
cameraConfig.position = .back
36+
}
37+
38+
DispatchQueue.main.async {
39+
Photo.capture(cameraConfig) { result, _, _ in
40+
print("result: ", result)
41+
}
42+
}
43+
}
44+
45+
func setCameraConfig(_ options: PickerCameraConfig) -> SystemCameraConfiguration {
46+
var config = SystemCameraConfiguration()
47+
48+
config.editExportPreset = .highQuality
49+
config.videoQuality = .typeHigh
50+
51+
switch Int(options.cameraDevice.rawValue) {
52+
case 0:
53+
config.cameraDevice = .front
54+
default:
55+
config.cameraDevice = .rear
56+
}
57+
58+
config.videoMaximumDuration = options.videoMaximumDuration ?? 60
59+
60+
return config
61+
}
1462
}

ios/HybridMultipleImagePicker+Config.swift

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -124,19 +124,7 @@ extension HybridMultipleImagePicker {
124124
if let cameraOption = options.camera {
125125
photoList.allowAddCamera = true
126126

127-
var cameraConfig = SystemCameraConfiguration()
128-
129-
cameraConfig.editExportPreset = .highQuality
130-
cameraConfig.videoQuality = .typeHigh
131-
132-
switch Int(cameraOption.cameraDevice.rawValue) {
133-
case 0:
134-
cameraConfig.cameraDevice = .front
135-
default:
136-
cameraConfig.cameraDevice = .rear
137-
}
138-
139-
cameraConfig.videoMaximumDuration = cameraOption.videoMaximumDuration ?? 60
127+
var cameraConfig = setCameraConfig(cameraOption)
140128

141129
photoList.cameraType = .system(cameraConfig)
142130
} else {
@@ -149,12 +137,7 @@ extension HybridMultipleImagePicker {
149137
setLanguage(options)
150138
setTheme(options)
151139

152-
switch Int(options.presentation.rawValue) {
153-
case 1:
154-
config.modalPresentationStyle = .formSheet
155-
default:
156-
config.modalPresentationStyle = .fullScreen
157-
}
140+
config.modalPresentationStyle = setPresentation(options.presentation)
158141
}
159142

160143
private func setTheme(_ options: NitroConfig) {
@@ -203,6 +186,19 @@ extension HybridMultipleImagePicker {
203186
config.photoList.cell.customSelectableCellClass = nil
204187
}
205188

189+
func setPresentation(_ presentation: Presentation?) -> UIModalPresentationStyle {
190+
if let presentation {
191+
switch Int(presentation.rawValue) {
192+
case 1:
193+
return .formSheet
194+
default:
195+
return .fullScreen
196+
}
197+
}
198+
199+
return .fullScreen
200+
}
201+
206202
private func setLanguage(_ options: NitroConfig) {
207203
if let text = options.text {
208204
if let finish = text.finish {

nitrogen/generated/android/MultipleImagePickerOnLoad.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "JFunc_void_std__vector_Result_.hpp"
1616
#include "JFunc_void_double.hpp"
1717
#include "JFunc_void_CropResult.hpp"
18+
#include "JFunc_void_CameraResult.hpp"
1819
#include <NitroModules/JNISharedPtr.hpp>
1920
#include <NitroModules/DefaultConstructableObject.hpp>
2021

@@ -32,6 +33,8 @@ int initialize(JavaVM* vm) {
3233
margelo::nitro::multipleimagepicker::JFunc_void_double::registerNatives();
3334
margelo::nitro::multipleimagepicker::JFunc_void_CropResult::registerNatives();
3435
margelo::nitro::multipleimagepicker::JFunc_void_double::registerNatives();
36+
margelo::nitro::multipleimagepicker::JFunc_void_CameraResult::registerNatives();
37+
margelo::nitro::multipleimagepicker::JFunc_void_double::registerNatives();
3538

3639
// Register Nitro Hybrid Objects
3740
HybridObjectRegistry::registerHybridObjectConstructor(

0 commit comments

Comments
 (0)