mirror of
https://github.com/zhigang1992/react-native-gifted-chat.git
synced 2026-04-29 04:35:46 +08:00
fix android keyboard
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
TODO.md
|
||||
__tests__
|
||||
|
||||
11
README.md
11
README.md
@@ -4,6 +4,16 @@ The most complete chat UI for React Native (formerly known as Gifted Messenger)
|
||||
## Installation
|
||||
- `npm install react-native-gifted-chat --save`
|
||||
|
||||
## Android installation
|
||||
- Add `windowSoftInputMode` in your Android Manifest `android/app/src/main/AndroidManifest.xml`
|
||||
```
|
||||
<!-- ... -->
|
||||
android:label="@string/app_name"
|
||||
android:windowSoftInputMode="adjustResize" // <!-- add this -->
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
|
||||
<!-- ... -->
|
||||
```
|
||||
|
||||
## Minimal example
|
||||
```jsx
|
||||
import React, { Component } from 'react';
|
||||
@@ -88,6 +98,7 @@ See [example project](example/Example.js)
|
||||
### Send
|
||||
### Loading
|
||||
|
||||
|
||||
## LICENSE
|
||||
- [MIT](LICENSE)
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node_modules/react-native/packager/packager.sh",
|
||||
"sync": "rm -rf ./node_modules/react-native-gifted-chat; sane '/usr/bin/rsync -v -a --exclude .git --exclude example --exclude node_modules ../ ./node_modules/react-native-gifted-chat/' .. --glob='{**/*.json,**/*.js}'"
|
||||
"sync": "rm -rf ./node_modules/react-native-gifted-chat; sane '/usr/bin/rsync -v -a --exclude .git --exclude example --exclude __tests__ --exclude node_modules ../ ./node_modules/react-native-gifted-chat/' .. --glob='{**/*.json,**/*.js}'"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "15.2.1",
|
||||
@@ -12,7 +12,7 @@
|
||||
"react-native-gifted-chat": "file:../"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^3.1.1",
|
||||
"eslint": "^3.2.0",
|
||||
"eslint-plugin-react": "^5.2.2",
|
||||
"eslint-plugin-react-native": "^1.2.0",
|
||||
"sane": "^1.4.0"
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
"description": "The most complete chat UI for React Native",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"test": "jest"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "jest-react-native"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -42,7 +45,6 @@
|
||||
"moment": "^2.13.0",
|
||||
"react-native-communications": "^2.0.0",
|
||||
"react-native-dismiss-keyboard": "^1.0.0",
|
||||
"react-native-gifted-material": "file:./react-native-gifted-material/",
|
||||
"react-native-invertible-scroll-view": "^1.0.0",
|
||||
"react-native-parsed-text": "0.0.15"
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"plugins": [
|
||||
"react",
|
||||
"react-native"
|
||||
],
|
||||
"extends": ["eslint:recommended", "plugin:react/recommended"],
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
"ecmaFeatures" : {
|
||||
experimentalObjectRestSpread: true
|
||||
}
|
||||
},
|
||||
"env": {
|
||||
"node": true
|
||||
}
|
||||
}
|
||||
1
react-native-gifted-material/.gitignore
vendored
1
react-native-gifted-material/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
TODO.md
|
||||
@@ -1 +0,0 @@
|
||||
TODO.md
|
||||
55
react-native-gifted-material/components/List.js
vendored
55
react-native-gifted-material/components/List.js
vendored
@@ -1,55 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
ListView,
|
||||
} from 'react-native';
|
||||
|
||||
import ListRow from './ListRow';
|
||||
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
|
||||
this.state = {
|
||||
dataSource: ds.cloneWithRows([]),
|
||||
};
|
||||
this.renderRow = this.renderRow.bind(this);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.updateListView(this.props);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.updateListView(nextProps);
|
||||
}
|
||||
|
||||
updateListView(props) {
|
||||
if (props.rows) {
|
||||
this.setState({
|
||||
dataSource: this.state.dataSource.cloneWithRows(props.rows),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
renderRow(row = {}) {
|
||||
if (this.props.renderRow) {
|
||||
return this.props.renderRow(row);
|
||||
}
|
||||
return (
|
||||
<ListRow
|
||||
primaryText={row.primaryText}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<ListView
|
||||
dataSource={this.state.dataSource}
|
||||
renderRow={this.renderRow}
|
||||
renderHeader={this.props.renderHeader}
|
||||
enableEmptySections={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
PixelRatio,
|
||||
TouchableHighlight,
|
||||
} from 'react-native';
|
||||
|
||||
export default class ListRow extends Component {
|
||||
renderRightIcon() {
|
||||
if (this.props.rightIcon) {
|
||||
return (
|
||||
<View style={styles.iconContainer}>
|
||||
{this.props.rightIcon()}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
renderLeftIcon() {
|
||||
if (this.props.leftIcon) {
|
||||
return (
|
||||
<View style={styles.iconContainer}>
|
||||
{this.props.leftIcon()}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<TouchableHighlight
|
||||
underlayColor={'#eee'}
|
||||
onPress={this.props.onPress}
|
||||
>
|
||||
<View style={styles.container}>
|
||||
{this.renderLeftIcon()}
|
||||
<View style={styles.textContainer}>
|
||||
<Text style={styles.primaryText}>
|
||||
{this.props.primaryText}
|
||||
</Text>
|
||||
<Text style={styles.secondaryText}>
|
||||
{this.props.secondaryText}
|
||||
</Text>
|
||||
</View>
|
||||
{this.renderRightIcon()}
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flexDirection: 'row',
|
||||
paddingTop: 10,
|
||||
paddingBottom: 10,
|
||||
alignItems: 'center',
|
||||
borderBottomWidth: 1 / PixelRatio.get(),
|
||||
borderColor: '#F8F8F8',
|
||||
},
|
||||
textContainer: {
|
||||
flex: 1,
|
||||
},
|
||||
primaryText: {
|
||||
fontSize: 12,
|
||||
marginBottom: 3,
|
||||
},
|
||||
secondaryText: {
|
||||
fontSize: 11,
|
||||
color: '#8D8D8D',
|
||||
},
|
||||
iconContainer: {
|
||||
height: 30,
|
||||
width: 30,
|
||||
borderRadius: 15,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginLeft: 10,
|
||||
marginRight: 10,
|
||||
backgroundColor: '#C4C4C4',
|
||||
},
|
||||
});
|
||||
@@ -1,9 +0,0 @@
|
||||
import Avatar from './Avatar';
|
||||
import List from './List';
|
||||
import ListRow from './ListRow';
|
||||
|
||||
export {
|
||||
Avatar,
|
||||
List,
|
||||
ListRow,
|
||||
};
|
||||
1
react-native-gifted-material/index.js
vendored
1
react-native-gifted-material/index.js
vendored
@@ -1 +0,0 @@
|
||||
export * from './components/';
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"name": "react-native-gifted-material",
|
||||
"version": "0.1.0",
|
||||
"description": "Material components",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Farid from Safi",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"eslint": "^3.1.1",
|
||||
"eslint-plugin-react": "^5.2.2",
|
||||
"eslint-plugin-react-native": "^1.1.0"
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
import {Avatar as GiftedAvatar} from 'react-native-gifted-material';
|
||||
import GiftedAvatar from './GiftedAvatar';
|
||||
|
||||
export default class Avatar extends Component {
|
||||
renderAvatar() {
|
||||
|
||||
@@ -39,7 +39,7 @@ const styles = StyleSheet.create({
|
||||
Composer.defaultProps = {
|
||||
textInputStyle: {},
|
||||
onChange: () => {},
|
||||
composerHeight: 33,
|
||||
composerHeight: 33, // TODO SHARE with GiftedChat.js and tests
|
||||
text: '',
|
||||
placeholder: 'Type a message...',
|
||||
placeholderTextColor: '#b2b2b2',
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*
|
||||
** This component will be published in a separate package
|
||||
*/
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
Image,
|
||||
@@ -29,6 +29,7 @@ import Time from './Time';
|
||||
|
||||
// Min and max heights of ToolbarInput and Composer
|
||||
// Needed for handling Composer's auto grow and ScrollView animation
|
||||
// TODO move these values to Constants.js (also with used colors #b2b2b2)
|
||||
const MIN_COMPOSER_HEIGHT = 33;
|
||||
const MAX_COMPOSER_HEIGHT = 100;
|
||||
const MIN_INPUT_TOOLBAR_HEIGHT = 44;
|
||||
@@ -242,11 +243,17 @@ class GiftedChat extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
onKeyboardDidShow() {
|
||||
onKeyboardDidShow(e) {
|
||||
if (Platform.OS === 'android') {
|
||||
this.onKeyboardWillShow(e);
|
||||
}
|
||||
this.setIsTypingDisabled(false);
|
||||
}
|
||||
|
||||
onKeyboardDidHide() {
|
||||
onKeyboardDidHide(e) {
|
||||
if (Platform.OS === 'android') {
|
||||
this.onKeyboardWillHide(e);
|
||||
}
|
||||
this.setIsTypingDisabled(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,18 +26,17 @@ export default class LoadEarlier extends Component {
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginTop: 5,
|
||||
marginBottom: 10,
|
||||
},
|
||||
wrapper: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#ccc',
|
||||
borderRadius: 10,
|
||||
justifyContent: 'center',
|
||||
backgroundColor: '#b2b2b2',
|
||||
borderRadius: 15,
|
||||
height: 30,
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
paddingTop: 5,
|
||||
paddingBottom: 5,
|
||||
},
|
||||
text: {
|
||||
backgroundColor: 'transparent',
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import {
|
||||
|
||||
} from 'react-native';
|
||||
|
||||
import InvertibleScrollView from 'react-native-invertible-scroll-view';
|
||||
|
||||
@@ -56,7 +53,6 @@ export default class MessageContainer extends Component {
|
||||
return (
|
||||
<InvertibleScrollView
|
||||
{...this.props.invertibleScrollViewProps}
|
||||
|
||||
ref={component => this._invertibleScrollViewRef = component}
|
||||
>
|
||||
{this.props.messages.map((message, index) => {
|
||||
|
||||
15
src/Send.js
15
src/Send.js
@@ -3,15 +3,16 @@ import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
export default class Send extends Component {
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
if (this.props.text.trim().length === 0 && nextProps.text.trim().length > 0 || this.props.text.trim().length > 0 && nextProps.text.trim().length === 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// shouldComponentUpdate(nextProps, nextState) {
|
||||
// if (this.props.text.trim().length === 0 && nextProps.text.trim().length > 0 || this.props.text.trim().length > 0 && nextProps.text.trim().length === 0) {
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
render() {
|
||||
if (this.props.text.trim().length > 0) {
|
||||
return (
|
||||
@@ -25,7 +26,7 @@ export default class Send extends Component {
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
return <View/>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user