Add ability to send file via base64-encoded msg
This commit is contained in:
parent
3352c68f5c
commit
644fcbe06d
@ -1,3 +1,4 @@
|
||||
import * as ChatActions from '../actions/ChatActions.js'
|
||||
import * as NotifyActions from '../actions/NotifyActions.js'
|
||||
import * as StreamActions from '../actions/StreamActions.js'
|
||||
import * as constants from '../constants.js'
|
||||
@ -46,10 +47,25 @@ class PeerHandler {
|
||||
}
|
||||
handleData = object => {
|
||||
const { dispatch, user } = this
|
||||
object = JSON.parse(new window.TextDecoder('utf-8').decode(object))
|
||||
const message = JSON.parse(new window.TextDecoder('utf-8').decode(object))
|
||||
debug('peer: %s, message: %o', user.id, object)
|
||||
const message = user.id + ': ' + object.message
|
||||
dispatch(NotifyActions.info(message))
|
||||
switch (object.type) {
|
||||
case 'file':
|
||||
dispatch(ChatActions.addMessage({
|
||||
userId: user.id,
|
||||
message: 'Sent a file: "' + message.payload.name,
|
||||
timestamp: new Date().toLocaleString(),
|
||||
image: message.payload.data
|
||||
}))
|
||||
break
|
||||
default:
|
||||
dispatch(ChatActions.addMessage({
|
||||
userId: user.id,
|
||||
message: message.payload,
|
||||
timestamp: new Date().toLocaleString(),
|
||||
image: null
|
||||
}))
|
||||
}
|
||||
}
|
||||
handleClose = () => {
|
||||
const { dispatch, user } = this
|
||||
@ -126,7 +142,42 @@ export const destroyPeers = () => ({
|
||||
})
|
||||
|
||||
export const sendMessage = message => (dispatch, getState) => {
|
||||
message = JSON.stringify({ message })
|
||||
const { peers } = getState()
|
||||
_.each(peers, peer => peer.send(message))
|
||||
dispatch(NotifyActions.info('Sending message type: {0} to {1} peers.',
|
||||
message.type, Object.keys(peers).length))
|
||||
_.each(peers, peer => {
|
||||
switch (message.type) {
|
||||
case 'file':
|
||||
dispatch(ChatActions.addMessage({
|
||||
userId: 'You',
|
||||
message: 'Send file: "' +
|
||||
message.payload.name + '" to peer: ' + peer._id,
|
||||
timestamp: new Date().toLocaleString(),
|
||||
image: message.payload.data
|
||||
}))
|
||||
}
|
||||
peer.send(JSON.stringify(message))
|
||||
})
|
||||
}
|
||||
|
||||
export const sendFile = file => async (dispatch, getState) => {
|
||||
const { name, size, type } = file
|
||||
if (!window.FileReader) {
|
||||
dispatch(NotifyActions.error('File API is not supported by your browser'))
|
||||
return
|
||||
}
|
||||
const reader = new window.FileReader()
|
||||
const base64File = await new Promise(resolve => {
|
||||
reader.addEventListener('load', () => {
|
||||
resolve({
|
||||
name,
|
||||
size,
|
||||
type,
|
||||
data: reader.result
|
||||
})
|
||||
})
|
||||
reader.readAsDataURL(file)
|
||||
})
|
||||
|
||||
sendMessage({ payload: base64File, type: 'file' })(dispatch, getState)
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ export default class App extends React.PureComponent {
|
||||
peers: PropTypes.object.isRequired,
|
||||
sendMessage: PropTypes.func.isRequired,
|
||||
streams: PropTypes.objectOf(StreamPropType).isRequired,
|
||||
onSendFile: PropTypes.func.isRequired,
|
||||
toggleActive: PropTypes.func.isRequired
|
||||
}
|
||||
constructor () {
|
||||
@ -56,6 +57,7 @@ export default class App extends React.PureComponent {
|
||||
notifications,
|
||||
notify,
|
||||
messages,
|
||||
onSendFile,
|
||||
peers,
|
||||
sendMessage,
|
||||
toggleActive,
|
||||
@ -70,6 +72,7 @@ export default class App extends React.PureComponent {
|
||||
chatVisible={this.state.chatVisible}
|
||||
messages={messages}
|
||||
onToggleChat={this.handleToggleChat}
|
||||
onSendFile={onSendFile}
|
||||
stream={streams[constants.ME]}
|
||||
/>
|
||||
<Alerts alerts={alerts} dismiss={dismissAlert} />
|
||||
|
||||
@ -82,7 +82,12 @@ export default class Chat extends React.PureComponent {
|
||||
</span>
|
||||
<span className="icon icon-schedule" />
|
||||
<time className="message-time">{message.timestamp}</time>
|
||||
<p className="message-text">{message.message}</p>
|
||||
<p className="message-text">
|
||||
{message.image && (
|
||||
<img src={message.image} width="100%" />
|
||||
)}
|
||||
{message.message}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -5,13 +5,22 @@ import screenfull from 'screenfull'
|
||||
import { MessagePropTypes } from './Chat.js'
|
||||
import { StreamPropType } from './Video.js'
|
||||
|
||||
const hidden = {
|
||||
display: 'none'
|
||||
}
|
||||
|
||||
export default class Toolbar extends React.PureComponent {
|
||||
static propTypes = {
|
||||
messages: PropTypes.arrayOf(MessagePropTypes).isRequired,
|
||||
stream: StreamPropType,
|
||||
onToggleChat: PropTypes.func.isRequired,
|
||||
onSendFile: PropTypes.func.isRequired,
|
||||
chatVisible: PropTypes.bool.isRequired
|
||||
}
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.file = React.createRef()
|
||||
}
|
||||
handleMicClick = () => {
|
||||
const { stream } = this.props
|
||||
stream.mediaStream.getAudioTracks().forEach(track => {
|
||||
@ -35,6 +44,14 @@ export default class Toolbar extends React.PureComponent {
|
||||
handleHangoutClick = () => {
|
||||
window.location.href = '/'
|
||||
}
|
||||
handleSendFile = () => {
|
||||
this.file.current.click()
|
||||
}
|
||||
handleSelectFiles = () => {
|
||||
Array
|
||||
.from(this.file.current.files)
|
||||
.forEach(file => this.props.onSendFile(file))
|
||||
}
|
||||
render () {
|
||||
const { messages, stream } = this.props
|
||||
|
||||
@ -49,6 +66,20 @@ export default class Toolbar extends React.PureComponent {
|
||||
>
|
||||
<span className="icon icon-question_answer" />
|
||||
</div>
|
||||
<div
|
||||
className="button send-file"
|
||||
onClick={this.handleSendFile}
|
||||
title="Send file"
|
||||
>
|
||||
<input
|
||||
style={hidden}
|
||||
type="file"
|
||||
multiple
|
||||
ref={this.file}
|
||||
onChange={this.handleSelectFiles}
|
||||
/>
|
||||
<span className="icon icon-file-text2" />
|
||||
</div>
|
||||
|
||||
{stream && (
|
||||
<div>
|
||||
|
||||
@ -23,7 +23,8 @@ function mapDispatchToProps (dispatch) {
|
||||
sendMessage: bindActionCreators(PeerActions.sendMessage, dispatch),
|
||||
dismissAlert: bindActionCreators(NotifyActions.dismissAlert, dispatch),
|
||||
init: bindActionCreators(CallActions.init, dispatch),
|
||||
notify: bindActionCreators(NotifyActions.info, dispatch)
|
||||
notify: bindActionCreators(NotifyActions.info, dispatch),
|
||||
onSendFile: bindActionCreators(PeerActions.sendFile, dispatch)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user