[FIX] Upload buttons on Android (#541)
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 792 B |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.8 KiB |
|
@ -25,8 +25,7 @@ const styles = StyleSheet.create({
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
textAlign: 'center',
|
textAlign: 'center'
|
||||||
fontWeight: '500'
|
|
||||||
},
|
},
|
||||||
background_primary: {
|
background_primary: {
|
||||||
backgroundColor: colors.background_primary
|
backgroundColor: colors.background_primary
|
||||||
|
@ -54,7 +53,8 @@ export default class Button extends React.PureComponent {
|
||||||
onPress: PropTypes.func,
|
onPress: PropTypes.func,
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
backgroundColor: PropTypes.string,
|
backgroundColor: PropTypes.string,
|
||||||
loading: PropTypes.bool
|
loading: PropTypes.bool,
|
||||||
|
style: PropTypes.any
|
||||||
}
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
|
@ -67,7 +67,7 @@ export default class Button extends React.PureComponent {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
title, type, onPress, disabled, backgroundColor, loading, ...otherProps
|
title, type, onPress, disabled, backgroundColor, loading, style, ...otherProps
|
||||||
} = this.props;
|
} = this.props;
|
||||||
return (
|
return (
|
||||||
<RectButton
|
<RectButton
|
||||||
|
@ -75,9 +75,9 @@ export default class Button extends React.PureComponent {
|
||||||
enabled={!(disabled || loading)}
|
enabled={!(disabled || loading)}
|
||||||
style={[
|
style={[
|
||||||
styles.container,
|
styles.container,
|
||||||
styles.border,
|
|
||||||
backgroundColor ? { backgroundColor } : styles[`background_${ type }`],
|
backgroundColor ? { backgroundColor } : styles[`background_${ type }`],
|
||||||
disabled && styles.disabled
|
disabled && styles.disabled,
|
||||||
|
style
|
||||||
]}
|
]}
|
||||||
{...otherProps}
|
{...otherProps}
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import {
|
import {
|
||||||
View, Text, StyleSheet, Image, ScrollView, Platform
|
View, Text, StyleSheet, Image, ScrollView, Platform, TouchableHighlight
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Modal from 'react-native-modal';
|
import Modal from 'react-native-modal';
|
||||||
|
@ -10,20 +10,24 @@ import equal from 'deep-equal';
|
||||||
import TextInput from '../TextInput';
|
import TextInput from '../TextInput';
|
||||||
import Button from '../Button';
|
import Button from '../Button';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
|
import sharedStyles from '../../views/Styles';
|
||||||
|
|
||||||
const cancelButtonColor = '#f7f8fa';
|
const cancelButtonColor = '#f7f8fa';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
modal: {
|
||||||
|
alignItems: 'center'
|
||||||
|
},
|
||||||
titleContainer: {
|
titleContainer: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
paddingHorizontal: 16,
|
paddingHorizontal: 16,
|
||||||
paddingTop: 16
|
paddingTop: 16
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
fontWeight: 'bold'
|
...sharedStyles.textBold
|
||||||
},
|
},
|
||||||
container: {
|
container: {
|
||||||
height: Platform.OS === 'ios' ? 404 : 430,
|
height: 430,
|
||||||
backgroundColor: '#ffffff',
|
backgroundColor: '#ffffff',
|
||||||
flexDirection: 'column'
|
flexDirection: 'column'
|
||||||
},
|
},
|
||||||
|
@ -43,9 +47,20 @@ const styles = StyleSheet.create({
|
||||||
padding: 16,
|
padding: 16,
|
||||||
backgroundColor: '#f7f8fa'
|
backgroundColor: '#f7f8fa'
|
||||||
},
|
},
|
||||||
buttonMargin: {
|
button: {
|
||||||
margin: 0
|
marginBottom: 0
|
||||||
|
},
|
||||||
|
androidButton: {
|
||||||
|
paddingHorizontal: 15,
|
||||||
|
justifyContent: 'center',
|
||||||
|
height: 48,
|
||||||
|
borderRadius: 2
|
||||||
|
},
|
||||||
|
androidButtonText: {
|
||||||
|
fontSize: 18,
|
||||||
|
textAlign: 'center'
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@responsive
|
@responsive
|
||||||
|
@ -75,21 +90,65 @@ export default class UploadModal extends Component {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_submit = () => {
|
submit = () => {
|
||||||
const { file, submit } = this.props;
|
const { file, submit } = this.props;
|
||||||
const { name, description } = this.state;
|
const { name, description } = this.state;
|
||||||
submit({ ...file, name, description });
|
submit({ ...file, name, description });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderButtons = () => {
|
||||||
|
const { close } = this.props;
|
||||||
|
if (Platform.OS === 'ios') {
|
||||||
|
return (
|
||||||
|
<View style={styles.buttonContainer}>
|
||||||
|
<Button
|
||||||
|
title={I18n.t('Cancel')}
|
||||||
|
type='secondary'
|
||||||
|
backgroundColor={cancelButtonColor}
|
||||||
|
style={styles.button}
|
||||||
|
onPress={close}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
title={I18n.t('Send')}
|
||||||
|
type='primary'
|
||||||
|
style={styles.button}
|
||||||
|
onPress={this.submit}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// FIXME: RNGH don't work well on Android modals: https://github.com/kmagiera/react-native-gesture-handler/issues/139
|
||||||
|
return (
|
||||||
|
<View style={styles.buttonContainer}>
|
||||||
|
<TouchableHighlight
|
||||||
|
onPress={close}
|
||||||
|
style={[styles.androidButton, { backgroundColor: cancelButtonColor }]}
|
||||||
|
underlayColor={cancelButtonColor}
|
||||||
|
activeOpacity={0.5}
|
||||||
|
>
|
||||||
|
<Text style={[styles.androidButtonText, { ...sharedStyles.textBold, color: '#1d74f5' }]}>{I18n.t('Cancel')}</Text>
|
||||||
|
</TouchableHighlight>
|
||||||
|
<TouchableHighlight
|
||||||
|
onPress={this.submit}
|
||||||
|
style={[styles.androidButton, { backgroundColor: '#1d74f5' }]}
|
||||||
|
underlayColor='#1d74f5'
|
||||||
|
activeOpacity={0.5}
|
||||||
|
>
|
||||||
|
<Text style={[styles.androidButtonText, { ...sharedStyles.textMedium, color: '#fff' }]}>{I18n.t('Send')}</Text>
|
||||||
|
</TouchableHighlight>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
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, file } = this.state;
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
isVisible={isVisible}
|
isVisible={isVisible}
|
||||||
style={{ alignItems: 'center' }}
|
style={styles.modal}
|
||||||
onBackdropPress={() => close()}
|
onBackdropPress={close}
|
||||||
onBackButtonPress={() => close()}
|
onBackButtonPress={close}
|
||||||
animationIn='fadeIn'
|
animationIn='fadeIn'
|
||||||
animationOut='fadeOut'
|
animationOut='fadeOut'
|
||||||
useNativeDriver
|
useNativeDriver
|
||||||
|
@ -97,7 +156,7 @@ export default class UploadModal extends Component {
|
||||||
>
|
>
|
||||||
<View style={[styles.container, { width: width - 32 }]}>
|
<View style={[styles.container, { width: width - 32 }]}>
|
||||||
<View style={styles.titleContainer}>
|
<View style={styles.titleContainer}>
|
||||||
<Text style={styles.title}>Upload file?</Text>
|
<Text style={styles.title}>{I18n.t('Upload_file_question_mark')}</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<ScrollView style={styles.scrollView}>
|
<ScrollView style={styles.scrollView}>
|
||||||
|
@ -113,21 +172,7 @@ export default class UploadModal extends Component {
|
||||||
onChangeText={value => this.setState({ description: value })}
|
onChangeText={value => this.setState({ description: value })}
|
||||||
/>
|
/>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<View style={styles.buttonContainer}>
|
{this.renderButtons()}
|
||||||
<Button
|
|
||||||
title={I18n.t('Cancel')}
|
|
||||||
type='secondary'
|
|
||||||
backgroundColor={cancelButtonColor}
|
|
||||||
margin={styles.buttonMargin}
|
|
||||||
onPress={close}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
title={I18n.t('Send')}
|
|
||||||
type='primary'
|
|
||||||
margin={styles.buttonMargin}
|
|
||||||
onPress={this._submit}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</View>
|
</View>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|
|
@ -40,7 +40,7 @@ const onlyUnique = function onlyUnique(value, index, self) {
|
||||||
const imagePickerConfig = {
|
const imagePickerConfig = {
|
||||||
cropping: true,
|
cropping: true,
|
||||||
compressImageQuality: 0.8,
|
compressImageQuality: 0.8,
|
||||||
cropperAvoidEmptySpaceAroundImage: false,
|
avoidEmptySpaceAroundImage: false,
|
||||||
cropperChooseText: I18n.t('Choose'),
|
cropperChooseText: I18n.t('Choose'),
|
||||||
cropperCancelText: I18n.t('Cancel')
|
cropperCancelText: I18n.t('Cancel')
|
||||||
};
|
};
|
||||||
|
|
|
@ -326,6 +326,7 @@ export default {
|
||||||
Unread_on_top: 'Unread on top',
|
Unread_on_top: 'Unread on top',
|
||||||
Unstar: 'Unstar',
|
Unstar: 'Unstar',
|
||||||
Uploading: 'Uploading',
|
Uploading: 'Uploading',
|
||||||
|
Upload_file_question_mark: 'Upload file?',
|
||||||
User_added_by: 'User {{userAdded}} added by {{userBy}}',
|
User_added_by: 'User {{userAdded}} added by {{userBy}}',
|
||||||
User_has_been_key: 'User has been {{key}}!',
|
User_has_been_key: 'User has been {{key}}!',
|
||||||
User_is_no_longer_role_by_: '{{user}} is no longer {{role}} by {{userBy}}',
|
User_is_no_longer_role_by_: '{{user}} is no longer {{role}} by {{userBy}}',
|
||||||
|
|
|
@ -325,6 +325,7 @@ export default {
|
||||||
Unread_on_top: 'Não lidas no topo',
|
Unread_on_top: 'Não lidas no topo',
|
||||||
Unstar: 'Remover favorito',
|
Unstar: 'Remover favorito',
|
||||||
Uploading: 'Subindo arquivo',
|
Uploading: 'Subindo arquivo',
|
||||||
|
Upload_file_question_mark: 'Enviar arquivo?',
|
||||||
User_added_by: 'Usuário {{userAdded}} adicionado por {{userBy}}',
|
User_added_by: 'Usuário {{userAdded}} adicionado por {{userBy}}',
|
||||||
User_has_been_key: 'Usuário foi {{key}}!',
|
User_has_been_key: 'Usuário foi {{key}}!',
|
||||||
User_is_no_longer_role_by_: '{{user}} não pertence mais à {{role}} por {{userBy}}',
|
User_is_no_longer_role_by_: '{{user}} não pertence mais à {{role}} por {{userBy}}',
|
||||||
|
|
|
@ -9,44 +9,40 @@ import equal from 'deep-equal';
|
||||||
|
|
||||||
import I18n from '../../../i18n';
|
import I18n from '../../../i18n';
|
||||||
import { STATUS_COLORS } from '../../../constants/colors';
|
import { STATUS_COLORS } from '../../../constants/colors';
|
||||||
|
import sharedStyles from '../../Styles';
|
||||||
|
|
||||||
const isIOS = () => Platform.OS === 'ios';
|
const isIOS = () => Platform.OS === 'ios';
|
||||||
const TITLE_SIZE = 18;
|
const TITLE_SIZE = 18;
|
||||||
const ICON_SIZE = 20;
|
const ICON_SIZE = 18;
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
backgroundColor: isIOS() ? 'transparent' : '#2F343D',
|
backgroundColor: isIOS() ? 'transparent' : '#2F343D'
|
||||||
height: 44
|
|
||||||
},
|
},
|
||||||
titleContainer: {
|
titleContainer: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center'
|
alignItems: 'center'
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
|
...sharedStyles.textSemibold,
|
||||||
color: isIOS() ? '#0C0D0F' : '#fff',
|
color: isIOS() ? '#0C0D0F' : '#fff',
|
||||||
fontSize: TITLE_SIZE,
|
fontSize: TITLE_SIZE
|
||||||
fontWeight: '500'
|
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
width: ICON_SIZE,
|
width: ICON_SIZE,
|
||||||
height: ICON_SIZE,
|
height: ICON_SIZE,
|
||||||
marginRight: 5,
|
marginRight: 8,
|
||||||
tintColor: isIOS() ? '#9EA2A8' : '#fff'
|
tintColor: isIOS() ? '#9EA2A8' : '#fff'
|
||||||
},
|
},
|
||||||
typing: {
|
typing: {
|
||||||
|
...sharedStyles.textRegular,
|
||||||
color: isIOS() ? '#9EA2A8' : '#fff',
|
color: isIOS() ? '#9EA2A8' : '#fff',
|
||||||
fontSize: 12
|
fontSize: 12
|
||||||
},
|
},
|
||||||
typingUsers: {
|
typingUsers: {
|
||||||
|
...sharedStyles.textSemibold,
|
||||||
fontWeight: '600'
|
fontWeight: '600'
|
||||||
},
|
|
||||||
alignItemsFlexStart: {
|
|
||||||
alignItems: 'flex-start'
|
|
||||||
},
|
|
||||||
alignItemsCenter: {
|
|
||||||
alignItems: 'center'
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -114,7 +110,7 @@ export default class RoomHeaderView extends PureComponent {
|
||||||
return (
|
return (
|
||||||
<Text style={styles.typing} numberOfLines={1}>
|
<Text style={styles.typing} numberOfLines={1}>
|
||||||
<Text style={styles.typingUsers}>{usersText} </Text>
|
<Text style={styles.typingUsers}>{usersText} </Text>
|
||||||
{ usersTyping.length > 1 ? I18n.t('are_typing') : I18n.t('is_typing') }
|
{ usersTyping.length > 1 ? I18n.t('are_typing') : I18n.t('is_typing') }...
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -124,11 +120,11 @@ export default class RoomHeaderView extends PureComponent {
|
||||||
window, title, type, status, usersTyping
|
window, title, type, status, usersTyping
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const icon = {
|
const icon = {
|
||||||
d: 'mention',
|
d: 'mention_header',
|
||||||
c: 'hashtag'
|
c: 'hashtag'
|
||||||
}[type] || 'lock';
|
}[type] || 'lock';
|
||||||
const portrait = window.height > window.width;
|
const portrait = window.height > window.width;
|
||||||
let height = 44;
|
let height = isIOS ? 44 : 60;
|
||||||
let scale = 1;
|
let scale = 1;
|
||||||
|
|
||||||
if (!portrait) {
|
if (!portrait) {
|
||||||
|
@ -144,8 +140,7 @@ export default class RoomHeaderView extends PureComponent {
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
styles.container,
|
styles.container,
|
||||||
portrait ? styles.alignItemsFlexStart : styles.alignItemsCenter,
|
{ width: window.width - 150, height }
|
||||||
{ maxWidth: window.width - 150, height }
|
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<View style={styles.titleContainer}>
|
<View style={styles.titleContainer}>
|
||||||
|
|
23
ios/RocketChatRN/Images.xcassets/Icons/mention_header.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "mention_header.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "mention_header@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "mention_header@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
BIN
ios/RocketChatRN/Images.xcassets/Icons/mention_header.imageset/mention_header.png
vendored
Normal file
After Width: | Height: | Size: 792 B |
BIN
ios/RocketChatRN/Images.xcassets/Icons/mention_header.imageset/mention_header@2x.png
vendored
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
ios/RocketChatRN/Images.xcassets/Icons/mention_header.imageset/mention_header@3x.png
vendored
Normal file
After Width: | Height: | Size: 2.9 KiB |