Files
jrshikoku/components/駅名表/Sign.js
2024-08-31 07:42:21 +00:00

441 lines
13 KiB
JavaScript

import React, { useRef, useState, useEffect, useLayoutEffect } from "react";
import { View, Text, TouchableOpacity } from "react-native";
import { widthPercentageToDP as wp } from "react-native-responsive-screen";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import LottieView from "lottie-react-native";
import { useInterval } from "../../lib/useInterval";
import { AS } from "../../storageControl";
import { useFavoriteStation } from "../../stateBox/useFavoriteStation";
import { StationName } from "./StationName";
import { StationNameArea } from "./StationNameArea";
import { StationNumberMaker } from "./StationNumberMaker";
import lineColorList from "../../assets/originData/lineColorList";
export default function Sign(props) {
const {
currentStation,
originalStationList,
oP,
oLP,
isCurrentStation = false,
} = props;
const { favoriteStation, setFavoriteStation } = useFavoriteStation();
const [nexPrePosition, setNexPrePosition] = useState(0);
const [preStation, setPreStation] = useState();
const [nexStation, setNexStation] = useState();
const [testButtonStatus, setTestButtonStatus] = useState(false);
useLayoutEffect(() => {
const isFavorite = favoriteStation.filter((d) => {
const compare = JSON.stringify(d);
const current = JSON.stringify(currentStation);
if (compare === current) {
return true;
} else {
return false;
}
});
setTestButtonStatus(isFavorite.length == 0 ? false : true);
}, [favoriteStation, currentStation]);
useEffect(() => {
const isFavorite = favoriteStation.filter((d) => {
const compare = JSON.stringify(d);
const current = JSON.stringify(currentStation);
if (compare === current) {
return true;
} else {
return false;
}
});
setTestButtonStatus(isFavorite.length == 0 ? false : true);
}, [favoriteStation, currentStation]);
useInterval(() => {
if (currentStation.length == 1) {
setNexPrePosition(0);
return () => {};
}
setNexPrePosition(
nexPrePosition + 1 == currentStation.length ? 0 : nexPrePosition + 1
);
}, 2000);
useEffect(() => {
setNexPrePosition(0);
getPreNextStation(currentStation[0]);
}, [currentStation]);
useEffect(() => {
if (!currentStation[nexPrePosition]) return () => {};
getPreNextStation(currentStation[nexPrePosition]);
}, [nexPrePosition]);
const getPreNextStation = (now) => {
const lineList = [
"予讃線(高松-松山間)[Y]",
"予讃線(松山-宇和島間)[U]",
"予讃線/愛ある伊予灘線(向井原-伊予大洲間)[S]",
"土讃線(多度津-高知間)[D]",
"土讃線(高知-窪川間)[K]",
"高徳線(高松-徳島間)[T]",
"徳島線(徳島-阿波池田間)[B]",
"鳴門線(池谷-鳴門間)[N]",
"瀬戸大橋線(児島-宇多津間)[M]",
];
let returnData;
lineList.forEach((d) => {
let cache = originalStationList[d].findIndex(
(data) => data.StationNumber == now.StationNumber
);
if (cache != -1) {
returnData = [
originalStationList[d][cache - 1],
originalStationList[d][cache + 1],
];
}
});
setPreStation(returnData[0]);
setNexStation(returnData[1]);
};
const lottieRef = useRef();
const isMatsuyama = currentStation[0].StationNumber == "Y55";
//const isMatsuyama = true;
if (isMatsuyama) {
return (
<TouchableOpacity style={styleSheet.外枠} onPress={oP} onLongPress={oLP}>
<LottieView
autoPlay
loop
style={{
width: wp("80%"),
height: (wp("80%") / 20) * 9,
backgroundColor: "#fff",
}}
source={{ uri: "https://cdn.lottielab.com/l/D4m3dmEqsjVN77.json?s" }}
/>
<StationNumberMaker
currentStation={currentStation}
isMatsuyama={isMatsuyama}
/>
<StationNameArea
currentStation={currentStation}
isMatsuyama={isMatsuyama}
/>
{isCurrentStation ? (
<TouchableOpacity style={{ position: "absolute", right: 0, top: 0 }}>
<MaterialCommunityIcons
name="crosshairs-gps"
style={{ padding: 5 }}
color="#2E94BB"
size={30}
/>
</TouchableOpacity>
) : (
<TouchableOpacity
style={{ position: "absolute", right: -15, top: -20 }}
onPress={() => {
if (testButtonStatus) {
const otherData = favoriteStation.filter((d) => {
const compare = JSON.stringify(d);
const current = JSON.stringify(currentStation);
if (compare !== current) {
return true;
} else {
return false;
}
});
AS.setItem("favoriteStation", JSON.stringify(otherData));
setFavoriteStation(otherData);
} else {
let ret = favoriteStation;
ret.push(currentStation);
AS.setItem("favoriteStation", JSON.stringify(ret));
setFavoriteStation(ret);
}
setTestButtonStatus(!testButtonStatus);
}}
>
<LottieDelayView
progress={testButtonStatus ? 1 : 0}
speed={1.4}
style={{ width: 80, height: 80 }}
source={require("../../assets/939-star.json")}
lottieRef={lottieRef}
loop={false}
/>
</TouchableOpacity>
)}
<Text style={styleSheet.JRStyle}>JR</Text>
<View style={styleSheet.下帯B} />
<View style={styleSheet.下帯内容B}>
<NexPreStationLine
preStation={preStation}
nexStation={nexStation}
isMatsuyama={isMatsuyama}
/>
</View>
</TouchableOpacity>
);
} else {
return (
<TouchableOpacity style={styleSheet.外枠} onPress={oP} onLongPress={oLP}>
<StationNumberMaker
currentStation={currentStation}
isMatsuyama={isMatsuyama}
/>
<StationNameArea
currentStation={currentStation}
isMatsuyama={isMatsuyama}
/>
{isCurrentStation ? (
<TouchableOpacity style={{ position: "absolute", right: 0, top: 0 }}>
<MaterialCommunityIcons
name="crosshairs-gps"
style={{ padding: 5 }}
color="#2E94BB"
size={30}
/>
</TouchableOpacity>
) : (
<TouchableOpacity
style={{ position: "absolute", right: -15, top: -20 }}
onPress={() => {
if (testButtonStatus) {
const otherData = favoriteStation.filter((d) => {
const compare = JSON.stringify(d);
const current = JSON.stringify(currentStation);
if (compare !== current) {
return true;
} else {
return false;
}
});
AS.setItem("favoriteStation", JSON.stringify(otherData));
setFavoriteStation(otherData);
} else {
let ret = favoriteStation;
ret.push(currentStation);
AS.setItem("favoriteStation", JSON.stringify(ret));
setFavoriteStation(ret);
}
setTestButtonStatus(!testButtonStatus);
}}
>
<LottieDelayView
progress={testButtonStatus ? 1 : 0}
speed={1.4}
style={{ width: 80, height: 80 }}
source={require("../../assets/939-star.json")}
lottieRef={lottieRef}
loop={false}
/>
</TouchableOpacity>
)}
<Text style={styleSheet.JRStyle}>JR</Text>
<View style={styleSheet.下帯} />
<View style={styleSheet.下帯内容}>
<NexPreStationLine
preStation={preStation}
nexStation={nexStation}
isMatsuyama={isMatsuyama}
/>
</View>
</TouchableOpacity>
);
}
}
const LottieDelayView = ({
progress,
speed,
style,
source,
lottieRef,
loop,
}) => {
const [progressState, setProgressState] = useState(undefined);
useEffect(() => {
if (progress == 0) {
lottieRef.current.play(progressState !== undefined ? 35 : 7, 7);
} else {
lottieRef.current.play(progressState !== undefined ? 7 : 35, 35);
}
}, [progress]);
return (
<LottieView
progress={progressState}
speed={speed}
style={style}
source={source}
ref={lottieRef}
loop={loop}
onAnimationFinish={(isCanceled) => {
setProgressState(progress);
}}
/>
);
};
const NexPreStationLine = ({ nexStation, preStation, isMatsuyama }) => {
return (
<View style={styleSheet.下枠フレーム}>
<View style={styleSheet.下枠フレーム}>
{preStation ? (
<>
{!isMatsuyama && <Text style={styleSheet.下枠左右マーク}></Text>}
{preStation.StationNumber ? (
<View
style={
isMatsuyama
? styleSheet.下枠駅ナンバーB
: styleSheet.下枠駅ナンバー
}
>
<View style={{ flex: 1 }} />
<Text
style={{
fontSize: parseInt("10%"),
color: isMatsuyama ? "black" : "white",
}}
>
{preStation.StationNumber}
</Text>
<View style={{ flex: 1 }} />
</View>
) : (
<></>
)}
<StationName
stringData={preStation}
ss={{ flex: 1, alignItems: "flex-start" }}
/>
</>
) : (
<></>
)}
</View>
<View style={styleSheet.下枠フレーム}>
{nexStation ? (
<>
<StationName
stringData={nexStation}
ss={{ flex: 1, alignItems: "flex-end" }}
/>
{nexStation.StationNumber ? (
<View
style={
isMatsuyama
? styleSheet.下枠駅ナンバーB
: styleSheet.下枠駅ナンバー
}
>
<View style={{ flex: 1 }} />
<Text
style={{
fontSize: parseInt("10%"),
color: isMatsuyama ? "black" : "white",
}}
>
{nexStation.StationNumber}
</Text>
<View style={{ flex: 1 }} />
</View>
) : (
<></>
)}
{!isMatsuyama && <Text style={styleSheet.下枠左右マーク}></Text>}
</>
) : (
<></>
)}
</View>
</View>
);
};
const styleSheet = {
外枠: {
width: wp("80%"),
height: (wp("80%") / 20) * 9,
borderColor: "#2E94BB",
borderWidth: 1,
backgroundColor: "white",
},
下帯: {
position: "absolute",
bottom: "0%",
left: "0%",
width: "100%",
height: "30%",
backgroundColor: "#2E94BB",
},
下帯B: {
position: "absolute",
bottom: "0%",
left: "0%",
width: "100%",
height: "25%",
backgroundColor: "#454545",
},
JRStyle: {
position: "absolute",
top: "2%",
left: "2%",
fontWeight: "bold",
fontSize: parseInt("30%"),
color: "#2E94BB",
},
下帯内容: {
position: "absolute",
bottom: "0%",
height: "30%",
width: "100%",
alignItems: "center",
flexDirection: "column",
},
下帯内容B: {
position: "absolute",
bottom: "0%",
height: "25%",
width: "100%",
alignItems: "center",
flexDirection: "column",
},
下枠フレーム: {
flex: 1,
flexDirection: "row",
alignContent: "center",
alignItems: "center",
},
下枠左右マーク: {
fontWeight: "bold",
fontSize: parseInt("20%"),
color: "white",
paddingHorizontal: 10,
textAlignVertical: "center",
},
下枠駅ナンバー: {
alignContent: "center",
alignItems: "center",
width: wp("8%"),
height: wp("8%"),
margin: wp("1%"),
borderColor: "white",
borderWidth: parseInt("2%"),
borderRadius: parseInt("100%"),
},
下枠駅ナンバーB: {
alignContent: "center",
alignItems: "center",
width: wp("7%"),
height: wp("7%"),
margin: wp("2%"),
borderColor: "black",
backgroundColor: "white",
borderWidth: parseInt("2%"),
borderRadius: parseInt("100%"),
},
};