diff options
author | Harrison Healey <harrisonmhealey@gmail.com> | 2016-07-05 11:58:18 -0400 |
---|---|---|
committer | Joram Wilander <jwawilander@gmail.com> | 2016-07-05 11:58:18 -0400 |
commit | dc2f2a800105b77e665ec2a00c6290f35b1a2ba3 (patch) | |
tree | 82f23c2e72a7c785f55c2d6c1c35c10c16994918 /webapp/components/post_view | |
parent | a65f1fc266f15eaa8f79541d4d11440c3d356bb6 (diff) | |
download | chat-dc2f2a800105b77e665ec2a00c6290f35b1a2ba3.tar.gz chat-dc2f2a800105b77e665ec2a00c6290f35b1a2ba3.tar.bz2 chat-dc2f2a800105b77e665ec2a00c6290f35b1a2ba3.zip |
PLT-3145 Custom Emojis (#3381)
* Reorganized Backstage code to use a view controller and separated it from integrations code
* Renamed InstalledIntegrations component to BackstageList
* Added EmojiList page
* Added AddEmoji page
* Added custom emoji to autocomplete and text formatter
* Moved system emoji to EmojiStore
* Stopped trying to get emoji before logging in
* Rerender posts when emojis change
* Fixed submit handler on backstage pages to properly support enter
* Removed debugging code
* Updated javascript driver
* Fixed unit tests
* Fixed backstage routes
* Added clientside validation to prevent users from creating an emoji with the same name as a system one
* Fixed AddEmoji page to properly redirect when an emoji is created successfully
* Fixed updating emoji list when an emoji is deleted
* Added type prop to BackstageList to properly support using a table for the list
* Added help text to EmojiList
* Fixed backstage on smaller screen sizes
* Disable custom emoji by default
* Improved restrictions on creating emojis
* Fixed non-admin users seeing the option to delete each other's emojis
* Fixing gofmt
* Fixed emoji unit tests
* Fixed trying to get emoji from the server when it's disabled
Diffstat (limited to 'webapp/components/post_view')
6 files changed, 46 insertions, 6 deletions
diff --git a/webapp/components/post_view/components/post.jsx b/webapp/components/post_view/components/post.jsx index c445ad9f3..6633bd9b9 100644 --- a/webapp/components/post_view/components/post.jsx +++ b/webapp/components/post_view/components/post.jsx @@ -84,6 +84,10 @@ export default class Post extends React.Component { return true; } + if (nextProps.emojis !== this.props.emojis) { + return true; + } + return false; } render() { @@ -200,6 +204,7 @@ export default class Post extends React.Component { handleCommentClick={this.handleCommentClick} compactDisplay={this.props.compactDisplay} previewCollapsed={this.props.previewCollapsed} + emojis={this.props.emojis} /> </div> </div> @@ -225,5 +230,6 @@ Post.propTypes = { compactDisplay: React.PropTypes.bool, previewCollapsed: React.PropTypes.string, commentCount: React.PropTypes.number, - useMilitaryTime: React.PropTypes.bool.isRequired + useMilitaryTime: React.PropTypes.bool.isRequired, + emojis: React.PropTypes.object.isRequired }; diff --git a/webapp/components/post_view/components/post_body.jsx b/webapp/components/post_view/components/post_body.jsx index 2a2be75a9..561860b65 100644 --- a/webapp/components/post_view/components/post_body.jsx +++ b/webapp/components/post_view/components/post_body.jsx @@ -37,6 +37,10 @@ export default class PostBody extends React.Component { return true; } + if (nextProps.emojis !== this.props.emojis) { + return true; + } + return false; } @@ -151,7 +155,7 @@ export default class PostBody extends React.Component { message = ( <span onClick={TextFormatting.handleClick} - dangerouslySetInnerHTML={{__html: TextFormatting.formatText(this.props.post.message)}} + dangerouslySetInnerHTML={{__html: TextFormatting.formatText(this.props.post.message, {emojis: this.props.emojis})}} /> ); } @@ -199,5 +203,6 @@ PostBody.propTypes = { retryPost: React.PropTypes.func.isRequired, handleCommentClick: React.PropTypes.func.isRequired, compactDisplay: React.PropTypes.bool, - previewCollapsed: React.PropTypes.string + previewCollapsed: React.PropTypes.string, + emojis: React.PropTypes.object.isRequired }; 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 0ab015ced..a51a557b9 100644 --- a/webapp/components/post_view/components/post_body_additional_content.jsx +++ b/webapp/components/post_view/components/post_body_additional_content.jsx @@ -35,6 +35,9 @@ export default class PostBodyAdditionalContent extends React.Component { if (!Utils.areObjectsEqual(nextProps.post, this.props.post)) { return true; } + if (!Utils.areObjectsEqual(nextProps.message, this.props.message)) { + return true; + } if (nextState.embedVisible !== this.state.embedVisible) { return true; } diff --git a/webapp/components/post_view/components/post_list.jsx b/webapp/components/post_view/components/post_list.jsx index 288a2d5e0..bcd763d58 100644 --- a/webapp/components/post_view/components/post_list.jsx +++ b/webapp/components/post_view/components/post_list.jsx @@ -265,6 +265,7 @@ export default class PostList extends React.Component { compactDisplay={this.props.compactDisplay} previewCollapsed={this.props.previewsCollapsed} useMilitaryTime={this.props.useMilitaryTime} + emojis={this.props.emojis} /> ); @@ -527,5 +528,6 @@ PostList.propTypes = { compactDisplay: React.PropTypes.bool, previewsCollapsed: React.PropTypes.string, useMilitaryTime: React.PropTypes.bool.isRequired, - isFocusPost: React.PropTypes.bool + isFocusPost: React.PropTypes.bool, + emojis: React.PropTypes.object.isRequired }; diff --git a/webapp/components/post_view/post_focus_view_controller.jsx b/webapp/components/post_view/post_focus_view_controller.jsx index c70ebb0f5..f8738e056 100644 --- a/webapp/components/post_view/post_focus_view_controller.jsx +++ b/webapp/components/post_view/post_focus_view_controller.jsx @@ -4,6 +4,7 @@ import PostList from './components/post_list.jsx'; import LoadingScreen from 'components/loading_screen.jsx'; +import EmojiStore from 'stores/emoji_store.jsx'; import PostStore from 'stores/post_store.jsx'; import UserStore from 'stores/user_store.jsx'; import ChannelStore from 'stores/channel_store.jsx'; @@ -20,6 +21,7 @@ export default class PostFocusView extends React.Component { this.onChannelChange = this.onChannelChange.bind(this); this.onPostsChange = this.onPostsChange.bind(this); this.onUserChange = this.onUserChange.bind(this); + this.onEmojiChange = this.onEmojiChange.bind(this); this.onPostListScroll = this.onPostListScroll.bind(this); const focusedPostId = PostStore.getFocusedPostId(); @@ -38,7 +40,8 @@ export default class PostFocusView extends React.Component { currentChannel: ChannelStore.getCurrentId().slice(), scrollPostId: focusedPostId, atTop: PostStore.getVisibilityAtTop(focusedPostId), - atBottom: PostStore.getVisibilityAtBottom(focusedPostId) + atBottom: PostStore.getVisibilityAtBottom(focusedPostId), + emojis: EmojiStore.getEmojis() }; } @@ -46,12 +49,14 @@ export default class PostFocusView extends React.Component { ChannelStore.addChangeListener(this.onChannelChange); PostStore.addChangeListener(this.onPostsChange); UserStore.addChangeListener(this.onUserChange); + EmojiStore.addChangeListener(this.onEmojiChange); } componentWillUnmount() { ChannelStore.removeChangeListener(this.onChannelChange); PostStore.removeChangeListener(this.onPostsChange); UserStore.removeChangeListener(this.onUserChange); + EmojiStore.removeChangeListener(this.onEmojiChange); } onChannelChange() { @@ -87,6 +92,12 @@ export default class PostFocusView extends React.Component { this.setState({currentUser: UserStore.getCurrentUser(), profiles: JSON.parse(JSON.stringify(profiles))}); } + onEmojiChange() { + this.setState({ + emojis: EmojiStore.getEmojis() + }); + } + onPostListScroll() { this.setState({scrollType: ScrollTypes.FREE}); } @@ -116,6 +127,7 @@ export default class PostFocusView extends React.Component { showMoreMessagesBottom={!this.state.atBottom} postsToHighlight={postsToHighlight} isFocusPost={true} + emojis={this.state.emojis} /> ); } diff --git a/webapp/components/post_view/post_view_controller.jsx b/webapp/components/post_view/post_view_controller.jsx index 6d724f659..17c3e94ae 100644 --- a/webapp/components/post_view/post_view_controller.jsx +++ b/webapp/components/post_view/post_view_controller.jsx @@ -4,6 +4,7 @@ import PostList from './components/post_list.jsx'; import LoadingScreen from 'components/loading_screen.jsx'; +import EmojiStore from 'stores/emoji_store.jsx'; import PreferenceStore from 'stores/preference_store.jsx'; import UserStore from 'stores/user_store.jsx'; import PostStore from 'stores/post_store.jsx'; @@ -24,6 +25,7 @@ export default class PostViewController extends React.Component { this.onPreferenceChange = this.onPreferenceChange.bind(this); this.onUserChange = this.onUserChange.bind(this); this.onPostsChange = this.onPostsChange.bind(this); + this.onEmojisChange = this.onEmojisChange.bind(this); this.onPostsViewJumpRequest = this.onPostsViewJumpRequest.bind(this); this.onPostListScroll = this.onPostListScroll.bind(this); this.onActivate = this.onActivate.bind(this); @@ -53,7 +55,8 @@ export default class PostViewController extends React.Component { 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'), - useMilitaryTime: PreferenceStore.getBool(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false) + useMilitaryTime: PreferenceStore.getBool(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.USE_MILITARY_TIME, false), + emojis: EmojiStore.getEmojis() }; } @@ -102,11 +105,18 @@ export default class PostViewController extends React.Component { }); } + onEmojisChange() { + this.setState({ + emojis: EmojiStore.getEmojis() + }); + } + onActivate() { PreferenceStore.addChangeListener(this.onPreferenceChange); UserStore.addChangeListener(this.onUserChange); PostStore.addChangeListener(this.onPostsChange); PostStore.addPostsViewJumpListener(this.onPostsViewJumpRequest); + EmojiStore.addChangeListener(this.onEmojisChange); } onDeactivate() { @@ -114,6 +124,7 @@ export default class PostViewController extends React.Component { UserStore.removeChangeListener(this.onUserChange); PostStore.removeChangeListener(this.onPostsChange); PostStore.removePostsViewJumpListener(this.onPostsViewJumpRequest); + EmojiStore.removeChangeListener(this.onEmojisChange); } componentWillReceiveProps(nextProps) { @@ -265,6 +276,7 @@ export default class PostViewController extends React.Component { previewsCollapsed={this.state.previewsCollapsed} useMilitaryTime={this.state.useMilitaryTime} lastViewed={this.state.lastViewed} + emojis={this.state.emojis} /> ); } |