more refactoring of topic and account editing
This commit is contained in:
+190
-88
@@ -244,9 +244,13 @@
|
||||
this.setState({text: e.target.value});
|
||||
},
|
||||
|
||||
handleKeyPress: function(e) {
|
||||
handleKeyDown: function(e) {
|
||||
if (e.keyCode === 27) {
|
||||
// Escape pressed
|
||||
this.setState({text: this.props.text, active: false});
|
||||
} else if (e.keyCode === 13) {
|
||||
// Enter pressed
|
||||
this.handleEditingFinished();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -257,8 +261,9 @@
|
||||
|
||||
handleEditingFinished: function() {
|
||||
this.setState({active: false});
|
||||
if (this.state.text !== this.props.text) {
|
||||
this.props.onFinished(this.state.text);
|
||||
var text = this.state.text.trim();
|
||||
if (text !== this.props.text) {
|
||||
this.props.onFinished(text);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -271,8 +276,8 @@
|
||||
spanText = this.props.placeholder;
|
||||
spanClass += " placeholder";
|
||||
}
|
||||
if (spanText.length > 16) {
|
||||
spanText = spanText.substring(0, 16) + "...";
|
||||
if (spanText.length > 20) {
|
||||
spanText = spanText.substring(0, 19) + "...";
|
||||
}
|
||||
return (
|
||||
this.state.active ?
|
||||
@@ -280,7 +285,7 @@
|
||||
value={this.state.text}
|
||||
placeholder={this.props.placeholder}
|
||||
onChange={this.handeTextChange}
|
||||
onKeyPress={this.handleKeyPress}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
onBlur={this.handleEditingFinished}
|
||||
autoFocus />
|
||||
:
|
||||
@@ -448,8 +453,8 @@
|
||||
}
|
||||
return (
|
||||
<form className="panel-form" onSubmit={this.handleSubmit}>
|
||||
<div className="panel-form-one">
|
||||
<div className="panel-form-two">
|
||||
<div className="panel-form-row">
|
||||
<div className="panel-form-column">
|
||||
<input type="text" placeholder="Login"
|
||||
value={this.state.login} onChange={this.handleLoginChange} required autoFocus />
|
||||
<input type="password" placeholder="Password"
|
||||
@@ -506,7 +511,9 @@
|
||||
<div className="avatar-upload">
|
||||
{this.state.dataUrl ?
|
||||
<img src={this.state.dataUrl} className="preview" /> :
|
||||
<div className="blank">128×128</div>}
|
||||
this.props.readOnly && this.props.uid ?
|
||||
<LetterTile avatar={true} topic={this.props.uid} title={this.props.title} /> :
|
||||
<div className="blank">128×128</div>}
|
||||
{this.props.readOnly ? null :
|
||||
<input type="file" id="file-input-avatar" className="inputfile hidden"
|
||||
accept="image/*" onChange={this.handleFileUpload} />}
|
||||
@@ -726,8 +733,6 @@
|
||||
var EditAccountView = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
updatedDesc: false,
|
||||
updatedPasswd: false,
|
||||
address: null,
|
||||
fullName: undefined,
|
||||
avatar: null,
|
||||
@@ -743,7 +748,6 @@
|
||||
fullName: me.public ? me.public.fn : undefined,
|
||||
avatar: makeImageUrl(me.public ? me.public.photo : null),
|
||||
address: Tinode.getCurrentUserID(),
|
||||
login: this.props.login,
|
||||
auth: defacs.auth,
|
||||
anon: defacs.anon
|
||||
});
|
||||
@@ -758,29 +762,23 @@
|
||||
},
|
||||
|
||||
handleFullNameUpdate: function(fn) {
|
||||
this.setState({updatedDesc: true, fullName: fn});
|
||||
this.setState({fullName: fn});
|
||||
this.props.onSubmit(null, vcard(fn, this.state.avatar));
|
||||
},
|
||||
handlePasswordUpdate: function(pwd) {
|
||||
this.setState({updatedPasswd: true, password: pwd});
|
||||
this.setState({password: pwd});
|
||||
this.props.onSubmit(pwd, null);
|
||||
},
|
||||
handleImageChanged: function(img) {
|
||||
this.setState({updatedDesc: true, avatar: img});
|
||||
},
|
||||
|
||||
handleSubmit: function(e) {
|
||||
e.preventDefault();
|
||||
if (this.state.updatedDesc || this.state.updatedPasswd) {
|
||||
this.props.onSubmit(
|
||||
this.state.updatedPasswd ? this.state.password : null,
|
||||
this.state.updatedDesc ? vcard(this.state.fullName, this.state.avatar) : null);
|
||||
}
|
||||
this.setState({avatar: img});
|
||||
this.props.onSubmit(null, vcard(this.state.fullName, img));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<form id="edit-account" className="panel-form" onSubmit={this.handleSubmit}>
|
||||
<div className="panel-form-one">
|
||||
<div className="panel-form-two">
|
||||
<div id="edit-account" className="panel-form">
|
||||
<div className="panel-form-row">
|
||||
<div className="panel-form-column">
|
||||
<div><label className="small">Your name</label></div>
|
||||
<div><InPlaceEdit
|
||||
placeholder="Full name, e.g. John Doe"
|
||||
@@ -794,22 +792,28 @@
|
||||
</div>
|
||||
<AvatarUpload
|
||||
avatar={this.state.avatar}
|
||||
uid={this.state.address}
|
||||
title={this.state.fullName}
|
||||
onImageChanged={this.handleImageChanged} />
|
||||
</div>
|
||||
<div>
|
||||
<div>Login: <tt>{this.state.login}</tt></div>
|
||||
<div>Address: <tt>{this.state.address}</tt></div>
|
||||
|
||||
<div><label className="small">Default access mode:</label></div>
|
||||
<div className="panel-form-column">
|
||||
<div className="panel-form-row">
|
||||
<label>Login:</label>
|
||||
<tt>{this.props.login}</tt>
|
||||
</div>
|
||||
<div className="panel-form-row">
|
||||
<label>Address:</label>
|
||||
<tt>{this.state.address}</tt>
|
||||
</div>
|
||||
<div>
|
||||
<label className="small">Default access mode:</label>
|
||||
</div>
|
||||
<div className="quoted">
|
||||
<div>Auth: <tt>{this.state.auth}</tt></div>
|
||||
<div>Anon: <tt>{this.state.anon}</tt></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="dialog-buttons">
|
||||
<button className="blue" type="submit">Update</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -845,7 +849,7 @@
|
||||
<div className="avatar-box">
|
||||
<LetterTile
|
||||
avatar={avatar} title={this.props.title} topic={this.props.topic} />
|
||||
<span className={online} />
|
||||
{this.props.showOnline ? <span className={online} /> : null}
|
||||
</div>
|
||||
<div className="text-box">
|
||||
<div><span className="contact-title">{title}</span>
|
||||
@@ -966,6 +970,7 @@
|
||||
contacts={this.state.contactList}
|
||||
emptyListMessage={<span>You have no chats<br />¯\_(ツ)_/¯</span>}
|
||||
topicSelected={this.props.topicSelected}
|
||||
showOnline={true}
|
||||
onTopicSelected={this.props.onTopicSelected}
|
||||
showContextMenu={this.props.showContextMenu} />
|
||||
);
|
||||
@@ -980,6 +985,10 @@
|
||||
var contactNodes = [];
|
||||
if (this.props.contacts && this.props.contacts.length > 0) {
|
||||
this.props.contacts.map(function(c) {
|
||||
var key = c.topic ? c.topic : c.user;
|
||||
if (!key) {
|
||||
console.log("empty key!");
|
||||
}
|
||||
contactNodes.push(
|
||||
<Contact
|
||||
title={c.public ? c.public.fn : null}
|
||||
@@ -987,10 +996,11 @@
|
||||
comment={c.private}
|
||||
unread={c.unread} now={c.online}
|
||||
selected={this.props.topicSelected}
|
||||
showOnline={this.props.showOnline}
|
||||
onSelected={this.props.onTopicSelected}
|
||||
showContextMenu={this.props.showContextMenu}
|
||||
topic={c.topic}
|
||||
key={c.topic} />
|
||||
topic={key}
|
||||
key={key} />
|
||||
);
|
||||
}, this);
|
||||
}
|
||||
@@ -1109,8 +1119,8 @@
|
||||
}
|
||||
return (
|
||||
<form className="panel-form" onSubmit={this.handleSubmit}>
|
||||
<div className="panel-form-one">
|
||||
<div className="panel-form-two">
|
||||
<div className="panel-form-row">
|
||||
<div className="panel-form-column">
|
||||
<input type="text" placeholder="Name of the topic to create"
|
||||
value={this.state.fn} onChange={this.handleFnChange} autoFocus required />
|
||||
<div className="dialog-buttons">
|
||||
@@ -1152,7 +1162,7 @@
|
||||
render: function() {
|
||||
return (
|
||||
<form className="panel-form" onSubmit={this.handleFindContacts}>
|
||||
<div className="panel-form-one">
|
||||
<div className="panel-form-row">
|
||||
<input type="text" placeholder="Comma separated list: email:alice@example.com, tel:17025550003..."
|
||||
value={this.state.search} onChange={this.handleSearchChange} onKeyPress={this.handleKeyPress} required />
|
||||
<a href="#" onClick={this.handleSearch}>
|
||||
@@ -1211,11 +1221,14 @@
|
||||
getInitialState: function() {
|
||||
return {
|
||||
owner: false,
|
||||
updated: false,
|
||||
address: null,
|
||||
groupTopic: undefined,
|
||||
fullName: undefined,
|
||||
avatar: null,
|
||||
private: null
|
||||
private: null,
|
||||
selectedContact: null,
|
||||
muted: undefined,
|
||||
contactList: []
|
||||
};
|
||||
},
|
||||
componentWillMount: function() {
|
||||
@@ -1225,6 +1238,31 @@
|
||||
}
|
||||
|
||||
topic.onMetaDesc = this.onMetaDesc;
|
||||
topic.onSubsUpdated = this.onSubsUpdated;
|
||||
this.resetDesc(topic);
|
||||
this.resetSubs(topic);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
var topic = Tinode.getTopic(this.props.topic);
|
||||
if (!topic) {
|
||||
return;
|
||||
}
|
||||
topic.onMetaDesc = undefined;
|
||||
topic.onSubsUpdated = undefined;
|
||||
},
|
||||
|
||||
resetSubs: function(topic) {
|
||||
var contacts = [];
|
||||
topic.subscribers(function(sub){
|
||||
contacts.push(sub);
|
||||
}, this);
|
||||
this.setState({
|
||||
contactList: contacts
|
||||
});
|
||||
},
|
||||
|
||||
resetDesc: function(topic) {
|
||||
var defacs = topic.getDefaultAccess() || {};
|
||||
var acs = topic.getAccessMode();
|
||||
this.setState({
|
||||
@@ -1233,30 +1271,62 @@
|
||||
avatar: makeImageUrl(topic.public ? topic.public.photo : null),
|
||||
private: topic.private,
|
||||
address: topic.name,
|
||||
groupTopic: (topic.getType() === "grp"),
|
||||
auth: defacs.auth,
|
||||
anon: defacs.anon
|
||||
anon: defacs.anon,
|
||||
muted: acs && acs.isMuted()
|
||||
});
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
|
||||
onMetaDesc: function(desc) {
|
||||
var topic = Tinode.getTopic(this.props.topic);
|
||||
if (!topic) {
|
||||
return;
|
||||
}
|
||||
topic.onMetaDesc = undefined;
|
||||
this.resetDesc(topic);
|
||||
},
|
||||
|
||||
onMetaDesc: function(desc) {
|
||||
// Update form with changed values
|
||||
onSubsUpdated: function() {
|
||||
var topic = Tinode.getTopic(this.props.topic);
|
||||
if (!topic) {
|
||||
return;
|
||||
}
|
||||
this.resetSubs(topic);
|
||||
},
|
||||
|
||||
handleFullNameUpdate: function(fn) {
|
||||
this.setState({updated: true, fullName: fn});
|
||||
this.setState({fullName: fn});
|
||||
this.props.onSubmit(this.props.topic,
|
||||
vcard(fn, this.state.avatar),
|
||||
null);
|
||||
},
|
||||
|
||||
handlePrivateUpdate: function(priv) {
|
||||
this.setState({updated: true, private: priv});
|
||||
this.setState({private: priv});
|
||||
this.props.onSubmit(this.props.topic,
|
||||
null,
|
||||
priv);
|
||||
},
|
||||
|
||||
handleImageChanged: function(img) {
|
||||
this.setState({updated: true, avatar: img});
|
||||
this.setState({avatar: img});
|
||||
this.props.onSubmit(this.props.topic,
|
||||
vcard(this.state.fullName, img),
|
||||
priv);
|
||||
},
|
||||
|
||||
handleMuted: function(e) {
|
||||
var checked = e.target.checked;
|
||||
this.setState({muted: checked});
|
||||
this.props.onChangePermissions(this.props.topic, checked ? "-P" : "+P");
|
||||
},
|
||||
|
||||
handleMemberSelected: function(uid) {
|
||||
this.setState({selectedContact: uid});
|
||||
},
|
||||
|
||||
handleContextMenu: function(item) {
|
||||
console.log("context menu: " + item);
|
||||
},
|
||||
|
||||
handleSubmit: function(e) {
|
||||
@@ -1277,43 +1347,63 @@
|
||||
<MenuCancel onCancel={this.props.onCancel} />
|
||||
</div>
|
||||
</div>
|
||||
<form id="edit-account" className="panel-form" onSubmit={this.handleSubmit}>
|
||||
<div className="panel-form-one">
|
||||
<div className="panel-form-two">
|
||||
<div><label className="small">Name</label></div>
|
||||
<div><InPlaceEdit
|
||||
placeholder="Group name"
|
||||
readOnly={!this.state.owner}
|
||||
text={this.state.fullName}
|
||||
onFinished={this.handleFullNameUpdate} /></div>
|
||||
<div><label className="small">Private comment</label></div>
|
||||
<div><InPlaceEdit
|
||||
placeholder="Visible to you only"
|
||||
text={this.state.private}
|
||||
onFinished={this.handlePrivateUpdate} /></div>
|
||||
</div>
|
||||
<AvatarUpload
|
||||
avatar={this.state.avatar}
|
||||
onImageChanged={this.handleImageChanged} />
|
||||
<div className="panel-form-row">
|
||||
<div className="panel-form-column">
|
||||
<div><label className="small">Name</label></div>
|
||||
<div><InPlaceEdit
|
||||
placeholder="Group name"
|
||||
readOnly={!this.state.owner}
|
||||
text={this.state.fullName}
|
||||
onFinished={this.handleFullNameUpdate} /></div>
|
||||
<div><label className="small">Private comment</label></div>
|
||||
<div><InPlaceEdit
|
||||
placeholder="Visible to you only"
|
||||
text={this.state.private}
|
||||
onFinished={this.handlePrivateUpdate} /></div>
|
||||
</div>
|
||||
<div>
|
||||
<div>Address: <tt>{this.state.address}</tt></div>
|
||||
{this.state.auth || this.state.anon ?
|
||||
<div>
|
||||
<div><label className="small">Default access mode:</label></div>
|
||||
<div className="quoted">
|
||||
<div>Auth: <tt>{this.state.auth}</tt></div>
|
||||
<div>Anon: <tt>{this.state.anon}</tt></div>
|
||||
</div>
|
||||
<AvatarUpload
|
||||
avatar={this.state.avatar}
|
||||
readOnly={!this.state.owner}
|
||||
uid={this.props.topic}
|
||||
title={this.state.fullName}
|
||||
onImageChanged={this.handleImageChanged} />
|
||||
</div>
|
||||
<div className="panel-form-column">
|
||||
<div className="panel-form-row">
|
||||
<label>Address:</label>
|
||||
<tt>{this.state.address}</tt>
|
||||
</div>
|
||||
<div className="panel-form-row">
|
||||
<label htmlFor="info-muted">Muted:</label>
|
||||
<input id="info-muted" type="checkbox" checked={this.state.muted}
|
||||
onChange={this.handleMuted} />
|
||||
</div>
|
||||
{this.state.auth || this.state.anon ?
|
||||
<div>
|
||||
<div><label className="small">Default access mode:</label></div>
|
||||
<div className="quoted">
|
||||
<div>Auth: <tt>{this.state.auth}</tt></div>
|
||||
<div>Anon: <tt>{this.state.anon}</tt></div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
<div className="dialog-buttons">
|
||||
<button className="blue" type="submit">Update</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
{this.state.groupTopic ?
|
||||
<div className="panel-form-row">
|
||||
<label className="small">Group members:</label>
|
||||
</div> : null}
|
||||
{this.state.groupTopic ?
|
||||
<ContactList
|
||||
contacts={this.state.contactList}
|
||||
emptyListMessage="No members"
|
||||
topicSelected={this.state.selectedContact}
|
||||
showOnline={false}
|
||||
onTopicSelected={this.handleMemberSelected}
|
||||
showContextMenu={this.handleContextMenu}
|
||||
/>
|
||||
: null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1897,7 +1987,6 @@
|
||||
},
|
||||
|
||||
handleUpdateAccountRequest: function(password, pub, priv) {
|
||||
this.handleSidepanelCancel();
|
||||
if (pub || priv) {
|
||||
Tinode.getMeTopic().setMeta({desc: {public: pub, private: priv}});
|
||||
}
|
||||
@@ -1964,6 +2053,18 @@
|
||||
var topic = Tinode.getTopic(topicName);
|
||||
topic.setMeta({desc: {public: pub, private: priv}});
|
||||
},
|
||||
|
||||
handleChangePermissions: function(topicName, want) {
|
||||
var topic = Tinode.getTopic(topicName);
|
||||
if (!topic) {
|
||||
return;
|
||||
}
|
||||
|
||||
var am = topic.getAccessMode();
|
||||
am.updateWant(want);
|
||||
topic.setMeta({sub: {mode: am.getWant()}});
|
||||
},
|
||||
|
||||
/** Called when the user enters a contact into the contact search field in the NewAccount panel
|
||||
@param query {Array} is an array of contacts to search for
|
||||
*/
|
||||
@@ -2122,6 +2223,7 @@
|
||||
topic={this.state.topicSelected}
|
||||
onSubmit={this.handleTopicUpdateRequest}
|
||||
onCancel={this.handleHideInfoView}
|
||||
onChangePermissions={this.handleChangePermissions}
|
||||
/>
|
||||
:
|
||||
null
|
||||
|
||||
Reference in New Issue
Block a user