diff options
author | 2018-06-21 14:59:56 +0300 | |
---|---|---|
committer | 2023-01-13 10:37:53 +0300 | |
commit | bc2e876c592d5b3c117108baf5a5a58905510eae (patch) | |
tree | 29cf37494d6bd3f79cd7819ca58f97875142b923 /vnext/src/components | |
parent | 586d67c8e43970cc8c6e936f9eda48df5128efa8 (diff) |
Add PM components
Diffstat (limited to 'vnext/src/components')
-rw-r--r-- | vnext/src/components/Chat.js | 72 | ||||
-rw-r--r-- | vnext/src/components/Contact.js | 16 | ||||
-rw-r--r-- | vnext/src/components/Contacts.js | 69 | ||||
-rw-r--r-- | vnext/src/components/MessageInput.js | 2 | ||||
-rw-r--r-- | vnext/src/components/PM.js | 22 |
5 files changed, 180 insertions, 1 deletions
diff --git a/vnext/src/components/Chat.js b/vnext/src/components/Chat.js new file mode 100644 index 00000000..79425c12 --- /dev/null +++ b/vnext/src/components/Chat.js @@ -0,0 +1,72 @@ +import React from 'react'; +import moment from 'moment'; + +import PM from './PM'; +import MessageInput from './MessageInput'; + +export default class Chat extends React.Component { + constructor(props) { + super(props); + + this.state = { + chats: [] + }; + this.loadChat = this.loadChat.bind(this); + } + componentWillMount() { + this.loadChat(this.props.match.params.user); + } + + loadChat(uname) { + const { hash } = this.props.visitor; + this.setState({ + chats: [] + }); + if (hash && uname) { + fetch(`https://api.juick.com/pm?uname=${uname}&hash=${hash}`) + .then(response => response.json()) + .then(jsonResponse => { + this.setState({ + chats: jsonResponse + }); + }); + } + } + + render() { + const { chats } = this.state; + const uname = this.props.match.params.user; + return ( + <div id="content"> + <article> + + { uname ? ( + <div className="chatroom"> + <ul style={chatStyle} ref="chats"> + { + chats.map((chat) => + <PM key={moment.utc(chat.timestamp).valueOf()} chat={chat} /> + ) + } + </ul> + <MessageInput data={{}} onSend={()=>{}}/> + </div> + ) : ( + <div className="chatroom no-selection"><p>No chat selected</p></div> + ) + } + </article> + </div> + ) + } +} + +const chatStyle = { + boxSizing: 'border-box', + padding: '0 20px', + overflowY: 'scroll', + height: '450px', + display: 'flex', + flexDirection: 'column-reverse', + width: '100%' +} diff --git a/vnext/src/components/Contact.js b/vnext/src/components/Contact.js new file mode 100644 index 00000000..0e969cc1 --- /dev/null +++ b/vnext/src/components/Contact.js @@ -0,0 +1,16 @@ +import React from 'react'; + +import Avatar from './Avatar'; + +export default class Contact extends React.Component { + + render() { + const { user } = this.props; + return ( + <React.Fragment> + <Avatar user={user} link={`/pm/${user.uname}`} /> + {user.uname }{ user.unreadCount && <span className="badge">{user.unreadCount}</span>} + </React.Fragment> + ); + } +} diff --git a/vnext/src/components/Contacts.js b/vnext/src/components/Contacts.js new file mode 100644 index 00000000..300e60eb --- /dev/null +++ b/vnext/src/components/Contacts.js @@ -0,0 +1,69 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; + + +import Contact from './Contact.js'; + +export default class Contacts extends React.Component { + constructor(props) { + super(props); + this.state = { + pms: [] + }; + } + componentWillMount() { + this.refreshChats(); + } + + refreshChats() { + fetch(`https://api.juick.com/groups_pms?hash=${this.props.visitor.hash}`) + .then(response => response.json()) + .then(jsonResponse => { + this.setState({ + isLoading: false, + pms: jsonResponse.pms + }); + }); + } + render() { + const { pms } = this.state; + const user = this.props.visitor; + return ( + <div style={wrapperStyle} className="msg-cont"> + <ul style={chatListStyle} ref="chats"> + { + pms && pms.map((chat) => + <li key={chat.uname} style={chatTitleStyle}> + <Contact key={chat.uname} user={chat} /> + </li> + ) + } + </ul> + </div> + ); + } +} + +const wrapperStyle = { + display: 'flex', + backgroundColor: '#fff' +} + +const chatListStyle = { + boxSizing: 'border-box', + padding: '0 20px', + overflowY: 'scroll', + display: 'flex', + alignItems: 'center', + flexDirection: 'column', + width: '100%' +} + +const chatTitleStyle = { + width: '100%', + padding: '3px 6px', + textAlign: 'left', + background: '#fff', + color: '#222', + borderBottom: '1px solid #eee' +}
\ No newline at end of file diff --git a/vnext/src/components/MessageInput.js b/vnext/src/components/MessageInput.js index 71802985..ef740e41 100644 --- a/vnext/src/components/MessageInput.js +++ b/vnext/src/components/MessageInput.js @@ -105,7 +105,7 @@ const activeStyle = { }; const inputBarStyle = { - border: '1px solid #DDD', + border: '1px solid #ddd', display: 'flex', alignItems: 'center', padding: '3px', diff --git a/vnext/src/components/PM.js b/vnext/src/components/PM.js new file mode 100644 index 00000000..44b81129 --- /dev/null +++ b/vnext/src/components/PM.js @@ -0,0 +1,22 @@ +import React from 'react'; + +import Avatar from './Avatar'; +import { format } from '../utils/embed'; + +export default function PM(props) { + const {chat} = props; + return ( + <li style={chatItemStyle}> + <Avatar user={chat.user} /> + <p dangerouslySetInnerHTML={{ __html: format(chat.body) }} /> + </li> + ); +} + +const chatItemStyle = { + padding: '5px 13px', + fontSize: '14px', + listStyle: 'none', + margin: '10px 0', + boxShadow: '0 0 3px rgba(0,0,0, 0.16)' +}
\ No newline at end of file |