mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-24 18:46:40 +07:00
map dialog optimizations
This commit is contained in:
parent
23b8f5dea6
commit
b6bf317649
3 changed files with 146 additions and 110 deletions
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { RouteRowWrapper } from '~/components/maps/RouteRowWrapper';
|
||||
import { Scroll } from '~/components/Scroll';
|
||||
|
@ -17,14 +17,13 @@ import { editorSetDialogActive } from '~/redux/editor/actions';
|
|||
import { isMobile } from '~/utils/window';
|
||||
import classnames from 'classnames';
|
||||
|
||||
import Range from 'rc-slider/lib/Range';
|
||||
import { TABS, TABS_TITLES } from '~/constants/dialogs';
|
||||
import { Icon } from '~/components/panels/Icon';
|
||||
import { pushPath } from '~/utils/history';
|
||||
import { IRouteListItem } from '~/redux/user';
|
||||
import { ROLES } from '~/constants/auth';
|
||||
import { IState } from '~/redux/store';
|
||||
|
||||
import { MapListDialogHead } from '~/components/search/MapListDialogHead';
|
||||
|
||||
const mapStateToProps = ({
|
||||
editor: { editing },
|
||||
|
@ -37,7 +36,6 @@ const mapStateToProps = ({
|
|||
return {
|
||||
routes,
|
||||
editing,
|
||||
marks: {},
|
||||
ready: false,
|
||||
role,
|
||||
};
|
||||
|
@ -48,16 +46,6 @@ const mapStateToProps = ({
|
|||
routes,
|
||||
editing,
|
||||
ready: true,
|
||||
marks: [...new Array(Math.floor((routes.filter.max - routes.filter.min) / 25) + 1)].reduce(
|
||||
(obj, el, i) => ({
|
||||
...obj,
|
||||
[routes.filter.min + i * 25]: ` ${routes.filter.min + i * 25}${
|
||||
routes.filter.min + i * 25 >= 200 ? '+' : ''
|
||||
}
|
||||
`,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -72,7 +60,7 @@ const mapDispatchToProps = {
|
|||
toggleRouteStarred,
|
||||
};
|
||||
|
||||
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {}
|
||||
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
|
||||
|
||||
export interface State {
|
||||
menu_target: IRouteListItem['address'];
|
||||
|
@ -82,7 +70,7 @@ export interface State {
|
|||
is_dropping: boolean;
|
||||
}
|
||||
|
||||
class MapListDialogUnconnected extends React.Component<Props, State> {
|
||||
class MapListDialogUnconnected extends PureComponent<Props, State> {
|
||||
state = {
|
||||
menu_target: null,
|
||||
editor_target: null,
|
||||
|
@ -178,8 +166,8 @@ class MapListDialogUnconnected extends React.Component<Props, State> {
|
|||
loading,
|
||||
filter: { min, max, title, distance, tab },
|
||||
},
|
||||
marks,
|
||||
}: Props = this.props;
|
||||
}: // marks,
|
||||
Props = this.props;
|
||||
|
||||
const { editor_target, menu_target, is_editing, is_dropping } = this.state;
|
||||
|
||||
|
@ -192,6 +180,7 @@ class MapListDialogUnconnected extends React.Component<Props, State> {
|
|||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{ready && !loading && list.length === 0 && (
|
||||
<div className="dialog-maplist-loader">
|
||||
<div className="dialog-maplist-icon">
|
||||
|
@ -200,6 +189,7 @@ class MapListDialogUnconnected extends React.Component<Props, State> {
|
|||
ТУТ ПУСТО <br />И ОДИНОКО
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="dialog-tabs">
|
||||
{Object.values(TABS).map(
|
||||
item =>
|
||||
|
@ -214,32 +204,16 @@ class MapListDialogUnconnected extends React.Component<Props, State> {
|
|||
)
|
||||
)}
|
||||
</div>
|
||||
<div className="dialog-head">
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Поиск по названию"
|
||||
value={title}
|
||||
onChange={this.setTitle}
|
||||
/>
|
||||
<br />
|
||||
{ready && Object.keys(marks).length > 2 ? (
|
||||
<Range
|
||||
min={min}
|
||||
max={max}
|
||||
marks={marks}
|
||||
step={25}
|
||||
onChange={this.props.searchSetDistance}
|
||||
defaultValue={[0, 10000]}
|
||||
value={distance}
|
||||
pushable={25}
|
||||
disabled={min >= max}
|
||||
/>
|
||||
) : (
|
||||
<div className="range-placeholder" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<MapListDialogHead
|
||||
min={min}
|
||||
max={max}
|
||||
distance={distance}
|
||||
onDistanceChange={this.props.searchSetDistance}
|
||||
ready={ready}
|
||||
search={title}
|
||||
onSearchChange={this.setTitle}
|
||||
/>
|
||||
|
||||
<Scroll className="dialog-shader" onScroll={this.onScroll}>
|
||||
<div className="dialog-maplist">
|
||||
|
@ -276,7 +250,6 @@ class MapListDialogUnconnected extends React.Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
const MapListDialog = connect(mapStateToProps, mapDispatchToProps)(MapListDialogUnconnected);
|
||||
|
||||
export { MapListDialog };
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import React from "react";
|
||||
import classnames from "classnames";
|
||||
import { MapListDialog } from "~/components/dialogs/MapListDialog";
|
||||
import { RouteRowView } from "~/components/maps/RouteRowView";
|
||||
import { RouteRowEditor } from "~/components/maps/RouteRowEditor";
|
||||
import { RouteRowDrop } from "~/components/maps/RouteRowDrop";
|
||||
import { ReactElement } from "react";
|
||||
import React, { FC, memo } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { MapListDialog } from '~/components/dialogs/MapListDialog';
|
||||
import { RouteRowView } from '~/components/maps/RouteRowView';
|
||||
import { RouteRowEditor } from '~/components/maps/RouteRowEditor';
|
||||
import { RouteRowDrop } from '~/components/maps/RouteRowDrop';
|
||||
import { ReactElement } from 'react';
|
||||
|
||||
interface Props {
|
||||
address: string;
|
||||
|
@ -28,64 +28,66 @@ interface Props {
|
|||
modifyRoute: typeof MapListDialog.modifyRoute;
|
||||
toggleStarred: typeof MapListDialog.toggleStarred;
|
||||
|
||||
is_editing_mode: "edit" | "drop";
|
||||
is_editing_mode: 'edit' | 'drop';
|
||||
}
|
||||
|
||||
export const RouteRowWrapper = ({
|
||||
title,
|
||||
distance,
|
||||
address,
|
||||
openRoute,
|
||||
tab,
|
||||
startEditing,
|
||||
showMenu,
|
||||
showDropCard,
|
||||
is_public,
|
||||
is_editing_target,
|
||||
is_menu_target,
|
||||
is_editing_mode,
|
||||
dropRoute,
|
||||
stopEditing,
|
||||
modifyRoute,
|
||||
hideMenu,
|
||||
is_admin,
|
||||
is_published,
|
||||
toggleStarred
|
||||
}: Props): ReactElement<Props, null> => (
|
||||
<div
|
||||
className={classnames("route-row-wrapper", {
|
||||
is_menu_target,
|
||||
is_editing_target
|
||||
})}
|
||||
>
|
||||
{is_editing_target && is_editing_mode === "edit" && (
|
||||
<RouteRowEditor
|
||||
title={title}
|
||||
address={address}
|
||||
is_public={is_public}
|
||||
modifyRoute={modifyRoute}
|
||||
/>
|
||||
)}
|
||||
{is_editing_target && is_editing_mode === "drop" && (
|
||||
<RouteRowDrop address={address} dropRoute={dropRoute} stopEditing={stopEditing} />
|
||||
)}
|
||||
{!is_editing_target && (
|
||||
<RouteRowView
|
||||
address={address}
|
||||
tab={tab}
|
||||
title={title}
|
||||
distance={distance}
|
||||
is_public={is_public}
|
||||
is_published={is_published}
|
||||
openRoute={openRoute}
|
||||
startEditing={startEditing}
|
||||
stopEditing={stopEditing}
|
||||
showMenu={showMenu}
|
||||
hideMenu={hideMenu}
|
||||
showDropCard={showDropCard}
|
||||
is_admin={is_admin}
|
||||
toggleStarred={toggleStarred}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
export const RouteRowWrapper: FC<Props> = memo(
|
||||
({
|
||||
title,
|
||||
distance,
|
||||
address,
|
||||
openRoute,
|
||||
tab,
|
||||
startEditing,
|
||||
showMenu,
|
||||
showDropCard,
|
||||
is_public,
|
||||
is_editing_target,
|
||||
is_menu_target,
|
||||
is_editing_mode,
|
||||
dropRoute,
|
||||
stopEditing,
|
||||
modifyRoute,
|
||||
hideMenu,
|
||||
is_admin,
|
||||
is_published,
|
||||
toggleStarred,
|
||||
}) => (
|
||||
<div
|
||||
className={classnames('route-row-wrapper', {
|
||||
is_menu_target,
|
||||
is_editing_target,
|
||||
})}
|
||||
>
|
||||
{is_editing_target && is_editing_mode === 'edit' && (
|
||||
<RouteRowEditor
|
||||
title={title}
|
||||
address={address}
|
||||
is_public={is_public}
|
||||
modifyRoute={modifyRoute}
|
||||
/>
|
||||
)}
|
||||
{is_editing_target && is_editing_mode === 'drop' && (
|
||||
<RouteRowDrop address={address} dropRoute={dropRoute} stopEditing={stopEditing} />
|
||||
)}
|
||||
{!is_editing_target && (
|
||||
<RouteRowView
|
||||
address={address}
|
||||
tab={tab}
|
||||
title={title}
|
||||
distance={distance}
|
||||
is_public={is_public}
|
||||
is_published={is_published}
|
||||
openRoute={openRoute}
|
||||
startEditing={startEditing}
|
||||
stopEditing={stopEditing}
|
||||
showMenu={showMenu}
|
||||
hideMenu={hideMenu}
|
||||
showDropCard={showDropCard}
|
||||
is_admin={is_admin}
|
||||
toggleStarred={toggleStarred}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
|
61
src/components/search/MapListDialogHead.tsx
Normal file
61
src/components/search/MapListDialogHead.tsx
Normal file
|
@ -0,0 +1,61 @@
|
|||
import React, { FC, memo, useMemo, ChangeEvent, ChangeEventHandler } from 'react';
|
||||
import Range from 'rc-slider/lib/Range';
|
||||
|
||||
interface Props {
|
||||
ready: boolean;
|
||||
min: number;
|
||||
max: number;
|
||||
search: string;
|
||||
distance: [number, number];
|
||||
onDistanceChange: (val: [number, number]) => void;
|
||||
onSearchChange: ChangeEventHandler<HTMLInputElement>;
|
||||
}
|
||||
|
||||
const MapListDialogHead: FC<Props> = memo(
|
||||
({ min, max, ready, distance, search, onSearchChange, onDistanceChange }) => {
|
||||
const marks = useMemo(
|
||||
() =>
|
||||
[...new Array(Math.floor((max - min) / 25) + 1)].reduce(
|
||||
(obj, el, i) => ({
|
||||
...obj,
|
||||
[min + i * 25]: min + i * 25 < 200 ? ` ${min + i * 25}` : ` ${min + i * 25}+`,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="dialog-head">
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Поиск по названию"
|
||||
value={search}
|
||||
onChange={onSearchChange}
|
||||
/>
|
||||
|
||||
<div />
|
||||
|
||||
{ready && Object.keys(marks).length > 2 ? (
|
||||
<Range
|
||||
min={min}
|
||||
max={max}
|
||||
marks={marks}
|
||||
step={25}
|
||||
onChange={onDistanceChange}
|
||||
defaultValue={[0, 10000]}
|
||||
value={distance}
|
||||
pushable={25}
|
||||
disabled={min >= max}
|
||||
/>
|
||||
) : (
|
||||
<div className="range-placeholder" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export { MapListDialogHead };
|
Loading…
Add table
Add a link
Reference in a new issue