mirror of
https://github.com/zhigang1992/examples.git
synced 2026-01-12 22:47:03 +08:00
213 lines
5.0 KiB
JavaScript
213 lines
5.0 KiB
JavaScript
import React from 'react';
|
|
import {
|
|
ActivityIndicator,
|
|
Button,
|
|
Clipboard,
|
|
Image,
|
|
Share,
|
|
StatusBar,
|
|
StyleSheet,
|
|
Text,
|
|
TouchableOpacity,
|
|
View,
|
|
} from 'react-native';
|
|
import Constants from 'expo-constants';
|
|
import * as ImagePicker from 'expo-image-picker';
|
|
import * as Permissions from 'expo-permissions';
|
|
|
|
export default class App extends React.Component {
|
|
state = {
|
|
image: null,
|
|
uploading: false,
|
|
};
|
|
|
|
render() {
|
|
return (
|
|
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
|
|
<Text
|
|
style={{
|
|
fontSize: 20,
|
|
marginBottom: 20,
|
|
textAlign: 'center',
|
|
marginHorizontal: 15,
|
|
}}>
|
|
Example: Upload ImagePicker result
|
|
</Text>
|
|
|
|
{this._maybeRenderControls()}
|
|
{this._maybeRenderUploadingIndicator()}
|
|
{this._maybeRenderImage()}
|
|
|
|
<StatusBar barStyle="default" />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
_maybeRenderUploadingIndicator = () => {
|
|
if (this.state.uploading) {
|
|
return <ActivityIndicator animating size="large" />;
|
|
}
|
|
};
|
|
|
|
_maybeRenderControls = () => {
|
|
if (!this.state.uploading) {
|
|
return (
|
|
<View>
|
|
<View style={{ marginVertical: 8 }}>
|
|
<Button
|
|
onPress={this._pickImage}
|
|
title="Pick an image from camera roll"
|
|
/>
|
|
</View>
|
|
<View style={{ marginVertical: 8 }}>
|
|
<Button onPress={this._takePhoto} title="Take a photo" />
|
|
</View>
|
|
</View>
|
|
);
|
|
}
|
|
};
|
|
|
|
_maybeRenderImage = () => {
|
|
if (this.state.image) {
|
|
return (
|
|
<View
|
|
style={{
|
|
marginTop: 30,
|
|
width: 250,
|
|
borderRadius: 3,
|
|
elevation: 2,
|
|
shadowColor: 'rgba(0,0,0,1)',
|
|
shadowOpacity: 0.2,
|
|
shadowOffset: { width: 4, height: 4 },
|
|
shadowRadius: 5,
|
|
}}>
|
|
<View
|
|
style={{
|
|
borderTopRightRadius: 3,
|
|
borderTopLeftRadius: 3,
|
|
overflow: 'hidden',
|
|
}}>
|
|
<Image
|
|
source={{ uri: this.state.image }}
|
|
style={{ width: 250, height: 250 }}
|
|
/>
|
|
</View>
|
|
|
|
<Text
|
|
onPress={this._copyToClipboard}
|
|
onLongPress={this._share}
|
|
style={{ paddingVertical: 10, paddingHorizontal: 10 }}>
|
|
{this.state.image}
|
|
</Text>
|
|
</View>
|
|
);
|
|
}
|
|
};
|
|
|
|
_share = () => {
|
|
Share.share({
|
|
message: this.state.image,
|
|
title: 'Check out this photo',
|
|
url: this.state.image,
|
|
});
|
|
};
|
|
|
|
_copyToClipboard = () => {
|
|
Clipboard.setString(this.state.image);
|
|
alert('Copied image URL to clipboard');
|
|
};
|
|
|
|
_askPermission = async (type, failureMessage) => {
|
|
const { status, permissions } = await Permissions.askAsync(type);
|
|
|
|
if (status === 'denied') {
|
|
alert(failureMessage);
|
|
}
|
|
};
|
|
|
|
_takePhoto = async () => {
|
|
await this._askPermission(
|
|
Permissions.CAMERA,
|
|
'We need the camera permission to take a picture...'
|
|
);
|
|
await this._askPermission(
|
|
Permissions.CAMERA_ROLL,
|
|
'We need the camera-roll permission to read pictures from your phone...'
|
|
);
|
|
let pickerResult = await ImagePicker.launchCameraAsync({
|
|
allowsEditing: true,
|
|
aspect: [4, 3],
|
|
});
|
|
|
|
this._handleImagePicked(pickerResult);
|
|
};
|
|
|
|
_pickImage = async () => {
|
|
await this._askPermission(
|
|
Permissions.CAMERA_ROLL,
|
|
'We need the camera-roll permission to read pictures from your phone...'
|
|
);
|
|
let pickerResult = await ImagePicker.launchImageLibraryAsync({
|
|
allowsEditing: true,
|
|
aspect: [4, 3],
|
|
});
|
|
|
|
this._handleImagePicked(pickerResult);
|
|
};
|
|
|
|
_handleImagePicked = async pickerResult => {
|
|
let uploadResponse, uploadResult;
|
|
|
|
try {
|
|
this.setState({ uploading: true });
|
|
|
|
if (!pickerResult.cancelled) {
|
|
uploadResponse = await uploadImageAsync(pickerResult.uri);
|
|
uploadResult = await uploadResponse.json();
|
|
this.setState({ image: uploadResult.location });
|
|
}
|
|
} catch (e) {
|
|
console.log({ uploadResponse });
|
|
console.log({ uploadResult });
|
|
console.log({ e });
|
|
alert('Upload failed, sorry :(');
|
|
} finally {
|
|
this.setState({ uploading: false });
|
|
}
|
|
};
|
|
}
|
|
|
|
async function uploadImageAsync(uri) {
|
|
let apiUrl = 'https://file-upload-example-backend-dkhqoilqqn.now.sh/upload';
|
|
|
|
// Note:
|
|
// Uncomment this if you want to experiment with local server
|
|
//
|
|
// if (Constants.isDevice) {
|
|
// apiUrl = `https://your-ngrok-subdomain.ngrok.io/upload`;
|
|
// } else {
|
|
// apiUrl = `http://localhost:3000/upload`
|
|
// }
|
|
|
|
let uriParts = uri.split('.');
|
|
let fileType = uri[uri.length - 1];
|
|
|
|
let formData = new FormData();
|
|
formData.append('photo', {
|
|
uri,
|
|
name: `photo.${fileType}`,
|
|
type: `image/${fileType}`,
|
|
});
|
|
|
|
let options = {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {
|
|
Accept: 'application/json',
|
|
'Content-Type': 'multipart/form-data',
|
|
},
|
|
};
|
|
|
|
return fetch(apiUrl, options);
|
|
}
|