Files
jrshikoku/components/Apps/FixedPositionBox/FixedTrainBox.tsx
harukin-expo-dev-env 50b2cbb21c path修正
2025-09-12 19:05:18 +00:00

484 lines
15 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 } 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";
type props = {
trainID: string;
};
export const FixedTrain: FC<props> = ({ trainID }) => {
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([]);
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 customTrainType = getTrainType({ type: customData.type, whiteMode: true });
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: customTrainType.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: 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: 65,
textAlignVertical: "center",
}}
>
{customData.trainName}
</Text>
)}
</View>
<View
style={{
backgroundColor: customTrainType.color,
width: 10,
borderLeftColor: customTrainType.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>
);
};