more refactoring of topic and account editing

This commit is contained in:
or-else
2017-06-29 14:02:16 +03:00
parent 933ede1220
commit 45eb91765b
2 changed files with 219 additions and 98 deletions
+190 -88
View File
@@ -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&times;128</div>}
this.props.readOnly && this.props.uid ?
<LetterTile avatar={true} topic={this.props.uid} title={this.props.title} /> :
<div className="blank">128&times;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