Files
jrshikoku/components/発車時刻表/LED_vidion.js
harukin-expo-dev-env 0fdd71db73 差分調整a
2024-09-02 15:19:22 +00:00

424 lines
12 KiB
JavaScript
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 React, { useState, useEffect } from "react";
import { View, Text, TouchableOpacity } from "react-native";
import { widthPercentageToDP as wp } from "react-native-responsive-screen";
import { customTrainDataDetector } from "../custom-train-data";
import { useInterval } from "../../lib/useInterval";
import { objectIsEmpty } from "../../lib/objectIsEmpty";
import { getTrainType } from "../../lib/getTrainType";
import { getTrainDelayStatus } from "../../lib/getTrainDelayStatus";
import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData";
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
import { useAreaInfo } from "../../stateBox/useAreaInfo";
import { SheetManager } from "react-native-actions-sheet";
import { AS } from "../../storageControl";
import { Footer } from "./LED_Vision_Component/Footer";
import { Header } from "./LED_Vision_Component/Header";
/**
*
* 1-30M しおかぜ
* 31-58D 南風
* 1001-1030M いしづち(併結)
* 1041-1046M いしづち(単独)
* 1051-1082D 宇和海
* 1091M MX松山
* 1092M MX高松
* 2001-2010D しまんと
* 2071-2086D あしずり
* 3001-3033D うずしお
* 3101-3177M マリンライナー
* 4001-4011D 剣山
* 5006,13,22,29 うずしお(岡山直通南風併結)
* 5831-5843D 土佐くろしお鉄道ごめん・なはり線直通快速
* 5853-5892D 土佐くろしお鉄道ごめん・なはり線直通普通
* 8011,8012D 四国まんなか千年ものがたり
* 8031,(8041) サンライズ瀬戸, 琴平(延長)
* 8053,8054D トキの夜明けのものがたり
* 8176,8179D アンパントロッコタカマツ
* 8277,8278D アンパントロッココトヒラ
* 8451,8452D よしの川トロッコ
* 8814,8819D しまんトロッコ
* 8911-8914D 伊予灘ものがたり
* 9001-9030* いしづち(リレー)
* 9031M サンライズ瀬戸琴平(延長)(臨時?)
* 9062D 四国まんなか千年ものがたり(臨時?)
*/
export default function LED_vision(props) {
const {
station,
trainDiagram,
getCurrentTrain,
navigate,
openStationACFromEachTrainInfo,
} = props;
const { currentTrain } = useCurrentTrain();
const [stationDiagram, setStationDiagram] = useState({}); //当該駅の全時刻表
const [finalSwitch, setFinalSwitch] = useState(false);
const [trainIDSwitch, setTrainIDSwitch] = useState(false);
const [trainDescriptionSwitch, setTrainDescriptionSwitch] = useState(false);
const [isInfoArea, setIsInfoArea] = useState(false);
const { areaInfo, areaStationID } = useAreaInfo();
useEffect(() => {
AS.getItem("LEDSettings/trainIDSwitch").then((data) => {
setTrainIDSwitch(data === "true");
});
AS.getItem("LEDSettings/trainDescriptionSwitch").then((data) => {
setTrainDescriptionSwitch(data == "true");
});
AS.getItem("LEDSettings/finalSwitch").then((data) => {
setFinalSwitch(data == "true");
});
}, []);
useEffect(() => {
// 現在の駅に停車するダイヤを作成する副作用[列車ダイヤと現在駅情報]
if (!trainDiagram) {
setStationDiagram({});
return;
}
let returnData = {};
Object.keys(trainDiagram).forEach((key) => {
if (trainDiagram[key].match(station[0].Station_JP + ",")) {
returnData[key] = trainDiagram[key];
}
});
setStationDiagram(returnData);
setIsInfoArea(station.some((s) => areaStationID.includes(s.StationNumber)));
}, [trainDiagram, station]);
const [trainTimeAndNumber, setTrainTimeAndNumber] = useState(null);
useEffect(() => {
//現在の駅に停車する列車から時刻を切り出してLEDベースにフォーマット
if (objectIsEmpty(stationDiagram)) return () => {};
const getTimeData = getTime(stationDiagram, station[0]);
setTrainTimeAndNumber(getTimeData);
}, [stationDiagram]);
const [selectedTrain, setSelectedTrain] = useState([]);
useEffect(() => {
if (!trainTimeAndNumber) return () => {};
if (!currentTrain) return () => {};
const data = trainTimeAndNumber
.filter((d) => currentTrain.map((m) => m.num).includes(d.train))
.filter(timeFiltering)
.filter((d) => !!finalSwitch || d.lastStation != "当駅止");
setSelectedTrain(data);
}, [trainTimeAndNumber, currentTrain, finalSwitch]);
const getTime = (stationDiagram, station) => {
const returnData = Object.keys(stationDiagram).map((trainNum) => {
let trainData = {};
stationDiagram[trainNum].split("#").forEach((data) => {
if (data.match("着")) {
trainData.lastStation = data.split(",着,")[0];
}
if (data.split(",")[0] === station.Station_JP) {
if (data.match(",発,")) {
trainData.time = data.split(",発,")[1];
} else {
trainData.time = data.split(",着,")[1];
trainData.lastStation = "当駅止";
}
}
});
return {
train: trainNum,
time: trainData.time,
lastStation: trainData.lastStation,
};
});
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;
}
});
};
const timeFiltering = (d) => {
const date = new Date();
const newDate = new Date();
let data = 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;
date.setHours(parseInt(data[0]));
date.setMinutes(parseInt(data[1]) + parseInt(delay));
return !(newDate > date);
};
const [areaString, setAreaString] = useState("");
const [areaStringLength, setAreaStringLength] = useState(0);
const [move, setMove] = useState(0);
useInterval(
() => {
if (areaInfo != "") {
setMove(areaStringLength < move ? 0 : move + 1);
}
},
350,
true
);
useEffect(() => {
if (!areaInfo) {
setAreaString("");
return () => {};
}
setAreaString(
areaInfo.substring(move, areaInfo.length) + areaInfo.substring(0, move)
);
}, [move]);
useEffect(() => {
if (!areaInfo) {
setAreaStringLength(0);
return () => {};
}
setAreaStringLength(areaInfo.length);
}, [areaInfo]);
return (
<View
style={{
width: wp("98%"),
/* height: wp("98%")/10*9, */ backgroundColor: "#432",
borderWidth: 1,
margin: 10,
marginHorizontal: wp("1%"),
}}
>
<Header getCurrentTrain={getCurrentTrain} />
{selectedTrain.map((d) => (
<EachData
{...{
d,
trainIDSwitch,
trainDescriptionSwitch,
customTrainDataDetector,
navigate,
openStationACFromEachTrainInfo,
}}
station={station[0]}
/>
))}
{areaString != "" && isInfoArea && (
<Description
numberOfLines={1}
info={areaString.replaceAll("\n", "").replaceAll("\r", "")}
onClick={() => alert(areaInfo)}
/>
)}
<Footer
{...{
trainIDSwitch,
setTrainIDSwitch,
trainDescriptionSwitch,
setTrainDescriptionSwitch,
finalSwitch,
setFinalSwitch,
}}
/>
</View>
);
}
const EachData = (props) => {
const {
d,
trainIDSwitch,
trainDescriptionSwitch,
station,
customTrainDataDetector,
navigate,
openStationACFromEachTrainInfo,
} = props;
const { currentTrain } = useCurrentTrain();
const openTrainInfo = (d) => {
let TrainNumber = "";
if (train.trainNumDistance != undefined) {
const timeInfo =
parseInt(d.train.replace("M", "").replace("D", "")) -
train.trainNumDistance;
TrainNumber = timeInfo + "号";
}
const payload = {
data: {
trainNum: d.train,
limited: `${getTrainType(train.type).data}:${
train.trainName
}${TrainNumber}`,
},
navigate,
openStationACFromEachTrainInfo,
from: "LED",
};
SheetManager.show("EachTrainInfo", {
payload,
});
};
const [train, setTrain] = useState(customTrainDataDetector(d.train));
useEffect(() => {
setTrain(customTrainDataDetector(d.train));
}, [currentTrain, d.train, trainDescriptionSwitch]);
// 土讃線複数存在対策
const currentTrainData = checkDuplicateTrainData(
currentTrain.filter((a) => a.num == d.train)
);
const trainDelayStatus = getTrainDelayStatus(
currentTrainData,
station.Station_JP
);
const trainPositionText = currentTrainData?.Pos.match("")
? `現在地:${
currentTrainData?.Pos.replace("(下り)", "")
.replace("(上り)", "")
.split("")[currentTrainData?.Direction == 1 ? 0 : 1]
}${
currentTrainData?.Pos.replace("(下り)", "")
.replace("(上り)", "")
.split("")[currentTrainData?.Direction == 1 ? 1 : 0]
}間を走行中`
: `現在地:${currentTrainData?.Pos}`;
return (
<>
<TouchableOpacity
style={{
alignContent: "center",
alignItems: "center",
width: "94%",
marginVertical: 5,
marginHorizontal: "3%",
backgroundColor: "#000",
flexDirection: "row",
}}
onPress={() => openTrainInfo(d)}
>
<TrainName
trainName={train.trainName}
trainNumDistance={train.trainNumDistance}
trainIDSwitch={trainIDSwitch}
trainID={d.train}
type={train.type}
/>
<LastStation lastStation={d.lastStation} />
<DependTime time={d.time} />
<StatusAndDelay trainDelayStatus={trainDelayStatus} />
</TouchableOpacity>
{trainDescriptionSwitch && <Description info={`${trainPositionText}`} />}
{trainDescriptionSwitch && !!train.info && (
<Description info={train.info} />
)}
</>
);
};
const TrainName = ({
trainName,
trainNumDistance,
trainIDSwitch,
trainID,
type,
}) => {
const { name, color } = getTrainType(type);
let TrainNumber =
trainNumDistance != undefined
? `${
parseInt(trainID.replace("M", "").replace("D", "")) - trainNumDistance
}`
: "";
return (
<View style={{ flex: 9 }}>
<Text
style={{
fontSize: trainName.length > 6 ? parseInt("12%") : parseInt("16%"),
color: color,
fontWeight: "bold",
}}
>
{trainIDSwitch ? trainID : `${name} ${trainName}${TrainNumber}`}
</Text>
</View>
);
};
const LastStation = ({ lastStation }) => {
return (
<View style={{ flex: 4, flexDirection: "row" }}>
<Text
style={{
fontSize: lastStation.length > 4 ? parseInt("12%") : parseInt("16%"),
color: "white",
fontWeight: "bold",
}}
>
{lastStation}
</Text>
</View>
);
};
const descriptionStyle = {
fontSize: parseInt("16%"),
fontWeight: "bold",
};
const DependTime = ({ time }) => (
<View style={{ flex: 3 }}>
<Text style={{ ...descriptionStyle, color: "white" }}>{time}</Text>
</View>
);
const StatusAndDelay = ({ trainDelayStatus }) => {
return (
<View style={{ flex: 4 }}>
<Text style={{ ...descriptionStyle, color: "white", paddingLeft: 1 }}>
{trainDelayStatus}
</Text>
</View>
);
};
const Description = ({ info, numberOfLines = 0, onClick }) => (
<TouchableOpacity
style={{
alignContent: "center",
alignItems: "center",
width: "94%",
marginVertical: 5,
marginHorizontal: "3%",
backgroundColor: "#000",
flexDirection: "row",
overflow: "hidden",
}}
onPress={onClick}
>
<View style={{ flex: 4, flexDirection: "row" }}>
{numberOfLines == 1 ? (
<Text style={{ ...descriptionStyle, color: "red" }}>
運行情報 &gt;{" "}
</Text>
) : (
<Text style={{ ...descriptionStyle, color: "green" }}> &gt; </Text>
)}
<Text
style={{ ...descriptionStyle, color: "green" }}
numberOfLines={numberOfLines}
>
{info}
</Text>
</View>
</TouchableOpacity>
);