From 009df5bad5f55c7e4c698f9dab8420d00a7ae71e Mon Sep 17 00:00:00 2001 From: JoramWilander Date: Mon, 22 Jun 2015 08:35:24 -0400 Subject: fixes mm-1318 only allow 5 files to be uploaded at a time --- web/react/components/create_comment.jsx | 28 +++++++++++++++++---------- web/react/components/create_post.jsx | 34 ++++++++++++++++++++------------- web/react/components/file_upload.jsx | 18 ++++++++--------- web/react/utils/constants.jsx | 1 + 4 files changed, 49 insertions(+), 32 deletions(-) (limited to 'web') diff --git a/web/react/components/create_comment.jsx b/web/react/components/create_comment.jsx index 9bcbad079..bb7027115 100644 --- a/web/react/components/create_comment.jsx +++ b/web/react/components/create_comment.jsx @@ -112,13 +112,28 @@ module.exports = React.createClass({ return { messageText: '', uploadsInProgress: 0, previews: [], submitting: false }; }, setUploads: function(val) { - var num = this.state.uploadsInProgress + val; - this.setState({uploadsInProgress: num}); + var oldInProgress = this.state.uploadsInProgress + var newInProgress = oldInProgress + val; + + if (newInProgress + this.state.previews.length > Constants.MAX_UPLOAD_FILES) { + newInProgress = Constants.MAX_UPLOAD_FILES - this.state.previews.length; + this.setState({limit_error: "Uploads limited to " + Constants.MAX_UPLOAD_FILES + " files maximum. Please use additional comments for more files."}); + } else { + this.setState({limit_error: null}); + } + + var numToUpload = newInProgress - oldInProgress; + if (numToUpload <= 0) return 0; + + this.setState({uploadsInProgress: newInProgress}); + + return numToUpload; }, render: function() { var server_error = this.state.server_error ?
: null; var post_error = this.state.post_error ? : null; + var limit_error = this.state.limit_error ?
: null; var preview =
; if (this.state.previews.length > 0 || this.state.uploadsInProgress > 0) { @@ -129,13 +144,6 @@ module.exports = React.createClass({ uploadsInProgress={this.state.uploadsInProgress} /> ); } - var limit_previews = "" - if (this.state.previews.length > 5) { - limit_previews =
- } - if (this.state.previews.length > 20) { - limit_previews =
- } return (
@@ -159,7 +167,7 @@ module.exports = React.createClass({ { post_error } { server_error } - { limit_previews } + { limit_error }
{ preview } diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx index a534e495d..e7cd661fb 100644 --- a/web/react/components/create_post.jsx +++ b/web/react/components/create_post.jsx @@ -51,7 +51,7 @@ module.exports = React.createClass({ false, function(data) { PostStore.storeDraft(data.channel_id, user_id, null); - this.setState({ messageText: '', submitting: false, post_error: null, previews: [], server_error: null }); + this.setState({ messageText: '', submitting: false, post_error: null, previews: [], server_error: null, limit_error: null }); if (data.goto_location.length > 0) { window.location.href = data.goto_location; @@ -71,7 +71,7 @@ module.exports = React.createClass({ client.createPost(post, ChannelStore.getCurrent(), function(data) { PostStore.storeDraft(data.channel_id, data.user_id, null); - this.setState({ messageText: '', submitting: false, post_error: null, previews: [], server_error: null }); + this.setState({ messageText: '', submitting: false, post_error: null, previews: [], server_error: null, limit_error: null }); this.resizePostHolder(); AsyncClient.getPosts(true); @@ -207,21 +207,36 @@ module.exports = React.createClass({ return { channel_id: ChannelStore.getCurrentId(), messageText: messageText, uploadsInProgress: 0, previews: previews, submitting: false, initialText: messageText }; }, setUploads: function(val) { - var num = this.state.uploadsInProgress + val; + var oldInProgress = this.state.uploadsInProgress + var newInProgress = oldInProgress + val; + + if (newInProgress + this.state.previews.length > Constants.MAX_UPLOAD_FILES) { + newInProgress = Constants.MAX_UPLOAD_FILES - this.state.previews.length; + this.setState({limit_error: "Uploads limited to " + Constants.MAX_UPLOAD_FILES + " files maximum. Please use additional posts for more files."}); + } else { + this.setState({limit_error: null}); + } + + var numToUpload = newInProgress - oldInProgress; + if (numToUpload <= 0) return 0; + var draft = PostStore.getCurrentDraft(); if (!draft) { draft = {} draft['message'] = ''; draft['previews'] = []; } - draft['uploadsInProgress'] = num; + draft['uploadsInProgress'] = newInProgress; PostStore.storeCurrentDraft(draft); - this.setState({uploadsInProgress: num}); + this.setState({uploadsInProgress: newInProgress}); + + return numToUpload; }, render: function() { var server_error = this.state.server_error ?
: null; var post_error = this.state.post_error ? : null; + var limit_error = this.state.limit_error ?
: null; var preview =
; if (this.state.previews.length > 0 || this.state.uploadsInProgress > 0) { @@ -232,13 +247,6 @@ module.exports = React.createClass({ uploadsInProgress={this.state.uploadsInProgress} /> ); } - var limit_previews = "" - if (this.state.previews.length > 5) { - limit_previews =
- } - if (this.state.previews.length > 20) { - limit_previews =
- } return ( @@ -260,7 +268,7 @@ module.exports = React.createClass({
{ post_error } { server_error } - { limit_previews } + { limit_error } { preview }
diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index c03a61c63..f2429f17e 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -12,18 +12,18 @@ module.exports = React.createClass({ this.props.onUploadError(null); - //This looks redundant, but must be done this way due to - //setState being an asynchronous call + // This looks redundant, but must be done this way due to + // setState being an asynchronous call var numFiles = 0; - for(var i = 0; i < files.length && i <= 20 ; i++) { + for(var i = 0; i < files.length && i < Constants.MAX_UPLOAD_FILES; i++) { if (files[i].size <= Constants.MAX_FILE_SIZE) { numFiles++; } } - this.props.setUploads(numFiles); + var numToUpload = this.props.setUploads(numFiles); - for (var i = 0; i < files.length && i <= 20; i++) { + for (var i = 0; i < files.length && i < numToUpload; i++) { if (files[i].size > Constants.MAX_FILE_SIZE) { this.props.onUploadError("Files must be no more than " + Constants.MAX_FILE_SIZE/1000000 + " MB"); continue; @@ -70,8 +70,8 @@ module.exports = React.createClass({ self.props.onUploadError(null); - //This looks redundant, but must be done this way due to - //setState being an asynchronous call + // This looks redundant, but must be done this way due to + // setState being an asynchronous call var items = e.clipboardData.items; var numItems = 0; if (items) { @@ -87,9 +87,9 @@ module.exports = React.createClass({ } } - self.props.setUploads(numItems); + var numToUpload = self.props.setUploads(numItems); - for (var i = 0; i < items.length; i++) { + for (var i = 0; i < items.length && i < numToUpload; i++) { if (items[i].type.indexOf("image") !== -1) { var file = items[i].getAsFile(); diff --git a/web/react/utils/constants.jsx b/web/react/utils/constants.jsx index deb07409b..6d129106b 100644 --- a/web/react/utils/constants.jsx +++ b/web/react/utils/constants.jsx @@ -45,6 +45,7 @@ module.exports = { PATCH_TYPES: ['patch'], ICON_FROM_TYPE: {'audio': 'audio', 'video': 'video', 'spreadsheet': 'ppt', 'pdf': 'pdf', 'code': 'code' , 'word': 'word' , 'excel': 'excel' , 'patch': 'patch', 'other': 'generic'}, MAX_DISPLAY_FILES: 5, + MAX_UPLOAD_FILES: 5, MAX_FILE_SIZE: 50000000, // 50 MB DEFAULT_CHANNEL: 'town-square', POST_CHUNK_SIZE: 60, -- cgit v1.2.3-1-g7c22 From f2401dd91f7e0ae005e1efddd1132d91bf4dad02 Mon Sep 17 00:00:00 2001 From: Asaad Mahmood Date: Fri, 26 Jun 2015 03:07:20 +0500 Subject: MM-1184 - Updating image preview --- web/sass-files/sass/partials/_modal.scss | 13 +++++++------ web/sass-files/sass/partials/_responsive.scss | 1 - 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'web') diff --git a/web/sass-files/sass/partials/_modal.scss b/web/sass-files/sass/partials/_modal.scss index 43dbdc077..22013aa4f 100644 --- a/web/sass-files/sass/partials/_modal.scss +++ b/web/sass-files/sass/partials/_modal.scss @@ -129,15 +129,16 @@ width:100%; margin: 0 auto; .image-wrapper { - padding: 4px; background: #FFF; position: relative; max-width: 80%; - min-height: 280px; min-width: 280px; - @include border-radius(4px); + @include border-radius(3px); display: table; margin: 0 auto; + &:hover { + @include border-radius(3px 3px 0 0); + } &:hover .modal-close { @include opacity(1); } @@ -217,10 +218,11 @@ } .modal-button-bar { position:absolute; - bottom:0px; + bottom:-40px; left:0px; right:0px; - background-color:rgba(0, 0, 0, 0.8); + background-color: #222; + @include border-radius(0 0 3px 3px); @include opacity(0); -webkit-transition: opacity 0.6s; -moz-transition: opacity 0.6s; @@ -228,7 +230,6 @@ transition: opacity 0.6s; line-height: 40px; padding: 0 10px; - margin: 4px; &.footer--show { @include opacity(1); } diff --git a/web/sass-files/sass/partials/_responsive.scss b/web/sass-files/sass/partials/_responsive.scss index bed2f6324..3949fc064 100644 --- a/web/sass-files/sass/partials/_responsive.scss +++ b/web/sass-files/sass/partials/_responsive.scss @@ -538,7 +538,6 @@ .modal { .modal-image { .image-wrapper { - padding-bottom: 40px; .modal-close { @include opacity(1); } -- cgit v1.2.3-1-g7c22 From febb6e3b656f0a5e48c928f26d071d2f1baf5b33 Mon Sep 17 00:00:00 2001 From: Asaad Mahmood Date: Fri, 26 Jun 2015 23:19:29 +0500 Subject: mm-1256 - Improving view modal and close modal button --- web/react/components/channel_info_modal.jsx | 15 ++++++++++++--- web/sass-files/sass/partials/_modal.scss | 23 +++++++++++++++++++++-- web/sass-files/sass/partials/_responsive.scss | 11 ++++------- 3 files changed, 37 insertions(+), 12 deletions(-) (limited to 'web') diff --git a/web/react/components/channel_info_modal.jsx b/web/react/components/channel_info_modal.jsx index 191297ce4..18addb52f 100644 --- a/web/react/components/channel_info_modal.jsx +++ b/web/react/components/channel_info_modal.jsx @@ -35,9 +35,18 @@ module.exports = React.createClass({

{channel.display_name}

-

Channel Name: {channel.display_name}

-

Channel Handle: {channel.name}

-

Channel ID: {channel.id}

+
+
Channel Name:
+
{channel.display_name}
+
+
+
Channel Handle:
+
{channel.name}
+
+
+
Channel ID:
+
{channel.id}
+
diff --git a/web/sass-files/sass/partials/_modal.scss b/web/sass-files/sass/partials/_modal.scss index 22013aa4f..9009dd768 100644 --- a/web/sass-files/sass/partials/_modal.scss +++ b/web/sass-files/sass/partials/_modal.scss @@ -1,9 +1,17 @@ +.modal-body { + padding: 20px 15px; +} .modal { &.image_modal { .modal-backdrop.in { @include opacity(0.7); } } + .info__label { + font-weight: bold; + text-align: right; + padding-right: 0; + } .remove__member { float: right; } @@ -29,7 +37,7 @@ border-radius: 0; background: $primary-color; color: #FFF; - padding: 15px 15px 11px; + padding: 15px 15px 11px; border: none; min-height: 56px; @include clearfix; @@ -41,11 +49,22 @@ margin: 0; } button.close { - margin-top: 0; + margin: -2px -2px 0 0; color: #fff; @include opacity(1); z-index: 5; + width: 30px; + height: 30px; + line-height: 30px; + @include single-transition(all, 0.25s, ease-in); position: relative; + &:hover { + background: rgba(0, 0, 0, 0.1); + } + span { + position: relative; + top: -1px; + } } .btn { margin-right: 10px; diff --git a/web/sass-files/sass/partials/_responsive.scss b/web/sass-files/sass/partials/_responsive.scss index 3949fc064..509c764b3 100644 --- a/web/sass-files/sass/partials/_responsive.scss +++ b/web/sass-files/sass/partials/_responsive.scss @@ -231,17 +231,14 @@ } } .modal { + .info__label { + text-align: left; + padding-bottom: 5px; + } .modal-header { - padding-left: 20px; - padding-right: 20px; .modal-action { margin-top: 10px; } - button.close { - width: 35px; - height: 32px; - margin: -5px -10px 0; - } .modal-title { float: none; } -- cgit v1.2.3-1-g7c22 From 0104bf822c70eef7793b8a31b78d5c72c0f1514e Mon Sep 17 00:00:00 2001 From: test Date: Fri, 26 Jun 2015 11:07:22 -0700 Subject: gui: fix mentions dropdown --- web/react/components/mention.jsx | 4 ++-- web/sass-files/sass/partials/_mentions.scss | 25 ++++++++++++++----------- 2 files changed, 16 insertions(+), 13 deletions(-) (limited to 'web') diff --git a/web/react/components/mention.jsx b/web/react/components/mention.jsx index ba758688b..86a423138 100644 --- a/web/react/components/mention.jsx +++ b/web/react/components/mention.jsx @@ -8,8 +8,8 @@ module.exports = React.createClass({ render: function() { return (
- - @{this.props.username}{this.props.name} + + @{this.props.username}{this.props.name}
); } diff --git a/web/sass-files/sass/partials/_mentions.scss b/web/sass-files/sass/partials/_mentions.scss index 11cd4e9e4..cb6ff16c5 100644 --- a/web/sass-files/sass/partials/_mentions.scss +++ b/web/sass-files/sass/partials/_mentions.scss @@ -3,21 +3,19 @@ background: $primary-color; position: relative; z-index: 10; - padding-bottom: 1px; + padding-bottom: 2px; @include border-radius(3px); - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; } .mentions--top { position: absolute; - z-index:99999; + z-index: 1040; .mentions-box { position:absolute; background-color:#fff; - border:1px solid #ddd; - overflow:scroll; + border: $border-gray; + overflow-x: hidden; + overflow-y: scroll; bottom:0; } } @@ -29,10 +27,10 @@ height:37px; padding:2px; z-index:101; -} - -.mentions-name:hover { - background-color:#e8eaed; + cursor: pointer; + &:hover { + background-color:#e8eaed; + } } .mentions-text { @@ -46,6 +44,11 @@ border-radius: 10%; } +.mention-fullname { + color: grey; + padding-left: 10px; +} + .mention-highlight { background-color:#fff2bb; } -- cgit v1.2.3-1-g7c22 From 9e7ba4aa5dec9882e6fcf747b464cd8d5cee1e98 Mon Sep 17 00:00:00 2001 From: Asaad Mahmood Date: Sat, 27 Jun 2015 00:29:37 +0500 Subject: Removing relative from span --- web/sass-files/sass/partials/_modal.scss | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'web') diff --git a/web/sass-files/sass/partials/_modal.scss b/web/sass-files/sass/partials/_modal.scss index 9009dd768..4427cb7dd 100644 --- a/web/sass-files/sass/partials/_modal.scss +++ b/web/sass-files/sass/partials/_modal.scss @@ -62,8 +62,7 @@ background: rgba(0, 0, 0, 0.1); } span { - position: relative; - top: -1px; + line-height: 10px; } } .btn { -- cgit v1.2.3-1-g7c22 From f25cdbdb08c11fc9cd3e6bbf0748b67d2635ff47 Mon Sep 17 00:00:00 2001 From: ralder Date: Fri, 26 Jun 2015 15:58:34 -0700 Subject: gui: fix broken mailto link in user-popover --- web/react/components/user_profile.jsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'web') diff --git a/web/react/components/user_profile.jsx b/web/react/components/user_profile.jsx index 8ffad737d..648960471 100644 --- a/web/react/components/user_profile.jsx +++ b/web/react/components/user_profile.jsx @@ -10,8 +10,7 @@ function getStateFromStores(userId) { if (profile == null) { return { profile: { id: "0", username: "..."} }; - } - else { + } else { return { profile: profile }; } } @@ -54,12 +53,11 @@ module.exports = React.createClass({ var name = this.props.overwriteName ? this.props.overwriteName : this.state.profile.username; - var data_content = "" - data_content += "" + var data_content = ""; if (!config.ShowEmail) { - data_content += "
Email not shared
"; + data_content += "
Email not shared
"; } else { - data_content += ""; + data_content += ""; } return ( -- cgit v1.2.3-1-g7c22 From e1714eaa3f3363c0e38c947c2cc438b201a16a02 Mon Sep 17 00:00:00 2001 From: Asaad Mahmood Date: Sun, 28 Jun 2015 04:18:24 +0500 Subject: Updating settings UI --- web/react/components/setting_item_max.jsx | 2 +- web/react/components/user_settings.jsx | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'web') diff --git a/web/react/components/setting_item_max.jsx b/web/react/components/setting_item_max.jsx index 03f05b0cf..b8b667e1a 100644 --- a/web/react/components/setting_item_max.jsx +++ b/web/react/components/setting_item_max.jsx @@ -13,7 +13,7 @@ module.exports = React.createClass({
  • {this.props.title}
    • -
    • +
    • {inputs}
    • diff --git a/web/react/components/user_settings.jsx b/web/react/components/user_settings.jsx index 7d542a8b7..147973fb7 100644 --- a/web/react/components/user_settings.jsx +++ b/web/react/components/user_settings.jsx @@ -155,7 +155,7 @@ var NotificationsTab = React.createClass({ var inputs = []; inputs.push( -
      +
    • +
    • { theme_buttons }
      -- cgit v1.2.3-1-g7c22 From ce74e4a7288c1edded736f1315beb8b1909a4641 Mon Sep 17 00:00:00 2001 From: ralder Date: Mon, 29 Jun 2015 01:39:31 +0300 Subject: fix pr #82 mention list inside modal --- web/sass-files/sass/partials/_mentions.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'web') diff --git a/web/sass-files/sass/partials/_mentions.scss b/web/sass-files/sass/partials/_mentions.scss index cb6ff16c5..86fe400c9 100644 --- a/web/sass-files/sass/partials/_mentions.scss +++ b/web/sass-files/sass/partials/_mentions.scss @@ -9,7 +9,7 @@ .mentions--top { position: absolute; - z-index: 1040; + z-index: 1060; .mentions-box { position:absolute; background-color:#fff; -- cgit v1.2.3-1-g7c22 From 2cd5f3629ff2410127a8fdc5df92fb16f52fa457 Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Sun, 28 Jun 2015 19:25:39 -0700 Subject: Fixed typo in team domain look-up page --- web/react/components/login.jsx | 2 +- web/react/utils/utils.jsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'web') diff --git a/web/react/components/login.jsx b/web/react/components/login.jsx index 85df5f797..3b6f96c2d 100644 --- a/web/react/components/login.jsx +++ b/web/react/components/login.jsx @@ -37,7 +37,7 @@ var FindTeamDomain = React.createClass({ window.location.href = window.location.protocol + "//" + domain + "." + utils.getDomainWithOutSub(); } else { - this.state.server_error = "We couldn't find your " + strings.TeamPlural + "."; + this.state.server_error = "We couldn't find your " + strings.Team + "."; this.setState(this.state); } }.bind(this), diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx index 75c583c8f..128d9d1e7 100644 --- a/web/react/utils/utils.jsx +++ b/web/react/utils/utils.jsx @@ -25,7 +25,7 @@ module.exports.cleanUpUrlable = function(input) { module.exports.isTestDomain = function() { - if ((/^localhost/).test(window.location.hostname)) + /*if ((/^localhost/).test(window.location.hostname)) return true; if ((/^dockerhost/).test(window.location.hostname)) @@ -44,7 +44,7 @@ module.exports.isTestDomain = function() { return true; if ((/^176./).test(window.location.hostname)) - return true; + return true;*/ return false; }; -- cgit v1.2.3-1-g7c22 From e621950364c93365fad4dbbbb6e94360d2fce809 Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Sun, 28 Jun 2015 19:38:19 -0700 Subject: Removed test code --- web/react/utils/utils.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'web') diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx index 128d9d1e7..75c583c8f 100644 --- a/web/react/utils/utils.jsx +++ b/web/react/utils/utils.jsx @@ -25,7 +25,7 @@ module.exports.cleanUpUrlable = function(input) { module.exports.isTestDomain = function() { - /*if ((/^localhost/).test(window.location.hostname)) + if ((/^localhost/).test(window.location.hostname)) return true; if ((/^dockerhost/).test(window.location.hostname)) @@ -44,7 +44,7 @@ module.exports.isTestDomain = function() { return true; if ((/^176./).test(window.location.hostname)) - return true;*/ + return true; return false; }; -- cgit v1.2.3-1-g7c22 From 2b4888d062d65546325470d2d9181f4a66a2fb00 Mon Sep 17 00:00:00 2001 From: JoramWilander Date: Mon, 22 Jun 2015 14:23:59 -0400 Subject: fixes mm-1316 improves channel notifications UI and updates channellist etag --- web/react/components/channel_header.jsx | 30 +--- web/react/components/channel_notifications.jsx | 208 +++++++++++++++++++------ 2 files changed, 165 insertions(+), 73 deletions(-) (limited to 'web') diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx index ade58a10a..428d3ed81 100644 --- a/web/react/components/channel_header.jsx +++ b/web/react/components/channel_header.jsx @@ -15,17 +15,8 @@ var AppDispatcher = require('../dispatcher/app_dispatcher.jsx'); var Constants = require('../utils/constants.jsx'); var ActionTypes = Constants.ActionTypes; -function getExtraInfoStateFromStores() { - return { - extra_info: ChannelStore.getCurrentExtraInfo() - }; -} - var ExtraMembers = React.createClass({ componentDidMount: function() { - ChannelStore.addExtraInfoChangeListener(this._onChange); - ChannelStore.addChangeListener(this._onChange); - var originalLeave = $.fn.popover.Constructor.prototype.leave; $.fn.popover.Constructor.prototype.leave = function(obj) { var self = obj instanceof this.constructor ? obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type); @@ -49,25 +40,12 @@ var ExtraMembers = React.createClass({ }); }, - componentWillUnmount: function() { - ChannelStore.removeExtraInfoChangeListener(this._onChange); - ChannelStore.removeChangeListener(this._onChange); - }, - _onChange: function() { - var newState = getExtraInfoStateFromStores(); - if (!utils.areStatesEqual(newState, this.state)) { - this.setState(newState); - } - }, - getInitialState: function() { - return getExtraInfoStateFromStores(); - }, render: function() { - var count = this.state.extra_info.members.length == 0 ? "-" : this.state.extra_info.members.length; - count = this.state.extra_info.members.length > 19 ? "20+" : count; + var count = this.props.members.length == 0 ? "-" : this.props.members.length; + count = this.props.members.length > 19 ? "20+" : count; var data_content = ""; - this.state.extra_info.members.forEach(function(m) { + this.props.members.forEach(function(m) { data_content += "
      " + m.username + "
      "; }); @@ -228,7 +206,7 @@ module.exports = React.createClass({ {channelTitle} } - + { searchForm }
      diff --git a/web/react/components/channel_notifications.jsx b/web/react/components/channel_notifications.jsx index 085536a0a..fa9ab42ae 100644 --- a/web/react/components/channel_notifications.jsx +++ b/web/react/components/channel_notifications.jsx @@ -1,6 +1,8 @@ // Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. // See License.txt for license information. +var SettingItemMin = require('./setting_item_min.jsx'); +var SettingItemMax = require('./setting_item_max.jsx'); var utils = require('../utils/utils.jsx'); var client = require('../utils/client.jsx'); @@ -9,26 +11,50 @@ var ChannelStore = require('../stores/channel_store.jsx'); module.exports = React.createClass({ componentDidMount: function() { + ChannelStore.addChangeListener(this._onChange); + var self = this; $(this.refs.modal.getDOMNode()).on('show.bs.modal', function(e) { var button = e.relatedTarget; var channel_id = button.dataset.channelid; var notifyLevel = ChannelStore.getMember(channel_id).notify_level; - self.setState({ notify_level: notifyLevel, title: button.dataset.title, channel_id: channel_id }); + var quietMode = false; + if (notifyLevel === "quiet") quietMode = true; + self.setState({ notify_level: notifyLevel, quiet_mode: quietMode, title: button.dataset.title, channel_id: channel_id }); }); }, + componentWillUnmount: function() { + ChannelStore.removeChangeListener(this._onChange); + }, + _onChange: function() { + if (!this.state.channel_id) return; + var notifyLevel = ChannelStore.getMember(this.state.channel_id).notify_level; + var quietMode = false; + if (notifyLevel === "quiet") quietMode = true; + + var newState = this.state; + newState.notify_level = notifyLevel; + newState.quiet_mode = quietMode; + + if (!utils.areStatesEqual(this.state, newState)) { + this.setState(newState); + } + }, + updateSection: function(section) { + this.setState({ activeSection: section }); + }, getInitialState: function() { - return { notify_level: "", title: "", channel_id: "" }; + return { notify_level: "", title: "", channel_id: "", activeSection: "" }; }, - handleUpdate: function(e) { + handleUpdate: function() { var channel_id = this.state.channel_id; - var notify_level = this.state.notify_level; + var notify_level = this.state.quiet_mode ? "quiet" : this.state.notify_level; var data = {}; data["channel_id"] = channel_id; data["user_id"] = UserStore.getCurrentId(); - data["notify_level"] = this.state.notify_level; + data["notify_level"] = notify_level; if (!data["notify_level"] || data["notify_level"].length === 0) return; @@ -37,7 +63,7 @@ module.exports = React.createClass({ var member = ChannelStore.getMember(channel_id); member.notify_level = notify_level; ChannelStore.setChannelMember(member); - $(this.refs.modal.getDOMNode()).modal('hide'); + this.updateSection(""); }.bind(this), function(err) { this.setState({ server_error: err.message }); @@ -45,42 +71,138 @@ module.exports = React.createClass({ ); }, handleRadioClick: function(notifyLevel) { - this.setState({ notify_level: notifyLevel }); + this.setState({ notify_level: notifyLevel, quiet_mode: false }); this.refs.modal.getDOMNode().focus(); }, - handleQuietToggle: function() { - if (this.state.notify_level === "quiet") { - this.setState({ notify_level: "none" }); - this.refs.modal.getDOMNode().focus(); - } else { - this.setState({ notify_level: "quiet" }); - this.refs.modal.getDOMNode().focus(); - } + handleQuietToggle: function(quietMode) { + this.setState({ notify_level: "none", quiet_mode: quietMode }); + this.refs.modal.getDOMNode().focus(); }, render: function() { var server_error = this.state.server_error ?
      : null; - var allActive = ""; - var mentionActive = ""; - var noneActive = ""; - var quietActive = ""; - var desktopHidden = ""; - - if (this.state.notify_level === "quiet") { - desktopHidden = "hidden"; - quietActive = "active"; - } else if (this.state.notify_level === "mention") { - mentionActive = "active"; - } else if (this.state.notify_level === "none") { - noneActive = "active"; + var self = this; + + var desktopSection; + if (this.state.activeSection === 'desktop') { + var notifyActive = [false, false, false]; + if (this.state.notify_level === "mention") { + notifyActive[1] = true; + } else if (this.state.notify_level === "all") { + notifyActive[0] = true; + } else { + notifyActive[2] = true; + } + + var inputs = []; + + inputs.push( +
      +
      + +
      +
      +
      + +
      +
      +
      + +
      +
      + ); + + desktopSection = ( + + ); + } else { + var describe = ""; + if (this.state.notify_level === "mention") { + describe = "Only for mentions"; + } else if (this.state.notify_level === "all") { + describe = "For all activity"; + } else { + describe = "Never"; + } + + desktopSection = ( + + ); + } + + var quietSection; + if (this.state.activeSection === 'quiet') { + var quietActive = ["",""]; + if (this.state.quiet_mode) { + quietActive[0] = "active"; + } else { + quietActive[1] = "active"; + } + + var inputs = []; + + inputs.push( +
      +
      + + +
      +
      + ); + + inputs.push( +
      +
      + Enabling quiet mode will turn off desktop notifications and only mark the channel as unread if you have been mentioned. +
      + ); + + quietSection = ( + + ); } else { - allActive = "active"; + var describe = ""; + if (this.state.quiet_mode) { + describe = "On"; + } else { + describe = "Off"; + } + + quietSection = ( + + ); } var self = this; return (