diff options
Diffstat (limited to 'webapp/components')
7 files changed, 196 insertions, 35 deletions
diff --git a/webapp/components/post_view/components/post.jsx b/webapp/components/post_view/components/post.jsx index 2ed062c74..d30216180 100644 --- a/webapp/components/post_view/components/post.jsx +++ b/webapp/components/post_view/components/post.jsx @@ -72,6 +72,10 @@ export default class Post extends React.Component { return true; } + if (nextProps.previewCollapsed !== this.props.previewCollapsed) { + return true; + } + if (!Utils.areObjectsEqual(nextProps.user, this.props.user)) { return true; } @@ -190,6 +194,7 @@ export default class Post extends React.Component { parentPost={parentPost} handleCommentClick={this.handleCommentClick} compactDisplay={this.props.compactDisplay} + previewCollapsed={this.props.previewCollapsed} /> </div> </div> @@ -213,5 +218,6 @@ Post.propTypes = { currentUser: React.PropTypes.object.isRequired, center: React.PropTypes.bool, compactDisplay: React.PropTypes.bool, + previewCollapsed: React.PropTypes.string, commentCount: React.PropTypes.number }; diff --git a/webapp/components/post_view/components/post_body.jsx b/webapp/components/post_view/components/post_body.jsx index eba62ad77..2a2be75a9 100644 --- a/webapp/components/post_view/components/post_body.jsx +++ b/webapp/components/post_view/components/post_body.jsx @@ -25,7 +25,11 @@ export default class PostBody extends React.Component { return true; } - if (!Utils.areObjectsEqual(nextProps.compactDisplay, this.props.compactDisplay)) { + if (nextProps.compactDisplay !== this.props.compactDisplay) { + return true; + } + + if (nextProps.previewCollapsed !== this.props.previewCollapsed) { return true; } @@ -172,6 +176,7 @@ export default class PostBody extends React.Component { post={this.props.post} message={messageWrapper} compactDisplay={this.props.compactDisplay} + previewCollapsed={this.props.previewCollapsed} /> ); } @@ -193,5 +198,6 @@ PostBody.propTypes = { parentPost: React.PropTypes.object, retryPost: React.PropTypes.func.isRequired, handleCommentClick: React.PropTypes.func.isRequired, - compactDisplay: React.PropTypes.bool + compactDisplay: React.PropTypes.bool, + previewCollapsed: React.PropTypes.string }; diff --git a/webapp/components/post_view/components/post_body_additional_content.jsx b/webapp/components/post_view/components/post_body_additional_content.jsx index bd29da962..6757f3b2a 100644 --- a/webapp/components/post_view/components/post_body_additional_content.jsx +++ b/webapp/components/post_view/components/post_body_additional_content.jsx @@ -22,10 +22,14 @@ export default class PostBodyAdditionalContent extends React.Component { this.toggleEmbedVisibility = this.toggleEmbedVisibility.bind(this); this.state = { - embedVisible: true + embedVisible: props.previewCollapsed.startsWith('false') }; } + componentWillReceiveProps(nextProps) { + this.setState({embedVisible: nextProps.previewCollapsed.startsWith('false')}); + } + shouldComponentUpdate(nextProps, nextState) { if (!Utils.areObjectsEqual(nextProps.post, this.props.post)) { return true; @@ -118,25 +122,23 @@ export default class PostBodyAdditionalContent extends React.Component { if (generateEmbed) { let messageWithToggle = []; - if (Utils.isFeatureEnabled(Constants.PRE_RELEASE_FEATURES.EMBED_TOGGLE)) { - // if message has only one line and starts with a link place toggle in this only line - // else - place it in new line between message and embed - const prependToggle = (/^\s*https?:\/\/.*$/).test(this.props.post.message); - messageWithToggle.push( - <a - className={`post__embed-visibility ${prependToggle ? 'pull-left' : ''}`} - data-expanded={this.state.embedVisible} - aria-label='Toggle Embed Visibility' - onClick={this.toggleEmbedVisibility} - /> - ); - if (prependToggle) { - messageWithToggle.push(this.props.message); - } else { - messageWithToggle.unshift(this.props.message); - } - } else { + + // if message has only one line and starts with a link place toggle in this only line + // else - place it in new line between message and embed + const prependToggle = (/^\s*https?:\/\/.*$/).test(this.props.post.message); + messageWithToggle.push( + <a + className={`post__embed-visibility ${prependToggle ? 'pull-left' : ''}`} + data-expanded={this.state.embedVisible} + aria-label='Toggle Embed Visibility' + onClick={this.toggleEmbedVisibility} + /> + ); + + if (prependToggle) { messageWithToggle.push(this.props.message); + } else { + messageWithToggle.unshift(this.props.message); } return ( @@ -156,8 +158,12 @@ export default class PostBodyAdditionalContent extends React.Component { } } +PostBodyAdditionalContent.defaultProps = { + previewCollapsed: 'false' +}; PostBodyAdditionalContent.propTypes = { post: React.PropTypes.object.isRequired, + message: React.PropTypes.element.isRequired, compactDisplay: React.PropTypes.bool, - message: React.PropTypes.element.isRequired + previewCollapsed: React.PropTypes.string }; diff --git a/webapp/components/post_view/components/post_list.jsx b/webapp/components/post_view/components/post_list.jsx index 288609cd9..28be93544 100644 --- a/webapp/components/post_view/components/post_list.jsx +++ b/webapp/components/post_view/components/post_list.jsx @@ -260,6 +260,7 @@ export default class PostList extends React.Component { center={this.props.displayPostsInCenter} commentCount={commentCount} compactDisplay={this.props.compactDisplay} + previewCollapsed={this.props.previewsCollapsed} /> ); @@ -520,5 +521,6 @@ PostList.propTypes = { postsToHighlight: React.PropTypes.object, displayNameType: React.PropTypes.string, displayPostsInCenter: React.PropTypes.bool, - compactDisplay: React.PropTypes.bool + compactDisplay: React.PropTypes.bool, + previewsCollapsed: React.PropTypes.string }; diff --git a/webapp/components/post_view/post_view_controller.jsx b/webapp/components/post_view/post_view_controller.jsx index d2866d8eb..e5a14af36 100644 --- a/webapp/components/post_view/post_view_controller.jsx +++ b/webapp/components/post_view/post_view_controller.jsx @@ -51,7 +51,8 @@ export default class PostViewController extends React.Component { scrollType: ScrollTypes.NEW_MESSAGE, displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false'), displayPostsInCenter: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED, - compactDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT + compactDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT, + previewsCollapsed: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.COLLAPSE_DISPLAY, 'false') }; } @@ -67,11 +68,19 @@ export default class PostViewController extends React.Component { } } - onPreferenceChange() { + onPreferenceChange(category) { + // Bit of a hack to force render when this setting is updated + // regardless of change + let previewSuffix = ''; + if (category === Preferences.CATEGORY_DISPLAY_SETTINGS) { + previewSuffix = '_' + Utils.generateId(); + } + this.setState({ displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false'), displayPostsInCenter: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED, - compactDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT + compactDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT, + previewsCollapsed: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.COLLAPSE_DISPLAY, 'false') + previewSuffix }); } @@ -132,6 +141,7 @@ export default class PostViewController extends React.Component { displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false'), displayPostsInCenter: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED, compactDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT, + previewsCollapsed: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.COLLAPSE_DISPLAY, 'false'), scrollType: ScrollTypes.NEW_MESSAGE }); } @@ -183,6 +193,10 @@ export default class PostViewController extends React.Component { return true; } + if (nextState.previewsCollapsed !== this.state.previewsCollapsed) { + return true; + } + if (nextState.lastViewed !== this.state.lastViewed) { return true; } @@ -241,6 +255,7 @@ export default class PostViewController extends React.Component { displayNameType={this.state.displayNameType} displayPostsInCenter={this.state.displayPostsInCenter} compactDisplay={this.state.compactDisplay} + previewsCollapsed={this.state.previewsCollapsed} lastViewed={this.state.lastViewed} /> ); diff --git a/webapp/components/user_settings/user_settings_advanced.jsx b/webapp/components/user_settings/user_settings_advanced.jsx index f1a72aa0f..35ab77256 100644 --- a/webapp/components/user_settings/user_settings_advanced.jsx +++ b/webapp/components/user_settings/user_settings_advanced.jsx @@ -234,13 +234,6 @@ export default class AdvancedSettingsDisplay extends React.Component { defaultMessage='Show preview snippet of links below message' /> ); - case 'EMBED_TOGGLE': - return ( - <FormattedMessage - id='user.settings.advance.embed_toggle' - defaultMessage='Show toggle for all embed previews' - /> - ); default: return null; } diff --git a/webapp/components/user_settings/user_settings_display.jsx b/webapp/components/user_settings/user_settings_display.jsx index 7036d7389..f7a030e52 100644 --- a/webapp/components/user_settings/user_settings_display.jsx +++ b/webapp/components/user_settings/user_settings_display.jsx @@ -24,7 +24,8 @@ function getDisplayStateFromStores() { nameFormat: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'username'), selectedFont: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'selected_font', Constants.DEFAULT_FONT), channelDisplayMode: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT), - messageDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) + messageDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT), + collapseDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.COLLAPSE_DISPLAY, Preferences.COLLAPSE_DISPLAY_DEFAULT) }; } @@ -41,9 +42,11 @@ export default class UserSettingsDisplay extends React.Component { this.updateSection = this.updateSection.bind(this); this.updateState = this.updateState.bind(this); this.deactivate = this.deactivate.bind(this); + this.createCollapseSection = this.createCollapseSection.bind(this); this.state = getDisplayStateFromStores(); } + handleSubmit() { const userId = UserStore.getCurrentId(); @@ -77,8 +80,14 @@ export default class UserSettingsDisplay extends React.Component { name: Preferences.MESSAGE_DISPLAY, value: this.state.messageDisplay }; + const collapseDisplayPreference = { + user_id: userId, + category: Preferences.CATEGORY_DISPLAY_SETTINGS, + name: Preferences.COLLAPSE_DISPLAY, + value: this.state.collapseDisplay + }; - AsyncClient.savePreferences([timePreference, namePreference, fontPreference, channelDisplayModePreference, messageDisplayPreference], + AsyncClient.savePreferences([timePreference, namePreference, fontPreference, channelDisplayModePreference, messageDisplayPreference, collapseDisplayPreference], () => { this.updateSection(''); }, @@ -87,27 +96,38 @@ export default class UserSettingsDisplay extends React.Component { } ); } + handleClockRadio(militaryTime) { this.setState({militaryTime}); } + handleNameRadio(nameFormat) { this.setState({nameFormat}); } + handleChannelDisplayModeRadio(channelDisplayMode) { this.setState({channelDisplayMode}); } + handlemessageDisplayRadio(messageDisplay) { this.setState({messageDisplay}); } + handleFont(selectedFont) { Utils.applyFont(selectedFont); this.setState({selectedFont}); } + + handleCollapseRadio(collapseDisplay) { + this.setState({collapseDisplay}); + } + updateSection(section) { $('.settings-modal .modal-body').scrollTop(0).perfectScrollbar('update'); this.updateState(); this.props.updateSection(section); } + updateState() { const newState = getDisplayStateFromStores(); if (!Utils.areObjectsEqual(newState, this.state)) { @@ -115,9 +135,118 @@ export default class UserSettingsDisplay extends React.Component { this.setState(newState); } } + deactivate() { this.updateState(); } + + createCollapseSection() { + if (this.props.activeSection === 'collapse') { + const collapseFormat = [false, false]; + if (this.state.collapseDisplay === 'true') { + collapseFormat[0] = true; + } else { + collapseFormat[1] = true; + } + + const handleUpdateCollapseSection = (e) => { + this.updateSection(''); + e.preventDefault(); + }; + + const inputs = [ + <div key='userDisplayCollapseOptions'> + <div className='radio'> + <label> + <input + type='radio' + name='collapseFormat' + checked={collapseFormat[0]} + onChange={this.handleCollapseRadio.bind(this, 'true')} + /> + <FormattedMessage + id='user.settings.display.collapseOn' + defaultMessage='On' + /> + </label> + <br/> + </div> + <div className='radio'> + <label> + <input + type='radio' + name='collapseFormat' + checked={collapseFormat[1]} + onChange={this.handleCollapseRadio.bind(this, 'false')} + /> + <FormattedMessage + id='user.settings.display.collapseOff' + defaultMessage='Off' + /> + </label> + <br/> + </div> + <div> + <br/> + <FormattedMessage + id='user.settings.display.collapseDesc' + defaultMessage='Toggle whether to automatically collapse all image previews.' + /> + </div> + </div> + ]; + + return ( + <SettingItemMax + title={ + <FormattedMessage + id='user.settings.display.collapseDisplay' + defaultMessage='Auto Collapse Previews' + /> + } + inputs={inputs} + submit={this.handleSubmit} + server_error={this.state.serverError} + updateSection={handleUpdateCollapseSection} + /> + ); + } + + let describe; + if (this.state.collapseDisplay === 'true') { + describe = ( + <FormattedMessage + id='user.settings.display.collapseOn' + defaultMessage='On' + /> + ); + } else { + describe = ( + <FormattedMessage + id='user.settings.display.collapseOff' + defaultMessage='Off' + /> + ); + } + + const handleUpdateCollapseSection = () => { + this.props.updateSection('collapse'); + }; + + return ( + <SettingItemMin + title={ + <FormattedMessage + id='user.settings.display.collapseDisplay' + defaultMessage='Auto Collapse Previews' + /> + } + describe={describe} + updateSection={handleUpdateCollapseSection} + /> + ); + } + render() { const serverError = this.state.serverError || null; let clockSection; @@ -127,6 +256,8 @@ export default class UserSettingsDisplay extends React.Component { let languagesSection; let messageDisplaySection; + const collapseSection = this.createCollapseSection(); + if (this.props.activeSection === 'clock') { const clockFormat = [false, false]; if (this.state.militaryTime === 'true') { @@ -729,6 +860,8 @@ export default class UserSettingsDisplay extends React.Component { <div className='divider-dark'/> {nameFormatSection} <div className='divider-dark'/> + {collapseSection} + <div className='divider-dark'/> {messageDisplaySection} <div className='divider-dark'/> {channelDisplayModeSection} |