213 lines
7.1 KiB
JavaScript
213 lines
7.1 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 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]);
|
|
const makeCurrentStation = (location) => {
|
|
if (!originalStationList) return () => {};
|
|
const findStationEachLine = (selectLine) => {
|
|
const searchArea = 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) => d.length > 0)
|
|
.reduce((pre, current) => {
|
|
pre.push(...current);
|
|
return pre;
|
|
}, []);
|
|
if (returnDataBase.length) {
|
|
let currentStation = currentStation == undefined ? [] : currentStation;
|
|
if (currentStation.toString() != returnDataBase.toString()) {
|
|
setCurrentStation(returnDataBase);
|
|
}
|
|
} else {
|
|
setCurrentStation(undefined);
|
|
}
|
|
};
|
|
|
|
const [currentStation, setCurrentStation] = useState(undefined); //第三要素
|
|
|
|
const carouselRef = useRef();
|
|
const [selectedCurrentStation, setSelectedCurrentStation] = useState(0);
|
|
|
|
const [allStationData, setAllStationData] = useState([]);
|
|
useEffect(() => {
|
|
setAllStationData(
|
|
[currentStation, ...favoriteStation].filter((d) => d != undefined)
|
|
);
|
|
}, [currentStation, favoriteStation]);
|
|
useEffect(() => {
|
|
if (allStationData.length == 0) {
|
|
setSelectedCurrentStation(0);
|
|
return;
|
|
}
|
|
if (allStationData[selectedCurrentStation] == undefined) {
|
|
const count = selectedCurrentStation - 1;
|
|
setSelectedCurrentStation(count);
|
|
}
|
|
}, [selectedCurrentStation, currentStation, allStationData]);
|
|
useEffect(() => {
|
|
if (!carouselRef.current) return;
|
|
carouselRef?.current.scrollTo({
|
|
count: selectedCurrentStation - carouselRef.current.getCurrentIndex(),
|
|
animated: true,
|
|
});
|
|
}, [selectedCurrentStation]);
|
|
|
|
useEffect(() => {
|
|
console.log(selectedCurrentStation);
|
|
if (allStationData.length == 0) return;
|
|
if (allStationData[selectedCurrentStation] == undefined) return;
|
|
const { lat, lng } =
|
|
originalStationList &&
|
|
allStationData[selectedCurrentStation] &&
|
|
allStationData[selectedCurrentStation][0];
|
|
const mapRegion = {
|
|
latitude: lat,
|
|
longitude: lng,
|
|
latitudeDelta: 0.05,
|
|
longitudeDelta: 0.05,
|
|
};
|
|
mapsRef.current.animateToRegion(mapRegion, 1000);
|
|
}, [selectedCurrentStation, currentStation, allStationData, 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 }} />
|
|
{allStationData.length != 0 && originalStationList.length != 0 && (
|
|
<>
|
|
<CarouselBox
|
|
{...{
|
|
originalStationList,
|
|
allStationData,
|
|
currentStation,
|
|
setSelectedCurrentStation,
|
|
carouselRef,
|
|
selectedCurrentStation,
|
|
navigate,
|
|
}}
|
|
/>
|
|
{allStationData[selectedCurrentStation] && (
|
|
<LED_vision
|
|
station={allStationData[selectedCurrentStation]}
|
|
getCurrentTrain={getCurrentTrain}
|
|
navigate={navigate}
|
|
openStationACFromEachTrainInfo={() => {}}
|
|
/>
|
|
)}
|
|
</>
|
|
)}
|
|
|
|
<TopMenuButton />
|
|
<JRSTraInfoBox />
|
|
<FixedContentBottom navigate={navigate} />
|
|
</ScrollView>
|
|
</View>
|
|
);
|
|
}
|