forked from Ivasoft/mattermost-mobile
Fixing post draft style to comply with design specs (#3818)
* Polishing post draft to comply with design specs * changed maxHeight in landscape mode, fixed icon sizes - Refactored code so that post draft icon sizes are taken from same constant value - Set maxHeight value in landscape mode to be smaller (tests pending) - Removed repeated styles for button wrappers (passing them down as props to child components) - Increased size of image attachment remote icon, and increased tappable area * Removing repeated logic for file upload * Fixing failed snapshot tests / style checks * Fixing file upload remove icon to have 64% opacity * post draft UX/UI improvements * Fix input box extra spacing * input box line height and attachment border * Animate to original state even if error is showing * Fix permissions * Improve attachment error animation * Fix iOS post input height * Update snapshots
This commit is contained in:
committed by
Amit Uttam
parent
e05207412f
commit
0b81a9b4e0
@@ -5,8 +5,7 @@ exports[`SendButton should change theme backgroundColor to 0.3 opacity 1`] = `
|
|||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"justifyContent": "flex-end",
|
"justifyContent": "flex-end",
|
||||||
"paddingHorizontal": 5,
|
"paddingRight": 8,
|
||||||
"paddingVertical": 2,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -17,10 +16,9 @@ exports[`SendButton should change theme backgroundColor to 0.3 opacity 1`] = `
|
|||||||
"alignItems": "center",
|
"alignItems": "center",
|
||||||
"backgroundColor": "#166de0",
|
"backgroundColor": "#166de0",
|
||||||
"borderRadius": 4,
|
"borderRadius": 4,
|
||||||
"height": 28,
|
"height": 32,
|
||||||
"justifyContent": "center",
|
"justifyContent": "center",
|
||||||
"paddingLeft": 3,
|
"width": 80,
|
||||||
"width": 72,
|
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"backgroundColor": "rgba(22,109,224,0.3)",
|
"backgroundColor": "rgba(22,109,224,0.3)",
|
||||||
@@ -29,9 +27,9 @@ exports[`SendButton should change theme backgroundColor to 0.3 opacity 1`] = `
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<PaperPlane
|
<PaperPlane
|
||||||
color="#ffffff"
|
color="rgba(255,255,255,0.5)"
|
||||||
height={13}
|
height={16}
|
||||||
width={15}
|
width={19}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
@@ -43,8 +41,7 @@ exports[`SendButton should match snapshot 1`] = `
|
|||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"justifyContent": "flex-end",
|
"justifyContent": "flex-end",
|
||||||
"paddingHorizontal": 5,
|
"paddingRight": 8,
|
||||||
"paddingVertical": 2,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
type="opacity"
|
type="opacity"
|
||||||
@@ -55,17 +52,16 @@ exports[`SendButton should match snapshot 1`] = `
|
|||||||
"alignItems": "center",
|
"alignItems": "center",
|
||||||
"backgroundColor": "#166de0",
|
"backgroundColor": "#166de0",
|
||||||
"borderRadius": 4,
|
"borderRadius": 4,
|
||||||
"height": 28,
|
"height": 32,
|
||||||
"justifyContent": "center",
|
"justifyContent": "center",
|
||||||
"paddingLeft": 3,
|
"width": 80,
|
||||||
"width": 72,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<PaperPlane
|
<PaperPlane
|
||||||
color="#ffffff"
|
color="#ffffff"
|
||||||
height={13}
|
height={16}
|
||||||
width={15}
|
width={19}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</TouchableWithFeedbackIOS>
|
</TouchableWithFeedbackIOS>
|
||||||
@@ -77,8 +73,7 @@ exports[`SendButton should render theme backgroundColor 1`] = `
|
|||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"justifyContent": "flex-end",
|
"justifyContent": "flex-end",
|
||||||
"paddingHorizontal": 5,
|
"paddingRight": 8,
|
||||||
"paddingVertical": 2,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
type="opacity"
|
type="opacity"
|
||||||
@@ -89,17 +84,16 @@ exports[`SendButton should render theme backgroundColor 1`] = `
|
|||||||
"alignItems": "center",
|
"alignItems": "center",
|
||||||
"backgroundColor": "#166de0",
|
"backgroundColor": "#166de0",
|
||||||
"borderRadius": 4,
|
"borderRadius": 4,
|
||||||
"height": 28,
|
"height": 32,
|
||||||
"justifyContent": "center",
|
"justifyContent": "center",
|
||||||
"paddingLeft": 3,
|
"width": 80,
|
||||||
"width": 72,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<PaperPlane
|
<PaperPlane
|
||||||
color="#ffffff"
|
color="#ffffff"
|
||||||
height={13}
|
height={16}
|
||||||
width={15}
|
width={19}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</TouchableWithFeedbackIOS>
|
</TouchableWithFeedbackIOS>
|
||||||
|
|||||||
@@ -329,18 +329,19 @@ export default class AttachmentButton extends PureComponent {
|
|||||||
hasStoragePermission = async () => {
|
hasStoragePermission = async () => {
|
||||||
if (Platform.OS === 'android') {
|
if (Platform.OS === 'android') {
|
||||||
const {formatMessage} = this.context.intl;
|
const {formatMessage} = this.context.intl;
|
||||||
|
const storagePermission = Permissions.PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE;
|
||||||
let permissionRequest;
|
let permissionRequest;
|
||||||
const hasPermissionToStorage = await Permissions.check('storage');
|
const hasPermissionToStorage = await Permissions.check(storagePermission);
|
||||||
|
|
||||||
switch (hasPermissionToStorage) {
|
switch (hasPermissionToStorage) {
|
||||||
case Permissions.RESULTS.DENIED:
|
case Permissions.RESULTS.DENIED:
|
||||||
permissionRequest = await Permissions.request('storage');
|
permissionRequest = await Permissions.request(storagePermission);
|
||||||
if (permissionRequest !== Permissions.RESULTS.GRANTED) {
|
if (permissionRequest !== Permissions.RESULTS.GRANTED) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Permissions.RESULTS.BLOCKED: {
|
case Permissions.RESULTS.BLOCKED: {
|
||||||
const {title, text} = this.getPermissionDeniedMessage('storage');
|
const {title, text} = this.getPermissionDeniedMessage(storagePermission);
|
||||||
|
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
title,
|
title,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import React, {PureComponent} from 'react';
|
import React, {PureComponent} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
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 RNFetchBlob from 'rn-fetch-blob';
|
||||||
import {AnimatedCircularProgress} from 'react-native-circular-progress';
|
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 {buildFileUploadData, encodeHeaderURIStringToUTF8} from 'app/utils/file';
|
||||||
import {emptyFunction} from 'app/utils/general';
|
import {emptyFunction} from 'app/utils/general';
|
||||||
import ImageCacheManager from 'app/utils/image_cache_manager';
|
import ImageCacheManager from 'app/utils/image_cache_manager';
|
||||||
|
import {makeStyleSheetFromTheme, changeOpacity} from 'app/utils/theme';
|
||||||
|
|
||||||
export default class FileUploadItem extends PureComponent {
|
export default class FileUploadItem extends PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@@ -163,6 +164,7 @@ export default class FileUploadItem extends PureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
renderProgress = (fill) => {
|
renderProgress = (fill) => {
|
||||||
|
const styles = getStyleSheet(this.props.theme);
|
||||||
const realFill = Number(fill.toFixed(0));
|
const realFill = Number(fill.toFixed(0));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -184,23 +186,28 @@ export default class FileUploadItem extends PureComponent {
|
|||||||
theme,
|
theme,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const {progress} = this.state;
|
const {progress} = this.state;
|
||||||
|
const styles = getStyleSheet(theme);
|
||||||
let filePreviewComponent;
|
let filePreviewComponent;
|
||||||
|
|
||||||
if (this.isImageType()) {
|
if (this.isImageType()) {
|
||||||
filePreviewComponent = (
|
filePreviewComponent = (
|
||||||
<FileAttachmentImage
|
<View style={styles.filePreview}>
|
||||||
file={file}
|
<FileAttachmentImage
|
||||||
theme={theme}
|
file={file}
|
||||||
/>
|
theme={theme}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
filePreviewComponent = (
|
filePreviewComponent = (
|
||||||
<FileAttachmentIcon
|
<View style={styles.filePreview}>
|
||||||
file={file}
|
<FileAttachmentIcon
|
||||||
theme={theme}
|
file={file}
|
||||||
wrapperHeight={100}
|
theme={theme}
|
||||||
wrapperWidth={100}
|
wrapperHeight={60}
|
||||||
/>
|
wrapperWidth={60}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +216,7 @@ export default class FileUploadItem extends PureComponent {
|
|||||||
key={file.clientId}
|
key={file.clientId}
|
||||||
style={styles.preview}
|
style={styles.preview}
|
||||||
>
|
>
|
||||||
<View style={styles.previewShadow}>
|
<View style={styles.previewContainer}>
|
||||||
{filePreviewComponent}
|
{filePreviewComponent}
|
||||||
{file.failed &&
|
{file.failed &&
|
||||||
<FileUploadRetry
|
<FileUploadRetry
|
||||||
@@ -220,7 +227,7 @@ export default class FileUploadItem extends PureComponent {
|
|||||||
{file.loading && !file.failed &&
|
{file.loading && !file.failed &&
|
||||||
<View style={styles.progressCircleContent}>
|
<View style={styles.progressCircleContent}>
|
||||||
<AnimatedCircularProgress
|
<AnimatedCircularProgress
|
||||||
size={100}
|
size={64}
|
||||||
fill={progress}
|
fill={progress}
|
||||||
width={4}
|
width={4}
|
||||||
backgroundColor='rgba(255, 255, 255, 0.5)'
|
backgroundColor='rgba(255, 255, 255, 0.5)'
|
||||||
@@ -245,29 +252,16 @@ export default class FileUploadItem extends PureComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const getStyleSheet = makeStyleSheetFromTheme((theme) => ({
|
||||||
preview: {
|
preview: {
|
||||||
justifyContent: 'flex-end',
|
paddingTop: 12,
|
||||||
height: 115,
|
marginLeft: 12,
|
||||||
width: 115,
|
|
||||||
},
|
},
|
||||||
previewShadow: {
|
previewContainer: {
|
||||||
height: 100,
|
height: 64,
|
||||||
width: 100,
|
width: 64,
|
||||||
elevation: 10,
|
elevation: 10,
|
||||||
borderRadius: 5,
|
borderRadius: 4,
|
||||||
...Platform.select({
|
|
||||||
ios: {
|
|
||||||
backgroundColor: '#fff',
|
|
||||||
shadowColor: '#000',
|
|
||||||
shadowOpacity: 0.5,
|
|
||||||
shadowRadius: 4,
|
|
||||||
shadowOffset: {
|
|
||||||
width: 0,
|
|
||||||
height: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
progressCircle: {
|
progressCircle: {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
@@ -278,10 +272,10 @@ const styles = StyleSheet.create({
|
|||||||
progressCircleContent: {
|
progressCircleContent: {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: 'rgba(0, 0, 0, 0.4)',
|
backgroundColor: 'rgba(0, 0, 0, 0.4)',
|
||||||
height: 100,
|
height: 64,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
width: 100,
|
width: 64,
|
||||||
},
|
},
|
||||||
progressCirclePercentage: {
|
progressCirclePercentage: {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
@@ -300,4 +294,11 @@ const styles = StyleSheet.create({
|
|||||||
color: 'white',
|
color: 'white',
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
},
|
},
|
||||||
});
|
filePreview: {
|
||||||
|
borderColor: changeOpacity(theme.centerChannelColor, 0.15),
|
||||||
|
borderRadius: 5,
|
||||||
|
borderWidth: 1,
|
||||||
|
width: 64,
|
||||||
|
height: 64,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {shallow} from 'enzyme';
|
import {shallow} from 'enzyme';
|
||||||
|
|
||||||
|
import {Preferences} from 'mattermost-redux/constants';
|
||||||
import ImageCacheManager from 'app/utils/image_cache_manager';
|
import ImageCacheManager from 'app/utils/image_cache_manager';
|
||||||
import FileUploadItem from './file_upload_item';
|
import FileUploadItem from './file_upload_item';
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@ describe('FileUploadItem', () => {
|
|||||||
file: {
|
file: {
|
||||||
loading: false,
|
loading: false,
|
||||||
},
|
},
|
||||||
theme: {},
|
theme: Preferences.THEMES.default,
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('downloadAndUploadFile', () => {
|
describe('downloadAndUploadFile', () => {
|
||||||
|
|||||||
@@ -4,19 +4,26 @@
|
|||||||
import React, {PureComponent} from 'react';
|
import React, {PureComponent} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {
|
import {
|
||||||
Platform,
|
InteractionManager,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
Text,
|
Text,
|
||||||
View,
|
View,
|
||||||
} from 'react-native';
|
} 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 EventEmitter from 'mattermost-redux/utils/event_emitter';
|
||||||
|
|
||||||
import FormattedText from 'app/components/formatted_text';
|
import FormattedText from 'app/components/formatted_text';
|
||||||
|
import {makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||||
|
|
||||||
import FileUploadItem from './file_upload_item';
|
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 {
|
export default class FileUploadPreview extends PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
channelId: PropTypes.string.isRequired,
|
channelId: PropTypes.string.isRequired,
|
||||||
@@ -36,9 +43,17 @@ export default class FileUploadPreview extends PureComponent {
|
|||||||
showFileMaxWarning: false,
|
showFileMaxWarning: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
errorRef = React.createRef();
|
||||||
|
errorContainerRef = React.createRef();
|
||||||
|
containerRef = React.createRef();
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
EventEmitter.on('fileMaxWarning', this.handleFileMaxWarning);
|
EventEmitter.on('fileMaxWarning', this.handleFileMaxWarning);
|
||||||
EventEmitter.on('fileSizeWarning', this.handleFileSizeWarning);
|
EventEmitter.on('fileSizeWarning', this.handleFileSizeWarning);
|
||||||
|
|
||||||
|
if (this.props.files.length) {
|
||||||
|
InteractionManager.runAfterInteractions(this.showOrHideContainer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
@@ -46,6 +61,12 @@ export default class FileUploadPreview extends PureComponent {
|
|||||||
EventEmitter.off('fileSizeWarning', this.handleFileSizeWarning);
|
EventEmitter.off('fileSizeWarning', this.handleFileSizeWarning);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
if (this.containerRef.current && this.props.files.length !== prevProps.files.length) {
|
||||||
|
InteractionManager.runAfterInteractions(this.showOrHideContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buildFilePreviews = () => {
|
buildFilePreviews = () => {
|
||||||
return this.props.files.map((file) => {
|
return this.props.files.map((file) => {
|
||||||
return (
|
return (
|
||||||
@@ -60,35 +81,88 @@ export default class FileUploadPreview extends PureComponent {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
clearErrorsFromState = (delay) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.setState({
|
||||||
|
showFileMaxWarning: false,
|
||||||
|
fileSizeWarning: null,
|
||||||
|
});
|
||||||
|
}, delay || 0);
|
||||||
|
}
|
||||||
|
|
||||||
handleFileMaxWarning = () => {
|
handleFileMaxWarning = () => {
|
||||||
this.setState({showFileMaxWarning: true});
|
this.setState({showFileMaxWarning: true});
|
||||||
setTimeout(() => {
|
if (this.errorRef.current) {
|
||||||
this.setState({showFileMaxWarning: false});
|
this.makeErrorVisible(true, 20, null, () => {
|
||||||
}, 3000);
|
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) => {
|
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 {
|
const {
|
||||||
channelIsLoading,
|
channelIsLoading,
|
||||||
filesUploadingForCurrentChannel,
|
filesUploadingForCurrentChannel,
|
||||||
files,
|
files,
|
||||||
} = this.props;
|
} = 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 {fileSizeWarning, showFileMaxWarning} = this.state;
|
||||||
const style = getStyleSheet(this.props.theme);
|
const style = getStyleSheet(this.props.theme);
|
||||||
if (
|
|
||||||
!fileSizeWarning && !showFileMaxWarning &&
|
|
||||||
(channelIsLoading || (!files.length && !filesUploadingForCurrentChannel))
|
|
||||||
) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={style.previewContainer}>
|
<View style={style.previewContainer}>
|
||||||
<View style={style.fileContainer}>
|
<Animatable.View
|
||||||
|
style={style.fileContainer}
|
||||||
|
ref={this.containerRef}
|
||||||
|
isInteraction={true}
|
||||||
|
duration={300}
|
||||||
|
>
|
||||||
<ScrollView
|
<ScrollView
|
||||||
horizontal={true}
|
horizontal={true}
|
||||||
style={style.scrollView}
|
style={style.scrollView}
|
||||||
@@ -97,21 +171,32 @@ export default class FileUploadPreview extends PureComponent {
|
|||||||
>
|
>
|
||||||
{this.buildFilePreviews()}
|
{this.buildFilePreviews()}
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</View>
|
</Animatable.View>
|
||||||
<View style={style.errorContainer}>
|
<Animatable.View
|
||||||
{showFileMaxWarning && (
|
ref={this.errorContainerRef}
|
||||||
<FormattedText
|
style={style.errorContainer}
|
||||||
style={style.warning}
|
isInteraction={true}
|
||||||
id='mobile.file_upload.max_warning'
|
>
|
||||||
defaultMessage='Uploads limited to 5 files maximum.'
|
<Animatable.View
|
||||||
/>
|
ref={this.errorRef}
|
||||||
)}
|
isInteraction={true}
|
||||||
{Boolean(fileSizeWarning) &&
|
style={style.errorTextContainer}
|
||||||
<Text style={style.warning}>
|
useNativeDriver={true}
|
||||||
{fileSizeWarning}
|
>
|
||||||
</Text>
|
{showFileMaxWarning && (
|
||||||
}
|
<FormattedText
|
||||||
</View>
|
style={style.warning}
|
||||||
|
id='mobile.file_upload.max_warning'
|
||||||
|
defaultMessage='Uploads limited to 5 files maximum.'
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{Boolean(fileSizeWarning) &&
|
||||||
|
<Text style={style.warning}>
|
||||||
|
{fileSizeWarning}
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
</Animatable.View>
|
||||||
|
</Animatable.View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -119,32 +204,36 @@ export default class FileUploadPreview extends PureComponent {
|
|||||||
|
|
||||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||||
return {
|
return {
|
||||||
fileContainer: {
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
},
|
|
||||||
errorContainer: {
|
|
||||||
height: 18,
|
|
||||||
},
|
|
||||||
previewContainer: {
|
previewContainer: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
},
|
},
|
||||||
|
fileContainer: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
height: 0,
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
errorContainer: {
|
||||||
|
height: 0,
|
||||||
|
},
|
||||||
|
errorTextContainer: {
|
||||||
|
marginTop: 5,
|
||||||
|
marginHorizontal: 12,
|
||||||
|
opacity: 0,
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
scrollView: {
|
scrollView: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
marginBottom: 10,
|
|
||||||
},
|
},
|
||||||
scrollViewContent: {
|
scrollViewContent: {
|
||||||
alignItems: 'flex-end',
|
alignItems: 'flex-end',
|
||||||
marginLeft: 14,
|
paddingRight: 12,
|
||||||
},
|
},
|
||||||
warning: {
|
warning: {
|
||||||
color: theme.errorTextColor,
|
color: theme.errorTextColor,
|
||||||
marginLeft: 14,
|
flex: 1,
|
||||||
marginBottom: Platform.select({
|
flexWrap: 'wrap',
|
||||||
android: 14,
|
|
||||||
ios: 0,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
import React, {PureComponent} from 'react';
|
import React, {PureComponent} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {Platform} from 'react-native';
|
import {View} from 'react-native';
|
||||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
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';
|
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
|
||||||
|
|
||||||
@@ -25,19 +25,21 @@ export default class FileUploadRemove extends PureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const style = getStyleSheet(this.props.theme);
|
const {theme} = this.props;
|
||||||
|
const style = getStyleSheet(theme);
|
||||||
return (
|
return (
|
||||||
<TouchableWithFeedback
|
<TouchableWithFeedback
|
||||||
style={style.removeButtonWrapper}
|
style={style.tappableContainer}
|
||||||
onPress={this.handleOnPress}
|
onPress={this.handleOnPress}
|
||||||
type={'opacity'}
|
type={'opacity'}
|
||||||
>
|
>
|
||||||
<Icon
|
<View style={style.removeButton}>
|
||||||
name='close-circle'
|
<Icon
|
||||||
color={this.props.theme.centerChannelColor}
|
name='close-circle'
|
||||||
size={20}
|
color={changeOpacity(theme.centerChannelColor, 0.64)}
|
||||||
style={style.removeButtonIcon}
|
size={18}
|
||||||
/>
|
/>
|
||||||
|
</View>
|
||||||
</TouchableWithFeedback>
|
</TouchableWithFeedback>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -45,25 +47,20 @@ export default class FileUploadRemove extends PureComponent {
|
|||||||
|
|
||||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||||
return {
|
return {
|
||||||
removeButtonIcon: Platform.select({
|
tappableContainer: {
|
||||||
ios: {
|
|
||||||
marginTop: 2,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
removeButtonWrapper: {
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
overflow: 'hidden',
|
|
||||||
elevation: 11,
|
elevation: 11,
|
||||||
top: 7,
|
top: -2,
|
||||||
right: 7,
|
right: -16,
|
||||||
width: 24,
|
width: 32,
|
||||||
height: 24,
|
height: 32,
|
||||||
borderRadius: 12,
|
},
|
||||||
|
removeButton: {
|
||||||
|
borderRadius: 20,
|
||||||
|
alignSelf: 'center',
|
||||||
|
paddingTop: 6,
|
||||||
|
paddingHorizontal: 1,
|
||||||
backgroundColor: theme.centerChannelBg,
|
backgroundColor: theme.centerChannelBg,
|
||||||
borderWidth: 2,
|
|
||||||
borderColor: theme.centerChannelBg,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,9 +18,7 @@ export class PasteableTextInput extends React.PureComponent {
|
|||||||
forwardRef: PropTypes.any,
|
forwardRef: PropTypes.any,
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
inputHeight = new Animated.Value(ViewTypes.INPUT_INITIAL_HEIGHT);
|
||||||
inputHeight: new Animated.Value(33),
|
|
||||||
};
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.subscription = OnPasteEventEmitter.addListener('onPaste', this.onPaste);
|
this.subscription = OnPasteEventEmitter.addListener('onPaste', this.onPaste);
|
||||||
@@ -40,22 +38,33 @@ export class PasteableTextInput extends React.PureComponent {
|
|||||||
animateHeight = (event) => {
|
animateHeight = (event) => {
|
||||||
if (Platform.OS === 'ios') {
|
if (Platform.OS === 'ios') {
|
||||||
const {height} = event.nativeEvent.contentSize;
|
const {height} = event.nativeEvent.contentSize;
|
||||||
const {style} = this.props;
|
const {style, value} = this.props;
|
||||||
const {inputHeight} = this.state;
|
|
||||||
const newHeight = Math.min(style.maxHeight, height + ViewTypes.INPUT_VERTICAL_PADDING);
|
const newHeight = Math.min(style.maxHeight, height + ViewTypes.INPUT_VERTICAL_PADDING);
|
||||||
const transitionSpeed = height === ViewTypes.INPUT_LINE_HEIGHT ? 500 : 1;
|
|
||||||
|
|
||||||
Animated.timing(inputHeight, {
|
if (value) {
|
||||||
toValue: newHeight,
|
this.inputHeight.setValue(newHeight);
|
||||||
duration: transitionSpeed,
|
} else {
|
||||||
easing: Easing.inOut(Easing.sin),
|
requestAnimationFrame(() => {
|
||||||
}).start();
|
Animated.timing(this.inputHeight, {
|
||||||
|
toValue: ViewTypes.INPUT_INITIAL_HEIGHT,
|
||||||
|
duration: 350,
|
||||||
|
delay: 100,
|
||||||
|
easing: Easing.inOut(Easing.sin),
|
||||||
|
}).start();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wrapperLayout = (children) => {
|
wrapperLayout = (children) => {
|
||||||
const {inputHeight} = this.state;
|
return (
|
||||||
return <Animated.View style={{flex: 1, height: inputHeight}}>{children}</Animated.View>;
|
<Animated.View
|
||||||
|
ref={this.containerRef}
|
||||||
|
style={{height: this.inputHeight}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Animated.View>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ exports[`PostTextBox should match, full snapshot 1`] = `
|
|||||||
"borderTopWidth": 1,
|
"borderTopWidth": 1,
|
||||||
"flexDirection": "row",
|
"flexDirection": "row",
|
||||||
"justifyContent": "center",
|
"justifyContent": "center",
|
||||||
"paddingVertical": 4,
|
"paddingBottom": 8,
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
]
|
]
|
||||||
@@ -36,11 +36,8 @@ exports[`PostTextBox should match, full snapshot 1`] = `
|
|||||||
style={
|
style={
|
||||||
Array [
|
Array [
|
||||||
Object {
|
Object {
|
||||||
"backgroundColor": "#ffffff",
|
|
||||||
"flex": 1,
|
"flex": 1,
|
||||||
"flexDirection": "column",
|
"flexDirection": "column",
|
||||||
"marginLeft": 10,
|
|
||||||
"marginRight": 10,
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -61,100 +58,249 @@ exports[`PostTextBox should match, full snapshot 1`] = `
|
|||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"color": "#3d3c40",
|
"color": "#3d3c40",
|
||||||
"fontSize": 14,
|
"fontSize": 16,
|
||||||
|
"lineHeight": 20,
|
||||||
"maxHeight": 150,
|
"maxHeight": 150,
|
||||||
"paddingBottom": 8,
|
"minHeight": 38,
|
||||||
"paddingLeft": 12,
|
"paddingBottom": 6,
|
||||||
"paddingRight": 12,
|
"paddingHorizontal": 12,
|
||||||
"paddingTop": 8,
|
"paddingTop": 12,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
underlineColorAndroid="transparent"
|
underlineColorAndroid="transparent"
|
||||||
value=""
|
value=""
|
||||||
/>
|
/>
|
||||||
<Connect(FileUploadPreview)
|
<React.Fragment>
|
||||||
files={Array []}
|
<Connect(FileUploadPreview)
|
||||||
rootId=""
|
files={Array []}
|
||||||
/>
|
rootId=""
|
||||||
<View
|
/>
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"alignItems": "center",
|
|
||||||
"display": "flex",
|
|
||||||
"flexDirection": "row",
|
|
||||||
"justifyContent": "space-between",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<View
|
<View
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
|
"alignItems": "center",
|
||||||
"display": "flex",
|
"display": "flex",
|
||||||
"flexDirection": "row",
|
"flexDirection": "row",
|
||||||
|
"justifyContent": "space-between",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<TouchableOpacity
|
<View
|
||||||
activeOpacity={0.2}
|
|
||||||
disabled={false}
|
|
||||||
onPress={[Function]}
|
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"paddingLeft": 10,
|
"display": "flex",
|
||||||
"paddingRight": 10,
|
"flexDirection": "row",
|
||||||
|
"height": 44,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Icon
|
<TouchableOpacity
|
||||||
allowFontScaling={false}
|
activeOpacity={0.2}
|
||||||
color="#3d3c40"
|
disabled={false}
|
||||||
name="at"
|
onPress={[Function]}
|
||||||
size={20}
|
style={
|
||||||
/>
|
|
||||||
</TouchableOpacity>
|
|
||||||
<TouchableOpacity
|
|
||||||
activeOpacity={0.2}
|
|
||||||
disabled={false}
|
|
||||||
onPress={[Function]}
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"paddingLeft": 10,
|
|
||||||
"paddingRight": 10,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Image
|
|
||||||
source={
|
|
||||||
Object {
|
Object {
|
||||||
"testUri": "../../../dist/assets/images/icons/slash-forward-box.png",
|
"alignItems": "center",
|
||||||
|
"justifyContent": "center",
|
||||||
|
"padding": 10,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
allowFontScaling={false}
|
||||||
|
color="rgba(61,60,64,0.64)"
|
||||||
|
name="at"
|
||||||
|
size={24}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
activeOpacity={0.2}
|
||||||
|
disabled={false}
|
||||||
|
onPress={[Function]}
|
||||||
style={
|
style={
|
||||||
Array [
|
Object {
|
||||||
|
"alignItems": "center",
|
||||||
|
"justifyContent": "center",
|
||||||
|
"padding": 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
source={
|
||||||
Object {
|
Object {
|
||||||
"height": 20,
|
"testUri": "../../../dist/assets/images/icons/slash-forward-box.png",
|
||||||
"opacity": 1,
|
}
|
||||||
"tintColor": "#3d3c40",
|
}
|
||||||
"width": 20,
|
style={
|
||||||
},
|
Array [
|
||||||
]
|
Object {
|
||||||
|
"height": 24,
|
||||||
|
"opacity": 1,
|
||||||
|
"tintColor": "rgba(61,60,64,0.64)",
|
||||||
|
"width": 24,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<FileUploadButton
|
||||||
|
blurTextBox={[Function]}
|
||||||
|
browseFileTypes="public.item"
|
||||||
|
buttonContainerStyle={
|
||||||
|
Object {
|
||||||
|
"alignItems": "center",
|
||||||
|
"justifyContent": "center",
|
||||||
|
"padding": 10,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
canBrowseFiles={true}
|
||||||
|
canBrowsePhotoLibrary={true}
|
||||||
|
canBrowseVideoLibrary={true}
|
||||||
|
canTakePhoto={true}
|
||||||
|
canTakeVideo={true}
|
||||||
|
extraOptions={null}
|
||||||
|
fileCount={0}
|
||||||
|
maxFileCount={5}
|
||||||
|
maxFileSize={1024}
|
||||||
|
onShowFileMaxWarning={[Function]}
|
||||||
|
onShowFileSizeWarning={[Function]}
|
||||||
|
theme={
|
||||||
|
Object {
|
||||||
|
"awayIndicator": "#ffbc42",
|
||||||
|
"buttonBg": "#166de0",
|
||||||
|
"buttonColor": "#ffffff",
|
||||||
|
"centerChannelBg": "#ffffff",
|
||||||
|
"centerChannelColor": "#3d3c40",
|
||||||
|
"codeTheme": "github",
|
||||||
|
"dndIndicator": "#f74343",
|
||||||
|
"errorTextColor": "#fd5960",
|
||||||
|
"linkColor": "#2389d7",
|
||||||
|
"mentionBg": "#ffffff",
|
||||||
|
"mentionBj": "#ffffff",
|
||||||
|
"mentionColor": "#145dbf",
|
||||||
|
"mentionHighlightBg": "#ffe577",
|
||||||
|
"mentionHighlightLink": "#166de0",
|
||||||
|
"newMessageSeparator": "#ff8800",
|
||||||
|
"onlineIndicator": "#06d6a0",
|
||||||
|
"sidebarBg": "#145dbf",
|
||||||
|
"sidebarHeaderBg": "#1153ab",
|
||||||
|
"sidebarHeaderTextColor": "#ffffff",
|
||||||
|
"sidebarText": "#ffffff",
|
||||||
|
"sidebarTextActiveBorder": "#579eff",
|
||||||
|
"sidebarTextActiveColor": "#ffffff",
|
||||||
|
"sidebarTextHoverBg": "#4578bf",
|
||||||
|
"sidebarUnreadText": "#ffffff",
|
||||||
|
"type": "Mattermost",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uploadFiles={[Function]}
|
||||||
|
validMimeTypes={Array []}
|
||||||
/>
|
/>
|
||||||
</TouchableOpacity>
|
<ImageUploadButton
|
||||||
<FileUploadButton
|
blurTextBox={[Function]}
|
||||||
blurTextBox={[Function]}
|
browseFileTypes="public.item"
|
||||||
browseFileTypes="public.item"
|
buttonContainerStyle={
|
||||||
canBrowseFiles={true}
|
Object {
|
||||||
canBrowsePhotoLibrary={true}
|
"alignItems": "center",
|
||||||
canBrowseVideoLibrary={true}
|
"justifyContent": "center",
|
||||||
canTakePhoto={true}
|
"padding": 10,
|
||||||
canTakeVideo={true}
|
}
|
||||||
extraOptions={null}
|
}
|
||||||
fileCount={0}
|
canBrowseFiles={true}
|
||||||
maxFileCount={5}
|
canBrowsePhotoLibrary={true}
|
||||||
maxFileSize={1024}
|
canBrowseVideoLibrary={true}
|
||||||
onShowFileMaxWarning={[Function]}
|
canTakePhoto={true}
|
||||||
onShowFileSizeWarning={[Function]}
|
canTakeVideo={true}
|
||||||
|
extraOptions={null}
|
||||||
|
fileCount={0}
|
||||||
|
maxFileCount={5}
|
||||||
|
maxFileSize={1024}
|
||||||
|
onShowFileMaxWarning={[Function]}
|
||||||
|
onShowFileSizeWarning={[Function]}
|
||||||
|
theme={
|
||||||
|
Object {
|
||||||
|
"awayIndicator": "#ffbc42",
|
||||||
|
"buttonBg": "#166de0",
|
||||||
|
"buttonColor": "#ffffff",
|
||||||
|
"centerChannelBg": "#ffffff",
|
||||||
|
"centerChannelColor": "#3d3c40",
|
||||||
|
"codeTheme": "github",
|
||||||
|
"dndIndicator": "#f74343",
|
||||||
|
"errorTextColor": "#fd5960",
|
||||||
|
"linkColor": "#2389d7",
|
||||||
|
"mentionBg": "#ffffff",
|
||||||
|
"mentionBj": "#ffffff",
|
||||||
|
"mentionColor": "#145dbf",
|
||||||
|
"mentionHighlightBg": "#ffe577",
|
||||||
|
"mentionHighlightLink": "#166de0",
|
||||||
|
"newMessageSeparator": "#ff8800",
|
||||||
|
"onlineIndicator": "#06d6a0",
|
||||||
|
"sidebarBg": "#145dbf",
|
||||||
|
"sidebarHeaderBg": "#1153ab",
|
||||||
|
"sidebarHeaderTextColor": "#ffffff",
|
||||||
|
"sidebarText": "#ffffff",
|
||||||
|
"sidebarTextActiveBorder": "#579eff",
|
||||||
|
"sidebarTextActiveColor": "#ffffff",
|
||||||
|
"sidebarTextHoverBg": "#4578bf",
|
||||||
|
"sidebarUnreadText": "#ffffff",
|
||||||
|
"type": "Mattermost",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uploadFiles={[Function]}
|
||||||
|
validMimeTypes={Array []}
|
||||||
|
/>
|
||||||
|
<AttachmentButton
|
||||||
|
blurTextBox={[Function]}
|
||||||
|
buttonContainerStyle={
|
||||||
|
Object {
|
||||||
|
"alignItems": "center",
|
||||||
|
"justifyContent": "center",
|
||||||
|
"padding": 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
canTakePhoto={true}
|
||||||
|
canTakeVideo={true}
|
||||||
|
fileCount={0}
|
||||||
|
maxFileCount={5}
|
||||||
|
maxFileSize={1024}
|
||||||
|
onShowFileMaxWarning={[Function]}
|
||||||
|
onShowFileSizeWarning={[Function]}
|
||||||
|
theme={
|
||||||
|
Object {
|
||||||
|
"awayIndicator": "#ffbc42",
|
||||||
|
"buttonBg": "#166de0",
|
||||||
|
"buttonColor": "#ffffff",
|
||||||
|
"centerChannelBg": "#ffffff",
|
||||||
|
"centerChannelColor": "#3d3c40",
|
||||||
|
"codeTheme": "github",
|
||||||
|
"dndIndicator": "#f74343",
|
||||||
|
"errorTextColor": "#fd5960",
|
||||||
|
"linkColor": "#2389d7",
|
||||||
|
"mentionBg": "#ffffff",
|
||||||
|
"mentionBj": "#ffffff",
|
||||||
|
"mentionColor": "#145dbf",
|
||||||
|
"mentionHighlightBg": "#ffe577",
|
||||||
|
"mentionHighlightLink": "#166de0",
|
||||||
|
"newMessageSeparator": "#ff8800",
|
||||||
|
"onlineIndicator": "#06d6a0",
|
||||||
|
"sidebarBg": "#145dbf",
|
||||||
|
"sidebarHeaderBg": "#1153ab",
|
||||||
|
"sidebarHeaderTextColor": "#ffffff",
|
||||||
|
"sidebarText": "#ffffff",
|
||||||
|
"sidebarTextActiveBorder": "#579eff",
|
||||||
|
"sidebarTextActiveColor": "#ffffff",
|
||||||
|
"sidebarTextHoverBg": "#4578bf",
|
||||||
|
"sidebarUnreadText": "#ffffff",
|
||||||
|
"type": "Mattermost",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uploadFiles={[Function]}
|
||||||
|
validMimeTypes={Array []}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<SendButton
|
||||||
|
disabled={true}
|
||||||
|
handleSendMessage={[Function]}
|
||||||
theme={
|
theme={
|
||||||
Object {
|
Object {
|
||||||
"awayIndicator": "#ffbc42",
|
"awayIndicator": "#ffbc42",
|
||||||
@@ -184,131 +330,9 @@ exports[`PostTextBox should match, full snapshot 1`] = `
|
|||||||
"type": "Mattermost",
|
"type": "Mattermost",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uploadFiles={[Function]}
|
|
||||||
validMimeTypes={Array []}
|
|
||||||
/>
|
|
||||||
<ImageUploadButton
|
|
||||||
blurTextBox={[Function]}
|
|
||||||
browseFileTypes="public.item"
|
|
||||||
canBrowseFiles={true}
|
|
||||||
canBrowsePhotoLibrary={true}
|
|
||||||
canBrowseVideoLibrary={true}
|
|
||||||
canTakePhoto={true}
|
|
||||||
canTakeVideo={true}
|
|
||||||
extraOptions={null}
|
|
||||||
fileCount={0}
|
|
||||||
maxFileCount={5}
|
|
||||||
maxFileSize={1024}
|
|
||||||
onShowFileMaxWarning={[Function]}
|
|
||||||
onShowFileSizeWarning={[Function]}
|
|
||||||
theme={
|
|
||||||
Object {
|
|
||||||
"awayIndicator": "#ffbc42",
|
|
||||||
"buttonBg": "#166de0",
|
|
||||||
"buttonColor": "#ffffff",
|
|
||||||
"centerChannelBg": "#ffffff",
|
|
||||||
"centerChannelColor": "#3d3c40",
|
|
||||||
"codeTheme": "github",
|
|
||||||
"dndIndicator": "#f74343",
|
|
||||||
"errorTextColor": "#fd5960",
|
|
||||||
"linkColor": "#2389d7",
|
|
||||||
"mentionBg": "#ffffff",
|
|
||||||
"mentionBj": "#ffffff",
|
|
||||||
"mentionColor": "#145dbf",
|
|
||||||
"mentionHighlightBg": "#ffe577",
|
|
||||||
"mentionHighlightLink": "#166de0",
|
|
||||||
"newMessageSeparator": "#ff8800",
|
|
||||||
"onlineIndicator": "#06d6a0",
|
|
||||||
"sidebarBg": "#145dbf",
|
|
||||||
"sidebarHeaderBg": "#1153ab",
|
|
||||||
"sidebarHeaderTextColor": "#ffffff",
|
|
||||||
"sidebarText": "#ffffff",
|
|
||||||
"sidebarTextActiveBorder": "#579eff",
|
|
||||||
"sidebarTextActiveColor": "#ffffff",
|
|
||||||
"sidebarTextHoverBg": "#4578bf",
|
|
||||||
"sidebarUnreadText": "#ffffff",
|
|
||||||
"type": "Mattermost",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uploadFiles={[Function]}
|
|
||||||
validMimeTypes={Array []}
|
|
||||||
/>
|
|
||||||
<AttachmentButton
|
|
||||||
blurTextBox={[Function]}
|
|
||||||
canTakePhoto={true}
|
|
||||||
canTakeVideo={true}
|
|
||||||
fileCount={0}
|
|
||||||
maxFileCount={5}
|
|
||||||
maxFileSize={1024}
|
|
||||||
onShowFileMaxWarning={[Function]}
|
|
||||||
onShowFileSizeWarning={[Function]}
|
|
||||||
theme={
|
|
||||||
Object {
|
|
||||||
"awayIndicator": "#ffbc42",
|
|
||||||
"buttonBg": "#166de0",
|
|
||||||
"buttonColor": "#ffffff",
|
|
||||||
"centerChannelBg": "#ffffff",
|
|
||||||
"centerChannelColor": "#3d3c40",
|
|
||||||
"codeTheme": "github",
|
|
||||||
"dndIndicator": "#f74343",
|
|
||||||
"errorTextColor": "#fd5960",
|
|
||||||
"linkColor": "#2389d7",
|
|
||||||
"mentionBg": "#ffffff",
|
|
||||||
"mentionBj": "#ffffff",
|
|
||||||
"mentionColor": "#145dbf",
|
|
||||||
"mentionHighlightBg": "#ffe577",
|
|
||||||
"mentionHighlightLink": "#166de0",
|
|
||||||
"newMessageSeparator": "#ff8800",
|
|
||||||
"onlineIndicator": "#06d6a0",
|
|
||||||
"sidebarBg": "#145dbf",
|
|
||||||
"sidebarHeaderBg": "#1153ab",
|
|
||||||
"sidebarHeaderTextColor": "#ffffff",
|
|
||||||
"sidebarText": "#ffffff",
|
|
||||||
"sidebarTextActiveBorder": "#579eff",
|
|
||||||
"sidebarTextActiveColor": "#ffffff",
|
|
||||||
"sidebarTextHoverBg": "#4578bf",
|
|
||||||
"sidebarUnreadText": "#ffffff",
|
|
||||||
"type": "Mattermost",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uploadFiles={[Function]}
|
|
||||||
validMimeTypes={Array []}
|
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<SendButton
|
</React.Fragment>
|
||||||
disabled={true}
|
|
||||||
handleSendMessage={[Function]}
|
|
||||||
theme={
|
|
||||||
Object {
|
|
||||||
"awayIndicator": "#ffbc42",
|
|
||||||
"buttonBg": "#166de0",
|
|
||||||
"buttonColor": "#ffffff",
|
|
||||||
"centerChannelBg": "#ffffff",
|
|
||||||
"centerChannelColor": "#3d3c40",
|
|
||||||
"codeTheme": "github",
|
|
||||||
"dndIndicator": "#f74343",
|
|
||||||
"errorTextColor": "#fd5960",
|
|
||||||
"linkColor": "#2389d7",
|
|
||||||
"mentionBg": "#ffffff",
|
|
||||||
"mentionBj": "#ffffff",
|
|
||||||
"mentionColor": "#145dbf",
|
|
||||||
"mentionHighlightBg": "#ffe577",
|
|
||||||
"mentionHighlightLink": "#166de0",
|
|
||||||
"newMessageSeparator": "#ff8800",
|
|
||||||
"onlineIndicator": "#06d6a0",
|
|
||||||
"sidebarBg": "#145dbf",
|
|
||||||
"sidebarHeaderBg": "#1153ab",
|
|
||||||
"sidebarHeaderTextColor": "#ffffff",
|
|
||||||
"sidebarText": "#ffffff",
|
|
||||||
"sidebarTextActiveBorder": "#579eff",
|
|
||||||
"sidebarTextActiveColor": "#ffffff",
|
|
||||||
"sidebarTextHoverBg": "#4578bf",
|
|
||||||
"sidebarUnreadText": "#ffffff",
|
|
||||||
"type": "Mattermost",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</View>
|
</View>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ export default class AttachmentButton extends PureComponent {
|
|||||||
if (Platform.OS === 'ios') {
|
if (Platform.OS === 'ios') {
|
||||||
const {formatMessage} = this.context.intl;
|
const {formatMessage} = this.context.intl;
|
||||||
let permissionRequest;
|
let permissionRequest;
|
||||||
const targetSource = 'camera';
|
const targetSource = Permissions.PERMISSIONS.IOS.CAMERA;
|
||||||
const hasPermissionToStorage = await Permissions.check(targetSource);
|
const hasPermissionToStorage = await Permissions.check(targetSource);
|
||||||
|
|
||||||
switch (hasPermissionToStorage) {
|
switch (hasPermissionToStorage) {
|
||||||
|
|||||||
@@ -96,11 +96,12 @@ export default class FileUploadButton extends PureComponent {
|
|||||||
if (Platform.OS === 'android') {
|
if (Platform.OS === 'android') {
|
||||||
const {formatMessage} = this.context.intl;
|
const {formatMessage} = this.context.intl;
|
||||||
let permissionRequest;
|
let permissionRequest;
|
||||||
const hasPermissionToStorage = await Permissions.check('storage');
|
const storagePermission = Permissions.PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE;
|
||||||
|
const hasPermissionToStorage = await Permissions.check(storagePermission);
|
||||||
|
|
||||||
switch (hasPermissionToStorage) {
|
switch (hasPermissionToStorage) {
|
||||||
case Permissions.RESULTS.UNAVAILABLE:
|
case Permissions.RESULTS.UNAVAILABLE:
|
||||||
permissionRequest = await Permissions.request('storage');
|
permissionRequest = await Permissions.request(storagePermission);
|
||||||
if (permissionRequest !== Permissions.RESULTS.AUTHORIZED) {
|
if (permissionRequest !== Permissions.RESULTS.AUTHORIZED) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ export default class ImageUploadButton extends PureComponent {
|
|||||||
if (Platform.OS === 'ios') {
|
if (Platform.OS === 'ios') {
|
||||||
const {formatMessage} = this.context.intl;
|
const {formatMessage} = this.context.intl;
|
||||||
let permissionRequest;
|
let permissionRequest;
|
||||||
const targetSource = 'photo';
|
const targetSource = Permissions.PERMISSIONS.IOS.PHOTO_LIBRARY;
|
||||||
const hasPermissionToStorage = await Permissions.check(targetSource);
|
const hasPermissionToStorage = await Permissions.check(targetSource);
|
||||||
|
|
||||||
switch (hasPermissionToStorage) {
|
switch (hasPermissionToStorage) {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
View,
|
View,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import {intlShape} from 'react-intl';
|
import {intlShape} from 'react-intl';
|
||||||
|
import RNFetchBlob from 'rn-fetch-blob';
|
||||||
import Button from 'react-native-button';
|
import Button from 'react-native-button';
|
||||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||||
import slashForwardBoxIcon from 'assets/images/icons/slash-forward-box.png';
|
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 PasteableTextInput from 'app/components/pasteable_text_input';
|
||||||
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
|
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
|
||||||
import SendButton from 'app/components/send_button';
|
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 {NOTIFY_ALL_MEMBERS} from 'app/constants/view';
|
||||||
import FileUploadPreview from 'app/components/file_upload_preview';
|
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) => {
|
getTextInputButton = (actionType) => {
|
||||||
const {channelIsReadOnly, theme} = this.props;
|
const {channelIsReadOnly, theme} = this.props;
|
||||||
const style = getStyleSheet(theme);
|
const style = getStyleSheet(theme);
|
||||||
|
|
||||||
let button = null;
|
let button = null;
|
||||||
const buttonStyle = [];
|
const buttonStyle = [];
|
||||||
let iconColor = theme.centerChannelColor;
|
let iconColor = changeOpacity(theme.centerChannelColor, 0.64);
|
||||||
let isDisabled = false;
|
let isDisabled = false;
|
||||||
|
|
||||||
if (!channelIsReadOnly) {
|
if (!channelIsReadOnly) {
|
||||||
@@ -253,21 +264,18 @@ export default class PostTextBoxBase extends PureComponent {
|
|||||||
case 'at':
|
case 'at':
|
||||||
isDisabled = this.state.value[this.state.value.length - 1] === '@';
|
isDisabled = this.state.value[this.state.value.length - 1] === '@';
|
||||||
if (isDisabled) {
|
if (isDisabled) {
|
||||||
iconColor = changeOpacity(theme.centerChannelColor, 0.6);
|
iconColor = changeOpacity(theme.centerChannelColor, 0.16);
|
||||||
}
|
}
|
||||||
button = (
|
button = (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
disabled={isDisabled}
|
disabled={isDisabled}
|
||||||
onPress={() => {
|
onPress={this.startAtMention}
|
||||||
this.handleTextChange(`${this.state.value}@`, true);
|
|
||||||
this.focus();
|
|
||||||
}}
|
|
||||||
style={style.iconWrapper}
|
style={style.iconWrapper}
|
||||||
>
|
>
|
||||||
<MaterialCommunityIcons
|
<MaterialCommunityIcons
|
||||||
color={iconColor}
|
color={iconColor}
|
||||||
name='at'
|
name='at'
|
||||||
size={20}
|
size={ICON_SIZE}
|
||||||
/>
|
/>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
);
|
);
|
||||||
@@ -282,10 +290,7 @@ export default class PostTextBoxBase extends PureComponent {
|
|||||||
button = (
|
button = (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
disabled={isDisabled}
|
disabled={isDisabled}
|
||||||
onPress={() => {
|
onPress={this.startSlashCommand}
|
||||||
this.handleTextChange('/', true);
|
|
||||||
this.focus();
|
|
||||||
}}
|
|
||||||
style={style.iconWrapper}
|
style={style.iconWrapper}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
@@ -303,6 +308,7 @@ export default class PostTextBoxBase extends PureComponent {
|
|||||||
|
|
||||||
getMediaButton = (actionType) => {
|
getMediaButton = (actionType) => {
|
||||||
const {canUploadFiles, channelIsReadOnly, files, maxFileSize, theme} = this.props;
|
const {canUploadFiles, channelIsReadOnly, files, maxFileSize, theme} = this.props;
|
||||||
|
const style = getStyleSheet(theme);
|
||||||
let button = null;
|
let button = null;
|
||||||
const props = {
|
const props = {
|
||||||
blurTextBox: this.blur,
|
blurTextBox: this.blur,
|
||||||
@@ -313,6 +319,7 @@ export default class PostTextBoxBase extends PureComponent {
|
|||||||
uploadFiles: this.handleUploadFiles,
|
uploadFiles: this.handleUploadFiles,
|
||||||
maxFileSize,
|
maxFileSize,
|
||||||
theme,
|
theme,
|
||||||
|
buttonContainerStyle: style.iconWrapper,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (canUploadFiles && !channelIsReadOnly) {
|
if (canUploadFiles && !channelIsReadOnly) {
|
||||||
@@ -504,8 +511,20 @@ export default class PostTextBoxBase extends PureComponent {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleUploadFiles = (files) => {
|
handleUploadFiles = async (files) => {
|
||||||
this.props.actions.initUploadFiles(files, this.props.rootId);
|
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 = () => {
|
isFileLoading = () => {
|
||||||
@@ -722,7 +741,7 @@ export default class PostTextBoxBase extends PureComponent {
|
|||||||
EventEmitter.emit('fileSizeWarning', fileSizeWarning);
|
EventEmitter.emit('fileSizeWarning', fileSizeWarning);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
EventEmitter.emit('fileSizeWarning', null);
|
EventEmitter.emit('fileSizeWarning', null);
|
||||||
}, 3000);
|
}, 5000);
|
||||||
};
|
};
|
||||||
|
|
||||||
onCloseChannelPress = () => {
|
onCloseChannelPress = () => {
|
||||||
@@ -835,6 +854,12 @@ export default class PostTextBoxBase extends PureComponent {
|
|||||||
const textValue = channelIsLoading ? '' : value;
|
const textValue = channelIsLoading ? '' : value;
|
||||||
const placeholder = this.getPlaceHolder();
|
const placeholder = this.getPlaceHolder();
|
||||||
|
|
||||||
|
let maxHeight = 150;
|
||||||
|
|
||||||
|
if (isLandscape) {
|
||||||
|
maxHeight = 88;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
style={[style.inputWrapper, padding(isLandscape)]}
|
style={[style.inputWrapper, padding(isLandscape)]}
|
||||||
@@ -861,7 +886,7 @@ export default class PostTextBoxBase extends PureComponent {
|
|||||||
multiline={true}
|
multiline={true}
|
||||||
blurOnSubmit={false}
|
blurOnSubmit={false}
|
||||||
underlineColorAndroid='transparent'
|
underlineColorAndroid='transparent'
|
||||||
style={style.input}
|
style={{...style.input, maxHeight}}
|
||||||
keyboardType={this.state.keyboardType}
|
keyboardType={this.state.keyboardType}
|
||||||
onEndEditing={this.handleEndEditing}
|
onEndEditing={this.handleEndEditing}
|
||||||
disableFullscreenUI={true}
|
disableFullscreenUI={true}
|
||||||
@@ -869,32 +894,35 @@ export default class PostTextBoxBase extends PureComponent {
|
|||||||
onPaste={this.handlePasteFiles}
|
onPaste={this.handlePasteFiles}
|
||||||
keyboardAppearance={getKeyboardAppearanceFromTheme(theme)}
|
keyboardAppearance={getKeyboardAppearanceFromTheme(theme)}
|
||||||
/>
|
/>
|
||||||
|
{!channelIsReadOnly &&
|
||||||
<FileUploadPreview
|
<React.Fragment>
|
||||||
files={files}
|
<FileUploadPreview
|
||||||
rootId={rootId}
|
files={files}
|
||||||
/>
|
rootId={rootId}
|
||||||
|
|
||||||
<View style={style.buttonsContainer}>
|
|
||||||
<View style={style.quickActionsContainer}>
|
|
||||||
|
|
||||||
{this.getTextInputButton('at')}
|
|
||||||
|
|
||||||
{this.getTextInputButton('slash')}
|
|
||||||
|
|
||||||
{this.getMediaButton('file')}
|
|
||||||
|
|
||||||
{this.getMediaButton('image')}
|
|
||||||
|
|
||||||
{this.getMediaButton('camera')}
|
|
||||||
|
|
||||||
</View>
|
|
||||||
<SendButton
|
|
||||||
disabled={!this.isSendButtonEnabled()}
|
|
||||||
handleSendMessage={this.handleSendMessage}
|
|
||||||
theme={theme}
|
|
||||||
/>
|
/>
|
||||||
</View>
|
|
||||||
|
<View style={style.buttonsContainer}>
|
||||||
|
<View style={style.quickActionsContainer}>
|
||||||
|
|
||||||
|
{this.getTextInputButton('at')}
|
||||||
|
|
||||||
|
{this.getTextInputButton('slash')}
|
||||||
|
|
||||||
|
{this.getMediaButton('file')}
|
||||||
|
|
||||||
|
{this.getMediaButton('image')}
|
||||||
|
|
||||||
|
{this.getMediaButton('camera')}
|
||||||
|
|
||||||
|
</View>
|
||||||
|
<SendButton
|
||||||
|
disabled={!this.isSendButtonEnabled()}
|
||||||
|
handleSendMessage={this.handleSendMessage}
|
||||||
|
theme={theme}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</React.Fragment>
|
||||||
|
}
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
@@ -910,37 +938,36 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
slashIcon: {
|
slashIcon: {
|
||||||
width: 20,
|
width: ICON_SIZE,
|
||||||
height: 20,
|
height: ICON_SIZE,
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
tintColor: theme.centerChannelColor,
|
tintColor: changeOpacity(theme.centerChannelColor, 0.64),
|
||||||
},
|
},
|
||||||
iconDisabled: {
|
iconDisabled: {
|
||||||
tintColor: changeOpacity(theme.centerChannelColor, 0.6),
|
tintColor: changeOpacity(theme.centerChannelColor, 0.16),
|
||||||
},
|
},
|
||||||
iconWrapper: {
|
iconWrapper: {
|
||||||
paddingLeft: 10,
|
alignItems: 'center',
|
||||||
paddingRight: 10,
|
justifyContent: 'center',
|
||||||
|
padding: 10,
|
||||||
},
|
},
|
||||||
quickActionsContainer: {
|
quickActionsContainer: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
|
height: 44,
|
||||||
},
|
},
|
||||||
input: {
|
input: {
|
||||||
color: theme.centerChannelColor,
|
color: theme.centerChannelColor,
|
||||||
fontSize: 14,
|
fontSize: 16,
|
||||||
paddingBottom: 8,
|
lineHeight: 20,
|
||||||
paddingLeft: 12,
|
paddingHorizontal: 12,
|
||||||
paddingRight: 12,
|
paddingTop: 12,
|
||||||
paddingTop: 8,
|
paddingBottom: 6,
|
||||||
maxHeight: 150,
|
minHeight: 38,
|
||||||
},
|
},
|
||||||
inputContainer: {
|
inputContainer: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
backgroundColor: theme.centerChannelBg,
|
|
||||||
marginRight: 10,
|
|
||||||
marginLeft: 10,
|
|
||||||
},
|
},
|
||||||
inputContentContainer: {
|
inputContentContainer: {
|
||||||
alignItems: 'stretch',
|
alignItems: 'stretch',
|
||||||
@@ -949,7 +976,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||||||
alignItems: 'flex-end',
|
alignItems: 'flex-end',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
paddingVertical: 4,
|
paddingBottom: 8,
|
||||||
backgroundColor: theme.centerChannelBg,
|
backgroundColor: theme.centerChannelBg,
|
||||||
borderTopWidth: 1,
|
borderTopWidth: 1,
|
||||||
borderTopColor: changeOpacity(theme.centerChannelColor, 0.20),
|
borderTopColor: changeOpacity(theme.centerChannelColor, 0.20),
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import React, {memo} from 'react';
|
import React, {memo} from 'react';
|
||||||
import {Platform, View} from 'react-native';
|
import {View} from 'react-native';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
|
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
|
||||||
@@ -18,19 +18,15 @@ function SendButton(props) {
|
|||||||
PaperPlane = require('app/components/paper_plane').default;
|
PaperPlane = require('app/components/paper_plane').default;
|
||||||
}
|
}
|
||||||
|
|
||||||
const icon = (
|
|
||||||
<PaperPlane
|
|
||||||
height={13}
|
|
||||||
width={15}
|
|
||||||
color={theme.buttonColor}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (props.disabled) {
|
if (props.disabled) {
|
||||||
return (
|
return (
|
||||||
<View style={style.sendButtonContainer}>
|
<View style={style.sendButtonContainer}>
|
||||||
<View style={[style.sendButton, style.disableButton]}>
|
<View style={[style.sendButton, style.disableButton]}>
|
||||||
{icon}
|
<PaperPlane
|
||||||
|
height={16}
|
||||||
|
width={19}
|
||||||
|
color={changeOpacity(theme.buttonColor, 0.5)}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
@@ -43,7 +39,11 @@ function SendButton(props) {
|
|||||||
type={'opacity'}
|
type={'opacity'}
|
||||||
>
|
>
|
||||||
<View style={style.sendButton}>
|
<View style={style.sendButton}>
|
||||||
{icon}
|
<PaperPlane
|
||||||
|
height={16}
|
||||||
|
width={19}
|
||||||
|
color={theme.buttonColor}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
</TouchableWithFeedback>
|
</TouchableWithFeedback>
|
||||||
);
|
);
|
||||||
@@ -62,20 +62,15 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||||||
},
|
},
|
||||||
sendButtonContainer: {
|
sendButtonContainer: {
|
||||||
justifyContent: 'flex-end',
|
justifyContent: 'flex-end',
|
||||||
paddingHorizontal: 5,
|
paddingRight: 8,
|
||||||
paddingVertical: Platform.select({
|
|
||||||
android: 8,
|
|
||||||
ios: 2,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
sendButton: {
|
sendButton: {
|
||||||
backgroundColor: theme.buttonBg,
|
backgroundColor: theme.buttonBg,
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
height: 28,
|
height: 32,
|
||||||
width: 72,
|
width: 80,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
paddingLeft: 3,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,3 +5,4 @@ export const MAX_FILE_COUNT = 5;
|
|||||||
export const IS_REACTION_REGEX = /(^\+:([^:\s]*):)$/i;
|
export const IS_REACTION_REGEX = /(^\+:([^:\s]*):)$/i;
|
||||||
export const INSERT_TO_DRAFT = 'insert_to_draft';
|
export const INSERT_TO_DRAFT = 'insert_to_draft';
|
||||||
export const INSERT_TO_COMMENT = 'insert_to_comment';
|
export const INSERT_TO_COMMENT = 'insert_to_comment';
|
||||||
|
export const ICON_SIZE = 24;
|
||||||
@@ -121,6 +121,7 @@ export default {
|
|||||||
NotificationLevels,
|
NotificationLevels,
|
||||||
SidebarSectionTypes,
|
SidebarSectionTypes,
|
||||||
IOS_HORIZONTAL_LANDSCAPE: 44,
|
IOS_HORIZONTAL_LANDSCAPE: 44,
|
||||||
INPUT_LINE_HEIGHT: 17,
|
INPUT_LINE_HEIGHT: 20,
|
||||||
INPUT_VERTICAL_PADDING: 16,
|
INPUT_VERTICAL_PADDING: 18,
|
||||||
|
INPUT_INITIAL_HEIGHT: 38,
|
||||||
};
|
};
|
||||||
|
|||||||
1
index.js
1
index.js
@@ -18,6 +18,7 @@ if (Platform.OS === 'android') {
|
|||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
YellowBox.ignoreWarnings([
|
YellowBox.ignoreWarnings([
|
||||||
'Warning: componentWillReceiveProps',
|
'Warning: componentWillReceiveProps',
|
||||||
|
'`-[RCTRootView cancelTouches]`',
|
||||||
|
|
||||||
// Hide warnings caused by React Native (https://github.com/facebook/react-native/issues/20841)
|
// Hide warnings caused by React Native (https://github.com/facebook/react-native/issues/20841)
|
||||||
'Require cycle: node_modules/react-native/Libraries/Network/fetch.js',
|
'Require cycle: node_modules/react-native/Libraries/Network/fetch.js',
|
||||||
|
|||||||
Reference in New Issue
Block a user