移动端千目GO
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

211 lines
6.0 KiB

import "./style.scss";
import React, { useState, useEffect } from "react";
import search from "./search.png";
import close from "./close.png";
import go from "./go.png";
import arrow from "./arrow.png";
import ShopsWithFilter from "../ShopsWithFilter/ShopsWithFilter";
const STATES = {
init: 0,
moreFac: 1,
facList: 2,
};
export const DefaultPopupStates = STATES;
const initMarginBottom = 47;
const DefaultPopup = ({
state,
setState,
onSearch,
facilities,
onClickFac,
mall,
onClick,
setEnd,
hasTab,
blurMap = () => {},
}) => {
const marginBottomStateMap = {
0: 47,
1: hasTab
? window.innerHeight - 52 - 179 - 98
: window.innerHeight - 52 - 179,
};
const baseMarginBottom = marginBottomStateMap[state];
const [facList, setFacList] = useState(null);
const [focused, setFocused] = useState(null);
const [start, setStart] = useState(null);
const [marginBottom, setMarginBottom] = useState(null);
const [doTransition, setdoTransition] = useState(false);
useEffect(() => {
setdoTransition(true);
setMarginBottom(baseMarginBottom);
setTimeout(() => {
setdoTransition(false);
}, 500);
}, [state]);
const handleTouchStart = (e) => {
if (start) return;
setStart({
identifier: e.changedTouches[0].identifier,
y: e.changedTouches[0].clientY,
});
};
const handleTouchMove = (e) => {
if (!start) return;
const touch = Array.from(e.changedTouches).find(
({ identifier }) => identifier === start.identifier
);
if (!touch) return;
const delta = touch.clientY - start.y;
setMarginBottom(baseMarginBottom - delta);
};
const handleTouchEnd = (e) => {
if (!start) return;
const touch = Array.from(e.changedTouches).find(
({ identifier }) => identifier === start.identifier
);
if (!touch) return;
setStart(null);
const delta = touch.clientY - start.y;
const newState =
state === STATES.init && delta < -100
? STATES.moreFac
: state === STATES.moreFac && delta > 100
? STATES.init
: state;
if (state === newState) {
setdoTransition(true);
setMarginBottom(baseMarginBottom);
setTimeout(() => {
setdoTransition(false);
}, 500);
} else setState(newState);
};
return (
<>
{state === STATES.init || state === STATES.moreFac ? (
<div
className={"dp" + (state === STATES.moreFac ? " more-fac" : "")}
style={{
marginBottom: marginBottom + "px",
transition: !doTransition ? "none" : "margin-bottom 0.5s ease",
}}
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onTouchCancel={handleTouchEnd}
onTouchEnd={handleTouchEnd}
>
<div
className="ts"
onClick={() =>
setState(state === STATES.moreFac ? STATES.init : STATES.moreFac)
}
>
<img className="t1" src={arrow} />
</div>
<div className="search" onClick={onSearch}>
<img className="icon" src={search}></img>
<div className="sep"></div>
搜索店铺
</div>
<div className="facs">
{Object.entries(facilities).map(([name, list]) => (
<div
className="fac"
key={name}
onClick={() => {
list.sort((a, b) => a.floorOrder - b.floorOrder);
setFacList(list);
setState(STATES.facList);
}}
>
<img src={list[0].url}></img>
{name}
</div>
))}
</div>
</div>
) : (
<>
<img
src={close}
className="close"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
setState(STATES.init);
setFacList(null);
blurMap();
}}
></img>
<div className="dp1">
{facList &&
facList.map((fac, i) => {
const showRow1 =
i === 0 || fac.floorName !== facList[i - 1].floorName;
const isActive = focused === fac.id;
return (
<div key={fac.id}>
{showRow1 && (
<div className={"row1" + (i === 0 ? "" : " has-border")}>
{fac.floorName}
</div>
)}
<div
className={[
"row2",
isActive ? "active" : "",
!showRow1 ? "has-margin" : "",
].join(" ")}
onClick={() => {
setFocused(fac.id);
onClickFac(fac.id);
}}
>
{fac.name}
<span className="meta">{fac.floorName}</span>
{isActive && (
<div
className="go"
src={go}
onClick={(e) => {
e.stopPropagation();
setState(STATES.init);
onClickFac(fac.id);
}}
>
GO
</div>
)}
</div>
</div>
);
})}
</div>
</>
)}
{state !== STATES.facList && (
<div
className="sf"
onClick={() => {
setState(STATES.moreFac);
}}
>
<ShopsWithFilter
mall={mall}
onClick={(e) => {
setState(STATES.init);
onClick(e);
}}
wingHeight="calc(100vh - 310px)"
></ShopsWithFilter>
</div>
)}
</>
);
};
export default DefaultPopup;