441 lines
13 KiB
JavaScript
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%"),
|
|
},
|
|
};
|