261 lines
7.9 KiB
JavaScript
261 lines
7.9 KiB
JavaScript
import React, { useRef, useState, useEffect } from "react";
|
|
import { View, Text, TouchableOpacity, Linking, Platform } from "react-native";
|
|
import MapView, { Marker } from "react-native-maps";
|
|
import Constants from "expo-constants";
|
|
import { MaterialCommunityIcons, Ionicons } from "@expo/vector-icons";
|
|
import { useCurrentTrain } from "../stateBox/useCurrentTrain";
|
|
import { useNavigation } from "@react-navigation/native";
|
|
import lineColorList from "../assets/originData/lineColorList";
|
|
import { stationIDPair } from "../lib/getStationList2";
|
|
import { lineListPair } from "../lib/getStationList";
|
|
import { SheetManager } from "react-native-actions-sheet";
|
|
import { useTrainMenu } from "../stateBox/useTrainMenu";
|
|
export default function TrainMenu({ stationData, style }) {
|
|
const { webview } = useCurrentTrain();
|
|
const mapRef = useRef();
|
|
const { navigate } = useNavigation();
|
|
const [stationPin, setStationPin] = useState([]);
|
|
const { selectedLine, setSelectedLine } = useTrainMenu();
|
|
useEffect(() => {
|
|
const stationPinData = [];
|
|
Object.keys(stationData).map((d, indexBase) =>
|
|
stationData[d].map((D, index) => {
|
|
if (!D.StationMap) return null;
|
|
if (selectedLine && selectedLine != d) return;
|
|
const latlng = D.StationMap.replace(
|
|
"https://www.google.co.jp/maps/place/",
|
|
""
|
|
).split(",");
|
|
if (latlng.length == 0) return null;
|
|
stationPinData.push({ D, d, latlng, indexBase: 0, index });
|
|
})
|
|
);
|
|
setStationPin(stationPinData);
|
|
}, [stationData, selectedLine]);
|
|
useEffect(() => {
|
|
mapRef.current.fitToCoordinates(
|
|
stationPin.map(({ latlng }) => ({
|
|
latitude: parseFloat(latlng[0]),
|
|
longitude: parseFloat(latlng[1]),
|
|
})),
|
|
{ edgePadding: { top: 100, bottom: 50, left: 50, right: 50 } } // Add margin values here
|
|
);
|
|
}, [stationPin]);
|
|
return (
|
|
<View style={{ height: "100%", backgroundColor: "#0099CC", ...style }}>
|
|
<MapView
|
|
style={{ flex: 1, width: "100%", height: "100%" }}
|
|
showsUserLocation={true}
|
|
loadingEnabled={true}
|
|
showsMyLocationButton={false}
|
|
moveOnMarkerPress={false}
|
|
showsCompass={false}
|
|
ref={mapRef}
|
|
//provider={PROVIDER_GOOGLE}
|
|
initialRegion={{
|
|
latitude: 33.774519,
|
|
longitude: 133.533306,
|
|
latitudeDelta: 1.8, //小さくなるほどズーム
|
|
longitudeDelta: 1.8,
|
|
}}
|
|
>
|
|
{stationPin.map(({ D, d, latlng, indexBase, index }) => (
|
|
<MapPin
|
|
index={index}
|
|
indexBase={indexBase}
|
|
latlng={latlng}
|
|
D={D}
|
|
d={d}
|
|
navigate={navigate}
|
|
webview={webview}
|
|
key={index + indexBase}
|
|
/>
|
|
))}
|
|
</MapView>
|
|
<View style={{ position: "relative" }}>
|
|
<View
|
|
style={{
|
|
flexDirection: "row",
|
|
position: "absolute",
|
|
width: "100vw",
|
|
bottom: 0,
|
|
flex: 1,
|
|
}}
|
|
>
|
|
<TouchableOpacity
|
|
style={{
|
|
backgroundColor: selectedLine
|
|
? lineColorList[stationIDPair[selectedLine]]
|
|
: "#0099CC",
|
|
padding: 10,
|
|
zIndex: 1,
|
|
alignItems: "center",
|
|
position: "absolute",
|
|
bottom: 0,
|
|
width: "100%",
|
|
paddingBottom: 50,
|
|
}}
|
|
onPress={() => SheetManager.show("TrainMenuLineSelector")}
|
|
>
|
|
<Text
|
|
style={{
|
|
color: "white",
|
|
fontWeight: "bold",
|
|
fontSize: 20,
|
|
textAlign: "center",
|
|
}}
|
|
>
|
|
{selectedLine
|
|
? lineListPair[stationIDPair[selectedLine]]
|
|
: "ここを押して路線をフィルタリングできます ▲"}
|
|
</Text>
|
|
</TouchableOpacity>
|
|
<Text style={{ position: "absolute", bottom: 40 }}>
|
|
路線記号からフィルタリング
|
|
</Text>
|
|
{Object.keys(stationData).map((d) => (
|
|
<TouchableOpacity
|
|
style={{
|
|
flex: 1,
|
|
backgroundColor: lineColorList[stationIDPair[d]],
|
|
padding: 5,
|
|
margin: 2,
|
|
borderRadius: 10,
|
|
borderColor: "white",
|
|
borderWidth: 1,
|
|
borderStyle: "solid",
|
|
alignItems: "center",
|
|
opacity: selectedLine == d ? 1 : !selectedLine ? 1 : 0.5,
|
|
zIndex: 10,
|
|
}}
|
|
onPress={() => setSelectedLine(selectedLine == d ? undefined : d)}
|
|
>
|
|
<Text
|
|
style={{ color: "white", fontWeight: "bold", fontSize: 20 }}
|
|
>
|
|
{stationIDPair[d]}
|
|
</Text>
|
|
</TouchableOpacity>
|
|
))}
|
|
</View>
|
|
</View>
|
|
{navigate && (
|
|
<View style={{ flexDirection: "row" }}>
|
|
<UsefulBox
|
|
backgroundColor={"#F89038"}
|
|
icon="train-car"
|
|
flex={1}
|
|
onPressButton={() =>
|
|
navigate("howto", {
|
|
info: "https://train.jr-shikoku.co.jp/usage.htm",
|
|
})
|
|
}
|
|
>
|
|
使い方
|
|
</UsefulBox>
|
|
<UsefulBox
|
|
backgroundColor={"#EA4752"}
|
|
icon="star"
|
|
flex={1}
|
|
onPressButton={() => navigate("favoriteList")}
|
|
>
|
|
お気に入り
|
|
</UsefulBox>
|
|
<UsefulBox
|
|
backgroundColor={"#91C31F"}
|
|
icon="clipboard-list-outline"
|
|
flex={1}
|
|
onPressButton={() =>
|
|
Linking.openURL(
|
|
"https://nexcloud.haruk.in/apps/forms/ZRHjWFF7znr5Xjr2"
|
|
)
|
|
}
|
|
>
|
|
フィードバック
|
|
</UsefulBox>
|
|
</View>
|
|
)}
|
|
<MapsButton
|
|
onPress={() => navigate("Apps")}
|
|
top={Platform.OS == "ios" ? Constants.statusBarHeight : 0}
|
|
mapSwitch={"flex"}
|
|
/>
|
|
</View>
|
|
);
|
|
}
|
|
const UsefulBox = (props) => {
|
|
const { icon, backgroundColor, flex, onPressButton, children } = props;
|
|
return (
|
|
<TouchableOpacity
|
|
style={{
|
|
flex: flex,
|
|
backgroundColor: backgroundColor,
|
|
padding: 5,
|
|
alignItems: "center",
|
|
margin: 2,
|
|
}}
|
|
onPress={onPressButton}
|
|
>
|
|
<MaterialCommunityIcons name={icon} color="white" size={50} />
|
|
<Text style={{ color: "white", fontWeight: "bold", fontSize: 16 }}>
|
|
{children}
|
|
</Text>
|
|
</TouchableOpacity>
|
|
);
|
|
};
|
|
|
|
const MapPin = ({ index, indexBase, latlng, D, d, navigate, webview }) => {
|
|
return (
|
|
<Marker
|
|
key={index + indexBase}
|
|
coordinate={{
|
|
latitude: parseFloat(latlng[0]),
|
|
longitude: parseFloat(latlng[1]),
|
|
}}
|
|
onPress={() => {
|
|
webview.current?.injectJavaScript(
|
|
`MoveDisplayStation('${d}_${D.MyStation}_${D.Station_JP}');
|
|
document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`
|
|
);
|
|
if (navigate) navigate("Apps");
|
|
}}
|
|
></Marker>
|
|
);
|
|
};
|
|
|
|
const MapsButton = ({ onPress, top, mapSwitch }) => {
|
|
const styles = {
|
|
touch: {
|
|
position: "absolute",
|
|
top,
|
|
left: 10,
|
|
width: 50,
|
|
height: 50,
|
|
backgroundColor: "#0099CC",
|
|
borderColor: "white",
|
|
borderStyle: "solid",
|
|
borderWidth: 1,
|
|
borderRadius: 50,
|
|
alignContent: "center",
|
|
alignSelf: "center",
|
|
alignItems: "center",
|
|
display: mapSwitch,
|
|
},
|
|
text: {
|
|
textAlign: "center",
|
|
width: "auto",
|
|
height: "auto",
|
|
textAlignVertical: "center",
|
|
fontWeight: "bold",
|
|
color: "white",
|
|
},
|
|
};
|
|
return (
|
|
<TouchableOpacity onPress={onPress} style={styles.touch}>
|
|
<View style={{ flex: 1 }} />
|
|
<Ionicons name="close" color="white" size={30} />
|
|
<View style={{ flex: 1 }} />
|
|
</TouchableOpacity>
|
|
);
|
|
};
|