separated contact list into a component
This commit is contained in:
+16
-1
@@ -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
@@ -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({
|
||||||
|
|||||||
Reference in New Issue
Block a user