separated contact list into a component

This commit is contained in:
or-else
2017-06-27 20:58:27 +03:00
parent b3ef0a856b
commit 933ede1220
2 changed files with 81 additions and 27 deletions
+16 -1
View File
@@ -461,6 +461,7 @@ ul.menu > li.separator:hover {
display: flex; display: flex;
padding: 0.35rem 0.25rem 0.5rem 0.35rem; padding: 0.35rem 0.25rem 0.5rem 0.35rem;
min-height: 3.5rem; min-height: 3.5rem;
border-bottom: 1px solid #eee;
} }
.contact-box > li:hover { .contact-box > li:hover {
background-color: #eceff1; /* blue-gray 50 highlight */ background-color: #eceff1; /* blue-gray 50 highlight */
@@ -1044,6 +1045,10 @@ ul.tabbar li.active > a:after {
color: rgba(250, 250, 250, 0.8); /* default text color #FAFAFA, gray 50 */ color: rgba(250, 250, 250, 0.8); /* default text color #FAFAFA, gray 50 */
} }
.lettertile:hover {
color: white;
}
/* Colors of letter tiles */ /* Colors of letter tiles */
.lettertile.color0 { .lettertile.color0 {
background-color: #ef9a9a; background-color: #ef9a9a;
@@ -1073,7 +1078,7 @@ ul.tabbar li.active > a:after {
background-color: #c5e1a5; background-color: #c5e1a5;
} }
.lettertile.color9 { .lettertile.color9 {
background-color: #fff59d; background-color: #f0e57d;
} }
.lettertile.color10 { .lettertile.color10 {
background-color: #f48fb1; background-color: #f48fb1;
@@ -1161,3 +1166,13 @@ ul.tabbar li.active > a:after {
background-color: #c0c0c0; background-color: #c0c0c0;
border-radius: 50%; border-radius: 50%;
} }
.chip {
display: inline-block;
background-color: white;
height: 2rem;
line-height: 2;
border-radius: 1rem;
padding: 0 1rem;
background-color: #ccc;
}
+53 -14
View File
@@ -885,6 +885,11 @@
/* ContactsView holds all contacts-related stuff */ /* ContactsView holds all contacts-related stuff */
var ContactsView = React.createClass({ var ContactsView = React.createClass({
getInitialState: function() {
return {
contactList: this.prepareContactList()
};
},
componentWillMount: function() { componentWillMount: function() {
var me = Tinode.getMeTopic(); var me = Tinode.getMeTopic();
me.onContactUpdate = this.tnMeContactUpdate; me.onContactUpdate = this.tnMeContactUpdate;
@@ -900,13 +905,13 @@
// Reactions to updates to the contact list. // Reactions to updates to the contact list.
tnMeContactUpdate: function(what, cont) { tnMeContactUpdate: function(what, cont) {
if (what === "on" || what === "off" || what === "read") { if (what === "on" || what === "off" || what === "read") {
this.forceUpdate(); this.resetContactList();
} else if (what === "msg") { } else if (what === "msg") {
// New message received // New message received
// Skip update if the topic is currently open, otherwise the badge will annoyingly flash. // Skip update if the topic is currently open, otherwise the badge will annoyingly flash.
if (this.props.topicSelected !== cont.topic) { if (this.props.topicSelected !== cont.topic) {
this.forceUpdate(); this.resetContactList();
} }
} else if (what === "recv") { } else if (what === "recv") {
// Explicitly ignoring "recv" -- it causes no visible updates to contact list. // Explicitly ignoring "recv" -- it causes no visible updates to contact list.
@@ -918,7 +923,7 @@
this.props.onTopicSelected(null); this.props.onTopicSelected(null);
} }
// Redraw without the deleted topic. // Redraw without the deleted topic.
this.forceUpdate(); this.resetContactList();
} else { } else {
// TODO(gene): handle other types of notifications: // TODO(gene): handle other types of notifications:
// * ua -- user agent changes (may display a pictogram for mobile/desktop) // * ua -- user agent changes (may display a pictogram for mobile/desktop)
@@ -927,27 +932,60 @@
console.log("changed (not updating for it): " + what + " in: " + cont.topic); console.log("changed (not updating for it): " + what + " in: " + cont.topic);
} }
}, },
tnInvite: function(invite) { tnInvite: function(invite) {
// TODO(gene): implement invite handling // TODO(gene): implement invite handling
console.log("Got invite:"); console.log("Got invite:");
console.log(invite); console.log(invite);
}, },
tnMeSubsUpdated: function(names) { tnMeSubsUpdated: function(names) {
this.forceUpdate(); this.resetContactList();
}, },
prepareContactList: function() {
var contacts = [];
Tinode.getMeTopic().contacts(function(c) {
c.unread = c.seq;
if (c.read > 0) {
c.unread -= c.read;
}
contacts.push(c);
}, this);
return contacts;
},
resetContactList: function() {
this.setState({contactList: this.prepareContactList()});
},
render: function() {
return (
<ContactList
contacts={this.state.contactList}
emptyListMessage={<span>You have no chats<br />¯\_(ツ)_/¯</span>}
topicSelected={this.props.topicSelected}
onTopicSelected={this.props.onTopicSelected}
showContextMenu={this.props.showContextMenu} />
);
}
});
/* END Contact list */
/* BEGIN ContactList: component for showing a list of contacts,
* such as a list of group members group chat */
var ContactList = React.createClass({
render: function() { render: function() {
var contactNodes = []; var contactNodes = [];
Tinode.getMeTopic().contacts(function(c) { if (this.props.contacts && this.props.contacts.length > 0) {
var unread = c.seq; this.props.contacts.map(function(c) {
if (c.read > 0) {
unread -= c.read;
}
contactNodes.push( contactNodes.push(
<Contact <Contact
title={c.public ? c.public.fn : null} title={c.public ? c.public.fn : null}
avatar={makeImageUrl(c.public ? c.public.photo : null)} avatar={makeImageUrl(c.public ? c.public.photo : null)}
comment={c.private} comment={c.private}
unread={unread} now={c.online} unread={c.unread} now={c.online}
selected={this.props.topicSelected} selected={this.props.topicSelected}
onSelected={this.props.onTopicSelected} onSelected={this.props.onTopicSelected}
showContextMenu={this.props.showContextMenu} showContextMenu={this.props.showContextMenu}
@@ -955,6 +993,7 @@
key={c.topic} /> key={c.topic} />
); );
}, this); }, this);
}
return ( return (
<div className="contacts-panel"> <div className="contacts-panel">
@@ -963,14 +1002,14 @@
{contactNodes} {contactNodes}
</ul> </ul>
: :
<p className="center-medium-text"> <div className="center-medium-text">
You have no chats<br />¯\_(ツ)_/¯ {this.props.emptyListMessage}
</p>} </div>}
</div> </div>
); );
} }
}); });
/* END Contact list */ /* END ContactList */
/* BEGIN Create new topic and invite users or send an invite */ /* BEGIN Create new topic and invite users or send an invite */
var NewTopicView = React.createClass({ var NewTopicView = React.createClass({