diff options
Diffstat (limited to 'web/react')
-rw-r--r-- | web/react/components/access_history_modal.jsx | 2 | ||||
-rw-r--r-- | web/react/components/activity_log_modal.jsx | 5 | ||||
-rw-r--r-- | web/react/components/create_comment.jsx | 65 | ||||
-rw-r--r-- | web/react/components/create_post.jsx | 8 | ||||
-rw-r--r-- | web/react/components/edit_channel_modal.jsx | 18 | ||||
-rw-r--r-- | web/react/components/setting_picture.jsx | 6 | ||||
-rw-r--r-- | web/react/components/signup_team.jsx | 4 | ||||
-rw-r--r-- | web/react/components/signup_team_complete.jsx | 2 | ||||
-rw-r--r-- | web/react/components/team_settings.jsx | 3 | ||||
-rw-r--r-- | web/react/components/user_settings.jsx | 4 | ||||
-rw-r--r-- | web/react/stores/post_store.jsx | 28 |
11 files changed, 115 insertions, 30 deletions
diff --git a/web/react/components/access_history_modal.jsx b/web/react/components/access_history_modal.jsx index b23b3213f..462f046f6 100644 --- a/web/react/components/access_history_modal.jsx +++ b/web/react/components/access_history_modal.jsx @@ -64,7 +64,7 @@ module.exports = React.createClass({ <div>{"URL: " + currentAudit.action.replace("/api/v1", "")}</div> </div> : - <a href="#" onClick={this.handleMoreInfo.bind(this, i)}>More info</a> + <a href="#" className="theme" onClick={this.handleMoreInfo.bind(this, i)}>More info</a> } </div> {i < this.state.audits.length - 1 ? diff --git a/web/react/components/activity_log_modal.jsx b/web/react/components/activity_log_modal.jsx index d6f8f40eb..7cce807a9 100644 --- a/web/react/components/activity_log_modal.jsx +++ b/web/react/components/activity_log_modal.jsx @@ -68,6 +68,9 @@ module.exports = React.createClass({ else if (currentSession.props.platform === "Macintosh" || currentSession.props.platform === "iPhone") { devicePicture = "fa fa-apple"; } + else if (currentSession.props.platform === "Linux") { + devicePicture = "fa fa-linux"; + } activityList[i] = ( <div className="activity-log__table"> @@ -83,7 +86,7 @@ module.exports = React.createClass({ <div>{"Session ID: " + currentSession.alt_id}</div> </div> : - <a href="#" onClick={this.handleMoreInfo.bind(this, i)}>More info</a> + <a className="theme" href="#" onClick={this.handleMoreInfo.bind(this, i)}>More info</a> } </div> </div> diff --git a/web/react/components/create_comment.jsx b/web/react/components/create_comment.jsx index 6ed0f0b34..3f8e9ed2e 100644 --- a/web/react/components/create_comment.jsx +++ b/web/react/components/create_comment.jsx @@ -5,6 +5,7 @@ var client = require('../utils/client.jsx'); var AsyncClient =require('../utils/async_client.jsx'); var SocketStore = require('../stores/socket_store.jsx'); var ChannelStore = require('../stores/channel_store.jsx'); +var PostStore = require('../stores/post_store.jsx'); var Textbox = require('./textbox.jsx'); var MsgTyping = require('./msg_typing.jsx'); var FileUpload = require('./file_upload.jsx'); @@ -43,6 +44,7 @@ module.exports = React.createClass({ client.createPost(post, ChannelStore.getCurrent(), function(data) { + PostStore.storeCommentDraft(this.props.rootId, null); this.setState({ messageText: '', submitting: false, post_error: null, server_error: null }); this.clearPreviews(); AsyncClient.getPosts(true, this.props.channelId); @@ -82,16 +84,33 @@ module.exports = React.createClass({ } }, handleUserInput: function(messageText) { + var draft = PostStore.getCommentDraft(this.props.rootId); + if (!draft) { + draft = { previews: [], uploadsInProgress: 0}; + } + draft.message = messageText; + PostStore.storeCommentDraft(this.props.rootId, draft); + $(".post-right__scroll").scrollTop($(".post-right__scroll")[0].scrollHeight); $(".post-right__scroll").perfectScrollbar('update'); this.setState({messageText: messageText}); }, handleFileUpload: function(newPreviews) { + var draft = PostStore.getCommentDraft(this.props.rootId); + if (!draft) { + draft = { message: '', uploadsInProgress: 0, previews: []} + } + $(".post-right__scroll").scrollTop($(".post-right__scroll")[0].scrollHeight); $(".post-right__scroll").perfectScrollbar('update'); - var oldPreviews = this.state.previews; + var previews = this.state.previews.concat(newPreviews); var num = this.state.uploadsInProgress; - this.setState({previews: oldPreviews.concat(newPreviews), uploadsInProgress:num-1}); + + draft.previews = previews; + draft.uploadsInProgress = num-1; + PostStore.storeCommentDraft(this.props.rootId, draft); + + this.setState({previews: previews, uploadsInProgress: num-1}); }, handleUploadError: function(err) { this.setState({ server_error: err }); @@ -107,10 +126,43 @@ module.exports = React.createClass({ break; } } + + var draft = PostStore.getCommentDraft(); + if (!draft) { + draft = { message: '', uploadsInProgress: 0}; + } + draft.previews = previews; + PostStore.storeCommentDraft(draft); + this.setState({previews: previews}); }, getInitialState: function() { - return { messageText: '', uploadsInProgress: 0, previews: [], submitting: false }; + PostStore.clearCommentDraftUploads(); + + var draft = PostStore.getCommentDraft(this.props.rootId); + messageText = ''; + uploadsInProgress = 0; + previews = []; + if (draft) { + messageText = draft.message; + uploadsInProgress = draft.uploadsInProgress; + previews = draft.previews + } + return { messageText: messageText, uploadsInProgress: uploadsInProgress, previews: previews, submitting: false }; + }, + componentWillReceiveProps: function(newProps) { + if(newProps.rootId !== this.props.rootId) { + var draft = PostStore.getCommentDraft(newProps.rootId); + messageText = ''; + uploadsInProgress = 0; + previews = []; + if (draft) { + messageText = draft.message; + uploadsInProgress = draft.uploadsInProgress; + previews = draft.previews + } + this.setState({ messageText: messageText, uploadsInProgress: uploadsInProgress, previews: previews }); + } }, setUploads: function(val) { var oldInProgress = this.state.uploadsInProgress @@ -126,6 +178,13 @@ module.exports = React.createClass({ var numToUpload = newInProgress - oldInProgress; if (numToUpload <= 0) return 0; + var draft = PostStore.getCommentDraft(this.props.rootId); + if (!draft) { + draft = { message: '', previews: []}; + } + draft.uploadsInProgress = newInProgress; + PostStore.storeCommentDraft(this.props.rootId, draft); + this.setState({uploadsInProgress: newInProgress}); return numToUpload; diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx index a2448b569..91d070958 100644 --- a/web/react/components/create_post.jsx +++ b/web/react/components/create_post.jsx @@ -55,7 +55,7 @@ module.exports = React.createClass({ post.message, false, function(data) { - PostStore.storeDraft(data.channel_id, user_id, null); + PostStore.storeDraft(data.channel_id, null); this.setState({ messageText: '', submitting: false, post_error: null, previews: [], server_error: null, limit_error: null }); if (data.goto_location.length > 0) { @@ -78,7 +78,7 @@ module.exports = React.createClass({ client.createPost(post, ChannelStore.getCurrent(), function(data) { - PostStore.storeDraft(data.channel_id, data.user_id, null); + PostStore.storeDraft(data.channel_id, null); this.setState({ messageText: '', submitting: false, post_error: null, previews: [], server_error: null, limit_error: null }); this.resizePostHolder(); AsyncClient.getPosts(true); @@ -209,7 +209,7 @@ module.exports = React.createClass({ $(window).trigger('resize'); }, handleFileUpload: function(newPreviews, channel_id) { - var draft = PostStore.getDraft(channel_id, UserStore.getCurrentId()); + var draft = PostStore.getDraft(channel_id); if (!draft) { draft = {} draft['message'] = ''; @@ -230,7 +230,7 @@ module.exports = React.createClass({ } else { draft['previews'] = draft['previews'].concat(newPreviews); draft['uploadsInProgress'] = draft['uploadsInProgress'] > 0 ? draft['uploadsInProgress'] - 1 : 0; - PostStore.storeDraft(channel_id, UserStore.getCurrentId(), draft); + PostStore.storeDraft(channel_id, draft); } }, handleUploadError: function(err) { diff --git a/web/react/components/edit_channel_modal.jsx b/web/react/components/edit_channel_modal.jsx index c0818959a..d055feacd 100644 --- a/web/react/components/edit_channel_modal.jsx +++ b/web/react/components/edit_channel_modal.jsx @@ -6,17 +6,24 @@ var AsyncClient = require('../utils/async_client.jsx'); module.exports = React.createClass({ handleEdit: function(e) { - var data = {} + var data = {}; data["channel_id"] = this.state.channel_id; if (data["channel_id"].length !== 26) return; data["channel_description"] = this.state.description.trim(); Client.updateChannelDesc(data, function(data) { + this.setState({ server_error: "" }); AsyncClient.getChannels(true); + $(this.refs.modal.getDOMNode()).modal('hide'); }.bind(this), function(err) { - AsyncClient.dispatchError(err, "updateChannelDesc"); + if (err.message === "Invalid channel_description parameter") { + this.setState({ server_error: "This description is too long, please enter a shorter one" }); + } + else { + this.setState({ server_error: err.message }); + } }.bind(this) ); }, @@ -27,13 +34,15 @@ module.exports = React.createClass({ var self = this; $(this.refs.modal.getDOMNode()).on('show.bs.modal', function(e) { var button = e.relatedTarget; - self.setState({ description: $(button).attr('data-desc'), title: $(button).attr('data-title'), channel_id: $(button).attr('data-channelid') }); + self.setState({ description: $(button).attr('data-desc'), title: $(button).attr('data-title'), channel_id: $(button).attr('data-channelid'), server_error: "" }); }); }, getInitialState: function() { return { description: "", title: "", channel_id: "" }; }, render: function() { + var server_error = this.state.server_error ? <div className='form-group has-error'><br/><label className='control-label'>{ this.state.server_error }</label></div> : null; + return ( <div className="modal fade" ref="modal" id="edit_channel" role="dialog" aria-hidden="true"> <div className="modal-dialog"> @@ -44,10 +53,11 @@ module.exports = React.createClass({ </div> <div className="modal-body"> <textarea className="form-control no-resize" rows="6" ref="channelDesc" maxLength="1024" value={this.state.description} onChange={this.handleUserInput}></textarea> + { server_error } </div> <div className="modal-footer"> <button type="button" className="btn btn-default" data-dismiss="modal">Close</button> - <button type="button" className="btn btn-primary" data-dismiss="modal" onClick={this.handleEdit}>Save</button> + <button type="button" className="btn btn-primary" onClick={this.handleEdit}>Save</button> </div> </div> </div> diff --git a/web/react/components/setting_picture.jsx b/web/react/components/setting_picture.jsx index 62c889b7f..6cfb74d60 100644 --- a/web/react/components/setting_picture.jsx +++ b/web/react/components/setting_picture.jsx @@ -25,9 +25,9 @@ module.exports = React.createClass({ var img = null; if (this.props.picture) { - img = (<img ref="image" className="col-xs-5 profile-img" src=""/>); + img = (<img ref="image" className="profile-img" src=""/>); } else { - img = (<img ref="image" className="col-xs-5 profile-img" src={this.props.src}/>); + img = (<img ref="image" className="profile-img" src={this.props.src}/>); } var self = this; @@ -37,7 +37,7 @@ module.exports = React.createClass({ <li className="col-xs-12 section-title">{this.props.title}</li> <li className="col-xs-offset-3 col-xs-8"> <ul className="setting-list"> - <li className="row setting-list-item"> + <li className="setting-list-item"> {img} </li> <li className="setting-list-item"> diff --git a/web/react/components/signup_team.jsx b/web/react/components/signup_team.jsx index cf982cc1e..362f79163 100644 --- a/web/react/components/signup_team.jsx +++ b/web/react/components/signup_team.jsx @@ -69,7 +69,9 @@ module.exports = React.createClass({ { name_error } </div> { server_error } - <button className="btn btn-md btn-primary" type="submit">Sign up for Free</button> + <div className="form-group"> + <button className="btn btn-md btn-primary" type="submit">Sign up for Free</button> + </div> <div className="form-group form-group--small"> <span><a href="/find_team">{"Find my " + strings.Team}</a></span> </div> diff --git a/web/react/components/signup_team_complete.jsx b/web/react/components/signup_team_complete.jsx index 9ceeb6324..3e8a57308 100644 --- a/web/react/components/signup_team_complete.jsx +++ b/web/react/components/signup_team_complete.jsx @@ -246,7 +246,7 @@ TeamURLPage = React.createClass({ <h2>{utils.toTitleCase(strings.Team) + " URL"}</h2> <div className={ name_error ? "form-group has-error" : "form-group" }> <div className="row"> - <div className="col-sm-9"> + <div className="col-sm-11"> <div className="input-group"> <span className="input-group-addon">{ window.location.origin + "/" }</span> <input type="text" ref="name" className="form-control" placeholder="" maxLength="128" defaultValue={this.props.state.team.name} autoFocus={true} onFocus={this.handleFocus}/> diff --git a/web/react/components/team_settings.jsx b/web/react/components/team_settings.jsx index 166b1f38b..3bbb5e892 100644 --- a/web/react/components/team_settings.jsx +++ b/web/react/components/team_settings.jsx @@ -73,13 +73,12 @@ var FeatureTab = React.createClass({ var inputs = []; inputs.push( - <div className="col-sm-12"> + <div> <div className="btn-group" data-toggle="buttons-radio"> <button className={"btn btn-default "+valetActive[0]} onClick={function(){self.handleValetRadio("true")}}>On</button> <button className={"btn btn-default "+valetActive[1]} onClick={function(){self.handleValetRadio("false")}}>Off</button> </div> <div><br/>Valet is a preview feature for enabling a non-user account limited to basic member permissions that can be manipulated by 3rd parties.<br/><br/>IMPORTANT: The preview version of Valet should not be used without a secure connection and a trusted 3rd party, since user credentials are used to connect. OAuth2 will be used in the final release.</div> - <br></br> </div> ); diff --git a/web/react/components/user_settings.jsx b/web/react/components/user_settings.jsx index ad890334e..1fbbf16ed 100644 --- a/web/react/components/user_settings.jsx +++ b/web/react/components/user_settings.jsx @@ -577,9 +577,9 @@ var SecurityTab = React.createClass({ { passwordSection } <div className="divider-dark"/> <br></br> - <a data-toggle="modal" className="security-links" data-target="#access-history" href="#" onClick={this.handleHistoryOpen}><i className="fa fa-clock-o"></i>View Access History</a> + <a data-toggle="modal" className="security-links theme" data-target="#access-history" href="#" onClick={this.handleHistoryOpen}><i className="fa fa-clock-o"></i>View Access History</a> <b> </b> - <a data-toggle="modal" className="security-links" data-target="#activity-log" href="#" onClick={this.handleDevicesOpen}><i className="fa fa-globe"></i>View and Logout of Active Devices</a> + <a data-toggle="modal" className="security-links theme" data-target="#activity-log" href="#" onClick={this.handleDevicesOpen}><i className="fa fa-globe"></i>View and Logout of Active Devices</a> </div> </div> ); diff --git a/web/react/stores/post_store.jsx b/web/react/stores/post_store.jsx index 1b3e1a119..0745fcdc3 100644 --- a/web/react/stores/post_store.jsx +++ b/web/react/stores/post_store.jsx @@ -149,19 +149,23 @@ var PostStore = assign({}, EventEmitter.prototype, { }, storeCurrentDraft: function(draft) { var channel_id = ChannelStore.getCurrentId(); - var user_id = UserStore.getCurrentId(); - BrowserStore.setItem("draft_" + channel_id + "_" + user_id, draft); + BrowserStore.setItem("draft_" + channel_id, draft); }, getCurrentDraft: function() { var channel_id = ChannelStore.getCurrentId(); - var user_id = UserStore.getCurrentId(); - return BrowserStore.getItem("draft_" + channel_id + "_" + user_id); + return BrowserStore.getItem("draft_" + channel_id); }, - storeDraft: function(channel_id, user_id, draft) { - BrowserStore.setItem("draft_" + channel_id + "_" + user_id, draft); + storeDraft: function(channel_id, draft) { + BrowserStore.setItem("draft_" + channel_id, draft); }, - getDraft: function(channel_id, user_id) { - return BrowserStore.getItem("draft_" + channel_id + "_" + user_id); + getDraft: function(channel_id) { + return BrowserStore.getItem("draft_" + channel_id); + }, + storeCommentDraft: function(parent_post_id, draft) { + BrowserStore.setItem("comment_draft_" + parent_post_id, draft); + }, + getCommentDraft: function(parent_post_id) { + return BrowserStore.getItem("comment_draft_" + parent_post_id); }, clearDraftUploads: function() { BrowserStore.actionOnItemsWithPrefix("draft_", function (key, value) { @@ -170,6 +174,14 @@ var PostStore = assign({}, EventEmitter.prototype, { BrowserStore.setItem(key, value); } }); + }, + clearCommentDraftUploads: function() { + BrowserStore.actionOnItemsWithPrefix("comment_draft_", function (key, value) { + if (value) { + value.uploadsInProgress = 0; + BrowserStore.setItem(key, value); + } + }); } }); |