Performance improvments (#2869)
Этот коммит содержится в:
коммит произвёл
Joram Wilander
родитель
1cf9432524
Коммит
274a2a58f0
@@ -61,7 +61,6 @@ export default class ChannelHeader extends React.Component {
|
|||||||
memberChannel: ChannelStore.getMember(this.props.channelId),
|
memberChannel: ChannelStore.getMember(this.props.channelId),
|
||||||
users: extraInfo.members,
|
users: extraInfo.members,
|
||||||
userCount: extraInfo.member_count,
|
userCount: extraInfo.member_count,
|
||||||
searchVisible: SearchStore.getSearchResults() !== null,
|
|
||||||
currentUser: UserStore.getCurrentUser()
|
currentUser: UserStore.getCurrentUser()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ class CreateComment extends React.Component {
|
|||||||
this.handleUploadError = this.handleUploadError.bind(this);
|
this.handleUploadError = this.handleUploadError.bind(this);
|
||||||
this.removePreview = this.removePreview.bind(this);
|
this.removePreview = this.removePreview.bind(this);
|
||||||
this.getFileCount = this.getFileCount.bind(this);
|
this.getFileCount = this.getFileCount.bind(this);
|
||||||
this.handleResize = this.handleResize.bind(this);
|
|
||||||
this.onPreferenceChange = this.onPreferenceChange.bind(this);
|
this.onPreferenceChange = this.onPreferenceChange.bind(this);
|
||||||
this.focusTextbox = this.focusTextbox.bind(this);
|
this.focusTextbox = this.focusTextbox.bind(this);
|
||||||
this.showPostDeletedModal = this.showPostDeletedModal.bind(this);
|
this.showPostDeletedModal = this.showPostDeletedModal.bind(this);
|
||||||
@@ -76,29 +75,22 @@ class CreateComment extends React.Component {
|
|||||||
uploadsInProgress: draft.uploadsInProgress,
|
uploadsInProgress: draft.uploadsInProgress,
|
||||||
previews: draft.previews,
|
previews: draft.previews,
|
||||||
submitting: false,
|
submitting: false,
|
||||||
windowWidth: Utils.windowWidth(),
|
|
||||||
ctrlSend: PreferenceStore.getBool(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, 'send_on_ctrl_enter'),
|
ctrlSend: PreferenceStore.getBool(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, 'send_on_ctrl_enter'),
|
||||||
showPostDeletedModal: false
|
showPostDeletedModal: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
PreferenceStore.addChangeListener(this.onPreferenceChange);
|
PreferenceStore.addChangeListener(this.onPreferenceChange);
|
||||||
window.addEventListener('resize', this.handleResize);
|
|
||||||
|
|
||||||
this.focusTextbox();
|
this.focusTextbox();
|
||||||
}
|
}
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
PreferenceStore.removeChangeListener(this.onPreferenceChange);
|
PreferenceStore.removeChangeListener(this.onPreferenceChange);
|
||||||
window.removeEventListener('resize', this.handleResize);
|
|
||||||
}
|
}
|
||||||
onPreferenceChange() {
|
onPreferenceChange() {
|
||||||
this.setState({
|
this.setState({
|
||||||
ctrlSend: PreferenceStore.getBool(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, 'send_on_ctrl_enter')
|
ctrlSend: PreferenceStore.getBool(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, 'send_on_ctrl_enter')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
handleResize() {
|
|
||||||
this.setState({windowWidth: Utils.windowWidth()});
|
|
||||||
}
|
|
||||||
componentDidUpdate(prevProps, prevState) {
|
componentDidUpdate(prevProps, prevState) {
|
||||||
if (prevState.uploadsInProgress < this.state.uploadsInProgress) {
|
if (prevState.uploadsInProgress < this.state.uploadsInProgress) {
|
||||||
$('.post-right__scroll').scrollTop($('.post-right__scroll')[0].scrollHeight);
|
$('.post-right__scroll').scrollTop($('.post-right__scroll')[0].scrollHeight);
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import TutorialTip from './tutorial/tutorial_tip.jsx';
|
|||||||
import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
|
import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
|
||||||
import * as GlobalActions from 'action_creators/global_actions.jsx';
|
import * as GlobalActions from 'action_creators/global_actions.jsx';
|
||||||
import Client from 'utils/web_client.jsx';
|
import Client from 'utils/web_client.jsx';
|
||||||
import * as AsyncClient from 'utils/async_client.jsx';
|
|
||||||
import * as Utils from 'utils/utils.jsx';
|
import * as Utils from 'utils/utils.jsx';
|
||||||
|
|
||||||
import ChannelStore from 'stores/channel_store.jsx';
|
import ChannelStore from 'stores/channel_store.jsx';
|
||||||
@@ -167,21 +166,12 @@ class CreatePost extends React.Component {
|
|||||||
post.create_at = time;
|
post.create_at = time;
|
||||||
post.parent_id = this.state.parentId;
|
post.parent_id = this.state.parentId;
|
||||||
|
|
||||||
const channel = ChannelStore.get(this.state.channelId);
|
|
||||||
|
|
||||||
GlobalActions.emitUserPostedEvent(post);
|
GlobalActions.emitUserPostedEvent(post);
|
||||||
this.setState({messageText: '', submitting: false, postError: null, previews: [], serverError: null});
|
this.setState({messageText: '', submitting: false, postError: null, previews: [], serverError: null});
|
||||||
|
|
||||||
Client.createPost(post,
|
Client.createPost(post,
|
||||||
(data) => {
|
() => {
|
||||||
AsyncClient.getPosts();
|
// DO nothing. Websockets will handle this.
|
||||||
|
|
||||||
const member = ChannelStore.getMember(channel.id);
|
|
||||||
member.msg_count = channel.total_msg_count;
|
|
||||||
member.last_viewed_at = Date.now();
|
|
||||||
ChannelStore.setChannelMember(member);
|
|
||||||
|
|
||||||
GlobalActions.emitPostRecievedEvent(data);
|
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err.id === 'api.post.create_post.root_id.app_error') {
|
if (err.id === 'api.post.create_post.root_id.app_error') {
|
||||||
|
|||||||
@@ -63,11 +63,12 @@ export default class LoggedIn extends React.Component {
|
|||||||
onUserChanged() {
|
onUserChanged() {
|
||||||
// Grab the current user
|
// Grab the current user
|
||||||
const user = UserStore.getCurrentUser();
|
const user = UserStore.getCurrentUser();
|
||||||
this.setupUser(user);
|
if (!Utils.areObjectsEqual(this.state.user, user)) {
|
||||||
|
this.setupUser(user);
|
||||||
this.setState({
|
this.setState({
|
||||||
user
|
user
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import * as GlobalActions from 'action_creators/global_actions.jsx';
|
|||||||
import PreferenceStore from 'stores/preference_store.jsx';
|
import PreferenceStore from 'stores/preference_store.jsx';
|
||||||
import UserStore from 'stores/user_store.jsx';
|
import UserStore from 'stores/user_store.jsx';
|
||||||
|
|
||||||
|
import {createChannelIntroMessage} from 'utils/channel_intro_messages.jsx';
|
||||||
|
|
||||||
import * as Utils from 'utils/utils.jsx';
|
import * as Utils from 'utils/utils.jsx';
|
||||||
import DelayedAction from 'utils/delayed_action.jsx';
|
import DelayedAction from 'utils/delayed_action.jsx';
|
||||||
|
|
||||||
@@ -394,6 +396,8 @@ export default class PostsView extends React.Component {
|
|||||||
UserStore.addChangeListener(this.onUserChange);
|
UserStore.addChangeListener(this.onUserChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.introText = createChannelIntroMessage(this.props.channel);
|
||||||
|
|
||||||
window.addEventListener('resize', this.handleResize);
|
window.addEventListener('resize', this.handleResize);
|
||||||
}
|
}
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
@@ -481,7 +485,7 @@ export default class PostsView extends React.Component {
|
|||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
moreMessagesTop = this.props.introText;
|
moreMessagesTop = this.introText;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give option to load more posts at bottom if nessisary
|
// Give option to load more posts at bottom if nessisary
|
||||||
@@ -559,7 +563,7 @@ PostsView.propTypes = {
|
|||||||
loadMorePostsBottomClicked: React.PropTypes.func.isRequired,
|
loadMorePostsBottomClicked: React.PropTypes.func.isRequired,
|
||||||
showMoreMessagesTop: React.PropTypes.bool,
|
showMoreMessagesTop: React.PropTypes.bool,
|
||||||
showMoreMessagesBottom: React.PropTypes.bool,
|
showMoreMessagesBottom: React.PropTypes.bool,
|
||||||
introText: React.PropTypes.element,
|
channel: React.PropTypes.object,
|
||||||
messageSeparatorTime: React.PropTypes.number,
|
messageSeparatorTime: React.PropTypes.number,
|
||||||
postsToHighlight: React.PropTypes.object
|
postsToHighlight: React.PropTypes.object
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ import * as GlobalActions from 'action_creators/global_actions.jsx';
|
|||||||
|
|
||||||
import Constants from 'utils/constants.jsx';
|
import Constants from 'utils/constants.jsx';
|
||||||
|
|
||||||
import {createChannelIntroMessage} from 'utils/channel_intro_messages.jsx';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const MAXIMUM_CACHED_VIEWS = 3;
|
const MAXIMUM_CACHED_VIEWS = 3;
|
||||||
@@ -188,7 +186,7 @@ export default class PostsViewContainer extends React.Component {
|
|||||||
}}
|
}}
|
||||||
showMoreMessagesTop={!this.state.atTop[this.state.currentChannelIndex]}
|
showMoreMessagesTop={!this.state.atTop[this.state.currentChannelIndex]}
|
||||||
showMoreMessagesBottom={false}
|
showMoreMessagesBottom={false}
|
||||||
introText={channel ? createChannelIntroMessage(channel) : null}
|
channel={channel}
|
||||||
messageSeparatorTime={this.state.currentLastViewed}
|
messageSeparatorTime={this.state.currentLastViewed}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ export default class Sidebar extends React.Component {
|
|||||||
this.onScroll = this.onScroll.bind(this);
|
this.onScroll = this.onScroll.bind(this);
|
||||||
this.updateUnreadIndicators = this.updateUnreadIndicators.bind(this);
|
this.updateUnreadIndicators = this.updateUnreadIndicators.bind(this);
|
||||||
this.handleLeaveDirectChannel = this.handleLeaveDirectChannel.bind(this);
|
this.handleLeaveDirectChannel = this.handleLeaveDirectChannel.bind(this);
|
||||||
this.handleResize = this.handleResize.bind(this);
|
|
||||||
|
|
||||||
this.showMoreChannelsModal = this.showMoreChannelsModal.bind(this);
|
this.showMoreChannelsModal = this.showMoreChannelsModal.bind(this);
|
||||||
this.showNewChannelModal = this.showNewChannelModal.bind(this);
|
this.showNewChannelModal = this.showNewChannelModal.bind(this);
|
||||||
@@ -64,7 +63,6 @@ export default class Sidebar extends React.Component {
|
|||||||
state.newChannelModalType = '';
|
state.newChannelModalType = '';
|
||||||
state.showDirectChannelsModal = false;
|
state.showDirectChannelsModal = false;
|
||||||
state.loadingDMChannel = -1;
|
state.loadingDMChannel = -1;
|
||||||
state.windowWidth = Utils.windowWidth();
|
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
getTotalUnreadCount() {
|
getTotalUnreadCount() {
|
||||||
@@ -150,8 +148,6 @@ export default class Sidebar extends React.Component {
|
|||||||
|
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
this.updateUnreadIndicators();
|
this.updateUnreadIndicators();
|
||||||
|
|
||||||
window.addEventListener('resize', this.handleResize);
|
|
||||||
}
|
}
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
if (!Utils.areObjectsEqual(nextState, this.state)) {
|
if (!Utils.areObjectsEqual(nextState, this.state)) {
|
||||||
@@ -173,20 +169,12 @@ export default class Sidebar extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
window.removeEventListener('resize', this.handleResize);
|
|
||||||
|
|
||||||
ChannelStore.removeChangeListener(this.onChange);
|
ChannelStore.removeChangeListener(this.onChange);
|
||||||
UserStore.removeChangeListener(this.onChange);
|
UserStore.removeChangeListener(this.onChange);
|
||||||
UserStore.removeStatusesChangeListener(this.onChange);
|
UserStore.removeStatusesChangeListener(this.onChange);
|
||||||
TeamStore.removeChangeListener(this.onChange);
|
TeamStore.removeChangeListener(this.onChange);
|
||||||
PreferenceStore.removeChangeListener(this.onChange);
|
PreferenceStore.removeChangeListener(this.onChange);
|
||||||
}
|
}
|
||||||
handleResize() {
|
|
||||||
this.setState({
|
|
||||||
windowWidth: Utils.windowWidth(),
|
|
||||||
windowHeight: Utils.windowHeight()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
onChange() {
|
onChange() {
|
||||||
this.setState(this.getStateFromStores());
|
this.setState(this.getStateFromStores());
|
||||||
}
|
}
|
||||||
@@ -492,6 +480,7 @@ export default class Sidebar extends React.Component {
|
|||||||
return (<div/>);
|
return (<div/>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.lastBadgesActive = this.badgesActive;
|
||||||
this.badgesActive = false;
|
this.badgesActive = false;
|
||||||
|
|
||||||
// keep track of the first and last unread channels so we can use them to set the unread indicators
|
// keep track of the first and last unread channels so we can use them to set the unread indicators
|
||||||
@@ -508,21 +497,23 @@ export default class Sidebar extends React.Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// update the favicon to show if there are any notifications
|
// update the favicon to show if there are any notifications
|
||||||
var link = document.createElement('link');
|
if (this.lastBadgesActive !== this.badgesActive) {
|
||||||
link.type = 'image/x-icon';
|
var link = document.createElement('link');
|
||||||
link.rel = 'shortcut icon';
|
link.type = 'image/x-icon';
|
||||||
link.id = 'favicon';
|
link.rel = 'shortcut icon';
|
||||||
if (this.badgesActive) {
|
link.id = 'favicon';
|
||||||
link.href = redFavicon;
|
if (this.badgesActive) {
|
||||||
} else {
|
link.href = redFavicon;
|
||||||
link.href = favicon;
|
} else {
|
||||||
|
link.href = favicon;
|
||||||
|
}
|
||||||
|
var head = document.getElementsByTagName('head')[0];
|
||||||
|
var oldLink = document.getElementById('favicon');
|
||||||
|
if (oldLink) {
|
||||||
|
head.removeChild(oldLink);
|
||||||
|
}
|
||||||
|
head.appendChild(link);
|
||||||
}
|
}
|
||||||
var head = document.getElementsByTagName('head')[0];
|
|
||||||
var oldLink = document.getElementById('favicon');
|
|
||||||
if (oldLink) {
|
|
||||||
head.removeChild(oldLink);
|
|
||||||
}
|
|
||||||
head.appendChild(link);
|
|
||||||
|
|
||||||
var directMessageMore = (
|
var directMessageMore = (
|
||||||
<li key='more'>
|
<li key='more'>
|
||||||
|
|||||||
@@ -67,8 +67,8 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"check": "eslint --ext \".jsx\" --ignore-pattern node_modules --quiet .",
|
"check": "eslint --ext \".jsx\" --ignore-pattern node_modules --quiet .",
|
||||||
"build": "webpack",
|
"build": "NODE_ENV=production webpack",
|
||||||
"run": "webpack --progress --watch",
|
"run": "NODE_ENV=production webpack --progress --watch",
|
||||||
"run-fullmap": "webpack --progress --watch",
|
"run-fullmap": "webpack --progress --watch",
|
||||||
"test": "mocha-webpack --webpack-config webpack.config-test.js \"**/*.test.jsx\""
|
"test": "mocha-webpack --webpack-config webpack.config-test.js \"**/*.test.jsx\""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,9 @@ class ErrorStoreClass extends EventEmitter {
|
|||||||
|
|
||||||
BrowserStore.removeGlobalItem('last_error');
|
BrowserStore.removeGlobalItem('last_error');
|
||||||
BrowserStore.removeGlobalItem('last_error_conn');
|
BrowserStore.removeGlobalItem('last_error_conn');
|
||||||
this.emitChange();
|
if (lastError) {
|
||||||
|
this.emitChange();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -131,7 +131,6 @@ export function updateLastViewedAt(id) {
|
|||||||
() => {
|
() => {
|
||||||
callTracker.updateLastViewed = 0;
|
callTracker.updateLastViewed = 0;
|
||||||
ErrorStore.clearLastError();
|
ErrorStore.clearLastError();
|
||||||
ErrorStore.emitChange();
|
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
callTracker.updateLastViewed = 0;
|
callTracker.updateLastViewed = 0;
|
||||||
|
|||||||
@@ -84,6 +84,11 @@ var config = {
|
|||||||
new webpack.LoaderOptionsPlugin({
|
new webpack.LoaderOptionsPlugin({
|
||||||
minimize: !DEV,
|
minimize: !DEV,
|
||||||
debug: false
|
debug: false
|
||||||
|
}),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env': {
|
||||||
|
NODE_ENV: JSON.stringify('production')
|
||||||
|
}
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user