Rename actions and functions

This commit is contained in:
Alan Friedman 2019-05-27 16:06:01 -04:00
parent 56ed301203
commit 435e193c93
13 changed files with 61 additions and 84 deletions

View File

@ -6,11 +6,11 @@ import {
} from 'utils/message' } from 'utils/message'
import { getSocket } from 'utils/socket' import { getSocket } from 'utils/socket'
export const receiveSocketMessage = payload => async (dispatch, getState) => { export const receiveEncryptedMessage = payload => async (dispatch, getState) => {
const state = getState() const state = getState()
const message = await processMessage(payload, state) const message = await processMessage(payload, state)
// Pass current state to all HANDLE_SOCKET_MESSAGE reducers for convenience, since each may have different needs // Pass current state to all RECEIVE_ENCRYPTED_MESSAGE reducers for convenience, since each may have different needs
dispatch({ type: `HANDLE_SOCKET_MESSAGE_${message.type}`, payload: { payload: message.payload, state } }) dispatch({ type: `RECEIVE_ENCRYPTED_MESSAGE_${message.type}`, payload: { payload: message.payload, state } })
} }
export const createUser = payload => async (dispatch) => { export const createUser = payload => async (dispatch) => {
@ -52,11 +52,11 @@ export const onFileTransfer = payload => async (dispatch) => {
dispatch({ type: 'PREFLIGHT_FILE_TRANSFER', payload }) dispatch({ type: 'PREFLIGHT_FILE_TRANSFER', payload })
} }
export const sendSocketMessage = payload => async (dispatch, getState) => { export const sendEncryptedMessage = payload => async (dispatch, getState) => {
const state = getState() const state = getState()
const msg = await prepareMessage(payload, state) const msg = await prepareMessage(payload, state)
dispatch({ type: `SEND_SOCKET_MESSAGE_${msg.original.type}`, payload: msg.original.payload }) dispatch({ type: `SEND_ENCRYPTED_MESSAGE_${msg.original.type}`, payload: msg.original.payload })
getSocket().emit('PAYLOAD', msg.toSend) getSocket().emit('ENCRYPTED_MESSAGE', msg.toSend)
} }
export const toggleLockRoom = () => async (dispatch, getState) => { export const toggleLockRoom = () => async (dispatch, getState) => {
@ -94,10 +94,6 @@ export const clearActivities = () => async (dispatch) => {
dispatch({ type: 'CLEAR_ACTIVITIES' }) dispatch({ type: 'CLEAR_ACTIVITIES' })
} }
export const onConnected = payload => async (dispatch) => {
dispatch({ type: 'CONNECTED', payload })
}
export const sendUserDisconnect = () => async () => { export const sendUserDisconnect = () => async () => {
getSocket().emit('USER_DISCONNECT') getSocket().emit('USER_DISCONNECT')
} }

View File

@ -3,11 +3,11 @@ import { mount } from 'enzyme'
import toJson from 'enzyme-to-json' import toJson from 'enzyme-to-json'
import { Chat } from './index.js' import { Chat } from './index.js'
const sendSocketMessage = jest.fn() const sendEncryptedMessage = jest.fn()
test('Chat Component', () => { test('Chat Component', () => {
const component = mount( const component = mount(
<Chat scrollToBottom={() => {}} focusChat={false} userId="foo" username="user" showNotice={() => {}} clearActivities={() => {}} sendSocketMessage={sendSocketMessage} /> <Chat scrollToBottom={() => {}} focusChat={false} userId="foo" username="user" showNotice={() => {}} clearActivities={() => {}} sendEncryptedMessage={sendEncryptedMessage} />
) )
const componentJSON = toJson(component) const componentJSON = toJson(component)

View File

@ -51,7 +51,7 @@ export class Chat extends Component {
}) })
} }
this.props.sendSocketMessage({ this.props.sendEncryptedMessage({
type: 'CHANGE_USERNAME', type: 'CHANGE_USERNAME',
payload: { payload: {
id: this.props.userId, id: this.props.userId,
@ -85,7 +85,7 @@ export class Chat extends Component {
return false return false
} }
this.props.sendSocketMessage({ this.props.sendEncryptedMessage({
type: 'USER_ACTION', type: 'USER_ACTION',
payload: { payload: {
action: actionMessage, action: actionMessage,
@ -216,8 +216,8 @@ export class Chat extends Component {
return return
} }
} else { } else {
this.props.sendSocketMessage({ this.props.sendEncryptedMessage({
type: 'SEND_MESSAGE', type: 'TEXT_MESSAGE',
payload: { payload: {
text: message, text: message,
timestamp: Date.now(), timestamp: Date.now(),
@ -256,7 +256,7 @@ export class Chat extends Component {
placeholder="Type here" placeholder="Type here"
onChange={this.handleInputChange.bind(this)} /> onChange={this.handleInputChange.bind(this)} />
<div className="input-controls"> <div className="input-controls">
<FileTransfer sendSocketMessage={this.props.sendSocketMessage} /> <FileTransfer sendEncryptedMessage={this.props.sendEncryptedMessage} />
{touchSupport && {touchSupport &&
<button onClick={this.handleSendClick.bind(this)} className={`icon is-right send btn btn-link ${this.canSend() ? 'active' : ''}`}> <button onClick={this.handleSendClick.bind(this)} className={`icon is-right send btn btn-link ${this.canSend() ? 'active' : ''}`}>
<CornerDownRight className={this.canSend() ? '' : 'disabled'} /> <CornerDownRight className={this.canSend() ? '' : 'disabled'} />
@ -269,7 +269,7 @@ export class Chat extends Component {
} }
Chat.propTypes = { Chat.propTypes = {
sendSocketMessage: PropTypes.func.isRequired, sendEncryptedMessage: PropTypes.func.isRequired,
showNotice: PropTypes.func.isRequired, showNotice: PropTypes.func.isRequired,
userId: PropTypes.string.isRequired, userId: PropTypes.string.isRequired,
username: PropTypes.string.isRequired, username: PropTypes.string.isRequired,

View File

@ -81,7 +81,7 @@ export default class FileTransfer extends Component {
this.setState({ this.setState({
localFileQueue, localFileQueue,
}, async () => { }, async () => {
this.props.sendSocketMessage({ this.props.sendEncryptedMessage({
type: 'SEND_FILE', type: 'SEND_FILE',
payload: { payload: {
fileName: fileData.fileName, fileName: fileData.fileName,
@ -112,5 +112,5 @@ export default class FileTransfer extends Component {
} }
FileTransfer.propTypes = { FileTransfer.propTypes = {
sendSocketMessage: PropTypes.func.isRequired, sendEncryptedMessage: PropTypes.func.isRequired,
} }

View File

@ -41,6 +41,7 @@ export default class Home extends Component {
} }
async componentWillMount() { async componentWillMount() {
console.log(this.props.dispatch);
const roomId = encodeURI(this.props.match.params.roomId) const roomId = encodeURI(this.props.match.params.roomId)
const user = await this.createUser() const user = await this.createUser()
@ -70,7 +71,7 @@ export default class Home extends Component {
socket.on('USER_ENTER', (payload) => { socket.on('USER_ENTER', (payload) => {
this.props.receiveUserEnter(payload) this.props.receiveUserEnter(payload)
this.props.sendSocketMessage({ this.props.sendEncryptedMessage({
type: 'ADD_USER', type: 'ADD_USER',
payload: { payload: {
username: this.props.username, username: this.props.username,
@ -85,18 +86,14 @@ export default class Home extends Component {
this.props.receiveUserExit(payload) this.props.receiveUserExit(payload)
}) })
socket.on('PAYLOAD', (payload) => { socket.on('ENCRYPTED_MESSAGE', (payload) => {
this.props.receiveSocketMessage(payload) this.props.receiveEncryptedMessage(payload)
}) })
socket.on('TOGGLE_LOCK_ROOM', (payload) => { socket.on('TOGGLE_LOCK_ROOM', (payload) => {
this.props.receiveToggleLockRoom(payload) this.props.receiveToggleLockRoom(payload)
}) })
socket.on('CONNECTED', (payload) => {
this.props.onConnected(payload);
});
socket.on('ROOM_LOCKED', (payload) => { socket.on('ROOM_LOCKED', (payload) => {
this.props.openModal('Room Locked') this.props.openModal('Room Locked')
}); });
@ -171,7 +168,7 @@ export default class Home extends Component {
getActivityComponent(activity) { getActivityComponent(activity) {
switch (activity.type) { switch (activity.type) {
case 'SEND_MESSAGE': case 'TEXT_MESSAGE':
return ( return (
<Message <Message
sender={activity.username} sender={activity.username}
@ -411,8 +408,8 @@ Home.defaultProps = {
} }
Home.propTypes = { Home.propTypes = {
receiveSocketMessage: PropTypes.func.isRequired, receiveEncryptedMessage: PropTypes.func.isRequired,
sendSocketMessage: PropTypes.func.isRequired, sendEncryptedMessage: PropTypes.func.isRequired,
createUser: PropTypes.func.isRequired, createUser: PropTypes.func.isRequired,
receiveUserExit: PropTypes.func.isRequired, receiveUserExit: PropTypes.func.isRequired,
receiveUserEnter: PropTypes.func.isRequired, receiveUserEnter: PropTypes.func.isRequired,
@ -441,5 +438,4 @@ Home.propTypes = {
toggleSoundEnabled: PropTypes.func.isRequired, toggleSoundEnabled: PropTypes.func.isRequired,
toggleSocketConnected: PropTypes.func.isRequired, toggleSocketConnected: PropTypes.func.isRequired,
socketConnected: PropTypes.bool.isRequired, socketConnected: PropTypes.bool.isRequired,
onConnected: PropTypes.func.isRequired
} }

View File

@ -1,12 +1,12 @@
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { sendSocketMessage } from 'actions' import { sendEncryptedMessage } from 'actions'
import ChatInput from 'components/Chat' import ChatInput from 'components/Chat'
const mapStateToProps = () => ({ const mapStateToProps = () => ({
}) })
const mapDispatchToProps = { const mapDispatchToProps = {
sendSocketMessage, sendEncryptedMessage,
} }
export default connect( export default connect(

View File

@ -1,8 +1,8 @@
import { connect } from 'react-redux' import { connect } from 'react-redux'
import Home from 'components/Home' import Home from 'components/Home'
import { import {
receiveSocketMessage, receiveEncryptedMessage,
sendSocketMessage, sendEncryptedMessage,
createUser, createUser,
receiveUserExit, receiveUserExit,
receiveUserEnter, receiveUserEnter,
@ -15,7 +15,6 @@ import {
toggleWindowFocus, toggleWindowFocus,
toggleSoundEnabled, toggleSoundEnabled,
toggleSocketConnected, toggleSocketConnected,
onConnected,
sendUserDisconnect sendUserDisconnect
} from 'actions' } from 'actions'
@ -42,8 +41,8 @@ const mapStateToProps = (state) => {
} }
const mapDispatchToProps = { const mapDispatchToProps = {
receiveSocketMessage, receiveEncryptedMessage,
sendSocketMessage, sendEncryptedMessage,
receiveUserExit, receiveUserExit,
receiveUserEnter, receiveUserEnter,
createUser, createUser,
@ -56,7 +55,6 @@ const mapDispatchToProps = {
toggleWindowFocus, toggleWindowFocus,
toggleSoundEnabled, toggleSoundEnabled,
toggleSocketConnected, toggleSocketConnected,
onConnected,
sendUserDisconnect sendUserDisconnect
} }

View File

@ -16,7 +16,7 @@ const activities = (state = initialState, action) => {
...state, ...state,
items: [], items: [],
} }
case 'SEND_SOCKET_MESSAGE_SLASH_COMMAND': case 'SEND_ENCRYPTED_MESSAGE_SLASH_COMMAND':
return { return {
...state, ...state,
items: [ items: [
@ -27,7 +27,7 @@ const activities = (state = initialState, action) => {
}, },
], ],
} }
case 'SEND_SOCKET_MESSAGE_FILE_TRANSFER': case 'SEND_ENCRYPTED_MESSAGE_FILE_TRANSFER':
return { return {
...state, ...state,
items: [ items: [
@ -38,29 +38,29 @@ const activities = (state = initialState, action) => {
}, },
], ],
} }
case 'SEND_SOCKET_MESSAGE_SEND_MESSAGE': case 'SEND_ENCRYPTED_MESSAGE_TEXT_MESSAGE':
return { return {
...state, ...state,
items: [ items: [
...state.items, ...state.items,
{ {
...action.payload, ...action.payload,
type: 'SEND_MESSAGE', type: 'TEXT_MESSAGE',
}, },
], ],
} }
case 'HANDLE_SOCKET_MESSAGE_SEND_MESSAGE': case 'RECEIVE_ENCRYPTED_MESSAGE_TEXT_MESSAGE':
return { return {
...state, ...state,
items: [ items: [
...state.items, ...state.items,
{ {
...action.payload.payload, ...action.payload.payload,
type: 'SEND_MESSAGE', type: 'TEXT_MESSAGE',
}, },
], ],
} }
case 'SEND_SOCKET_MESSAGE_SEND_FILE': case 'SEND_ENCRYPTED_MESSAGE_SEND_FILE':
return { return {
...state, ...state,
items: [ items: [
@ -71,7 +71,7 @@ const activities = (state = initialState, action) => {
}, },
], ],
} }
case 'HANDLE_SOCKET_MESSAGE_SEND_FILE': case 'RECEIVE_ENCRYPTED_MESSAGE_SEND_FILE':
return { return {
...state, ...state,
items: [ items: [
@ -82,7 +82,7 @@ const activities = (state = initialState, action) => {
}, },
], ],
} }
case 'HANDLE_SOCKET_MESSAGE_ADD_USER': case 'RECEIVE_ENCRYPTED_MESSAGE_ADD_USER':
const newUserId = action.payload.payload.id const newUserId = action.payload.payload.id
const haveUser = action.payload.state.room.members.find(m => m.id === newUserId) const haveUser = action.payload.state.room.members.find(m => m.id === newUserId)
@ -159,7 +159,7 @@ const activities = (state = initialState, action) => {
}, },
], ],
} }
case 'SEND_SOCKET_MESSAGE_CHANGE_USERNAME': case 'SEND_ENCRYPTED_MESSAGE_CHANGE_USERNAME':
return { return {
...state, ...state,
items: [ items: [
@ -179,7 +179,7 @@ const activities = (state = initialState, action) => {
return item return item
}), }),
} }
case 'HANDLE_SOCKET_MESSAGE_CHANGE_USERNAME': case 'RECEIVE_ENCRYPTED_MESSAGE_CHANGE_USERNAME':
return { return {
...state, ...state,
items: [ items: [
@ -190,7 +190,7 @@ const activities = (state = initialState, action) => {
newUsername: action.payload.payload.newUsername, newUsername: action.payload.payload.newUsername,
}, },
].map((item) => { ].map((item) => {
if (['SEND_MESSAGE', 'USER_ACTION'].includes(item.type) && item.sender === action.payload.payload.sender) { if (['TEXT_MESSAGE', 'USER_ACTION'].includes(item.type) && item.sender === action.payload.payload.sender) {
return { return {
...item, ...item,
username: action.payload.payload.newUsername, username: action.payload.payload.newUsername,
@ -199,7 +199,7 @@ const activities = (state = initialState, action) => {
return item return item
}), }),
} }
case 'SEND_SOCKET_MESSAGE_USER_ACTION': case 'SEND_ENCRYPTED_MESSAGE_USER_ACTION':
return { return {
...state, ...state,
items: [ items: [
@ -210,7 +210,7 @@ const activities = (state = initialState, action) => {
}, },
], ],
} }
case 'HANDLE_SOCKET_MESSAGE_USER_ACTION': case 'RECEIVE_ENCRYPTED_MESSAGE_USER_ACTION':
return { return {
...state, ...state,
items: [ items: [

View File

@ -30,7 +30,7 @@ const app = (state = initialState, action) => {
windowIsFocused: action.payload, windowIsFocused: action.payload,
unreadMessageCount: 0, unreadMessageCount: 0,
} }
case 'HANDLE_SOCKET_MESSAGE_SEND_MESSAGE': case 'RECEIVE_ENCRYPTED_MESSAGE_TEXT_MESSAGE':
return { return {
...state, ...state,
unreadMessageCount: state.windowIsFocused ? 0 : state.unreadMessageCount + 1, unreadMessageCount: state.windowIsFocused ? 0 : state.unreadMessageCount + 1,

View File

@ -15,15 +15,6 @@ const initialState = {
const room = (state = initialState, action) => { const room = (state = initialState, action) => {
switch (action.type) { switch (action.type) {
case 'CONNECTED':
const size = action.payload.users ? action.payload.users.length : 1;
return {
...state,
id: action.payload.id,
isLocked: Boolean(action.payload.isLocked),
size,
joining: false
}
case 'USER_EXIT': case 'USER_EXIT':
const memberPubKeys = action.payload.members.map(m => JSON.stringify(m.publicKey)) const memberPubKeys = action.payload.members.map(m => JSON.stringify(m.publicKey))
return { return {
@ -38,7 +29,7 @@ const room = (state = initialState, action) => {
} }
}), }),
} }
case 'HANDLE_SOCKET_MESSAGE_ADD_USER': case 'RECEIVE_ENCRYPTED_MESSAGE_ADD_USER':
const membersWithId = state.members.filter(m => m.id) const membersWithId = state.members.filter(m => m.id)
const joining = false const joining = false
@ -70,17 +61,15 @@ const room = (state = initialState, action) => {
], ],
} }
case 'USER_ENTER': case 'USER_ENTER':
/* const members = _.uniqBy(action.payload.users, member => member.publicKey.n);
In this payload the server sends all users' public keys. Normally the server const size = action.payload.users ? action.payload.users.length : 1;
will have all the users the client does, but in some cases - such as when
new users join before this client has registered with the server (this can
happen when lots of users join in quick succession) - the client
will receive a USER_ENTER event that doesn't contain itself. In that case we
want to prepend "me" to the members payload
*/
const members = _.uniqBy(action.payload, member => member.publicKey.n);
return { return {
...state, ...state,
id: action.payload.id,
isLocked: Boolean(action.payload.isLocked),
size,
joining: false,
members: members.reduce((acc, user) => { members: members.reduce((acc, user) => {
const exists = state.members.find(m => m.publicKey.n === user.publicKey.n) const exists = state.members.find(m => m.publicKey.n === user.publicKey.n)
if (exists) { if (exists) {
@ -112,7 +101,7 @@ const room = (state = initialState, action) => {
...state, ...state,
isLocked: action.payload.locked, isLocked: action.payload.locked,
} }
case 'SEND_SOCKET_MESSAGE_CHANGE_USERNAME': case 'SEND_ENCRYPTED_MESSAGE_CHANGE_USERNAME':
const newUsername = action.payload.newUsername const newUsername = action.payload.newUsername
const userId = action.payload.id const userId = action.payload.id
return { return {
@ -125,7 +114,7 @@ const room = (state = initialState, action) => {
} : member } : member
)), )),
} }
case 'HANDLE_SOCKET_MESSAGE_CHANGE_USERNAME': case 'RECEIVE_ENCRYPTED_MESSAGE_CHANGE_USERNAME':
const newUsername2 = action.payload.payload.newUsername const newUsername2 = action.payload.payload.newUsername
const userId2 = action.payload.payload.id const userId2 = action.payload.payload.id
return { return {

View File

@ -12,7 +12,7 @@ const user = (state = initialState, action) => {
...action.payload, ...action.payload,
id: action.payload.publicKey.n, id: action.payload.publicKey.n,
} }
case 'SEND_SOCKET_MESSAGE_CHANGE_USERNAME': case 'SEND_ENCRYPTED_MESSAGE_CHANGE_USERNAME':
return { return {
...state, ...state,
username: action.payload.newUsername, username: action.payload.newUsername,

View File

@ -142,7 +142,7 @@ textarea
.activity-item .activity-item
margin-bottom: 15px margin-bottom: 15px
&.SEND_MESSAGE &.TEXT_MESSAGE
.chat-meta .chat-meta
font-size: 13px font-size: 13px
.timestamp .timestamp

View File

@ -75,11 +75,11 @@ export default class Socket {
} }
async handleSocket(socket) { async handleSocket(socket) {
socket.on('PAYLOAD', (payload) => { socket.on('ENCRYPTED_MESSAGE', (payload) => {
socket.to(this._roomId).emit('PAYLOAD', payload); socket.to(this._roomId).emit('ENCRYPTED_MESSAGE', payload);
}); });
socket.on('USER_ENTER', async payload => { socket.on('USER_ENTER', async (payload) => {
let room = await this.fetchRoom() let room = await this.fetchRoom()
if (_.isEmpty(room)) { if (_.isEmpty(room)) {
room = { room = {
@ -99,10 +99,8 @@ export default class Socket {
}] }]
} }
await this.saveRoom(newRoom) await this.saveRoom(newRoom)
getIO().to(this._roomId).emit('USER_ENTER', newRoom.users.map(u => ({
publicKey: u.publicKey, getIO().to(this._roomId).emit('USER_ENTER', newRoom);
isOwner: u.isOwner,
})));
}) })
socket.on('TOGGLE_LOCK_ROOM', async (data, callback) => { socket.on('TOGGLE_LOCK_ROOM', async (data, callback) => {