topic invites work correctly now, UI fixes
This commit is contained in:
+34
-1
@@ -1161,7 +1161,7 @@ ul.tabbar li.active > a:after {
|
|||||||
/* Miscellaneous */
|
/* Miscellaneous */
|
||||||
|
|
||||||
/* Badge with the number of unread messages */
|
/* Badge with the number of unread messages */
|
||||||
.badge {
|
.unread {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
@@ -1176,6 +1176,39 @@ ul.tabbar li.active > a:after {
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Badge with a label, like [you], [muted], etc */
|
||||||
|
.badge {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
border: 1px solid #666;
|
||||||
|
background-color: #eee;
|
||||||
|
color: #666;
|
||||||
|
padding: 0 0.15rem 0 0.15rem;
|
||||||
|
margin-left: 0.1rem;
|
||||||
|
margin-right: 0.1rem;
|
||||||
|
border-radius: 0.15rem;
|
||||||
|
display: inline-block;
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.green {
|
||||||
|
border-color: #383;
|
||||||
|
background-color: #efe;
|
||||||
|
color: #383;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.yellow {
|
||||||
|
border-color: #660;
|
||||||
|
background-color: #ffe;
|
||||||
|
color: #660;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.red {
|
||||||
|
border-color: #933;
|
||||||
|
background-color: #fee;
|
||||||
|
color: #933;
|
||||||
|
}
|
||||||
|
|
||||||
/* Letter tile base style, responsive square box */
|
/* Letter tile base style, responsive square box */
|
||||||
.lettertile {
|
.lettertile {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
+95
-34
@@ -131,8 +131,6 @@
|
|||||||
|
|
||||||
// Function is used by context menu to set permissions.
|
// Function is used by context menu to set permissions.
|
||||||
function topicPermissionSetter(mode, topicName, uid) {
|
function topicPermissionSetter(mode, topicName, uid) {
|
||||||
console.log("topicPermissionSetter called with arguments:");
|
|
||||||
console.log(arguments);
|
|
||||||
var topic = Tinode.getTopic(topicName);
|
var topic = Tinode.getTopic(topicName);
|
||||||
if (!topic) {
|
if (!topic) {
|
||||||
console.log("Topic not found: " + topicName);
|
console.log("Topic not found: " + topicName);
|
||||||
@@ -527,6 +525,7 @@
|
|||||||
<div className="panel-form-column">
|
<div className="panel-form-column">
|
||||||
{this.props.userTitle ?
|
{this.props.userTitle ?
|
||||||
<ul className="contact-box"><Contact
|
<ul className="contact-box"><Contact
|
||||||
|
item={this.props.item}
|
||||||
title={this.props.userTitle}
|
title={this.props.userTitle}
|
||||||
avatar={makeImageUrl(this.props.userAvatar ? this.props.userAvatar : null)} /></ul> : null}
|
avatar={makeImageUrl(this.props.userAvatar ? this.props.userAvatar : null)} /></ul> : null}
|
||||||
<label className="small">Permissions</label>
|
<label className="small">Permissions</label>
|
||||||
@@ -1210,6 +1209,19 @@
|
|||||||
}
|
}
|
||||||
var online = this.props.now ? "online" : "offline";
|
var online = this.props.now ? "online" : "offline";
|
||||||
var avatar = this.props.avatar ? this.props.avatar : true;
|
var avatar = this.props.avatar ? this.props.avatar : true;
|
||||||
|
var badges = [];
|
||||||
|
if (this.props.badges && this.props.badges.length > 0) {
|
||||||
|
var count = 0;
|
||||||
|
this.props.badges.map(function(b) {
|
||||||
|
var style = "badge" + (b.color ? " " + b.color : "");
|
||||||
|
badges.push(<span className={style} key={count}>{b.name}</span>);
|
||||||
|
count ++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this.props.mode) {
|
||||||
|
badges.push(<span className="badge" key="mode">{this.props.mode}</span>);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li className={!this.props.showCheckmark && this.props.selected ? "selected" : null}
|
<li className={!this.props.showCheckmark && this.props.selected ? "selected" : null}
|
||||||
onClick={this.handleClick}>
|
onClick={this.handleClick}>
|
||||||
@@ -1224,9 +1236,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div className="text-box">
|
<div className="text-box">
|
||||||
<div><span className="contact-title">{title}</span>
|
<div><span className="contact-title">{title}</span>
|
||||||
{this.props.showUnread && (this.props.unread > 0) ?
|
{this.props.unread > 0 ? <Contact.Unread count={this.props.unread} /> : null}
|
||||||
<Contact.Unread count={this.props.unread} /> : null}</div>
|
</div>
|
||||||
{this.props.comment ? <div className="contact-comment">{this.props.comment}</div> : null}
|
{this.props.comment ? <div className="contact-comment">{this.props.comment}</div> : null}
|
||||||
|
<span>{badges}</span>
|
||||||
</div>
|
</div>
|
||||||
{this.props.showContextMenu ?
|
{this.props.showContextMenu ?
|
||||||
<span className="menuTrigger">
|
<span className="menuTrigger">
|
||||||
@@ -1245,12 +1258,29 @@
|
|||||||
var showUnreadBadge = null;
|
var showUnreadBadge = null;
|
||||||
if (this.props.count > 0) {
|
if (this.props.count > 0) {
|
||||||
var count = this.props.count > 9 ? "9+" : this.props.count;
|
var count = this.props.count > 9 ? "9+" : this.props.count;
|
||||||
showUnreadBadge = <span className="badge">{count}</span>;
|
showUnreadBadge = <span className="unread">{count}</span>;
|
||||||
}
|
}
|
||||||
return showUnreadBadge;
|
return showUnreadBadge;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* Contact's labels: [you], [muted], [blocked], etc */
|
||||||
|
Contact.Badges = React.createClass({
|
||||||
|
render: function() {
|
||||||
|
var badges = null;
|
||||||
|
if (this.props.badges && this.props.badges.length > 0) {
|
||||||
|
var count = 0;
|
||||||
|
badges = [];
|
||||||
|
this.props.badges.map(function(b) {
|
||||||
|
var style = "badge" + (b.color ? " " + b.color : "");
|
||||||
|
badges.push(<span className={style} key={count}>{b.name}</span>);
|
||||||
|
count ++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return badges;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/* ContactsView holds all contacts-related stuff */
|
/* ContactsView holds all contacts-related stuff */
|
||||||
var ContactsView = React.createClass({
|
var ContactsView = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
@@ -1261,7 +1291,6 @@
|
|||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
var me = Tinode.getMeTopic();
|
var me = Tinode.getMeTopic();
|
||||||
me.onContactUpdate = this.tnMeContactUpdate;
|
me.onContactUpdate = this.tnMeContactUpdate;
|
||||||
me.onData = this.tnInvite;
|
|
||||||
me.onSubsUpdated = this.tnMeSubsUpdated;
|
me.onSubsUpdated = this.tnMeSubsUpdated;
|
||||||
},
|
},
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
@@ -1301,12 +1330,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
tnInvite: function(invite) {
|
|
||||||
// TODO(gene): implement invite handling
|
|
||||||
console.log("Got invite:");
|
|
||||||
console.log(invite);
|
|
||||||
},
|
|
||||||
|
|
||||||
tnMeSubsUpdated: function(names) {
|
tnMeSubsUpdated: function(names) {
|
||||||
this.resetContactList();
|
this.resetContactList();
|
||||||
},
|
},
|
||||||
@@ -1314,10 +1337,7 @@
|
|||||||
prepareContactList: function() {
|
prepareContactList: function() {
|
||||||
var contacts = [];
|
var contacts = [];
|
||||||
Tinode.getMeTopic().contacts(function(c) {
|
Tinode.getMeTopic().contacts(function(c) {
|
||||||
c.unread = c.seq;
|
c.unread = c.seq - (c.read > 0 ? c.read : 0);
|
||||||
if (c.read > 0) {
|
|
||||||
c.unread -= c.read;
|
|
||||||
}
|
|
||||||
contacts.push(c);
|
contacts.push(c);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
@@ -1347,6 +1367,7 @@
|
|||||||
* such as a list of group members in a group chat */
|
* such as a list of group members in a group chat */
|
||||||
var ContactList = React.createClass({
|
var ContactList = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
|
var me = Tinode.getCurrentUserID();
|
||||||
var contactNodes = [];
|
var contactNodes = [];
|
||||||
var instance = this;
|
var instance = this;
|
||||||
var showCheckmark = Array.isArray(this.props.topicSelected);
|
var showCheckmark = Array.isArray(this.props.topicSelected);
|
||||||
@@ -1354,7 +1375,6 @@
|
|||||||
if (this.props.contacts && this.props.contacts.length > 0) {
|
if (this.props.contacts && this.props.contacts.length > 0) {
|
||||||
this.props.contacts.map(function(c) {
|
this.props.contacts.map(function(c) {
|
||||||
var key = c.topic ? c.topic : c.user;
|
var key = c.topic ? c.topic : c.user;
|
||||||
|
|
||||||
// If filter function is provided, filter out the items
|
// If filter function is provided, filter out the items
|
||||||
// which don't satisfy the condition.
|
// which don't satisfy the condition.
|
||||||
if (instance.props.filterFunc && instance.props.filter) {
|
if (instance.props.filterFunc && instance.props.filter) {
|
||||||
@@ -1374,16 +1394,24 @@
|
|||||||
(this.props.topicSelected.indexOf(key) > -1) :
|
(this.props.topicSelected.indexOf(key) > -1) :
|
||||||
(this.props.topicSelected === key);
|
(this.props.topicSelected === key);
|
||||||
|
|
||||||
|
var mode = this.props.showMode && c.acs ? c.acs.getMode() : null;
|
||||||
|
|
||||||
|
var badges = (key === me ? [{name:'you',color:'green'}] : null);
|
||||||
|
|
||||||
|
var comment = Array.isArray(c.private) ? c.private.join(", ") : c.private;
|
||||||
|
|
||||||
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={comment}
|
||||||
unread={c.unread} now={c.online}
|
unread={this.props.showUnread ? c.unread : 0}
|
||||||
|
now={c.online}
|
||||||
|
mode={mode}
|
||||||
|
badges={badges}
|
||||||
showCheckmark={showCheckmark}
|
showCheckmark={showCheckmark}
|
||||||
selected={selected}
|
selected={selected}
|
||||||
showOnline={this.props.showOnline}
|
showOnline={this.props.showOnline}
|
||||||
showUnread={this.props.showUnread}
|
|
||||||
onSelected={this.props.onTopicSelected}
|
onSelected={this.props.onTopicSelected}
|
||||||
showContextMenu={this.props.showContextMenu}
|
showContextMenu={this.props.showContextMenu}
|
||||||
item={key}
|
item={key}
|
||||||
@@ -1414,7 +1442,6 @@
|
|||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
members: this.props.members,
|
members: this.props.members,
|
||||||
contacts: this.props.contacts,
|
|
||||||
index: this.indexMembers(this.props.members),
|
index: this.indexMembers(this.props.members),
|
||||||
contactFilter: '',
|
contactFilter: '',
|
||||||
noContactsMessage: 'You have no contacts :-(',
|
noContactsMessage: 'You have no contacts :-(',
|
||||||
@@ -1586,14 +1613,14 @@
|
|||||||
handleContactSelected: function(sel) {
|
handleContactSelected: function(sel) {
|
||||||
if (this.state.tabSelected === "p2p") {
|
if (this.state.tabSelected === "p2p") {
|
||||||
this.props.onCreateTopic(sel, undefined);
|
this.props.onCreateTopic(sel, undefined);
|
||||||
} else {
|
|
||||||
// TODO(gene): implement handling of group invites
|
|
||||||
console.log("handle group invite " + sel);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleGroupSubmit: function(name, dataUrl) {
|
handleGroupSubmit: function(name, dataUrl) {
|
||||||
this.props.onCreateTopic(undefined, vcard(name, dataUrl));
|
this.props.onCreateTopic(undefined, vcard(name, dataUrl));
|
||||||
},
|
},
|
||||||
|
handleGroupSubscribe: function(topicName) {
|
||||||
|
this.props.onCreateTopic(topicName);
|
||||||
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div className="flex-column">
|
<div className="flex-column">
|
||||||
@@ -1604,9 +1631,14 @@
|
|||||||
<li className={this.state.tabSelected === "grp" ? "active" : null}>
|
<li className={this.state.tabSelected === "grp" ? "active" : null}>
|
||||||
<a href="#" data-id="grp" onClick={this.handleTabClick}>group</a>
|
<a href="#" data-id="grp" onClick={this.handleTabClick}>group</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li className={this.state.tabSelected === "byId" ? "active" : null}>
|
||||||
|
<a href="#" data-id="byId" onClick={this.handleTabClick}>by id</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{this.state.tabSelected === "grp" ?
|
{this.state.tabSelected === "grp" ?
|
||||||
<NewTopicView.Group onSubmit={this.handleGroupSubmit} /> :
|
<NewTopicView.Group onSubmit={this.handleGroupSubmit} /> :
|
||||||
|
this.state.tabSelected === "byId" ?
|
||||||
|
<NewTopicView.ById onSubmit={this.handleGroupSubscribe} /> :
|
||||||
<div className="flex-column">
|
<div className="flex-column">
|
||||||
<NewTopicView.SearchContacts type="p2p"
|
<NewTopicView.SearchContacts type="p2p"
|
||||||
searchQuery={this.state.searchQuery}
|
searchQuery={this.state.searchQuery}
|
||||||
@@ -1716,6 +1748,42 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
NewTopicView.ById = React.createClass({
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
groupId: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
handleChange: function(e) {
|
||||||
|
this.setState({groupId: e.target.value});
|
||||||
|
},
|
||||||
|
handleKeyPress: function(e) {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
this.handleSubmit(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleSubmit: function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (this.state.groupId && this.state.groupId.trim()) {
|
||||||
|
this.props.onSubmit(this.state.groupId.trim());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<div className="panel-form">
|
||||||
|
<div className="panel-form-row">
|
||||||
|
<input type="text" placeholder="Group ID"
|
||||||
|
value={this.state.groupId} onChange={this.handleChange}
|
||||||
|
onKeyPress={this.handleKeyPress} required />
|
||||||
|
</div>
|
||||||
|
<div className="dialog-buttons">
|
||||||
|
<button className="blue" onClick={this.handleSubmit}>Subscribe</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
/* END Create new topic and invite users or send an invite */
|
/* END Create new topic and invite users or send an invite */
|
||||||
|
|
||||||
/* BEGIN InfoView: panel with topic/user info */
|
/* BEGIN InfoView: panel with topic/user info */
|
||||||
@@ -1881,9 +1949,6 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleLaunchPermissionsEditor: function(which, uid) {
|
handleLaunchPermissionsEditor: function(which, uid) {
|
||||||
console.log("handleLaunchPermissionsEditor called with arguments");
|
|
||||||
console.log(arguments);
|
|
||||||
|
|
||||||
var toEdit, toCompare, toSkip, titleEdit, titleCompare, userTitle, userAvatar
|
var toEdit, toCompare, toSkip, titleEdit, titleCompare, userTitle, userAvatar
|
||||||
switch (which) {
|
switch (which) {
|
||||||
case 'mode':
|
case 'mode':
|
||||||
@@ -1976,9 +2041,6 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleContextMenu: function(item, x, y) {
|
handleContextMenu: function(item, x, y) {
|
||||||
console.log("handleContextMenu called with agruments");
|
|
||||||
console.log(arguments);
|
|
||||||
|
|
||||||
var instance = this;
|
var instance = this;
|
||||||
var topic = Tinode.getTopic(this.props.topic);
|
var topic = Tinode.getTopic(this.props.topic);
|
||||||
if (!topic) {
|
if (!topic) {
|
||||||
@@ -2025,6 +2087,7 @@
|
|||||||
modeTitle={this.state.editedPermissionsTitle}
|
modeTitle={this.state.editedPermissionsTitle}
|
||||||
compareTitle={this.state.immutablePermissionsTitle}
|
compareTitle={this.state.immutablePermissionsTitle}
|
||||||
userTitle={this.state.userPermissionsTitle}
|
userTitle={this.state.userPermissionsTitle}
|
||||||
|
item={this.state.userPermissionsEdited}
|
||||||
userAvatar={this.state.userPermissionsAvatar}
|
userAvatar={this.state.userPermissionsAvatar}
|
||||||
skip={this.state.editedPermissionsSkipped}
|
skip={this.state.editedPermissionsSkipped}
|
||||||
onSubmit={this.handlePermissionsChanged}
|
onSubmit={this.handlePermissionsChanged}
|
||||||
@@ -2139,6 +2202,7 @@
|
|||||||
topicSelected={this.state.selectedContact}
|
topicSelected={this.state.selectedContact}
|
||||||
showOnline={false}
|
showOnline={false}
|
||||||
showUnread={false}
|
showUnread={false}
|
||||||
|
showMode={true}
|
||||||
noScroll={true}
|
noScroll={true}
|
||||||
onTopicSelected={this.handleMemberSelected}
|
onTopicSelected={this.handleMemberSelected}
|
||||||
showContextMenu={this.state.admin ? this.handleContextMenu : false}
|
showContextMenu={this.state.admin ? this.handleContextMenu : false}
|
||||||
@@ -2927,9 +2991,6 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleShowContextMenu: function(topicName, y, x, uid, menuItems) {
|
handleShowContextMenu: function(topicName, y, x, uid, menuItems) {
|
||||||
console.log("handleShowContextMenu called with arguments");
|
|
||||||
console.log(arguments);
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
contextMenuVisible: true,
|
contextMenuVisible: true,
|
||||||
contextMenuClickAt: {x: x, y: y},
|
contextMenuClickAt: {x: x, y: y},
|
||||||
@@ -2989,7 +3050,7 @@
|
|||||||
|
|
||||||
if (added && added.length > 0) {
|
if (added && added.length > 0) {
|
||||||
added.map(function(uid) {
|
added.map(function(uid) {
|
||||||
topic.invite(uid, null, "Join my group!");
|
topic.invite(uid, null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user