227 lines
7.5 KiB
JavaScript
227 lines
7.5 KiB
JavaScript
import React, { useRef, useState, useEffect } from "react";
|
|
import { Platform, View, ScrollView, useWindowDimensions } from "react-native";
|
|
import Constants from "expo-constants";
|
|
import {
|
|
configureReanimatedLogger,
|
|
ReanimatedLogLevel,
|
|
} from "react-native-reanimated";
|
|
import StatusbarDetect from "./StatusbarDetect";
|
|
|
|
import LED_vision from "./components/発車時刻表/LED_vidion";
|
|
import { TitleBar } from "./components/Menu/TitleBar";
|
|
import { FixedContentBottom } from "./components/Menu/FixedContentBottom";
|
|
|
|
import { lineList } from "./lib/getStationList";
|
|
import { useFavoriteStation } from "./stateBox/useFavoriteStation";
|
|
import { useNavigation } from "@react-navigation/native";
|
|
import { useStationList } from "./stateBox/useStationList";
|
|
import { TopMenuButton } from "@/components/Menu/TopMenuButton";
|
|
import { JRSTraInfoBox } from "@/components/Menu/JRSTraInfoBox";
|
|
import MapView from "react-native-maps";
|
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs";
|
|
import { CarouselBox } from "./components/Menu/Carousel/CarouselBox";
|
|
import { CarouselTypeChanger } from "./components/Menu/Carousel/CarouselTypeChanger";
|
|
import { useUserPosition } from "./stateBox/useUserPosition";
|
|
configureReanimatedLogger({
|
|
level: ReanimatedLogLevel.error, // Set the log level to error
|
|
strict: true, // Reanimated runs in strict mode by default
|
|
});
|
|
export default function Menu({ getCurrentTrain, scrollRef }) {
|
|
const { navigate, addListener, isFocused } = useNavigation();
|
|
const { favoriteStation } = useFavoriteStation();
|
|
const { originalStationList } = useStationList();
|
|
const { height, width } = useWindowDimensions();
|
|
const { bottom, left, right, top } = useSafeAreaInsets();
|
|
const tabBarHeight = useBottomTabBarHeight();
|
|
const [mapsOpacity, setMapsOpacity] = useState(false);
|
|
const [stationListMode, setStationListMode] = useState(
|
|
/*<"position"|"favorite">*/ "position"
|
|
);
|
|
const mapsRef = useRef(null);
|
|
const MapHeight =
|
|
height -
|
|
tabBarHeight +
|
|
(Platform.OS == "android" ? Constants.statusBarHeight : 0) -
|
|
100 -
|
|
((((width / 100) * 80) / 20) * 9 + 10 + 30);
|
|
useEffect(() => {
|
|
setTimeout(() => {
|
|
if (scrollRef.current) {
|
|
scrollRef.current.scrollTo({
|
|
y: MapHeight - 80,
|
|
animated: false,
|
|
});
|
|
}
|
|
}, 10);
|
|
}, []);
|
|
//位置情報
|
|
const { position, locationStatus } = useUserPosition();
|
|
|
|
useEffect(() => {
|
|
if (!position) return () => {};
|
|
makeCurrentStation(position);
|
|
}, [position, stationListMode]);
|
|
const makeCurrentStation = (location) => {
|
|
if (!originalStationList) return () => {};
|
|
const findStationEachLine = (selectLine) => {
|
|
const searchArea = stationListMode == "position" ? 0.07 : 0.002;
|
|
const _calcDistance = (from, to) => {
|
|
let lat = Math.abs(from.lat - to.lat);
|
|
let lng = Math.abs(from.lng - to.lng);
|
|
return Math.sqrt(lat * lat + lng * lng);
|
|
};
|
|
let NearStation = selectLine.filter(
|
|
(d) =>
|
|
_calcDistance(d, {
|
|
lat: location.coords.latitude,
|
|
lng: location.coords.longitude,
|
|
}) < searchArea
|
|
);
|
|
return NearStation;
|
|
};
|
|
|
|
let returnDataBase = lineList
|
|
.map((d) => findStationEachLine(originalStationList[d]))
|
|
.filter((d) => {
|
|
return d.length > 0;
|
|
})
|
|
.reduce((pre, current) => {
|
|
pre.push(...current);
|
|
return pre;
|
|
}, []);
|
|
if (returnDataBase.length) {
|
|
let currentStation = currentStation == undefined ? [] : currentStation;
|
|
if (currentStation.toString() != returnDataBase.toString()) {
|
|
setNearPositionStation(returnDataBase);
|
|
}
|
|
} else {
|
|
setNearPositionStation(undefined);
|
|
}
|
|
};
|
|
|
|
const [nearPositionStation, setNearPositionStation] = useState(undefined); //第三要素
|
|
|
|
const carouselRef = useRef();
|
|
const [listIndex, setListIndex] = useState(0);
|
|
|
|
const [listUpStation, setListUpStation] = useState([]);
|
|
useEffect(() => {
|
|
if (stationListMode == "position") {
|
|
console.log(nearPositionStation);
|
|
setListUpStation([nearPositionStation].filter((d) => d != undefined));
|
|
} else {
|
|
setListUpStation(favoriteStation.filter((d) => d != undefined));
|
|
}
|
|
}, [nearPositionStation, favoriteStation, stationListMode]);
|
|
useEffect(() => {
|
|
if (listUpStation.length == 0) {
|
|
setListIndex(0);
|
|
return;
|
|
}
|
|
if (listUpStation[listIndex] == undefined) {
|
|
const count = listIndex - 1;
|
|
setListIndex(count);
|
|
}
|
|
}, [listIndex, nearPositionStation, listUpStation]);
|
|
useEffect(() => {
|
|
if (!carouselRef.current) return;
|
|
carouselRef?.current.scrollTo({
|
|
count: listIndex - carouselRef.current.getCurrentIndex(),
|
|
animated: true,
|
|
});
|
|
}, [listIndex]);
|
|
|
|
useEffect(() => {
|
|
if (originalStationList == undefined) return;
|
|
if (listUpStation.length == 0) return;
|
|
if (listUpStation[listIndex] == undefined) return;
|
|
const { lat, lng } = listUpStation[listIndex][0];
|
|
const mapRegion = {
|
|
latitude: lat,
|
|
longitude: lng,
|
|
latitudeDelta: 0.05,
|
|
longitudeDelta: 0.05,
|
|
};
|
|
mapsRef.current.animateToRegion(mapRegion, 1000);
|
|
}, [listIndex, nearPositionStation, listUpStation, mapsRef]);
|
|
return (
|
|
<View
|
|
style={{
|
|
height: "100%",
|
|
backgroundColor: "white",
|
|
paddingTop: Platform.OS == "ios" ? Constants.statusBarHeight : 0,
|
|
}}
|
|
>
|
|
<StatusbarDetect />
|
|
<TitleBar />
|
|
<ScrollView
|
|
ref={scrollRef}
|
|
snapToStart={false}
|
|
snapToEnd={false}
|
|
decelerationRate={"normal"}
|
|
onScroll={(d) => {
|
|
const scrollY = d.nativeEvent.contentOffset.y + 100;
|
|
setMapsOpacity(scrollY < MapHeight);
|
|
}}
|
|
snapToOffsets={[MapHeight - 80]}
|
|
>
|
|
<MapView
|
|
ref={mapsRef}
|
|
style={{ flex: 1, width: "100%", height: MapHeight }}
|
|
showsUserLocation={true}
|
|
loadingEnabled={true}
|
|
showsMyLocationButton={false}
|
|
moveOnMarkerPress={false}
|
|
showsCompass={false}
|
|
//provider={PROVIDER_GOOGLE}
|
|
initialRegion={{
|
|
latitude: 33.774519,
|
|
longitude: 133.533306,
|
|
latitudeDelta: 1.8, //小さくなるほどズーム
|
|
longitudeDelta: 1.8,
|
|
}}
|
|
onPress={() => alert("地図をタップ")}
|
|
/>
|
|
<CarouselTypeChanger
|
|
{...{
|
|
locationStatus,
|
|
position,
|
|
mapsRef,
|
|
stationListMode,
|
|
setStationListMode,
|
|
setSelectedCurrentStation: setListIndex,
|
|
}}
|
|
/>
|
|
{listUpStation.length != 0 && originalStationList.length != 0 && (
|
|
<>
|
|
<CarouselBox
|
|
{...{
|
|
originalStationList,
|
|
allStationData: listUpStation,
|
|
currentStation: nearPositionStation,
|
|
setSelectedCurrentStation: setListIndex,
|
|
carouselRef,
|
|
selectedCurrentStation: listIndex,
|
|
navigate,
|
|
}}
|
|
/>
|
|
{listUpStation[listIndex] && (
|
|
<LED_vision
|
|
station={listUpStation[listIndex]}
|
|
getCurrentTrain={getCurrentTrain}
|
|
navigate={navigate}
|
|
openStationACFromEachTrainInfo={() => {}}
|
|
/>
|
|
)}
|
|
</>
|
|
)}
|
|
|
|
<TopMenuButton />
|
|
<JRSTraInfoBox />
|
|
<FixedContentBottom navigate={navigate} />
|
|
</ScrollView>
|
|
</View>
|
|
);
|
|
}
|