mirror of
https://github.com/zhigang1992/react-native-gifted-chat.git
synced 2026-04-29 04:35:46 +08:00
development helper
This commit is contained in:
17
example/README.md
Normal file
17
example/README.md
Normal file
@@ -0,0 +1,17 @@
|
||||
## Example App
|
||||
|
||||
Normally, after a code change to react-native-gifted-chat src files,
|
||||
you must remove the node_modules/react-native-gifted-chat directory
|
||||
and npm install. The react-native packager wont follow symlinks.
|
||||
|
||||
To assist development, this command watches and rsyncs changes:
|
||||
|
||||
```
|
||||
npm run sync
|
||||
```
|
||||
|
||||
Leave a terminal open running this command when running the Example
|
||||
app and making react-native-gifted-chat src changes.
|
||||
|
||||
|
||||
Development helper inspired by [@joenoon](https://github.com/aksonov/react-native-router-flux/commit/ba85007a36b1d317e9114b9cd46086f4aba9d142)
|
||||
@@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node_modules/react-native/packager/packager.sh",
|
||||
"sync-rngc": "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 node_modules ../ ./node_modules/react-native-gifted-chat/' .. --glob='{**/*.json,**/*.js}'"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "15.2.1",
|
||||
@@ -15,6 +15,6 @@
|
||||
"eslint": "^3.1.1",
|
||||
"eslint-plugin-react": "^5.2.2",
|
||||
"eslint-plugin-react-native": "^1.2.0",
|
||||
"sane": "^1.3.4"
|
||||
"sane": "^1.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"plugins": [
|
||||
"react",
|
||||
"react-native"
|
||||
],
|
||||
"extends": ["eslint:recommended", "plugin:react/recommended"],
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
"ecmaFeatures" : {
|
||||
experimentalObjectRestSpread: true
|
||||
}
|
||||
},
|
||||
"env": {
|
||||
"node": true
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
TODO.md
|
||||
@@ -1 +0,0 @@
|
||||
TODO.md
|
||||
@@ -1,141 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
Image,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
// TODO
|
||||
// 3 words name initials
|
||||
// handle only alpha numeric chars
|
||||
|
||||
class GiftedAvatar extends Component {
|
||||
setAvatarColor() {
|
||||
const userName = this.props.user.name || '';
|
||||
const name = userName.toUpperCase().split(' ');
|
||||
if (name.length === 1) {
|
||||
this.avatarName = `${name[0].charAt(0)}`;
|
||||
} else if (name.length > 1) {
|
||||
this.avatarName = `${name[0].charAt(0)}${name[1].charAt(0)}`;
|
||||
} else {
|
||||
this.avatarName = '';
|
||||
}
|
||||
|
||||
let sumChars = 0;
|
||||
for(let i = 0; i < userName.length; i++) {
|
||||
sumChars += userName.charCodeAt(i);
|
||||
}
|
||||
|
||||
// inspired by https://github.com/wbinnssmith/react-user-avatar
|
||||
// colors from https://flatuicolors.com/
|
||||
const colors = [
|
||||
'#2ecc71', // emerald
|
||||
'#3498db', // peter river
|
||||
'#8e44ad', // wisteria
|
||||
'#e67e22', // carrot
|
||||
'#e74c3c', // alizarin
|
||||
'#1abc9c', // turquoise
|
||||
'#2c3e50', // midnight blue
|
||||
];
|
||||
|
||||
this.avatarColor = colors[sumChars % colors.length];
|
||||
}
|
||||
|
||||
renderAvatar() {
|
||||
if (typeof this.props.user.avatar === 'function') {
|
||||
return this.props.user.avatar();
|
||||
} else if (typeof this.props.user.avatar === 'string') {
|
||||
return (
|
||||
<Image
|
||||
source={{uri: this.props.user.avatar}}
|
||||
style={[defaultStyles.avatarStyle, this.props.avatarStyle]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
renderInitials() {
|
||||
return (
|
||||
<Text style={[defaultStyles.textStyle, this.props.textStyle]}>
|
||||
{this.avatarName}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.props.user.name && !this.props.user.avatar) {
|
||||
// render placeholder
|
||||
return (
|
||||
<View style={[
|
||||
defaultStyles.avatarStyle,
|
||||
{backgroundColor: 'transparent'},
|
||||
this.props.avatarStyle,
|
||||
]}/>
|
||||
)
|
||||
}
|
||||
if (this.props.user.avatar) {
|
||||
// disabled={this.props.onPress ? false : true}
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
const {onPress, ...other} = this.props;
|
||||
this.props.onPress && this.props.onPress(other);
|
||||
}}
|
||||
>
|
||||
{this.renderAvatar()}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.avatarColor) {
|
||||
this.setAvatarColor();
|
||||
}
|
||||
|
||||
// disabled={this.props.onPress ? false : true}
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
const {onPress, ...other} = this.props;
|
||||
this.props.onPress && this.props.onPress(other);
|
||||
}}
|
||||
style={[
|
||||
defaultStyles.avatarStyle,
|
||||
{backgroundColor: this.avatarColor},
|
||||
this.props.avatarStyle,
|
||||
]}
|
||||
>
|
||||
{this.renderInitials()}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
GiftedAvatar.defaultProps = {
|
||||
user: {
|
||||
name: null,
|
||||
avatar: null,
|
||||
},
|
||||
onPress: null,
|
||||
avatarStyle: {},
|
||||
textStyle: {},
|
||||
};
|
||||
|
||||
const defaultStyles = {
|
||||
avatarStyle: {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 16,
|
||||
backgroundColor: 'transparent',
|
||||
fontWeight: '100',
|
||||
},
|
||||
};
|
||||
|
||||
export default GiftedAvatar;
|
||||
@@ -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 +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"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user