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, ScrollView, } from "react-native"; import { getTrainType } from "@/lib/getTrainType"; import { trainDataType, 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"; import dayjs from "dayjs"; import { useTrainMenu } from "@/stateBox/useTrainMenu"; type props = { trainID: string; displaySize: number; setDisplaySize: (e: number) => void; }; export const FixedTrain: FC = ({ trainID, displaySize, setDisplaySize, }) => { const {fixedPosition, setFixedPosition, currentTrain, getCurrentStationData, getPosition } = useCurrentTrain(); const { mapSwitch } = useTrainMenu(); const { allCustomTrainData, allTrainDiagram } = useAllTrainDiagram(); const [train, setTrain] = useState(null); const [customData, setCustomData] = useState( getCurrentTrainData(trainID, currentTrain, allCustomTrainData) ); useEffect(() => { setCustomData( getCurrentTrainData(trainID, currentTrain, allCustomTrainData) ); }, [currentTrain, trainID]); useEffect(() => { const stationData = getCurrentStationData(trainID); if (stationData) { setTrain(stationData); } else{ alert("追跡していた列車が消えました。追跡を終了します。"); setFixedPosition({ type: null, value: null }); } }, [trainID, currentTrain]); const { getStationDataFromName, stationList, originalStationList } = useStationList(); const [trainDataWidhThrough, setTrainDataWithThrough] = useState( [] ); 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) => { 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) => { 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(() => { let position = getPosition(train); if (position) { if (position.length > 1) { if (position[0] == "-Iyo") { position[0] = stopStationIDList[ stopStationIDList.findIndex((d) => d.includes("U14")) - 1 ][0]; } else if (position[0] == "+Iyo") { position[0] = stopStationIDList[ stopStationIDList.findIndex((d) => d.includes("U14")) + 1 ][0]; } if (position[1] == "+Iyo") { position[1] = stopStationIDList[ stopStationIDList.findIndex((d) => d.includes("U14")) + 1 ][0]; } else if (position[1] == "-Iyo") { position[1] = stopStationIDList[ stopStationIDList.findIndex((d) => d.includes("U14")) - 1 ][0]; } } setCurrentPosition(position); } }, [train]); const [nextStationData, setNextStationData] = useState([]); const [untilStationData, setUntilStationData] = useState([]); const [probably, setProbably] = useState(false); useEffect(() => { //棒線駅判定を入れて、棒線駅なら時間を見て分数がマイナスならcontinue; const points = findReversalPoints(currentPosition, stopStationIDList); if (!points) return; if (points.length == 0) return; let searchCountFirst = points.findIndex((d) => d == true); let searchCountLast = points.findLastIndex((d) => d == true); const delayTime = train?.delay == "入線" ? 0 : train?.delay; let additionalSkipCount = 0; for ( let searchCount = searchCountFirst; searchCount < points.length; searchCount++ ) { const nextPos = trainDataWidhThrough[searchCount]; if (nextPos) { const [station, se, time] = nextPos.split(","); if (searchCountFirst == searchCountLast) { if (se.includes("通")) { continue; } setNextStationData(getStationDataFromName(station)); break; } //棒線駅判定 let distanceMinute = 0; if (time != "") { const now = dayjs(); const hour = parseInt(time.split(":")[0]); const distanceTime = now .hour(hour < 4 ? hour + 24 : hour) .minute(parseInt(time.split(":")[1])); distanceMinute = distanceTime.diff(now, "minute") + delayTime; if (now.hour() < 4) { if (hour < 4) { distanceMinute = distanceMinute - 1440; } } } if (distanceMinute >= 0) { if (se.includes("通")) { continue; } else { setNextStationData(getStationDataFromName(station)); break; } } else { additionalSkipCount++; continue; } } } let trainList = []; for ( let searchCount = searchCountFirst - 1; searchCount < points.length; searchCount++ ) { trainList.push(trainDataWidhThrough[searchCount]); } if (additionalSkipCount > 0) { trainList = trainList.slice(additionalSkipCount); setProbably(true); } else { setProbably(false); } 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([]); 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, }); const trainNameText = `${customData.trainName}${ customData.trainNumDistance !== null ? ` ${parseInt(customData.TrainNumber) - customData.trainNumDistance}号` : "" }`; return ( 4 ? 12 : 14, fontFamily: customTrainType.fontAvailable ? "JR-Nishi" : undefined, fontWeight: !customTrainType.fontAvailable ? "bold" : undefined, marginTop: customTrainType.fontAvailable ? 3 : 0, color: "white", textAlignVertical: "center", textAlign: "left", }} > {customTrainType.shortName} {customData.trainName && ( 4 ? 8 : 14, color: "white", maxWidth: displaySize === 226 ? 200 : 60, textAlignVertical: "center", }} > {trainNameText} )} 4 ? 9 : 12, color: "white", fontWeight: "bold", textAlignVertical: "center", margin: 0, padding: 0, height: "100%", }} > {ToData}行 {displaySize === 226 && ( )} {nextStationData[0]?.Station_JP == train?.Pos ? "ただいま" : "次は"} {probably && ( (時刻推定) )} {nextStationData[0]?.Station_JP || "不明"} {displaySize !== 226 && ( )} { setFixedPosition({ type: null, value: null }); }} > 列車追跡中 { LayoutAnimation.configureNext({ duration: 200, update: { type: "easeInEaseOut", springDamping: 0.4 }, }); if (displaySize === 226) { setDisplaySize(mapSwitch == "true" ? 76 : 80); } else { setDisplaySize(226); } }} > {displaySize == 226 ? "列車情報縮小" : "列車情報展開"} ); }; const CurrentPositionBox = ({ train, lineColor, trainDataWithThrough, isSmall, }) => { let firstText = ""; let secondText = ""; let marginText = ""; 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; } } const delayTime = train?.delay == "入線" ? 0 : parseInt(train?.delay); return ( {isSmall && ( )} {trainDataWithThrough.length > 0 && trainDataWithThrough.map((d, index) => ( ))} ); }; type eachStopType = { d: string; delayTime: number; isSmall: boolean; index: number; secondText: string; }; const EachStopData: FC = (props) => { const { d, delayTime, isSmall, index, secondText } = props; if (!d) return null; if (d == "") return null; const [station, se, time] = d.split(","); let distanceMinute = 0; if (time != "") { const now = dayjs(); const hour = parseInt(time.split(":")[0]); const distanceTime = now .hour(hour < 4 ? hour + 24 : hour) .minute(parseInt(time.split(":")[1])); distanceMinute = distanceTime.diff(now, "minute") + delayTime; if (now.hour() < 4) { if (hour < 4) { distanceMinute = distanceMinute - 1440; } } } return ( <> {station.split("").map((i, index, array) => { return ( {i} ); })} {isSmall || (time != "" && ( {distanceMinute} ))} {index == 1 && secondText == "" ? "→" : se.includes("通") ? null : "●"} {index == 0 && secondText != "" && ( )} ); };