diff --git a/app/components/__snapshots__/send_button.test.js.snap b/app/components/__snapshots__/send_button.test.js.snap
index ba764cb7db..4062649972 100644
--- a/app/components/__snapshots__/send_button.test.js.snap
+++ b/app/components/__snapshots__/send_button.test.js.snap
@@ -5,8 +5,7 @@ exports[`SendButton should change theme backgroundColor to 0.3 opacity 1`] = `
style={
Object {
"justifyContent": "flex-end",
- "paddingHorizontal": 5,
- "paddingVertical": 2,
+ "paddingRight": 8,
}
}
>
@@ -17,10 +16,9 @@ exports[`SendButton should change theme backgroundColor to 0.3 opacity 1`] = `
"alignItems": "center",
"backgroundColor": "#166de0",
"borderRadius": 4,
- "height": 28,
+ "height": 32,
"justifyContent": "center",
- "paddingLeft": 3,
- "width": 72,
+ "width": 80,
},
Object {
"backgroundColor": "rgba(22,109,224,0.3)",
@@ -29,9 +27,9 @@ exports[`SendButton should change theme backgroundColor to 0.3 opacity 1`] = `
}
>
@@ -43,8 +41,7 @@ exports[`SendButton should match snapshot 1`] = `
style={
Object {
"justifyContent": "flex-end",
- "paddingHorizontal": 5,
- "paddingVertical": 2,
+ "paddingRight": 8,
}
}
type="opacity"
@@ -55,17 +52,16 @@ exports[`SendButton should match snapshot 1`] = `
"alignItems": "center",
"backgroundColor": "#166de0",
"borderRadius": 4,
- "height": 28,
+ "height": 32,
"justifyContent": "center",
- "paddingLeft": 3,
- "width": 72,
+ "width": 80,
}
}
>
@@ -77,8 +73,7 @@ exports[`SendButton should render theme backgroundColor 1`] = `
style={
Object {
"justifyContent": "flex-end",
- "paddingHorizontal": 5,
- "paddingVertical": 2,
+ "paddingRight": 8,
}
}
type="opacity"
@@ -89,17 +84,16 @@ exports[`SendButton should render theme backgroundColor 1`] = `
"alignItems": "center",
"backgroundColor": "#166de0",
"borderRadius": 4,
- "height": 28,
+ "height": 32,
"justifyContent": "center",
- "paddingLeft": 3,
- "width": 72,
+ "width": 80,
}
}
>
diff --git a/app/components/attachment_button/index.js b/app/components/attachment_button/index.js
index 7b96cb410a..58be8d1763 100644
--- a/app/components/attachment_button/index.js
+++ b/app/components/attachment_button/index.js
@@ -329,18 +329,19 @@ export default class AttachmentButton extends PureComponent {
hasStoragePermission = async () => {
if (Platform.OS === 'android') {
const {formatMessage} = this.context.intl;
+ const storagePermission = Permissions.PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE;
let permissionRequest;
- const hasPermissionToStorage = await Permissions.check('storage');
+ const hasPermissionToStorage = await Permissions.check(storagePermission);
switch (hasPermissionToStorage) {
case Permissions.RESULTS.DENIED:
- permissionRequest = await Permissions.request('storage');
+ permissionRequest = await Permissions.request(storagePermission);
if (permissionRequest !== Permissions.RESULTS.GRANTED) {
return false;
}
break;
case Permissions.RESULTS.BLOCKED: {
- const {title, text} = this.getPermissionDeniedMessage('storage');
+ const {title, text} = this.getPermissionDeniedMessage(storagePermission);
Alert.alert(
title,
diff --git a/app/components/file_upload_preview/file_upload_item/file_upload_item.js b/app/components/file_upload_preview/file_upload_item/file_upload_item.js
index df3ff436da..9270a57e67 100644
--- a/app/components/file_upload_preview/file_upload_item/file_upload_item.js
+++ b/app/components/file_upload_preview/file_upload_item/file_upload_item.js
@@ -3,7 +3,7 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
-import {Platform, StyleSheet, Text, View} from 'react-native';
+import {Text, View} from 'react-native';
import RNFetchBlob from 'rn-fetch-blob';
import {AnimatedCircularProgress} from 'react-native-circular-progress';
@@ -17,6 +17,7 @@ import mattermostBucket from 'app/mattermost_bucket';
import {buildFileUploadData, encodeHeaderURIStringToUTF8} from 'app/utils/file';
import {emptyFunction} from 'app/utils/general';
import ImageCacheManager from 'app/utils/image_cache_manager';
+import {makeStyleSheetFromTheme, changeOpacity} from 'app/utils/theme';
export default class FileUploadItem extends PureComponent {
static propTypes = {
@@ -163,6 +164,7 @@ export default class FileUploadItem extends PureComponent {
};
renderProgress = (fill) => {
+ const styles = getStyleSheet(this.props.theme);
const realFill = Number(fill.toFixed(0));
return (
@@ -184,23 +186,28 @@ export default class FileUploadItem extends PureComponent {
theme,
} = this.props;
const {progress} = this.state;
+ const styles = getStyleSheet(theme);
let filePreviewComponent;
if (this.isImageType()) {
filePreviewComponent = (
-
+
+
+
);
} else {
filePreviewComponent = (
-
+
+
+
);
}
@@ -209,7 +216,7 @@ export default class FileUploadItem extends PureComponent {
key={file.clientId}
style={styles.preview}
>
-
+
{filePreviewComponent}
{file.failed &&
({
preview: {
- justifyContent: 'flex-end',
- height: 115,
- width: 115,
+ paddingTop: 12,
+ marginLeft: 12,
},
- previewShadow: {
- height: 100,
- width: 100,
+ previewContainer: {
+ height: 64,
+ width: 64,
elevation: 10,
- borderRadius: 5,
- ...Platform.select({
- ios: {
- backgroundColor: '#fff',
- shadowColor: '#000',
- shadowOpacity: 0.5,
- shadowRadius: 4,
- shadowOffset: {
- width: 0,
- height: 0,
- },
- },
- }),
+ borderRadius: 4,
},
progressCircle: {
alignItems: 'center',
@@ -278,10 +272,10 @@ const styles = StyleSheet.create({
progressCircleContent: {
alignItems: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.4)',
- height: 100,
+ height: 64,
justifyContent: 'center',
position: 'absolute',
- width: 100,
+ width: 64,
},
progressCirclePercentage: {
alignItems: 'center',
@@ -300,4 +294,11 @@ const styles = StyleSheet.create({
color: 'white',
fontSize: 18,
},
-});
+ filePreview: {
+ borderColor: changeOpacity(theme.centerChannelColor, 0.15),
+ borderRadius: 5,
+ borderWidth: 1,
+ width: 64,
+ height: 64,
+ },
+}));
diff --git a/app/components/file_upload_preview/file_upload_item/file_upload_item.test.js b/app/components/file_upload_preview/file_upload_item/file_upload_item.test.js
index 45d9f016bd..eca4744f34 100644
--- a/app/components/file_upload_preview/file_upload_item/file_upload_item.test.js
+++ b/app/components/file_upload_preview/file_upload_item/file_upload_item.test.js
@@ -3,6 +3,7 @@
import React from 'react';
import {shallow} from 'enzyme';
+import {Preferences} from 'mattermost-redux/constants';
import ImageCacheManager from 'app/utils/image_cache_manager';
import FileUploadItem from './file_upload_item';
@@ -18,7 +19,7 @@ describe('FileUploadItem', () => {
file: {
loading: false,
},
- theme: {},
+ theme: Preferences.THEMES.default,
};
describe('downloadAndUploadFile', () => {
diff --git a/app/components/file_upload_preview/file_upload_preview.js b/app/components/file_upload_preview/file_upload_preview.js
index 7f909bb2c6..01d460f579 100644
--- a/app/components/file_upload_preview/file_upload_preview.js
+++ b/app/components/file_upload_preview/file_upload_preview.js
@@ -4,19 +4,26 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {
- Platform,
+ InteractionManager,
ScrollView,
Text,
View,
} from 'react-native';
-import {makeStyleSheetFromTheme} from 'app/utils/theme';
+import * as Animatable from 'react-native-animatable';
import EventEmitter from 'mattermost-redux/utils/event_emitter';
import FormattedText from 'app/components/formatted_text';
+import {makeStyleSheetFromTheme} from 'app/utils/theme';
import FileUploadItem from './file_upload_item';
+const initial = {opacity: 0, scale: 0};
+const final = {opacity: 1, scale: 1};
+const showFiles = {opacity: 1, height: 81};
+const hideFiles = {opacity: 0, height: 0};
+const hideError = {height: 0};
+
export default class FileUploadPreview extends PureComponent {
static propTypes = {
channelId: PropTypes.string.isRequired,
@@ -36,9 +43,17 @@ export default class FileUploadPreview extends PureComponent {
showFileMaxWarning: false,
};
+ errorRef = React.createRef();
+ errorContainerRef = React.createRef();
+ containerRef = React.createRef();
+
componentDidMount() {
EventEmitter.on('fileMaxWarning', this.handleFileMaxWarning);
EventEmitter.on('fileSizeWarning', this.handleFileSizeWarning);
+
+ if (this.props.files.length) {
+ InteractionManager.runAfterInteractions(this.showOrHideContainer);
+ }
}
componentWillUnmount() {
@@ -46,6 +61,12 @@ export default class FileUploadPreview extends PureComponent {
EventEmitter.off('fileSizeWarning', this.handleFileSizeWarning);
}
+ componentDidUpdate(prevProps) {
+ if (this.containerRef.current && this.props.files.length !== prevProps.files.length) {
+ InteractionManager.runAfterInteractions(this.showOrHideContainer);
+ }
+ }
+
buildFilePreviews = () => {
return this.props.files.map((file) => {
return (
@@ -60,35 +81,88 @@ export default class FileUploadPreview extends PureComponent {
});
};
+ clearErrorsFromState = (delay) => {
+ setTimeout(() => {
+ this.setState({
+ showFileMaxWarning: false,
+ fileSizeWarning: null,
+ });
+ }, delay || 0);
+ }
+
handleFileMaxWarning = () => {
this.setState({showFileMaxWarning: true});
- setTimeout(() => {
- this.setState({showFileMaxWarning: false});
- }, 3000);
+ if (this.errorRef.current) {
+ this.makeErrorVisible(true, 20, null, () => {
+ this.errorRef.current.transition(initial, final, 350, 'ease-in');
+ });
+ setTimeout(() => {
+ this.makeErrorVisible(false, 20, 350, () => {
+ this.errorRef.current.transition(final, initial, 350, 'ease-out');
+ this.clearErrorsFromState(400);
+ });
+ }, 5000);
+ }
};
handleFileSizeWarning = (message) => {
- this.setState({fileSizeWarning: message});
+ if (this.errorRef.current) {
+ if (message) {
+ this.setState({fileSizeWarning: message});
+ this.makeErrorVisible(true, 42, null, () => {
+ this.errorRef.current.transition(initial, final, 350, 'ease-in');
+ });
+ } else {
+ this.makeErrorVisible(false, 42, 350, () => {
+ this.errorRef.current.transition(final, initial, 350, 'ease-out');
+ this.clearErrorsFromState(400);
+ });
+ }
+ }
};
- render() {
+ makeErrorVisible = (visible, height, delay, callback) => {
+ if (this.errorContainerRef.current) {
+ if (visible) {
+ this.errorContainerRef.current.transition(hideError, {height}, 100);
+ setTimeout(callback, delay || 150);
+ } else {
+ callback();
+ setTimeout(() => {
+ this.errorContainerRef.current.transition({height}, hideError, 300);
+ }, delay || 150);
+ }
+ }
+ }
+
+ showOrHideContainer = () => {
const {
channelIsLoading,
filesUploadingForCurrentChannel,
files,
} = this.props;
+
+ if ((channelIsLoading || (!files.length && !filesUploadingForCurrentChannel))) {
+ this.containerRef.current.transition(showFiles, hideFiles, 150, 'ease-out');
+ this.shown = false;
+ } else if (files.length && !this.shown) {
+ this.containerRef.current.transition(hideFiles, showFiles, 350, 'ease-in');
+ this.shown = true;
+ }
+ }
+
+ render() {
const {fileSizeWarning, showFileMaxWarning} = this.state;
const style = getStyleSheet(this.props.theme);
- if (
- !fileSizeWarning && !showFileMaxWarning &&
- (channelIsLoading || (!files.length && !filesUploadingForCurrentChannel))
- ) {
- return null;
- }
return (
-
+
{this.buildFilePreviews()}
-
-
- {showFileMaxWarning && (
-
- )}
- {Boolean(fileSizeWarning) &&
-
- {fileSizeWarning}
-
- }
-
+
+
+
+ {showFileMaxWarning && (
+
+ )}
+ {Boolean(fileSizeWarning) &&
+
+ {fileSizeWarning}
+
+ }
+
+
);
}
@@ -119,32 +204,36 @@ export default class FileUploadPreview extends PureComponent {
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
return {
- fileContainer: {
- display: 'flex',
- flexDirection: 'row',
- },
- errorContainer: {
- height: 18,
- },
previewContainer: {
display: 'flex',
flexDirection: 'column',
},
+ fileContainer: {
+ display: 'flex',
+ flexDirection: 'row',
+ height: 0,
+ alignItems: 'center',
+ },
+ errorContainer: {
+ height: 0,
+ },
+ errorTextContainer: {
+ marginTop: 5,
+ marginHorizontal: 12,
+ opacity: 0,
+ flex: 1,
+ },
scrollView: {
flex: 1,
- marginBottom: 10,
},
scrollViewContent: {
alignItems: 'flex-end',
- marginLeft: 14,
+ paddingRight: 12,
},
warning: {
color: theme.errorTextColor,
- marginLeft: 14,
- marginBottom: Platform.select({
- android: 14,
- ios: 0,
- }),
+ flex: 1,
+ flexWrap: 'wrap',
},
};
});
diff --git a/app/components/file_upload_preview/file_upload_remove.js b/app/components/file_upload_preview/file_upload_remove.js
index fa0abd42f6..51dbcfde89 100644
--- a/app/components/file_upload_preview/file_upload_remove.js
+++ b/app/components/file_upload_preview/file_upload_remove.js
@@ -3,9 +3,9 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
-import {Platform} from 'react-native';
+import {View} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import {makeStyleSheetFromTheme} from 'app/utils/theme';
+import {makeStyleSheetFromTheme, changeOpacity} from 'app/utils/theme';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
@@ -25,19 +25,21 @@ export default class FileUploadRemove extends PureComponent {
};
render() {
- const style = getStyleSheet(this.props.theme);
+ const {theme} = this.props;
+ const style = getStyleSheet(theme);
return (
-
+
+
+
);
}
@@ -45,25 +47,20 @@ export default class FileUploadRemove extends PureComponent {
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
return {
- removeButtonIcon: Platform.select({
- ios: {
- marginTop: 2,
- },
- }),
- removeButtonWrapper: {
- alignItems: 'center',
- justifyContent: 'center',
+ tappableContainer: {
position: 'absolute',
- overflow: 'hidden',
elevation: 11,
- top: 7,
- right: 7,
- width: 24,
- height: 24,
- borderRadius: 12,
+ top: -2,
+ right: -16,
+ width: 32,
+ height: 32,
+ },
+ removeButton: {
+ borderRadius: 20,
+ alignSelf: 'center',
+ paddingTop: 6,
+ paddingHorizontal: 1,
backgroundColor: theme.centerChannelBg,
- borderWidth: 2,
- borderColor: theme.centerChannelBg,
},
};
});
diff --git a/app/components/pasteable_text_input/index.js b/app/components/pasteable_text_input/index.js
index 04b748fe46..abdb0fd989 100644
--- a/app/components/pasteable_text_input/index.js
+++ b/app/components/pasteable_text_input/index.js
@@ -18,9 +18,7 @@ export class PasteableTextInput extends React.PureComponent {
forwardRef: PropTypes.any,
}
- state = {
- inputHeight: new Animated.Value(33),
- };
+ inputHeight = new Animated.Value(ViewTypes.INPUT_INITIAL_HEIGHT);
componentDidMount() {
this.subscription = OnPasteEventEmitter.addListener('onPaste', this.onPaste);
@@ -40,22 +38,33 @@ export class PasteableTextInput extends React.PureComponent {
animateHeight = (event) => {
if (Platform.OS === 'ios') {
const {height} = event.nativeEvent.contentSize;
- const {style} = this.props;
- const {inputHeight} = this.state;
+ const {style, value} = this.props;
const newHeight = Math.min(style.maxHeight, height + ViewTypes.INPUT_VERTICAL_PADDING);
- const transitionSpeed = height === ViewTypes.INPUT_LINE_HEIGHT ? 500 : 1;
- Animated.timing(inputHeight, {
- toValue: newHeight,
- duration: transitionSpeed,
- easing: Easing.inOut(Easing.sin),
- }).start();
+ if (value) {
+ this.inputHeight.setValue(newHeight);
+ } else {
+ requestAnimationFrame(() => {
+ Animated.timing(this.inputHeight, {
+ toValue: ViewTypes.INPUT_INITIAL_HEIGHT,
+ duration: 350,
+ delay: 100,
+ easing: Easing.inOut(Easing.sin),
+ }).start();
+ });
+ }
}
}
wrapperLayout = (children) => {
- const {inputHeight} = this.state;
- return {children};
+ return (
+
+ {children}
+
+ );
}
render() {
diff --git a/app/components/post_textbox/__snapshots__/post_textbox.test.js.snap b/app/components/post_textbox/__snapshots__/post_textbox.test.js.snap
index 0fea5b5ecf..34227db227 100644
--- a/app/components/post_textbox/__snapshots__/post_textbox.test.js.snap
+++ b/app/components/post_textbox/__snapshots__/post_textbox.test.js.snap
@@ -14,7 +14,7 @@ exports[`PostTextBox should match, full snapshot 1`] = `
"borderTopWidth": 1,
"flexDirection": "row",
"justifyContent": "center",
- "paddingVertical": 4,
+ "paddingBottom": 8,
},
null,
]
@@ -36,11 +36,8 @@ exports[`PostTextBox should match, full snapshot 1`] = `
style={
Array [
Object {
- "backgroundColor": "#ffffff",
"flex": 1,
"flexDirection": "column",
- "marginLeft": 10,
- "marginRight": 10,
},
]
}
@@ -61,100 +58,249 @@ exports[`PostTextBox should match, full snapshot 1`] = `
style={
Object {
"color": "#3d3c40",
- "fontSize": 14,
+ "fontSize": 16,
+ "lineHeight": 20,
"maxHeight": 150,
- "paddingBottom": 8,
- "paddingLeft": 12,
- "paddingRight": 12,
- "paddingTop": 8,
+ "minHeight": 38,
+ "paddingBottom": 6,
+ "paddingHorizontal": 12,
+ "paddingTop": 12,
}
}
underlineColorAndroid="transparent"
value=""
/>
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
+
-
-
-
-
+
diff --git a/app/components/post_textbox/components/cameraButton.js b/app/components/post_textbox/components/cameraButton.js
index c1e79226e9..2b1eb15013 100644
--- a/app/components/post_textbox/components/cameraButton.js
+++ b/app/components/post_textbox/components/cameraButton.js
@@ -106,7 +106,7 @@ export default class AttachmentButton extends PureComponent {
if (Platform.OS === 'ios') {
const {formatMessage} = this.context.intl;
let permissionRequest;
- const targetSource = 'camera';
+ const targetSource = Permissions.PERMISSIONS.IOS.CAMERA;
const hasPermissionToStorage = await Permissions.check(targetSource);
switch (hasPermissionToStorage) {
diff --git a/app/components/post_textbox/components/fileUploadButton.js b/app/components/post_textbox/components/fileUploadButton.js
index d8c1b7933d..e790b6b148 100644
--- a/app/components/post_textbox/components/fileUploadButton.js
+++ b/app/components/post_textbox/components/fileUploadButton.js
@@ -96,11 +96,12 @@ export default class FileUploadButton extends PureComponent {
if (Platform.OS === 'android') {
const {formatMessage} = this.context.intl;
let permissionRequest;
- const hasPermissionToStorage = await Permissions.check('storage');
+ const storagePermission = Permissions.PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE;
+ const hasPermissionToStorage = await Permissions.check(storagePermission);
switch (hasPermissionToStorage) {
case Permissions.RESULTS.UNAVAILABLE:
- permissionRequest = await Permissions.request('storage');
+ permissionRequest = await Permissions.request(storagePermission);
if (permissionRequest !== Permissions.RESULTS.AUTHORIZED) {
return false;
}
diff --git a/app/components/post_textbox/components/imageUploadButton.js b/app/components/post_textbox/components/imageUploadButton.js
index f41458e452..334a44165a 100644
--- a/app/components/post_textbox/components/imageUploadButton.js
+++ b/app/components/post_textbox/components/imageUploadButton.js
@@ -108,7 +108,7 @@ export default class ImageUploadButton extends PureComponent {
if (Platform.OS === 'ios') {
const {formatMessage} = this.context.intl;
let permissionRequest;
- const targetSource = 'photo';
+ const targetSource = Permissions.PERMISSIONS.IOS.PHOTO_LIBRARY;
const hasPermissionToStorage = await Permissions.check(targetSource);
switch (hasPermissionToStorage) {
diff --git a/app/components/post_textbox/post_textbox_base.js b/app/components/post_textbox/post_textbox_base.js
index 6c2afad217..803ad21006 100644
--- a/app/components/post_textbox/post_textbox_base.js
+++ b/app/components/post_textbox/post_textbox_base.js
@@ -19,6 +19,7 @@ import {
View,
} from 'react-native';
import {intlShape} from 'react-intl';
+import RNFetchBlob from 'rn-fetch-blob';
import Button from 'react-native-button';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import slashForwardBoxIcon from 'assets/images/icons/slash-forward-box.png';
@@ -35,7 +36,7 @@ import FormattedText from 'app/components/formatted_text';
import PasteableTextInput from 'app/components/pasteable_text_input';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
import SendButton from 'app/components/send_button';
-import {INSERT_TO_COMMENT, INSERT_TO_DRAFT, IS_REACTION_REGEX, MAX_FILE_COUNT} from 'app/constants/post_textbox';
+import {INSERT_TO_COMMENT, INSERT_TO_DRAFT, IS_REACTION_REGEX, MAX_FILE_COUNT, ICON_SIZE} from 'app/constants/post_textbox';
import {NOTIFY_ALL_MEMBERS} from 'app/constants/view';
import FileUploadPreview from 'app/components/file_upload_preview';
@@ -239,13 +240,23 @@ export default class PostTextBoxBase extends PureComponent {
}
};
+ startAtMention = () => {
+ this.handleTextChange(`${this.state.value}@`, true);
+ this.focus();
+ };
+
+ startSlashCommand = () => {
+ this.handleTextChange('/', true);
+ this.focus();
+ };
+
getTextInputButton = (actionType) => {
const {channelIsReadOnly, theme} = this.props;
const style = getStyleSheet(theme);
let button = null;
const buttonStyle = [];
- let iconColor = theme.centerChannelColor;
+ let iconColor = changeOpacity(theme.centerChannelColor, 0.64);
let isDisabled = false;
if (!channelIsReadOnly) {
@@ -253,21 +264,18 @@ export default class PostTextBoxBase extends PureComponent {
case 'at':
isDisabled = this.state.value[this.state.value.length - 1] === '@';
if (isDisabled) {
- iconColor = changeOpacity(theme.centerChannelColor, 0.6);
+ iconColor = changeOpacity(theme.centerChannelColor, 0.16);
}
button = (
{
- this.handleTextChange(`${this.state.value}@`, true);
- this.focus();
- }}
+ onPress={this.startAtMention}
style={style.iconWrapper}
>
);
@@ -282,10 +290,7 @@ export default class PostTextBoxBase extends PureComponent {
button = (
{
- this.handleTextChange('/', true);
- this.focus();
- }}
+ onPress={this.startSlashCommand}
style={style.iconWrapper}
>
{
const {canUploadFiles, channelIsReadOnly, files, maxFileSize, theme} = this.props;
+ const style = getStyleSheet(theme);
let button = null;
const props = {
blurTextBox: this.blur,
@@ -313,6 +319,7 @@ export default class PostTextBoxBase extends PureComponent {
uploadFiles: this.handleUploadFiles,
maxFileSize,
theme,
+ buttonContainerStyle: style.iconWrapper,
};
if (canUploadFiles && !channelIsReadOnly) {
@@ -504,8 +511,20 @@ export default class PostTextBoxBase extends PureComponent {
}
};
- handleUploadFiles = (files) => {
- this.props.actions.initUploadFiles(files, this.props.rootId);
+ handleUploadFiles = async (files) => {
+ const file = files[0];
+ if (!file.fileSize | !file.fileName) {
+ const path = (file.path || file.uri).replace('file://', '');
+ const fileInfo = await RNFetchBlob.fs.stat(path);
+ file.fileSize = fileInfo.size;
+ file.fileName = fileInfo.filename;
+ }
+
+ if (file.fileSize > this.props.maxFileSize) {
+ this.onShowFileSizeWarning(file.fileName);
+ } else {
+ this.props.actions.initUploadFiles(files, this.props.rootId);
+ }
};
isFileLoading = () => {
@@ -722,7 +741,7 @@ export default class PostTextBoxBase extends PureComponent {
EventEmitter.emit('fileSizeWarning', fileSizeWarning);
setTimeout(() => {
EventEmitter.emit('fileSizeWarning', null);
- }, 3000);
+ }, 5000);
};
onCloseChannelPress = () => {
@@ -835,6 +854,12 @@ export default class PostTextBoxBase extends PureComponent {
const textValue = channelIsLoading ? '' : value;
const placeholder = this.getPlaceHolder();
+ let maxHeight = 150;
+
+ if (isLandscape) {
+ maxHeight = 88;
+ }
+
return (
-
-
-
-
-
-
- {this.getTextInputButton('at')}
-
- {this.getTextInputButton('slash')}
-
- {this.getMediaButton('file')}
-
- {this.getMediaButton('image')}
-
- {this.getMediaButton('camera')}
-
-
-
+
-
+
+
+
+
+ {this.getTextInputButton('at')}
+
+ {this.getTextInputButton('slash')}
+
+ {this.getMediaButton('file')}
+
+ {this.getMediaButton('image')}
+
+ {this.getMediaButton('camera')}
+
+
+
+
+
+ }
);
@@ -910,37 +938,36 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
alignItems: 'center',
},
slashIcon: {
- width: 20,
- height: 20,
+ width: ICON_SIZE,
+ height: ICON_SIZE,
opacity: 1,
- tintColor: theme.centerChannelColor,
+ tintColor: changeOpacity(theme.centerChannelColor, 0.64),
},
iconDisabled: {
- tintColor: changeOpacity(theme.centerChannelColor, 0.6),
+ tintColor: changeOpacity(theme.centerChannelColor, 0.16),
},
iconWrapper: {
- paddingLeft: 10,
- paddingRight: 10,
+ alignItems: 'center',
+ justifyContent: 'center',
+ padding: 10,
},
quickActionsContainer: {
display: 'flex',
flexDirection: 'row',
+ height: 44,
},
input: {
color: theme.centerChannelColor,
- fontSize: 14,
- paddingBottom: 8,
- paddingLeft: 12,
- paddingRight: 12,
- paddingTop: 8,
- maxHeight: 150,
+ fontSize: 16,
+ lineHeight: 20,
+ paddingHorizontal: 12,
+ paddingTop: 12,
+ paddingBottom: 6,
+ minHeight: 38,
},
inputContainer: {
flex: 1,
flexDirection: 'column',
- backgroundColor: theme.centerChannelBg,
- marginRight: 10,
- marginLeft: 10,
},
inputContentContainer: {
alignItems: 'stretch',
@@ -949,7 +976,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
alignItems: 'flex-end',
flexDirection: 'row',
justifyContent: 'center',
- paddingVertical: 4,
+ paddingBottom: 8,
backgroundColor: theme.centerChannelBg,
borderTopWidth: 1,
borderTopColor: changeOpacity(theme.centerChannelColor, 0.20),
diff --git a/app/components/send_button.js b/app/components/send_button.js
index bf4cee0e4c..b500edbcc2 100644
--- a/app/components/send_button.js
+++ b/app/components/send_button.js
@@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
import React, {memo} from 'react';
-import {Platform, View} from 'react-native';
+import {View} from 'react-native';
import PropTypes from 'prop-types';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
@@ -18,19 +18,15 @@ function SendButton(props) {
PaperPlane = require('app/components/paper_plane').default;
}
- const icon = (
-
- );
-
if (props.disabled) {
return (
- {icon}
+
);
@@ -43,7 +39,11 @@ function SendButton(props) {
type={'opacity'}
>
- {icon}
+
);
@@ -62,20 +62,15 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
},
sendButtonContainer: {
justifyContent: 'flex-end',
- paddingHorizontal: 5,
- paddingVertical: Platform.select({
- android: 8,
- ios: 2,
- }),
+ paddingRight: 8,
},
sendButton: {
backgroundColor: theme.buttonBg,
borderRadius: 4,
- height: 28,
- width: 72,
+ height: 32,
+ width: 80,
alignItems: 'center',
justifyContent: 'center',
- paddingLeft: 3,
},
};
});
diff --git a/app/constants/post_textbox.js b/app/constants/post_textbox.js
index 462a4406d9..082ecf56a6 100644
--- a/app/constants/post_textbox.js
+++ b/app/constants/post_textbox.js
@@ -5,3 +5,4 @@ export const MAX_FILE_COUNT = 5;
export const IS_REACTION_REGEX = /(^\+:([^:\s]*):)$/i;
export const INSERT_TO_DRAFT = 'insert_to_draft';
export const INSERT_TO_COMMENT = 'insert_to_comment';
+export const ICON_SIZE = 24;
\ No newline at end of file
diff --git a/app/constants/view.js b/app/constants/view.js
index b59639f2f0..34791a1a9e 100644
--- a/app/constants/view.js
+++ b/app/constants/view.js
@@ -121,6 +121,7 @@ export default {
NotificationLevels,
SidebarSectionTypes,
IOS_HORIZONTAL_LANDSCAPE: 44,
- INPUT_LINE_HEIGHT: 17,
- INPUT_VERTICAL_PADDING: 16,
+ INPUT_LINE_HEIGHT: 20,
+ INPUT_VERTICAL_PADDING: 18,
+ INPUT_INITIAL_HEIGHT: 38,
};
diff --git a/index.js b/index.js
index 26d39923fc..e9612ada76 100644
--- a/index.js
+++ b/index.js
@@ -18,6 +18,7 @@ if (Platform.OS === 'android') {
if (__DEV__) {
YellowBox.ignoreWarnings([
'Warning: componentWillReceiveProps',
+ '`-[RCTRootView cancelTouches]`',
// Hide warnings caused by React Native (https://github.com/facebook/react-native/issues/20841)
'Require cycle: node_modules/react-native/Libraries/Network/fetch.js',