525 lines
16 KiB
TypeScript
525 lines
16 KiB
TypeScript
import lineColorList from "@/assets/originData/lineColorList";
|
||
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||
import { useCurrentTrain } from "@/stateBox/useCurrentTrain";
|
||
import { useStationList, StationProps } from "@/stateBox/useStationList";
|
||
import { FC, useEffect, useState } from "react";
|
||
import { Text, TouchableOpacity, View, Image } from "react-native";
|
||
import { customTrainDataDetector } from "../../custom-train-data";
|
||
import { getStringConfig, typeID } from "@/lib/getStringConfig";
|
||
import { getTrainType } from "@/lib/getTrainType";
|
||
import { trainPosition } from "@/lib/trainPositionTextArray";
|
||
import { StationNumberMaker } from "../../駅名表/StationNumberMaker";
|
||
import { lineListPair, stationIDPair } from "@/lib/getStationList";
|
||
import { findReversalPoints } from "@/lib/eachTrainInfoCoreLib/findReversalPoints";
|
||
|
||
type props = {
|
||
trainID: string;
|
||
};
|
||
|
||
export const FixedTrain: FC<props> = ({ trainID }) => {
|
||
const {
|
||
fixedPosition,
|
||
setFixedPosition,
|
||
currentTrain,
|
||
getCurrentStationData,
|
||
getPosition,
|
||
} = useCurrentTrain();
|
||
const { allCustomTrainData, allTrainDiagram } = useAllTrainDiagram();
|
||
|
||
const getTrainDataFromCurrentTrain = (trainNum: string) => {
|
||
const customTrainData = customTrainDataDetector(
|
||
trainNum,
|
||
allCustomTrainData
|
||
);
|
||
switch (customTrainData.type) {
|
||
case "Normal":
|
||
case "OneMan":
|
||
const currentTrainData = currentTrain.filter((a) => a.num == trainNum);
|
||
if (currentTrainData.length == 0) return customTrainData;
|
||
else if (currentTrainData[0].Type.includes("rapid:")) {
|
||
const typeText = currentTrainData[0].Type.split(":");
|
||
const returnData = {
|
||
type: "Rapid",
|
||
trainName: typeText[1].replace("\r", ""),
|
||
trainIcon: null,
|
||
trainNumDistance: null,
|
||
info: "",
|
||
};
|
||
return returnData;
|
||
}
|
||
return customTrainData;
|
||
default:
|
||
return customTrainData;
|
||
}
|
||
};
|
||
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<{
|
||
ToData: string;
|
||
TrainNumber: string;
|
||
id: string;
|
||
img: string;
|
||
isWanman: boolean;
|
||
trainName: string;
|
||
trainNumDistance: number;
|
||
type: typeID;
|
||
viaData: string;
|
||
info?: string;
|
||
uwasa?: string;
|
||
}>(getTrainDataFromCurrentTrain(trainID));
|
||
useEffect(() => {
|
||
setCustomData(getTrainDataFromCurrentTrain(trainID));
|
||
}, [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([]);
|
||
|
||
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 [stringConfig, setStringConfig] = useState([, ,]);
|
||
useEffect(() => {
|
||
const x = getStringConfig(customData.type, customData.TrainNumber);
|
||
setStringConfig(x);
|
||
}, [customData]);
|
||
|
||
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";
|
||
return (
|
||
<TouchableOpacity
|
||
style={{ flex: 1, flexDirection: "row", backgroundColor: "black" }}
|
||
onPress={() => {
|
||
setFixedPosition({ type: null, value: null });
|
||
}}
|
||
>
|
||
<View
|
||
style={{ flexDirection: "column", flex: 1, backgroundColor: "white" }}
|
||
>
|
||
<View style={{ flex: 1, flexDirection: "row" }}>
|
||
<View
|
||
style={{
|
||
backgroundColor: getTrainType(customData.type, true).color,
|
||
flexDirection: "row",
|
||
alignContent: "center",
|
||
alignSelf: "center",
|
||
height: "100%",
|
||
}}
|
||
>
|
||
<Image
|
||
source={{ uri: customData.img }}
|
||
width={14}
|
||
height={17}
|
||
style={{ margin: 5 }}
|
||
/>
|
||
<View
|
||
style={{
|
||
flexDirection: "row",
|
||
alignContent: "center",
|
||
alignSelf: "center",
|
||
}}
|
||
>
|
||
<Text
|
||
style={{
|
||
fontSize: 14,
|
||
fontFamily: stringConfig[1] ? "JR-Nishi" : undefined,
|
||
fontWeight: !stringConfig[1] ? "bold" : undefined,
|
||
marginTop: stringConfig[1] ? 3 : 0,
|
||
color: "white",
|
||
textAlignVertical: "center",
|
||
textAlign: "center",
|
||
}}
|
||
>
|
||
{stringConfig[0]}
|
||
</Text>
|
||
{customData.trainName && (
|
||
<Text
|
||
style={{
|
||
fontSize: customData?.trainName?.length > 6 ? 9 : 14,
|
||
color: "white",
|
||
maxWidth: 65,
|
||
textAlignVertical: "center",
|
||
}}
|
||
>
|
||
{customData.trainName}
|
||
</Text>
|
||
)}
|
||
</View>
|
||
<View
|
||
style={{
|
||
backgroundColor: getTrainType(customData.type, true).color,
|
||
width: 10,
|
||
borderLeftColor: getTrainType(customData.type, true).color,
|
||
borderTopColor: lineColor,
|
||
borderBottomColor: lineColor,
|
||
borderTopWidth: 14,
|
||
borderBottomWidth: 14,
|
||
borderLeftWidth: 10,
|
||
borderRightWidth: 0,
|
||
}}
|
||
></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>
|
||
|
||
<View
|
||
style={{
|
||
backgroundColor: "black",
|
||
flex: 1,
|
||
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>
|
||
<View
|
||
style={{
|
||
backgroundColor: "white",
|
||
width: 10,
|
||
borderLeftColor: "black",
|
||
borderTopColor: "black",
|
||
borderBottomColor: "white",
|
||
borderRightColor: "white",
|
||
borderTopWidth: 25,
|
||
borderBottomWidth: 0,
|
||
borderLeftWidth: 0,
|
||
borderRightWidth: 10,
|
||
}}
|
||
></View>
|
||
</View>
|
||
</View>
|
||
<CurrentPositionBox
|
||
train={train}
|
||
lineColor={lineColor}
|
||
trainDataWithThrough={untilStationData}
|
||
/>
|
||
</TouchableOpacity>
|
||
);
|
||
};
|
||
|
||
const CurrentPositionBox = ({ train, lineColor, trainDataWithThrough }) => {
|
||
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: 1, backgroundColor: "white", flexDirection: "row" }}>
|
||
<View style={{ flexDirection: "column", height: "100%" }}>
|
||
<View
|
||
style={{
|
||
backgroundColor: "white",
|
||
width: 10,
|
||
borderLeftColor: lineColor,
|
||
borderTopColor: lineColor,
|
||
borderBottomColor: "white",
|
||
borderRightColor: "white",
|
||
borderTopWidth: 25,
|
||
borderBottomWidth: 0,
|
||
borderLeftWidth: 0,
|
||
borderRightWidth: 10,
|
||
flex: 1,
|
||
}}
|
||
></View>
|
||
<View
|
||
style={{
|
||
backgroundColor: "white",
|
||
width: 10,
|
||
borderLeftColor: "white",
|
||
borderTopColor: "white",
|
||
borderBottomColor: "white",
|
||
borderRightColor: "white",
|
||
borderTopWidth: 25,
|
||
borderBottomWidth: 0,
|
||
borderLeftWidth: 0,
|
||
borderRightWidth: 10,
|
||
flex: 1,
|
||
}}
|
||
></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: 2,
|
||
padding: 2,
|
||
justifyContent: "center",
|
||
alignItems: "center",
|
||
overflow: "hidden",
|
||
}}
|
||
>
|
||
{station.split("").map((i, index) => {
|
||
return (
|
||
<Text
|
||
key={index}
|
||
style={{
|
||
fontSize: 6,
|
||
color: "white",
|
||
margin: 0,
|
||
padding: 0,
|
||
fontWeight: "bold",
|
||
}}
|
||
>
|
||
{i}
|
||
</Text>
|
||
);
|
||
})}
|
||
<View style={{ flex: 1 }} />
|
||
<Text style={{ fontSize: 8, 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: 8, color: "black" }}>></Text>
|
||
</View>
|
||
)}
|
||
</>
|
||
);
|
||
})}
|
||
</View>
|
||
</View>
|
||
);
|
||
};
|