refactored rerendering speed

This commit is contained in:
Fedor Katurov 2020-01-16 11:49:24 +07:00
parent b6bf317649
commit 69d1d749cf
32 changed files with 144 additions and 2045 deletions

View file

@ -32,20 +32,11 @@ const mapStateToProps = ({
user: { role },
},
}: IState) => {
if (routes.filter.max >= 9999) {
return {
routes,
editing,
ready: false,
role,
};
}
return {
role,
routes,
editing,
ready: true,
ready: routes.filter.max < 9999,
};
};

View file

@ -89,18 +89,17 @@ const mapDispatchToProps = {
editorRouterSubmit: EDITOR_ACTIONS.editorRouterSubmit,
};
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & { };
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
const RouterDialogUnconnected: FC<Props> = ({
editor: {
router: { waypoints },
is_routing,
},
editorRouterCancel,
editorRouterSubmit,
}) => (
<div className="control-dialog bottom right">
<div className={classnames('save-loader', { active: is_routing })} />
<div className={classnames('save-loader')} />
{!waypoints.length && noPoints({ editorRouterCancel })}
{waypoints.length === 1 && firstPoint({ editorRouterCancel })}

View file

@ -1,29 +1,25 @@
// @flow
import React from 'react';
import { Icon } from '~/components/panels/Icon';
import { MapListDialog } from "~/components/dialogs/MapListDialog";
import { Tooltip } from "~/components/panels/Tooltip";
import { ReactElement } from "react";
import React, { FC, memo } from 'react';
import { MapListDialog } from '~/components/dialogs/MapListDialog';
import { ReactElement } from 'react';
interface Props {
address: string,
stopEditing: typeof MapListDialog.stopEditing,
dropRoute: typeof MapListDialog.dropRoute,
address: string;
stopEditing: typeof MapListDialog.stopEditing;
dropRoute: typeof MapListDialog.dropRoute;
}
export const RouteRowDrop = ({
address, stopEditing, dropRoute,
}: Props): ReactElement<Props, null> => (
<div
className="route-row-drop"
>
<div
className="route-row"
>
export const RouteRowDrop: FC<Props> = memo(({ address, stopEditing, dropRoute }) => (
<div className="route-row-drop">
<div className="route-row">
<div className="button-group">
<div className="button" onClick={dropRoute.bind(null, address)}>Удалить</div>
<div className="button primary" onClick={stopEditing}>Отмена</div>
<div className="button" onClick={dropRoute.bind(null, address)}>
Удалить
</div>
<div className="button primary" onClick={stopEditing}>
Отмена
</div>
</div>
</div>
</div>
);
));

View file

@ -4,27 +4,24 @@ import { Icon } from '~/components/panels/Icon';
import { connect } from 'react-redux';
import Slider from 'rc-slider/lib/Slider';
import { editorSetSpeed } from '~/redux/editor/actions';
import { Tooltip } from "~/components/panels/Tooltip";
import { isMobile } from "~/utils/window";
import { Tooltip } from '~/components/panels/Tooltip';
import { isMobile } from '~/utils/window';
import { IState } from '~/redux/store';
import pick from 'ramda/es/pick';
import { selectEditor } from '~/redux/editor/selectors';
function mapStateToProps(state) {
const {
editor: { distance, estimated, speed },
}: IState = state;
return { distance, estimated, speed };
}
const mapStateToProps = (state: IState) =>
pick(['distance', 'estimated', 'speed'], selectEditor(state));
const mapDispatchToProps = { editorSetSpeed };
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
interface State {
dialogOpened: boolean,
dialogOpened: boolean;
}
class Component extends React.PureComponent<Props, State> {
class DistanceBarUnconnected extends React.PureComponent<Props, State> {
constructor(props) {
super(props);
this.state = {
@ -36,10 +33,15 @@ class Component extends React.PureComponent<Props, State> {
min: number = 5;
max: number = 30;
marks: { [x: number]: string } = [...Array((Math.floor(this.max - this.min) / this.step) + 1)].reduce((obj, el, index) => ({
...obj,
[this.min + (index * this.step)]: String(this.min + (index * this.step)),
}), { });
marks: { [x: number]: string } = [
...Array(Math.floor(this.max - this.min) / this.step + 1),
].reduce(
(obj, el, index) => ({
...obj,
[this.min + index * this.step]: String(this.min + index * this.step),
}),
{}
);
toggleDialog = () => {
if (isMobile()) return;
@ -51,10 +53,12 @@ class Component extends React.PureComponent<Props, State> {
const {
props: { distance, estimated, speed },
state: { dialogOpened },
min, max, step, marks,
min,
max,
step,
marks,
} = this;
return (
<React.Fragment>
<div className="status-bar padded pointer tooltip-container" onClick={this.toggleDialog}>
@ -65,8 +69,7 @@ class Component extends React.PureComponent<Props, State> {
</span>
<div className="desktop-only">{toHours(estimated)}</div>
</div>
{
dialogOpened &&
{dialogOpened && (
<div className="control-dialog top left" style={{ left: 0, top: 42 }}>
<div className="helper speed-helper">
<Slider
@ -80,13 +83,10 @@ class Component extends React.PureComponent<Props, State> {
/>
</div>
</div>
}
)}
</React.Fragment>
);
}
}
export const DistanceBar = connect(
mapStateToProps,
mapDispatchToProps
)(Component);
export const DistanceBar = connect(mapStateToProps, mapDispatchToProps)(DistanceBarUnconnected);

View file

@ -4,7 +4,6 @@ import classnames from 'classnames';
import { Icon } from '~/components/panels/Icon';
import { EditorDialog } from '~/components/panels/EditorDialog';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import {
editorSetMode,
@ -16,10 +15,10 @@ import {
import { Tooltip } from '~/components/panels/Tooltip';
import { IState } from '~/redux/store';
import { selectEditor } from '~/redux/editor/selectors';
import pick from 'ramda/es/pick';
const mapStateToProps = (state: IState) => ({
editor: selectEditor(state),
});
const mapStateToProps = (state: IState) =>
pick(['mode', 'changed', 'editing', 'features'], selectEditor(state));
const mapDispatchToProps = {
editorSetMode,
@ -54,18 +53,15 @@ class EditorPanelUnconnected extends PureComponent<Props, void> {
startRouterMode = () => this.props.editorSetMode(MODES.ROUTER);
startTrashMode = () => this.props.editorSetMode(MODES.TRASH);
startSaveMode = () => {
// if (!this.props.changed) return;
this.props.editorSetMode(MODES.SAVE);
};
render() {
const {
editor: {
mode,
changed,
editing,
features: { routing },
},
mode,
changed,
editing,
features: { routing },
} = this.props;
return (

View file

@ -1,6 +1,6 @@
import React from 'react';
import React, { memo } from 'react';
export const Icon = ({ icon, size = 32 }: { icon: string, size?: number }) => (
export const Icon = memo(({ icon, size = 32 }: { icon: string; size?: number }) => (
<svg width={size} height={size} viewBox="0 0 32 32">
<defs>
<mask id={`icon-mask-${icon}`}>
@ -9,5 +9,4 @@ export const Icon = ({ icon, size = 32 }: { icon: string, size?: number }) => (
</defs>
<rect x="0" y="0" width="32" height="32" stroke="none" mask={`url(#icon-mask-${icon})`} />
</svg>
);
));

View file

@ -1,10 +1,10 @@
import React from 'react';
import React, { memo } from 'react';
import { UserLocation } from '~/components/UserLocation';
import { DistanceBar } from '~/components/panels/DistanceBar';
export const TopLeftPanel = () => (
export const TopLeftPanel = memo(() => (
<div className="status-panel top left">
<UserLocation />
<DistanceBar />
</div>
);
));

View file

@ -9,11 +9,14 @@ import { MODES } from '~/constants/modes';
import { Tooltip } from '~/components/panels/Tooltip';
import { selectMap } from '~/redux/map/selectors';
import { selectEditor } from '~/redux/editor/selectors';
import { IState } from '~/redux/store';
const mapStateToProps = state => ({
map: selectMap(state),
editor: selectEditor(state),
});
const mapStateToProps = (state: IState) => {
const { provider, logo } = selectMap(state);
const { markers_shown, editing } = selectEditor(state);
return { provider, logo, markers_shown, editing };
};
const mapDispatchToProps = {
editorSetMode: EDITOR_ACTIONS.editorSetMode,
@ -22,8 +25,10 @@ const mapDispatchToProps = {
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
const TopRightPanelUnconnected = ({
map: { provider, logo },
editor: { markers_shown, editing },
provider,
logo,
markers_shown,
editing,
editorSetMode,
}: Props) => {
const startProviderMode = useCallback(() => editorSetMode(MODES.PROVIDER), [editorSetMode]);

View file

@ -19,21 +19,18 @@ import { CLIENT } from '~/config/frontend';
import { DIALOGS, TABS } from '~/constants/dialogs';
import { Tooltip } from '~/components/panels/Tooltip';
import { TitleDialog } from '~/components/dialogs/TitleDialog';
import { IState } from '~/redux/store';
const mapStateToProps = ({
user: { user },
editor: { dialog, dialog_active },
map: { route, stickers },
}) => ({
editor: {
dialog,
dialog_active,
},
user: { user },
map: {
route,
stickers,
}
}: IState) => ({
dialog,
dialog_active,
user,
route,
stickers,
});
const mapDispatchToProps = {
@ -100,7 +97,7 @@ export class UserPanelUnconnected extends PureComponent<Props, State> {
openAppInfoDialog = () => {
this.setMenuOpened();
this.props.editorSetDialog(DIALOGS.APP_INFO);
this.props.editorSetDialogActive(this.props.editor.dialog !== DIALOGS.APP_INFO);
this.props.editorSetDialogActive(this.props.dialog !== DIALOGS.APP_INFO);
};
openOauthFrame = () => {
@ -118,7 +115,7 @@ export class UserPanelUnconnected extends PureComponent<Props, State> {
render() {
const {
props: { user: { user }, editor: { dialog, dialog_active }, map: { route, stickers } },
props: { user, dialog, dialog_active, route, stickers },
state: { menuOpened },
} = this;

View file

@ -1,25 +1,22 @@
// @flow
import React from "react";
import { UserPicture } from "~/components/user/UserPicture";
import { IUser } from "~/constants/auth";
import React, { FC, memo } from 'react';
import { UserPicture } from '~/components/user/UserPicture';
import { IUser } from '~/constants/auth';
interface Props {
user: IUser;
setMenuOpened: () => void;
}
export const UserButton = ({
setMenuOpened,
user: { uid, photo, name }
}: Props) => (
export const UserButton: FC<Props> = memo(({ setMenuOpened, user: { uid, photo, name } }) => (
<div className="control-bar user-bar">
<div className="user-button" onClick={setMenuOpened}>
<UserPicture photo={photo} />
<div className="user-button-fields">
<div className="user-button-name">{name || uid || "..."}</div>
<div className="user-button-text">{uid || "пользователь"}</div>
<div className="user-button-name">{name || uid || '...'}</div>
<div className="user-button-text">{uid || 'пользователь'}</div>
</div>
</div>
</div>
);
));