Merge commit 'fe8df6af2e4c871811953c42e75c8dede4c9de89' into develop

This commit is contained in:
harukin-OneMix4 2024-02-14 01:29:03 +09:00
commit e967dfac2f
10 changed files with 758 additions and 688 deletions

86
Apps.js
View File

@ -5,6 +5,7 @@ import {
Text,
TouchableOpacity,
useWindowDimensions,
LayoutAnimation,
} from "react-native";
import { WebView } from "react-native-webview";
import Constants from "expo-constants";
@ -19,6 +20,7 @@ import { useFavoriteStation } from "./stateBox/useFavoriteStation";
import { useCurrentTrain } from "./stateBox/useCurrentTrain";
import { SheetManager } from "react-native-actions-sheet";
import TrainMenu from "./components/trainMenu";
import { EachTrainInfoCore } from "./components/ActionSheetComponents/EachTrainInfoCore";
/*
import StatusbarDetect from './StatusbarDetect';
var Status = StatusbarDetect(); */
@ -186,6 +188,7 @@ export default function Apps({ navigation, webview, stationData }) {
case "ShowTrainTimeInfo": {
const { trainNum, limited } = dataSet;
//alert(trainNum, limited);
LayoutAnimation.easeInEaseOut();
setTrainInfo({
trainNum,
limited,
@ -193,6 +196,7 @@ export default function Apps({ navigation, webview, stationData }) {
currentTrain.filter((a) => a.num == trainNum)
),
}); //遅延情報は未実装
if (isLandscape) return;
const payload = {
data: {
trainNum,
@ -294,7 +298,7 @@ export default function Apps({ navigation, webview, stationData }) {
}}
onLayout={handleLayout}
>
{isLandscape ? (
{!trainInfo.trainData && isLandscape ? (
<TrainMenu
webview={webview}
stationData={stationData}
@ -343,6 +347,26 @@ export default function Apps({ navigation, webview, stationData }) {
}
}}
/>
{isLandscape && trainInfo.trainData && (
<View
style={{
width: (width / 100) * 40,
height: height,
flexDirection: "column",
}}
>
<EachTrainInfoCore
{...{
data: trainInfo.trainData ? trainInfo : undefined,
navigate,
originalStationList,
openStationACFromEachTrainInfo,
from: "Train",
setTrainInfo,
}}
/>
</View>
)}
{isLandscape || (
<MapsButton
onPress={() => navigate("trainMenu", { webview })}
@ -350,9 +374,23 @@ export default function Apps({ navigation, webview, stationData }) {
mapSwitch={mapSwitch == "true" ? "flex" : "none"}
/>
)}
{isLandscape && trainInfo.trainData && (
<LandscapeBackButton
onPress={() => {
LayoutAnimation.easeInEaseOut();
setTrainInfo({
trainNum: undefined,
limited: undefined,
trainData: undefined,
});
}}
top={Platform.OS == "ios" ? Constants.statusBarHeight : 0}
/>
)}
<ReloadButton
onPress={() => webview.current.reload()}
top={Platform.OS == "ios" ? Constants.statusBarHeight : 0}
right={isLandscape && trainInfo.trainData ? (width / 100) * 40 : 0}
LoadError={LoadError}
/>
</View>
@ -395,12 +433,54 @@ const MapsButton = ({ onPress, top, mapSwitch }) => {
);
};
const ReloadButton = ({ onPress, top, mapSwitch, LoadError = false }) => {
const LandscapeBackButton = ({ onPress, top }) => {
const styles = {
touch: {
position: "absolute",
top,
right: 10,
left: 10,
width: 50,
height: 50,
backgroundColor: "#0099CC",
borderColor: "white",
borderStyle: "solid",
borderWidth: 1,
borderRadius: 50,
alignContent: "center",
alignSelf: "center",
alignItems: "center",
display: "flex",
},
text: {
textAlign: "center",
width: "auto",
height: "auto",
textAlignVertical: "center",
fontWeight: "bold",
color: "white",
},
};
return (
<TouchableOpacity onPress={onPress} style={styles.touch}>
<View style={{ flex: 1 }} />
<Ionicons name="arrow-back" color="white" size={30} />
<View style={{ flex: 1 }} />
</TouchableOpacity>
);
};
const ReloadButton = ({
onPress,
top,
mapSwitch,
LoadError = false,
right,
}) => {
const styles = {
touch: {
position: "absolute",
top,
right: 10 + right,
width: 50,
height: 50,
backgroundColor: LoadError ? "red" : "#0099CC",

View File

@ -1,397 +1,11 @@
import React, { useEffect, useState, useRef } from "react";
import {
View,
LayoutAnimation,
Text,
TouchableOpacity,
Platform,
StyleSheet,
useWindowDimensions,
} from "react-native";
import { Ionicons } from "@expo/vector-icons";
import ActionSheet, {
SheetManager,
useScrollHandlers,
} from "react-native-actions-sheet";
import { AS } from "../../storageControl";
import trainList from "../../assets/originData/trainList";
import { lineList } from "../../lib/getStationList";
import { heightPercentageToDP } from "react-native-responsive-screen";
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData";
import { getTrainType } from "../../lib/getTrainType";
import { customTrainDataDetector } from "../custom-train-data";
import { useBusAndTrainData } from "../../stateBox/useBusAndTrainData";
import { EachStopList } from "./EachTrainInfo/EachStopList";
import { DataFromButton } from "./EachTrainInfo/DataFromButton";
import { DynamicHeaderScrollView } from "../DynamicHeaderScrollView";
import { LongHeader } from "./EachTrainInfo/LongHeader";
import { ShortHeader } from "./EachTrainInfo/ShortHeader";
import { ScrollStickyContent } from "./EachTrainInfo/ScrollStickyContent";
import { LandscapeTrainInfo } from "./EachTrainInfo/LandscapeTrainInfo";
import React, { useRef } from "react";
import { Platform } from "react-native";
import ActionSheet from "react-native-actions-sheet";
import { EachTrainInfoCore } from "./EachTrainInfoCore";
export const EachTrainInfo = (props) => {
if (!props.payload) return <></>;
const {
data,
navigate,
originalStationList,
openStationACFromEachTrainInfo = () => {},
from,
} = props.payload;
const [trainData, setTrainData] = useState([]);
const [currentPosition, setCurrentPosition] = useState([]);
const [trainPositionSwitch, setTrainPositionSwitch] = useState("false");
const { currentTrain } = useCurrentTrain();
const { getInfluencedTrainData } = useBusAndTrainData();
const [currentTrainData, setCurrentTrainData] = useState([]);
const [nearTrainIDList, setNearTrainIDList] = useState([]);
const [showNearTrain, setShowNearTrain] = useState([]);
const [isConcatNear, setIsConcatNear] = useState(false);
const [tailStation, setTailStation] = useState();
const [headStation, setHeadStation] = useState();
const { height, width } = useWindowDimensions();
const [isLandscape, setIsLandscape] = useState(false);
useEffect(() => {
if (height / width > 1.5) {
setIsLandscape(false);
}
if (height / width < 1.5) {
setIsLandscape(true);
}
}, [width, height]);
// const [actionSheetHorizonalScroll, setActionSheetHorizonalScroll] = useState(false);
//裏列車探索
useEffect(() => {
if (!data.trainNum) return;
const [returnArray, TDArray] = getInfluencedTrainData(data.trainNum);
setNearTrainIDList(returnArray);
setShowNearTrain(TDArray);
}, [data]);
useEffect(() => {
if (trainData.length == 0) return;
if (showNearTrain.length == 0) return;
showNearTrain.forEach((d) => {
const [station, se, time] = d.split(",");
if (station == trainData[0].split(",")[0])
setHeadStation(trainData[0].split(",")[0]);
if (station == trainData[trainData.length - 1].split(",")[0])
setTailStation(trainData[trainData.length - 1].split(",")[0]);
});
}, [trainData, showNearTrain]);
const openBackTrainInfo = (stationInfo, currentTrainIndex) => {
const migrationArray = (stationInfo) => {
const mainTrainStationPosition = trainData.findIndex(
(d) => d.split(",")[0] == stationInfo
);
const relationMain = (() => {
if (mainTrainStationPosition == 0) return "head";
if (mainTrainStationPosition == trainData.length - 1) return "tail";
return "middle";
})();
const subTrainStationPosition = showNearTrain.findIndex(
(d) => d.split(",")[0] == stationInfo
);
const relationSub = (() => {
if (subTrainStationPosition == 0) return "head";
if (subTrainStationPosition == showNearTrain.length - 1) return "tail";
return "middle";
})();
switch (relationMain) {
case "head":
if (relationSub == "head") {
return;
} else if (relationSub == "tail") {
return [
...showNearTrain.slice(0, subTrainStationPosition),
...trainData,
];
} else if (relationSub == "middle") {
return [
...showNearTrain.slice(0, subTrainStationPosition),
...trainData,
];
} else return;
case "tail":
if (relationSub == "head") {
return [
...trainData.slice(0, mainTrainStationPosition),
...showNearTrain,
];
} else if (relationSub == "tail") {
return;
} else if (relationSub == "middle") {
return [
...trainData.slice(0, mainTrainStationPosition),
...showNearTrain.slice(subTrainStationPosition),
];
} else return;
case "middle":
if (relationSub == "head") {
return [
...trainData.slice(0, mainTrainStationPosition),
...showNearTrain,
];
} else if (relationSub == "tail") {
return [
...showNearTrain.slice(0, subTrainStationPosition),
...trainData.slice(mainTrainStationPosition),
];
} else return;
}
};
const array = migrationArray(stationInfo);
if (!array) return;
setTrainData(array);
setIsConcatNear(true);
};
const openTrainInfo = (d) => {
const train = customTrainDataDetector(d);
let TrainNumber = "";
if (train.trainNumDistance != undefined) {
const timeInfo =
parseInt(d.replace("M", "").replace("D", "")) - train.trainNumDistance;
TrainNumber = timeInfo + "号";
}
const payload = {
data: {
trainNum: d,
limited: `${getTrainType(train.type).data}:${
train.trainName
}${TrainNumber}`,
},
navigate,
originalStationList,
from: "AllTrainDiagramView",
};
SheetManager.hide("EachTrainInfo").then(() => {
//0.1秒待機してから開く
setTimeout(() => {
SheetManager.show("EachTrainInfo", { payload });
}, 1);
});
};
useEffect(() => {
setCurrentTrainData(
checkDuplicateTrainData(
currentTrain.filter((d) => d.num == data.trainNum)
)
);
}, [currentTrain]);
useEffect(() => {
//列車現在地アイコン表示スイッチ
AS.getItem("trainPositionSwitch")
.then((d) => {
if (d) {
setTrainPositionSwitch(d);
} else {
}
})
.catch((d) => AS.setItem("trainPositionSwitch", "false"));
}, []);
//bconst insets = useSafeAreaInsets();
const getStationData = (stationName) => {
const Stations = stationList.map((a) =>
a.filter((d) => d.StationName == stationName)
);
const Station =
Stations &&
Stations.reduce((newArray, e) => {
return newArray.concat(e);
}, []);
if (!Station[0]) return [];
return Station.map((d) => d.StationNumber)[0];
};
useEffect(() => {
//currentTrainData.Pos = "鴨川~端岡"; //test
if (!currentTrainData?.Pos) return;
if (currentTrainData?.Pos.match("")) {
const pos = currentTrainData?.Pos.replace("(下り)", "")
.replace("(上り)", "")
.split("");
setCurrentPosition([getStationData(pos[0]), getStationData(pos[1])]);
} else {
setCurrentPosition([getStationData(currentTrainData?.Pos)]);
}
}, [currentTrainData]);
const stationList =
originalStationList &&
lineList.map((d) =>
originalStationList[d].map((a) => ({
StationNumber: a.StationNumber,
StationName: a.Station_JP,
}))
);
const stopStationIDList = trainData.map((i, index) => {
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);
}, [])
.filter((d) => d.StationNumber)
.map((d) => d.StationNumber);
return StationNumbers[0];
});
function findReversalPoints(array) {
try {
// arrayは現在位置の駅ID(駅在宅の場合は1つの配列、駅間の場合は2つの配列)
// stopStationIDListは停車駅の駅IDの配列
if (!stopStationIDList.length) return [];
// arrayが二次元配列だったら早期リターン
if (!array instanceof Array) return [];
if (!array.length) return [];
if (array[0] instanceof Array) return [];
const arrayNumber = array.map((d) => ({
line: d
.split("")
.filter((s) => "A" < s && s < "Z")
.join(""),
ID: d
.split("")
.filter((s) => "0" <= s && s <= "9")
.join(""),
}));
const stopStationIDListNumber = stopStationIDList.map((d) => {
if (!d) return { line: [], ID: [] };
return {
line: d
.split("")
.filter((s) => "A" < s && s < "Z")
.join(""),
ID: d
.split("")
.filter((s) => "0" <= s && s <= "9")
.join(""),
};
});
// 完全一致
if (array.length == 1) {
const index = stopStationIDList.indexOf(array[0]);
if (index != -1) return [index];
// 通過駅の場合
for (let i = 0; i < stopStationIDListNumber.length - 1; i++) {
if (stopStationIDListNumber[i].ID < arrayNumber[0].ID) {
if (stopStationIDListNumber[i + 1].ID > arrayNumber[0].ID) {
return [i + 1];
}
}
if (stopStationIDListNumber[i].ID > arrayNumber[0].ID) {
if (stopStationIDListNumber[i + 1].ID < arrayNumber[0].ID) {
return [i + 1];
}
}
}
}
// 駅間の場合
if (array.length == 2) {
const index1 = stopStationIDList.indexOf(array[0]);
const index2 = stopStationIDList.indexOf(array[1]);
if (index1 != -1 && index2 != -1) {
// 駅間で通過駅も無い場合
if (index1 < index2) {
if (index1 + 1 == index2) {
return [index2];
} else {
const returnArray = [];
for (let i = index1 + 1; i <= index2; i++) {
returnArray.push(i);
}
return returnArray;
}
}
if (index1 > index2) {
if (index2 + 1 == index1) return [index1];
else {
const returnArray = [];
for (let i = index2 + 1; i <= index1; i++) {
returnArray.push(i);
}
return returnArray;
}
}
} else {
const getNearStationID = (stationID) => {
for (let i = 0; i <= stopStationIDListNumber.length; i++) {
if (stopStationIDListNumber[i].ID < stationID) {
if (stopStationIDListNumber[i + 1].ID > stationID) {
return i + 1;
}
}
if (stopStationIDListNumber[i].ID > stationID) {
if (stopStationIDListNumber[i + 1].ID < stationID) {
return i + 1;
}
}
}
};
let newIndex1 = index1;
let newIndex2 = index2;
if (index1 == -1) {
newIndex1 = getNearStationID(arrayNumber[0].ID);
}
if (index2 == -1) {
newIndex2 = getNearStationID(arrayNumber[1].ID);
}
if (newIndex1 && newIndex2) {
return [newIndex1, newIndex2];
}
// 通過駅の場合
}
return [];
}
} catch (e) {
console.log(e);
}
}
// 使用例
const points =
trainPositionSwitch == "true" ? findReversalPoints(currentPosition) : [];
useEffect(() => {
if (!data.trainNum) return;
const TD = trainList[data.trainNum];
if (!TD) {
setTrainData([]);
return;
}
setTrainData(TD.split("#").filter((d) => d != ""));
}, [data]);
const getType = (string) => {
switch (string) {
case "express":
return "特急";
case "rapid":
return "快速";
default:
return "";
}
};
const migrateTrainName = (string) => {
return string
.replace("マリン", "マリンライナー")
.replace("ライナーライナー", "ライナー");
};
const actionSheetRef = useRef(null);
const scrollHandlers = useScrollHandlers("scrollview-1", actionSheetRef);
return (
<ActionSheet
gestureEnabled={true}
@ -403,300 +17,7 @@ export const EachTrainInfo = (props) => {
//useBottomSafeAreaPadding={Platform.OS == "android"}
>
<View
style={{
backgroundColor: "#0099CC",
borderTopRadius: 5,
borderColor: "dark",
borderWidth: 1,
}}
>
<View style={{ height: 26, width: "100%" }}>
<View
style={{
height: 6,
width: 45,
borderRadius: 100,
backgroundColor: "#f0f0f0",
marginVertical: 10,
alignSelf: "center",
}}
/>
</View>
<View
style={{ padding: 10, flexDirection: "row", alignItems: "center" }}
>
<Text style={{ fontSize: 20, fontWeight: "bold", color: "white" }}>
{data.limited
? getType(data.limited.split(":")[0]) +
migrateTrainName(
data.limited.split(":")[1] ||
(trainData.length > 0
? trainData[trainData.length - 1].split(",")[0] + "行き"
: " ")
)
: ""}
</Text>
<View style={{ flex: 1 }} />
<Text style={{ fontSize: 20, fontWeight: "bold", color: "white" }}>
{data.trainNum}
{isConcatNear ? ` + ${nearTrainIDList}` : ""}
</Text>
{data.limited != undefined &&
getType(data.limited.split(":")[0]) &&
!data.limited.split(":")[1].match("サンポート") && (
<Ionicons
name="subway"
color="white"
size={30}
style={{ margin: 5 }}
onPress={() => {
LayoutAnimation.easeInEaseOut(); //setLoadingDelayData(true);
navigate("trainbase", {
info: "train.html?tn=" + data.trainNum,
from,
});
SheetManager.hide("EachTrainInfo");
}}
/>
)}
</View>
{isLandscape ? (
<LandscapeTrainInfo
scrollHandlers={scrollHandlers}
leftContent={
from == "AllTrainDiagramView" ? (
<></>
) : (
<LongHeader
currentTrainData={currentTrainData}
currentPosition={currentPosition}
nearTrainIDList={nearTrainIDList}
openTrainInfo={openTrainInfo}
/>
)
}
topStickyContent={
<ScrollStickyContent currentTrainData={currentTrainData} />
}
>
{headStation && !isConcatNear && (
<TouchableOpacity
onPress={() => openBackTrainInfo(headStation)}
style={{
padding: 10,
flexDirection: "row",
borderColor: "blue",
borderWidth: 1,
margin: 10,
borderRadius: 5,
alignItems: "center",
}}
>
<Text
style={{ fontSize: 18, fontWeight: "bold", color: "black" }}
>
本当の始発駅を表示
</Text>
</TouchableOpacity>
)}
{/* <LottieView
autoPlay
loop
style={{ width: 150, height: 150, backgroundColor: "#fff" }}
source={require("../../assets/51690-loading-diamonds.json")}
/>
<Text>ほげほげふがふが</Text> */}
{trainData.map((i, index) =>
i.split(",")[1] == "提" ? (
<DataFromButton i={i} />
) : (
<EachStopList
i={i}
index={index}
stationList={stationList}
points={points}
currentTrainData={currentTrainData}
openStationACFromEachTrainInfo={
openStationACFromEachTrainInfo
}
/>
)
)}
{tailStation && !isConcatNear && (
<TouchableOpacity
onPress={() => openBackTrainInfo(tailStation)}
style={{
padding: 10,
flexDirection: "row",
borderColor: "blue",
borderWidth: 1,
margin: 10,
borderRadius: 5,
alignItems: "center",
}}
>
<Text
style={{ fontSize: 18, fontWeight: "bold", color: "black" }}
>
本当の終着駅を表示
</Text>
</TouchableOpacity>
)}
<View style={{ flexDirection: "row" }}>
<View
style={{
padding: 8,
flexDirection: "row",
borderBottomWidth: 1,
borderBottomColor: "#f0f0f0",
flex: 1,
}}
>
<Text style={{ fontSize: 20 }}> </Text>
<View style={{ flex: 1 }} />
</View>
</View>
</LandscapeTrainInfo>
) : (
<DynamicHeaderScrollView
styles={styles}
containerProps={{
style: { maxHeight: heightPercentageToDP("70%") },
}}
Max_Header_Height={from == "AllTrainDiagramView" ? 0 : 200}
Min_Header_Height={from == "AllTrainDiagramView" ? 0 : 80}
shortHeader={
from == "AllTrainDiagramView" ? (
<></>
) : (
<ShortHeader
currentTrainData={currentTrainData}
currentPosition={currentPosition}
nearTrainIDList={nearTrainIDList}
openTrainInfo={openTrainInfo}
/>
)
}
longHeader={
from == "AllTrainDiagramView" ? (
<></>
) : (
<LongHeader
currentTrainData={currentTrainData}
currentPosition={currentPosition}
nearTrainIDList={nearTrainIDList}
openTrainInfo={openTrainInfo}
/>
)
}
topStickyContent={
<ScrollStickyContent currentTrainData={currentTrainData} />
}
>
{headStation && !isConcatNear && (
<TouchableOpacity
onPress={() => openBackTrainInfo(headStation)}
style={{
padding: 10,
flexDirection: "row",
borderColor: "blue",
borderWidth: 1,
margin: 10,
borderRadius: 5,
alignItems: "center",
}}
>
<Text
style={{ fontSize: 18, fontWeight: "bold", color: "black" }}
>
本当の始発駅を表示
</Text>
</TouchableOpacity>
)}
{/* <LottieView
autoPlay
loop
style={{ width: 150, height: 150, backgroundColor: "#fff" }}
source={require("../../assets/51690-loading-diamonds.json")}
/>
<Text>ほげほげふがふが</Text> */}
{trainData.map((i, index) =>
i.split(",")[1] == "提" ? (
<DataFromButton i={i} />
) : (
<EachStopList
i={i}
index={index}
stationList={stationList}
points={points}
currentTrainData={currentTrainData}
openStationACFromEachTrainInfo={
openStationACFromEachTrainInfo
}
/>
)
)}
{tailStation && !isConcatNear && (
<TouchableOpacity
onPress={() => openBackTrainInfo(tailStation)}
style={{
padding: 10,
flexDirection: "row",
borderColor: "blue",
borderWidth: 1,
margin: 10,
borderRadius: 5,
alignItems: "center",
}}
>
<Text
style={{ fontSize: 18, fontWeight: "bold", color: "black" }}
>
本当の終着駅を表示
</Text>
</TouchableOpacity>
)}
<View style={{ flexDirection: "row" }}>
<View
style={{
padding: 8,
flexDirection: "row",
borderBottomWidth: 1,
borderBottomColor: "#f0f0f0",
flex: 1,
}}
>
<Text style={{ fontSize: 20 }}> </Text>
<View style={{ flex: 1 }} />
</View>
</View>
</DynamicHeaderScrollView>
)}
</View>
<EachTrainInfoCore {...{ actionSheetRef, ...props.payload }} />
</ActionSheet>
);
};
const styles = StyleSheet.create({
header: {
justifyContent: "center",
alignItems: "center",
left: 0,
right: 0,
//paddingTop: 10,
position: "absolute",
zIndex: 1,
backgroundColor: "f0f0f0",
},
headerText: {
color: "#fff",
fontSize: 25,
fontWeight: "bold",
textAlign: "center",
},
});

View File

@ -35,7 +35,7 @@ export const TrainDataView = ({
flexDirection: "row",
//minHeight: 200,
//height: heightPercentageToDP("20%"),
width: isLandscape ? width / 2 : width,
width: isLandscape ? (width / 100) * 40 : width,
flex: 1,
}}
>

View File

@ -0,0 +1,442 @@
import React, { useEffect, useState, useRef } from "react";
import {
View,
LayoutAnimation,
Text,
TouchableOpacity,
Platform,
StyleSheet,
useWindowDimensions,
} from "react-native";
import { Ionicons } from "@expo/vector-icons";
import ActionSheet, {
SheetManager,
useScrollHandlers,
} from "react-native-actions-sheet";
import { AS } from "../../storageControl";
import trainList from "../../assets/originData/trainList";
import { lineList } from "../../lib/getStationList";
import { heightPercentageToDP } from "react-native-responsive-screen";
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData";
import { getTrainType } from "../../lib/getTrainType";
import { customTrainDataDetector } from "../custom-train-data";
import { useBusAndTrainData } from "../../stateBox/useBusAndTrainData";
import { EachStopList } from "./EachTrainInfo/EachStopList";
import { DataFromButton } from "./EachTrainInfo/DataFromButton";
import { DynamicHeaderScrollView } from "../DynamicHeaderScrollView";
import { LongHeader } from "./EachTrainInfo/LongHeader";
import { ShortHeader } from "./EachTrainInfo/ShortHeader";
import { ScrollStickyContent } from "./EachTrainInfo/ScrollStickyContent";
import { LandscapeTrainInfo } from "./EachTrainInfo/LandscapeTrainInfo";
import { getStationData } from "../../lib/eachTrainInfoCoreLib/getStationData";
import { findReversalPoints } from "../../lib/eachTrainInfoCoreLib/findReversalPoints";
import { migrateTrainName } from "../../lib/eachTrainInfoCoreLib/migrateTrainName";
import { getType } from "../../lib/eachTrainInfoCoreLib/getType";
import { searchSpecialTrain } from "../../lib/eachTrainInfoCoreLib/searchSpecialTrain";
import { openBackTrainInfo } from "../../lib/eachTrainInfoCoreLib/openBackTrainInfo";
export const EachTrainInfoCore = ({
actionSheetRef,
data,
navigate,
originalStationList,
openStationACFromEachTrainInfo,
from,
setTrainInfo,
}) => {
// const [actionSheetHorizonalScroll, setActionSheetHorizonalScroll] = useState(false);
const { currentTrain } = useCurrentTrain();
const [currentTrainData, setCurrentTrainData] = useState();
// const [actionSheetHorizonalScroll, setActionSheetHorizonalScroll] = useState(false);
useEffect(() => {
console.log(currentTrain.length);
if (!currentTrain.length) return;
setCurrentTrainData(
checkDuplicateTrainData(
currentTrain.filter((d) => d.num == data.trainNum)
)
);
}, [currentTrain, data.trainNum]);
//bconst insets = useSafeAreaInsets();
const [headStation, setHeadStation] = useState();
const [tailStation, setTailStation] = useState();
const [isConcatNear, setIsConcatNear] = useState(false);
const [showNearTrain, setShowNearTrain] = useState([]);
const [nearTrainIDList, setNearTrainIDList] = useState([]);
const { getInfluencedTrainData } = useBusAndTrainData();
const [trainPositionSwitch, setTrainPositionSwitch] = useState("false");
const [currentPosition, setCurrentPosition] = useState([]);
const [trainData, setTrainData] = useState([]);
const scrollHandlers = actionSheetRef
? useScrollHandlers("scrollview-1", actionSheetRef)
: null;
const stationList =
originalStationList &&
lineList.map((d) =>
originalStationList[d].map((a) => ({
StationNumber: a.StationNumber,
StationName: a.Station_JP,
}))
);
// 使用例
const points =
trainPositionSwitch == "true"
? findReversalPoints(currentPosition, stopStationIDList)
: [];
const stopStationIDList = trainData.map((i, index) => {
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);
}, [])
.filter((d) => d.StationNumber)
.map((d) => d.StationNumber);
return StationNumbers[0];
});
const { height, width } = useWindowDimensions();
const [isLandscape, setIsLandscape] = useState(false);
const [trueTrainID, setTrueTrainID] = useState();
useEffect(() => {
if (!data.trainNum) return;
const TD = trainList[data.trainNum];
if (!TD) {
const specialTrainActualID = searchSpecialTrain(data.trainNum, trainList);
setTrueTrainID(specialTrainActualID || undefined);
setTrainData([]);
return;
}
setTrainData(TD.split("#").filter((d) => d != ""));
}, [data]);
//裏列車探索
useEffect(() => {
if (!data.trainNum) return;
const [returnArray, TDArray] = getInfluencedTrainData(data.trainNum);
setNearTrainIDList(returnArray);
setShowNearTrain(TDArray);
if (trainData.length == 0) return;
if (TDArray.length == 0) return;
TDArray.forEach((d) => {
const [station, se, time] = d.split(",");
if (station == trainData[0].split(",")[0])
setHeadStation(trainData[0].split(",")[0]);
if (station == trainData[trainData.length - 1].split(",")[0])
setTailStation(trainData[trainData.length - 1].split(",")[0]);
});
}, [trainData, data]);
useEffect(() => {
//currentTrainData.Pos = "鴨川~端岡"; //test
if (!currentTrainData) return;
if (!currentTrainData?.Pos) return;
if (currentTrainData?.Pos.match("")) {
const pos = currentTrainData?.Pos.replace("(下り)", "")
.replace("(上り)", "")
.split("");
setCurrentPosition([
getStationData(pos[0], stationList),
getStationData(pos[1], stationList),
]);
} else {
setCurrentPosition([getStationData(currentTrainData?.Pos, stationList)]);
}
}, [currentTrainData]);
useEffect(() => {
if (height / width > 1.5) {
setIsLandscape(false);
}
if (height / width < 1.5) {
setIsLandscape(true);
}
}, [width, height]);
const replaceSpecialTrainDetail = (trainNum) => {
let TD = trainList[trainNum];
if (!TD) return;
setTrainData(TD.split("#").filter((d) => d != ""));
};
useEffect(() => {
//列車現在地アイコン表示スイッチ
AS.getItem("trainPositionSwitch")
.then((d) => {
if (d) setTrainPositionSwitch(d);
})
.catch((d) => AS.setItem("trainPositionSwitch", "false"));
}, []);
const openTrainInfo = (d) => {
const train = customTrainDataDetector(d);
let TrainNumber = "";
if (train.trainNumDistance != undefined) {
const timeInfo =
parseInt(d.replace("M", "").replace("D", "")) - train.trainNumDistance;
TrainNumber = timeInfo + "号";
}
const payload = {
data: {
trainNum: d,
limited: `${getTrainType(train.type).data}:${
train.trainName
}${TrainNumber}`,
},
navigate,
originalStationList,
from: "AllTrainDiagramView",
};
if (setTrainInfo) {
setTrainInfo(payload.data);
} else {
SheetManager.hide("EachTrainInfo").then(() => {
//0.1秒待機してから開く
setTimeout(() => {
SheetManager.show("EachTrainInfo", { payload });
}, 1);
});
}
};
return (
<View
style={{
backgroundColor: "#0099CC",
borderTopRadius: 5,
borderColor: "dark",
borderWidth: 1,
}}
>
{isLandscape || (
<View style={{ height: 26, width: "100%" }}>
<View
style={{
height: 6,
width: 45,
borderRadius: 100,
backgroundColor: "#f0f0f0",
marginVertical: 10,
alignSelf: "center",
}}
/>
</View>
)}
<View style={{ padding: 10, flexDirection: "row", alignItems: "center" }}>
<Text style={{ fontSize: 20, fontWeight: "bold", color: "white" }}>
{data.limited
? getType(data.limited.split(":")[0]) +
migrateTrainName(
data.limited.split(":")[1] ||
(trainData.length > 0
? trainData[trainData.length - 1].split(",")[0] + "行き"
: " ")
)
: ""}
</Text>
<View style={{ flex: 1 }} />
<Text style={{ fontSize: 20, fontWeight: "bold", color: "white" }}>
{data.trainNum}
{isConcatNear ? ` + ${nearTrainIDList}` : ""}
</Text>
{data.limited != undefined &&
getType(data.limited.split(":")[0]) &&
!data.limited.split(":")[1].match("サンポート") && (
<Ionicons
name="subway"
color="white"
size={30}
style={{ margin: 5 }}
onPress={() => {
LayoutAnimation.easeInEaseOut(); //setLoadingDelayData(true);
navigate("trainbase", {
info: "train.html?tn=" + data.trainNum,
from,
});
SheetManager.hide("EachTrainInfo");
}}
/>
)}
</View>
<DynamicHeaderScrollView
styles={styles}
scrollViewProps={scrollHandlers}
containerProps={{
style: {
maxHeight: isLandscape ? height - 94 : heightPercentageToDP("70%"),
},
}}
Max_Header_Height={from == "AllTrainDiagramView" ? 0 : 200}
Min_Header_Height={from == "AllTrainDiagramView" ? 0 : 80}
shortHeader={
from == "AllTrainDiagramView" ? (
<></>
) : (
<ShortHeader
currentTrainData={currentTrainData}
currentPosition={currentPosition}
nearTrainIDList={nearTrainIDList}
openTrainInfo={openTrainInfo}
/>
)
}
longHeader={
from == "AllTrainDiagramView" ? (
<></>
) : (
<LongHeader
currentTrainData={currentTrainData}
currentPosition={currentPosition}
nearTrainIDList={nearTrainIDList}
openTrainInfo={openTrainInfo}
/>
)
}
topStickyContent={
<ScrollStickyContent currentTrainData={currentTrainData} />
}
>
{headStation && !isConcatNear && (
<TouchableOpacity
onPress={() => {
const array = openBackTrainInfo(
headStation,
trainData,
showNearTrain
);
if (!array) return;
setTrainData(array);
setIsConcatNear(true);
}}
style={{
padding: 10,
flexDirection: "row",
borderColor: "blue",
borderWidth: 1,
margin: 10,
borderRadius: 5,
alignItems: "center",
}}
>
<Text style={{ fontSize: 18, fontWeight: "bold", color: "black" }}>
本当の始発駅を表示
</Text>
</TouchableOpacity>
)}
{/* <LottieView
autoPlay
loop
style={{ width: 150, height: 150, backgroundColor: "#fff" }}
source={require("../../assets/51690-loading-diamonds.json")}
/>
<Text>ほげほげふがふが</Text> */}
{trainData.length == 0 && trueTrainID && (
<TouchableOpacity
onPress={() => replaceSpecialTrainDetail(trueTrainID)}
style={{
padding: 10,
flexDirection: "row",
borderColor: "blue",
borderWidth: 1,
margin: 10,
borderRadius: 5,
alignItems: "center",
}}
>
<Text style={{ fontSize: 18, fontWeight: "bold", color: "black" }}>
本来の列車情報を表示
</Text>
</TouchableOpacity>
)}
{trainData.map((i, index) =>
i.split(",")[1] == "提" ? (
<DataFromButton i={i} />
) : (
<EachStopList
i={i}
index={index}
stationList={stationList}
points={points}
currentTrainData={currentTrainData}
openStationACFromEachTrainInfo={openStationACFromEachTrainInfo}
/>
)
)}
{tailStation && !isConcatNear && (
<TouchableOpacity
onPress={() => {
const array = openBackTrainInfo(
tailStation,
trainData,
showNearTrain
);
if (!array) return;
setTrainData(array);
setIsConcatNear(true);
}}
style={{
padding: 10,
flexDirection: "row",
borderColor: "blue",
borderWidth: 1,
margin: 10,
borderRadius: 5,
alignItems: "center",
}}
>
<Text style={{ fontSize: 18, fontWeight: "bold", color: "black" }}>
本当の終着駅を表示
</Text>
</TouchableOpacity>
)}
<View style={{ flexDirection: "row" }}>
<View
style={{
padding: 8,
flexDirection: "row",
borderBottomWidth: 1,
borderBottomColor: "#f0f0f0",
flex: 1,
}}
>
<Text style={{ fontSize: 20 }}> </Text>
<View style={{ flex: 1 }} />
</View>
</View>
</DynamicHeaderScrollView>
</View>
);
};
const styles = StyleSheet.create({
header: {
justifyContent: "center",
alignItems: "center",
left: 0,
right: 0,
//paddingTop: 10,
position: "absolute",
zIndex: 1,
backgroundColor: "f0f0f0",
},
headerText: {
color: "#fff",
fontSize: 25,
fontWeight: "bold",
textAlign: "center",
},
});

View File

@ -0,0 +1,113 @@
// arrayは現在位置の駅ID(駅在宅の場合は1つの配列、駅間の場合は2つの配列)
// stopStationIDListは停車駅の駅IDの配列 [Y01,Y02,Y05,...]
export const findReversalPoints = (array, stopStationIDList) => {
try {
if (!stopStationIDList) return [];
// arrayが二次元配列だったら早期リターン
if (!array instanceof Array) return [];
if (!array) return [];
if (array[0] instanceof Array) return [];
const arrayNumber = array.map((d) => ({
line: d
.split("")
.filter((s) => "A" < s && s < "Z")
.join(""),
ID: d
.split("")
.filter((s) => "0" <= s && s <= "9")
.join(""),
}));
const stopStationIDListNumber = stopStationIDList.map((d) => {
if (!d) return { line: [], ID: [] };
return {
line: d
.split("")
.filter((s) => "A" < s && s < "Z")
.join(""),
ID: d
.split("")
.filter((s) => "0" <= s && s <= "9")
.join(""),
};
});
// 完全一致
if (array.length == 1) {
const index = stopStationIDList.indexOf(array[0]);
if (index != -1) return [index];
// 通過駅の場合
for (let i = 0; i < stopStationIDListNumber.length - 1; i++) {
if (stopStationIDListNumber[i].ID < arrayNumber[0].ID) {
if (stopStationIDListNumber[i + 1].ID > arrayNumber[0].ID) {
return [i + 1];
}
}
if (stopStationIDListNumber[i].ID > arrayNumber[0].ID) {
if (stopStationIDListNumber[i + 1].ID < arrayNumber[0].ID) {
return [i + 1];
}
}
}
}
// 駅間の場合
if (array.length == 2) {
const index1 = stopStationIDList.indexOf(array[0]);
const index2 = stopStationIDList.indexOf(array[1]);
if (index1 != -1 && index2 != -1) {
// 駅間で通過駅も無い場合
if (index1 < index2) {
if (index1 + 1 == index2) {
return [index2];
} else {
const returnArray = [];
for (let i = index1 + 1; i <= index2; i++) {
returnArray.push(i);
}
return returnArray;
}
}
if (index1 > index2) {
if (index2 + 1 == index1) return [index1];
else {
const returnArray = [];
for (let i = index2 + 1; i <= index1; i++) {
returnArray.push(i);
}
return returnArray;
}
}
} else {
const getNearStationID = (stationID) => {
for (let i = 0; i <= stopStationIDListNumber.length; i++) {
if (stopStationIDListNumber[i].ID < stationID) {
if (stopStationIDListNumber[i + 1].ID > stationID) {
return i + 1;
}
}
if (stopStationIDListNumber[i].ID > stationID) {
if (stopStationIDListNumber[i + 1].ID < stationID) {
return i + 1;
}
}
}
};
let newIndex1 = index1;
let newIndex2 = index2;
if (index1 == -1) {
newIndex1 = getNearStationID(arrayNumber[0].ID);
}
if (index2 == -1) {
newIndex2 = getNearStationID(arrayNumber[1].ID);
}
if (newIndex1 && newIndex2) {
return [newIndex1, newIndex2];
}
// 通過駅の場合
}
return [];
}
} catch (e) {
console.log(e);
}
};

View File

@ -0,0 +1,15 @@
// 駅名から駅情報を取得する
//stationName: 駅名
//stationList: 駅情報リスト
export const getStationData = (stationName, stationList) => {
const Stations = stationList.map((a) =>
a.filter((d) => d.StationName == stationName)
);
const Station =
Stations &&
Stations.reduce((newArray, e) => {
return newArray.concat(e);
}, []);
if (!Station[0]) return [];
return Station.map((d) => d.StationNumber)[0];
};

View File

@ -0,0 +1,11 @@
// 種別判定
export const getType = (string) => {
switch (string) {
case "express":
return "特急";
case "rapid":
return "快速";
default:
return "";
}
};

View File

@ -0,0 +1,7 @@
// Description: 電車名の変換を行う。
// マリンライナーやマリン表記をマリンライナーに変換する。
export const migrateTrainName = (string) => {
return string
.replace("マリン", "マリンライナー")
.replace("ライナーライナー", "ライナー");
};

View File

@ -0,0 +1,68 @@
export const openBackTrainInfo = (stationInfo, trainData, showNearTrain) => {
const migrationArray = (stationInfo) => {
const mainTrainStationPosition = trainData.findIndex(
(d) => d.split(",")[0] == stationInfo
);
const relationMain = (() => {
if (mainTrainStationPosition == 0) return "head";
if (mainTrainStationPosition == trainData.length - 1) return "tail";
return "middle";
})();
const subTrainStationPosition = showNearTrain.findIndex(
(d) => d.split(",")[0] == stationInfo
);
const relationSub = (() => {
if (subTrainStationPosition == 0) return "head";
if (subTrainStationPosition == showNearTrain.length - 1) return "tail";
return "middle";
})();
switch (relationMain) {
case "head":
if (relationSub == "head") {
return;
} else if (relationSub == "tail") {
return [
...showNearTrain.slice(0, subTrainStationPosition),
...trainData,
];
} else if (relationSub == "middle") {
return [
...showNearTrain.slice(0, subTrainStationPosition),
...trainData,
];
} else return;
case "tail":
if (relationSub == "head") {
return [
...trainData.slice(0, mainTrainStationPosition),
...showNearTrain,
];
} else if (relationSub == "tail") {
return;
} else if (relationSub == "middle") {
return [
...trainData.slice(0, mainTrainStationPosition),
...showNearTrain.slice(subTrainStationPosition),
];
} else return;
case "middle":
if (relationSub == "head") {
return [
...trainData.slice(0, mainTrainStationPosition),
...showNearTrain,
];
} else if (relationSub == "tail") {
return [
...showNearTrain.slice(0, subTrainStationPosition),
...trainData.slice(mainTrainStationPosition),
];
} else return;
}
};
const array = migrationArray(stationInfo);
if (!array) return null;
return array;
};

View File

@ -0,0 +1,13 @@
// S列番の列車からDやMの列車を検索する
export const searchSpecialTrain = (trainNum, trainList) => {
const searchBase = trainNum.replace("S", "").replace("X", "");
const search = (text) => {
const TD = trainList[searchBase + text];
if (TD) {
return true;
}
return false;
};
if (search("D")) return searchBase + "D";
if (search("M")) return searchBase + "M";
};