|
import React, { Component } from 'react'; |
|
import Promise from 'bluebird'; |
|
Promise.config({ |
|
warnings: false |
|
}); |
|
|
|
import { |
|
TextInput, |
|
Button, |
|
StyleSheet, |
|
Text, |
|
View, |
|
FlatList, |
|
TouchableHighlight, |
|
ScrollView |
|
} from 'react-native'; |
|
import axios from 'axios'; |
|
import './poly.js'; |
|
import sdk from 'matrix-js-sdk'; |
|
const baseUrl = 'https://msg.tebinja.com'; |
|
export default class App extends Component<{}> { |
|
constructor(props) { |
|
super(props); |
|
this.state = { |
|
userName: 'dummyUser', |
|
password: 'password', |
|
userId: '', |
|
accessToken: '', |
|
client: '', |
|
newRoom: '', |
|
room_alias: 'not in a room', |
|
nextSyncToken: '', |
|
room_id: '', |
|
roomToJoin: '', |
|
memberList: [], |
|
rooms: [], |
|
hasRooms: false, |
|
message: '', |
|
messages: {}, |
|
isTyping: false, |
|
displayName: '' |
|
}; |
|
} |
|
login = async e => { |
|
const { userName, password } = this.state; |
|
let url = baseUrl + '/_matrix/client/r0/login'; |
|
try { |
|
let res = await axios.get(url); |
|
let { data } = await axios.post(url, { |
|
type: 'm.login.password', |
|
user: userName, |
|
password: password |
|
}); |
|
let client = sdk.createClient({ |
|
baseUrl: baseUrl, |
|
accessToken: data.access_token, |
|
userId: data.user_id |
|
}); |
|
let _this = this; |
|
client.on('sync', function(state, prevState, data) { |
|
try { |
|
_this.setState({ |
|
nextSyncToken: data.nextSyncToken |
|
}); |
|
switch (state) { |
|
case 'PREPARED': |
|
let roomList = client.getRooms(); |
|
_this.setState({ rooms: roomList }); |
|
break; |
|
} |
|
} catch (e) { |
|
console.warn(e, 'sync'); |
|
} |
|
}); |
|
client.on('Room.timeline', function(event, state) { |
|
if (event.event.type == 'm.room.message') { |
|
return _this.newMessage(event); |
|
} |
|
}); |
|
client.on('RoomMember.typing', function(event, member) { |
|
var isTyping = member.typing; |
|
console.log(member, event, 'typing'); |
|
if (isTyping) { |
|
return _this.setState({ |
|
isTyping: { status: true, member: member } |
|
}); |
|
} |
|
return _this.setState({ |
|
isTyping: { status: false, member } |
|
}); |
|
}); |
|
|
|
client.on('RoomMember.membership', function(event, member) { |
|
if (member.membership === 'invite' && member.userId === _this.state.userId) { |
|
client.joinRoom(member.roomId).done(function() { |
|
let roomList = client.getRooms(); |
|
_this.setState({ rooms: roomList }); |
|
}); |
|
} |
|
}); |
|
client.on('RoomState.members', function(event, state, member) { |
|
var room = client.getRoom(state.roomId); |
|
if (!room) { |
|
return; |
|
} |
|
var memberList = state.getMembers(); |
|
if (memberList.length > 0) { |
|
_this.setState({ |
|
memberList: memberList |
|
}); |
|
} |
|
}); |
|
client.startClient(); |
|
|
|
this.setState({ |
|
userId: data.user_id, |
|
accessToken: data.access_token, |
|
client: client |
|
}); |
|
} catch (e) { |
|
console.log(e, ' login request result'); |
|
console.warn(e.message, ' login request result'); |
|
} |
|
}; |
|
|
|
getRoomMessages = async (roomId, nextSyncToken, accessToken) => { |
|
try { |
|
let allMessages = |
|
baseUrl + |
|
`/_matrix/client/r0/rooms/${roomId}/messages?limit=10&from=${nextSyncToken}&access_token=${accessToken}&dir=b`; |
|
let result = await axios.get(allMessages); |
|
return result.data; |
|
} catch (error) { |
|
console.log(error); |
|
} |
|
}; |
|
joinRoom = async (room)=>{ |
|
|
|
// e.preventDefault() |
|
// console.warn(room,'aaaaaaaaaaa') |
|
let {messages,roomToJoin,accessToken,client,nextSyncToken} = this.state |
|
let url = baseUrl +`/_matrix/client/r0/join/${room.roomId}?access_token=${accessToken}` |
|
try{ |
|
let {data} = await axios.post(url, |
|
{ |
|
room_id : roomToJoin, |
|
|
|
}) |
|
let roomMessages = messages[room.roomId] |
|
// console.log(roomMessages , 'room messages',room.roomId) |
|
if(roomMessages && roomMessages.length > 0){ |
|
let lastMsg = roomMessages[roomMessages.length-1] |
|
// console.log(lastMsg , 'last msg') |
|
// console.log(lastMsg.event,'aaaaaa') |
|
// client.sendReadReceipt(lastMsg.event) |
|
} |
|
this.setState({ |
|
room_id:room.roomId, |
|
room_alias : room.name, |
|
}) |
|
}catch(e){ |
|
console.log(e) |
|
} |
|
} |
|
sendMessage = async e => { |
|
let { client, room_id, accessToken, message } = this.state; |
|
try { |
|
let content = { |
|
msgtype: 'm.text', |
|
body: message |
|
}; |
|
let sentMessage = await client.sendMessage(room_id, content); |
|
console.log(sentMessage, ' sent message '); |
|
let url = `${baseUrl}/_matrix/client/r0/rooms/${room_id}/read_markers?access_token=${accessToken}`; |
|
axios.post(url, { |
|
'm.fully_read': sentMessage.event_id |
|
}); |
|
client.sendTyping(room_id, false); |
|
this.setState({ |
|
message: '' |
|
}); |
|
} catch (e) { |
|
console.log(e); |
|
} |
|
}; |
|
|
|
newMessage = async data => { |
|
let { room_id, messages } = this.state; |
|
console.warn(data, '---------'); |
|
let message = data.event.content; |
|
if (!messages[data.event.room_id]) { |
|
messages[data.event.room_id] = []; |
|
} |
|
|
|
message['sender'] = data.sender.name; |
|
console.log(message['event'], 'new message', data); |
|
// message['event'] = data.event |
|
|
|
if (message.msgtype == 'm.image') { |
|
message['type'] = 'image'; |
|
console.log(message.url, 'urlllllllll'); |
|
// let image = this.getFile(message.url) |
|
// message['url'] = image |
|
message['url'] = message.url; |
|
} |
|
|
|
messages[data.event.room_id].push(message); |
|
console.log(messages); |
|
this.setState({ |
|
messages: messages |
|
}); |
|
}; |
|
getFile = mediaId => { |
|
try { |
|
mediaId = mediaId.replace('mxc://', ''); |
|
let url = baseUrl + `/_matrix/media/r0/download/${mediaId}`; |
|
return url; |
|
} catch (e) { |
|
console.log(e); |
|
} |
|
}; |
|
handleChange = (stateKey, e) => { |
|
this.setState({ |
|
[`${stateKey}`]: e |
|
}); |
|
}; |
|
setTyping = e => { |
|
this.handleChange('message', e); |
|
let { client, room_id } = this.state; |
|
client.sendTyping(room_id, true); |
|
}; |
|
|
|
|
|
userTyping = () => { |
|
let { isTyping, userId } = this.state; |
|
if (isTyping.status == true && isTyping.member.userId != userId) { |
|
return isTyping.member.name + ' is Typing'; |
|
} |
|
}; |
|
|
|
render() { |
|
let messages = this.state.messages[this.state.room_id] |
|
? this.state.messages[this.state.room_id] |
|
: []; |
|
console.log(this.state.message, 'rooms list'); |
|
return ( |
|
<View> |
|
<TextInput |
|
style={{ height: 40 }} |
|
placeholder="username" |
|
onChangeText={e => this.handleChange('userName', e)} |
|
/> |
|
<TextInput |
|
style={{ height: 40 }} |
|
placeholder="password" |
|
onChangeText={e => this.handleChange('password', e)} |
|
/> |
|
<Button onPress={this.login} title="LOGIN" /> |
|
<TextInput |
|
style={{ height: 40 }} |
|
placeholder="username" |
|
onChangeText={e => this.handleChange('newRoom', e)} |
|
/> |
|
<Button onPress={this.createRoom} title="Add friend" /> |
|
<FlatList |
|
data={this.state.rooms} |
|
renderItem={({ item }) => ( |
|
<TouchableHighlight onPress={() => this.joinRoom(item)}> |
|
<View key={item.roomId}> |
|
<Text> {item.name} </Text> |
|
</View> |
|
</TouchableHighlight> |
|
)} |
|
/> |
|
<Text> now in room: {this.state.room_alias} </Text> |
|
<TextInput onChangeText={e => this.setTyping(e)} /> |
|
<Button onPress={this.sendMessage} title="send" /> |
|
<View style={StyleSheet.chat}> |
|
<FlatList |
|
data={messages} |
|
renderItem={({ item }) => ( |
|
<ScrollView> |
|
<Text> {item.body} </Text> |
|
</ScrollView> |
|
)} |
|
/> |
|
</View> |
|
</View> |
|
); |
|
} |
|
} |
|
const styles = StyleSheet.create({ |
|
container: { |
|
flex: 1, |
|
justifyContent: 'center', |
|
alignItems: 'center', |
|
backgroundColor: '#F5FCFF' |
|
}, |
|
welcome: { |
|
fontSize: 20, |
|
textAlign: 'center', |
|
margin: 10 |
|
}, |
|
instructions: { |
|
textAlign: 'center', |
|
color: '#333333', |
|
marginBottom: 5 |
|
}, |
|
chat: { |
|
height: 1000, |
|
flex: 1 |
|
} |
|
}); |
Doesn't work in Expo projects...