Skip to content
This repository has been archived by the owner on Oct 1, 2019. It is now read-only.

Commit

Permalink
Implement user conversations
Browse files Browse the repository at this point in the history
  • Loading branch information
voidxnull committed Dec 18, 2016
1 parent b6125a2 commit 70f4156
Show file tree
Hide file tree
Showing 12 changed files with 393 additions and 21 deletions.
2 changes: 2 additions & 0 deletions src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
37 changes: 37 additions & 0 deletions src/actions/user-messages.js
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/
// 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
};
}
10 changes: 10 additions & 0 deletions src/api/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
105 changes: 105 additions & 0 deletions src/components/tools/conversation.js
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/
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 (
<div className={className}>
<Time className="conversations_tool__time" timestamp={message.get('created_at')} />
{!hideAvatar &&
<Avatar className="conversations_tool__avatar" size={32} user={user} />
}
{message.get('text')}
</div>
);
}

export default class Conversation extends React.Component<void, Props, void> {
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 (
<Message
currentUser={currentUser}
hideAvatar={hideAvatar}
key={message.get('id')}
message={message}
selectedUser={selectedUser}
/>
);
});

return (
<div>
<div className="conversations_tool__messages">
{messageElements}
</div>
<form ref={c => this.form = c} onSubmit={this.handleSubmit}>
<textarea
className="conversations_tool__input"
name="text"
placeholder={'Type your message here, hit "enter" or "Send" button'}
/>
<input className="button button-red" type="submit" value="Send" />
</form>
</div>
);
}
}
77 changes: 77 additions & 0 deletions src/less/blocks/tools/conversations_tool.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
.conversations_tool {
&__messages {
display: flex;
flex-direction: column;
}

&__message {
position: relative;
display: flex;
margin-bottom: 20px;
padding: 20px 20px 30px 20px;
align-items: center;
background-color: white;
border: 1px solid @color__gray;
max-width: 60%;
min-width: 170px; // to fit the time

&-my {
align-self: flex-end;
flex-flow: row-reverse;

> .conversations_tool__avatar {
margin-left: 10px;
}

> .conversations_tool__time {
right: 20px;
}
}

&-their {
align-self: flex-start;

> .conversations_tool__avatar {
margin-right: 10px;
}

> .conversations_tool__time {
left: 20px;
}
}
}

&__avatar {
align-self: flex-start;
}

&__input {
display: block;
width: 100%;
margin-bottom: 10px;
}

&__time {
position: absolute;
bottom: 2px;
color: @color__gray;
font-size: 13px;
}
}
8 changes: 8 additions & 0 deletions src/less/blocks/tools/tools_item.less
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
&-selected {
background: #FD9315;
color: white;

> .tools_item__icon {
color: white;
}
}

&-clickable {
Expand All @@ -39,4 +43,8 @@
&__child-padded {
margin-left: @space;
}

&__icon {
color: @color__gray;
}
}
1 change: 1 addition & 0 deletions src/less/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
@import 'blocks/tools/tools_details';
@import 'blocks/tools/schools_tool';
@import 'blocks/tools/people_tool';
@import 'blocks/tools/conversations_tool';
@import 'blocks/v2/layout';
@import 'blocks/form';
@import 'blocks/sidebar';
Expand Down

0 comments on commit 70f4156

Please sign in to comment.