[NEW] Video support (#801)
This commit is contained in:
parent
dafeb68704
commit
725d85588b
|
@ -13,6 +13,7 @@ import I18n from '../../i18n';
|
||||||
import sharedStyles from '../../views/Styles';
|
import sharedStyles from '../../views/Styles';
|
||||||
import { isIOS } from '../../utils/deviceInfo';
|
import { isIOS } from '../../utils/deviceInfo';
|
||||||
import { COLOR_PRIMARY, COLOR_BACKGROUND_CONTAINER, COLOR_WHITE } from '../../constants/colors';
|
import { COLOR_PRIMARY, COLOR_BACKGROUND_CONTAINER, COLOR_WHITE } from '../../constants/colors';
|
||||||
|
import { CustomIcon } from '../../lib/Icons';
|
||||||
|
|
||||||
const cancelButtonColor = COLOR_BACKGROUND_CONTAINER;
|
const cancelButtonColor = COLOR_BACKGROUND_CONTAINER;
|
||||||
|
|
||||||
|
@ -63,6 +64,21 @@ const styles = StyleSheet.create({
|
||||||
androidButtonText: {
|
androidButtonText: {
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
textAlign: 'center'
|
textAlign: 'center'
|
||||||
|
},
|
||||||
|
fileIcon: {
|
||||||
|
color: COLOR_PRIMARY,
|
||||||
|
margin: 20,
|
||||||
|
flex: 1,
|
||||||
|
textAlign: 'center'
|
||||||
|
},
|
||||||
|
video: {
|
||||||
|
flex: 1,
|
||||||
|
borderRadius: 4,
|
||||||
|
height: 150,
|
||||||
|
backgroundColor: '#1f2329',
|
||||||
|
marginBottom: 6,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center'
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -166,9 +182,24 @@ export default class UploadModal extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderPreview() {
|
||||||
|
const { file } = this.props;
|
||||||
|
if (file.mime && file.mime.match(/image/)) {
|
||||||
|
return (<Image source={{ isStatic: true, uri: file.path }} style={styles.image} />);
|
||||||
|
}
|
||||||
|
if (file.mime && file.mime.match(/video/)) {
|
||||||
|
return (
|
||||||
|
<View style={styles.video}>
|
||||||
|
<CustomIcon name='play' size={72} color={COLOR_WHITE} />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (<CustomIcon name='file-generic' size={72} style={styles.fileIcon} />);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { window: { width }, isVisible, close } = this.props;
|
const { window: { width }, isVisible, close } = this.props;
|
||||||
const { name, description, file } = this.state;
|
const { name, description } = this.state;
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
isVisible={isVisible}
|
isVisible={isVisible}
|
||||||
|
@ -187,7 +218,7 @@ export default class UploadModal extends Component {
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<ScrollView style={styles.scrollView}>
|
<ScrollView style={styles.scrollView}>
|
||||||
<Image source={{ isStatic: true, uri: file.path }} style={styles.image} />
|
{this.renderPreview()}
|
||||||
<TextInput
|
<TextInput
|
||||||
placeholder={I18n.t('File_name')}
|
placeholder={I18n.t('File_name')}
|
||||||
value={name}
|
value={name}
|
||||||
|
|
|
@ -49,9 +49,18 @@ const imagePickerConfig = {
|
||||||
avoidEmptySpaceAroundImage: false
|
avoidEmptySpaceAroundImage: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const libraryPickerConfig = {
|
||||||
|
mediaType: 'any'
|
||||||
|
};
|
||||||
|
|
||||||
|
const videoPickerConfig = {
|
||||||
|
mediaType: 'video'
|
||||||
|
};
|
||||||
|
|
||||||
const FILE_CANCEL_INDEX = 0;
|
const FILE_CANCEL_INDEX = 0;
|
||||||
const FILE_PHOTO_INDEX = 1;
|
const FILE_PHOTO_INDEX = 1;
|
||||||
const FILE_LIBRARY_INDEX = 2;
|
const FILE_VIDEO_INDEX = 2;
|
||||||
|
const FILE_LIBRARY_INDEX = 3;
|
||||||
|
|
||||||
class MessageBox extends Component {
|
class MessageBox extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
@ -101,12 +110,25 @@ class MessageBox extends Component {
|
||||||
this.fileOptions = [
|
this.fileOptions = [
|
||||||
I18n.t('Cancel'),
|
I18n.t('Cancel'),
|
||||||
I18n.t('Take_a_photo'),
|
I18n.t('Take_a_photo'),
|
||||||
|
I18n.t('Take_a_video'),
|
||||||
I18n.t('Choose_from_library')
|
I18n.t('Choose_from_library')
|
||||||
];
|
];
|
||||||
|
const libPickerLabels = {
|
||||||
|
cropperChooseText: I18n.t('Choose'),
|
||||||
|
cropperCancelText: I18n.t('Cancel'),
|
||||||
|
loadingLabelText: I18n.t('Processing')
|
||||||
|
};
|
||||||
this.imagePickerConfig = {
|
this.imagePickerConfig = {
|
||||||
...imagePickerConfig,
|
...imagePickerConfig,
|
||||||
cropperChooseText: I18n.t('Choose'),
|
...libPickerLabels
|
||||||
cropperCancelText: I18n.t('Cancel')
|
};
|
||||||
|
this.libraryPickerConfig = {
|
||||||
|
...libraryPickerConfig,
|
||||||
|
...libPickerLabels
|
||||||
|
};
|
||||||
|
this.videoPickerConfig = {
|
||||||
|
...videoPickerConfig,
|
||||||
|
...libPickerLabels
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,7 +485,7 @@ class MessageBox extends Component {
|
||||||
this.setShowSend(false);
|
this.setShowSend(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendImageMessage = async(file) => {
|
sendMediaMessage = async(file) => {
|
||||||
const { rid, tmid } = this.props;
|
const { rid, tmid } = this.props;
|
||||||
|
|
||||||
this.setState({ file: { isVisible: false } });
|
this.setState({ file: { isVisible: false } });
|
||||||
|
@ -491,9 +513,18 @@ class MessageBox extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
takeVideo = async() => {
|
||||||
|
try {
|
||||||
|
const video = await ImagePicker.openCamera(this.videoPickerConfig);
|
||||||
|
this.showUploadModal(video);
|
||||||
|
} catch (e) {
|
||||||
|
log('err_take_video', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chooseFromLibrary = async() => {
|
chooseFromLibrary = async() => {
|
||||||
try {
|
try {
|
||||||
const image = await ImagePicker.openPicker(this.imagePickerConfig);
|
const image = await ImagePicker.openPicker(this.libraryPickerConfig);
|
||||||
this.showUploadModal(image);
|
this.showUploadModal(image);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('err_choose_from_library', e);
|
log('err_choose_from_library', e);
|
||||||
|
@ -518,6 +549,9 @@ class MessageBox extends Component {
|
||||||
case FILE_PHOTO_INDEX:
|
case FILE_PHOTO_INDEX:
|
||||||
this.takePhoto();
|
this.takePhoto();
|
||||||
break;
|
break;
|
||||||
|
case FILE_VIDEO_INDEX:
|
||||||
|
this.takeVideo();
|
||||||
|
break;
|
||||||
case FILE_LIBRARY_INDEX:
|
case FILE_LIBRARY_INDEX:
|
||||||
this.chooseFromLibrary();
|
this.chooseFromLibrary();
|
||||||
break;
|
break;
|
||||||
|
@ -896,7 +930,7 @@ class MessageBox extends Component {
|
||||||
isVisible={(file && file.isVisible)}
|
isVisible={(file && file.isVisible)}
|
||||||
file={file}
|
file={file}
|
||||||
close={() => this.setState({ file: {} })}
|
close={() => this.setState({ file: {} })}
|
||||||
submit={this.sendImageMessage}
|
submit={this.sendMediaMessage}
|
||||||
/>
|
/>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
|
|
|
@ -262,6 +262,7 @@ export default {
|
||||||
Private_Channel: 'Private Channel',
|
Private_Channel: 'Private Channel',
|
||||||
Private_Groups: 'Private Groups',
|
Private_Groups: 'Private Groups',
|
||||||
Private: 'Private',
|
Private: 'Private',
|
||||||
|
Processing: 'Processing...',
|
||||||
Profile_saved_successfully: 'Profile saved successfully!',
|
Profile_saved_successfully: 'Profile saved successfully!',
|
||||||
Profile: 'Profile',
|
Profile: 'Profile',
|
||||||
Public_Channel: 'Public Channel',
|
Public_Channel: 'Public Channel',
|
||||||
|
@ -335,6 +336,7 @@ export default {
|
||||||
Started_discussion: 'Started a discussion:',
|
Started_discussion: 'Started a discussion:',
|
||||||
Submit: 'Submit',
|
Submit: 'Submit',
|
||||||
Take_a_photo: 'Take a photo',
|
Take_a_photo: 'Take a photo',
|
||||||
|
Take_a_video: 'Take a video',
|
||||||
tap_to_change_status: 'tap to change status',
|
tap_to_change_status: 'tap to change status',
|
||||||
Tap_to_view_servers_list: 'Tap to view servers list',
|
Tap_to_view_servers_list: 'Tap to view servers list',
|
||||||
Terms_of_Service: ' Terms of Service ',
|
Terms_of_Service: ' Terms of Service ',
|
||||||
|
|
|
@ -255,6 +255,7 @@ export default {
|
||||||
Private_Channel: 'Canal Privado',
|
Private_Channel: 'Canal Privado',
|
||||||
Private_Groups: 'Grupo Privado',
|
Private_Groups: 'Grupo Privado',
|
||||||
Private: 'Privado',
|
Private: 'Privado',
|
||||||
|
Processing: 'Processando...',
|
||||||
Profile_saved_successfully: 'Perfil salvo com sucesso!',
|
Profile_saved_successfully: 'Perfil salvo com sucesso!',
|
||||||
Profile: 'Perfil',
|
Profile: 'Perfil',
|
||||||
Public_Channel: 'Canal Público',
|
Public_Channel: 'Canal Público',
|
||||||
|
@ -322,6 +323,7 @@ export default {
|
||||||
Started_discussion: 'Iniciou uma discussão:',
|
Started_discussion: 'Iniciou uma discussão:',
|
||||||
Submit: 'Enviar',
|
Submit: 'Enviar',
|
||||||
Take_a_photo: 'Tirar uma foto',
|
Take_a_photo: 'Tirar uma foto',
|
||||||
|
Take_a_video: 'Gravar um vídeo',
|
||||||
Terms_of_Service: ' Termos de Serviço ',
|
Terms_of_Service: ' Termos de Serviço ',
|
||||||
The_URL_is_invalid: 'A URL fornecida é inválida ou não acessível. Por favor tente novamente, mas com uma url diferente.',
|
The_URL_is_invalid: 'A URL fornecida é inválida ou não acessível. Por favor tente novamente, mas com uma url diferente.',
|
||||||
There_was_an_error_while_action: 'Aconteceu um erro {{action}}!',
|
There_was_an_error_while_action: 'Aconteceu um erro {{action}}!',
|
||||||
|
|
|
@ -11547,8 +11547,8 @@ react-native-gesture-handler@^1.2.1:
|
||||||
prop-types "^15.5.10"
|
prop-types "^15.5.10"
|
||||||
|
|
||||||
"react-native-image-crop-picker@git+https://github.com/RocketChat/react-native-image-crop-picker.git":
|
"react-native-image-crop-picker@git+https://github.com/RocketChat/react-native-image-crop-picker.git":
|
||||||
version "0.21.1"
|
version "0.24.1"
|
||||||
resolved "git+https://github.com/RocketChat/react-native-image-crop-picker.git#6c205596b5496b207daa93408c9cef886e04bdbb"
|
resolved "git+https://github.com/RocketChat/react-native-image-crop-picker.git#d3e92c13fee5ce2f2dd3655ba719a70ba99a7d36"
|
||||||
|
|
||||||
react-native-image-pan-zoom@^2.1.9:
|
react-native-image-pan-zoom@^2.1.9:
|
||||||
version "2.1.11"
|
version "2.1.11"
|
||||||
|
|
Loading…
Reference in New Issue