Skip to content

Instantly share code, notes, and snippets.

@bogoslavskiy
Created November 23, 2018 13:51
Show Gist options
  • Save bogoslavskiy/fd2b6e8fb2dee194c30837f31cf292d9 to your computer and use it in GitHub Desktop.
Save bogoslavskiy/fd2b6e8fb2dee194c30837f31cf292d9 to your computer and use it in GitHub Desktop.
import React from 'react';
import {
View,
Text,
StyleSheet,
TextInput,
InputAccessoryView,
Button,
ScrollView,
Dimensions,
Alert,
Image,
FlatList,
Keyboard
} from 'react-native';
import { Notifications } from 'expo';
import API from '../api';
import { Viewport } from '../utils';
import { KeyboardAwareFlatList } from 'react-native-keyboard-aware-scroll-view'
class Message extends React.PureComponent<*> {
render() {
let isOwner = this.props.isOwner ? styles.messageOwner : {};
let isOwnerText = this.props.isOwner ? styles.messageTextOwner : {};
return (
<View style={[styles.message, isOwner]}>
<Text style={[styles.messageText, isOwnerText]}>{this.props.message}</Text>
</View>
);
}
}
export default class InputAccessoryViewExample extends React.Component {
static title = '<InputAccessoryView>';
static description = 'Example showing how to use an InputAccessoryView to build an iMessage-like sticky text input';
static navigationOptions = {
title: 'Messanger'
}
state = {
messages: [],
text: '',
notification: {},
}
componentDidMount() {
this.get();
this._notificationSubscription = Notifications.addListener(this._handleNotification);
this.keyboardShowFrames = {};
this.keyboardWillShowSub = Keyboard.addListener('keyboardWillShow', (frames) => {
this.keyboardShowFrames = frames;
});
this.keyboardHideFrames = {};
this.keyboardWillHideSub = Keyboard.addListener('keyboardWillHide', (frames) => {
this.keyboardHideFrames = frames;
});
}
componentWillUnmount() {
this.keyboardWillShowSub.remove();
this.keyboardWillHideSub.remove();
}
_handleNotification = async (notification) => {
let newMessage = await API('test.create', {
text: notification.data.text,
from_id: 2,
peer_id: 1
});
this.setState({
notification: notification,
messages: [
...this.state.messages,
newMessage
]
});
setTimeout(() => {
this.scroll.scrollToEnd();
}, 100)
};
get = async () => {
let messages = await API('test.get', {});
this.setState({ messages: messages });
}
send = async () => {
//this.setState({ loading: true });
console.log('qweqwe');
if(this.state.text == '') {
return;
}
let newMessage = await API('test.create', {
text: this.state.text,
from_id: 1,
peer_id: 2
});
this.setState({
text: '',
messages: [
...this.state.messages,
{...newMessage, owner: true}
]
});
setTimeout(() => {
this.scroll.scrollToEnd();
}, 100)
}
render() {
let { messages } = this.state;
return (
<View style={styles.container}>
<KeyboardAwareFlatList
innerRef={(ref) => this.scroll = ref}
extraScrollHeight={10}
enableResetScrollToCoords={false}
onScroll={(event) => {
this._contentOffset = event.nativeEvent.contentOffset.y;
}}
data={messages}
keyExtractor={(item) => item._id}
renderItem={({ item }) => (
<Message message={item.text} isOwner={item.from_id == 1} />
)}
/>
<InputAccessoryView backgroundColor="#fff" style={{height: 50}}>
<View style={[styles.textInputContainer, { width: Viewport.width }]}>
<TextInput
onFocus={() => {
console.log('SHOW');
this.scroll.props.scrollToPosition(0, this._contentOffset + 265 - 10)
console.log('HIDE this._contentOffset', this._contentOffset);
//this.scroll.props.scrollToEnd();
}}
onBlur={() => {
if(this.keyboardHideFrames.duration >= 250) {
this.scroll.props.scrollToPosition(0, this._contentOffset - 265 + 10)
}
setTimeout(() => {
if(this.keyboardHideFrames.duration >= 250) {
console.log('HIDE', this.keyboardHideFrames);
console.log('HIDE this._contentOffset', this._contentOffset);
//this.scroll.props.scrollToEnd();
}
}, 20);
//this.scroll.props.scrollToEnd();
console.log(this.scroll.props);
}}
style={styles.textInput}
onChangeText={(text) => {
this.setState({ text });
}}
value={this.state.text}
placeholder={'Type a message...'}
/>
<Button
onPress={this.send}
title="Send"
/>
</View>
</InputAccessoryView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
//flex: 1,
},
textInputContainer: {
flexDirection: 'row',
paddingVertical: 10,
},
textInput: {
flex: 1,
paddingLeft: 10,
},
messagesWrapper: {
flex: 1,
},
message: {
backgroundColor: 'grey',
borderRadius: 20,
margin: 10,
marginBottom: 0,
marginTop: 15,
alignSelf: 'flex-start'
},
messageOwner: {
backgroundColor: '#fff',
alignSelf: 'flex-end'
},
messageTextOwner: {
color: '#000',
},
messageText: {
color: '#fff',
padding: 15,
fontSize: 18
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment