355 lines
11 KiB
TypeScript
355 lines
11 KiB
TypeScript
import lineColorList from "@/assets/originData/lineColorList";
|
||
import { customTrainDataDetector } from "@/components/custom-train-data";
|
||
import { StationNumberMaker } from "@/components/駅名表/StationNumberMaker";
|
||
import { checkDuplicateTrainData } from "@/lib/checkDuplicateTrainData";
|
||
import { typeID } from "@/lib/getStringConfig";
|
||
import { getTrainDelayStatus } from "@/lib/getTrainDelayStatus";
|
||
import { getTrainType } from "@/lib/getTrainType";
|
||
import { objectIsEmpty } from "@/lib/objectIsEmpty";
|
||
import { trainPosition } from "@/lib/trainPositionTextArray";
|
||
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||
import { useAreaInfo } from "@/stateBox/useAreaInfo";
|
||
import { useCurrentTrain } from "@/stateBox/useCurrentTrain";
|
||
import { useStationList, StationProps } from "@/stateBox/useStationList";
|
||
import dayjs from "dayjs";
|
||
import { useEffect, useState } from "react";
|
||
import { Text, TouchableOpacity, View } from "react-native";
|
||
|
||
export const FixedStation = ({ stationID }) => {
|
||
const { fixedPosition, setFixedPosition } = useCurrentTrain();
|
||
const { getStationDataFromId } = useStationList();
|
||
const [station, setStation] = useState<StationProps[]>([]);
|
||
useEffect(() => {
|
||
const data = getStationDataFromId(stationID);
|
||
setStation(data);
|
||
}, [stationID]);
|
||
const lineColor =
|
||
station.length > 0
|
||
? lineColorList[station[0]?.StationNumber.slice(0, 1)]
|
||
: "white";
|
||
////
|
||
|
||
const timeFiltering = (d) => {
|
||
const baseTime = 2;
|
||
if (currentTrain.filter((t) => t.num == d.train).length == 0) {
|
||
const date = dayjs();
|
||
const trainTime = date
|
||
.hour(parseInt(d.time.split(":")[0]))
|
||
.minute(parseInt(d.time.split(":")[1]));
|
||
|
||
if (date.isAfter(trainTime)) {
|
||
return false;
|
||
} else if (trainTime.diff(date) < baseTime * 60 * 60 * 1000) {
|
||
return true;
|
||
}
|
||
return false;
|
||
} else {
|
||
const Pos = trainPosition(
|
||
currentTrain.filter((t) => t.num == d.train)[0]
|
||
);
|
||
const nextPos = Pos.isBetween ? Pos.Pos.to : Pos.Pos.Pos;
|
||
const PrePos = Pos.isBetween ? Pos.Pos.from : "";
|
||
if (station[0].Station_JP == nextPos) {
|
||
if (d.lastStation != station[0].Station_JP) return true;
|
||
} else if (station[0].Station_JP == PrePos) {
|
||
return false;
|
||
}
|
||
let [h, m] = d.time.split(":");
|
||
let delay = isNaN(currentTrain.filter((t) => t.num == d.train)[0].delay)
|
||
? 0
|
||
: currentTrain.filter((t) => t.num == d.train)[0].delay;
|
||
const date = dayjs();
|
||
let targetHour = parseInt(h);
|
||
|
||
// 4時を日付変更線として処理
|
||
if (targetHour < 4) {
|
||
targetHour += 24;
|
||
}
|
||
|
||
let currentHour = date.hour();
|
||
if (currentHour < 4) {
|
||
currentHour += 24;
|
||
}
|
||
|
||
const db = dayjs()
|
||
.hour(targetHour)
|
||
.minute(parseInt(m) + parseInt(delay));
|
||
const currentTime = dayjs().hour(currentHour);
|
||
|
||
return !currentTime.isAfter(db);
|
||
}
|
||
};
|
||
type trainDataProps = {
|
||
train?: string;
|
||
lastStation?: string;
|
||
time?: string;
|
||
isThrough?: boolean;
|
||
};
|
||
const getTime = (stationDiagram, station) => {
|
||
const returnData = Object.keys(stationDiagram)
|
||
.map((trainNum) => {
|
||
let trainData: trainDataProps = {};
|
||
stationDiagram[trainNum].split("#").forEach((data) => {
|
||
if (data.match("着")) {
|
||
trainData.lastStation = data.split(",着,")[0];
|
||
}
|
||
if (data.match("着編")) {
|
||
trainData.lastStation = data.split(",着編,")[0];
|
||
}
|
||
if (data.split(",")[0] === station.Station_JP) {
|
||
if (data.match(",発,")) {
|
||
trainData.time = data.split(",発,")[1];
|
||
} else if (data.match(",発編,")) {
|
||
trainData.time = data.split(",発編,")[1];
|
||
} else if (data.match(",通編,")) {
|
||
trainData.time = data.split(",通編,")[1];
|
||
trainData.isThrough = true;
|
||
} else if (data.match(",着,")) {
|
||
trainData.time = data.split(",着,")[1];
|
||
} else if (data.match(",着編,")) {
|
||
trainData.time = data.split(",着編,")[1];
|
||
}
|
||
}
|
||
});
|
||
return {
|
||
train: trainNum,
|
||
time: trainData.time,
|
||
lastStation: trainData.lastStation,
|
||
isThrough: trainData.isThrough,
|
||
};
|
||
})
|
||
.filter((d) => d.time);
|
||
return returnData.sort((a, b) => {
|
||
switch (true) {
|
||
case parseInt(a.time.split(":")[0]) < parseInt(b.time.split(":")[0]):
|
||
return -1;
|
||
case parseInt(a.time.split(":")[0]) > parseInt(b.time.split(":")[0]):
|
||
return 1;
|
||
case parseInt(a.time.split(":")[1]) < parseInt(b.time.split(":")[1]):
|
||
return -1;
|
||
case parseInt(a.time.split(":")[1]) > parseInt(b.time.split(":")[1]):
|
||
return 1;
|
||
default:
|
||
return 0;
|
||
}
|
||
});
|
||
};
|
||
|
||
const { allTrainDiagram } = useAllTrainDiagram();
|
||
const { areaInfo, areaStationID } = useAreaInfo();
|
||
const [stationDiagram, setStationDiagram] = useState({}); //当該駅の全時刻表
|
||
const [isInfoArea, setIsInfoArea] = useState(false);
|
||
const { currentTrain } = useCurrentTrain();
|
||
|
||
useEffect(() => {
|
||
// 現在の駅に停車するダイヤを作成する副作用[列車ダイヤと現在駅情報]
|
||
if (!allTrainDiagram) {
|
||
setStationDiagram({});
|
||
return;
|
||
}
|
||
if (station.length == 0) {
|
||
setStationDiagram({});
|
||
return;
|
||
}
|
||
let returnData = {};
|
||
Object.keys(allTrainDiagram).forEach((key) => {
|
||
if (allTrainDiagram[key].match(station[0].Station_JP + ",")) {
|
||
returnData[key] = allTrainDiagram[key];
|
||
}
|
||
});
|
||
setStationDiagram(returnData);
|
||
setIsInfoArea(station.some((s) => areaStationID.includes(s.StationNumber)));
|
||
}, [allTrainDiagram, station]);
|
||
|
||
const [trainTimeAndNumber, setTrainTimeAndNumber] = useState([]);
|
||
|
||
useEffect(() => {
|
||
//現在の駅に停車する列車から時刻を切り出してLEDベースにフォーマット
|
||
if (objectIsEmpty(stationDiagram)) return () => {};
|
||
const getTimeData = getTime(stationDiagram, station[0]);
|
||
setTrainTimeAndNumber(getTimeData);
|
||
}, [stationDiagram]);
|
||
const [selectedTrain, setSelectedTrain] = useState<
|
||
{
|
||
isThrough?: boolean;
|
||
train?: string;
|
||
lastStation?: string;
|
||
time?: string;
|
||
}[]
|
||
>([]);
|
||
useEffect(() => {
|
||
if (!trainTimeAndNumber) return () => {};
|
||
if (!currentTrain) return () => {};
|
||
const data = trainTimeAndNumber
|
||
.filter((d) => currentTrain.map((m) => m.num).includes(d.train)) //現在の列車に絞る[ToDo]
|
||
.filter(timeFiltering).filter(d=>!d.isThrough)
|
||
.filter((d) => d.lastStation != station[0].Station_JP) //最終列車表示設定
|
||
setSelectedTrain(data);
|
||
}, [trainTimeAndNumber, currentTrain /*finalSwitch*/]);
|
||
|
||
return (
|
||
<TouchableOpacity
|
||
style={{ flex: 1, flexDirection: "row" }}
|
||
onPress={() => {
|
||
setFixedPosition({ type: null, value: null });
|
||
}}
|
||
>
|
||
<View
|
||
style={{
|
||
flex: 3,
|
||
flexDirection: "column",
|
||
alignContent: "center",
|
||
alignSelf: "center",
|
||
alignItems: "center",
|
||
height: "100%",
|
||
backgroundColor: "white",
|
||
}}
|
||
>
|
||
<View
|
||
style={{
|
||
backgroundColor: lineColor,
|
||
flexDirection: "row",
|
||
width: "100%",
|
||
alignContent: "center",
|
||
alignItems: "center",
|
||
}}
|
||
>
|
||
<StationNumberMaker
|
||
currentStation={station}
|
||
singleSize={18}
|
||
useEach={true}
|
||
/>
|
||
<Text
|
||
style={{
|
||
fontSize: 18,
|
||
textAlignVertical: "center",
|
||
margin: 0,
|
||
padding: 0,
|
||
flex: 1,
|
||
color:"white"
|
||
}}
|
||
>
|
||
{station[0]?.Station_JP}
|
||
</Text>
|
||
<View
|
||
style={{
|
||
backgroundColor: "white",
|
||
width: 10,
|
||
borderLeftColor: lineColor,
|
||
borderTopColor: lineColor,
|
||
borderBottomColor: "white",
|
||
borderBottomWidth: 16,
|
||
borderLeftWidth: 8,
|
||
borderRightWidth: 0,
|
||
borderTopWidth: 5,
|
||
height: "100%",
|
||
}}
|
||
/>
|
||
</View>
|
||
<View
|
||
style={{
|
||
height: "100%",
|
||
backgroundColor: "white",
|
||
flex: 1,
|
||
}}
|
||
>
|
||
<Text style={{ fontSize: 20 }}>次の発車予定:</Text>
|
||
</View>
|
||
</View>
|
||
|
||
<View
|
||
style={{
|
||
flex: 5,
|
||
flexDirection: "column",
|
||
backgroundColor: "white",
|
||
borderTopWidth: 5,
|
||
borderTopColor: lineColor,
|
||
overflow: "hidden",
|
||
}}
|
||
>
|
||
{selectedTrain.length > 0 ? (
|
||
selectedTrain.map((d) => (
|
||
<FixedStationBoxEachTrain
|
||
d={d}
|
||
station={station[0]}
|
||
key={d.train + "-fixedStationBox"}
|
||
/>
|
||
))
|
||
) : (
|
||
<View style={{ backgroundColor: "white", flex: 1 }}>
|
||
<Text style={{ fontSize: 20 }}>
|
||
当駅を発着する走行中の列車はありません。
|
||
</Text>
|
||
</View>
|
||
)}
|
||
</View>
|
||
</TouchableOpacity>
|
||
);
|
||
};
|
||
|
||
const FixedStationBoxEachTrain = ({ d, station }) => {
|
||
const { currentTrain } = useCurrentTrain();
|
||
const { stationList } = useStationList();
|
||
const { allCustomTrainData } = useAllTrainDiagram();
|
||
const currentTrainData = checkDuplicateTrainData(
|
||
currentTrain.filter((a) => a.num == d.train),
|
||
stationList
|
||
);
|
||
|
||
const trainDelayStatus = `${getTrainDelayStatus(
|
||
currentTrainData,
|
||
station.Station_JP
|
||
)}`;
|
||
const getTrainDataFromCurrentTrain = (trainNum: string) => {
|
||
const customTrainData = customTrainDataDetector(
|
||
d.train,
|
||
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<{
|
||
ToData: string;
|
||
TrainNumber: string;
|
||
id: string;
|
||
img: string;
|
||
isWanman: boolean;
|
||
trainName: string;
|
||
trainNumDistance: number;
|
||
type: typeID;
|
||
viaData: string;
|
||
info?: string;
|
||
uwasa?: string;
|
||
}>(getTrainDataFromCurrentTrain(d.train));
|
||
useEffect(() => {
|
||
setTrain(getTrainDataFromCurrentTrain(d.train));
|
||
}, [currentTrain, d.train]);
|
||
const { name, color } = getTrainType(train.type, true);
|
||
return (
|
||
<View style={{ backgroundColor: "white", flexDirection: "row",height:"33%",overflow:"visible" }}>
|
||
<Text style={{ fontSize: 14, flex: 3 }}>{d.time}</Text>
|
||
<Text style={{ fontSize: 14, flex: 4, color }}>{name}</Text>
|
||
<Text style={{ fontSize: 14, flex: 4 }}>{d.lastStation}行</Text>
|
||
<Text style={{ fontSize: 14, flex: 3 }}>{trainDelayStatus}</Text>
|
||
</View>
|
||
);
|
||
};
|