674 lines
20 KiB
TypeScript
674 lines
20 KiB
TypeScript
import lineColorList from "@/assets/originData/lineColorList";
|
||
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||
import { useCurrentTrain } from "@/stateBox/useCurrentTrain";
|
||
import { useStationList } from "@/stateBox/useStationList";
|
||
import { StationProps } from "@/lib/CommonTypes";
|
||
import { FC, useEffect, useState } from "react";
|
||
import {
|
||
Text,
|
||
TouchableOpacity,
|
||
View,
|
||
Image,
|
||
LayoutAnimation,
|
||
} from "react-native";
|
||
import { getTrainType } from "@/lib/getTrainType";
|
||
import { trainPosition } from "@/lib/trainPositionTextArray";
|
||
import { StationNumberMaker } from "@/components/駅名表/StationNumberMaker";
|
||
import { lineListPair, stationIDPair } from "@/lib/getStationList";
|
||
import { findReversalPoints } from "@/lib/eachTrainInfoCoreLib/findReversalPoints";
|
||
import { CustomTrainData, trainTypeID } from "@/lib/CommonTypes";
|
||
import { getCurrentTrainData } from "@/lib/getCurrentTrainData";
|
||
import { Ionicons } from "@expo/vector-icons";
|
||
|
||
type props = {
|
||
trainID: string;
|
||
displaySize: number;
|
||
setDisplaySize: (e: number) => void;
|
||
};
|
||
|
||
export const FixedTrain: FC<props> = ({
|
||
trainID,
|
||
displaySize,
|
||
setDisplaySize,
|
||
}) => {
|
||
const {
|
||
fixedPosition,
|
||
setFixedPosition,
|
||
currentTrain,
|
||
getCurrentStationData,
|
||
getPosition,
|
||
} = useCurrentTrain();
|
||
const { allCustomTrainData, allTrainDiagram } = useAllTrainDiagram();
|
||
|
||
const [train, setTrain] = useState<{
|
||
Pos?: string;
|
||
Direction?: number;
|
||
Index?: number;
|
||
Line?: string;
|
||
PosNum?: number;
|
||
Type?: string;
|
||
delay?: string | number;
|
||
num?: string;
|
||
}>(null);
|
||
const [customData, setCustomData] = useState<CustomTrainData>(
|
||
getCurrentTrainData(trainID, currentTrain, allCustomTrainData)
|
||
);
|
||
useEffect(() => {
|
||
setCustomData(
|
||
getCurrentTrainData(trainID, currentTrain, allCustomTrainData)
|
||
);
|
||
}, [currentTrain, trainID]);
|
||
useEffect(() => {
|
||
const stationData = getCurrentStationData(trainID);
|
||
if (stationData) {
|
||
setTrain(stationData);
|
||
}
|
||
}, [trainID, currentTrain]);
|
||
|
||
const { getStationDataFromName, stationList, originalStationList } =
|
||
useStationList();
|
||
|
||
const [trainDataWidhThrough, setTrainDataWithThrough] = useState<string[]>(
|
||
[]
|
||
);
|
||
|
||
useEffect(() => {
|
||
const trainData = allTrainDiagram[trainID]?.split("#");
|
||
if (!trainData) return;
|
||
//let haveThrough = false;
|
||
//
|
||
const stopStationList = trainData.map((i) => {
|
||
const [station, se, time] = i.split(",");
|
||
//if (se == "通編") setHaveThrough(true);
|
||
return stationList.map((a) => a.filter((d) => d.StationName == station));
|
||
});
|
||
const allThroughStationList = stopStationList.map((i, index, array) => {
|
||
let allThroughStation = [];
|
||
if (index == array.length - 1) return;
|
||
|
||
const firstItem = array[index];
|
||
const secondItem = array[index + 1];
|
||
let betweenStationLine = "";
|
||
let baseStationNumberFirst = "";
|
||
let baseStationNumberSecond = "";
|
||
Object.keys(stationIDPair).forEach((d, index2, array) => {
|
||
if (!d) return;
|
||
const haveFirst = firstItem[index2];
|
||
const haveSecond = secondItem[index2];
|
||
if (haveFirst.length && haveSecond.length) {
|
||
betweenStationLine = d;
|
||
baseStationNumberFirst = haveFirst[0].StationNumber;
|
||
baseStationNumberSecond = haveSecond[0].StationNumber;
|
||
}
|
||
});
|
||
if (!betweenStationLine) return;
|
||
let reverse = false;
|
||
originalStationList[
|
||
lineListPair[stationIDPair[betweenStationLine]]
|
||
].forEach((d) => {
|
||
if (
|
||
d.StationNumber > baseStationNumberFirst &&
|
||
d.StationNumber < baseStationNumberSecond
|
||
) {
|
||
allThroughStation.push(`${d.Station_JP},通過,`);
|
||
//setHaveThrough(true);
|
||
reverse = false;
|
||
} else {
|
||
if (
|
||
d.StationNumber < baseStationNumberFirst &&
|
||
d.StationNumber > baseStationNumberSecond
|
||
) {
|
||
allThroughStation.push(`${d.Station_JP},通過,`);
|
||
//setHaveThrough(true);
|
||
reverse = true;
|
||
}
|
||
}
|
||
});
|
||
if (reverse) allThroughStation.reverse();
|
||
return allThroughStation;
|
||
});
|
||
let mainArray = [...trainData];
|
||
let indexs = 0;
|
||
trainData.forEach((d, index, array) => {
|
||
indexs = indexs + 1;
|
||
if (!allThroughStationList[index]) return;
|
||
if (allThroughStationList[index].length == 0) return;
|
||
mainArray.splice(indexs, 0, ...allThroughStationList[index]);
|
||
indexs = indexs + allThroughStationList[index].length;
|
||
});
|
||
setTrainDataWithThrough(mainArray);
|
||
}, [allTrainDiagram, stationList, trainID]);
|
||
const stopStationIDList = trainDataWidhThrough.map((i) => {
|
||
const [station, se, time] = i.split(",");
|
||
const Stations = stationList.map((a) =>
|
||
a.filter((d) => d.StationName == station)
|
||
);
|
||
const StationNumbers =
|
||
Stations &&
|
||
Stations.reduce((newArray, e) => {
|
||
return newArray.concat(e);
|
||
}, []).map((d) => d.StationNumber);
|
||
return StationNumbers;
|
||
});
|
||
const [currentPosition, setCurrentPosition] = useState<string[]>([]);
|
||
|
||
useEffect(() => {
|
||
const position = getPosition(train);
|
||
if (position) setCurrentPosition(position);
|
||
}, [train]);
|
||
|
||
const [nextStationData, setNextStationData] = useState<StationProps[]>([]);
|
||
const [untilStationData, setUntilStationData] = useState<StationProps[]>([]);
|
||
useEffect(() => {
|
||
const points = findReversalPoints(currentPosition, stopStationIDList);
|
||
if (!points) return;
|
||
if (points.length == 0) return;
|
||
let searchCountBase = points.findIndex((d) => d == true);
|
||
for (
|
||
let searchCount = searchCountBase;
|
||
searchCount < points.length;
|
||
searchCount++
|
||
) {
|
||
const nextPos = trainDataWidhThrough[searchCount];
|
||
if (nextPos) {
|
||
const [station, se, time] = nextPos.split(",");
|
||
if (se.includes("通")) continue;
|
||
else {
|
||
setNextStationData(getStationDataFromName(station));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
let trainList = [];
|
||
for (
|
||
let searchCount = searchCountBase - 1;
|
||
searchCount < points.length;
|
||
searchCount++
|
||
) {
|
||
trainList.push(trainDataWidhThrough[searchCount]);
|
||
}
|
||
setUntilStationData(trainList);
|
||
}, [currentPosition, trainDataWidhThrough]);
|
||
const [ToData, setToData] = useState("");
|
||
useEffect(() => {
|
||
if (customData.ToData && customData.ToData != "") {
|
||
setToData(customData.ToData);
|
||
} else {
|
||
if (trainDataWidhThrough.length == 0) return;
|
||
setToData(
|
||
trainDataWidhThrough[trainDataWidhThrough.length - 2].split(",")[0]
|
||
);
|
||
}
|
||
}, [customData, trainDataWidhThrough]);
|
||
|
||
const [station, setStation] = useState<StationProps[]>([]);
|
||
useEffect(() => {
|
||
const data = getStationDataFromName(ToData);
|
||
setStation(data);
|
||
}, [ToData]);
|
||
const lineColor =
|
||
station.length > 0
|
||
? lineColorList[station[0]?.StationNumber.slice(0, 1)]
|
||
: "black";
|
||
//const lineColor = "red";
|
||
const customTrainType = getTrainType({
|
||
type: customData.type,
|
||
whiteMode: true,
|
||
});
|
||
return (
|
||
<TouchableOpacity
|
||
style={{
|
||
flex: 1,
|
||
flexDirection: displaySize === 50 ? "row" : "column",
|
||
backgroundColor: "black",
|
||
borderBottomColor: "black",
|
||
borderBottomWidth: 2,
|
||
position: "relative",
|
||
}}
|
||
activeOpacity={1}
|
||
onPress={() => {
|
||
//setFixedPosition({ type: null, value: null });
|
||
}}
|
||
>
|
||
<View
|
||
style={{
|
||
flexDirection: displaySize === 50 ? "column" : "row",
|
||
flex: 1,
|
||
backgroundColor: "white",
|
||
height: displaySize === 50 ? 50 : 200,
|
||
overflow: "hidden",
|
||
}}
|
||
>
|
||
<View style={{ flex: displaySize === 50 ? 1 : 5, flexDirection: "row" }}>
|
||
<View
|
||
style={{
|
||
backgroundColor: customTrainType.color,
|
||
flexDirection: "row",
|
||
alignContent: "center",
|
||
alignSelf: "center",
|
||
alignItems: "center",
|
||
height: "100%",
|
||
}}
|
||
>
|
||
<Image
|
||
source={{ uri: customData.img }}
|
||
width={14}
|
||
height={17}
|
||
style={{ margin: 5 }}
|
||
/>
|
||
<View
|
||
style={{
|
||
flexDirection: displaySize === 50 ? "row" : "column",
|
||
alignContent: "center",
|
||
alignSelf: "center",
|
||
}}
|
||
>
|
||
<Text
|
||
style={{
|
||
fontSize: 14,
|
||
fontFamily: customTrainType.fontAvailable
|
||
? "JR-Nishi"
|
||
: undefined,
|
||
fontWeight: !customTrainType.fontAvailable
|
||
? "bold"
|
||
: undefined,
|
||
marginTop: customTrainType.fontAvailable ? 3 : 0,
|
||
color: "white",
|
||
textAlignVertical: "center",
|
||
textAlign: "center",
|
||
}}
|
||
>
|
||
{customTrainType.shortName}
|
||
</Text>
|
||
{customData.trainName && (
|
||
<Text
|
||
style={{
|
||
fontSize: customData?.trainName?.length > 6 ? 9 : 14,
|
||
color: "white",
|
||
maxWidth: displaySize === 50 ? 65 : 200,
|
||
textAlignVertical: "center",
|
||
}}
|
||
>
|
||
{customData.trainName}
|
||
</Text>
|
||
)}
|
||
</View>
|
||
<View
|
||
style={{
|
||
backgroundColor: customTrainType.color,
|
||
width: 10,
|
||
borderLeftColor: customTrainType.color,
|
||
borderTopColor: lineColor,
|
||
borderBottomColor: lineColor,
|
||
borderTopWidth: displaySize === 50 ? 14 : 50,
|
||
borderBottomWidth: displaySize === 50 ? 14 : 50,
|
||
borderLeftWidth: displaySize === 50 ? 10 : 30,
|
||
borderRightWidth: 0,
|
||
//height: displaySize === 50 ? 20 : 100,
|
||
height: "100%",
|
||
}}
|
||
></View>
|
||
</View>
|
||
<View
|
||
style={{
|
||
flexDirection: "row",
|
||
alignContent: "center",
|
||
alignSelf: "center",
|
||
height: "100%",
|
||
backgroundColor: lineColor,
|
||
flex: 1,
|
||
}}
|
||
>
|
||
<View
|
||
style={{
|
||
flexDirection: "row",
|
||
alignContent: "center",
|
||
alignSelf: "center",
|
||
alignItems: "center",
|
||
}}
|
||
>
|
||
<StationNumberMaker
|
||
currentStation={station}
|
||
singleSize={20}
|
||
useEach={true}
|
||
/>
|
||
<Text
|
||
style={{
|
||
fontSize: 14,
|
||
color: "white",
|
||
fontWeight: "bold",
|
||
textAlignVertical: "center",
|
||
margin: 0,
|
||
padding: 0,
|
||
height: "100%",
|
||
}}
|
||
>
|
||
{ToData}行
|
||
</Text>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
{displaySize === 200 && (
|
||
<View
|
||
style={{
|
||
backgroundColor: "white",
|
||
width: 10,
|
||
borderLeftColor: "black",
|
||
borderTopColor: lineColor,
|
||
borderBottomColor: "white",
|
||
borderRightColor: "black",
|
||
borderTopWidth: 50,
|
||
borderBottomWidth: 0,
|
||
borderLeftWidth: 0,
|
||
borderRightWidth: 20,
|
||
}}
|
||
></View>
|
||
)}
|
||
<View
|
||
style={{
|
||
backgroundColor: "black",
|
||
flex: displaySize === 50 ? 1 : 4,
|
||
flexDirection: "row",
|
||
alignItems: "center",
|
||
}}
|
||
>
|
||
<Text
|
||
style={{
|
||
fontSize: 10,
|
||
fontWeight: "bold",
|
||
color: "white",
|
||
marginHorizontal: 5,
|
||
}}
|
||
>
|
||
{nextStationData[0]?.Station_JP == train?.Pos ? "ただいま" : "次は"}
|
||
</Text>
|
||
<StationNumberMaker
|
||
currentStation={nextStationData}
|
||
singleSize={20}
|
||
useEach={true}
|
||
/>
|
||
<Text
|
||
style={{
|
||
fontSize: 18,
|
||
fontWeight: "bold",
|
||
color: "white",
|
||
flex: 1,
|
||
}}
|
||
>
|
||
{nextStationData[0]?.Station_JP || "不明"}
|
||
</Text>
|
||
{displaySize === 50 && (
|
||
<View
|
||
style={{
|
||
backgroundColor: "white",
|
||
width: 10,
|
||
borderLeftColor: "black",
|
||
borderTopColor: "black",
|
||
borderBottomColor: "white",
|
||
borderRightColor: "white",
|
||
borderTopWidth: 21,
|
||
borderBottomWidth: 0,
|
||
borderLeftWidth: 0,
|
||
borderRightWidth: 7,
|
||
}}
|
||
></View>
|
||
)}
|
||
</View>
|
||
</View>
|
||
<CurrentPositionBox
|
||
train={train}
|
||
lineColor={lineColor}
|
||
trainDataWithThrough={untilStationData}
|
||
isSmall={displaySize === 50}
|
||
/>
|
||
<TouchableOpacity
|
||
style={{
|
||
position: "absolute",
|
||
top: "100%",
|
||
left: 0,
|
||
flexDirection: "row",
|
||
alignItems: "center",
|
||
}}
|
||
onPress={() => {
|
||
setFixedPosition({ type: null, value: null });
|
||
}}
|
||
>
|
||
<View
|
||
style={{
|
||
flexDirection: "row",
|
||
alignItems: "center",
|
||
backgroundColor: "black",
|
||
paddingHorizontal: 5,
|
||
height: 26,
|
||
}}
|
||
>
|
||
<Ionicons name="lock-closed" size={15} color="white" />
|
||
<Text
|
||
style={{
|
||
color: "white",
|
||
fontSize: 15,
|
||
paddingRight: 5,
|
||
}}
|
||
>
|
||
列車追跡中
|
||
</Text>
|
||
<Ionicons name="close" size={15} color="white" />
|
||
</View>
|
||
|
||
<View
|
||
style={{
|
||
backgroundColor: "#0000",
|
||
width: 6,
|
||
borderLeftColor: "black",
|
||
borderTopColor: "black",
|
||
borderBottomColor: "#0000",
|
||
borderRightColor: "#0000",
|
||
borderBottomWidth: 26,
|
||
borderLeftWidth: 10,
|
||
borderRightWidth: 0,
|
||
borderTopWidth: 0,
|
||
height: 26,
|
||
}}
|
||
/>
|
||
</TouchableOpacity>
|
||
<TouchableOpacity
|
||
style={{
|
||
position: "absolute",
|
||
top: "100%",
|
||
right: 0,
|
||
flexDirection: "row",
|
||
alignItems: "center",
|
||
}}
|
||
onPress={() => {
|
||
LayoutAnimation.configureNext(LayoutAnimation.Presets.linear);
|
||
if (displaySize === 50) {
|
||
setDisplaySize(200);
|
||
} else {
|
||
setDisplaySize(50);
|
||
}
|
||
}}
|
||
>
|
||
<View
|
||
style={{
|
||
backgroundColor: "#0000",
|
||
width: 6,
|
||
borderLeftColor: "#0000",
|
||
borderTopColor: "black",
|
||
borderBottomColor: "#0000",
|
||
borderRightColor: "black",
|
||
borderBottomWidth: 26,
|
||
borderLeftWidth: 0,
|
||
borderRightWidth: 10,
|
||
borderTopWidth: 0,
|
||
height: 26,
|
||
}}
|
||
/>
|
||
<View
|
||
style={{
|
||
flexDirection: "row",
|
||
alignItems: "center",
|
||
backgroundColor: "black",
|
||
paddingHorizontal: 5,
|
||
height: 26,
|
||
}}
|
||
pointerEvents="none"
|
||
>
|
||
<Ionicons
|
||
name={displaySize == 50 ? "chevron-down" : "chevron-up"}
|
||
size={15}
|
||
color="white"
|
||
/>
|
||
<Text
|
||
style={{
|
||
color: "white",
|
||
paddingRight: 5,
|
||
backgroundColor: "black",
|
||
fontSize: 15,
|
||
}}
|
||
>
|
||
{displaySize == 50 ? "列車情報展開" : "列車情報縮小"}
|
||
</Text>
|
||
</View>
|
||
</TouchableOpacity>
|
||
</TouchableOpacity>
|
||
);
|
||
};
|
||
|
||
const CurrentPositionBox = ({
|
||
train,
|
||
lineColor,
|
||
trainDataWithThrough,
|
||
isSmall,
|
||
}) => {
|
||
let firstText = "";
|
||
let secondText = "";
|
||
let marginText = "";
|
||
let externalText = "";
|
||
const { isBetween, Pos: PosData } = trainPosition(train);
|
||
if (isBetween === true) {
|
||
const { from, to } = PosData;
|
||
firstText = from;
|
||
secondText = to;
|
||
marginText = "→";
|
||
} else {
|
||
const { Pos } = PosData;
|
||
if (Pos !== "") {
|
||
firstText = Pos;
|
||
}
|
||
}
|
||
return (
|
||
<View
|
||
style={{
|
||
flex: isSmall ? 1 : 3,
|
||
backgroundColor: "white",
|
||
flexDirection: "row",
|
||
}}
|
||
>
|
||
{isSmall && (
|
||
<View style={{ flexDirection: "column" }}>
|
||
<View
|
||
style={{
|
||
backgroundColor: "white",
|
||
width: 10,
|
||
borderLeftColor: lineColor,
|
||
borderTopColor: lineColor,
|
||
borderBottomColor: "white",
|
||
borderRightColor: "white",
|
||
borderTopWidth: 28,
|
||
borderBottomWidth: 0,
|
||
borderLeftWidth: 0,
|
||
borderRightWidth: 10,
|
||
}}
|
||
></View>
|
||
<View
|
||
style={{
|
||
backgroundColor: "white",
|
||
width: 10,
|
||
borderLeftColor: "white",
|
||
borderTopColor: "white",
|
||
borderBottomColor: "white",
|
||
borderRightColor: "white",
|
||
borderTopWidth: 18,
|
||
borderBottomWidth: 0,
|
||
borderLeftWidth: 0,
|
||
borderRightWidth: 10,
|
||
}}
|
||
></View>
|
||
</View>
|
||
)}
|
||
<View style={{ flex: 1, flexDirection: "row", overflow: "hidden" }}>
|
||
{trainDataWithThrough.length > 0 &&
|
||
trainDataWithThrough.map((d, index, array) => {
|
||
if (!d) return null;
|
||
if (d == "") return null;
|
||
const [station, se, time] = d.split(",");
|
||
return (
|
||
<>
|
||
{(index == 0 && secondText == "") || (
|
||
<View
|
||
style={{
|
||
flexDirection: "column",
|
||
backgroundColor: "#6e6e6eff",
|
||
borderRadius: 10,
|
||
marginHorizontal: isSmall ? 2 : 4,
|
||
marginVertical: isSmall ? 0 : 2,
|
||
padding: isSmall ? 2 : 4,
|
||
justifyContent: "center",
|
||
alignItems: "center",
|
||
overflow: "hidden",
|
||
}}
|
||
key={d + "CurrentPositionBox"}
|
||
>
|
||
{station.split("").map((i, index) => {
|
||
return (
|
||
<Text
|
||
key={i + index}
|
||
style={{
|
||
fontSize: isSmall ? 6 : 14,
|
||
color: "white",
|
||
margin: 0,
|
||
padding: 0,
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
{i}
|
||
</Text>
|
||
);
|
||
})}
|
||
<View style={{ flex: 1 }} />
|
||
<Text
|
||
style={{ fontSize: isSmall ? 8 : 14, color: "white" }}
|
||
>
|
||
{se.includes("通") ? "" : "●"}
|
||
</Text>
|
||
</View>
|
||
)}
|
||
{index == 0 && secondText != "" && (
|
||
<View
|
||
style={{
|
||
flexDirection: "column",
|
||
backgroundColor: "#6e6e6e0e",
|
||
borderRadius: 10,
|
||
marginHorizontal: 2,
|
||
padding: 2,
|
||
justifyContent: "center",
|
||
alignItems: "center",
|
||
overflow: "hidden",
|
||
}}
|
||
>
|
||
<View style={{ flex: 1 }} />
|
||
<Text
|
||
style={{ fontSize: isSmall ? 8 : 14, color: "black" }}
|
||
>
|
||
>
|
||
</Text>
|
||
</View>
|
||
)}
|
||
</>
|
||
);
|
||
})}
|
||
</View>
|
||
</View>
|
||
);
|
||
};
|