tag management works now
This commit is contained in:
@@ -1382,6 +1382,7 @@ ul.tabbar li.active > a:after {
|
|||||||
padding: 0 0.15rem 0 0.15rem;
|
padding: 0 0.15rem 0 0.15rem;
|
||||||
margin-left: 0.1rem;
|
margin-left: 0.1rem;
|
||||||
margin-right: 0.1rem;
|
margin-right: 0.1rem;
|
||||||
|
margin-bottom: 0.1rem;
|
||||||
border-radius: 0.15rem;
|
border-radius: 0.15rem;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
|
|||||||
+161
-35
@@ -286,6 +286,23 @@
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deep-shallow compare two arrays.
|
||||||
|
function arrayEqual(a, b) {
|
||||||
|
// Compare lengths first.
|
||||||
|
if (a.length != b.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Order of elements is ignored.
|
||||||
|
a.sort();
|
||||||
|
b.sort();
|
||||||
|
for (var i = 0, l = a.length; i < l; i++) {
|
||||||
|
if (a[i] !== b[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Convert a number of bytes to human-readable format.
|
// Convert a number of bytes to human-readable format.
|
||||||
function bytesToHumanSize(bytes) {
|
function bytesToHumanSize(bytes) {
|
||||||
if (!bytes || bytes == 0) {
|
if (!bytes || bytes == 0) {
|
||||||
@@ -795,9 +812,12 @@
|
|||||||
componentWillReceiveProps: function(newProps) {
|
componentWillReceiveProps: function(newProps) {
|
||||||
this.setState({
|
this.setState({
|
||||||
sortedChips: this.sortChips(newProps.chips, newProps.required),
|
sortedChips: this.sortChips(newProps.chips, newProps.required),
|
||||||
chipIndex: this.indexChips(newProps.chips),
|
chipIndex: this.indexChips(newProps.chips)
|
||||||
input: ''
|
|
||||||
});
|
});
|
||||||
|
if (newProps.chips.length > this.props.chips.length) {
|
||||||
|
// Chip added: clear input.
|
||||||
|
this.setState({input: ''});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Map chip index to user name
|
// Map chip index to user name
|
||||||
@@ -1296,6 +1316,7 @@
|
|||||||
<EditAccountView
|
<EditAccountView
|
||||||
login={this.props.login}
|
login={this.props.login}
|
||||||
onSubmit={this.props.onUpdateAccount}
|
onSubmit={this.props.onUpdateAccount}
|
||||||
|
onUpdateTags={this.props.onUpdateAccountTags}
|
||||||
onCancel={this.props.onCancel}
|
onCancel={this.props.onCancel}
|
||||||
onError={this.props.onError} /> :
|
onError={this.props.onError} /> :
|
||||||
|
|
||||||
@@ -1364,7 +1385,7 @@
|
|||||||
avatar: null,
|
avatar: null,
|
||||||
login: undefined,
|
login: undefined,
|
||||||
password: undefined,
|
password: undefined,
|
||||||
tagInput: '',
|
previousOnTags: undefined,
|
||||||
tags: []
|
tags: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -1377,12 +1398,20 @@
|
|||||||
address: Tinode.getCurrentUserID(),
|
address: Tinode.getCurrentUserID(),
|
||||||
auth: defacs.auth,
|
auth: defacs.auth,
|
||||||
anon: defacs.anon,
|
anon: defacs.anon,
|
||||||
tags: me.tags()
|
tags: me.tags(),
|
||||||
|
previousOnTags: me.onTagsUpdated,
|
||||||
|
showTagManager: false
|
||||||
});
|
});
|
||||||
|
me.onTagsUpdated = this.tnNewTags;
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
// Not needed?
|
var me = Tinode.getMeTopic();
|
||||||
|
me.onTagsUpdated = this.state.previousOnTags;
|
||||||
|
},
|
||||||
|
|
||||||
|
tnNewTags: function(tags) {
|
||||||
|
this.setState({tags: tags});
|
||||||
},
|
},
|
||||||
|
|
||||||
handleFullNameUpdate: function(fn) {
|
handleFullNameUpdate: function(fn) {
|
||||||
@@ -1398,34 +1427,30 @@
|
|||||||
this.props.onSubmit(null, vcard(this.state.fullName, img));
|
this.props.onSubmit(null, vcard(this.state.fullName, img));
|
||||||
},
|
},
|
||||||
|
|
||||||
handleTagInput: function(text) {
|
handleShowTagManager: function() {
|
||||||
// Check if user entered ',', ' ' or ';'
|
this.setState({showTagManager: true});
|
||||||
if (text.length > 0) {
|
},
|
||||||
var last = text[text.length-1];
|
|
||||||
if (last == ',' || last == ' ' || last == ';') {
|
handleHideTagManager: function() {
|
||||||
this.handleAddTag(text.substr(0, text.length-1));
|
this.setState({showTagManager: false});
|
||||||
}
|
},
|
||||||
|
|
||||||
|
handleTagsUpdated: function(tags) {
|
||||||
|
this.setState({showTagManager: false});
|
||||||
|
// Check if tags have actually changed.
|
||||||
|
if (arrayEqual(this.state.tags.slice(0), tags.slice(0))) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
},
|
this.props.onUpdateTags(tags);
|
||||||
handleAddTag: function(tag) {
|
|
||||||
var tags = this.state.tags.slice(0);
|
|
||||||
tags.push(tag);
|
|
||||||
this.setState({tags: tags});
|
|
||||||
},
|
|
||||||
handleRemoveTag: function(tag, index) {
|
|
||||||
var tags = this.state.tags.slice(0);
|
|
||||||
tags.splice(index, 1);
|
|
||||||
this.setState({tags: tags});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var tags = [];
|
var tags = [];
|
||||||
var instance = this;
|
|
||||||
this.state.tags.map(function(tag) {
|
this.state.tags.map(function(tag) {
|
||||||
tags.push({user: tag});
|
tags.push(<span className="badge" key={tags.length}>{tag}</span>);
|
||||||
});
|
});
|
||||||
if (tags.length == 0) {
|
if (tags.length == 0) {
|
||||||
tags = <i>none</i>;
|
tags = <i>No tags defined. Add some.</i>;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div id="edit-account" className="panel-form">
|
<div id="edit-account" className="panel-form">
|
||||||
@@ -1468,22 +1493,114 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="hr" />
|
<div className="hr" />
|
||||||
<div className="panel-form-column">
|
{this.state.showTagManager ?
|
||||||
<div><label className="small">Tags (user discovery):</label></div>
|
<TagManager
|
||||||
<ChipInput
|
tags={this.state.tags}
|
||||||
chips={tags}
|
onSubmit={this.handleTagsUpdated}
|
||||||
avatarDisabled={true}
|
onCancel={this.handleHideTagManager} />
|
||||||
prompt="Add tags"
|
:
|
||||||
onEnter={this.handleAddTag}
|
<div className="panel-form-column">
|
||||||
onChipRemoved={this.handleRemoveTag}
|
<div><label className="small">Tags (user discovery):</label></div>
|
||||||
filterFunc={this.handleTagInput} />
|
<a href="#" className="flat-button" onClick={this.handleShowTagManager}>
|
||||||
</div>
|
<i className="material-icons">edit</i> Manage tags
|
||||||
|
</a>
|
||||||
|
<span>{tags}</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
/* END EditAccount */
|
/* END EditAccount */
|
||||||
|
|
||||||
|
/* BEGIN TagManager: edit topic or user tags */
|
||||||
|
var TagManager = React.createClass({
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
tags: this.wrapTags(this.props.tags),
|
||||||
|
tagInput: '',
|
||||||
|
noTagsMessage: 'Add some tags'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
wrapTags: function(tags) {
|
||||||
|
var wrapped = [];
|
||||||
|
tags.map(function(tag) {
|
||||||
|
wrapped.push({user: tag});
|
||||||
|
});
|
||||||
|
return wrapped;
|
||||||
|
},
|
||||||
|
|
||||||
|
unwrapTags: function(tags) {
|
||||||
|
var unwrapped = [];
|
||||||
|
tags.map(function(tag) {
|
||||||
|
unwrapped.push(tag.user);
|
||||||
|
});
|
||||||
|
return unwrapped;
|
||||||
|
},
|
||||||
|
|
||||||
|
handleTagInput: function(text) {
|
||||||
|
this.setState({tagInput: text});
|
||||||
|
// Check if user entered ',', ' ' or ';'
|
||||||
|
if (text.length > 0) {
|
||||||
|
var last = text[text.length-1];
|
||||||
|
if (last == ',' || last == ' ' || last == ';') {
|
||||||
|
this.handleAddTag(text.substr(0, text.length-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleAddTag: function(tag) {
|
||||||
|
tag = tag.trim();
|
||||||
|
if (tag.length > 0) {
|
||||||
|
var tags = this.state.tags.slice(0);
|
||||||
|
tags.push({user: tag});
|
||||||
|
this.setState({tags: tags, tagInput: ''});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleRemoveTag: function(tag, index) {
|
||||||
|
var tags = this.state.tags.slice(0);
|
||||||
|
tags.splice(index, 1);
|
||||||
|
this.setState({tags: tags});
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSubmit: function() {
|
||||||
|
var tags = this.unwrapTags(this.state.tags);
|
||||||
|
var inp = this.state.tagInput.trim();
|
||||||
|
if (inp.length > 0) {
|
||||||
|
tags.push(inp);
|
||||||
|
}
|
||||||
|
this.props.onSubmit(tags);
|
||||||
|
},
|
||||||
|
|
||||||
|
handleCancel: function() {
|
||||||
|
this.props.onCancel();
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<div id="tag-manager">
|
||||||
|
<div className="panel-form-row">
|
||||||
|
<label className="small">Tags (user discovery)</label>
|
||||||
|
</div>
|
||||||
|
<ChipInput
|
||||||
|
chips={this.state.tags}
|
||||||
|
avatarDisabled={true}
|
||||||
|
prompt={this.state.noTagsMessage}
|
||||||
|
onEnter={this.handleAddTag}
|
||||||
|
onChipRemoved={this.handleRemoveTag}
|
||||||
|
filterFunc={this.handleTagInput} />
|
||||||
|
<div id="tag-manager-buttons" className="panel-form-row">
|
||||||
|
<button className="blue" onClick={this.handleSubmit}>OK</button>
|
||||||
|
<button className="white" onClick={this.handleCancel}>Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/* END TagManager */
|
||||||
|
|
||||||
/* BEGIN Contact list (list of topics) */
|
/* BEGIN Contact list (list of topics) */
|
||||||
/* A single topic */;
|
/* A single topic */;
|
||||||
var Contact = React.createClass({
|
var Contact = React.createClass({
|
||||||
@@ -3607,6 +3724,14 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleUpdateAccountTagsRequest: function(tags) {
|
||||||
|
var instance = this;
|
||||||
|
Tinode.getMeTopic().setMeta({tags: tags}).catch(function(err) {
|
||||||
|
instance.handleError(err.message, "err");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
// User chose Settings menu item.
|
// User chose Settings menu item.
|
||||||
handleSettings: function() {
|
handleSettings: function() {
|
||||||
this.setState({sidePanelSelected: this.state.myUserId ? 'edit-account' : 'settings'});
|
this.setState({sidePanelSelected: this.state.myUserId ? 'edit-account' : 'settings'});
|
||||||
@@ -3825,6 +3950,7 @@
|
|||||||
onLoginRequest={this.handleLoginRequest}
|
onLoginRequest={this.handleLoginRequest}
|
||||||
onCreateAccount={this.handleNewAccountRequest}
|
onCreateAccount={this.handleNewAccountRequest}
|
||||||
onUpdateAccount={this.handleUpdateAccountRequest}
|
onUpdateAccount={this.handleUpdateAccountRequest}
|
||||||
|
onUpdateAccountTags={this.handleUpdateAccountTagsRequest}
|
||||||
onTopicSelected={this.handleTopicSelected}
|
onTopicSelected={this.handleTopicSelected}
|
||||||
onCreateTopic={this.handleNewTopicRequest}
|
onCreateTopic={this.handleNewTopicRequest}
|
||||||
onNewTopic={this.handleNewTopic}
|
onNewTopic={this.handleNewTopic}
|
||||||
|
|||||||
Reference in New Issue
Block a user