diff --git a/src/actions/index.js b/src/actions/index.js index 3713bc6a..ff572b84 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -35,3 +35,5 @@ export const users = require('./users'); export const quotes = require('./quotes'); export const tools = require('./tools'); + +export const userMessages = require('./user-messages'); diff --git a/src/actions/user-messages.js b/src/actions/user-messages.js new file mode 100644 index 00000000..613ceb90 --- /dev/null +++ b/src/actions/user-messages.js @@ -0,0 +1,37 @@ +/* + This file is a part of libertysoil.org website + Copyright (C) 2016 Loki Education (Social Enterprise) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +// When updating the whole message chain. +export const SET_USER_MESSAGES = 'SET_USER_MESSAGES'; +// When sending a new message. +export const ADD_USER_MESSAGE = 'ADD_USER_MESSAGE'; + +export function setUserMessages(userId, messages) { + return { + type: SET_USER_MESSAGES, + messages, + userId + }; +} + +export function addUserMessage(userId, message) { + return { + type: ADD_USER_MESSAGE, + message, + userId + }; +} diff --git a/src/api/controller.js b/src/api/controller.js index 93fe30eb..40aedff6 100644 --- a/src/api/controller.js +++ b/src/api/controller.js @@ -3314,6 +3314,16 @@ export default class ApiController { .orderBy('created_at', 'ASC'); }) .fetch(); + await UserMessage.collection() + .query(qb => { + qb + .where({ sender_id: ctx.session.user, reciever_id: ctx.params.id }) + // TODO: Replace with a single orWhere() when knex is upgraded from 0.10 + .orWhere({ sender_id: ctx.params.id }) + .andWhere({ reciever_id: ctx.session.user }) + .orderBy('created_at', 'ASC'); + }) + .fetch(); ctx.body = messages; } diff --git a/src/components/tools/conversation.js b/src/components/tools/conversation.js new file mode 100644 index 00000000..ef7a23fb --- /dev/null +++ b/src/components/tools/conversation.js @@ -0,0 +1,105 @@ +/* + This file is a part of libertysoil.org website + Copyright (C) 2016 Loki Education (Social Enterprise) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +import React, { PropTypes } from 'react'; + +import Avatar from '../user/avatar'; +import Time from '../time'; +import { Immutable as ImmutablePropType } from '../../prop-types/common'; +import { User as UserPropType } from '../../prop-types/users'; + + +function Message({ currentUser, selectedUser, message, hideAvatar = false }) { + const isMyMessage = message.get('sender_id') === currentUser.get('id'); + let className = 'conversations_tool__message'; + if (isMyMessage) { + className += ' conversations_tool__message-my'; + } else { + className += ' conversations_tool__message-their'; + } + + let user = currentUser; + if (!isMyMessage) { + user = selectedUser; + } + + return ( +
+
+ ); +} + +export default class Conversation extends React.Component { + static propTypes = { + currentUser: ImmutablePropType(UserPropType.isRequired), + messages: ImmutablePropType(PropTypes.shape({})), + selectedUser: ImmutablePropType(UserPropType) + }; + + handleSubmit = (e) => { + e.preventDefault(); + this.props.onSend(this.props.selectedUser.get('id'), this.form.text.value); + this.form.text.value = ''; + }; + + render() { + const { + currentUser, + messages, + selectedUser, + } = this.props; + + if (!selectedUser) { + return null; + } + + const messageElements = messages.map((message, index) => { + const hideAvatar = index > 0 && messages.getIn([index - 1, 'sender_id']) === message.get('sender_id'); + + return ( + + ); + }); + + return ( +
+
+ {messageElements} +
+
this.form = c} onSubmit={this.handleSubmit}> +