Compare commits
182 Commits
7716cb516c
...
patch/6.x
Author | SHA1 | Date | |
---|---|---|---|
|
59e7ba5290 | ||
|
83539d5df3 | ||
|
9e831ecd6e | ||
|
4e367d1e3c | ||
|
4151f3f056 | ||
|
1073d1f681 | ||
|
7f0e56e86c | ||
|
8702b22cdd | ||
|
3dbcc93448 | ||
|
211e361285 | ||
|
e05da6e2d3 | ||
|
ba074a181c | ||
|
525fbaa717 | ||
|
7ab402d35f | ||
|
c0a29fab0d | ||
|
f7e59cd75b | ||
|
7ae6bc8801 | ||
|
ba65389596 | ||
|
83e45e1aa3 | ||
|
2d6a67c793 | ||
|
6b6c2d7eba | ||
|
d36195df69 | ||
|
8ddf3a3e8d | ||
|
1b26afb37b | ||
|
25ff4a8019 | ||
|
c8119e2373 | ||
|
85fd66b728 | ||
|
2fe525d620 | ||
|
acb1849544 | ||
|
3531a128ab | ||
|
64de920dc6 | ||
|
a650a21669 | ||
|
7dc3c324f9 | ||
|
4edfb951d4 | ||
|
60e1dcd1a5 | ||
|
a8cf24e745 | ||
|
19103d9796 | ||
|
50b2cbb21c | ||
|
7bea2ac454 | ||
|
2d0c7605f6 | ||
|
58df77ae49 | ||
|
9ac36216b9 | ||
|
338afb087a | ||
|
71ee79289a | ||
|
ad2d18e263 | ||
|
9ab4c0a205 | ||
|
0d9c1cdb18 | ||
|
d419e90140 | ||
|
bc4cb450a3 | ||
|
6de39e53b6 | ||
|
2fa4ea75ee | ||
|
ddb467e4c6 | ||
|
a593958feb | ||
|
ea2ae7037a | ||
|
c7487d38db | ||
|
30c05bdee6 | ||
|
4674f46c82 | ||
|
b43604c7f1 | ||
|
4dba21ccdd | ||
|
b0cf702620 | ||
|
b76f1adec1 | ||
|
869731eedf | ||
|
5d9a7e185f | ||
|
7b9cbf963e | ||
|
74054b107d | ||
|
0c2c733a59 | ||
|
291091a3ec | ||
|
405f91a7d8 | ||
|
3d3414fc1a | ||
|
8970eedbfb | ||
|
b0a488868e | ||
|
01378c2f7e | ||
|
a5139aca63 | ||
|
a0cfca7a41 | ||
|
63ae4e8c14 | ||
|
b7d3dccd95 | ||
|
cafb5b04f5 | ||
|
92b5052f3b | ||
|
620be8b58e | ||
|
ac11117fd6 | ||
|
eda1d10c0c | ||
|
b37b40b6a8 | ||
|
0c64f7af45 | ||
|
99dbada0c2 | ||
|
2967837dd5 | ||
|
8b74273fed | ||
|
b38d8fe39d | ||
|
92d37b7277 | ||
|
35f1860b03 | ||
|
c19d9f21d1 | ||
|
2711e0850e | ||
|
9b4c0735b0 | ||
|
7f3ef067ca | ||
|
036a7ee914 | ||
|
d6100c99c7 | ||
|
9410925f70 | ||
|
7edfa62673 | ||
|
c25050f344 | ||
|
7e0749a2f2 | ||
|
edc1dc5b2d | ||
|
5f7c4d202d | ||
|
a927a73c29 | ||
|
23cd316213 | ||
|
c00034a11b | ||
|
2f558cddb2 | ||
|
087f6c8829 | ||
|
d9a61dae33 | ||
|
391674ae42 | ||
|
c7d509b61a | ||
|
ddaad38ccc | ||
|
0eef74a799 | ||
|
eb35cb8d56 | ||
|
bcdde280a2 | ||
|
172f5aa2c8 | ||
|
56240b0614 | ||
|
8f49bdb64a | ||
|
8daffd3d3b | ||
|
4c9270171c | ||
|
fd699c8150 | ||
|
8792d3a770 | ||
|
c2226eb49e | ||
|
7e46dcda2f | ||
|
8cc1fcf3de | ||
|
ebf72e35bc | ||
|
37e21be4c0 | ||
|
4d167408f2 | ||
|
b07521e4ef | ||
|
98d3b750de | ||
|
cbc572ee6f | ||
|
46cff473e6 | ||
|
7814037d2a | ||
|
ed6dc3809e | ||
|
fc44c55e3a | ||
|
6fbe47f527 | ||
|
eabb2499fa | ||
|
14c5800aa2 | ||
|
e52b019803 | ||
|
f16fe6c994 | ||
|
d15d7c74fb | ||
|
ba5da62736 | ||
|
6567bab066 | ||
|
5defa845fe | ||
|
8edf26c9be | ||
|
7bbb5b972f | ||
|
ac9d4afdd8 | ||
|
911d6942f6 | ||
|
dc552aada4 | ||
|
eaadf66eda | ||
|
fdc8b95406 | ||
|
fe5baba037 | ||
|
8102680ba7 | ||
|
6518b53de9 | ||
|
367a70170f | ||
|
d412941635 | ||
|
ff4eb2c95f | ||
|
5d97ab2f87 | ||
|
a5b3db5676 | ||
|
c822799637 | ||
|
fa664a15bd | ||
|
00e43772a0 | ||
|
980b251d43 | ||
|
7216392c9b | ||
|
913a198a93 | ||
|
a119b426db | ||
|
c258dfad3d | ||
|
3143f73396 | ||
|
9280fc77f6 | ||
|
a2a6c7fdb9 | ||
|
c0804d2ac7 | ||
|
6b4606f2b5 | ||
|
4c68d7d103 | ||
|
268c11111e | ||
|
3dbaa6bfbf | ||
|
dec33e9c64 | ||
|
9b266c15f8 | ||
|
28a3df44cc | ||
|
d19efd0e68 | ||
|
d4443c862e | ||
|
c3646a97d4 | ||
|
99349c3200 | ||
|
e8e9d709ee | ||
|
e6204bf504 |
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { Platform, UIManager } from "react-native";
|
||||
import { Platform, UIManager, Text } from "react-native";
|
||||
import { GestureHandlerRootView } from "react-native-gesture-handler";
|
||||
import { AppContainer } from "./Apps";
|
||||
import { UpdateAsync } from "./UpdateAsync";
|
||||
@@ -32,8 +32,13 @@ if (Platform.OS === "android") {
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
useEffect(() => UpdateAsync(), []);
|
||||
|
||||
useEffect(() => {
|
||||
UpdateAsync();
|
||||
}, []);
|
||||
if (Text.defaultProps == null) {
|
||||
Text.defaultProps = {};
|
||||
Text.defaultProps.allowFontScaling = false;
|
||||
}
|
||||
const ProviderTree = buildProvidersTree([
|
||||
AllTrainDiagramProvider,
|
||||
NotificationProvider,
|
1
Apps.js
1
Apps.js
@@ -28,6 +28,7 @@ export function AppContainer() {
|
||||
"JR-Nishi": require("./assets/fonts/jr-nishi.otf"),
|
||||
Zou: require("./assets/fonts/DelaGothicOne-Regular.ttf"),
|
||||
"JNR-font": require("./assets/fonts/JNRfont_pict.ttf"),
|
||||
"DiaPro": require("./assets/fonts/DiaPro-Regular.otf"),
|
||||
});
|
||||
return (
|
||||
<NavigationContainer ref={navigationRef}>
|
||||
|
@@ -6,19 +6,20 @@ import Constants from "expo-constants";
|
||||
import { Dimensions, StatusBar } from "react-native";
|
||||
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import { AS } from "./storageControl";
|
||||
import TrainBase from "./components/trainbaseview";
|
||||
import HowTo from "./howto";
|
||||
import Menu from "./menu";
|
||||
import News from "./components/news";
|
||||
import Setting from "./components/Settings/settings";
|
||||
import { useFavoriteStation } from "./stateBox/useFavoriteStation";
|
||||
import { optionData } from "./lib/stackOption";
|
||||
import AllTrainDiagramView from "./components/AllTrainDiagramView";
|
||||
import { AS } from "@/storageControl";
|
||||
import TrainBase from "@/components/trainbaseview";
|
||||
import HowTo from "@/howto";
|
||||
import { Menu } from "@/menu";
|
||||
import News from "@/components/news";
|
||||
import Setting from "@/components/Settings/settings";
|
||||
import { useFavoriteStation } from "@/stateBox/useFavoriteStation";
|
||||
import { optionData } from "@/lib/stackOption";
|
||||
import AllTrainDiagramView from "@/components/AllTrainDiagramView";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { news } from "./config/newsUpdate";
|
||||
import { news } from "@/config/newsUpdate";
|
||||
import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs";
|
||||
import GeneralWebView from "./GeneralWebView";
|
||||
import GeneralWebView from "@/GeneralWebView";
|
||||
import { StationDiagramView } from "@/components/StationDiagram/StationDiagramView";
|
||||
const Stack = createStackNavigator();
|
||||
|
||||
export function MenuPage() {
|
||||
@@ -86,7 +87,7 @@ export function MenuPage() {
|
||||
})
|
||||
.catch((error) => {
|
||||
if (__DEV__) {
|
||||
console.warn('お気に入り駅の読み込みに失敗しました:', error);
|
||||
console.warn("お気に入り駅の読み込みに失敗しました:", error);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -94,7 +95,7 @@ export function MenuPage() {
|
||||
return unsubscribe;
|
||||
}, [navigation, mapHeight, favoriteStation, setFavoriteStation]);
|
||||
return (
|
||||
<Stack.Navigator>
|
||||
<Stack.Navigator id={null}>
|
||||
<Stack.Screen
|
||||
name="menu"
|
||||
options={{
|
||||
@@ -112,6 +113,11 @@ export function MenuPage() {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="stDiagram"
|
||||
options={{ ...optionData, gestureEnabled: false }}
|
||||
component={StationDiagramView}
|
||||
/>
|
||||
<Stack.Screen name="news" options={optionData} component={News} />
|
||||
<Stack.Screen
|
||||
name="setting"
|
||||
@@ -133,7 +139,11 @@ export function MenuPage() {
|
||||
component={AllTrainDiagramView}
|
||||
/>
|
||||
<Stack.Screen name="howto" options={optionData} component={HowTo} />
|
||||
<Stack.Screen name="generalWebView" options={optionData} component={GeneralWebView} />
|
||||
<Stack.Screen
|
||||
name="generalWebView"
|
||||
options={optionData}
|
||||
component={GeneralWebView}
|
||||
/>
|
||||
</Stack.Navigator>
|
||||
);
|
||||
}
|
@@ -14,6 +14,7 @@ import { AS } from "./storageControl";
|
||||
import { news } from "./config/newsUpdate";
|
||||
import { Linking, Platform } from "react-native";
|
||||
import GeneralWebView from "./GeneralWebView";
|
||||
import { StationDiagramView } from "@/components/StationDiagram/StationDiagramView";
|
||||
const Stack = createStackNavigator();
|
||||
export const Top = () => {
|
||||
const { webview } = useCurrentTrain();
|
||||
@@ -37,7 +38,8 @@ export const Top = () => {
|
||||
return;
|
||||
}
|
||||
if (!isFocused()) navigate("positions", { screen: "Apps" });
|
||||
else if (mapSwitch == "true") navigate("positions", { screen: "trainMenu" });
|
||||
else if (mapSwitch == "true")
|
||||
navigate("positions", { screen: "trainMenu" });
|
||||
else webview.current?.injectJavaScript(`AccordionClassEvent()`);
|
||||
return;
|
||||
};
|
||||
@@ -48,7 +50,7 @@ export const Top = () => {
|
||||
}, [addListener, mapSwitch]);
|
||||
|
||||
return (
|
||||
<Stack.Navigator detachInactiveScreens={false}>
|
||||
<Stack.Navigator id={null} detachInactiveScreens={false}>
|
||||
<Stack.Screen
|
||||
name="Apps"
|
||||
options={{
|
||||
@@ -64,8 +66,17 @@ export const Top = () => {
|
||||
options={{ ...optionData }}
|
||||
component={TrainBase}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="stDiagram"
|
||||
options={{ ...optionData, gestureEnabled: false }}
|
||||
component={StationDiagramView}
|
||||
/>
|
||||
<Stack.Screen name="howto" options={optionData} component={HowTo} />
|
||||
<Stack.Screen name="generalWebView" options={optionData} component={GeneralWebView} />
|
||||
<Stack.Screen
|
||||
name="generalWebView"
|
||||
options={optionData}
|
||||
component={GeneralWebView}
|
||||
/>
|
||||
<Stack.Screen name="news" options={optionData} component={News} />
|
||||
<Stack.Screen
|
||||
name="trainMenu"
|
4
app.json
4
app.json
@@ -7,7 +7,7 @@
|
||||
"android",
|
||||
"web"
|
||||
],
|
||||
"version": "6.0.2",
|
||||
"version": "6.0.4",
|
||||
"orientation": "default",
|
||||
"icon": "./assets/icons/s8600.png",
|
||||
"splash": {
|
||||
@@ -22,7 +22,7 @@
|
||||
"**/*"
|
||||
],
|
||||
"ios": {
|
||||
"buildNumber": "48",
|
||||
"buildNumber": "50",
|
||||
"supportsTablet": false,
|
||||
"bundleIdentifier": "jrshikokuinfo.xprocess.hrkn",
|
||||
"config": {
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 41 KiB |
BIN
assets/fonts/DiaPro-Regular.otf
Normal file
BIN
assets/fonts/DiaPro-Regular.otf
Normal file
Binary file not shown.
@@ -1,157 +0,0 @@
|
||||
import React from "react";
|
||||
import { View, Text, TouchableWithoutFeedback } from "react-native";
|
||||
import dayjs from "dayjs";
|
||||
import lineColorList from "../../../assets/originData/lineColorList";
|
||||
|
||||
export const EachStopList = ({
|
||||
i,
|
||||
index,
|
||||
stationList,
|
||||
points,
|
||||
currentTrainData,
|
||||
openStationACFromEachTrainInfo,
|
||||
showThrew,
|
||||
}) => {
|
||||
if (!showThrew && i.split(",")[1] == "通過") return null;
|
||||
const [station, se, time] = i.split(","); // 阿波池田,発,6:21
|
||||
const Stations = stationList
|
||||
.map((a) => a.filter((d) => d.StationName == station))
|
||||
.reduce((newArray, e) => newArray.concat(e), []);
|
||||
/*Array [
|
||||
Object {
|
||||
"StationName": "佐古",
|
||||
"StationNumber": "T01",
|
||||
},
|
||||
Object {
|
||||
"StationName": "佐古",
|
||||
"StationNumber": "B01",
|
||||
},
|
||||
] */
|
||||
const StationNumbers =
|
||||
Stations &&
|
||||
Stations.filter((d) => d.StationNumber).map((d) => d.StationNumber);
|
||||
// Array [ "T01", "B01",]
|
||||
const lineIDs = [];
|
||||
const EachIDs = [];
|
||||
StationNumbers.forEach((d) => {
|
||||
const textArray = d.split("");
|
||||
lineIDs.push(textArray.filter((s) => "A" < s && s < "Z").join(""));
|
||||
EachIDs.push(textArray.filter((s) => "0" <= s && s <= "9").join(""));
|
||||
});
|
||||
// Array [ "T", "B",]
|
||||
// Array [ "01", "01",]
|
||||
|
||||
const dates = dayjs()
|
||||
.set("hour", parseInt(time.split(":")[0]))
|
||||
.set("minute", parseInt(time.split(":")[1]))
|
||||
.add(isNaN(currentTrainData?.delay) ? 0 : currentTrainData.delay, "minute");
|
||||
const timeString = se == "通過" ? "" : dates.format("HH:mm").split(":");
|
||||
const onClickStateText = (string) => {
|
||||
if (string != "通過") return;
|
||||
alert("この駅は通過駅です");
|
||||
};
|
||||
return (
|
||||
<TouchableWithoutFeedback
|
||||
onPress={() =>
|
||||
openStationACFromEachTrainInfo &&
|
||||
openStationACFromEachTrainInfo(station)
|
||||
}
|
||||
key={station}
|
||||
>
|
||||
<View style={{ flexDirection: "row", backgroundColor: "white" }}>
|
||||
<View
|
||||
style={{
|
||||
width: 35,
|
||||
position: "relative",
|
||||
marginHorizontal: 15,
|
||||
flexDirection: "row",
|
||||
height: "101%",
|
||||
}}
|
||||
>
|
||||
{lineIDs.map((lineID, index) => (
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: `${lineColorList[lineID]}${
|
||||
se == "通過" ? "80" : ""
|
||||
}`,
|
||||
flex: 1,
|
||||
}}
|
||||
key={lineID}
|
||||
>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Text
|
||||
style={{
|
||||
color: "white",
|
||||
textAlign: "center",
|
||||
fontSize: 10,
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{lineIDs[index]}
|
||||
{"\n"}
|
||||
{EachIDs[index]}
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
padding: 8,
|
||||
flexDirection: "row",
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: "#f0f0f0",
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{ fontSize: 20, color: `#000${se == "通過" ? "5" : ""}` }}
|
||||
>
|
||||
{station}
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
<View style={{ position: "relative", width: 0 }}>
|
||||
{points ? (
|
||||
<Text style={{ fontSize: 20, position: "absolute", left: -60 }}>
|
||||
🚊
|
||||
</Text>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
{!isNaN(currentTrainData?.delay) && currentTrainData?.delay != 0 && (
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 15,
|
||||
color: "black",
|
||||
width: 60,
|
||||
position: "absolute",
|
||||
right: 120,
|
||||
textAlign: "right",
|
||||
textDecorationLine: "line-through",
|
||||
}}
|
||||
>
|
||||
{time}
|
||||
</Text>
|
||||
)}
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
color: isNaN(currentTrainData?.delay)
|
||||
? "black"
|
||||
: currentTrainData?.delay == 0
|
||||
? "black"
|
||||
: "red",
|
||||
width: 60,
|
||||
}}
|
||||
onPress={() => onClickStateText(se)}
|
||||
>
|
||||
{se == "通過" ? "レ" : `${timeString[0]}:${timeString[1]}`}
|
||||
</Text>
|
||||
<Text style={{ fontSize: 18, width: 50 }}>
|
||||
{se?.replace("発", "出発").replace("着", "到着")}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
);
|
||||
};
|
237
components/ActionSheetComponents/EachTrainInfo/EachStopList.tsx
Normal file
237
components/ActionSheetComponents/EachTrainInfo/EachStopList.tsx
Normal file
@@ -0,0 +1,237 @@
|
||||
import React, { FC } from "react";
|
||||
import { View, Text, TouchableWithoutFeedback } from "react-native";
|
||||
import dayjs from "dayjs";
|
||||
import lineColorList from "../../../assets/originData/lineColorList";
|
||||
|
||||
type seTypes =
|
||||
| "発編"
|
||||
| "着編"
|
||||
| "通編"
|
||||
| "頃編"
|
||||
| "発"
|
||||
| "着"
|
||||
| "休編"
|
||||
| "通休編"
|
||||
| string;
|
||||
|
||||
type currentTrainDataType = {
|
||||
Index: number;
|
||||
num: string;
|
||||
delay: "入線" | number | undefined;
|
||||
Pos: string;
|
||||
PosNum: number;
|
||||
Direction: number;
|
||||
Type: string;
|
||||
Line: string;
|
||||
};
|
||||
type props = {
|
||||
i: string;
|
||||
index: number;
|
||||
stationList: { StationName: string; StationNumber: string }[][];
|
||||
points: boolean;
|
||||
currentTrainData?: currentTrainDataType;
|
||||
openStationACFromEachTrainInfo?: (station: string) => void;
|
||||
showThrew: boolean;
|
||||
};
|
||||
export const EachStopList: FC<props> = ({
|
||||
i,
|
||||
index,
|
||||
stationList,
|
||||
points,
|
||||
currentTrainData,
|
||||
openStationACFromEachTrainInfo,
|
||||
showThrew,
|
||||
}) => {
|
||||
const [station, se, time] = i.split(",") as [string, seTypes, string]; // 阿波池田,発,6:21
|
||||
if (!showThrew) {
|
||||
if (se == "通過") return null;
|
||||
if (se == "通編") return null;
|
||||
if (se == "通休編") return null;
|
||||
}
|
||||
const Stations = stationList
|
||||
.map((a) => a.filter((d) => d.StationName == station))
|
||||
.reduce((newArray, e) => newArray.concat(e), []);
|
||||
/*Array [
|
||||
Object {
|
||||
"StationName": "佐古",
|
||||
"StationNumber": "T01",
|
||||
},
|
||||
Object {
|
||||
"StationName": "佐古",
|
||||
"StationNumber": "B01",
|
||||
},
|
||||
] */
|
||||
const StationNumbers =
|
||||
Stations &&
|
||||
Stations.filter((d) => d.StationNumber).map((d) => d.StationNumber);
|
||||
const [seString, seType] = (() => {
|
||||
switch (se) {
|
||||
case "発":
|
||||
return ["出発", "normal"];
|
||||
case "着":
|
||||
return ["到着", "normal"];
|
||||
case "発編":
|
||||
return ["出発", "community"];
|
||||
case "着編":
|
||||
return ["到着", "community"];
|
||||
case "通編":
|
||||
return ["通過", "community"];
|
||||
case "頃編":
|
||||
return ["頃", "community"];
|
||||
case "休編":
|
||||
case "通休編":
|
||||
return ["運休", "community"];
|
||||
default:
|
||||
return [se, "normal"];
|
||||
}
|
||||
})();
|
||||
// Array [ "T01", "B01",]
|
||||
// Array [ "T", "B",]
|
||||
// Array [ "01", "01",]
|
||||
|
||||
const textColor = `#${seType == "community" ? "44f" : "000"}${
|
||||
se == "通過" || se == "通編" || se == "通休編" ? "5" : ""
|
||||
}`;
|
||||
return (
|
||||
<TouchableWithoutFeedback
|
||||
onPress={() =>
|
||||
openStationACFromEachTrainInfo &&
|
||||
openStationACFromEachTrainInfo(station)
|
||||
}
|
||||
key={station}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
backgroundColor: (se != "休編" && se != "通休編") ? "#ffffffc2" : "#474747c2",
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: 35,
|
||||
position: "relative",
|
||||
marginHorizontal: 15,
|
||||
flexDirection: "row",
|
||||
height: "101%",
|
||||
}}
|
||||
>
|
||||
{StationNumbers.map((stn, index) => (
|
||||
<StationNumbersBox stn={stn} se={se} key={index} />
|
||||
))}
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
padding: 8,
|
||||
flexDirection: "row",
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: "#f0f0f0",
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
color: textColor,
|
||||
fontStyle: seType == "community" ? "italic" : "normal",
|
||||
}}
|
||||
>
|
||||
{station}
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
<View style={{ position: "relative", width: 0 }}>
|
||||
{points && (
|
||||
<Text style={{ fontSize: 20, position: "absolute", left: -60 }}>
|
||||
🚊
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
{!!currentTrainData?.delay &&
|
||||
currentTrainData?.delay != "入線" &&
|
||||
currentTrainData?.delay != 0 && (
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 15,
|
||||
color: textColor,
|
||||
width: 60,
|
||||
position: "absolute",
|
||||
right: 120,
|
||||
textAlign: "right",
|
||||
textDecorationLine: "line-through",
|
||||
fontStyle: seType == "community" ? "italic" : "normal",
|
||||
}}
|
||||
>
|
||||
{time}
|
||||
</Text>
|
||||
)}
|
||||
<StationTimeBox
|
||||
delay={currentTrainData?.delay}
|
||||
textColor={textColor}
|
||||
seType={seType}
|
||||
se={se}
|
||||
time={time}
|
||||
/>
|
||||
<Text style={{ fontSize: 18, width: 50, color: textColor }}>
|
||||
{seString}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
);
|
||||
};
|
||||
|
||||
const StationNumbersBox: FC<{ stn: string; se: seTypes }> = (props) => {
|
||||
const { stn, se } = props;
|
||||
const lineColor = lineColorList[stn.charAt(0)];
|
||||
const hasThrew = (se == "通過" || se == "通編" || se == "通休編") ? "80" : "";
|
||||
const backgroundColor = `${lineColor}${hasThrew}`;
|
||||
return (
|
||||
<View style={{ backgroundColor, flex: 1 }} key={stn}>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Text
|
||||
style={{
|
||||
color: "white",
|
||||
textAlign: "center",
|
||||
fontSize: 10,
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{stn.charAt(0)}
|
||||
{"\n"}
|
||||
{stn.slice(1)}
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
type StationTimeBoxType = {
|
||||
delay: "入線" | number | undefined;
|
||||
textColor: string;
|
||||
seType: seTypes;
|
||||
se: string;
|
||||
time: string;
|
||||
};
|
||||
|
||||
const StationTimeBox: FC<StationTimeBoxType> = (props) => {
|
||||
const { delay, textColor, seType, se, time } = props;
|
||||
const dates = dayjs()
|
||||
.set("hour", parseInt(time.split(":")[0]))
|
||||
.set("minute", parseInt(time.split(":")[1]))
|
||||
.add(delay == "入線" || delay == undefined ? 0 : delay, "minute");
|
||||
return (
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
color:
|
||||
delay != "入線" && delay != undefined
|
||||
? delay != 0 && "red"
|
||||
: textColor,
|
||||
width: 60,
|
||||
fontStyle: seType == "community" ? "italic" : "normal",
|
||||
}}
|
||||
>
|
||||
{se.includes("通") && time == "" ? "レ" : dates.format("HH:mm")}
|
||||
</Text>
|
||||
);
|
||||
};
|
@@ -1,46 +0,0 @@
|
||||
import React from "react";
|
||||
import { View, Text, ScrollView, useWindowDimensions } from "react-native";
|
||||
|
||||
export const LandscapeTrainInfo = (props) => {
|
||||
const { leftContent, topStickyContent, children, scrollHandlers } = props;
|
||||
const { height, width } = useWindowDimensions();
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
backgroundColor: "blue",
|
||||
width: width,
|
||||
height: (height / 100) * 70,
|
||||
marginBottom: 50,
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "column",
|
||||
height: (height / 100) * 70,
|
||||
width: width / 2,
|
||||
}}
|
||||
>
|
||||
{leftContent}
|
||||
</View>
|
||||
<ScrollView
|
||||
{...scrollHandlers}
|
||||
style={{
|
||||
width: width / 2,
|
||||
height: "auto",
|
||||
}}
|
||||
stickyHeaderIndices={[1]}
|
||||
scrollEventThrottle={16}
|
||||
onScroll={(d) => {
|
||||
// Handle scroll events
|
||||
}}
|
||||
>
|
||||
<View style={{ height: 0 }} />
|
||||
<View style={{ flexDirection: "column" }} index={1}>
|
||||
{topStickyContent}
|
||||
</View>
|
||||
{children}
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
};
|
@@ -1,8 +1,15 @@
|
||||
import React from "react";
|
||||
import React, { FC } from "react";
|
||||
import { ScrollView } from "react-native";
|
||||
import { TrainDataView } from "./TrainDataView";
|
||||
|
||||
export const LongHeader = ({
|
||||
import { trainDataType } from "@/lib/trainPositionTextArray";
|
||||
type props = {
|
||||
currentTrainData: trainDataType;
|
||||
currentPosition: string[] | undefined;
|
||||
nearTrainIDList: string[];
|
||||
openTrainInfo: (f: string) => void;
|
||||
navigate: (screen: string, data?: any) => void;
|
||||
}
|
||||
export const LongHeader:FC<props> = ({
|
||||
currentTrainData,
|
||||
currentPosition,
|
||||
nearTrainIDList,
|
122
components/ActionSheetComponents/EachTrainInfo/PositionBox.tsx
Normal file
122
components/ActionSheetComponents/EachTrainInfo/PositionBox.tsx
Normal file
@@ -0,0 +1,122 @@
|
||||
import { trainPosition } from "@/lib/trainPositionTextArray";
|
||||
import React, { FC } from "react";
|
||||
import { View, Text, TextStyle, ViewStyle } from "react-native";
|
||||
|
||||
type stateBox = {
|
||||
currentTrainData: any;
|
||||
platformNumber: any;
|
||||
title: string;
|
||||
style?: ViewStyle;
|
||||
mode?: number;
|
||||
platformDescription: string;
|
||||
lineNumber: string;
|
||||
};
|
||||
export const PositionBox: FC<stateBox> = (props) => {
|
||||
const {
|
||||
currentTrainData,
|
||||
platformNumber,
|
||||
title,
|
||||
style,
|
||||
mode,
|
||||
platformDescription,
|
||||
lineNumber,
|
||||
} = props;
|
||||
let firstText = "";
|
||||
let secondText = "";
|
||||
let marginText = "";
|
||||
let externalText = "";
|
||||
const { isBetween, Pos: PosData } = trainPosition(currentTrainData);
|
||||
if (isBetween === true) {
|
||||
const { from, to } = PosData;
|
||||
firstText = from;
|
||||
secondText = to;
|
||||
marginText = mode == 2 ? "→" : "↓";
|
||||
} else {
|
||||
const { Pos } = PosData;
|
||||
if (Pos !== "") {
|
||||
firstText = Pos;
|
||||
if (platformNumber) {
|
||||
secondText = `${platformNumber}番乗り場`;
|
||||
if (lineNumber) {
|
||||
externalText = `${lineNumber}番線`;
|
||||
}
|
||||
} else if (lineNumber) {
|
||||
secondText = `${lineNumber}番線`;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
<View style={{ ...(mode == 2 ? boxStyle2 : boxStyle), ...style }}>
|
||||
<Text style={{ fontSize: 12, color: "#0099CC" }}>{title}</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
<View style={{ flexDirection: mode == 2 ? "row" : "column" }}>
|
||||
{firstText && (
|
||||
<Text style={mode == 2 ? boxTextStyle2 : (isBetween ? boxTextStyle : boxTextStyleBig)}>
|
||||
{firstText}
|
||||
</Text>
|
||||
)}
|
||||
{marginText && (
|
||||
<Text style={{ color: "#0099CC", textAlign: "right" }}>
|
||||
{marginText}
|
||||
</Text>
|
||||
)}
|
||||
{secondText && (
|
||||
<Text style={mode == 2 ? boxTextStyle2 :(isBetween ? boxTextStyle : boxTextStyleMini)}>
|
||||
{secondText}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
{(platformDescription || externalText) && (
|
||||
<View style={{ flexDirection: mode == 2 ? "row" : "column" }}>
|
||||
<Text
|
||||
style={{
|
||||
...{ ...(mode == 2 ? boxTextStyle2 : boxTextStyle) },
|
||||
fontSize: 10,
|
||||
}}
|
||||
>
|
||||
{" " + externalText}
|
||||
{" " + platformDescription}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
const boxStyle: ViewStyle = {
|
||||
flex: 1,
|
||||
backgroundColor: "white",
|
||||
borderRadius: 10,
|
||||
padding: 10,
|
||||
margin: 10,
|
||||
};
|
||||
const boxStyle2: ViewStyle = {
|
||||
flex: 1,
|
||||
backgroundColor: "white",
|
||||
borderRadius: 10,
|
||||
padding: 5,
|
||||
margin: 5,
|
||||
};
|
||||
const boxTextStyle2: TextStyle = {
|
||||
fontSize: 18,
|
||||
color: "#0099CC",
|
||||
textAlign: "right",
|
||||
};
|
||||
const boxTextStyleBig: TextStyle = {
|
||||
fontSize: 28,
|
||||
color: "#0099CC",
|
||||
textAlign: "right",
|
||||
};
|
||||
|
||||
|
||||
const boxTextStyleMini: TextStyle = {
|
||||
fontSize: 16,
|
||||
color: "#0099CC",
|
||||
textAlign: "right",
|
||||
};
|
||||
|
||||
|
||||
const boxTextStyle: TextStyle = {
|
||||
fontSize: 25,
|
||||
color: "#0099CC",
|
||||
textAlign: "right",
|
||||
};
|
@@ -7,7 +7,7 @@ export const ScrollStickyContent = (props) => {
|
||||
<View
|
||||
style={{
|
||||
alignItems: "center",
|
||||
backgroundColor: "white",
|
||||
backgroundColor: "#ffffffc2",
|
||||
flexDirection: "row",
|
||||
}}
|
||||
>
|
||||
@@ -16,7 +16,7 @@ export const ScrollStickyContent = (props) => {
|
||||
padding: 8,
|
||||
flexDirection: "row",
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: "#f0f0f0",
|
||||
borderBottomColor: "#ffffffc2",
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
|
@@ -1,8 +1,15 @@
|
||||
import React from "react";
|
||||
import React, { FC } from "react";
|
||||
import { ScrollView } from "react-native";
|
||||
import { TrainDataView } from "./TrainDataView";
|
||||
|
||||
export const ShortHeader = ({
|
||||
import { trainDataType } from "@/lib/trainPositionTextArray";
|
||||
type props = {
|
||||
currentTrainData: trainDataType;
|
||||
currentPosition: string[] | undefined;
|
||||
nearTrainIDList: string[];
|
||||
openTrainInfo: (f: string) => void;
|
||||
navigate: (screen: string, data?: any) => void;
|
||||
}
|
||||
export const ShortHeader:FC<props> = ({
|
||||
currentTrainData,
|
||||
currentPosition,
|
||||
nearTrainIDList,
|
@@ -14,24 +14,29 @@ export const ShowSpecialTrain = ({
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{isTrainDataNothing && 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>
|
||||
)}
|
||||
{isTrainDataNothing &&
|
||||
trueTrainID?.map((ids) => {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => replaceSpecialTrainDetail(ids)}
|
||||
style={{
|
||||
padding: 10,
|
||||
flexDirection: "row",
|
||||
borderColor: "blue",
|
||||
borderWidth: 1,
|
||||
margin: 10,
|
||||
borderRadius: 5,
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{ fontSize: 18, fontWeight: "bold", color: "black" }}
|
||||
>
|
||||
本来の列車情報候補を表示:({ids})
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@@ -15,21 +15,7 @@ export const StateBox: FC<stateBox> = (props) => {
|
||||
<Text style={{ fontSize: 12, color: "#0099CC" }}>{title}</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
<View style={{ flexDirection: mode == 2 ? "row" : "column" }}>
|
||||
{text?.match("~") ? (
|
||||
<>
|
||||
<Text style={mode == 2 ? boxTextStyle2 : boxTextStyle}>
|
||||
{text.split("~")[0]}
|
||||
</Text>
|
||||
<Text style={{ color: "#0099CC", textAlign: "right" }}>
|
||||
{mode == 2 ? "→" : "↓"}
|
||||
</Text>
|
||||
<Text style={mode == 2 ? boxTextStyle2 : boxTextStyle}>
|
||||
{text.split("~")[1]}
|
||||
</Text>
|
||||
</>
|
||||
) : (
|
||||
<Text style={mode == 2 ? boxTextStyle2 : boxTextStyle}>{text}</Text>
|
||||
)}
|
||||
<Text style={mode == 2 ? boxTextStyle2 : boxTextStyle}>{text}</Text>
|
||||
</View>
|
||||
{endText && (
|
||||
<View style={{ flexDirection: mode == 2 ? "row" : "column" }}>
|
||||
|
@@ -1,187 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { View, TouchableOpacity, useWindowDimensions } from "react-native";
|
||||
import { StateBox } from "./StateBox";
|
||||
import { useDeviceOrientationChange } from "../../../stateBox/useDeviceOrientationChange";
|
||||
import { getStationList2 } from "../../../lib/getStationList";
|
||||
import { useCurrentTrain } from "../../../stateBox/useCurrentTrain";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import { trainPosition } from "../../../lib/trainPositionTextArray";
|
||||
import { TrainPositionDataPush } from "../../発車時刻表/LED_inside_Component/TrainPositionDataPush";
|
||||
import { getStationID } from "../../../lib/eachTrainInfoCoreLib/getStationData";
|
||||
import { useStationList } from "../../../stateBox/useStationList";
|
||||
|
||||
export const TrainDataView = ({
|
||||
currentTrainData,
|
||||
currentPosition,
|
||||
nearTrainIDList,
|
||||
openTrainInfo,
|
||||
mode = 0,
|
||||
navigate,
|
||||
}) => {
|
||||
const { stationList } = useStationList();
|
||||
|
||||
const { width, height } = useWindowDimensions();
|
||||
const { isLandscape } = useDeviceOrientationChange();
|
||||
const { inject } = useCurrentTrain();
|
||||
const [mapsStationData, setMapsStationData] = useState(undefined);
|
||||
|
||||
const [platformNumber, setPlatformNumber] = useState();
|
||||
const [platformDescription, setPlatformDescription] = useState();
|
||||
useEffect(() => {
|
||||
//currentTrainData.Pos = "鴨川~端岡"; //test
|
||||
if (!currentTrainData) return;
|
||||
fetch(
|
||||
`https://n8n.haruk.in/webhook/JR-shikoku-PosID?PosNum=${currentTrainData?.PosNum}&Line=${currentTrainData?.Line}`
|
||||
)
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
setPlatformNumber(data?.type == "Station" ? data?.platform : undefined);
|
||||
setPlatformDescription(
|
||||
data?.type == "Station" ? data?.description : undefined
|
||||
);
|
||||
});
|
||||
}, [currentTrainData]);
|
||||
useEffect(() => {
|
||||
getStationList2().then(setMapsStationData);
|
||||
}, []);
|
||||
const onLine = !!currentPosition?.toString().length;
|
||||
const trainPositionText = (trainData) => {
|
||||
const { isBetween, Pos: PosData } = trainPosition(trainData);
|
||||
const { from, to, Pos } = PosData;
|
||||
if (isBetween === true) return `${from}~${to}`;
|
||||
if (Pos == "") return "";
|
||||
return `${Pos}${platformNumber ? ` ${platformNumber}番線` : ""}`;
|
||||
};
|
||||
const [dialog, setDialog] = useState(false);
|
||||
const [deleteDialog, setDeleteDialog] = useState(false);
|
||||
const [posInput, setPosInput] = useState("");
|
||||
const [descInput, setDescInput] = useState("");
|
||||
const [stationInput, setStationInput] = useState("");
|
||||
const [stationNumberInput, setStationNumberInput] = useState("");
|
||||
return (
|
||||
<>
|
||||
<TrainPositionDataPush
|
||||
dialog={dialog}
|
||||
setDialog={setDialog}
|
||||
currentTrainData={currentTrainData}
|
||||
stationInput={stationInput}
|
||||
stationNumberInput={stationNumberInput}
|
||||
posInput={posInput}
|
||||
descInput={descInput}
|
||||
setPosInput={setPosInput}
|
||||
setDescInput={setDescInput}
|
||||
station={{
|
||||
Station_JP: trainPositionText(currentTrainData),
|
||||
StationNumber: currentPosition[0],
|
||||
}}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
//minHeight: 200,
|
||||
//height: heightPercentageToDP("20%"),
|
||||
width: isLandscape ? (width / 100) * 40 : width,
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<TouchableOpacity
|
||||
style={{ flex: 1, flexDirection: "row" }}
|
||||
//disabled={!onLine}
|
||||
onLongPress={() => {
|
||||
const { isBetween, Pos } = trainPosition(currentTrainData);
|
||||
if (isBetween === true) {
|
||||
if (
|
||||
platformNumber == undefined &&
|
||||
platformDescription == undefined
|
||||
)
|
||||
return;
|
||||
setStationInput(`${Pos.from}→${Pos.to}間`);
|
||||
setStationNumberInput(
|
||||
getStationID(currentTrainData?.Pos, stationList)
|
||||
);
|
||||
setPosInput(platformNumber?.toString() || "");
|
||||
setDeleteDialog(true);
|
||||
} else {
|
||||
setStationInput(Pos.Pos);
|
||||
setStationNumberInput(
|
||||
getStationID(currentTrainData?.Pos, stationList)
|
||||
);
|
||||
setDescInput(platformDescription || "");
|
||||
setPosInput(platformNumber?.toString() || "");
|
||||
setDialog(true);
|
||||
}
|
||||
}}
|
||||
onPress={() => {
|
||||
if (!onLine) return;
|
||||
const test = [];
|
||||
Object.keys(mapsStationData).forEach((d) => {
|
||||
mapsStationData[d].forEach((x) => {
|
||||
if (x.StationNumber == currentPosition[0])
|
||||
test.push({ line: d, station: x });
|
||||
});
|
||||
if (currentPosition[0] == "M12") {
|
||||
test.push({
|
||||
line: "seto",
|
||||
station: { Station_JP: "児島", MyStation: "0" },
|
||||
});
|
||||
}
|
||||
});
|
||||
if (!test.length) return;
|
||||
navigate("positions", { screen: "Apps" });
|
||||
inject(
|
||||
`MoveDisplayStation('${test[0].line}_${test[0].station.MyStation}_${test[0].station.Station_JP}');document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`
|
||||
);
|
||||
SheetManager.hide("EachTrainInfo");
|
||||
}}
|
||||
>
|
||||
<StateBox
|
||||
mode={mode}
|
||||
title={`現在地 ${currentPosition?.toString()}${onLine ? "▶️" : ""}`}
|
||||
text={trainPositionText(currentTrainData)}
|
||||
endText={platformDescription ? `${platformDescription}` : ""}
|
||||
style={
|
||||
onLine
|
||||
? { borderWidth: 1, borderColor: "red", borderStyle: "solid" }
|
||||
: {}
|
||||
}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={{ flex: 1, flexDirection: mode == 2 ? "row" : "column" }}>
|
||||
<View style={{ flex: 1, flexDirection: "row" }}>
|
||||
<StateBox
|
||||
mode={mode}
|
||||
title={isNaN(currentTrainData?.delay) ? "状態" : "遅延時分"}
|
||||
text={`${currentTrainData?.delay}${
|
||||
isNaN(currentTrainData?.delay) ? "" : "分"
|
||||
}`}
|
||||
/>
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
style={{ flex: 1, flexDirection: "row" }}
|
||||
disabled={nearTrainIDList.length == 0}
|
||||
onPress={() => {
|
||||
if (nearTrainIDList.length == 0) return;
|
||||
openTrainInfo(nearTrainIDList[0]);
|
||||
}}
|
||||
>
|
||||
{nearTrainIDList.length == 0 ? (
|
||||
<StateBox mode={mode} title="列番" text={currentTrainData?.num} />
|
||||
) : (
|
||||
<StateBox
|
||||
mode={mode}
|
||||
title="増解結相手を表示▶️"
|
||||
text={`${nearTrainIDList}`}
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
borderColor: "red",
|
||||
borderStyle: "solid",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
};
|
229
components/ActionSheetComponents/EachTrainInfo/TrainDataView.tsx
Normal file
229
components/ActionSheetComponents/EachTrainInfo/TrainDataView.tsx
Normal file
@@ -0,0 +1,229 @@
|
||||
import React, { useState, useEffect, FC } from "react";
|
||||
import { View, TouchableOpacity, useWindowDimensions } from "react-native";
|
||||
import { StateBox } from "./StateBox";
|
||||
import { PositionBox } from "./PositionBox";
|
||||
import { useDeviceOrientationChange } from "../../../stateBox/useDeviceOrientationChange";
|
||||
import { getStationList2 } from "../../../lib/getStationList";
|
||||
import { useCurrentTrain } from "../../../stateBox/useCurrentTrain";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import { trainDataType, trainPosition } from "@/lib/trainPositionTextArray";
|
||||
import { StationPosPushDialog } from "../../発車時刻表/LED_inside_Component/TrainPositionDataPush";
|
||||
import { getStationID } from "../../../lib/eachTrainInfoCoreLib/getStationData";
|
||||
import { useStationList } from "../../../stateBox/useStationList";
|
||||
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||
import { customTrainDataDetector } from "@/components/custom-train-data";
|
||||
|
||||
|
||||
type props = {
|
||||
currentTrainData: trainDataType;
|
||||
currentPosition: string[] | undefined;
|
||||
nearTrainIDList: string[];
|
||||
openTrainInfo: (f: string) => void;
|
||||
mode?: 0 | 1 | 2; //0:通常,1:コンパクト,2:横並び
|
||||
navigate: (screen: string, data?: any) => void;
|
||||
}
|
||||
export const TrainDataView:FC<props> = ({
|
||||
currentTrainData,
|
||||
currentPosition,
|
||||
nearTrainIDList,
|
||||
openTrainInfo,
|
||||
mode = 0,
|
||||
navigate,
|
||||
}) => {
|
||||
const { stationList } = useStationList();
|
||||
|
||||
const { width, height } = useWindowDimensions();
|
||||
const { isLandscape } = useDeviceOrientationChange();
|
||||
const { setInjectData } = useCurrentTrain();
|
||||
|
||||
const { allCustomTrainData } = useAllTrainDiagram();
|
||||
const [mapsStationData, setMapsStationData] = useState(undefined);
|
||||
|
||||
const [platformNumber, setPlatformNumber] = useState();
|
||||
const [lineNumber, setLineNumber] = useState();
|
||||
const [platformDescription, setPlatformDescription] = useState();
|
||||
type data = {
|
||||
type: string;
|
||||
lineNumber: string;
|
||||
platformNumber: string;
|
||||
position: string;
|
||||
stationName: string;
|
||||
description: string;
|
||||
};
|
||||
const [database, setDatabase] = useState<data>(null);
|
||||
useEffect(() => {
|
||||
//currentTrainData.Pos = "鴨川~端岡"; //test
|
||||
if (!currentTrainData) return;
|
||||
fetch(
|
||||
`https://n8n.haruk.in/webhook/JR-shikoku-PosID-v3?PosId=${currentTrainData?.PosNum}&lineName=${currentTrainData?.Line}&StationName=${currentTrainData?.Pos}`
|
||||
)
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
if (!data) return;
|
||||
const {
|
||||
type,
|
||||
stationName,
|
||||
lineNumber,
|
||||
platformNumber,
|
||||
position,
|
||||
description,
|
||||
} = data;
|
||||
setDatabase(data);
|
||||
if (type == "Station") {
|
||||
setLineNumber(lineNumber);
|
||||
setPlatformNumber(platformNumber);
|
||||
setPlatformDescription(description);
|
||||
} else {
|
||||
setLineNumber(undefined);
|
||||
setPlatformNumber(undefined);
|
||||
setPlatformDescription(undefined);
|
||||
}
|
||||
});
|
||||
}, [currentTrainData]);
|
||||
useEffect(() => {
|
||||
getStationList2().then(setMapsStationData);
|
||||
}, []);
|
||||
const onLine = !!currentPosition?.toString().length;
|
||||
|
||||
const [trainNumber, setTrainNumber] = useState(currentTrainData?.num);
|
||||
useEffect(() => {
|
||||
const { TrainNumberOverride } = customTrainDataDetector(
|
||||
currentTrainData?.num,
|
||||
allCustomTrainData
|
||||
);
|
||||
if (TrainNumberOverride) {
|
||||
setTrainNumber(TrainNumberOverride);
|
||||
}else{
|
||||
setTrainNumber(currentTrainData?.num);
|
||||
}
|
||||
}, [currentTrainData?.num, allCustomTrainData]);
|
||||
// 投稿システム関係
|
||||
// Dialog表示関係
|
||||
const [dialog, setDialog] = useState(false);
|
||||
const [deleteDialog, setDeleteDialog] = useState(false);
|
||||
//固定値
|
||||
const [PosNum, setPosNum] = useState<number | undefined>();
|
||||
const [Pos, setPos] = useState<string>("");
|
||||
const [Line, setLine] = useState<string>("");
|
||||
const [StationNum, setStationNum] = useState<string>("");
|
||||
|
||||
//編集情報
|
||||
const [lineInput, setLineInput] = useState<string>("");
|
||||
const [posInput, setPosInput] = useState<string>("");
|
||||
const [descInput, setDescInput] = useState<string>("");
|
||||
|
||||
const openEditWindow = () => {
|
||||
const { isBetween, Pos } = trainPosition(currentTrainData);
|
||||
if (isBetween === true) return;
|
||||
//固定値
|
||||
setPosNum(currentTrainData?.PosNum);
|
||||
setPos(currentTrainData?.Pos);
|
||||
setLine(currentTrainData?.Line);
|
||||
setStationNum(getStationID(currentTrainData?.Pos, stationList));
|
||||
|
||||
//入力欄
|
||||
setPosInput(database?.platformNumber?.toString() || "");
|
||||
setDescInput(database?.description || "");
|
||||
setLineInput(database?.lineNumber?.toString() || "");
|
||||
setDialog(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<StationPosPushDialog
|
||||
// Dialog表示関係
|
||||
dialog={dialog}
|
||||
setDialog={setDialog}
|
||||
// 固定情報
|
||||
PosNum={PosNum}
|
||||
Pos={Pos}
|
||||
Line={Line}
|
||||
StationNum={StationNum}
|
||||
// 入力欄
|
||||
lineInput={lineInput}
|
||||
setLineInput={setLineInput}
|
||||
posInput={posInput}
|
||||
setPosInput={setPosInput}
|
||||
descInput={descInput}
|
||||
setDescInput={setDescInput}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
//minHeight: 200,
|
||||
//height: heightPercentageToDP("20%"),
|
||||
width: isLandscape ? (width / 100) * 40 : width,
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<TouchableOpacity
|
||||
style={{ flex: 1, flexDirection: "row" }}
|
||||
//disabled={!onLine}
|
||||
//onLongPress={openEditWindow}
|
||||
onLongPress={()=>{
|
||||
if (!onLine) return;
|
||||
setInjectData({ type:"train", value:currentTrainData?.num, fixed:true});
|
||||
navigate("positions", { screen: "Apps" });
|
||||
SheetManager.hide("EachTrainInfo");
|
||||
}}
|
||||
onPress={() => {
|
||||
if (!onLine) return;
|
||||
setInjectData({ type: "station", value: currentPosition[0], fixed: false });
|
||||
|
||||
navigate("positions", { screen: "Apps" });
|
||||
SheetManager.hide("EachTrainInfo");
|
||||
}}
|
||||
>
|
||||
<PositionBox
|
||||
mode={mode}
|
||||
title={`現在地 ${currentPosition?.toString()}${onLine ? "▶️" : ""}`}
|
||||
currentTrainData={currentTrainData}
|
||||
platformNumber={platformNumber}
|
||||
lineNumber={lineNumber}
|
||||
platformDescription={platformDescription || ""}
|
||||
style={
|
||||
onLine
|
||||
? { borderWidth: 1, borderColor: "red", borderStyle: "solid" }
|
||||
: {}
|
||||
}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={{ flex: 1, flexDirection: mode == 2 ? "row" : "column" }}>
|
||||
<View style={{ flex: 1, flexDirection: "row" }}>
|
||||
<StateBox
|
||||
mode={mode}
|
||||
title={isNaN(currentTrainData?.delay) ? "状態" : "遅延時分"}
|
||||
text={`${currentTrainData?.delay}${
|
||||
isNaN(currentTrainData?.delay) ? "" : "分"
|
||||
}`}
|
||||
/>
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
style={{ flex: 1, flexDirection: "row" }}
|
||||
disabled={nearTrainIDList.length == 0}
|
||||
onPress={() => {
|
||||
if (nearTrainIDList.length == 0) return;
|
||||
openTrainInfo(nearTrainIDList[0]);
|
||||
}}
|
||||
>
|
||||
{nearTrainIDList.length == 0 ? (
|
||||
<StateBox mode={mode} title="列番" text={trainNumber} />
|
||||
) : (
|
||||
<StateBox
|
||||
mode={mode}
|
||||
title="増解結相手を表示▶️"
|
||||
text={`${nearTrainIDList}`}
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
borderColor: "red",
|
||||
borderStyle: "solid",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
};
|
@@ -42,21 +42,19 @@ export const EachTrainInfoCore = ({
|
||||
from,
|
||||
navigate,
|
||||
}) => {
|
||||
const { currentTrain } = useCurrentTrain();
|
||||
const { currentTrain, getCurrentStationData, getPosition } =
|
||||
useCurrentTrain();
|
||||
const { originalStationList, stationList } = useStationList();
|
||||
const { allTrainDiagram: trainList, allCustonTrainData } =
|
||||
const { allTrainDiagram: trainList, allCustomTrainData } =
|
||||
useAllTrainDiagram();
|
||||
const { setTrainInfo } = useTrainMenu();
|
||||
const [currentTrainData, setCurrentTrainData] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentTrain.length) return;
|
||||
setCurrentTrainData(
|
||||
checkDuplicateTrainData(
|
||||
currentTrain.filter((d) => d.num == data.trainNum),
|
||||
stationList
|
||||
)
|
||||
);
|
||||
const stationData = getCurrentStationData(data.trainNum);
|
||||
if (stationData) {
|
||||
setCurrentTrainData(stationData);
|
||||
}
|
||||
}, [currentTrain, data.trainNum]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -85,27 +83,36 @@ export const EachTrainInfoCore = ({
|
||||
const [haveThrough, setHaveThrough] = useState(false);
|
||||
|
||||
// 使用例
|
||||
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 [stopStationIDList, setStopStationList] = useState([]);
|
||||
useEffect(() => {
|
||||
const stopStationList = trainData.map((i) => {
|
||||
const x = 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;
|
||||
});
|
||||
setStopStationList(x);
|
||||
}, [trainDataWidhThrough]);
|
||||
|
||||
useEffect(() => {
|
||||
const isCancel = [];
|
||||
const stopStationList = trainData.map((i, index, array) => {
|
||||
const [station, se, time] = i.split(",");
|
||||
const [nextStation, nextSe, nextTime] =
|
||||
array[index + 1]?.split(",") || [];
|
||||
isCancel.push(se.includes("休") && nextSe.includes("休"));
|
||||
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 = "";
|
||||
@@ -130,7 +137,9 @@ export const EachTrainInfoCore = ({
|
||||
d.StationNumber > baseStationNumberFirst &&
|
||||
d.StationNumber < baseStationNumberSecond
|
||||
) {
|
||||
allThroughStation.push(`${d.Station_JP},通過,`);
|
||||
allThroughStation.push(
|
||||
`${d.Station_JP},${isCancel[index] ? "通休編" : "通過"},`
|
||||
);
|
||||
setHaveThrough(true);
|
||||
reverse = false;
|
||||
} else {
|
||||
@@ -138,7 +147,9 @@ export const EachTrainInfoCore = ({
|
||||
d.StationNumber < baseStationNumberFirst &&
|
||||
d.StationNumber > baseStationNumberSecond
|
||||
) {
|
||||
allThroughStation.push(`${d.Station_JP},通過,`);
|
||||
allThroughStation.push(
|
||||
`${d.Station_JP},${isCancel[index] ? "通休編" : "通過"},`
|
||||
);
|
||||
setHaveThrough(true);
|
||||
reverse = true;
|
||||
}
|
||||
@@ -197,15 +208,18 @@ export const EachTrainInfoCore = ({
|
||||
const scrollHandlers = actionSheetRef
|
||||
? useScrollHandlers("scrollview-1", actionSheetRef)
|
||||
: null;
|
||||
const [trueTrainID, setTrueTrainID] = useState();
|
||||
const [trueTrainID, setTrueTrainID] = useState([]);
|
||||
useEffect(() => {
|
||||
if (!data.trainNum) return;
|
||||
const TD = trainList[data.trainNum];
|
||||
setHeadStation([]);
|
||||
setTailStation([]);
|
||||
if (!TD) {
|
||||
const specialTrainActualID = searchSpecialTrain(data.trainNum, trainList);
|
||||
setTrueTrainID(specialTrainActualID || undefined);
|
||||
const specialTrainActualIDs = searchSpecialTrain(
|
||||
data.trainNum,
|
||||
trainList
|
||||
);
|
||||
setTrueTrainID(specialTrainActualIDs || []);
|
||||
setTrainData([]);
|
||||
return;
|
||||
}
|
||||
@@ -246,72 +260,37 @@ export const EachTrainInfoCore = ({
|
||||
}, [trainData, data]);
|
||||
|
||||
useEffect(() => {
|
||||
//currentTrainData.Pos = "鴨川~端岡"; //test
|
||||
if (!currentTrainData) return;
|
||||
if (!currentTrainData?.Pos) return;
|
||||
if (currentTrainData?.Pos.match("~")) {
|
||||
const pos = currentTrainData?.Pos.replace("(下り)", "")
|
||||
.replace("(上り)", "")
|
||||
.replace("(徳島線)", "")
|
||||
.replace("(高徳線)", "")
|
||||
.split("~");
|
||||
const direction = parseInt(currentTrainData?.Direction) || 0;
|
||||
if (pos[0] == "児島" && pos[1] == "宇多津") {
|
||||
setCurrentPosition(["M12", "Y09"]);
|
||||
return;
|
||||
} else if (pos[1] == "児島" && pos[0] == "宇多津") {
|
||||
setCurrentPosition(["Y09", "M12"]);
|
||||
return;
|
||||
} else if (pos[0] == "伊予若宮" && pos[1] == "伊予白滝") {
|
||||
setCurrentPosition(["S18", "S14"]);
|
||||
return;
|
||||
} else if (pos[0] == "伊予白滝" && pos[1] == "伊予若宮") {
|
||||
setCurrentPosition(["S14", "S18"]);
|
||||
return;
|
||||
} else if (pos[0] == "伊予大洲" && pos[1] == "伊予若宮") {
|
||||
setCurrentPosition(["U14", "U14"]);
|
||||
return;
|
||||
} else if (pos[0] == "伊予若宮" && pos[1] == "伊予大洲") {
|
||||
setCurrentPosition(["U14", "U14"]);
|
||||
return;
|
||||
const position = getPosition(currentTrainData);
|
||||
if (stopStationIDList.length == 0) return;
|
||||
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];
|
||||
}
|
||||
}
|
||||
const currentPosID = Object.keys(originalStationList).map((key) => {
|
||||
let firstStation = false;
|
||||
let firstStationID = "";
|
||||
let secondStation = false;
|
||||
let secondStationID = "";
|
||||
originalStationList[key].forEach((station) => {
|
||||
if (station.Station_JP === pos[0]) {
|
||||
firstStation = true;
|
||||
firstStationID = station.StationNumber;
|
||||
}
|
||||
if (station.Station_JP === pos[1]) {
|
||||
secondStation = true;
|
||||
secondStationID = station.StationNumber;
|
||||
}
|
||||
});
|
||||
if (firstStation && secondStation) {
|
||||
return [firstStationID, secondStationID];
|
||||
} else return false;
|
||||
});
|
||||
const currentPos = currentPosID.filter((d) => d != false)[0];
|
||||
if (currentPos) {
|
||||
setCurrentPosition(direction == 0 ? currentPos.reverse() : currentPos);
|
||||
} else if (direction == 0) {
|
||||
setCurrentPosition([
|
||||
getStationID(pos[1], stationList),
|
||||
getStationID(pos[0], stationList),
|
||||
]);
|
||||
} else {
|
||||
setCurrentPosition([
|
||||
getStationID(pos[0], stationList),
|
||||
getStationID(pos[1], stationList),
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
setCurrentPosition([getStationID(currentTrainData?.Pos, stationList)]);
|
||||
|
||||
setCurrentPosition(position);
|
||||
}
|
||||
}, [currentTrainData]);
|
||||
}, [currentTrainData,stopStationIDList]);
|
||||
|
||||
useEffect(() => {
|
||||
//列車現在地アイコン表示スイッチ
|
||||
@@ -321,21 +300,23 @@ export const EachTrainInfoCore = ({
|
||||
})
|
||||
.catch(() => AS.setItem("trainPositionSwitch", "true"));
|
||||
}, []);
|
||||
const customTrainType = getTrainType({
|
||||
type: customTrainDataDetector(data.trainNum, allCustomTrainData).type,
|
||||
});
|
||||
|
||||
const openTrainInfo = (d) => {
|
||||
const train = customTrainDataDetector(d, allCustonTrainData);
|
||||
const train = customTrainDataDetector(d, allCustomTrainData);
|
||||
let TrainNumber = "";
|
||||
if (train.trainNumDistance != undefined) {
|
||||
const timeInfo =
|
||||
parseInt(d.replace("M", "").replace("D", "")) - train.trainNumDistance;
|
||||
TrainNumber = timeInfo + "号";
|
||||
}
|
||||
const limitedData = getTrainType({ type: train.type });
|
||||
const payload = {
|
||||
data: {
|
||||
trainNum: d,
|
||||
limited: `${getTrainType(train.type).data}:${
|
||||
train.trainName
|
||||
}${TrainNumber}`,
|
||||
limited: `${limitedData.data}:${train.trainName}${TrainNumber}`,
|
||||
},
|
||||
navigate,
|
||||
from: from == "LED" ? "LED2" : "NearTrainDiagramView",
|
||||
@@ -392,6 +373,8 @@ export const EachTrainInfoCore = ({
|
||||
containerProps={{
|
||||
style: {
|
||||
maxHeight: isLandscape ? height - 94 : (height / 100) * 70,
|
||||
backgroundColor:
|
||||
customTrainType.data === "notService" ? "#777777ff" : "white",
|
||||
},
|
||||
}}
|
||||
shortHeader={
|
||||
@@ -422,6 +405,11 @@ export const EachTrainInfoCore = ({
|
||||
/>
|
||||
}
|
||||
>
|
||||
{customTrainType.data === "notService" && (
|
||||
<Text style={{ backgroundColor: "#ffffffc2", fontWeight: "bold" }}>
|
||||
この列車には乗車できません。
|
||||
</Text>
|
||||
)}
|
||||
{headStation.length != 0 &&
|
||||
headStation.map((i, index) =>
|
||||
showHeadStation.findIndex((d) => d == index) == -1 ? (
|
||||
@@ -441,6 +429,7 @@ export const EachTrainInfoCore = ({
|
||||
borderRadius: 5,
|
||||
alignItems: "center",
|
||||
}}
|
||||
key={i.station + "-head"}
|
||||
>
|
||||
<Text
|
||||
style={{ fontSize: 18, fontWeight: "bold", color: "black" }}
|
||||
@@ -470,6 +459,7 @@ export const EachTrainInfoCore = ({
|
||||
margin: 10,
|
||||
borderRadius: 5,
|
||||
alignItems: "center",
|
||||
backgroundColor: "#ffffffc2",
|
||||
}}
|
||||
>
|
||||
<Text style={{ fontSize: 18, fontWeight: "bold", color: "black" }}>
|
||||
@@ -479,7 +469,7 @@ export const EachTrainInfoCore = ({
|
||||
)}
|
||||
{trainDataWidhThrough.map((i, index) =>
|
||||
i.split(",")[1] == "提" ? (
|
||||
<DataFromButton i={i} />
|
||||
<DataFromButton i={i} key={i + "-data"} />
|
||||
) : (
|
||||
<EachStopList
|
||||
{...{
|
||||
@@ -491,9 +481,13 @@ export const EachTrainInfoCore = ({
|
||||
openStationACFromEachTrainInfo,
|
||||
showThrew,
|
||||
}}
|
||||
key={i + "-stop"}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
<Text style={{ backgroundColor: "#ffffffc2" }}>
|
||||
時刻が斜体,青色になっている時刻はコミュニティで追加されている独自データです。
|
||||
</Text>
|
||||
{tailStation.length != 0 &&
|
||||
tailStation.map(({ station, dia }, index) =>
|
||||
showTailStation.findIndex((d) => d == index) == -1 ? (
|
||||
@@ -534,6 +528,7 @@ export const EachTrainInfoCore = ({
|
||||
flexDirection: "row",
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: "#f0f0f0",
|
||||
backgroundColor: "#ffffffc2",
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
|
@@ -10,6 +10,9 @@ import { InfogramText } from "@/components/ActionSheetComponents/EachTrainInfoCo
|
||||
import { useTrainMenu } from "@/stateBox/useTrainMenu";
|
||||
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||
import { useNotification } from "@/stateBox/useNotifications";
|
||||
import { getStringConfig } from "@/lib/getStringConfig";
|
||||
import { FontAwesome, MaterialCommunityIcons } from "@expo/vector-icons";
|
||||
import { getPDFViewURL } from "@/lib/getPdfViewURL";
|
||||
|
||||
type Props = {
|
||||
data: { trainNum: string; limited: string };
|
||||
@@ -44,86 +47,82 @@ export const HeaderText: FC<Props> = ({
|
||||
const { limited, trainNum } = data;
|
||||
|
||||
const { updatePermission } = useTrainMenu();
|
||||
const { allCustonTrainData } = useAllTrainDiagram();
|
||||
const { allCustomTrainData } = useAllTrainDiagram();
|
||||
const { expoPushToken } = useNotification();
|
||||
|
||||
// 列車名、種別、フォントの取得
|
||||
const [typeName, trainName, fontAvailable, isOneMan, infogram] =
|
||||
useMemo(() => {
|
||||
const customTrainData = customTrainDataDetector(
|
||||
trainNum,
|
||||
allCustonTrainData
|
||||
);
|
||||
const [type, fontAvailable, isOneMan] = (() => {
|
||||
switch (customTrainData.type) {
|
||||
case "LTDEXP":
|
||||
return ["特急", true, false];
|
||||
case "Rapid":
|
||||
return ["快速", true, false];
|
||||
case "Normal":
|
||||
return ["普通", true, false];
|
||||
case "OneManRapid":
|
||||
return ["快速", true, true];
|
||||
case "OneMan":
|
||||
return ["普通", true, true];
|
||||
case "NightLTDEXP":
|
||||
return ["特急", true, false];
|
||||
case "SPCL":
|
||||
return ["臨時", false, false];
|
||||
case "SPCL_EXP":
|
||||
return ["臨時特急", false, false];
|
||||
case "SPCL_Rapid":
|
||||
return ["臨時快速", true, false];
|
||||
case "SPCL_Normal":
|
||||
return ["臨時", true, false];
|
||||
case "Freight":
|
||||
return ["貨物", false, false];
|
||||
case "Other":
|
||||
switch (true) {
|
||||
case !!trainNum.includes("T"):
|
||||
return ["単機回送", false, false];
|
||||
case !!trainNum.includes("R"):
|
||||
case !!trainNum.includes("E"):
|
||||
case !!trainNum.includes("L"):
|
||||
case !!trainNum.includes("A"):
|
||||
case !!trainNum.includes("B"):
|
||||
return ["回送", false, false];
|
||||
case !!trainNum.includes("H"):
|
||||
return ["試運転", false, false];
|
||||
}
|
||||
return ["", false, false];
|
||||
}
|
||||
})();
|
||||
switch (true) {
|
||||
case customTrainData.trainName !== "":
|
||||
// 特急の場合は、列車名を取得
|
||||
// 列番対称データがある場合はそれから列車番号を取得
|
||||
const distance = customTrainData.trainNumDistance;
|
||||
const number =
|
||||
distance !== null ? ` ${parseInt(trainNum) - distance}号` : "";
|
||||
const trainName = customTrainData.trainName + number;
|
||||
return [
|
||||
type,
|
||||
trainName,
|
||||
fontAvailable,
|
||||
isOneMan,
|
||||
customTrainData.infogram,
|
||||
];
|
||||
case trainData[trainData.length - 1] === undefined:
|
||||
return [type, "", fontAvailable, isOneMan, customTrainData.infogram];
|
||||
default:
|
||||
// 行先がある場合は、行先を取得
|
||||
return [
|
||||
type,
|
||||
migrateTrainName(
|
||||
trainData[trainData.length - 1].split(",")[0] + "行き"
|
||||
),
|
||||
fontAvailable,
|
||||
isOneMan,
|
||||
customTrainData.infogram,
|
||||
];
|
||||
}
|
||||
}, [trainData]);
|
||||
const [
|
||||
typeName,
|
||||
trainName,
|
||||
fontAvailable,
|
||||
isOneMan,
|
||||
infogram,
|
||||
isEdit,
|
||||
uwasa,
|
||||
vehicleFormation,
|
||||
trainInfoUrl,
|
||||
] = useMemo(() => {
|
||||
const {
|
||||
type,
|
||||
trainName,
|
||||
trainNumDistance,
|
||||
infogram,
|
||||
isEdit,
|
||||
uwasa,
|
||||
vehicleFormation,
|
||||
trainInfoUrl,
|
||||
} = customTrainDataDetector(trainNum, allCustomTrainData);
|
||||
const [typeString, fontAvailable, isOneMan] = getStringConfig(
|
||||
type,
|
||||
trainNum
|
||||
);
|
||||
switch (true) {
|
||||
case trainName !== "":
|
||||
// 特急の場合は、列車名を取得
|
||||
// 列番対称データがある場合はそれから列車番号を取得
|
||||
return [
|
||||
typeString,
|
||||
trainName +
|
||||
(trainNumDistance !== null
|
||||
? ` ${parseInt(trainNum) - trainNumDistance}号`
|
||||
: ""),
|
||||
fontAvailable,
|
||||
isOneMan,
|
||||
infogram,
|
||||
isEdit,
|
||||
uwasa,
|
||||
vehicleFormation,
|
||||
trainInfoUrl,
|
||||
];
|
||||
case trainData[trainData.length - 1] === undefined:
|
||||
return [
|
||||
typeString,
|
||||
"",
|
||||
fontAvailable,
|
||||
isOneMan,
|
||||
infogram,
|
||||
isEdit,
|
||||
uwasa,
|
||||
vehicleFormation,
|
||||
trainInfoUrl,
|
||||
];
|
||||
default:
|
||||
// 行先がある場合は、行先を取得
|
||||
return [
|
||||
typeString,
|
||||
migrateTrainName(
|
||||
trainData[trainData.length - 1].split(",")[0] + "行き"
|
||||
),
|
||||
fontAvailable,
|
||||
isOneMan,
|
||||
infogram,
|
||||
isEdit,
|
||||
uwasa,
|
||||
vehicleFormation,
|
||||
trainInfoUrl,
|
||||
];
|
||||
}
|
||||
}, [trainData]);
|
||||
|
||||
return (
|
||||
<View
|
||||
@@ -134,19 +133,28 @@ export const HeaderText: FC<Props> = ({
|
||||
>
|
||||
<TrainIconStatus {...{ data, navigate, from }} />
|
||||
<TouchableOpacity
|
||||
style={{ borderRadius: 5, flexDirection: "row", alignItems: "center" }}
|
||||
onLongPress={() => {
|
||||
navigate("generalWebView", {
|
||||
uri:
|
||||
"https://jr-shikoku-data-post-system.pages.dev?trainNum=" +
|
||||
trainNum +
|
||||
"&token=" +
|
||||
expoPushToken,
|
||||
useExitButton: false,
|
||||
});
|
||||
style={{
|
||||
borderRadius: 5,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
...(trainInfoUrl
|
||||
? {
|
||||
borderWidth: 0,
|
||||
borderBottomWidth: 1,
|
||||
borderStyle: "solid",
|
||||
borderColor: "white",
|
||||
}
|
||||
: {}),
|
||||
}}
|
||||
onPress={() => {
|
||||
if (!trainInfoUrl) return;
|
||||
const uri = trainInfoUrl.includes("pdf")
|
||||
? getPDFViewURL(trainInfoUrl)
|
||||
: trainInfoUrl;
|
||||
navigate("generalWebView", { uri, useExitButton: true });
|
||||
SheetManager.hide("EachTrainInfo");
|
||||
}}
|
||||
disabled={!updatePermission}
|
||||
disabled={!trainInfoUrl}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
@@ -160,16 +168,48 @@ export const HeaderText: FC<Props> = ({
|
||||
{typeName}
|
||||
</Text>
|
||||
{isOneMan && <OneManText />}
|
||||
<Text style={textConfig}>{trainName}</Text>
|
||||
<Text style={{...textConfig,...trainName.length >10 ?{fontSize:14}:{} }}>{trainName}</Text>
|
||||
<InfogramText infogram={infogram} />
|
||||
{/* {trainInfoUrl && (
|
||||
<MaterialCommunityIcons
|
||||
name={"open-in-new"}
|
||||
color="white"
|
||||
size={15}
|
||||
/>
|
||||
)} */}
|
||||
</TouchableOpacity>
|
||||
{isEdit && (
|
||||
<FontAwesome
|
||||
name="commenting-o"
|
||||
size={20}
|
||||
color="white"
|
||||
style={{ marginLeft: 5 }}
|
||||
onPress={() =>
|
||||
alert(
|
||||
`[このアイコン、列車データはコミュニティによってリアルタイム追加されています。]\n使用車両情報:\n${vehicleFormation}\n投稿者メモ:\n${
|
||||
uwasa || "なし"
|
||||
}`
|
||||
)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
<View style={{ flex: 1 }} />
|
||||
<Text style={textConfig}>
|
||||
{showHeadStation.map((d) => `${headStation[d].id} + `)}
|
||||
{trainNum}
|
||||
{showTailStation.map((d) => ` + ${tailStation[d].id}`)}
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
onLongPress={() => {
|
||||
if (!updatePermission) return;
|
||||
const uri = `https://jr-shikoku-data-post-system.pages.dev?trainNum=${trainNum}&token=${expoPushToken}`;
|
||||
navigate("generalWebView", { uri, useExitButton: false });
|
||||
SheetManager.hide("EachTrainInfo");
|
||||
}}
|
||||
disabled={!updatePermission}
|
||||
>
|
||||
<Text style={textConfig}>
|
||||
{showHeadStation.map((d) => `${headStation[d].id} + `)}
|
||||
{trainNum}
|
||||
{showTailStation.map((d) => ` + ${tailStation[d].id}`)}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TrainViewIcon {...{ data, navigate, from }} />
|
||||
</View>
|
||||
|
@@ -23,12 +23,12 @@ export const TrainIconStatus: FC<Props> = ({ data, navigate, from }) => {
|
||||
const [trainIcon, setTrainIcon] = useState(null);
|
||||
const [anpanmanStatus, setAnpanmanStatus] = useState<apt>();
|
||||
const [address, setAddress] = useState("");
|
||||
const { allCustonTrainData } = useAllTrainDiagram();
|
||||
const { allCustomTrainData } = useAllTrainDiagram();
|
||||
useEffect(() => {
|
||||
if (!data.trainNum) return;
|
||||
const { img, infoUrl } = customTrainDataDetector(
|
||||
data.trainNum,
|
||||
allCustonTrainData
|
||||
allCustomTrainData
|
||||
);
|
||||
if (img) setTrainIcon(img);
|
||||
if (infoUrl) setAddress(infoUrl);
|
||||
@@ -111,13 +111,13 @@ export const TrainIconStatus: FC<Props> = ({ data, navigate, from }) => {
|
||||
{move ? (
|
||||
<Image
|
||||
source={{ uri: trainIcon }}
|
||||
style={{ height: 34, width: 30, marginRight: 5 }}
|
||||
resizeMethod="scale"
|
||||
style={{ height: 30, width: 24, marginRight: 5 }}
|
||||
resizeMethod="resize"
|
||||
/>
|
||||
) : (
|
||||
<Ionicons
|
||||
{...anpanmanStatus}
|
||||
size={30}
|
||||
size={24}
|
||||
style={{ marginRight: 5 }}
|
||||
/>
|
||||
)}
|
||||
|
@@ -1,10 +1,14 @@
|
||||
import React, { useRef } from "react";
|
||||
import React, { FC, useRef } from "react";
|
||||
import { View, Platform } from "react-native";
|
||||
import ActionSheet from "react-native-actions-sheet";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
|
||||
import { SpecialTrainInfoBox } from "../Menu/SpecialTrainInfoBox";
|
||||
export const SpecialTrainInfo = ({ payload }) => {
|
||||
|
||||
type props = {
|
||||
payload: { navigate: (screen: string, params?: object) => void };
|
||||
};
|
||||
export const SpecialTrainInfo: FC<props> = ({ payload }) => {
|
||||
const { navigate } = payload;
|
||||
const actionSheetRef = useRef(null);
|
||||
const insets = useSafeAreaInsets();
|
||||
|
@@ -19,6 +19,8 @@ import { 駅構内図 } from "./StationDeteilView/StationInsideMapButton";
|
||||
import { WebSiteButton } from "./StationDeteilView/WebSiteButton";
|
||||
import { StationTimeTableButton } from "./StationDeteilView/StationTimeTableButton";
|
||||
import { StationTrainPositionButton } from "./StationDeteilView/StationTrainPositionButton";
|
||||
import { StationDiagramButton } from "./StationDeteilView/StationDiagramButton";
|
||||
import { useTrainMenu } from "@/stateBox/useTrainMenu";
|
||||
|
||||
export const StationDeteilView = (props) => {
|
||||
if (!props.payload) return <></>;
|
||||
@@ -26,6 +28,7 @@ export const StationDeteilView = (props) => {
|
||||
const { width } = useWindowDimensions();
|
||||
const { busAndTrainData } = useBusAndTrainData();
|
||||
const [trainBus, setTrainBus] = useState();
|
||||
const { updatePermission } = useTrainMenu();
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentStation) return () => {};
|
||||
@@ -132,6 +135,11 @@ export const StationDeteilView = (props) => {
|
||||
onExit={onExit}
|
||||
/>
|
||||
)}
|
||||
{updatePermission &&<StationDiagramButton
|
||||
navigate={navigate}
|
||||
onExit={onExit}
|
||||
currentStation={currentStation}
|
||||
/>}
|
||||
{!currentStation[0].StationTimeTable || (
|
||||
<StationTimeTableButton
|
||||
info={info}
|
||||
|
@@ -0,0 +1,40 @@
|
||||
import React, { FC } from "react";
|
||||
import { Linking } from "react-native";
|
||||
import { FontAwesome } from "@expo/vector-icons";
|
||||
import { TicketBox } from "@/components/atom/TicketBox";
|
||||
type Props = {
|
||||
navigate: (screen: string, params?: object) => void;
|
||||
onExit: () => void;
|
||||
currentStation: {
|
||||
Station_JP: string;
|
||||
Station_EN: string;
|
||||
StationName?: string;
|
||||
MyStation?: string;
|
||||
StationNumber: string;
|
||||
DispNum?: string;
|
||||
StationTimeTable: string;
|
||||
StationMap?: string;
|
||||
JrHpUrl?: string;
|
||||
lat: number;
|
||||
lng: number;
|
||||
jslodApi: string;
|
||||
}[];
|
||||
};
|
||||
export const StationDiagramButton: FC<Props> = (props) => {
|
||||
const { navigate, onExit, currentStation } = props;
|
||||
return (
|
||||
<TicketBox
|
||||
backgroundColor={"#8F5902"}
|
||||
icon={<FontAwesome name="table" color="white" size={50} />}
|
||||
flex={1}
|
||||
onPressButton={() => {
|
||||
navigate("stDiagram", {
|
||||
currentStation,
|
||||
});
|
||||
onExit();
|
||||
}}
|
||||
>
|
||||
時刻表v2
|
||||
</TicketBox>
|
||||
);
|
||||
};
|
@@ -1,6 +1,5 @@
|
||||
import { FC } from "react";
|
||||
import { TouchableOpacity, View, Text, Linking } from "react-native";
|
||||
import { useStationList } from "@/stateBox/useStationList";
|
||||
import { useCurrentTrain } from "@/stateBox/useCurrentTrain";
|
||||
import AntDesign from "react-native-vector-icons/AntDesign";
|
||||
type Props = {
|
||||
@@ -10,10 +9,7 @@ type Props = {
|
||||
};
|
||||
export const StationTrainPositionButton: FC<Props> = (props) => {
|
||||
const { stationNumber, onExit, navigate } = props;
|
||||
const {
|
||||
inject,
|
||||
} = useCurrentTrain();
|
||||
const { getInjectJavascriptAddress } = useStationList();
|
||||
const { setInjectData } = useCurrentTrain();
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
@@ -23,12 +19,16 @@ export const StationTrainPositionButton: FC<Props> = (props) => {
|
||||
alignContent: "center",
|
||||
alignItems: "center",
|
||||
margin: 2,
|
||||
flex: 1
|
||||
flex: 1,
|
||||
}}
|
||||
onLongPress={() => {
|
||||
navigate("positions", { screen: "Apps" });
|
||||
setInjectData({ type: "station", value:stationNumber, fixed: true });
|
||||
onExit();
|
||||
}}
|
||||
onPress={() => {
|
||||
navigate("positions", { screen: "Apps" });
|
||||
const script = getInjectJavascriptAddress(stationNumber);
|
||||
inject(script);
|
||||
setInjectData({ type: "station", value: stationNumber, fixed: false });
|
||||
onExit();
|
||||
}}
|
||||
>
|
||||
|
@@ -73,6 +73,7 @@ export const TrainMenuLineSelector = () => {
|
||||
});
|
||||
});
|
||||
}}
|
||||
key={d+"TrainMenuLineSelector"}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
|
@@ -10,6 +10,7 @@ import {
|
||||
Keyboard,
|
||||
ScrollView,
|
||||
Linking,
|
||||
Image,
|
||||
} from "react-native";
|
||||
import { useAllTrainDiagram } from "../stateBox/useAllTrainDiagram";
|
||||
|
||||
@@ -19,9 +20,12 @@ import { SheetManager } from "react-native-actions-sheet";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { BigButton } from "./atom/BigButton";
|
||||
import { Switch } from "react-native-elements";
|
||||
import { migrateTrainName } from "@/lib/eachTrainInfoCoreLib/migrateTrainName";
|
||||
import { OneManText } from "./ActionSheetComponents/EachTrainInfoCore/HeaderTextParts/OneManText";
|
||||
import { getStringConfig } from "@/lib/getStringConfig";
|
||||
export default function AllTrainDiagramView() {
|
||||
const { goBack, navigate } = useNavigation();
|
||||
const { keyList, allTrainDiagram, allCustonTrainData } = useAllTrainDiagram();
|
||||
const { keyList, allTrainDiagram, allCustomTrainData } = useAllTrainDiagram();
|
||||
const [input, setInput] = useState(""); // 文字入力
|
||||
const [keyBoardVisible, setKeyBoardVisible] = useState(false);
|
||||
const [useStationName, setUseStationName] = useState(false);
|
||||
@@ -53,14 +57,14 @@ export default function AllTrainDiagramView() {
|
||||
}, []);
|
||||
|
||||
const openTrainInfo = (d) => {
|
||||
const train = customTrainDataDetector(d, allCustonTrainData);
|
||||
const train = customTrainDataDetector(d, allCustomTrainData);
|
||||
let TrainNumber = "";
|
||||
if (train.trainNumDistance != undefined) {
|
||||
const timeInfo =
|
||||
parseInt(d.replace("M", "").replace("D", "")) - train.trainNumDistance;
|
||||
TrainNumber = timeInfo + "号";
|
||||
}
|
||||
const type = getTrainType(train.type).data;
|
||||
const type = getTrainType({type:train.type}).data;
|
||||
const limited = `${type}:${train.trainName}${TrainNumber}`;
|
||||
const payload = {
|
||||
data: { trainNum: d, limited },
|
||||
@@ -71,6 +75,75 @@ export default function AllTrainDiagramView() {
|
||||
payload,
|
||||
});
|
||||
};
|
||||
|
||||
const Item = ({ id, openTrainInfo }) => {
|
||||
const { img, trainName, type, trainNumDistance, infogram } =
|
||||
customTrainDataDetector(id, allCustomTrainData);
|
||||
|
||||
const [typeString, fontAvailable, isOneMan] = getStringConfig(type, id);
|
||||
const trainNameString = (() => {
|
||||
switch (true) {
|
||||
case trainName !== "":
|
||||
// 特急の場合は、列車名を取得
|
||||
// 列番対称データがある場合はそれから列車番号を取得
|
||||
const distance = trainNumDistance;
|
||||
const number =
|
||||
distance !== null ? ` ${parseInt(id) - distance}号` : "";
|
||||
return trainName + number;
|
||||
case allTrainDiagram[id] === undefined:
|
||||
return "";
|
||||
default:
|
||||
// 行先がある場合は、行先を取得
|
||||
const s = allTrainDiagram[id].split("#");
|
||||
const hoge = s[s.length - 2].split(",")[0];
|
||||
return migrateTrainName(hoge + "行き");
|
||||
}
|
||||
})();
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
padding: 5,
|
||||
flexDirection: "row",
|
||||
borderColor: "white",
|
||||
borderWidth: 1,
|
||||
margin: 5,
|
||||
borderRadius: 5,
|
||||
alignItems: "center",
|
||||
}}
|
||||
onPress={() => openTrainInfo(id)}
|
||||
>
|
||||
{img && (
|
||||
<Image
|
||||
source={{ uri: img }}
|
||||
style={{ width: 20, height: 20, marginLeft: 10, marginRight: 10 }}
|
||||
/>
|
||||
)}
|
||||
{typeString && (
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
color: "white",
|
||||
fontFamily: fontAvailable ? "JR-Nishi" : undefined,
|
||||
fontWeight: !fontAvailable ? "bold" : undefined,
|
||||
marginRight: 5,
|
||||
}}
|
||||
>
|
||||
{typeString}
|
||||
</Text>
|
||||
)}
|
||||
{isOneMan && <OneManText />}
|
||||
{trainNameString && (
|
||||
<Text style={{ fontSize: 20, fontWeight: "bold", color: "white" }}>
|
||||
{trainNameString}
|
||||
</Text>
|
||||
)}
|
||||
<View style={{ flex: 1 }} />
|
||||
<Text style={{ fontSize: 20, fontWeight: "bold", color: "white" }}>
|
||||
{id}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<View style={{ backgroundColor: "#0099CC", height: "100%" }}>
|
||||
<FlatList
|
||||
@@ -78,10 +151,20 @@ export default function AllTrainDiagramView() {
|
||||
style={{ flex: 1 }}
|
||||
data={keyList?.filter((d) => {
|
||||
if (useStationName) {
|
||||
const ls = input.split(",").map((stationName) => {
|
||||
return allTrainDiagram[d].includes(stationName);
|
||||
const EachStopInfo = allTrainDiagram[d].split("#");
|
||||
const ls = input.split(",").map((inputStationValue) => {
|
||||
const isHit = EachStopInfo.find((dx) => {
|
||||
if (!dx) return undefined;
|
||||
const returnData = dx.split(",")[0] == inputStationValue;
|
||||
if (returnData) {
|
||||
const isThrew = dx.split(",")[1].includes("通");
|
||||
if (isThrew) return undefined;
|
||||
}
|
||||
return returnData;
|
||||
});
|
||||
return isHit;
|
||||
});
|
||||
return !ls.includes(false);
|
||||
return !ls.includes(undefined);
|
||||
}
|
||||
if (useRegex) {
|
||||
try {
|
||||
@@ -91,7 +174,8 @@ export default function AllTrainDiagramView() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return d.includes(input);
|
||||
const { img, trainName, type, trainNumDistance, infogram, TrainNumberOverride } = customTrainDataDetector(d, allCustomTrainData);
|
||||
return d.includes(input) || trainName.includes(input) || (TrainNumberOverride && TrainNumberOverride.includes(input));
|
||||
})}
|
||||
renderItem={({ item }) => <Item {...{ openTrainInfo, id: item }} />}
|
||||
ListEmptyComponent={
|
||||
@@ -101,7 +185,6 @@ export default function AllTrainDiagramView() {
|
||||
</Text>
|
||||
</View>
|
||||
}
|
||||
|
||||
keyExtractor={(item) => item}
|
||||
//initialNumToRender={100}
|
||||
/>
|
||||
@@ -205,7 +288,7 @@ export default function AllTrainDiagramView() {
|
||||
}}
|
||||
>
|
||||
<TextInput
|
||||
placeholder="列番を入力してフィルタリングします。"
|
||||
placeholder="列番・列車名を入力してフィルタリングします。"
|
||||
onFocus={() => setKeyBoardVisible(true)}
|
||||
onEndEditing={() => {}}
|
||||
onChange={(ret) => setInput(ret.nativeEvent.text)}
|
||||
@@ -225,25 +308,3 @@ export default function AllTrainDiagramView() {
|
||||
</View>
|
||||
);
|
||||
}
|
||||
const Item = ({ id, openTrainInfo }) => {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
padding: 5,
|
||||
flexDirection: "row",
|
||||
borderColor: "white",
|
||||
borderWidth: 1,
|
||||
margin: 5,
|
||||
borderRadius: 5,
|
||||
alignItems: "center",
|
||||
}}
|
||||
onPress={() => openTrainInfo(id)}
|
||||
>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Text style={{ fontSize: 25, fontWeight: "bold", color: "white" }}>
|
||||
{id}
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
@@ -4,6 +4,7 @@ import {
|
||||
Platform,
|
||||
useWindowDimensions,
|
||||
LayoutAnimation,
|
||||
Text,
|
||||
} from "react-native";
|
||||
import Constants from "expo-constants";
|
||||
import * as Updates from "expo-updates";
|
||||
@@ -23,6 +24,7 @@ import { MapsButton } from "./Apps/MapsButton";
|
||||
import { ReloadButton } from "./Apps/ReloadButton";
|
||||
import { LandscapeBackButton } from "./Apps/LandscapeBackButton";
|
||||
import { useStationList } from "../stateBox/useStationList";
|
||||
import { FixedPositionBox } from "./Apps/FixedPositionBox";
|
||||
/*
|
||||
import StatusbarDetect from '../StatusbarDetect';
|
||||
var Status = StatusbarDetect(); */
|
||||
@@ -30,7 +32,7 @@ var Status = StatusbarDetect(); */
|
||||
const top = Platform.OS == "ios" ? Constants.statusBarHeight : 0;
|
||||
|
||||
export default function Apps() {
|
||||
const { webview } = useCurrentTrain();
|
||||
const { webview, fixedPosition, setFixedPosition } = useCurrentTrain();
|
||||
const { height, width } = useWindowDimensions();
|
||||
const { navigate } = useNavigation();
|
||||
const { isLandscape } = useDeviceOrientationChange();
|
||||
@@ -125,6 +127,10 @@ export default function Apps() {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{fixedPosition.type && (
|
||||
<FixedPositionBox />
|
||||
)}
|
||||
|
||||
{mapSwitch == "true" ? (
|
||||
<ReloadButton
|
||||
onPress={() => Updates.reloadAsync()}
|
||||
|
45
components/Apps/FixedPositionBox.tsx
Normal file
45
components/Apps/FixedPositionBox.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import { useCurrentTrain } from "@/stateBox/useCurrentTrain";
|
||||
import { View, Platform } from "react-native";
|
||||
import { useKeepAwake } from "expo-keep-awake";
|
||||
import Constants from "expo-constants";
|
||||
import { FixedTrain } from "./FixedPositionBox/FixedTrainBox";
|
||||
import { FixedStation } from "./FixedPositionBox/FixedStationBox";
|
||||
import { useState } from "react";
|
||||
import { useTrainMenu } from "@/stateBox/useTrainMenu";
|
||||
|
||||
export const FixedPositionBox = () => {
|
||||
const { mapSwitch } = useTrainMenu();
|
||||
const { fixedPosition } = useCurrentTrain();
|
||||
const [displaySize, setDisplaySize] = useState(mapSwitch == "true" ? 76 : 80);
|
||||
|
||||
useKeepAwake();
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: Platform.OS == "ios" ? Constants.statusBarHeight : 0,
|
||||
borderRadius: 5,
|
||||
zIndex: 1500,
|
||||
width: "100%",
|
||||
height: displaySize,
|
||||
flexDirection: "row",
|
||||
}}
|
||||
pointerEvents="box-none"
|
||||
>
|
||||
{fixedPosition.type === "station" && (
|
||||
<FixedStation
|
||||
stationID={fixedPosition.value}
|
||||
displaySize={displaySize}
|
||||
setDisplaySize={setDisplaySize}
|
||||
/>
|
||||
)}
|
||||
{fixedPosition.type === "train" && (
|
||||
<FixedTrain
|
||||
trainID={fixedPosition.value}
|
||||
displaySize={displaySize}
|
||||
setDisplaySize={setDisplaySize}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
381
components/Apps/FixedPositionBox/FixedStationBox.tsx
Normal file
381
components/Apps/FixedPositionBox/FixedStationBox.tsx
Normal file
@@ -0,0 +1,381 @@
|
||||
import lineColorList from "@/assets/originData/lineColorList";
|
||||
import { StationNumberMaker } from "@/components/駅名表/StationNumberMaker";
|
||||
import { checkDuplicateTrainData } from "@/lib/checkDuplicateTrainData";
|
||||
import {
|
||||
CustomTrainData,
|
||||
eachTrainDiagramType,
|
||||
StationProps,
|
||||
} from "@/lib/CommonTypes";
|
||||
import { getCurrentTrainData } from "@/lib/getCurrentTrainData";
|
||||
import { getTrainDelayStatus } from "@/lib/getTrainDelayStatus";
|
||||
import { getTrainType } from "@/lib/getTrainType";
|
||||
import { objectIsEmpty } from "@/lib/objectIsEmpty";
|
||||
import { getTime, trainTimeFiltering } from "@/lib/trainTimeFiltering";
|
||||
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||
import { useAreaInfo } from "@/stateBox/useAreaInfo";
|
||||
import { useCurrentTrain } from "@/stateBox/useCurrentTrain";
|
||||
import { useStationList } from "@/stateBox/useStationList";
|
||||
import { useTrainMenu } from "@/stateBox/useTrainMenu";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
|
||||
import { FC, useEffect, useState } from "react";
|
||||
import { LayoutAnimation, Text, TouchableOpacity, View } from "react-native";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
|
||||
type props = {
|
||||
stationID: string;
|
||||
displaySize: number;
|
||||
setDisplaySize: (size: number) => void;
|
||||
};
|
||||
|
||||
export const FixedStation: FC<props> = ({
|
||||
stationID,
|
||||
displaySize,
|
||||
setDisplaySize,
|
||||
}) => {
|
||||
const { mapSwitch } = useTrainMenu();
|
||||
const { currentTrain, setFixedPosition } = useCurrentTrain();
|
||||
const { getStationDataFromId } = useStationList();
|
||||
const { navigate } = useNavigation();
|
||||
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 { allTrainDiagram } = useAllTrainDiagram();
|
||||
const { areaStationID } = useAreaInfo();
|
||||
const [stationDiagram, setStationDiagram] = useState({}); //当該駅の全時刻表
|
||||
const [isInfoArea, setIsInfoArea] = useState(false);
|
||||
|
||||
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<
|
||||
eachTrainDiagramType[]
|
||||
>([]);
|
||||
|
||||
useEffect(() => {
|
||||
//現在の駅に停車する列車から時刻を切り出してLEDベースにフォーマット
|
||||
if (objectIsEmpty(stationDiagram)) return () => {};
|
||||
const getTimeData = getTime(stationDiagram, station[0]);
|
||||
setTrainTimeAndNumber(getTimeData);
|
||||
}, [stationDiagram]);
|
||||
const [selectedTrain, setSelectedTrain] = useState<eachTrainDiagramType[]>(
|
||||
[]
|
||||
);
|
||||
useEffect(() => {
|
||||
if (!trainTimeAndNumber) return () => {};
|
||||
if (!currentTrain) return () => {};
|
||||
const data = trainTimeAndNumber
|
||||
.filter((d) => currentTrain.map((m) => m.num).includes(d.train)) //現在の列車に絞る[ToDo]
|
||||
.filter((d) => trainTimeFiltering({ d, currentTrain, station })) //時間フィルター
|
||||
.filter((d) => !d.isThrough)
|
||||
.filter((d) => d.lastStation != station[0].Station_JP); //最終列車表示設定
|
||||
setSelectedTrain(data);
|
||||
}, [trainTimeAndNumber, currentTrain /*finalSwitch*/]);
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{ display: "flex", flexDirection: "column", flex: 1 }}
|
||||
pointerEvents="box-none"
|
||||
>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: "row",
|
||||
borderBottomColor: lineColor,
|
||||
borderBottomWidth: 2,
|
||||
position: "relative",
|
||||
}}
|
||||
activeOpacity={1}
|
||||
onPress={() => {
|
||||
const payload = {
|
||||
currentStation: station,
|
||||
navigate,
|
||||
goTo: "menu",
|
||||
onExit: () => SheetManager.hide("StationDetailView"),
|
||||
};
|
||||
//@ts-ignore
|
||||
SheetManager.show("StationDetailView", { payload });
|
||||
}}
|
||||
>
|
||||
<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",
|
||||
height: 22,
|
||||
overflow: "hidden",
|
||||
paddingLeft: 5,
|
||||
}}
|
||||
>
|
||||
<StationNumberMaker
|
||||
currentStation={station}
|
||||
singleSize={18}
|
||||
useEach={true}
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 14,
|
||||
textAlignVertical: "center",
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
paddingLeft: 5,
|
||||
flex: 1,
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
{station[0]?.Station_JP}
|
||||
</Text>
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "white",
|
||||
width: 6,
|
||||
borderLeftColor: lineColor,
|
||||
borderTopColor: lineColor,
|
||||
borderBottomColor: "white",
|
||||
borderRightColor: "white",
|
||||
borderBottomWidth: 18,
|
||||
borderLeftWidth: 10,
|
||||
borderRightWidth: 0,
|
||||
borderTopWidth: 5,
|
||||
height: 20,
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
height: "100%",
|
||||
backgroundColor: "white",
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<Text style={{ fontSize: 18 }}>次の発車予定:</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]}
|
||||
displaySize={displaySize}
|
||||
key={d.train + "-fixedStationBox"}
|
||||
/>
|
||||
))
|
||||
) : (
|
||||
<View style={{ backgroundColor: "white", flex: 1 }}>
|
||||
<Text style={{ fontSize: parseInt("11%") }}>
|
||||
当駅を発着する走行中の列車はありません。
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
borderTopColor: lineColor,
|
||||
borderTopWidth: 2,
|
||||
}}
|
||||
pointerEvents="box-none"
|
||||
>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
onPress={() => {
|
||||
setFixedPosition({ type: null, value: null });
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
backgroundColor: lineColor,
|
||||
paddingHorizontal: 5,
|
||||
height: 26,
|
||||
}}
|
||||
>
|
||||
<Ionicons name="lock-closed" size={15} color="white" />
|
||||
<Text
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: 15,
|
||||
paddingRight: 5,
|
||||
}}
|
||||
>
|
||||
駅位置ロック中
|
||||
</Text>
|
||||
<Ionicons name="close" size={15} color="white" />
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "#0000",
|
||||
width: 6,
|
||||
borderLeftColor: lineColor,
|
||||
borderTopColor: lineColor,
|
||||
borderBottomColor: "#0000",
|
||||
borderRightColor: "#0000",
|
||||
borderBottomWidth: 26,
|
||||
borderLeftWidth: 10,
|
||||
borderRightWidth: 0,
|
||||
borderTopWidth: 0,
|
||||
height: 26,
|
||||
}}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
onPress={() => {
|
||||
LayoutAnimation.configureNext({
|
||||
duration: 500,
|
||||
update: { type: "spring", springDamping: 0.7 },
|
||||
});
|
||||
if (displaySize === 226) {
|
||||
setDisplaySize(mapSwitch == "true" ? 76 : 80);
|
||||
} else {
|
||||
setDisplaySize(226);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "#0000",
|
||||
width: 6,
|
||||
borderLeftColor: "#0000",
|
||||
borderTopColor: lineColor,
|
||||
borderBottomColor: "#0000",
|
||||
borderRightColor: lineColor,
|
||||
borderBottomWidth: 26,
|
||||
borderLeftWidth: 0,
|
||||
borderRightWidth: 10,
|
||||
borderTopWidth: 0,
|
||||
height: 26,
|
||||
}}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
backgroundColor: lineColor,
|
||||
paddingHorizontal: 5,
|
||||
height: 26,
|
||||
}}
|
||||
pointerEvents="none"
|
||||
>
|
||||
<Ionicons
|
||||
name={displaySize == 226 ? "chevron-up" : "chevron-down"}
|
||||
size={15}
|
||||
color="white"
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
color: "white",
|
||||
paddingRight: 5,
|
||||
backgroundColor: lineColor,
|
||||
fontSize: 15,
|
||||
}}
|
||||
>
|
||||
{displaySize == 226 ? "時刻表を縮小する" : "時刻表を展開する"}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const FixedStationBoxEachTrain = ({ d, station, displaySize }) => {
|
||||
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 [train, setTrain] = useState<CustomTrainData>(
|
||||
getCurrentTrainData(d.train, currentTrain, allCustomTrainData)
|
||||
);
|
||||
useEffect(() => {
|
||||
setTrain(getCurrentTrainData(d.train, currentTrain, allCustomTrainData));
|
||||
}, [currentTrain, d.train]);
|
||||
const { name, color } = getTrainType({ type: train.type, whiteMode: true });
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "white",
|
||||
flexDirection: "row",
|
||||
height: displaySize == 226 ? "7.5%" : "33%",
|
||||
overflow: "visible",
|
||||
}}
|
||||
>
|
||||
<Text style={{ fontSize: parseInt("11%"), flex: 3 }}>{d.time}</Text>
|
||||
<Text style={{ fontSize: parseInt("11%"), flex: 4, color }}>{name}</Text>
|
||||
<Text style={{ fontSize: parseInt("11%"), flex: 4 }}>
|
||||
{d.lastStation}行
|
||||
</Text>
|
||||
<Text style={{ fontSize: parseInt("11%"), flex: 3 }}>
|
||||
{trainDelayStatus}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
847
components/Apps/FixedPositionBox/FixedTrainBox.tsx
Normal file
847
components/Apps/FixedPositionBox/FixedTrainBox.tsx
Normal file
@@ -0,0 +1,847 @@
|
||||
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<props> = ({
|
||||
trainID,
|
||||
displaySize,
|
||||
setDisplaySize,
|
||||
}) => {
|
||||
const {
|
||||
fixedPosition,
|
||||
setFixedPosition,
|
||||
currentTrain,
|
||||
getCurrentStationData,
|
||||
getPosition,
|
||||
} = useCurrentTrain();
|
||||
|
||||
const { mapSwitch } = useTrainMenu();
|
||||
const { allCustomTrainData, allTrainDiagram } = useAllTrainDiagram();
|
||||
|
||||
const [train, setTrain] = useState<trainDataType>(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);
|
||||
} else {
|
||||
alert("追跡していた列車が消えました。追跡を終了します。");
|
||||
setFixedPosition({ type: null, value: null });
|
||||
}
|
||||
}, [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) => {
|
||||
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, setStopStationList] = useState([]);
|
||||
useEffect(() => {
|
||||
const x = 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;
|
||||
});
|
||||
setStopStationList(x);
|
||||
}, [trainDataWidhThrough]);
|
||||
const [currentPosition, setCurrentPosition] = useState<string[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
let position = getPosition(train);
|
||||
if (stopStationIDList.length == 0) return;
|
||||
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,stopStationIDList]);
|
||||
|
||||
const [nextStationData, setNextStationData] = useState<StationProps[]>([]);
|
||||
const [untilStationData, setUntilStationData] = useState<StationProps[]>([]);
|
||||
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<StationProps[]>([]);
|
||||
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 (
|
||||
<View
|
||||
style={{ display: "flex", flexDirection: "column", flex: 1 }}
|
||||
pointerEvents="box-none"
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: displaySize === 226 ? "column" : "row",
|
||||
backgroundColor: "black",
|
||||
//borderBottomColor: "black",
|
||||
//borderBottomWidth: 2,
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: displaySize === 226 ? "row" : "column",
|
||||
flex: 1,
|
||||
backgroundColor: "white",
|
||||
height: displaySize === 226 ? 200 : 50,
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{ flex: displaySize === 226 ? 5 : 1, flexDirection: "row" }}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: customTrainType.color,
|
||||
flexDirection: "row",
|
||||
alignContent: "center",
|
||||
alignSelf: "center",
|
||||
alignItems: "center",
|
||||
height: "100%",
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
source={{ uri: customData.img }}
|
||||
width={displaySize === 226 ? 23 : 14}
|
||||
height={displaySize === 226 ? 26 : 17}
|
||||
style={{ margin: 5 }}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: displaySize === 226 ? "column" : "row",
|
||||
alignContent: "center",
|
||||
alignSelf: "center",
|
||||
alignItems: "center",
|
||||
maxWidth: displaySize === 226 ? 80 : 100,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: trainNameText.length > 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}
|
||||
</Text>
|
||||
{customData.trainName && (
|
||||
<Text
|
||||
style={{
|
||||
fontSize: trainNameText.length > 4 ? 8 : 14,
|
||||
color: "white",
|
||||
maxWidth: displaySize === 226 ? 200 : 60,
|
||||
textAlignVertical: "center",
|
||||
}}
|
||||
>
|
||||
{trainNameText}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: customTrainType.color,
|
||||
width: 10,
|
||||
borderLeftColor: customTrainType.color,
|
||||
borderTopColor: lineColor,
|
||||
borderBottomColor: lineColor,
|
||||
borderTopWidth: displaySize === 226 ? 50 : 14,
|
||||
borderBottomWidth: displaySize === 226 ? 50 : 14,
|
||||
borderLeftWidth: displaySize === 226 ? 30 : 10,
|
||||
borderRightWidth: 0,
|
||||
//height: displaySize === 226 ? 20 : 100,
|
||||
height: "100%",
|
||||
}}
|
||||
></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={18}
|
||||
useEach={true}
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: customData?.ToData?.length > 4 ? 9 : 12,
|
||||
color: "white",
|
||||
fontWeight: "bold",
|
||||
textAlignVertical: "center",
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
height: "100%",
|
||||
}}
|
||||
>
|
||||
{ToData}行
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
{displaySize === 226 && (
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "white",
|
||||
width: 10,
|
||||
borderLeftColor: "black",
|
||||
borderTopColor: lineColor,
|
||||
borderBottomColor: "white",
|
||||
borderRightColor: "black",
|
||||
borderTopWidth: 50,
|
||||
borderBottomWidth: 0,
|
||||
borderLeftWidth: 0,
|
||||
borderRightWidth: 20,
|
||||
}}
|
||||
></View>
|
||||
)}
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "black",
|
||||
flex: displaySize === 226 ? 4 : 1,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<View style={{ flexDirection: "column" }}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 10,
|
||||
fontWeight: "bold",
|
||||
color: "white",
|
||||
marginHorizontal: 5,
|
||||
paddingVertical: 0,
|
||||
marginVertical: -1,
|
||||
}}
|
||||
>
|
||||
{nextStationData[0]?.Station_JP == train?.Pos
|
||||
? "ただいま"
|
||||
: "次は"}
|
||||
</Text>
|
||||
{probably && (
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 5,
|
||||
color: "white",
|
||||
fontWeight: "bold",
|
||||
marginHorizontal: 5,
|
||||
paddingVertical: 0,
|
||||
marginVertical: -1,
|
||||
}}
|
||||
>
|
||||
(時刻推定)
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
<StationNumberMaker
|
||||
currentStation={nextStationData}
|
||||
singleSize={20}
|
||||
useEach={true}
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 18,
|
||||
fontWeight: "bold",
|
||||
color: "white",
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
{nextStationData[0]?.Station_JP || "不明"}
|
||||
</Text>
|
||||
{displaySize !== 226 && (
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "white",
|
||||
width: 10,
|
||||
borderLeftColor: "black",
|
||||
borderTopColor: "black",
|
||||
borderBottomColor: "white",
|
||||
borderRightColor: "white",
|
||||
borderTopWidth: 21,
|
||||
borderBottomWidth: 0,
|
||||
borderLeftWidth: 0,
|
||||
borderRightWidth: 7,
|
||||
}}
|
||||
></View>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
<CurrentPositionBox
|
||||
train={train}
|
||||
lineColor={lineColor}
|
||||
trainDataWithThrough={untilStationData}
|
||||
isSmall={displaySize !== 226}
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
borderTopColor: "black",
|
||||
borderTopWidth: 2,
|
||||
}}
|
||||
pointerEvents="box-none"
|
||||
>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
onPress={() => {
|
||||
setFixedPosition({ type: null, value: null });
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
backgroundColor: "black",
|
||||
paddingHorizontal: 5,
|
||||
height: 26,
|
||||
}}
|
||||
>
|
||||
<Ionicons name="lock-closed" size={15} color="white" />
|
||||
<Text
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: 15,
|
||||
paddingRight: 5,
|
||||
}}
|
||||
>
|
||||
列車追跡中
|
||||
</Text>
|
||||
<Ionicons name="close" size={15} color="white" />
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "#0000",
|
||||
width: 6,
|
||||
borderLeftColor: "black",
|
||||
borderTopColor: "black",
|
||||
borderBottomColor: "#0000",
|
||||
borderRightColor: "#0000",
|
||||
borderBottomWidth: 26,
|
||||
borderLeftWidth: 10,
|
||||
borderRightWidth: 0,
|
||||
borderTopWidth: 0,
|
||||
height: 26,
|
||||
}}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
}}
|
||||
onPress={() => {
|
||||
LayoutAnimation.configureNext({
|
||||
duration: 200,
|
||||
update: { type: "easeInEaseOut", springDamping: 0.4 },
|
||||
});
|
||||
if (displaySize === 226) {
|
||||
setDisplaySize(mapSwitch == "true" ? 76 : 80);
|
||||
} else {
|
||||
setDisplaySize(226);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "#0000",
|
||||
width: 6,
|
||||
borderLeftColor: "#0000",
|
||||
borderTopColor: "black",
|
||||
borderBottomColor: "#0000",
|
||||
borderRightColor: "black",
|
||||
borderBottomWidth: 26,
|
||||
borderLeftWidth: 0,
|
||||
borderRightWidth: 10,
|
||||
borderTopWidth: 0,
|
||||
height: 26,
|
||||
}}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
backgroundColor: "black",
|
||||
paddingHorizontal: 5,
|
||||
height: 26,
|
||||
}}
|
||||
>
|
||||
<Ionicons
|
||||
name={displaySize == 226 ? "chevron-up" : "chevron-down"}
|
||||
size={15}
|
||||
color="white"
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
color: "white",
|
||||
paddingRight: 5,
|
||||
backgroundColor: "black",
|
||||
fontSize: 15,
|
||||
}}
|
||||
>
|
||||
{displaySize == 226 ? "列車情報縮小" : "列車情報展開"}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
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 (
|
||||
<View
|
||||
style={{
|
||||
flex: isSmall ? 1 : 3,
|
||||
backgroundColor: "white",
|
||||
flexDirection: "row",
|
||||
}}
|
||||
>
|
||||
{isSmall && (
|
||||
<View style={{ flexDirection: "column" }}>
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "white",
|
||||
width: 10,
|
||||
borderLeftColor: lineColor,
|
||||
borderTopColor: lineColor,
|
||||
borderBottomColor: "white",
|
||||
borderRightColor: "white",
|
||||
borderTopWidth: 28,
|
||||
borderBottomWidth: 0,
|
||||
borderLeftWidth: 0,
|
||||
borderRightWidth: 10,
|
||||
}}
|
||||
></View>
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "white",
|
||||
width: 10,
|
||||
borderLeftColor: "white",
|
||||
borderTopColor: "white",
|
||||
borderBottomColor: "white",
|
||||
borderRightColor: "white",
|
||||
borderTopWidth: 18,
|
||||
borderBottomWidth: 0,
|
||||
borderLeftWidth: 0,
|
||||
borderRightWidth: 10,
|
||||
}}
|
||||
></View>
|
||||
</View>
|
||||
)}
|
||||
<ScrollView
|
||||
style={{ flex: 1, flexDirection: "row" }}
|
||||
horizontal
|
||||
overScrollMode="always"
|
||||
>
|
||||
{trainDataWithThrough.length > 0 &&
|
||||
trainDataWithThrough.map((d, index) => (
|
||||
<EachStopData
|
||||
d={d}
|
||||
index={index}
|
||||
key={d}
|
||||
delayTime={delayTime}
|
||||
isSmall={isSmall}
|
||||
secondText={secondText}
|
||||
/>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
type eachStopType = {
|
||||
d: string;
|
||||
delayTime: number;
|
||||
isSmall: boolean;
|
||||
index: number;
|
||||
secondText: string;
|
||||
};
|
||||
|
||||
const EachStopData: FC<eachStopType> = (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 (
|
||||
<>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "column",
|
||||
backgroundColor: se.includes("通") ? "#6e6e6e77" : "#6e6e6eff",
|
||||
borderRadius: 30,
|
||||
marginHorizontal: isSmall ? 2 : 4,
|
||||
marginVertical: isSmall ? 0 : 2,
|
||||
padding: isSmall ? 2 : 4,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
key={d + "CurrentPositionBox"}
|
||||
>
|
||||
{station.split("").map((i, index, array) => {
|
||||
return (
|
||||
<Text
|
||||
key={i + index}
|
||||
style={{
|
||||
fontSize:
|
||||
array.length < 5 ? (isSmall ? 5 : 12) : isSmall ? 3 : 10,
|
||||
color: "white",
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{i}
|
||||
</Text>
|
||||
);
|
||||
})}
|
||||
<View style={{ flex: 1 }} />
|
||||
{isSmall ||
|
||||
(time != "" && (
|
||||
<Text
|
||||
style={{
|
||||
fontSize: isSmall ? 8 : 12,
|
||||
color: "black",
|
||||
backgroundColor: "white",
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{distanceMinute}
|
||||
</Text>
|
||||
))}
|
||||
<Text
|
||||
style={{
|
||||
fontSize: isSmall ? 8 : 14,
|
||||
color:
|
||||
index == 1 && secondText == ""
|
||||
? "#ffe852ff"
|
||||
: se.includes("通")
|
||||
? "#020202ff"
|
||||
: "white",
|
||||
marginTop: isSmall ? 0 : 3,
|
||||
height: isSmall ? "auto" : 17,
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{index == 1 && secondText == ""
|
||||
? "→"
|
||||
: se.includes("通")
|
||||
? null
|
||||
: "●"}
|
||||
</Text>
|
||||
</View>
|
||||
{index == 0 && secondText != "" && (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "column",
|
||||
backgroundColor: "#0000",
|
||||
borderRadius: 10,
|
||||
marginHorizontal: isSmall ? 2 : 4,
|
||||
padding: isSmall ? 2 : 4,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Ionicons
|
||||
name="arrow-forward"
|
||||
size={isSmall ? 8 : 14}
|
||||
color="black"
|
||||
style={{ marginTop: isSmall ? 0 : 3 }}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
@@ -37,6 +37,7 @@ export const MapsButton: FC<MapsButtonProps> = ({ onPress }) => {
|
||||
alignSelf: "center",
|
||||
alignItems: "center",
|
||||
display: mapSwitch == "true" ? "flex" : "none",
|
||||
zIndex: 1000,
|
||||
},
|
||||
text: {
|
||||
textAlign: "center",
|
||||
|
@@ -38,6 +38,7 @@ export const ReloadButton:FC<ReloadButton> = ({ onPress, right }) => {
|
||||
alignSelf: "center",
|
||||
alignItems: "center",
|
||||
display: mapSwitch,
|
||||
zIndex: 1000,
|
||||
},
|
||||
text: {
|
||||
textAlign: "center",
|
||||
|
@@ -23,7 +23,8 @@ export const AppsWebView = ({ openStationACFromEachTrainInfo }) => {
|
||||
const { navigate } = useNavigation();
|
||||
const { favoriteStation } = useFavoriteStation();
|
||||
const { isLandscape } = useDeviceOrientationChange();
|
||||
const { originalStationList, stationList, getInjectJavascriptAddress } = useStationList();
|
||||
const { originalStationList, stationList, getInjectJavascriptAddress } =
|
||||
useStationList();
|
||||
const {
|
||||
setSelectedLine,
|
||||
mapsStationData: stationData,
|
||||
@@ -51,7 +52,6 @@ export const AppsWebView = ({ openStationACFromEachTrainInfo }) => {
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const onMessage = (event) => {
|
||||
const { data } = event.nativeEvent;
|
||||
/**
|
||||
@@ -137,7 +137,9 @@ export const AppsWebView = ({ openStationACFromEachTrainInfo }) => {
|
||||
if (!stationData) return () => {};
|
||||
if (!originalStationList) return () => {};
|
||||
if (favoriteStation.length < 1) return () => {};
|
||||
const string = getInjectJavascriptAddress(favoriteStation[0][0].StationNumber);
|
||||
const string = getInjectJavascriptAddress(
|
||||
favoriteStation[0][0].StationNumber
|
||||
);
|
||||
if (!string) return () => {};
|
||||
webview?.current.injectJavaScript(string);
|
||||
once = true;
|
||||
|
@@ -159,7 +159,7 @@ export const DynamicHeaderScrollView = (props) => {
|
||||
ref={scrollHandlers.ref}
|
||||
onLayout={scrollHandlers.onLayout}
|
||||
scrollEventThrottle={scrollHandlers.scrollEventThrottle}
|
||||
style={{ backgroundColor: "white", zIndex: 0 }}
|
||||
style={{ zIndex: 0 }}
|
||||
stickyHeaderIndices={[1]}
|
||||
onScroll={onScroll}
|
||||
>
|
||||
|
@@ -53,6 +53,7 @@ export const FavoriteList: FC = () => {
|
||||
goBack();
|
||||
if (canGoBack()) goBack();
|
||||
}}
|
||||
key={currentStation[0].StationNumber + "FavoriteList"}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
|
@@ -52,22 +52,6 @@ export const FixedContentBottom = (props) => {
|
||||
旅行ツアー
|
||||
</TicketBox>
|
||||
</View>
|
||||
<TextBox
|
||||
backgroundColor="red"
|
||||
flex={1}
|
||||
onPressButton={() =>
|
||||
Linking.openURL(
|
||||
"https://xprocess.haruk.in/JR-shikoku-Apps-Common/2025-update-status"
|
||||
)
|
||||
}
|
||||
>
|
||||
<Text style={{ color: "white", fontWeight: "bold", fontSize: 20 }}>
|
||||
【ダイヤ改正に伴うデータ更新状況】
|
||||
</Text>
|
||||
<Text style={{ color: "white", fontSize: 18 }}>
|
||||
ダイヤ改正に伴うデータの更新状況を随時更新します。
|
||||
</Text>
|
||||
</TextBox>
|
||||
<TextBox
|
||||
backgroundColor="#ed86b5"
|
||||
flex={1}
|
||||
@@ -213,6 +197,19 @@ export const FixedContentBottom = (props) => {
|
||||
</Text>
|
||||
</TextBox>
|
||||
<Text style={{ fontWeight: "bold", fontSize: 20 }}>その他</Text>
|
||||
<TextBox
|
||||
backgroundColor="rgb(88, 101, 242)"
|
||||
flex={1}
|
||||
onPressButton={() => Linking.openURL("https://twitter.com/Xprocess_main/status/1955242437817012300")}
|
||||
|
||||
>
|
||||
<Text style={{ color: "white", fontWeight: "bold", fontSize: 20 }}>
|
||||
公式Discordのご案内
|
||||
</Text>
|
||||
<Text style={{ color: "white", fontSize: 18 }}>
|
||||
皆さんの目撃情報をアプリに反映しませんか?Discordに登録して運用を報告しましょう!
|
||||
</Text>
|
||||
</TextBox>
|
||||
<TextBox
|
||||
backgroundColor="linear-gradient(120deg, rgba(247,135,54,0.208) 0%, rgba(54,125,247,0.208) 100%)"
|
||||
flex={1}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { FC, useEffect, useLayoutEffect, useState } from "react";
|
||||
import { FC, useLayoutEffect, useState } from "react";
|
||||
import { View, Text, TouchableOpacity } from "react-native";
|
||||
import { getPDFViewURL } from "@/lib/getPdfViewURL";
|
||||
import { ScrollView, SheetManager } from "react-native-actions-sheet";
|
||||
@@ -6,20 +6,27 @@ import { ScrollView, SheetManager } from "react-native-actions-sheet";
|
||||
type props = {
|
||||
navigate: (screen: string, params?: object) => void;
|
||||
};
|
||||
type specialDataType = { address: string; text: string; description: string };
|
||||
|
||||
export const SpecialTrainInfoBox: FC<props> = ({ navigate }) => {
|
||||
const [specialData, setSpecialData] = useState([]);
|
||||
const [specialData, setSpecialData] = useState<specialDataType[]>([]);
|
||||
useLayoutEffect(() => {
|
||||
fetch("https://n8n.haruk.in/webhook/sptrainfo")
|
||||
.then((res) => res.json())
|
||||
.then((data) => setSpecialData(data.data))
|
||||
.catch((err) => console.log(err));
|
||||
}, []);
|
||||
|
||||
const onPressItem: (d: specialDataType) => void = (d) => {
|
||||
navigate("howto", {
|
||||
info: getPDFViewURL("https://www.jr-shikoku.co.jp" + d.address),
|
||||
goTo: "menu",
|
||||
});
|
||||
SheetManager.hide("SpecialTrainInfo");
|
||||
};
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "#0099CC",
|
||||
}}
|
||||
>
|
||||
<View style={{ backgroundColor: "#0099CC" }}>
|
||||
<View style={{ flexDirection: "row", alignItems: "center" }}>
|
||||
<Text
|
||||
style={{
|
||||
@@ -33,20 +40,10 @@ export const SpecialTrainInfoBox: FC<props> = ({ navigate }) => {
|
||||
臨時列車情報
|
||||
</Text>
|
||||
</View>
|
||||
<ScrollView
|
||||
style={{
|
||||
backgroundColor: "white",
|
||||
}}
|
||||
>
|
||||
<ScrollView style={{ backgroundColor: "white" }}>
|
||||
{specialData.map((d) => (
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
navigate("howto", {
|
||||
info: getPDFViewURL("https://www.jr-shikoku.co.jp" + d.address),
|
||||
goTo: "menu",
|
||||
});
|
||||
SheetManager.hide("SpecialTrainInfo");
|
||||
}}
|
||||
onPress={() => onPressItem(d)}
|
||||
onLongPress={() => alert(d.description)}
|
||||
key={d.address}
|
||||
style={{
|
||||
|
@@ -1,22 +1,9 @@
|
||||
import React, { FC, useState } from "react";
|
||||
import { View, Text, TouchableOpacity } from "react-native";
|
||||
import { useInterval } from "../../lib/useInterval";
|
||||
import { useInterval } from "@/lib/useInterval";
|
||||
|
||||
import lineColorList from "../../assets/originData/lineColorList";
|
||||
|
||||
type StationProps = {
|
||||
DispNum: string;
|
||||
JrHpUrl: string;
|
||||
MyStation: string;
|
||||
StationMap: string;
|
||||
StationNumber: string | null;
|
||||
StationTimeTable: string;
|
||||
Station_EN: string;
|
||||
Station_JP: string;
|
||||
jslodApi: string;
|
||||
lat: number;
|
||||
lng: number;
|
||||
};
|
||||
import lineColorList from "@/assets/originData/lineColorList";
|
||||
import { StationProps } from "@/lib/CommonTypes";
|
||||
type StationNumberProps = {
|
||||
currentStation: StationProps[];
|
||||
active: boolean;
|
||||
|
@@ -17,7 +17,7 @@ import { SwitchArea } from "../atom/SwitchArea";
|
||||
import { useNotification } from "../../stateBox/useNotifications";
|
||||
import { SheetHeaderItem } from "@/components/atom/SheetHeaderItem";
|
||||
|
||||
const versionCode = "6.1.1"; // Update this version code as needed
|
||||
const versionCode = "6.1.8"; // Update this version code as needed
|
||||
|
||||
export const SettingTopPage = ({
|
||||
testNFC,
|
||||
|
355
components/StationDiagram/ExGridView.tsx
Normal file
355
components/StationDiagram/ExGridView.tsx
Normal file
@@ -0,0 +1,355 @@
|
||||
import { FC, useRef, useState, useCallback, useEffect } from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
ScrollView,
|
||||
useWindowDimensions,
|
||||
Vibration,
|
||||
} from "react-native";
|
||||
import { ExGridViewItem } from "./ExGridViewItem";
|
||||
import Animated, {
|
||||
useAnimatedStyle,
|
||||
useSharedValue,
|
||||
runOnJS,
|
||||
useAnimatedScrollHandler,
|
||||
withTiming,
|
||||
Easing,
|
||||
FadeIn,
|
||||
FadeOut,
|
||||
BounceInUp,
|
||||
FadeInUp,
|
||||
FadeOutUp,
|
||||
} from "react-native-reanimated";
|
||||
import { Gesture, GestureDetector } from "react-native-gesture-handler";
|
||||
import { ExGridViewTimePositionItem } from "./ExGridViewTimePositionItem";
|
||||
import { useCurrentTrain } from "@/stateBox/useCurrentTrain";
|
||||
import dayjs from "dayjs";
|
||||
type hoge = {
|
||||
trainNumber: string;
|
||||
array: string;
|
||||
name: string;
|
||||
timeType: string;
|
||||
time: string;
|
||||
}[];
|
||||
export const ExGridView: FC<{
|
||||
data: hoge;
|
||||
}> = ({ data }) => {
|
||||
const groupedData: {
|
||||
[d: number]: {
|
||||
trainNumber: string;
|
||||
array: string;
|
||||
name: string;
|
||||
timeType: string;
|
||||
time: string;
|
||||
isOperating: boolean;
|
||||
}[];
|
||||
} = {
|
||||
"4": [],
|
||||
"5": [],
|
||||
"6": [],
|
||||
"7": [],
|
||||
"8": [],
|
||||
"9": [],
|
||||
"10": [],
|
||||
"11": [],
|
||||
"12": [],
|
||||
"13": [],
|
||||
"14": [],
|
||||
"15": [],
|
||||
"16": [],
|
||||
"17": [],
|
||||
"18": [],
|
||||
"19": [],
|
||||
"20": [],
|
||||
"21": [],
|
||||
"22": [],
|
||||
"23": [],
|
||||
"0": [],
|
||||
"1": [],
|
||||
"2": [],
|
||||
"3": [],
|
||||
};
|
||||
const groupKeys = [
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"10",
|
||||
"11",
|
||||
"12",
|
||||
"13",
|
||||
"14",
|
||||
"15",
|
||||
"16",
|
||||
"17",
|
||||
"18",
|
||||
"19",
|
||||
"20",
|
||||
"21",
|
||||
"22",
|
||||
"23",
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
];
|
||||
|
||||
const { width } = useWindowDimensions();
|
||||
const { currentTrain } = useCurrentTrain();
|
||||
data.forEach((item) => {
|
||||
let isOperating = false;
|
||||
let [hour, minute] = dayjs()
|
||||
.hour(parseInt(item.time.split(":")[0]))
|
||||
.minute(parseInt(item.time.split(":")[1]))
|
||||
.format("H:m")
|
||||
.split(":");
|
||||
if (currentTrain.findIndex((x) => x.num == item.trainNumber) != -1) {
|
||||
const currentTrainTime = currentTrain.find(
|
||||
(x) => x.num == item.trainNumber
|
||||
)?.delay;
|
||||
if (currentTrainTime != "入線") {
|
||||
[hour, minute] = dayjs()
|
||||
.hour(parseInt(hour))
|
||||
.minute(parseInt(minute))
|
||||
.add(parseInt(currentTrainTime), "minute")
|
||||
.format("H:m")
|
||||
.split(":");
|
||||
}
|
||||
isOperating = true;
|
||||
}
|
||||
groupedData[hour].push({ ...item, time: `${hour}:${minute}`, isOperating });
|
||||
});
|
||||
// ドラッグ位置を保持する共有値
|
||||
const widthX = useSharedValue(width);
|
||||
const savedWidthX = useSharedValue(width);
|
||||
const isChanging = useSharedValue(false);
|
||||
const [scrollEnabled, setScrollEnabled] = useState(true);
|
||||
const scrollRef = useRef<Animated.ScrollView>(null);
|
||||
const scrollRef2 = useRef<Animated.ScrollView>(null);
|
||||
|
||||
// ScrollViewの有効/無効を切り替える関数
|
||||
const toggleScrollEnabled = useCallback((enabled: boolean) => {
|
||||
setScrollEnabled(enabled);
|
||||
}, []);
|
||||
|
||||
// パンジェスチャー(ドラッグ)のハンドラー
|
||||
const pinchGesture = Gesture.Pinch()
|
||||
.onUpdate((e) => {
|
||||
const calc = savedWidthX.value * e.scale;
|
||||
widthX.value = calc > width ? calc : width;
|
||||
//runOnJS(scrollToRightEnd)();
|
||||
})
|
||||
.onEnd(() => {
|
||||
savedWidthX.value = widthX.value;
|
||||
});
|
||||
|
||||
const gesture = Gesture.Pan()
|
||||
.minPointers(2) // 最低2本指
|
||||
.maxPointers(2) // 最大2本指
|
||||
.onStart(() => {
|
||||
runOnJS(toggleScrollEnabled)(false);
|
||||
})
|
||||
.onEnd(() => {
|
||||
runOnJS(toggleScrollEnabled)(true);
|
||||
savedWidthX.value = widthX.value;
|
||||
});
|
||||
const longPressGesture = Gesture.Pan()
|
||||
.minPointers(1)
|
||||
.maxPointers(1)
|
||||
.activateAfterLongPress(200)
|
||||
.onStart(() => {
|
||||
runOnJS(Vibration.vibrate)(30);
|
||||
isChanging.value = true;
|
||||
})
|
||||
.onUpdate((e) => {
|
||||
const calc = widthX.value + e.velocityY;
|
||||
widthX.value = calc > width ? calc : width;
|
||||
})
|
||||
.onEnd(() => {
|
||||
console.log("Long press ended");
|
||||
isChanging.value = false;
|
||||
});
|
||||
|
||||
// ジェスチャーを組み合わせる
|
||||
const composed = Gesture.Simultaneous(
|
||||
longPressGesture,
|
||||
pinchGesture,
|
||||
gesture
|
||||
);
|
||||
|
||||
// アニメーションスタイル
|
||||
const animatedStyle = useAnimatedStyle(() => ({
|
||||
width: widthX.value,
|
||||
backgroundColor: isChanging.value ? "#8adeffff" : "white",
|
||||
}));
|
||||
// 時ヘッダーを横にスクロールしたときの処理
|
||||
const scrollX = useSharedValue(0);
|
||||
const scrollHandler = useAnimatedScrollHandler({
|
||||
onScroll: (event) => {
|
||||
scrollX.value = event.contentOffset.x;
|
||||
},
|
||||
});
|
||||
const stickyTextStyle = useAnimatedStyle(() => ({
|
||||
transform: [{ translateX: scrollX.value }],
|
||||
}));
|
||||
const animatedLongPressStyle = useAnimatedStyle(() => ({
|
||||
display: isChanging.value ? "flex" : "none",
|
||||
}));
|
||||
useEffect(() => {
|
||||
const getCurrentTime = dayjs().hour();
|
||||
setTimeout(() => {
|
||||
const keyTime =
|
||||
getCurrentTime - 4 <= 0 ? getCurrentTime + 24 : getCurrentTime;
|
||||
const goTo = keyTime * 60;
|
||||
if (goTo > 400) {
|
||||
scrollRef2.current?.scrollTo({ y: goTo - 300, animated: true });
|
||||
}
|
||||
}, 400);
|
||||
}, [scrollRef2]);
|
||||
return (
|
||||
<>
|
||||
<Animated.View
|
||||
style={[
|
||||
{
|
||||
position: "absolute",
|
||||
width,
|
||||
backgroundColor: "#26d1baff",
|
||||
zIndex: 500,
|
||||
top: 0,
|
||||
},
|
||||
animatedLongPressStyle,
|
||||
]}
|
||||
entering={FadeInUp}
|
||||
exiting={FadeOutUp}
|
||||
>
|
||||
<Text style={{ fontSize: 30, textAlign: "center", flex: 1 }}>
|
||||
↑縮小 ・ 拡大↓
|
||||
</Text>
|
||||
</Animated.View>
|
||||
<GestureDetector gesture={composed}>
|
||||
<Animated.ScrollView
|
||||
horizontal
|
||||
nestedScrollEnabled
|
||||
pinchGestureEnabled={false}
|
||||
scrollEnabled={scrollEnabled}
|
||||
onScroll={scrollHandler}
|
||||
onContentSizeChange={(contentWidth) => {
|
||||
// 現在のスクロール位置を取得
|
||||
const currentScrollX = scrollX.value;
|
||||
const containerWidth = width - 50;
|
||||
|
||||
// コンテンツが画面からはみ出している場合のみ右端にスクロール
|
||||
if (currentScrollX + containerWidth > contentWidth) {
|
||||
const newScrollX = Math.max(0, contentWidth - containerWidth);
|
||||
scrollRef.current?.scrollTo({ x: newScrollX, animated: true });
|
||||
}
|
||||
}}
|
||||
ref={scrollRef}
|
||||
contentContainerStyle={{
|
||||
flexDirection: "column",
|
||||
backgroundColor: "white",
|
||||
}}
|
||||
>
|
||||
<Animated.View
|
||||
style={[
|
||||
{
|
||||
width: width,
|
||||
flexDirection: "row",
|
||||
},
|
||||
animatedStyle,
|
||||
]}
|
||||
>
|
||||
{Array.from({ length: 60 }, (_, i) => i + 1).map((num) => {
|
||||
if (num % 5 === 0) {
|
||||
return (
|
||||
<Text
|
||||
key={num + "ExGridViewTimeLabel"}
|
||||
style={{
|
||||
flex: 1,
|
||||
textAlign: "left",
|
||||
borderRightWidth: 0.5,
|
||||
borderColor: "#ccc",
|
||||
flexWrap: "nowrap",
|
||||
fontSize: 12,
|
||||
}}
|
||||
>
|
||||
{num - 5}
|
||||
</Text>
|
||||
);
|
||||
} else return <></>;
|
||||
})}
|
||||
<Text
|
||||
style={{
|
||||
textAlign: "right",
|
||||
borderRightWidth: 0.5,
|
||||
borderColor: "#ccc",
|
||||
flexWrap: "nowrap",
|
||||
fontSize: 12,
|
||||
width: 50,
|
||||
}}
|
||||
>
|
||||
(分)
|
||||
</Text>
|
||||
</Animated.View>
|
||||
<Animated.ScrollView
|
||||
style={[{ width: width }, animatedStyle]}
|
||||
pinchGestureEnabled={false}
|
||||
minimumZoomScale={0.5}
|
||||
maximumZoomScale={3.0}
|
||||
scrollEnabled={scrollEnabled}
|
||||
stickyHeaderIndices={
|
||||
groupKeys.at(0) ? groupKeys.map((_, i) => i * 2) : []
|
||||
}
|
||||
ref={scrollRef2}
|
||||
>
|
||||
{groupKeys.map((hour) => [
|
||||
<View
|
||||
style={{
|
||||
padding: 5,
|
||||
borderBottomWidth: 0.5,
|
||||
borderTopWidth: 0.5,
|
||||
borderBottomColor: "#ccc",
|
||||
backgroundColor: "#f0f0f0",
|
||||
}}
|
||||
key={hour}
|
||||
>
|
||||
<Animated.Text
|
||||
style={[
|
||||
{
|
||||
fontSize: 15,
|
||||
zIndex: 1,
|
||||
marginLeft: 0,
|
||||
},
|
||||
stickyTextStyle,
|
||||
]}
|
||||
>
|
||||
{hour}時台
|
||||
</Animated.Text>
|
||||
</View>,
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
position: "relative",
|
||||
height: 50,
|
||||
}}
|
||||
>
|
||||
{groupedData[hour].map((d, i, array) => (
|
||||
<ExGridViewItem
|
||||
key={d.trainNumber + i}
|
||||
d={d}
|
||||
index={i}
|
||||
width={widthX}
|
||||
array={array}
|
||||
/>
|
||||
))}
|
||||
<ExGridViewTimePositionItem width={widthX} hour={hour} />
|
||||
</View>,
|
||||
])}
|
||||
</Animated.ScrollView>
|
||||
</Animated.ScrollView>
|
||||
</GestureDetector>
|
||||
</>
|
||||
);
|
||||
};
|
254
components/StationDiagram/ExGridViewItem.tsx
Normal file
254
components/StationDiagram/ExGridViewItem.tsx
Normal file
@@ -0,0 +1,254 @@
|
||||
import { migrateTrainName } from "@/lib/eachTrainInfoCoreLib/migrateTrainName";
|
||||
import { getStringConfig } from "@/lib/getStringConfig";
|
||||
import { getTrainType } from "@/lib/getTrainType";
|
||||
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||
import { FC, useEffect, useLayoutEffect, useMemo, useState } from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
useWindowDimensions,
|
||||
} from "react-native";
|
||||
import { customTrainDataDetector } from "../custom-train-data";
|
||||
import dayjs from "dayjs";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { lineList } from "@/lib/getStationList";
|
||||
import { useStationList } from "@/stateBox/useStationList";
|
||||
import { SharedValue, useAnimatedStyle } from "react-native-reanimated";
|
||||
import Animated from "react-native-reanimated";
|
||||
import lineColorList from "@/assets/originData/lineColorList";
|
||||
import { CustomTrainData, trainTypeID } from "@/lib/CommonTypes";
|
||||
|
||||
export const ExGridViewItem: FC<{
|
||||
d: {
|
||||
trainNumber: string;
|
||||
array: string;
|
||||
name: string;
|
||||
timeType: string;
|
||||
time: string;
|
||||
isOperating: boolean;
|
||||
};
|
||||
index: number;
|
||||
width: SharedValue<number>;
|
||||
array: {
|
||||
train: string;
|
||||
lastStation: string;
|
||||
time: string;
|
||||
isThrough?: boolean;
|
||||
}[];
|
||||
}> = ({ d, index, width, array }) => {
|
||||
const { allCustomTrainData } = useAllTrainDiagram();
|
||||
const { originalStationList, stationList } = useStationList();
|
||||
const { navigate, goBack } = useNavigation();
|
||||
const [trainData, setTrainData] = useState<CustomTrainData>();
|
||||
useEffect(() => {
|
||||
if (allCustomTrainData) {
|
||||
allCustomTrainData.forEach((x) => {
|
||||
if (x.TrainNumber === d.trainNumber) {
|
||||
setTrainData(x);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
const { color, name, data } = getTrainType({ type: trainData?.type, whiteMode: true });
|
||||
// 列車名、種別、フォントの取得
|
||||
const [
|
||||
typeString,
|
||||
trainName,
|
||||
fontAvailable,
|
||||
isOneMan,
|
||||
infogram,
|
||||
isEdit,
|
||||
uwasa,
|
||||
vehicleFormation,
|
||||
trainInfoUrl,
|
||||
] = useMemo(() => {
|
||||
const {
|
||||
type,
|
||||
trainName,
|
||||
trainNumDistance,
|
||||
infogram,
|
||||
isEdit,
|
||||
uwasa,
|
||||
vehicleFormation,
|
||||
trainInfoUrl,
|
||||
} = customTrainDataDetector(d.trainNumber, allCustomTrainData);
|
||||
const [typeString, fontAvailable, isOneMan] = getStringConfig(
|
||||
type,
|
||||
d.trainNumber
|
||||
);
|
||||
const trainData = d.array.split("#").filter((d) => d !== "");
|
||||
switch (true) {
|
||||
case trainData[trainData.length - 1] === undefined:
|
||||
return [
|
||||
typeString,
|
||||
"",
|
||||
fontAvailable,
|
||||
isOneMan,
|
||||
infogram,
|
||||
isEdit,
|
||||
uwasa,
|
||||
vehicleFormation,
|
||||
trainInfoUrl,
|
||||
];
|
||||
default:
|
||||
// 行先がある場合は、行先を取得
|
||||
const trainName = (d.timeType == "着" || d.timeType == "着編") ? trainData[0].split(",")[0] : trainData[trainData.length - 1].split(",")[0]
|
||||
return [
|
||||
typeString,
|
||||
migrateTrainName(trainName),
|
||||
fontAvailable,
|
||||
isOneMan,
|
||||
infogram,
|
||||
isEdit,
|
||||
uwasa,
|
||||
vehicleFormation,
|
||||
trainInfoUrl,
|
||||
];
|
||||
}
|
||||
}, [d.array]);
|
||||
const timeArray = d.time.split(":").map((s) => parseInt(s));
|
||||
const formattedTime = dayjs()
|
||||
.set("hour", timeArray[0])
|
||||
.set("minute", timeArray[1])
|
||||
.format("m");
|
||||
let isSameTimeBefore = false;
|
||||
if (index > 0) {
|
||||
const beforeItem = array[index - 1];
|
||||
const beforeTimeArray = beforeItem.time.split(":").map((s) => parseInt(s));
|
||||
const beforeFormattedTime = dayjs()
|
||||
.set("hour", beforeTimeArray[0])
|
||||
.set("minute", beforeTimeArray[1])
|
||||
.format("m");
|
||||
isSameTimeBefore = beforeFormattedTime === formattedTime;
|
||||
}
|
||||
|
||||
const openStationACFromEachTrainInfo = async (stationName) => {
|
||||
await SheetManager.hide("EachTrainInfo");
|
||||
const findStationEachLine = (selectLine) => {
|
||||
let NearStation = selectLine.filter((d) => d.Station_JP == stationName);
|
||||
return NearStation;
|
||||
};
|
||||
let returnDataBase = lineList
|
||||
.map((d) => findStationEachLine(originalStationList[d]))
|
||||
.filter((d) => d.length > 0)
|
||||
.reduce((pre, current) => {
|
||||
pre.push(...current);
|
||||
return pre;
|
||||
}, []);
|
||||
if (returnDataBase.length) {
|
||||
const payload = {
|
||||
currentStation: returnDataBase,
|
||||
navigate,
|
||||
//@ts-ignore
|
||||
useShow: () => SheetManager.show("StationDetailView", { payload }),
|
||||
onExit: () => SheetManager.hide("StationDetailView"),
|
||||
}; //@ts-ignore
|
||||
setTimeout(() => SheetManager.show("StationDetailView", { payload }), 50);
|
||||
} else {
|
||||
SheetManager.hide("StationDetailView");
|
||||
}
|
||||
};
|
||||
const openTrainInfo = () => {
|
||||
let TrainNumber = "";
|
||||
if (trainData.trainNumDistance != undefined) {
|
||||
const timeInfo =
|
||||
parseInt(trainData.TrainNumber.replace("M", "").replace("D", "")) -
|
||||
trainData.trainNumDistance;
|
||||
TrainNumber = timeInfo + "号";
|
||||
}
|
||||
const payload = {
|
||||
data: {
|
||||
trainNum: trainData.TrainNumber,
|
||||
limited: `${data}:${trainData.trainName}${TrainNumber}`,
|
||||
},
|
||||
navigate,
|
||||
openStationACFromEachTrainInfo,
|
||||
from: d.isOperating ? null :"AllTrainIDList",
|
||||
};
|
||||
SheetManager.show("EachTrainInfo", {
|
||||
//@ts-ignore
|
||||
payload,
|
||||
onClose: (data) => {
|
||||
//alert(data);
|
||||
},
|
||||
});
|
||||
};
|
||||
const [stationColor, setStationColor] = useState(["gray"]);
|
||||
useEffect(() => {
|
||||
const Stations = stationList
|
||||
.map((a) => a.filter((d) => d.StationName == trainName))
|
||||
.reduce((newArray, e) => newArray.concat(e), []);
|
||||
const StationNumbers =
|
||||
Stations &&
|
||||
Stations.filter((d) => d.StationNumber).map((d) => d.StationNumber);
|
||||
|
||||
if (StationNumbers) {
|
||||
const stationLineColor = StationNumbers.map(
|
||||
(d) => lineColorList[d.charAt(0)]
|
||||
);
|
||||
setStationColor(stationLineColor || ["gray"]);
|
||||
}
|
||||
}, [stationList]);
|
||||
// if(typeString == "回送"){
|
||||
// return<></>;
|
||||
// }
|
||||
const animatedStyle = useAnimatedStyle(() => {
|
||||
const leftPosition =
|
||||
((((width.value - 50) / 100) * parseInt(formattedTime)) / 60) * 100;
|
||||
return {
|
||||
left: leftPosition,
|
||||
};
|
||||
}, [formattedTime]);
|
||||
return (
|
||||
<View style={{ left: 0, height: 50 }}>
|
||||
<Animated.View
|
||||
style={[
|
||||
{
|
||||
flexDirection: "column",
|
||||
//borderTopWidth: 1,
|
||||
//borderBottomWidth: 0.5,
|
||||
borderStyle: "solid",
|
||||
borderColor: "darkgray",
|
||||
opacity: d.timeType.includes("通") ? 0.5 : 1,
|
||||
position: "absolute",
|
||||
height: "100%",
|
||||
width: 28,
|
||||
top: isSameTimeBefore ? 10 : 0,
|
||||
},
|
||||
animatedStyle,
|
||||
]}
|
||||
>
|
||||
<TouchableOpacity style={{ flex: 1 }} onPress={() => openTrainInfo()}>
|
||||
<View style={{ position: "relative" }}>
|
||||
<Text style={{ fontSize: 20, color: color, opacity: isSameTimeBefore ? 0 : 1, fontWeight:d.isOperating ? "bold" : "thin", fontStyle:d.isOperating? "italic" :"normal" }}>{formattedTime}</Text>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 10,
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{d.timeType}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{ flex: 1, flexDirection: "column" }}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 8,
|
||||
flex: 1,
|
||||
fontWeight: "bold",
|
||||
color: stationColor[0],
|
||||
}}
|
||||
>
|
||||
{trainName}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</Animated.View>
|
||||
</View>
|
||||
);
|
||||
};
|
44
components/StationDiagram/ExGridViewTimePositionItem.tsx
Normal file
44
components/StationDiagram/ExGridViewTimePositionItem.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import { FC } from "react";
|
||||
import { View } from "react-native";
|
||||
import dayjs from "dayjs";
|
||||
import { SharedValue, useAnimatedStyle } from "react-native-reanimated";
|
||||
import Animated from "react-native-reanimated";
|
||||
|
||||
export const ExGridViewTimePositionItem: FC<{
|
||||
width: SharedValue<number>;
|
||||
hour: string;
|
||||
}> = ({ width, hour }) => {
|
||||
const date = dayjs();
|
||||
const formattedTime = date.format("m");
|
||||
const formattedHour = date.format("H");
|
||||
|
||||
// if(typeString == "回送"){
|
||||
// return<></>;
|
||||
// }
|
||||
const animatedStyle = useAnimatedStyle(() => {
|
||||
const leftPosition =
|
||||
((((width.value - 50) / 100) * parseInt(formattedTime)) / 60) * 100;
|
||||
return {
|
||||
left: leftPosition,
|
||||
};
|
||||
}, [formattedTime]);
|
||||
if (formattedHour != hour) return <></>;
|
||||
return (
|
||||
<View style={{ left: 0, height: 50, width: 1 }}>
|
||||
<Animated.View
|
||||
style={[
|
||||
{
|
||||
flexDirection: "column",
|
||||
borderLeftWidth: 2,
|
||||
//borderBottomWidth: 0.5,
|
||||
borderStyle: "solid",
|
||||
borderColor: "red",
|
||||
position: "absolute",
|
||||
height: "100%",
|
||||
},
|
||||
animatedStyle,
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
43
components/StationDiagram/ListView.tsx
Normal file
43
components/StationDiagram/ListView.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import { FC } from "react";
|
||||
import { ListViewItem } from "@/components/StationDiagram/ListViewItem";
|
||||
import { View, Text, ScrollView } from "react-native";
|
||||
type hoge = {
|
||||
trainNumber: string;
|
||||
array: string;
|
||||
name: string;
|
||||
timeType: string;
|
||||
time: string;
|
||||
};
|
||||
export const ListView: FC<{
|
||||
data: hoge[];
|
||||
}> = ({ data }) => {
|
||||
const groupedData: Record<string, hoge[]> = {};
|
||||
const groupKeys = [];
|
||||
data.forEach((item) => {
|
||||
const hour = item.time.split(":")[0];
|
||||
if (!groupedData[hour]) {
|
||||
groupedData[hour] = [];
|
||||
groupKeys.push(hour);
|
||||
}
|
||||
groupedData[hour].push(item);
|
||||
});
|
||||
return (
|
||||
<ScrollView
|
||||
style={{ backgroundColor: "white" }}
|
||||
stickyHeaderIndices={
|
||||
groupKeys.at(0) ? groupKeys.map((_, i) => i * 2) : []
|
||||
}
|
||||
>
|
||||
{groupKeys.map((hour) => [
|
||||
<View style={{ backgroundColor: "white", padding: 5, borderBottomWidth: 0.5, borderTopWidth: 0.5, borderBottomColor: "#ccc" }} key={hour}>
|
||||
<Text style={{ fontSize: 15 }}>{hour}時台</Text>
|
||||
</View>,
|
||||
<View>
|
||||
{groupedData[hour].map((d, i) => (
|
||||
<ListViewItem key={d.trainNumber + i} d={d} />
|
||||
))}
|
||||
</View>,
|
||||
])}
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
247
components/StationDiagram/ListViewItem.tsx
Normal file
247
components/StationDiagram/ListViewItem.tsx
Normal file
@@ -0,0 +1,247 @@
|
||||
import { migrateTrainName } from "@/lib/eachTrainInfoCoreLib/migrateTrainName";
|
||||
import { getStringConfig } from "@/lib/getStringConfig";
|
||||
import { getTrainType } from "@/lib/getTrainType";
|
||||
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||
import { FC, useEffect, useMemo, useState } from "react";
|
||||
import { View, Text, TouchableOpacity } from "react-native";
|
||||
import { customTrainDataDetector } from "../custom-train-data";
|
||||
import dayjs from "dayjs";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { lineList } from "@/lib/getStationList";
|
||||
import { useStationList } from "@/stateBox/useStationList";
|
||||
import { CustomTrainData, trainTypeID } from "@/lib/CommonTypes";
|
||||
import { StationNumberMaker } from "../駅名表/StationNumberMaker";
|
||||
import { getStationID } from "@/lib/eachTrainInfoCoreLib/getStationData";
|
||||
import lineColorList from "@/assets/originData/lineColorList";
|
||||
|
||||
export const ListViewItem: FC<{
|
||||
d: {
|
||||
trainNumber: string;
|
||||
array: string;
|
||||
name: string;
|
||||
timeType: string;
|
||||
time: string;
|
||||
};
|
||||
}> = ({ d }) => {
|
||||
const { allCustomTrainData } = useAllTrainDiagram();
|
||||
const { navigate, goBack } = useNavigation();
|
||||
const [trainData, setTrainData] = useState<CustomTrainData>();
|
||||
useEffect(() => {
|
||||
if (allCustomTrainData) {
|
||||
allCustomTrainData.forEach((x) => {
|
||||
if (x.TrainNumber === d.trainNumber) {
|
||||
setTrainData(x);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
const { color, name, data } = getTrainType({
|
||||
type: trainData?.type,
|
||||
whiteMode: true,
|
||||
});
|
||||
// 列車名、種別、フォントの取得
|
||||
const { getStationDataFromName, stationList, originalStationList } =
|
||||
useStationList();
|
||||
const [
|
||||
typeString,
|
||||
trainName,
|
||||
fontAvailable,
|
||||
isOneMan,
|
||||
infogram,
|
||||
isEdit,
|
||||
uwasa,
|
||||
vehicleFormation,
|
||||
trainInfoUrl,lineColor
|
||||
] = useMemo(() => {
|
||||
const {
|
||||
type,
|
||||
trainName,
|
||||
trainNumDistance,
|
||||
infogram,
|
||||
isEdit,
|
||||
uwasa,
|
||||
vehicleFormation,
|
||||
trainInfoUrl,
|
||||
} = customTrainDataDetector(d.trainNumber, allCustomTrainData);
|
||||
const [typeString, fontAvailable, isOneMan] = getStringConfig(
|
||||
type,
|
||||
d.trainNumber
|
||||
);
|
||||
const trainData = d.array.split("#").filter((d) => d !== "");
|
||||
const station = getStationDataFromName(trainData[trainData.length - 1].split(",")[0]);
|
||||
const lineColor =
|
||||
station.length > 0
|
||||
? lineColorList[station[0]?.StationNumber.slice(0, 1)]
|
||||
: "black";
|
||||
switch (true) {
|
||||
case trainData[trainData.length - 1] === undefined:
|
||||
return [
|
||||
typeString,
|
||||
"",
|
||||
fontAvailable,
|
||||
isOneMan,
|
||||
infogram,
|
||||
isEdit,
|
||||
uwasa,
|
||||
vehicleFormation,
|
||||
trainInfoUrl,lineColor
|
||||
];
|
||||
default:
|
||||
// 行先がある場合は、行先を取得
|
||||
return [
|
||||
typeString,
|
||||
migrateTrainName(
|
||||
trainData[trainData.length - 1].split(",")[0] + "行き"
|
||||
),
|
||||
fontAvailable,
|
||||
isOneMan,
|
||||
infogram,
|
||||
isEdit,
|
||||
uwasa,
|
||||
vehicleFormation,
|
||||
trainInfoUrl,lineColor
|
||||
];
|
||||
}
|
||||
}, [d.array]);
|
||||
const timeArray = d.time.split(":").map((s) => parseInt(s));
|
||||
const formattedTime = dayjs()
|
||||
.set("hour", timeArray[0])
|
||||
.set("minute", timeArray[1])
|
||||
.format("HH:mm");
|
||||
|
||||
const openStationACFromEachTrainInfo = async (stationName) => {
|
||||
await SheetManager.hide("EachTrainInfo");
|
||||
const findStationEachLine = (selectLine) => {
|
||||
let NearStation = selectLine.filter((d) => d.Station_JP == stationName);
|
||||
return NearStation;
|
||||
};
|
||||
let returnDataBase = lineList
|
||||
.map((d) => findStationEachLine(originalStationList[d]))
|
||||
.filter((d) => d.length > 0)
|
||||
.reduce((pre, current) => {
|
||||
pre.push(...current);
|
||||
return pre;
|
||||
}, []);
|
||||
if (returnDataBase.length) {
|
||||
const payload = {
|
||||
currentStation: returnDataBase,
|
||||
navigate,
|
||||
//@ts-ignore
|
||||
useShow: () => SheetManager.show("StationDetailView", { payload }),
|
||||
onExit: () => SheetManager.hide("StationDetailView"),
|
||||
}; //@ts-ignore
|
||||
setTimeout(() => SheetManager.show("StationDetailView", { payload }), 50);
|
||||
} else {
|
||||
SheetManager.hide("StationDetailView");
|
||||
}
|
||||
};
|
||||
const openTrainInfo = () => {
|
||||
let TrainNumber = "";
|
||||
if (trainData.trainNumDistance != undefined) {
|
||||
const timeInfo =
|
||||
parseInt(trainData.TrainNumber.replace("M", "").replace("D", "")) -
|
||||
trainData.trainNumDistance;
|
||||
TrainNumber = timeInfo + "号";
|
||||
}
|
||||
const payload = {
|
||||
data: {
|
||||
trainNum: trainData.TrainNumber,
|
||||
limited: `${data}:${trainData.trainName}${TrainNumber}`,
|
||||
},
|
||||
navigate,
|
||||
openStationACFromEachTrainInfo,
|
||||
from: "AllTrainIDList",
|
||||
};
|
||||
SheetManager.show("EachTrainInfo", {
|
||||
//@ts-ignore
|
||||
payload,
|
||||
onClose: (data) => {
|
||||
//alert(data);
|
||||
},
|
||||
});
|
||||
};
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
marginHorizontal: 10,
|
||||
borderTopWidth: 1,
|
||||
borderBottomWidth: 0.5,
|
||||
borderStyle: "solid",
|
||||
borderColor: "darkgray",
|
||||
padding: 10,
|
||||
opacity: d.timeType?.includes("通") ? 0.5 : 1,
|
||||
}}
|
||||
onPress={() => openTrainInfo()}
|
||||
>
|
||||
<View style={{ position: "relative", flex: 3 }}>
|
||||
<Text style={{ fontSize: 30, fontFamily: "DiaPro" }}>
|
||||
{formattedTime}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 10,
|
||||
position: "absolute",
|
||||
bottom: -3,
|
||||
right: 0,
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{d.timeType}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{ flex: 10, flexDirection: "column" }}>
|
||||
<View style={{ flexDirection: "row" }}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 15,
|
||||
fontFamily: fontAvailable ? "JR-Nishi" : undefined,
|
||||
fontWeight: !fontAvailable ? "bold" : undefined,
|
||||
paddingTop: fontAvailable ? 2 : 0,
|
||||
paddingLeft: 10,
|
||||
color: color,
|
||||
}}
|
||||
>
|
||||
{typeString}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 15,
|
||||
fontWeight: "bold",
|
||||
flex: 1,
|
||||
paddingLeft: 2,
|
||||
color: color,
|
||||
}}
|
||||
>
|
||||
{trainData?.trainName +
|
||||
(trainData?.trainNumDistance !== null
|
||||
? ` ${parseInt(d.trainNumber) - trainData?.trainNumDistance}号`
|
||||
: "")}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 15,
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{trainData?.TrainNumber}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{ flexDirection: "row", alignItems: "center", flex: 1 }}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 15,
|
||||
flex: 1,
|
||||
paddingHorizontal: 10,
|
||||
fontWeight: "bold",
|
||||
color: lineColor
|
||||
}}
|
||||
>
|
||||
{trainName}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
164
components/StationDiagram/SearchBox/SearchInputSuggestBox.tsx
Normal file
164
components/StationDiagram/SearchBox/SearchInputSuggestBox.tsx
Normal file
@@ -0,0 +1,164 @@
|
||||
import lineColorList from "@/assets/originData/lineColorList";
|
||||
import { useStationList } from "@/stateBox/useStationList";
|
||||
import { FC, useEffect, useState } from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
LayoutAnimation,
|
||||
} from "react-native";
|
||||
|
||||
type hoge = {
|
||||
trainNumber: string;
|
||||
array: string;
|
||||
name: string;
|
||||
timeType: string;
|
||||
time: string;
|
||||
}[];
|
||||
|
||||
export const SearchInputSuggestBox: FC<{
|
||||
input: string;
|
||||
setInput: (f: string) => void;
|
||||
currentStationDiagram: hoge;
|
||||
}> = ({ input, setInput, currentStationDiagram }) => {
|
||||
const { getStationDataFromName } = useStationList();
|
||||
const [stationList, setStationList] = useState<
|
||||
{
|
||||
stationName: string;
|
||||
number: string[];
|
||||
}[]
|
||||
>([]);
|
||||
const [listFiltered, setListFiltered] = useState<string>("");
|
||||
const [filteredStationLine, setFilteredStationLine] = useState<string[]>([]);
|
||||
useEffect(() => {
|
||||
const x: { stationName: string; number: string[] }[] = [];
|
||||
currentStationDiagram.forEach((d) => {
|
||||
d.array.split("#").forEach((s) => {
|
||||
if (s == "") return;
|
||||
const [stationName, type, time] = s.split(",");
|
||||
if (!x.find((item) => item.stationName === stationName)) {
|
||||
if (!type?.includes("通")) {
|
||||
const stationData = getStationDataFromName(stationName);
|
||||
if (listFiltered === "その他") {
|
||||
if (stationData.length === 0) {
|
||||
x.push({
|
||||
stationName,
|
||||
number: stationData.map((item) => item.StationNumber),
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
const filter = stationData.filter((s) => {
|
||||
if (listFiltered === "") return true;
|
||||
if (listFiltered === "その他") {
|
||||
return !(
|
||||
s.StationNumber ? s.StationNumber.slice(0, 1) : ""
|
||||
).match(/[A-Z]/);
|
||||
}
|
||||
return (
|
||||
s.StationNumber ? s.StationNumber.slice(0, 1) : ""
|
||||
).includes(listFiltered);
|
||||
});
|
||||
if (filter.length === 0) return;
|
||||
x.push({
|
||||
stationName,
|
||||
number: stationData.map((item) => item.StationNumber),
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
setStationList(x);
|
||||
}, [currentStationDiagram, listFiltered]);
|
||||
useEffect(() => {
|
||||
const filtered = stationList
|
||||
.map((s) => s.number?.map((r) => (r ? r.slice(0, 1) : "")))
|
||||
.flat();
|
||||
const arrayB = Array.from(new Set(filtered));
|
||||
setFilteredStationLine(arrayB.map((r) => (r !== "" ? r : "その他")));
|
||||
}, [stationList]);
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
maxHeight: 200,
|
||||
width: "100%",
|
||||
backgroundColor: "#0099CC",
|
||||
zIndex: 100,
|
||||
}}
|
||||
>
|
||||
<Text>{input}</Text>
|
||||
<ScrollView keyboardShouldPersistTaps="handled">
|
||||
<View style={{ flexDirection: "row", flexWrap: "wrap" }}>
|
||||
{stationList.map(({ stationName, number }) => (
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
margin: 5,
|
||||
padding: 5,
|
||||
backgroundColor: "#eee",
|
||||
borderRadius: 20,
|
||||
}}
|
||||
key={stationName + number.join(",")}
|
||||
onPress={() => setInput(stationName)}
|
||||
>
|
||||
<Text>{stationName}</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap",
|
||||
borderTopColor: "#ccc",
|
||||
borderTopWidth: 0.5,
|
||||
paddingTop: 0,
|
||||
marginTop: 10,
|
||||
}}
|
||||
>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
margin: 5,
|
||||
padding: 5,
|
||||
backgroundColor: "#eee",
|
||||
borderRadius: 5,
|
||||
}}
|
||||
key={"empty"}
|
||||
onPress={() => {
|
||||
LayoutAnimation.configureNext({
|
||||
duration: 400,
|
||||
update: { type: "easeInEaseOut", springDamping: 0.6 },
|
||||
});
|
||||
setListFiltered("");
|
||||
}}
|
||||
>
|
||||
<Text>全て</Text>
|
||||
</TouchableOpacity>
|
||||
{filteredStationLine.map((line) => (
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
margin: 5,
|
||||
padding: 5,
|
||||
backgroundColor: lineColorList[line]
|
||||
? `${lineColorList[line]}`
|
||||
: "#eee",
|
||||
borderRadius: 5,
|
||||
}}
|
||||
key={line}
|
||||
onPress={() => {
|
||||
LayoutAnimation.configureNext({
|
||||
duration: 400,
|
||||
update: { type: "easeInEaseOut", springDamping: 0.6 },
|
||||
});
|
||||
setListFiltered(line);
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: lineColorList[line] ? `white` : "black" }}>
|
||||
{line}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
509
components/StationDiagram/StationDiagramView.tsx
Normal file
509
components/StationDiagram/StationDiagramView.tsx
Normal file
@@ -0,0 +1,509 @@
|
||||
import { FC, useEffect, useState } from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
ScrollView,
|
||||
TextInput,
|
||||
Keyboard,
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
TouchableOpacity,
|
||||
LayoutAnimation,
|
||||
} from "react-native";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { BigButton } from "../atom/BigButton";
|
||||
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||
import { ListView } from "@/components/StationDiagram/ListView";
|
||||
import dayjs from "dayjs";
|
||||
import { ExGridView } from "./ExGridView";
|
||||
import { Switch } from "react-native-elements";
|
||||
import { customTrainDataDetector } from "../custom-train-data";
|
||||
import { getTrainType } from "@/lib/getTrainType";
|
||||
import { trainTypeID } from "@/lib/CommonTypes";
|
||||
import { SearchInputSuggestBox } from "./SearchBox/SearchInputSuggestBox";
|
||||
|
||||
type props = {
|
||||
route: {
|
||||
params: {
|
||||
currentStation: {
|
||||
Station_JP: string;
|
||||
Station_EN: string;
|
||||
StationName?: string;
|
||||
MyStation?: string;
|
||||
StationNumber: string;
|
||||
DispNum?: string;
|
||||
StationTimeTable: string;
|
||||
StationMap?: string;
|
||||
JrHpUrl?: string;
|
||||
lat: number;
|
||||
lng: number;
|
||||
jslodApi: string;
|
||||
}[];
|
||||
};
|
||||
};
|
||||
};
|
||||
export const StationDiagramView: FC<props> = ({ route }) => {
|
||||
if (!route.params) {
|
||||
return null;
|
||||
}
|
||||
const { currentStation } = route.params;
|
||||
// 必要な情報:駅情報、全ダイヤ、カスタム列車情報
|
||||
// 表示モード:縦並びリスト、横並びグリッド(時刻分割)、横並び単純左詰め
|
||||
// フィルタリング:終点路線、種別、行先、関係停車駅
|
||||
|
||||
const { keyList, allTrainDiagram, allCustomTrainData } = useAllTrainDiagram();
|
||||
|
||||
const { navigate, addListener, goBack, canGoBack } = useNavigation();
|
||||
const [keyBoardVisible, setKeyBoardVisible] = useState(false);
|
||||
const [input, setInput] = useState("");
|
||||
const [displayMode, setDisplayMode] = useState<"list" | "grid">("list");
|
||||
const [selectedTypeList, setSelectedTypeList] = useState<trainTypeID[]>([
|
||||
"Normal",
|
||||
"OneMan",
|
||||
"Rapid",
|
||||
"OneManRapid",
|
||||
"LTDEXP",
|
||||
"NightLTDEXP",
|
||||
]);
|
||||
type hoge = {
|
||||
trainNumber: string;
|
||||
array: string;
|
||||
name: string;
|
||||
timeType: string;
|
||||
time: string;
|
||||
}[];
|
||||
const [showTypeFiltering, setShowTypeFiltering] = useState(false);
|
||||
const [showLastStop, setShowLastStop] = useState(false);
|
||||
const [threw, setIsThrew] = useState(false);
|
||||
const [currentStationDiagram, setCurrentStationDiagram] = useState<hoge>([]);
|
||||
useEffect(() => {
|
||||
if (allTrainDiagram && currentStation.length > 0) {
|
||||
const stationName = currentStation[0].Station_JP;
|
||||
let returnDataArray: hoge = [];
|
||||
keyList
|
||||
.filter((s) => {
|
||||
const boolData = allTrainDiagram[s];
|
||||
let isStop = false;
|
||||
let isStopPos = -1;
|
||||
let isInput = false;
|
||||
let isInputPos = -1;
|
||||
|
||||
boolData.split("#").forEach((d, index, array) => {
|
||||
const [station, type, time] = d.split(",");
|
||||
if (station === stationName) {
|
||||
isStop = true;
|
||||
isStopPos = index;
|
||||
}
|
||||
if (station === input && type && !type.includes("通")) {
|
||||
isInput = true;
|
||||
isInputPos = index;
|
||||
}
|
||||
});
|
||||
if (input && input.length > 0) {
|
||||
if (isInput && isStop) {
|
||||
return isInputPos > isStopPos;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return isStop;
|
||||
})
|
||||
.forEach((d) => {
|
||||
allTrainDiagram[d]
|
||||
.split("#")
|
||||
.filter((d) => {
|
||||
const [station, type, time] = d.split(",");
|
||||
return station === stationName;
|
||||
})
|
||||
.forEach((x) => {
|
||||
const [name, timeType, time] = x.split(",");
|
||||
if (!name || !timeType || !time) return;
|
||||
|
||||
const { img, trainName, type, trainNumDistance, infogram } =
|
||||
customTrainDataDetector(d, allCustomTrainData);
|
||||
const arrayData = {
|
||||
trainNumber: d,
|
||||
array: allTrainDiagram[d],
|
||||
name,
|
||||
timeType,
|
||||
time,
|
||||
};
|
||||
// //条件によってフィルタリング
|
||||
if (!threw && timeType && timeType.includes("通")) return;
|
||||
if (!showLastStop && timeType && timeType.includes("着")) return;
|
||||
if (
|
||||
selectedTypeList.findIndex((item) => item === "SPCL") === -1
|
||||
) {
|
||||
if (d.match(/9\d\d\d[D,M,S]/)) return;
|
||||
}
|
||||
if (
|
||||
selectedTypeList.length > 0 &&
|
||||
selectedTypeList.findIndex((item) => item === type) === -1
|
||||
) {
|
||||
if (
|
||||
selectedTypeList.findIndex(
|
||||
(item) => item === "Forwarding"
|
||||
) !== -1
|
||||
) {
|
||||
if (!d.match(/[A,B,R,H,E,T,L]/)) return;
|
||||
} else if (
|
||||
selectedTypeList.findIndex((item) => item === "SPCL") !== -1
|
||||
) {
|
||||
if (!d.match(/9\d\d\d[D,M,S]/)) return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
returnDataArray.push(arrayData);
|
||||
});
|
||||
});
|
||||
setCurrentStationDiagram(
|
||||
returnDataArray.sort((a, b) => {
|
||||
const adjustTime = (t: string) => {
|
||||
const [h, m] = t.split(":").map(Number);
|
||||
// 4時未満は翌日の時刻とみなして+24時間
|
||||
return h < 4
|
||||
? dayjs().add(1, "day").hour(h).minute(m)
|
||||
: dayjs().hour(h).minute(m);
|
||||
};
|
||||
const aa = adjustTime(a.time);
|
||||
const bb = adjustTime(b.time);
|
||||
const x = aa.isAfter(bb);
|
||||
return x ? 1 : -1;
|
||||
//return true;
|
||||
})
|
||||
);
|
||||
}
|
||||
}, [currentStation, showLastStop, threw, input, selectedTypeList]);
|
||||
|
||||
useEffect(() => {
|
||||
const showSubscription = Keyboard.addListener("keyboardDidShow", () => {
|
||||
LayoutAnimation.configureNext({
|
||||
duration: 600,
|
||||
update: { type: "spring", springDamping: 0.6 },
|
||||
});
|
||||
setKeyBoardVisible(true);
|
||||
});
|
||||
const hideSubscription = Keyboard.addListener("keyboardDidHide", () => {
|
||||
LayoutAnimation.configureNext({
|
||||
duration: 600,
|
||||
update: { type: "spring", springDamping: 0.6 },
|
||||
});
|
||||
setKeyBoardVisible(false);
|
||||
});
|
||||
|
||||
return () => {
|
||||
showSubscription.remove();
|
||||
hideSubscription.remove();
|
||||
};
|
||||
}, []);
|
||||
return (
|
||||
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
||||
<Text
|
||||
style={{
|
||||
textAlign: "center",
|
||||
fontSize: 20,
|
||||
color: "white",
|
||||
fontWeight: "bold",
|
||||
paddingVertical: 10,
|
||||
}}
|
||||
>
|
||||
{currentStation[0].Station_JP}駅 時刻表
|
||||
</Text>
|
||||
{displayMode === "list" ? (
|
||||
<ListView data={currentStationDiagram} />
|
||||
) : (
|
||||
<ExGridView data={currentStationDiagram} />
|
||||
)}
|
||||
{/* <Text
|
||||
style={{
|
||||
backgroundColor: "white",
|
||||
borderWidth: 1,
|
||||
borderStyle: "solid",
|
||||
}}
|
||||
>
|
||||
お気に入り登録した駅のうち、位置情報システムで移動可能な駅が表示されています。タップすることで位置情報システムの当該の駅に移動します。
|
||||
</Text> */}
|
||||
<KeyboardAvoidingView
|
||||
behavior="padding"
|
||||
keyboardVerticalOffset={80}
|
||||
enabled={Platform.OS === "ios"}
|
||||
>
|
||||
{!keyBoardVisible ? (
|
||||
<ScrollView
|
||||
horizontal
|
||||
style={{
|
||||
height: 35,
|
||||
flexDirection: "row",
|
||||
display: "flex",
|
||||
}}
|
||||
>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
alignItems: "center",
|
||||
marginHorizontal: 5,
|
||||
backgroundColor: threw ? "white" : "#ffffff00",
|
||||
alignSelf: "center",
|
||||
borderColor: "white",
|
||||
borderWidth: 1,
|
||||
borderRadius: 100,
|
||||
}}
|
||||
onPress={() => {
|
||||
setIsThrew(!threw);
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: threw ? "#0099CC" : "white",
|
||||
fontSize: 14,
|
||||
margin: 5,
|
||||
}}
|
||||
>
|
||||
通過
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
alignItems: "center",
|
||||
marginHorizontal: 5,
|
||||
backgroundColor: showLastStop ? "white" : "#ffffff00",
|
||||
alignSelf: "center",
|
||||
borderColor: "white",
|
||||
borderWidth: 1,
|
||||
borderRadius: 100,
|
||||
}}
|
||||
onPress={() => {
|
||||
setShowLastStop(!showLastStop);
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: showLastStop ? "#0099CC" : "white",
|
||||
fontSize: 14,
|
||||
margin: 5,
|
||||
}}
|
||||
>
|
||||
当駅止
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<View
|
||||
style={{
|
||||
height: "auto",
|
||||
borderLeftWidth: 1,
|
||||
margin: 5,
|
||||
borderColor: "white",
|
||||
}}
|
||||
/>
|
||||
{showTypeFiltering ? (
|
||||
<>
|
||||
<TypeSelectorBox
|
||||
selectedTypeList={selectedTypeList}
|
||||
setSelectedTypeList={setSelectedTypeList}
|
||||
typeID="Normal"
|
||||
relativeID={["OneMan"]}
|
||||
/>
|
||||
<TypeSelectorBox
|
||||
selectedTypeList={selectedTypeList}
|
||||
setSelectedTypeList={setSelectedTypeList}
|
||||
typeID="Rapid"
|
||||
relativeID={["OneManRapid"]}
|
||||
/>
|
||||
<TypeSelectorBox
|
||||
selectedTypeList={selectedTypeList}
|
||||
setSelectedTypeList={setSelectedTypeList}
|
||||
typeID="LTDEXP"
|
||||
relativeID={["NightLTDEXP"]}
|
||||
/>
|
||||
<TypeSelectorBox
|
||||
selectedTypeList={selectedTypeList}
|
||||
setSelectedTypeList={setSelectedTypeList}
|
||||
typeID="SPCL"
|
||||
relativeID={[
|
||||
"SPCL_Normal",
|
||||
"SPCL_Rapid",
|
||||
"SPCL_EXP",
|
||||
"Party",
|
||||
]}
|
||||
/>
|
||||
<TypeSelectorBox
|
||||
selectedTypeList={selectedTypeList}
|
||||
setSelectedTypeList={setSelectedTypeList}
|
||||
typeID="Freight"
|
||||
/>
|
||||
<TypeSelectorBox
|
||||
selectedTypeList={selectedTypeList}
|
||||
setSelectedTypeList={setSelectedTypeList}
|
||||
typeID="Forwarding"
|
||||
relativeID={["FreightForwarding"]}
|
||||
/>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
alignItems: "center",
|
||||
marginHorizontal: 5,
|
||||
backgroundColor: "#ffffff00",
|
||||
alignSelf: "center",
|
||||
borderColor: "white",
|
||||
borderWidth: 1,
|
||||
borderRadius: 100,
|
||||
}}
|
||||
onPress={() => {
|
||||
LayoutAnimation.configureNext(
|
||||
LayoutAnimation.Presets.easeInEaseOut
|
||||
);
|
||||
setShowTypeFiltering(false);
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: 14,
|
||||
margin: 5,
|
||||
}}
|
||||
>
|
||||
<
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
) : (
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
alignItems: "center",
|
||||
marginHorizontal: 5,
|
||||
backgroundColor: "#ffffff00",
|
||||
alignSelf: "center",
|
||||
borderColor: "white",
|
||||
borderWidth: 1,
|
||||
borderRadius: 100,
|
||||
}}
|
||||
onPress={() => {
|
||||
LayoutAnimation.configureNext(
|
||||
LayoutAnimation.Presets.easeInEaseOut
|
||||
);
|
||||
setShowTypeFiltering(true);
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: 14,
|
||||
margin: 5,
|
||||
}}
|
||||
>
|
||||
>
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
alignItems: "center",
|
||||
marginHorizontal: 5,
|
||||
backgroundColor: "#ffffff00",
|
||||
alignSelf: "center",
|
||||
borderColor: "white",
|
||||
borderWidth: 1,
|
||||
borderRadius: 100,
|
||||
}}
|
||||
onPress={() => {
|
||||
setDisplayMode(displayMode === "list" ? "grid" : "list");
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: "white",
|
||||
fontSize: 14,
|
||||
margin: 5,
|
||||
}}
|
||||
>
|
||||
{displayMode === "list" ? "横並びモード" : "リストモード"}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</ScrollView>
|
||||
) : (
|
||||
<View style={{ position: "relative", display: "flex" }}>
|
||||
<SearchInputSuggestBox
|
||||
input={input}
|
||||
setInput={setInput}
|
||||
currentStationDiagram={currentStationDiagram}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
<View
|
||||
style={{
|
||||
height: 35,
|
||||
margin: 5,
|
||||
alignItems: "center",
|
||||
backgroundColor: "#F4F4F4",
|
||||
flexDirection: "row",
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
borderRadius: 25,
|
||||
borderColor: "#F4F4F4",
|
||||
}}
|
||||
>
|
||||
<TextInput
|
||||
placeholder="駅名を入力して停車駅でフィルタリングします。"
|
||||
onFocus={() => setKeyBoardVisible(true)}
|
||||
onEndEditing={() => {}}
|
||||
onChange={(ret) => setInput(ret.nativeEvent.text)}
|
||||
value={input}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
{keyBoardVisible || (
|
||||
<BigButton onPress={() => goBack()} string="閉じる" />
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export const TypeSelectorBox: FC<{
|
||||
selectedTypeList: trainTypeID[];
|
||||
setSelectedTypeList: (list: trainTypeID[]) => void;
|
||||
typeID: trainTypeID;
|
||||
relativeID?: trainTypeID[];
|
||||
}> = (props) => {
|
||||
const { selectedTypeList, setSelectedTypeList, typeID, relativeID } = props;
|
||||
const isSelected =
|
||||
selectedTypeList.findIndex((item) => item === typeID) !== -1;
|
||||
const { color, shortName } = getTrainType({ type: typeID, whiteMode: true });
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
alignItems: "center",
|
||||
marginHorizontal: 5,
|
||||
opacity: isSelected ? 1 : 0.8,
|
||||
backgroundColor: isSelected ? "white" : color,
|
||||
alignSelf: "center",
|
||||
borderColor: color,
|
||||
borderWidth: 1,
|
||||
borderRadius: 100,
|
||||
}}
|
||||
onPress={() => {
|
||||
if (selectedTypeList.findIndex((item) => item === typeID) === -1) {
|
||||
setSelectedTypeList([
|
||||
...selectedTypeList,
|
||||
typeID,
|
||||
...(relativeID ?? []),
|
||||
]);
|
||||
} else {
|
||||
setSelectedTypeList(
|
||||
selectedTypeList.filter(
|
||||
(item) => item !== typeID && !relativeID?.includes(item)
|
||||
)
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: isSelected ? color : "white",
|
||||
fontSize: 14,
|
||||
margin: 5,
|
||||
}}
|
||||
>
|
||||
{shortName}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
@@ -1,10 +1,15 @@
|
||||
import { CustomTrainData } from "@/lib/CommonTypes";
|
||||
import dayjs from "dayjs";
|
||||
export const customTrainDataDetector = (
|
||||
type CustomTrainDataDetector = (
|
||||
TrainNumber: string,
|
||||
allCustonTrainData?: any[]
|
||||
allCustomTrainData?: any[]
|
||||
) => CustomTrainData;
|
||||
export const customTrainDataDetector: CustomTrainDataDetector = (
|
||||
TrainNumber,
|
||||
allCustomTrainData
|
||||
) => {
|
||||
if (allCustonTrainData && allCustonTrainData.length > 0) {
|
||||
const customTrain = allCustonTrainData.find(
|
||||
if (allCustomTrainData && allCustomTrainData.length > 0) {
|
||||
const customTrain = allCustomTrainData.find(
|
||||
(train) => train.TrainNumber === TrainNumber
|
||||
);
|
||||
if (customTrain) {
|
||||
|
@@ -180,11 +180,11 @@ export default function TrainMenu({ style }) {
|
||||
flex={1}
|
||||
onPressButton={() =>
|
||||
navigate("howto", {
|
||||
info: "https://train.jr-shikoku.co.jp/usage.htm",
|
||||
info: "https://xprocess.haruk.in/JR-shikoku-Apps-Common/info/train-position",
|
||||
})
|
||||
}
|
||||
>
|
||||
使い方
|
||||
走行位置の見方
|
||||
</UsefulBox>
|
||||
<UsefulBox
|
||||
backgroundColor={"#EA4752"}
|
||||
|
@@ -1,37 +1,35 @@
|
||||
import React, { FC, useEffect, useState } from "react";
|
||||
import { Linking, TouchableOpacity, Text } from "react-native";
|
||||
import { Dialog, Button, Input } from "react-native-elements";
|
||||
import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData";
|
||||
import { getTrainDelayStatus } from "../../lib/getTrainDelayStatus";
|
||||
import { getTrainType } from "../../lib/getTrainType";
|
||||
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
|
||||
import { TouchableOpacity } from "react-native";
|
||||
import { checkDuplicateTrainData } from "@/lib/checkDuplicateTrainData";
|
||||
import { getTrainDelayStatus } from "@/lib/getTrainDelayStatus";
|
||||
import { getTrainType } from "@/lib/getTrainType";
|
||||
import { useCurrentTrain } from "@/stateBox/useCurrentTrain";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import { Description } from "./LED_inside_Component/Description";
|
||||
import { DependTime } from "./LED_inside_Component/DependTime";
|
||||
import { LastStation } from "./LED_inside_Component/LastStation";
|
||||
import { StatusAndDelay } from "./LED_inside_Component/StatusAndDelay";
|
||||
import { TrainName } from "./LED_inside_Component/TrainName";
|
||||
import { customTrainDataDetector } from "../custom-train-data";
|
||||
import { TrainPosition } from "./LED_inside_Component/TrainPosition";
|
||||
import { TrainPositionDataPush } from "./LED_inside_Component/TrainPositionDataPush";
|
||||
import { TrainPositionDataDelete } from "./LED_inside_Component/TrainPositionDataDelete";
|
||||
import { useStationList } from "../../stateBox/useStationList";
|
||||
import { Description } from "@/components/発車時刻表/LED_inside_Component/Description";
|
||||
import { DependTime } from "@/components/発車時刻表/LED_inside_Component/DependTime";
|
||||
import { LastStation } from "@/components/発車時刻表/LED_inside_Component/LastStation";
|
||||
import { StatusAndDelay } from "@/components/発車時刻表/LED_inside_Component/StatusAndDelay";
|
||||
import { TrainName } from "@/components/発車時刻表/LED_inside_Component/TrainName";
|
||||
import { TrainPosition } from "@/components/発車時刻表/LED_inside_Component/TrainPosition";
|
||||
import { StationPosPushDialog } from "@/components/発車時刻表/LED_inside_Component/TrainPositionDataPush";
|
||||
import { StationPosDeleteDialog } from "@/components/発車時刻表/LED_inside_Component/TrainPositionDataDelete";
|
||||
import { useStationList } from "@/stateBox/useStationList";
|
||||
import useInterval from "@/lib/useInterval";
|
||||
import dayjs from "dayjs";
|
||||
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||
import { CustomTrainData, StationProps, trainTypeID } from "@/lib/CommonTypes";
|
||||
import { getCurrentTrainData } from "@/lib/getCurrentTrainData";
|
||||
|
||||
type Props = {
|
||||
d: {
|
||||
train: string;
|
||||
lastStation: string;
|
||||
time: string;
|
||||
isThrough?: boolean;
|
||||
};
|
||||
trainIDSwitch: boolean;
|
||||
trainDescriptionSwitch: boolean;
|
||||
station: {
|
||||
Station_JP: string;
|
||||
StationNumber: string;
|
||||
};
|
||||
station: StationProps;
|
||||
navigate: (screen: string, data?: any) => void;
|
||||
openStationACFromEachTrainInfo: (station: string) => void;
|
||||
};
|
||||
@@ -46,7 +44,7 @@ export const EachData: FC<Props> = (props) => {
|
||||
} = props;
|
||||
const { currentTrain } = useCurrentTrain();
|
||||
const { stationList } = useStationList();
|
||||
const { allCustonTrainData } = useAllTrainDiagram();
|
||||
const { allCustomTrainData } = useAllTrainDiagram();
|
||||
const openTrainInfo = (d: {
|
||||
train: string;
|
||||
lastStation: string;
|
||||
@@ -62,7 +60,7 @@ export const EachData: FC<Props> = (props) => {
|
||||
const payload = {
|
||||
data: {
|
||||
trainNum: d.train,
|
||||
limited: `${getTrainType(train.type).data}:${
|
||||
limited: `${getTrainType({type:train.type}).data}:${
|
||||
train.trainName
|
||||
}${TrainNumber}`,
|
||||
},
|
||||
@@ -75,35 +73,9 @@ export const EachData: FC<Props> = (props) => {
|
||||
});
|
||||
};
|
||||
|
||||
const getTrainDataFromCurrentTrain = (trainNum: string) => {
|
||||
const customTrainData = customTrainDataDetector(
|
||||
d.train,
|
||||
allCustonTrainData
|
||||
);
|
||||
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(getTrainDataFromCurrentTrain(d.train));
|
||||
const [train, setTrain] = useState<CustomTrainData>(getCurrentTrainData(d.train,currentTrain,allCustomTrainData));
|
||||
useEffect(() => {
|
||||
setTrain(getTrainDataFromCurrentTrain(d.train));
|
||||
setTrain(getCurrentTrainData(d.train,currentTrain,allCustomTrainData));
|
||||
}, [currentTrain, d.train, trainDescriptionSwitch]);
|
||||
// 土讃線複数存在対策
|
||||
const currentTrainData = checkDuplicateTrainData(
|
||||
@@ -115,23 +87,31 @@ export const EachData: FC<Props> = (props) => {
|
||||
station.Station_JP
|
||||
)}`;
|
||||
|
||||
const [platformNumber, setPlatformNumber] = useState<number>();
|
||||
const [platformDescription, setPlatformDescription] = useState<string>();
|
||||
|
||||
// 投稿システム関係
|
||||
// Dialog表示関係
|
||||
const [dialog, setDialog] = useState(false);
|
||||
const [deleteDialog, setDeleteDialog] = useState(false);
|
||||
const [posInput, setPosInput] = useState("");
|
||||
const [descInput, setDescInput] = useState("");
|
||||
const [stationInput, setStationInput] = useState("");
|
||||
const [stationNumberInput, setStationNumberInput] = useState("");
|
||||
//固定値
|
||||
const [PosNum, setPosNum] = useState<number | undefined>();
|
||||
const [Pos, setPos] = useState<string>("");
|
||||
const [Line, setLine] = useState<string>("");
|
||||
const [StationNum, setStationNum] = useState<string>("");
|
||||
|
||||
//編集情報
|
||||
const [lineInput, setLineInput] = useState<string>("");
|
||||
const [posInput, setPosInput] = useState<string>("");
|
||||
const [descInput, setDescInput] = useState<string>("");
|
||||
|
||||
const [isShow, setIsShow] = useState(true);
|
||||
const [isDepartureNow, setIsDepartureNow] = useState(false);
|
||||
useEffect(() => {
|
||||
const [h, m] = d.time.split(":");
|
||||
const IntH = parseInt(h);
|
||||
const IntM = parseInt(m);
|
||||
const currentTime = dayjs();
|
||||
const trainTime = currentTime
|
||||
.set("hour", parseInt(d.time.split(":")[0]))
|
||||
.set("minute", parseInt(d.time.split(":")[1]));
|
||||
.set("hour", IntH < 4 ? IntH + 24 : IntH)
|
||||
.set("minute", IntM);
|
||||
const diff = trainTime.diff(currentTime, "minute");
|
||||
if (diff < 2) setIsDepartureNow(true);
|
||||
else setIsDepartureNow(false);
|
||||
@@ -147,24 +127,30 @@ export const EachData: FC<Props> = (props) => {
|
||||
}, 800);
|
||||
return (
|
||||
<>
|
||||
<TrainPositionDataDelete
|
||||
<StationPosDeleteDialog
|
||||
dialog={deleteDialog}
|
||||
setDialog={setDeleteDialog}
|
||||
{...{ currentTrainData, stationInput, stationNumberInput }}
|
||||
Pos={Pos}
|
||||
PosNum={PosNum}
|
||||
Line={Line}
|
||||
StationNum={StationNum}
|
||||
/>
|
||||
<TrainPositionDataPush
|
||||
<StationPosPushDialog
|
||||
// Dialog表示関係
|
||||
dialog={dialog}
|
||||
setDialog={setDialog}
|
||||
{...{
|
||||
currentTrainData,
|
||||
stationInput,
|
||||
stationNumberInput,
|
||||
posInput,
|
||||
descInput,
|
||||
setPosInput,
|
||||
setDescInput,
|
||||
station,
|
||||
}}
|
||||
// 固定情報
|
||||
PosNum={PosNum}
|
||||
Pos={Pos}
|
||||
Line={Line}
|
||||
StationNum={StationNum}
|
||||
// 入力欄
|
||||
lineInput={lineInput}
|
||||
setLineInput={setLineInput}
|
||||
posInput={posInput}
|
||||
setPosInput={setPosInput}
|
||||
descInput={descInput}
|
||||
setDescInput={setDescInput}
|
||||
/>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
@@ -186,41 +172,50 @@ export const EachData: FC<Props> = (props) => {
|
||||
trainIDSwitch={trainIDSwitch}
|
||||
trainID={d.train}
|
||||
type={train.type}
|
||||
isThrew={d.isThrough}
|
||||
/>
|
||||
<LastStation lastStation={d.lastStation} />
|
||||
<LastStation lastStation={d.lastStation} ToData={train.ToData} Station_JP={station.Station_JP} />
|
||||
<DependTime time={d.time} />
|
||||
<StatusAndDelay trainDelayStatus={trainDelayStatus} />
|
||||
</TouchableOpacity>
|
||||
{!!isDepartureNow && (
|
||||
<Description
|
||||
info={
|
||||
d.lastStation == "当駅止"
|
||||
d.isThrough
|
||||
? "通過列車にご注意ください"
|
||||
: d.lastStation == station.Station_JP
|
||||
? "この列車は当駅止です。間もなく到着します。"
|
||||
: "列車の出発時刻です。"
|
||||
}
|
||||
key={d.train + "-description"}
|
||||
key={d.train + "-isDepartureNow"}
|
||||
/>
|
||||
)}
|
||||
{trainDescriptionSwitch && (
|
||||
<TrainPosition
|
||||
// LED表示関係
|
||||
trainIDSwitch={trainIDSwitch}
|
||||
currentTrainData={currentTrainData}
|
||||
setStationInput={setStationInput}
|
||||
setStationNumberInput={setStationNumberInput}
|
||||
setDescInput={setDescInput}
|
||||
setPosInput={setPosInput}
|
||||
// ポップアップ表示関係
|
||||
setDialog={setDialog}
|
||||
setDeleteDialog={setDeleteDialog}
|
||||
setPlatformDescription={setPlatformDescription}
|
||||
setPlatformNumber={setPlatformNumber}
|
||||
platformDescription={platformDescription}
|
||||
platformNumber={platformNumber}
|
||||
// 固定情報
|
||||
setPos={setPos}
|
||||
setPosNum={setPosNum}
|
||||
setLine={setLine}
|
||||
setStationNum={setStationNum}
|
||||
//編集機能関係
|
||||
setLineInput={setLineInput}
|
||||
setPosInput={setPosInput}
|
||||
setDescInput={setDescInput}
|
||||
key={d.train + "-trainPosition"}
|
||||
/>
|
||||
)}
|
||||
{trainDescriptionSwitch && !!train.info && (
|
||||
<Description info={train.info} key={d.train + "-description"} />
|
||||
)}
|
||||
{trainDescriptionSwitch && !!train.uwasa && (
|
||||
<Description info={train.uwasa} key={d.train + "-uwasa"} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
79
components/発車時刻表/LED_inside_Component/AreaDescription.tsx
Normal file
79
components/発車時刻表/LED_inside_Component/AreaDescription.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
import React, { FC, useState, useEffect } from "react";
|
||||
import { Text, TextStyle, View, TouchableOpacity } from "react-native";
|
||||
import { useInterval } from "../../../lib/useInterval";
|
||||
|
||||
const descriptionStyle: TextStyle = {
|
||||
fontSize: parseInt("16%"),
|
||||
fontWeight: "bold",
|
||||
};
|
||||
|
||||
type Props = {
|
||||
areaInfo: string;
|
||||
numberOfLines?: number;
|
||||
onClick?: () => void;
|
||||
onLongClick?: () => void;
|
||||
};
|
||||
export const AreaDescription:FC<Props> = ({ areaInfo, numberOfLines = 0, onClick, onLongClick }) => {
|
||||
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(
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
alignContent: "center",
|
||||
alignItems: "center",
|
||||
width: "94%",
|
||||
marginVertical: 5,
|
||||
marginHorizontal: "3%",
|
||||
backgroundColor: "#000",
|
||||
flexDirection: "row",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
onPress={onClick}
|
||||
onLongPress={onLongClick}
|
||||
>
|
||||
<View style={{ flex: 4, flexDirection: "row" }}>
|
||||
{numberOfLines == 1 ? (
|
||||
<Text style={{ ...descriptionStyle, color: "red" }}>
|
||||
運行情報 >{" "}
|
||||
</Text>
|
||||
) : (
|
||||
<Text style={{ ...descriptionStyle, color: "green" }}> > </Text>
|
||||
)}
|
||||
|
||||
<Text
|
||||
style={{ ...descriptionStyle, color: "green" }}
|
||||
numberOfLines={numberOfLines}
|
||||
>
|
||||
{areaString.replaceAll("\n", "").replaceAll("\r", "")}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
@@ -3,18 +3,22 @@ import { Text, View } from "react-native";
|
||||
|
||||
type Props = {
|
||||
lastStation: string;
|
||||
ToData: string;
|
||||
Station_JP: string;
|
||||
};
|
||||
export const LastStation: FC<Props> = ({ lastStation }) => {
|
||||
export const LastStation: FC<Props> = ({ lastStation, ToData, Station_JP }) => {
|
||||
const isEdit = !ToData ? false : ToData !== lastStation;
|
||||
const string = isEdit ? ToData : lastStation;
|
||||
return (
|
||||
<View style={{ flex: 4, flexDirection: "row" }}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: lastStation.length > 4 ? parseInt("12%") : parseInt("16%"),
|
||||
color: "white",
|
||||
fontSize: lastStation?.length > 4 ? parseInt("12%") : parseInt("16%"),
|
||||
color: isEdit ? "#ffd16fff" : "white",
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{lastStation}
|
||||
{string === Station_JP ? "当駅止" : string}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
|
@@ -1,16 +1,18 @@
|
||||
import React, { FC } from "react";
|
||||
import { Text, View } from "react-native";
|
||||
import { getTrainType } from "../../../lib/getTrainType";
|
||||
import { trainTypeID } from "@/lib/CommonTypes";
|
||||
type Props = {
|
||||
trainName: string;
|
||||
trainNumDistance?: number;
|
||||
trainIDSwitch: boolean;
|
||||
trainID: string;
|
||||
type: string;
|
||||
type: trainTypeID;
|
||||
isThrew: boolean;
|
||||
};
|
||||
export const TrainName: FC<Props> = (props) => {
|
||||
const { trainName, trainNumDistance, trainIDSwitch, trainID, type } = props;
|
||||
const { name, color } = getTrainType(type);
|
||||
const { trainName, trainNumDistance, trainIDSwitch, trainID, type, isThrew } = props;
|
||||
const { name, color } = getTrainType({ type });
|
||||
const TrainNumber =
|
||||
trainNumDistance != undefined
|
||||
? `${
|
||||
@@ -26,7 +28,7 @@ export const TrainName: FC<Props> = (props) => {
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{trainIDSwitch ? trainID : `${name} ${trainName}${TrainNumber}`}
|
||||
{trainIDSwitch ? trainID : `${isThrew ? `★通過列車★` : `${name} ${trainName}${TrainNumber}`} `}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import React, { FC, useEffect } from "react";
|
||||
import React, { FC, useEffect, useState } from "react";
|
||||
import { Text, TextStyle, View, TouchableOpacity } from "react-native";
|
||||
import { useStationList } from "../../../stateBox/useStationList";
|
||||
import {
|
||||
@@ -14,56 +14,118 @@ const descriptionStyle: TextStyle = {
|
||||
};
|
||||
|
||||
type Props = {
|
||||
// LED表示関係
|
||||
numberOfLines?: number;
|
||||
trainIDSwitch: boolean;
|
||||
currentTrainData: trainDataType;
|
||||
setStationInput: (station: string) => void;
|
||||
setStationNumberInput: (station: string) => void;
|
||||
setDescInput: (desc: string) => void;
|
||||
setPosInput: (pos: string) => void;
|
||||
//ポップアップ表示関係
|
||||
setDialog: (dialog: boolean) => void;
|
||||
setDeleteDialog: (dialog: boolean) => void;
|
||||
platformDescription: string;
|
||||
platformNumber: number;
|
||||
setPlatformDescription: (desc: string) => void;
|
||||
setPlatformNumber: (num: number) => void;
|
||||
|
||||
//固定値設定
|
||||
setPos: React.Dispatch<React.SetStateAction<string>>
|
||||
setPosNum: React.Dispatch<React.SetStateAction<number>>;
|
||||
setLine: React.Dispatch<React.SetStateAction<string>>;
|
||||
setStationNum: React.Dispatch<React.SetStateAction<string>>;
|
||||
|
||||
//編集機能関係
|
||||
setLineInput: (line: string) => void;
|
||||
setPosInput: (pos: string) => void;
|
||||
setDescInput: (desc: string) => void;
|
||||
};
|
||||
|
||||
export const TrainPosition: FC<Props> = ({
|
||||
// LED表示関係
|
||||
numberOfLines = 0,
|
||||
trainIDSwitch,
|
||||
currentTrainData,
|
||||
setStationInput,
|
||||
setStationNumberInput,
|
||||
setDescInput,
|
||||
setPosInput,
|
||||
//ポップアップ表示関係
|
||||
setDialog,
|
||||
setDeleteDialog,
|
||||
setPlatformDescription,
|
||||
setPlatformNumber,
|
||||
platformDescription,
|
||||
platformNumber,
|
||||
}) => {
|
||||
const { currentTrain } = useCurrentTrain();
|
||||
const { stationList } = useStationList();
|
||||
|
||||
//固定値設定
|
||||
setPos,
|
||||
setPosNum,
|
||||
setLine,
|
||||
setStationNum,
|
||||
|
||||
//編集機能関係
|
||||
setLineInput,
|
||||
setPosInput,
|
||||
setDescInput,
|
||||
|
||||
}) => {
|
||||
const { stationList } = useStationList();
|
||||
type data = {
|
||||
type: string;
|
||||
lineNumber: string;
|
||||
platformNumber: string;
|
||||
position: string;
|
||||
stationName: string;
|
||||
description: string;
|
||||
};
|
||||
const [database, setDatabase] = useState<data>(null);
|
||||
const [text, setText] = useState("");
|
||||
const [masterText, setMasterText] = useState("");
|
||||
useEffect(() => {
|
||||
const text = `${currentTrainData?.PosNum} ${currentTrainData?.Line} ${currentTrainData?.Pos}`;
|
||||
setText(trainIDSwitch ? text : masterText);
|
||||
return () => {
|
||||
setText("");
|
||||
};
|
||||
}, [masterText, trainIDSwitch]);
|
||||
useEffect(() => {
|
||||
fetch(
|
||||
`https://n8n.haruk.in/webhook/JR-shikoku-PosID?PosNum=${currentTrainData?.PosNum}&Line=${currentTrainData?.Line}`
|
||||
`https://n8n.haruk.in/webhook/JR-shikoku-PosID-v3?PosId=${currentTrainData?.PosNum}&lineName=${currentTrainData?.Line}&StationName=${currentTrainData?.Pos}`
|
||||
)
|
||||
.then((res) => res.json())
|
||||
.then((data: { type: string; platform: number; description: string }) => {
|
||||
setPlatformNumber(data?.type == "Station" ? data?.platform : undefined);
|
||||
setPlatformDescription(
|
||||
data?.type == "Station" ? data?.description : undefined
|
||||
);
|
||||
.then((data: data) => {
|
||||
const { type, platformNumber, description, lineNumber } = data;
|
||||
setDatabase(data);
|
||||
const { isBetween, Pos } = trainPosition(currentTrainData);
|
||||
if (isBetween === true) {
|
||||
// 移動中
|
||||
setMasterText(`現在地:${Pos.from}→${Pos.to}間を走行中`);
|
||||
} else {
|
||||
if (Pos.Pos) {
|
||||
let platform = platformNumber ? `${platformNumber}番乗り場` : "";
|
||||
let line = lineNumber ? `${lineNumber}番線` : "";
|
||||
setMasterText(
|
||||
`現在地:${Pos.Pos} ${platform || line} ${description || ""}`
|
||||
);
|
||||
} else {
|
||||
setMasterText("");
|
||||
}
|
||||
}
|
||||
});
|
||||
}, [currentTrainData, currentTrain]);
|
||||
return () => {
|
||||
setMasterText("");
|
||||
};
|
||||
}, [currentTrainData?.PosNum, currentTrainData?.Line, currentTrainData?.Pos]);
|
||||
//editWindow向けにfixした情報を送信
|
||||
const openEditWindow = () => {
|
||||
const { isBetween, Pos } = trainPosition(currentTrainData);
|
||||
|
||||
const trainPositionText = (trainData: trainDataType) => {
|
||||
const { isBetween, Pos } = trainPosition(trainData);
|
||||
if (isBetween === true) return `現在地:${Pos.from}→${Pos.to}間を走行中`;
|
||||
else return Pos.Pos == "" ? "" : `現在地:${Pos.Pos}`;
|
||||
//固定値
|
||||
setPosNum(currentTrainData?.PosNum);
|
||||
setPos(currentTrainData?.Pos);
|
||||
setLine(currentTrainData?.Line);
|
||||
setStationNum(getStationID(currentTrainData?.Pos, stationList));
|
||||
|
||||
//入力欄
|
||||
if (isBetween === true) {
|
||||
if (
|
||||
database?.platformNumber == undefined &&
|
||||
database?.description == undefined
|
||||
)
|
||||
return;
|
||||
setDeleteDialog(true);
|
||||
} else {
|
||||
setPosInput(database?.platformNumber?.toString() || "");
|
||||
setDescInput(database?.description || "");
|
||||
setLineInput(database?.lineNumber?.toString() || "");
|
||||
setDialog(true);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -78,40 +140,14 @@ export const TrainPosition: FC<Props> = ({
|
||||
flexDirection: "row",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
onLongPress={() => {
|
||||
const { isBetween, Pos } = trainPosition(currentTrainData);
|
||||
if (isBetween === true) {
|
||||
if (platformNumber == undefined && platformDescription == undefined)
|
||||
return;
|
||||
setStationInput(`${Pos.from}→${Pos.to}間`);
|
||||
setStationNumberInput(
|
||||
getStationID(currentTrainData?.Pos, stationList)
|
||||
);
|
||||
setPosInput(platformNumber?.toString() || "");
|
||||
setDeleteDialog(true);
|
||||
} else {
|
||||
setStationInput(Pos.Pos);
|
||||
setStationNumberInput(
|
||||
getStationID(currentTrainData?.Pos, stationList)
|
||||
);
|
||||
setDescInput(platformDescription || "");
|
||||
setPosInput(platformNumber?.toString() || "");
|
||||
setDialog(true);
|
||||
}
|
||||
}}
|
||||
onLongPress={openEditWindow}
|
||||
>
|
||||
<View style={{ flex: 4, flexDirection: "row" }}>
|
||||
<Text
|
||||
style={{ ...descriptionStyle, color: "green" }}
|
||||
numberOfLines={numberOfLines}
|
||||
>
|
||||
{`${
|
||||
trainIDSwitch
|
||||
? currentTrainData?.PosNum + currentTrainData?.Line
|
||||
: trainPositionText(currentTrainData)
|
||||
} ${platformNumber ? platformNumber + "番線" : ""} ${
|
||||
platformDescription ? "(" + platformDescription + ")" : ""
|
||||
}`}
|
||||
{text}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
@@ -1,28 +1,32 @@
|
||||
import React, { FC } from "react";
|
||||
import { Text } from "react-native";
|
||||
import { Dialog, Button } from "react-native-elements";
|
||||
import { trainDataType } from "../../../lib/trainPositionTextArray";
|
||||
|
||||
type Props = {
|
||||
dialog: boolean;
|
||||
setDialog: (dialog: boolean) => void;
|
||||
currentTrainData: trainDataType;
|
||||
stationInput: string;
|
||||
stationNumberInput: string;
|
||||
PosNum: number;
|
||||
Line: string;
|
||||
Pos: string;
|
||||
StationNum: string;
|
||||
};
|
||||
export const TrainPositionDataDelete: FC<Props> = ({
|
||||
|
||||
export const StationPosDeleteDialog: FC<Props> = ({
|
||||
dialog,
|
||||
setDialog,
|
||||
currentTrainData,
|
||||
stationInput,
|
||||
stationNumberInput,
|
||||
PosNum,
|
||||
Line,
|
||||
Pos,
|
||||
StationNum
|
||||
}) => {
|
||||
const sendPlatformData = () => {
|
||||
fetch(`https://n8n.haruk.in/webhook/JR-shikoku-PosID`, {
|
||||
fetch(`https://n8n.haruk.in/webhook/JR-shikoku-PosID-v3`, {
|
||||
method: "DELETE",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
PosId: currentTrainData?.PosNum,
|
||||
lineName: currentTrainData?.Line,
|
||||
PosId: PosNum,
|
||||
lineName: Line,
|
||||
StationName: Pos, //自動:駅名、漢字
|
||||
}),
|
||||
})
|
||||
.then(() => {
|
||||
@@ -36,10 +40,10 @@ export const TrainPositionDataDelete: FC<Props> = ({
|
||||
return (
|
||||
<Dialog isVisible={dialog} onBackdropPress={() => setDialog(false)}>
|
||||
<Text>以下のデータを誤情報として削除要求を出しますか?</Text>
|
||||
<Text>路線: {currentTrainData?.Line}</Text>
|
||||
<Text>地点ID: {currentTrainData?.PosNum}</Text>
|
||||
<Text>駅名: {stationInput}</Text>
|
||||
<Text>駅ナンバー: {stationNumberInput}</Text>
|
||||
<Text>路線: {Line}</Text>
|
||||
<Text>地点ID: {PosNum}</Text>
|
||||
<Text>駅名: {Pos}</Text>
|
||||
<Text>駅ナンバー: {StationNum}</Text>
|
||||
<Button title="送信" onPress={sendPlatformData} />
|
||||
</Dialog>
|
||||
);
|
||||
|
@@ -1,46 +1,56 @@
|
||||
import React, { FC, useState } from "react";
|
||||
import React, { FC } from "react";
|
||||
import { Text } from "react-native";
|
||||
import { Dialog, Input, Button } from "react-native-elements";
|
||||
import { trainDataType } from "../../../lib/trainPositionTextArray";
|
||||
import { useCurrentTrain } from "../../../stateBox/useCurrentTrain";
|
||||
import { getStationID } from "@/lib/eachTrainInfoCoreLib/getStationData";
|
||||
import { useStationList } from "@/stateBox/useStationList";
|
||||
type Props = {
|
||||
dialog: boolean;
|
||||
setDialog: (dialog: boolean) => void;
|
||||
currentTrainData: trainDataType;
|
||||
stationInput: string;
|
||||
stationNumberInput: string;
|
||||
|
||||
PosNum:number;
|
||||
Pos:string;
|
||||
Line:string;
|
||||
StationNum: string;
|
||||
|
||||
lineInput: string;
|
||||
setLineInput: (line: string) => void;
|
||||
posInput: string;
|
||||
descInput: string;
|
||||
setPosInput: (pos: string) => void;
|
||||
descInput: string;
|
||||
setDescInput: (desc: string) => void;
|
||||
station: {
|
||||
Station_JP: string;
|
||||
StationNumber: string;
|
||||
};
|
||||
};
|
||||
export const TrainPositionDataPush: FC<Props> = ({
|
||||
export const StationPosPushDialog: FC<Props> = ({
|
||||
// Dialog表示関係
|
||||
dialog,
|
||||
setDialog,
|
||||
currentTrainData,
|
||||
stationInput,
|
||||
stationNumberInput,
|
||||
//固定情報
|
||||
PosNum,//地点ID
|
||||
Pos,//駅名
|
||||
Line,//路線名
|
||||
StationNum,//駅ナンバリング
|
||||
|
||||
//入力欄
|
||||
lineInput,
|
||||
setLineInput,
|
||||
posInput,
|
||||
descInput,
|
||||
setPosInput,
|
||||
descInput,
|
||||
setDescInput,
|
||||
station,
|
||||
}) => {
|
||||
const { stationList } = useStationList();
|
||||
const sendPlatformData = () => {
|
||||
fetch(`https://n8n.haruk.in/webhook/JR-shikoku-PosID`, {
|
||||
fetch(`https://n8n.haruk.in/webhook/JR-shikoku-PosID-v3`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
PosId: currentTrainData?.PosNum,
|
||||
lineName: currentTrainData?.Line,
|
||||
PlatformNum: parseInt(posInput),
|
||||
Description: descInput,
|
||||
StationName: station.Station_JP,
|
||||
StationId: station.StationNumber,
|
||||
PosId: PosNum, //自動:位置情報ID
|
||||
StationId: getStationID(Pos, stationList), //自動:駅ID
|
||||
StationName: Pos, //自動:駅名、漢字
|
||||
lineName: Line, //自動:位置情報路線ID(koutoku/yosan)
|
||||
Description: descInput, //手動入力、参考情報
|
||||
platformNumber: parseInt(posInput), //手動入力、乗り場表記
|
||||
lineNumber: parseInt(lineInput), //手動入力、番線表記
|
||||
}),
|
||||
})
|
||||
.then(() => {
|
||||
@@ -55,22 +65,30 @@ export const TrainPositionDataPush: FC<Props> = ({
|
||||
};
|
||||
return (
|
||||
<Dialog isVisible={dialog} onBackdropPress={() => setDialog(false)}>
|
||||
<Text>路線: {currentTrainData?.Line}</Text>
|
||||
<Text>地点ID: {currentTrainData?.PosNum}</Text>
|
||||
<Text>駅名: {stationInput}</Text>
|
||||
<Text>駅ナンバー: {stationNumberInput}</Text>
|
||||
<Text style={{ fontSize: 20, fontWeight: "bold" }}>駅番線情報投稿機能</Text>
|
||||
<Text>路線: {Line}</Text>
|
||||
<Text>地点ID: {PosNum}</Text>
|
||||
<Text>駅名: {Pos}</Text>
|
||||
<Text>駅ナンバー: {StationNum}</Text>
|
||||
<Input
|
||||
label="番線"
|
||||
label="乗り場"
|
||||
inputMode="numeric"
|
||||
value={posInput}
|
||||
onChangeText={setPosInput}
|
||||
/>
|
||||
<Input
|
||||
label="番線"
|
||||
inputMode="numeric"
|
||||
value={lineInput}
|
||||
onChangeText={setLineInput}
|
||||
/>
|
||||
<Input
|
||||
label="参考情報"
|
||||
inputMode="text"
|
||||
value={descInput}
|
||||
onChangeText={setDescInput}
|
||||
/>
|
||||
<Text style={{ fontSize: 12, fontWeight: "bold" }}>この機能は駅の停車位置に関する情報を投稿する機能です。列車の遅れ、運行情報を投稿するフォームではありませんのでご注意ください。</Text>
|
||||
<Button title="送信" onPress={sendPlatformData} />
|
||||
</Dialog>
|
||||
);
|
||||
|
@@ -1,259 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { View, useWindowDimensions } from "react-native";
|
||||
import dayjs from "dayjs";
|
||||
import { useInterval } from "../../lib/useInterval";
|
||||
import { objectIsEmpty } from "../../lib/objectIsEmpty";
|
||||
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
|
||||
import { useAreaInfo } from "../../stateBox/useAreaInfo";
|
||||
import { AS } from "../../storageControl";
|
||||
import { Footer } from "./LED_Vision_Component/Footer";
|
||||
import { Header } from "./LED_Vision_Component/Header";
|
||||
import { Description } from "./LED_inside_Component/Description";
|
||||
import { EachData } from "./EachData";
|
||||
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||
import { trainPosition } from "@/lib/trainPositionTextArray";
|
||||
|
||||
/**
|
||||
*
|
||||
* 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, 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();
|
||||
const { allTrainDiagram } = useAllTrainDiagram();
|
||||
|
||||
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 (!allTrainDiagram) {
|
||||
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]);
|
||||
|
||||
/*
|
||||
{lastStation: "当駅止", time: "12:34", train: "1234M"}
|
||||
*/
|
||||
const [trainTimeAndNumber, setTrainTimeAndNumber] = useState([]);
|
||||
|
||||
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)) //現在の列車に絞る[ToDo]
|
||||
.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 if (data.match(",着,")) {
|
||||
trainData.time = data.split(",着,")[1];
|
||||
trainData.lastStation = "当駅止";
|
||||
}
|
||||
}
|
||||
});
|
||||
return {
|
||||
train: trainNum,
|
||||
time: trainData.time,
|
||||
lastStation: trainData.lastStation,
|
||||
};
|
||||
})
|
||||
.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 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 != "当駅止") return true;
|
||||
} else if (station[0].Station_JP == PrePos) {
|
||||
return false;
|
||||
}
|
||||
const date = dayjs();
|
||||
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 db = date.hour(parseInt(h)).minute(parseInt(m) + parseInt(delay));
|
||||
return !date.isAfter(db);
|
||||
}
|
||||
};
|
||||
|
||||
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]);
|
||||
const { width } = useWindowDimensions();
|
||||
const adjustedWidth = width * 0.98;
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
width: adjustedWidth,
|
||||
/* height: wp("98%")/10*9, */ backgroundColor: "#432",
|
||||
borderWidth: 1,
|
||||
margin: 10,
|
||||
marginHorizontal: width * 0.01,
|
||||
}}
|
||||
>
|
||||
<Header station={station[0]} />
|
||||
{selectedTrain.map((d) => (
|
||||
<EachData
|
||||
{...{
|
||||
d,
|
||||
trainIDSwitch,
|
||||
trainDescriptionSwitch,
|
||||
navigate,
|
||||
openStationACFromEachTrainInfo,
|
||||
}}
|
||||
station={station[0]}
|
||||
key={d.train}
|
||||
/>
|
||||
))}
|
||||
{areaString != "" && isInfoArea && (
|
||||
<Description
|
||||
numberOfLines={1}
|
||||
info={areaString.replaceAll("\n", "").replaceAll("\r", "")}
|
||||
onClick={() => alert(areaInfo)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Footer
|
||||
{...{
|
||||
trainIDSwitch,
|
||||
setTrainIDSwitch,
|
||||
trainDescriptionSwitch,
|
||||
setTrainDescriptionSwitch,
|
||||
finalSwitch,
|
||||
setFinalSwitch,
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
164
components/発車時刻表/LED_vidion.tsx
Normal file
164
components/発車時刻表/LED_vidion.tsx
Normal file
@@ -0,0 +1,164 @@
|
||||
import React, { useState, useEffect, FC } from "react";
|
||||
import { View, useWindowDimensions } from "react-native";
|
||||
import { objectIsEmpty } from "@/lib/objectIsEmpty";
|
||||
import { useCurrentTrain } from "@/stateBox/useCurrentTrain";
|
||||
import { useAreaInfo } from "@/stateBox/useAreaInfo";
|
||||
import { AS } from "@/storageControl";
|
||||
import { Footer } from "@/components/発車時刻表/LED_Vision_Component/Footer";
|
||||
import { Header } from "@/components/発車時刻表/LED_Vision_Component/Header";
|
||||
import { EachData } from "@/components/発車時刻表/EachData";
|
||||
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||
import { AreaDescription } from "@/components/発車時刻表/LED_inside_Component/AreaDescription";
|
||||
import { getTime, trainTimeFiltering } from "@/lib/trainTimeFiltering";
|
||||
import { eachTrainDiagramType, StationProps } from "@/lib/CommonTypes";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
|
||||
/**
|
||||
*
|
||||
* 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 四国まんなか千年ものがたり(臨時?)
|
||||
*/
|
||||
type props = {
|
||||
station: StationProps[];
|
||||
};
|
||||
export const LED_vision: FC<props> = (props) => {
|
||||
const { station } = props;
|
||||
|
||||
const { navigate, addListener, isFocused } = useNavigation();
|
||||
const { currentTrain } = useCurrentTrain();
|
||||
const [stationDiagram, setStationDiagram] = useState<{
|
||||
[key: string]: string;
|
||||
}>({}); //当該駅の全時刻表
|
||||
const [finalSwitch, setFinalSwitch] = useState(false);
|
||||
const [trainIDSwitch, setTrainIDSwitch] = useState(false);
|
||||
const [trainDescriptionSwitch, setTrainDescriptionSwitch] = useState(false);
|
||||
const [isInfoArea, setIsInfoArea] = useState(false);
|
||||
const { areaInfo, areaStationID } = useAreaInfo();
|
||||
const { allTrainDiagram } = useAllTrainDiagram();
|
||||
|
||||
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 (!allTrainDiagram) {
|
||||
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]);
|
||||
|
||||
/*
|
||||
{lastStation: "当駅止", time: "12:34", train: "1234M"}
|
||||
*/
|
||||
const [trainTimeAndNumber, setTrainTimeAndNumber] = useState<
|
||||
eachTrainDiagramType[]
|
||||
>([]);
|
||||
|
||||
useEffect(() => {
|
||||
//現在の駅に停車する列車から時刻を切り出してLEDベースにフォーマット
|
||||
if (objectIsEmpty(stationDiagram)) return () => {};
|
||||
const getTimeData = getTime(stationDiagram, station[0]);
|
||||
setTrainTimeAndNumber(getTimeData);
|
||||
}, [stationDiagram]);
|
||||
|
||||
const [selectedTrain, setSelectedTrain] = useState<eachTrainDiagramType[]>(
|
||||
[]
|
||||
);
|
||||
useEffect(() => {
|
||||
if (!trainTimeAndNumber) return () => {};
|
||||
if (!currentTrain) return () => {};
|
||||
const data = trainTimeAndNumber
|
||||
.filter((d) => currentTrain.map((m) => m.num).includes(d.train)) //現在の列車に絞る[ToDo]
|
||||
.filter((d) => trainTimeFiltering({ d, currentTrain, station })) //時間フィルター
|
||||
.filter((d) => !!finalSwitch || d.lastStation != station[0].Station_JP); //最終列車表示設定
|
||||
setSelectedTrain(data);
|
||||
}, [trainTimeAndNumber, currentTrain, finalSwitch]);
|
||||
|
||||
const { width } = useWindowDimensions();
|
||||
const adjustedWidth = width * 0.98;
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
width: adjustedWidth,
|
||||
/* height: wp("98%")/10*9, */ backgroundColor: "#432",
|
||||
borderWidth: 1,
|
||||
margin: 10,
|
||||
marginHorizontal: width * 0.01,
|
||||
}}
|
||||
>
|
||||
<Header station={station[0]} />
|
||||
{selectedTrain.map((d) => (
|
||||
<EachData
|
||||
{...{
|
||||
d,
|
||||
trainIDSwitch,
|
||||
trainDescriptionSwitch,
|
||||
navigate,
|
||||
openStationACFromEachTrainInfo: () => {},
|
||||
}}
|
||||
station={station[0]}
|
||||
key={d.train}
|
||||
/>
|
||||
))}
|
||||
{areaInfo != "" && isInfoArea && (
|
||||
<AreaDescription
|
||||
numberOfLines={1}
|
||||
areaInfo={areaInfo}
|
||||
onClick={() => alert(areaInfo)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Footer
|
||||
{...{
|
||||
trainIDSwitch,
|
||||
setTrainIDSwitch,
|
||||
trainDescriptionSwitch,
|
||||
setTrainDescriptionSwitch,
|
||||
finalSwitch,
|
||||
setFinalSwitch,
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
@@ -197,9 +197,7 @@ export default function Sign(props) {
|
||||
source={require("../../assets/StationSign.json")}
|
||||
/>
|
||||
)}
|
||||
<StationNumberMaker
|
||||
{...{ currentStation: currentStationData, isMatsuyama }}
|
||||
/>
|
||||
<StationNumberMaker {...{ currentStation: currentStationData }} />
|
||||
<StationNameArea
|
||||
{...{ currentStation: currentStationData, isMatsuyama }}
|
||||
/>
|
||||
|
@@ -1,10 +1,16 @@
|
||||
import React from "react";
|
||||
import React, { FC } from "react";
|
||||
import { Text, View } from "react-native";
|
||||
import { useWindowDimensions } from "react-native";
|
||||
import lineColorList from "../../assets/originData/lineColorList";
|
||||
import lineColorList from "@/assets/originData/lineColorList";
|
||||
import { StationProps } from "@/lib/CommonTypes";
|
||||
|
||||
export const StationNumberMaker = (props) => {
|
||||
const { currentStation, isMatsuyama } = props;
|
||||
type props = {
|
||||
currentStation: StationProps[];
|
||||
useEach?: boolean;
|
||||
singleSize?: number;
|
||||
};
|
||||
export const StationNumberMaker: FC<props> = (props) => {
|
||||
const { currentStation, useEach = false, singleSize } = props;
|
||||
const { width } = useWindowDimensions();
|
||||
const getTop = (array: number[], index: number) => {
|
||||
if (array.length == 1) return 20;
|
||||
@@ -12,7 +18,7 @@ export const StationNumberMaker = (props) => {
|
||||
else if (index == 1) return 35;
|
||||
else return 20;
|
||||
};
|
||||
return currentStation
|
||||
return <>{currentStation
|
||||
.filter((d) => (d.StationNumber ? true : false))
|
||||
.map((d, index, array) => {
|
||||
const lineID = d.StationNumber.slice(0, 1);
|
||||
@@ -20,29 +26,41 @@ export const StationNumberMaker = (props) => {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
position: "absolute",
|
||||
alignContent: "center",
|
||||
alignItems: "center",
|
||||
top: `${getTop(array, index)}%`,
|
||||
right: "10%",
|
||||
width: (width / 100 * 10),
|
||||
height: (width / 100 * 10),
|
||||
borderColor: lineColorList[lineID],
|
||||
backgroundColor: "white",
|
||||
...(useEach ? {
|
||||
width: singleSize,
|
||||
height: singleSize,
|
||||
borderWidth: parseInt("1%"),
|
||||
borderRadius: parseInt("100%"),
|
||||
} : {
|
||||
width: (width / 100) * 10,
|
||||
height: (width / 100) * 10,
|
||||
borderWidth: parseInt("3%"),
|
||||
borderRadius: parseInt("100%"),
|
||||
position: "absolute",
|
||||
top: `${getTop(array, index)}%`,
|
||||
right: "10%"
|
||||
})
|
||||
}}
|
||||
key={array[index].StationNumber}
|
||||
>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Text
|
||||
style={{
|
||||
fontSize: parseInt("13%"),
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
textAlign: "center",
|
||||
color: "black",
|
||||
color: "black",
|
||||
fontWeight: "bold",
|
||||
...(useEach ? {
|
||||
|
||||
fontSize: 6,//singleSize * 0.03,
|
||||
}:{
|
||||
fontSize: parseInt("13%"),
|
||||
})
|
||||
}}
|
||||
>
|
||||
{lineID + "\n" + lineName}
|
||||
@@ -50,5 +68,5 @@ export const StationNumberMaker = (props) => {
|
||||
<View style={{ flex: 1 }} />
|
||||
</View>
|
||||
);
|
||||
});
|
||||
})}</>
|
||||
};
|
||||
|
58
lib/CommonTypes.ts
Normal file
58
lib/CommonTypes.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
export type trainTypeID =
|
||||
| "Normal"
|
||||
| "OneMan"
|
||||
| "Rapid"
|
||||
| "OneManRapid"
|
||||
| "LTDEXP"
|
||||
| "NightLTDEXP"
|
||||
| "SPCL"
|
||||
| "SPCL_Normal"
|
||||
| "SPCL_Rapid"
|
||||
| "SPCL_EXP"
|
||||
| "Party"
|
||||
| "Freight"
|
||||
| "Forwarding"
|
||||
| "FreightForwarding"
|
||||
| "Other";
|
||||
|
||||
export type CustomTrainData = {
|
||||
ToData?: string;
|
||||
TrainNumber?: string;
|
||||
TrainNumberOverride?: string;
|
||||
id?: string;
|
||||
img?: string;
|
||||
isWanman?: boolean;
|
||||
trainName?: string;
|
||||
trainNumDistance?: number;
|
||||
type?: trainTypeID;
|
||||
viaData?: string;
|
||||
info?: string;
|
||||
infoUrl?: string;
|
||||
infogram?: string;
|
||||
uwasa?: string;
|
||||
isEdit?: boolean;
|
||||
isSeason?: boolean;
|
||||
vehicleFormation?: string;
|
||||
trainInfoUrl?: string;
|
||||
};
|
||||
export type eachTrainDiagramType = {
|
||||
train: string;
|
||||
time: string;
|
||||
lastStation: string;
|
||||
isThrough: boolean;
|
||||
};
|
||||
|
||||
export type StationProps = {
|
||||
DispNum: string;
|
||||
JrHpUrl?: string;
|
||||
MyStation: string;
|
||||
StationMap: string;
|
||||
StationNumber: string | null;
|
||||
StationTimeTable: string;
|
||||
Station_EN: string;
|
||||
Station_JP: string;
|
||||
jslodApi: string;
|
||||
lat: number;
|
||||
lng: number;
|
||||
};
|
@@ -21,15 +21,27 @@ export const findReversalPoints = (array, stopStationIDList) => {
|
||||
}
|
||||
// 駅間の場合
|
||||
if (array.length == 2) {
|
||||
const allThroughStation = stopStationIDList.map((d) => {
|
||||
if (
|
||||
(array[0] == "M12" && array[1] == "Y09") ||
|
||||
(array[0] == "Y09" && array[1] == "M12")
|
||||
)
|
||||
const allThroughStation = stopStationIDList.map((d, index, arrays) => {
|
||||
if (array[0] == "Y09" && array[1] == "M12") {
|
||||
return d[0] == "M12" ? true : false;
|
||||
} else if (array[0] == "M12" && array[1] == "Y09") {
|
||||
if (index) {
|
||||
if (arrays[index - 1][0] == "M12") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (array[0] == "U15" && array[1] == "U14") {
|
||||
|
||||
return d[0] == "U13" ? true : false;
|
||||
} else if (array[0] == "S17" && array[1] == "U14") {
|
||||
|
||||
return d[0] == "U14" ? true : false;
|
||||
}
|
||||
|
||||
let returndata = false;
|
||||
d.forEach((x) => {
|
||||
console.log(array, x, d);
|
||||
if (array[0] < x && x < array[1]) {
|
||||
returndata = true;
|
||||
} else if (array[0] < x && x == array[1]) {
|
||||
|
@@ -8,8 +8,9 @@ export const searchSpecialTrain = (trainNum: string, trainList: any[]) => {
|
||||
}
|
||||
return false;
|
||||
};
|
||||
if (search("D")) return searchBase + "D";
|
||||
if (search("M")) return searchBase + "M";
|
||||
const returnBase = [];
|
||||
if (search("D")) returnBase.push(searchBase + "D");
|
||||
if (search("M")) returnBase.push(searchBase + "M");
|
||||
|
||||
//増結いしづちの場合
|
||||
const baseStr = trainNum
|
||||
@@ -21,6 +22,7 @@ export const searchSpecialTrain = (trainNum: string, trainList: any[]) => {
|
||||
if (9000 < baseNum && baseNum < 9047) {
|
||||
//いしづちの1001M-1046Mが9000番台になっている場合に発動
|
||||
const TD = trainList[`${baseNum - 8000}M`];
|
||||
if (TD) return `${baseNum - 8000}M`;
|
||||
if (TD) returnBase.push(`${baseNum - 8000}M`);
|
||||
}
|
||||
return returnBase;
|
||||
};
|
||||
|
31
lib/getCurrentTrainData.ts
Normal file
31
lib/getCurrentTrainData.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { customTrainDataDetector } from "@/components/custom-train-data";
|
||||
import { CustomTrainData, trainTypeID } from "./CommonTypes";
|
||||
import { trainDataType } from "./trainPositionTextArray";
|
||||
|
||||
export const getCurrentTrainData = (
|
||||
trainNum: string,
|
||||
currentTrain: trainDataType[],
|
||||
allCustomTrainData: CustomTrainData[] | undefined
|
||||
) => {
|
||||
const customTrainData = customTrainDataDetector(trainNum, 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" as trainTypeID,
|
||||
trainName: typeText[1].replace("\r", ""),
|
||||
trainIcon: null,
|
||||
trainNumDistance: null,
|
||||
info: "",
|
||||
};
|
||||
return returnData;
|
||||
}
|
||||
return customTrainData;
|
||||
default:
|
||||
return customTrainData;
|
||||
}
|
||||
};
|
49
lib/getStringConfig.ts
Normal file
49
lib/getStringConfig.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { trainTypeID } from "@/lib/CommonTypes";
|
||||
|
||||
type types = (types: trainTypeID, id: string) => [string, boolean, boolean];
|
||||
export const getStringConfig: types = (type, id) => {
|
||||
switch (type) {
|
||||
case "Normal":
|
||||
return ["普通", true, false];
|
||||
case "OneMan":
|
||||
return ["普通", true, true];
|
||||
case "Rapid":
|
||||
return ["快速", true, false];
|
||||
case "OneManRapid":
|
||||
return ["快速", true, true];
|
||||
case "LTDEXP":
|
||||
return ["特急", true, false];
|
||||
case "NightLTDEXP":
|
||||
return ["特急", true, false];
|
||||
case "SPCL":
|
||||
return ["臨時", true, false];
|
||||
case "SPCL_Normal":
|
||||
return ["臨時", true, false];
|
||||
case "SPCL_Rapid":
|
||||
return ["臨時快速", true, false];
|
||||
case "SPCL_EXP":
|
||||
return ["臨時特急", true, false];
|
||||
case "Party":
|
||||
return ["団体臨時", true, false];
|
||||
case "Freight":
|
||||
return ["貨物", false, false];
|
||||
case "Forwarding":
|
||||
return ["回送", false, false];
|
||||
case "FreightForwarding":
|
||||
return ["単機回送", false, false];
|
||||
case "Other":
|
||||
switch (true) {
|
||||
case !!id.includes("T"):
|
||||
return ["単機回送", false, false];
|
||||
case !!id.includes("R"):
|
||||
case !!id.includes("E"):
|
||||
case !!id.includes("L"):
|
||||
case !!id.includes("A"):
|
||||
case !!id.includes("B"):
|
||||
return ["回送", false, false];
|
||||
case !!id.includes("H"):
|
||||
return ["試運転", false, false];
|
||||
}
|
||||
return ["", false, false];
|
||||
}
|
||||
};
|
@@ -1,11 +1,18 @@
|
||||
type nameString =
|
||||
| "Rapid"
|
||||
| "LTDEXP"
|
||||
| "NightLTDEXP"
|
||||
| "SPCL"
|
||||
| "Normal"
|
||||
| string;
|
||||
type colorString = "aqua" | "red" | "#297bff" | "white" | "pink";
|
||||
import { trainTypeID } from "./CommonTypes";
|
||||
|
||||
export type colorString =
|
||||
| "aqua"
|
||||
| "#00a0bdff"
|
||||
| "#007488ff"
|
||||
| "red"
|
||||
| "#297bff"
|
||||
| "#ff7300ff"
|
||||
| "#5f5f5fff"
|
||||
| "#e000b0ff"
|
||||
| "white"
|
||||
| "black"
|
||||
| "pink";
|
||||
|
||||
type trainTypeString =
|
||||
| "快速"
|
||||
| "特急"
|
||||
@@ -13,32 +20,191 @@ type trainTypeString =
|
||||
| "臨時"
|
||||
| "普通列車"
|
||||
| "普通列車(ワンマン)"
|
||||
| "臨時快速"
|
||||
| "臨時特急"
|
||||
| "団体臨時"
|
||||
| "貨物"
|
||||
| "回送"
|
||||
| "単機回送"
|
||||
| "試運転"
|
||||
| "その他";
|
||||
type trainTypeDataString = "rapid" | "express" | "normal";
|
||||
type getTrainType = (d: nameString) => {
|
||||
type trainTypeDataString = "rapid" | "express" | "normal" | "notService";
|
||||
type getTrainType = (e: {
|
||||
type: trainTypeID;
|
||||
id?: string;
|
||||
whiteMode?: boolean;
|
||||
}) => {
|
||||
color: colorString;
|
||||
name: trainTypeString;
|
||||
shortName: string;
|
||||
fontAvailable: boolean;
|
||||
isOneMan: boolean;
|
||||
data: trainTypeDataString;
|
||||
};
|
||||
export const getTrainType: getTrainType = (nameString) => {
|
||||
switch (nameString) {
|
||||
case "Rapid":
|
||||
case "OneManRapid":
|
||||
return { color: "aqua", name: "快速", data: "rapid" };
|
||||
case "LTDEXP":
|
||||
return { color: "red", name: "特急", data: "express" };
|
||||
case "NightLTDEXP":
|
||||
return { color: "pink", name: "寝台特急", data: "express" };
|
||||
case "SPCL":
|
||||
case "SPCL_Rapid":
|
||||
case "SPCL_EXP":
|
||||
case "SPCL_Normal":
|
||||
return { color: "#297bff", name: "臨時", data: "normal" };
|
||||
case "OneMan":
|
||||
return { color: "white", name: "普通列車(ワンマン)", data: "normal" };
|
||||
export const getTrainType: getTrainType = ({ type, id, whiteMode }) => {
|
||||
switch (type) {
|
||||
case "Normal":
|
||||
return { color: "white", name: "普通列車", data: "normal" };
|
||||
return {
|
||||
color: whiteMode ? "black" : "white",
|
||||
name: "普通列車",
|
||||
shortName: "普通",
|
||||
fontAvailable: true,
|
||||
isOneMan: false,
|
||||
data: "normal",
|
||||
};
|
||||
case "OneMan":
|
||||
return {
|
||||
color: whiteMode ? "black" : "white",
|
||||
name: "普通列車(ワンマン)",
|
||||
shortName: "普通",
|
||||
fontAvailable: true,
|
||||
isOneMan: true,
|
||||
data: "normal",
|
||||
};
|
||||
case "Rapid":
|
||||
return {
|
||||
color: whiteMode ? "#00a0bdff" : "aqua",
|
||||
name: "快速",
|
||||
shortName: "快速",
|
||||
fontAvailable: true,
|
||||
isOneMan: false,
|
||||
data: "rapid",
|
||||
};
|
||||
case "OneManRapid":
|
||||
return {
|
||||
color: whiteMode ? "#00a0bdff" : "aqua",
|
||||
name: "快速",
|
||||
shortName: "快速",
|
||||
fontAvailable: true,
|
||||
isOneMan: true,
|
||||
data: "rapid",
|
||||
};
|
||||
case "LTDEXP":
|
||||
return {
|
||||
color: "red",
|
||||
name: "特急",
|
||||
shortName: "特急",
|
||||
fontAvailable: true,
|
||||
isOneMan: false,
|
||||
data: "express",
|
||||
};
|
||||
case "NightLTDEXP":
|
||||
return {
|
||||
color: whiteMode ? "#e000b0ff" : "pink",
|
||||
name: "寝台特急",
|
||||
shortName: "特急",
|
||||
fontAvailable: true,
|
||||
isOneMan: false,
|
||||
data: "express",
|
||||
};
|
||||
case "SPCL":
|
||||
case "SPCL_Normal":
|
||||
return {
|
||||
color: "#297bff",
|
||||
name: "臨時",
|
||||
shortName: "臨時",
|
||||
fontAvailable: true,
|
||||
isOneMan: false,
|
||||
data: "normal",
|
||||
};
|
||||
case "SPCL_Rapid":
|
||||
return {
|
||||
color: "#297bff",
|
||||
name: "臨時快速",
|
||||
shortName: "臨時快速",
|
||||
fontAvailable: true,
|
||||
isOneMan: false,
|
||||
data: "normal",
|
||||
};
|
||||
case "SPCL_EXP":
|
||||
return {
|
||||
color: "#297bff",
|
||||
name: "臨時特急",
|
||||
shortName: "臨時特急",
|
||||
fontAvailable: true,
|
||||
isOneMan: false,
|
||||
data: "normal",
|
||||
};
|
||||
case "Party":
|
||||
return {
|
||||
color: "#ff7300ff",
|
||||
name: "団体臨時",
|
||||
shortName: "団体臨時",
|
||||
fontAvailable: true,
|
||||
isOneMan: false,
|
||||
data: "normal",
|
||||
};
|
||||
case "Freight":
|
||||
return {
|
||||
color: "#007488ff",
|
||||
name: "貨物",
|
||||
shortName: "貨物",
|
||||
fontAvailable: false,
|
||||
isOneMan: false,
|
||||
data: "notService",
|
||||
};
|
||||
case "Forwarding":
|
||||
return {
|
||||
color: "#5f5f5fff",
|
||||
name: "回送",
|
||||
shortName: "回送",
|
||||
fontAvailable: false,
|
||||
isOneMan: false,
|
||||
data: "notService",
|
||||
};
|
||||
case "FreightForwarding":
|
||||
return {
|
||||
color: "#5f5f5fff",
|
||||
name: "単機回送",
|
||||
shortName: "単機回送",
|
||||
fontAvailable: false,
|
||||
isOneMan: false,
|
||||
data: "notService",
|
||||
};
|
||||
case "Other":
|
||||
default:
|
||||
return { color: "white", name: "その他", data: "normal" };
|
||||
if (id) {
|
||||
switch (true) {
|
||||
case !!id.includes("T"):
|
||||
return {
|
||||
color: "#5f5f5fff",
|
||||
name: "単機回送",
|
||||
shortName: "単機回送",
|
||||
fontAvailable: false,
|
||||
isOneMan: false,
|
||||
data: "notService",
|
||||
};
|
||||
case !!id.includes("R"):
|
||||
case !!id.includes("E"):
|
||||
case !!id.includes("L"):
|
||||
case !!id.includes("A"):
|
||||
case !!id.includes("B"):
|
||||
return {
|
||||
color: "#5f5f5fff",
|
||||
name: "回送",
|
||||
shortName: "回送",
|
||||
fontAvailable: false,
|
||||
isOneMan: false,
|
||||
data: "notService",
|
||||
};
|
||||
case !!id.includes("H"):
|
||||
return {
|
||||
color: "#5f5f5fff",
|
||||
name: "試運転",
|
||||
shortName: "試運転",
|
||||
fontAvailable: false,
|
||||
isOneMan: false,
|
||||
data: "notService",
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
color: whiteMode ? "black" : "white",
|
||||
name: "その他",
|
||||
shortName: "その他",
|
||||
fontAvailable: false,
|
||||
isOneMan: false,
|
||||
data: "normal",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@@ -9,30 +9,13 @@ export const initIcon = (
|
||||
tabBarBadge: string,
|
||||
isInfo: boolean
|
||||
) => {
|
||||
switch (type) {
|
||||
case "Ionicons":
|
||||
return ({ focused, color, size }) => (
|
||||
<>
|
||||
{!!tabBarBadge && <Badge tabBarBadge={tabBarBadge} isInfo={isInfo} />}
|
||||
<Ionicons
|
||||
name={name}
|
||||
size={30}
|
||||
color={focused ? "#0099CC" : "black"}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
case "AntDesign":
|
||||
return ({ focused, color, size }) => (
|
||||
<>
|
||||
{!!tabBarBadge && <Badge tabBarBadge={tabBarBadge} isInfo={isInfo} />}
|
||||
<AntDesign
|
||||
name={name}
|
||||
size={30}
|
||||
color={focused ? "#0099CC" : "black"}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
const IconComponent = type == "Ionicons" ? Ionicons : AntDesign;
|
||||
return ({ focused, color, size }) => (
|
||||
<>
|
||||
{!!tabBarBadge && <Badge tabBarBadge={tabBarBadge} isInfo={isInfo} />}
|
||||
<IconComponent name={name} size={30} color={focused ? "#0099CC" : "black"} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
type BadgeProps = { tabBarBadge: string; isInfo: boolean };
|
||||
|
||||
@@ -60,7 +43,7 @@ export const Badge: FC<BadgeProps> = ({ tabBarBadge, isInfo }) => {
|
||||
shadowOffset: { width: 0, height: 0 },
|
||||
shadowOpacity: 0.5,
|
||||
shadowRadius: 4,
|
||||
elevation: 2
|
||||
elevation: 2,
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: "white", paddingHorizontal: 4 }}>
|
||||
|
@@ -18,7 +18,7 @@ export type trainDataType = {
|
||||
Line?: string;
|
||||
PosNum?: number;
|
||||
Type?: string;
|
||||
delay?: string | number;
|
||||
delay?: "入線" | number;
|
||||
num?: string;
|
||||
};
|
||||
type trainData = (
|
||||
|
107
lib/trainTimeFiltering.ts
Normal file
107
lib/trainTimeFiltering.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import dayjs from "dayjs";
|
||||
import { trainDataType, trainPosition } from "@/lib/trainPositionTextArray";
|
||||
import { eachTrainDiagramType, StationProps } from "@/lib/CommonTypes";
|
||||
type trainDataProps = {
|
||||
d: eachTrainDiagramType;
|
||||
currentTrain: trainDataType[];
|
||||
station: StationProps[];
|
||||
};
|
||||
export const trainTimeFiltering: (x: trainDataProps) => boolean = (props) => {
|
||||
const { d, currentTrain, station } = props;
|
||||
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]);
|
||||
let nextPos = "";
|
||||
let PrePos = "";
|
||||
//
|
||||
if (Pos.isBetween == true) {
|
||||
nextPos = Pos.Pos.to;
|
||||
PrePos = Pos.Pos.from;
|
||||
} else {
|
||||
nextPos = Pos.Pos.Pos;
|
||||
}
|
||||
const stationData = station[0].Station_JP;
|
||||
switch (stationData) {
|
||||
case nextPos:
|
||||
if (d.lastStation != stationData) return true;
|
||||
break;
|
||||
case PrePos:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
const [h, m] = d.time.split(":");
|
||||
const delayData = currentTrain.filter((t) => t.num == d.train)[0].delay;
|
||||
let delay = delayData === "入線" ? 0 : delayData;
|
||||
const date = dayjs();
|
||||
const IntH = parseInt(h) < 4 ? parseInt(h) + 24 : parseInt(h);
|
||||
const IntM = parseInt(m);
|
||||
const targetDate = date.hour(IntH).minute(IntM + delay);
|
||||
if (date.isAfter(targetDate)) return false;
|
||||
if (targetDate.diff(date) < baseTime * 60 * 60 * 1000) return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
type getTimeProps = (
|
||||
stationDiagram: { [key: string]: string },
|
||||
station: StationProps
|
||||
) => eachTrainDiagramType[];
|
||||
export const getTime: getTimeProps = (stationDiagram, station) => {
|
||||
const returnData = Object.keys(stationDiagram)
|
||||
.map((trainNum) => {
|
||||
let trainData: eachTrainDiagramType = {
|
||||
time: "",
|
||||
lastStation: "",
|
||||
isThrough: false,
|
||||
train: trainNum,
|
||||
};
|
||||
stationDiagram[trainNum].split("#").forEach((data) => {
|
||||
const [stationName, type, time] = data.split(",");
|
||||
if (!type) return;
|
||||
if (type.match("着")) {
|
||||
trainData.lastStation = stationName;
|
||||
}
|
||||
if (stationName === station.Station_JP) {
|
||||
if (type.match("発")) {
|
||||
trainData.time = time;
|
||||
} else if (type.match("通")) {
|
||||
trainData.time = time;
|
||||
trainData.isThrough = true;
|
||||
} else if (type.match("着")) {
|
||||
trainData.time = time;
|
||||
}
|
||||
}
|
||||
});
|
||||
return {
|
||||
train: trainNum,
|
||||
time: trainData.time,
|
||||
lastStation: trainData.lastStation,
|
||||
isThrough: trainData.isThrough,
|
||||
};
|
||||
})
|
||||
.filter((d) => d.time);
|
||||
return returnData.sort((a, b) => {
|
||||
let [aH, aM] = a.time.split(":");
|
||||
let [bH, bM] = b.time.split(":");
|
||||
if (parseInt(aH) < 4) aH = (parseInt(aH) + 24).toString();
|
||||
if (parseInt(bH) < 4) bH = (parseInt(bH) + 24).toString();
|
||||
const baseTime = dayjs();
|
||||
const aTime = baseTime.hour(parseInt(aH)).minute(parseInt(aM));
|
||||
const bTime = baseTime.hour(parseInt(bH)).minute(parseInt(bM));
|
||||
if (aTime.isBefore(bTime)) return -1;
|
||||
if (aTime.isAfter(bTime)) return 1;
|
||||
return 0;
|
||||
});
|
||||
};
|
@@ -24,6 +24,8 @@ export const useInterval = (fn: Fn, interval: number, autostart = true) => {
|
||||
useEffect(() => {
|
||||
if (autostart) {
|
||||
setState("RUNNING");
|
||||
}else{
|
||||
setState("STOPPED");
|
||||
}
|
||||
}, [autostart]);
|
||||
useEffect(() => {
|
||||
|
@@ -17,6 +17,7 @@ export const injectJavascriptData: InjectJavascriptData = (
|
||||
mapSwitch != "true"
|
||||
? `
|
||||
document.querySelector('#header a').style.display = 'none';
|
||||
document.querySelector('#main').style.left = '0px';
|
||||
document.querySelector('#header').style.height = '50px';
|
||||
document.querySelector('#main').style.paddingTop = '54px';
|
||||
document.querySelector('#headerStr').style.display = 'none';
|
||||
@@ -24,50 +25,91 @@ export const injectJavascriptData: InjectJavascriptData = (
|
||||
: `
|
||||
document.querySelector('.accordionClass').style.display = 'none';
|
||||
document.querySelector('#header').style.display = 'none';
|
||||
document.querySelector('#main').style.left = '0px';
|
||||
document.querySelector('#main').style.paddingTop = '0px';
|
||||
document.querySelector('#headerStr').style.display = 'none';
|
||||
`;
|
||||
|
||||
// 上部ヘッダーの取り扱い、自動再読み込み、setStringsの実行
|
||||
const bootData = `
|
||||
// 起動時にブラウザにlodashを読み込むscript追加処理
|
||||
const script = document.createElement('script');
|
||||
script.src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js";
|
||||
document.head.appendChild(script);
|
||||
|
||||
const script2 = document.createElement('link');
|
||||
script2.rel = "stylesheet";
|
||||
script2.href = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.0/css/all.min.css";
|
||||
document.head.appendChild(script2);
|
||||
|
||||
let stationList = {};
|
||||
fetch("https://n8n.haruk.in/webhook/jr-shikoku-station-list").then((response) => response.json()).then((data) => {
|
||||
stationList = data;
|
||||
});
|
||||
let trainDataList = [];
|
||||
fetch("https://n8n.haruk.in/webhook/jr-shikoku-position-custom-datalist").then((response) => response.json()).then((data) => {
|
||||
trainDataList = data[0].data;
|
||||
}).then(()=>setReload());
|
||||
let trainDiagramData2 = {};
|
||||
fetch("https://n8n.haruk.in/webhook/JR-shikoku-diagram-migrate-original")
|
||||
.then((response) => response.json())
|
||||
.then((res)=>res.data)
|
||||
.then((res) => {
|
||||
const data = {};
|
||||
res.forEach((d) => {
|
||||
const keys = Object.keys(d);
|
||||
data[keys] = d[keys];
|
||||
|
||||
let trainDataList = [];
|
||||
const DatalistUpdate = () =>{
|
||||
try{
|
||||
fetch("https://n8n.haruk.in/webhook/jr-shikoku-position-custom-datalist").then((response) => response.json())
|
||||
.then((data) => data[0].data)
|
||||
.then((data) => {
|
||||
if(!_.isEqual(data, trainDataList)) {
|
||||
trainDataList = data;
|
||||
setReload();
|
||||
}
|
||||
});
|
||||
return data;
|
||||
})
|
||||
.then((data) => {
|
||||
trainDiagramData2 = data;
|
||||
});
|
||||
}catch(error){}
|
||||
setTimeout(DatalistUpdate, 60000);
|
||||
}
|
||||
DatalistUpdate();
|
||||
|
||||
|
||||
let trainDiagramData2 = {};
|
||||
const TrainDiagramData2Update = () =>{
|
||||
try{
|
||||
fetch("https://n8n.haruk.in/webhook/JR-shikoku-diagram-migrate-original")
|
||||
.then((response) => response.json())
|
||||
.then((res)=>res.data)
|
||||
.then((res) => {
|
||||
const data = {};
|
||||
res.forEach((d) => {
|
||||
const keys = Object.keys(d);
|
||||
data[keys] = d[keys];
|
||||
});
|
||||
return data;
|
||||
})
|
||||
.then((data) => {
|
||||
if(!_.isEqual(data, trainDiagramData2)) {
|
||||
trainDiagramData2 = data;
|
||||
setReload();
|
||||
}
|
||||
});
|
||||
}catch(error){}
|
||||
setTimeout(TrainDiagramData2Update, 60000);
|
||||
}
|
||||
TrainDiagramData2Update();
|
||||
|
||||
let probremsData = [];
|
||||
fetch("https://n8n.haruk.in/webhook/jrshikoku-position-problems").then((response) => response.json()).then((data) => {
|
||||
probremsData = data.data;
|
||||
});
|
||||
|
||||
const getProblemsData = () =>{
|
||||
try{
|
||||
fetch("https://n8n.haruk.in/webhook/jrshikoku-position-problems").then((response) => response.json()).then((data) => {
|
||||
if(!_.isEqual(data, probremsData)) {
|
||||
probremsData = data.data;
|
||||
setReload();
|
||||
}
|
||||
});
|
||||
}catch(error){}
|
||||
setTimeout(getProblemsData, 30000);
|
||||
}
|
||||
getProblemsData();
|
||||
|
||||
const setReload = () =>{
|
||||
try{
|
||||
document.getElementById('refreshIcon').click();
|
||||
fetch("https://n8n.haruk.in/webhook/jrshikoku-position-problems").then((response) => response.json()).then((data) => {
|
||||
probremsData = data.data;
|
||||
});
|
||||
setStrings();
|
||||
}catch(error){}
|
||||
setTimeout(setReload, 10000);
|
||||
}
|
||||
setReload();
|
||||
};
|
||||
`;
|
||||
// 左か右かを判定してアイコンを設置する
|
||||
const trainIcon = `
|
||||
@@ -458,432 +500,6 @@ export const injectJavascriptData: InjectJavascriptData = (
|
||||
case "8077":
|
||||
return "https://storage.haruk.in/ef210a.png";
|
||||
|
||||
// // 普通列車系統、6000系運用
|
||||
// //61運用
|
||||
// case "1213M":
|
||||
// case "1214M":
|
||||
// case "143M":
|
||||
// case "147M":
|
||||
// //62運用
|
||||
// case "114M":
|
||||
// //961運用
|
||||
// case "143M":
|
||||
// case "147M":
|
||||
// //962運用
|
||||
// case "114M":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s6000p.png',hasProblem);
|
||||
// break;
|
||||
|
||||
// // 土讃線普通列車系統(include ごな線)
|
||||
// // ごな線
|
||||
// case "5851D": //219D併結 [ToDo: 219Dとの分割対策]
|
||||
// case "5854D":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/tosa9640jgr.png',hasProblem);
|
||||
// break;
|
||||
|
||||
// //JR車両乗り入れ運用
|
||||
// case "5858D":
|
||||
// case "5869D":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s1000.png',hasProblem);
|
||||
// break;
|
||||
// //併結運用の併結される側 [ToDo: 分割対策]
|
||||
// case "5845D":
|
||||
// case "5851D":
|
||||
// case "5818D":
|
||||
// case "5820D":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/tosa9640.png',hasProblem);
|
||||
// break;
|
||||
// // 土讃線単体列車のキハ32運用
|
||||
// case "715D":
|
||||
// case "718D":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s32ns.png',hasProblem);
|
||||
// break;
|
||||
|
||||
// // サンライズに伴う気動車代走
|
||||
// case "6219D":
|
||||
// case "6222D":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s1000.png',hasProblem);
|
||||
// break;
|
||||
// // それ以外の土讃線ごな線直通列車
|
||||
// case "5811D":
|
||||
// case "5813D":
|
||||
// case "5815D":
|
||||
// case "5817D":
|
||||
// case "5843D":
|
||||
// case "5853D":
|
||||
// case "5855D":
|
||||
// case "5859D":
|
||||
// case "5861D":
|
||||
// case "5865D":
|
||||
// case "5881D":
|
||||
// case "5885D":
|
||||
// case "5889D":
|
||||
|
||||
// case "5812D":
|
||||
// case "5814D":
|
||||
// case "5816D":
|
||||
// case "5852D":
|
||||
// case "5856D":
|
||||
// case "5860D":
|
||||
// case "5862D":
|
||||
// case "5872D":
|
||||
// case "5874D":
|
||||
// case "5876D":
|
||||
// case "5880D":
|
||||
// case "5882D":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/tosa9640.png',hasProblem);
|
||||
// break;
|
||||
// // それ以外の土讃線普通列車(1000)
|
||||
// case "4210D":
|
||||
// case "4212D":
|
||||
// case "4214D":
|
||||
// case "4218D":
|
||||
// case "4220D":
|
||||
// case "4222D":
|
||||
// case "4224D":
|
||||
// case "4226D":
|
||||
// case "4228D":
|
||||
// case "4230D":
|
||||
// case "4232D":
|
||||
// case "4234D":
|
||||
// case "4236D":
|
||||
// case "4238D":
|
||||
// case "4240D":
|
||||
// case "4242D":
|
||||
// case "4244D":
|
||||
// case "4250D":
|
||||
// case "4252D":
|
||||
// case "4254D":
|
||||
// case "4256D":
|
||||
|
||||
// case "4211D":
|
||||
// case "4221D":
|
||||
// case "4223D":
|
||||
// case "4225D":
|
||||
// case "4227D":
|
||||
// case "4229D":
|
||||
// case "4231D":
|
||||
// case "4235D":
|
||||
// case "4237D":
|
||||
// case "4239D":
|
||||
// case "4241D":
|
||||
// case "4245D":
|
||||
// case "4247D":
|
||||
// case "4249D":
|
||||
// case "4251D":
|
||||
// case "4253D":
|
||||
// case "4255D":
|
||||
// case "4257D":
|
||||
// case "4259D":
|
||||
// case "4261D":
|
||||
|
||||
// case "4710D":
|
||||
// case "4726D":
|
||||
// case "4730D":
|
||||
// case "4732D":
|
||||
// case "4734D":
|
||||
// case "4738D":
|
||||
// case "4740D":
|
||||
// case "4742D":
|
||||
// case "4744D":
|
||||
// case "4746D":
|
||||
// case "4752D":
|
||||
// case "4756D":
|
||||
// case "4762D":
|
||||
// case "4764D":
|
||||
// case "4766D":
|
||||
|
||||
// case "4711D":
|
||||
// case "4713D":
|
||||
// case "4723D":
|
||||
// case "4725D":
|
||||
// case "4727D":
|
||||
// case "4729D":
|
||||
// case "4731D":
|
||||
// case "4737D":
|
||||
// case "4739D":
|
||||
// case "4745D":
|
||||
// case "4753D":
|
||||
// case "4755D":
|
||||
// case "4759D":
|
||||
// case "4761D":
|
||||
// case "4763D":
|
||||
|
||||
// case "216D":
|
||||
// case "238D":
|
||||
// case "246D":
|
||||
// case "248D":
|
||||
|
||||
// case "213D":
|
||||
// case "215D":
|
||||
// case "217D":
|
||||
// case "219D":
|
||||
// case "233D":
|
||||
// case "243D":
|
||||
|
||||
// case "710D":
|
||||
// case "712D":
|
||||
// case "714D":
|
||||
// case "716D":
|
||||
// case "720D":
|
||||
// case "722D":
|
||||
// case "724D":
|
||||
// case "728D":
|
||||
// case "736D":
|
||||
// case "748D":
|
||||
// case "750D":
|
||||
// case "754D":
|
||||
// case "758D":
|
||||
// case "760D":
|
||||
// case "768D":
|
||||
|
||||
// case "717D":
|
||||
// case "719D":
|
||||
// case "721D":
|
||||
// case "733D":
|
||||
// case "735D":
|
||||
// case "737D":
|
||||
// case "741D":
|
||||
// case "743D":
|
||||
// case "747D":
|
||||
// case "749D":
|
||||
// case "751D":
|
||||
// case "755D":
|
||||
// case "757D":
|
||||
// case "761D":
|
||||
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s1000.png',hasProblem);
|
||||
// break;
|
||||
// // 予讃線/土讃線普通列車運用(7000,7200)
|
||||
// // 下り列車(伊予西条-松山は全て7000系)
|
||||
|
||||
// case "5519M":
|
||||
// case "5525M":
|
||||
// case "5215M":
|
||||
// case "5103M":
|
||||
// case "107M":
|
||||
// case "1219M":
|
||||
// case "5109M":
|
||||
// case "6109M":
|
||||
// case "5531M":
|
||||
// case "1221M":
|
||||
// case "5225M":
|
||||
// case "5111M":
|
||||
// case "1227M":
|
||||
// case "115M":
|
||||
// case "5229M":
|
||||
// case "5117M":
|
||||
// case "5119M":
|
||||
// case "119M":
|
||||
// case "5231M":
|
||||
// case "4537M":
|
||||
// case "5233M":
|
||||
// case "123M":
|
||||
// case "125M":
|
||||
// case "5235M":
|
||||
// case "5239M":
|
||||
// case "5547M":
|
||||
// case "129M":
|
||||
// case "5241M":
|
||||
// case "5133M":
|
||||
// case "135M":
|
||||
// case "1243M":
|
||||
// case "137M":
|
||||
// case "5139M":
|
||||
// case "4559M":
|
||||
// case "1245M":
|
||||
// case "141M":
|
||||
// case "1247M":
|
||||
// case "5249M":
|
||||
// case "145M":
|
||||
// case "5253M":
|
||||
// case "5149M":
|
||||
// case "5255M":
|
||||
// case "151M":
|
||||
// case "5257M":
|
||||
// case "153M":
|
||||
// case "5259M":
|
||||
// case "155M":
|
||||
// case "1263M":
|
||||
// case "157M":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s7200.png',hasProblem);
|
||||
// break;
|
||||
// // 下り7000系
|
||||
// case "101M":
|
||||
// case "4601M":
|
||||
// case "4113M":
|
||||
// case "121M":
|
||||
// case "127M":
|
||||
// case "131M":
|
||||
// case "555M":
|
||||
// case "4565M":
|
||||
// case "159M":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s7000.png',hasProblem);
|
||||
// break;
|
||||
// // 上り列車 7200系
|
||||
// case "5102M":
|
||||
// case "104M":
|
||||
// case "5210M":
|
||||
// case "5108M":
|
||||
// case "4108M":
|
||||
// case "110M":
|
||||
// case "112M":
|
||||
// case "118M":
|
||||
// case "5218M":
|
||||
// case "5120M":
|
||||
// case "5220M":
|
||||
// case "5512M":
|
||||
// case "1602M":
|
||||
// case "1224M":
|
||||
// case "5124M":
|
||||
// case "5226M":
|
||||
// case "5126M":
|
||||
// case "5128M":
|
||||
// case "1230M":
|
||||
// case "4128M":
|
||||
// case "130M":
|
||||
// case "4522M":
|
||||
// case "5232M":
|
||||
// case "132M":
|
||||
// case "5234M":
|
||||
// case "136M":
|
||||
// case "5236M":
|
||||
// case "5140M":
|
||||
// case "5238M":
|
||||
// case "5240M":
|
||||
// case "142M":
|
||||
// case "4530M":
|
||||
// case "144M":
|
||||
// case "5242M":
|
||||
// case "146M":
|
||||
// case "5244M":
|
||||
// case "4148M":
|
||||
// case "1246M":
|
||||
// case "150M":
|
||||
// case "5538M":
|
||||
// case "5152M":
|
||||
// case "154M":
|
||||
// case "156M":
|
||||
// case "1252M":
|
||||
// case "158M":
|
||||
// case "4604M":
|
||||
// case "548M":
|
||||
// case "5254M":
|
||||
// case "1606M":
|
||||
// case "5160M":
|
||||
// case "5256M":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s7200.png',hasProblem);
|
||||
// break;
|
||||
// // 上り7000系
|
||||
// case "114M":
|
||||
// case "122M":
|
||||
// case "134M":
|
||||
// case "4138M":
|
||||
// case "138M":
|
||||
// case "4542M":
|
||||
// case "162M":
|
||||
// case "4166M":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s7000.png',hasProblem);
|
||||
// break;
|
||||
// // 松山界隈気動車運用
|
||||
// // 上り下りの概念アリ
|
||||
// // キハ32 通常運用
|
||||
// case "4625D":
|
||||
// case "4916D":
|
||||
// case "925D":
|
||||
// case "4618D":
|
||||
// case "4913D":
|
||||
// case "4918D":
|
||||
// case "4643D":
|
||||
// case "4654D":
|
||||
// case "4657D":
|
||||
// case "4928D":
|
||||
// case "4667D":
|
||||
// case "653D":
|
||||
// case "3621D":
|
||||
// case "4818D":
|
||||
// case "4821D":
|
||||
// case "4824D":
|
||||
// case "4813D":
|
||||
// case "4664D":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s32s.png',hasProblem);
|
||||
// break;
|
||||
// // 河童うようよ号偶数
|
||||
// case "4816D":
|
||||
// case "4830D":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s32kpuy2.png',hasProblem);
|
||||
// break;
|
||||
// // 河童うようよ号奇数
|
||||
// case "4827D":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s32kpuy1.png',hasProblem);
|
||||
// break;
|
||||
// // 新幹線偶数
|
||||
// case "4810D":
|
||||
// case "4822D":
|
||||
// case "4826D":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s32tht.png',hasProblem);
|
||||
// break;
|
||||
// // 新幹線奇数
|
||||
// case "4817D":
|
||||
// case "4823D":
|
||||
// case "4829D":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s32thtk.png',hasProblem);
|
||||
// break;
|
||||
// // キハ54 通常運用
|
||||
// case "4632D":
|
||||
// case "4634D":
|
||||
// case "4921D":
|
||||
// case "4926D":
|
||||
// case "4927D":
|
||||
// case "912D":
|
||||
// case "4917D":
|
||||
// case "4641D":
|
||||
// case "4652D":
|
||||
// case "4651D":
|
||||
// case "4666D":
|
||||
// case "4820D":
|
||||
// case "4825D":
|
||||
// case "4828D":
|
||||
// case "4811D":
|
||||
// case "4640D":
|
||||
// case "622D":
|
||||
// case "4633D":
|
||||
// case "4920D":
|
||||
// case "4637D":
|
||||
// case "4648D":
|
||||
// case "620D":
|
||||
// case "4627D":
|
||||
// case "4624D":
|
||||
// case "4915D":
|
||||
// case "4924D":
|
||||
// case "4649D":
|
||||
// case "4812D":
|
||||
// case "4815D":
|
||||
// case "4659D":
|
||||
// case "4658D":
|
||||
// case "4665D":
|
||||
// case "4914D":
|
||||
// case "4626D":
|
||||
// case "4631D":
|
||||
// case "4636D":
|
||||
// case "4919D":
|
||||
// case "4922D":
|
||||
// case "4923D":
|
||||
// case "4663D":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s54s.png',hasProblem);
|
||||
// break;
|
||||
// // 54しまんとろっこ
|
||||
// case "4623D":
|
||||
// case "8814D":
|
||||
// case "8819D":
|
||||
// case "4662D":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s54to0ys.png',hasProblem);
|
||||
// break;
|
||||
// // キハ185 通常運用
|
||||
// case "911D":
|
||||
// case "628D":
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s185cm.png',hasProblem);
|
||||
// break;
|
||||
// 伊予灘ものがたり 赤
|
||||
case "8091D":
|
||||
case "8093D":
|
||||
@@ -1005,54 +621,12 @@ export const injectJavascriptData: InjectJavascriptData = (
|
||||
} else if (new RegExp(/^9(5|6|7|8)\\dD$/).test(列番データ)) {
|
||||
return "https://storage.haruk.in/s1500.png";
|
||||
}
|
||||
// 牟岐線普通列車系統 一旦閉鎖
|
||||
// else if(new RegExp(/^(4|5)5\\d\\dD$/).test(列番データ)){
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s7200.png',hasProblem);
|
||||
// break;
|
||||
// }
|
||||
// else if(new RegExp(/^5\\d\\dD$/).test(列番データ)){
|
||||
// setStationIcon(e.querySelector("img"),'https://storage.haruk.in/s7000.png',hasProblem);
|
||||
// break;
|
||||
// }
|
||||
break;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const normal_train_name = `
|
||||
const getJRF = num =>{
|
||||
switch(num){
|
||||
case "71":
|
||||
return "東京(タ)→高松(タ)";
|
||||
case "73":
|
||||
case "75":
|
||||
return "大阪(タ)→高松(タ)";
|
||||
case "3079":
|
||||
return "高松(タ)→伊予三島";
|
||||
case "3071":
|
||||
case "3077":
|
||||
return "高松(タ)→新居浜";
|
||||
case "3073":
|
||||
return "高松(タ)→松山貨物";
|
||||
case "70":
|
||||
return "高松(タ)→東京(タ)";
|
||||
case "74":
|
||||
case "76":
|
||||
return "高松(タ)→大阪(タ)";
|
||||
case "3078":
|
||||
return "伊予三島→高松(タ)";
|
||||
case "3070":
|
||||
return "新居浜→高松(タ)";
|
||||
case "3076":
|
||||
return "新居浜→高松(タ)";
|
||||
case "3072":
|
||||
return "松山貨物→高松(タ)";
|
||||
case "9070":
|
||||
return "臨時貨物";
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
const nameReplace = (列車名データ,列番データ,行き先情報,hasProblem,isLeft) =>{
|
||||
let isWanman = false;
|
||||
let trainName = "";
|
||||
@@ -1061,7 +635,9 @@ export const injectJavascriptData: InjectJavascriptData = (
|
||||
let viaData = "";
|
||||
let ToData = "";
|
||||
let TrainNumber = 列番データ;
|
||||
|
||||
let isEdit = false;
|
||||
let isSeason = false;
|
||||
let TrainNumberOverride;
|
||||
try{
|
||||
const diagram = trainDiagramData2[列番データ] || trainTimeInfo[列番データ];
|
||||
if(diagram){
|
||||
@@ -1108,15 +684,6 @@ export const injectJavascriptData: InjectJavascriptData = (
|
||||
trainName = "臨時列車";
|
||||
}
|
||||
|
||||
|
||||
let JRF = true;
|
||||
const JRFTemp = getJRF(列番データ);
|
||||
|
||||
if(JRFTemp){
|
||||
trainName = JRFTemp;
|
||||
JRF = false;
|
||||
}
|
||||
|
||||
const getThrew = num =>{
|
||||
|
||||
switch(num){
|
||||
@@ -1217,30 +784,6 @@ export const injectJavascriptData: InjectJavascriptData = (
|
||||
viaData = "ごめん・なはり線[快速]";
|
||||
ToData = "(後免にて解結)\\n土佐山田/奈半利";
|
||||
break;
|
||||
case "9395D":
|
||||
viaData = "[臨時]普通";
|
||||
ToData = "三本松";
|
||||
break;
|
||||
case "9174M":
|
||||
viaData = "[臨時]マリンライナー94号";
|
||||
ToData = "岡山";
|
||||
break;
|
||||
case "9662D":
|
||||
viaData = "[臨時]れんげ号";
|
||||
ToData = "八幡浜";
|
||||
break;
|
||||
case "9665D":
|
||||
viaData = "[臨時]れんげ号";
|
||||
ToData = "宇和島";
|
||||
break;
|
||||
case "9664D":
|
||||
viaData = "[臨時]わらぐろ号";
|
||||
ToData = "八幡浜";
|
||||
break;
|
||||
case "9663D":
|
||||
viaData = "[臨時]わらぐろ号";
|
||||
ToData = "卯之町";
|
||||
break;
|
||||
default:
|
||||
if(new RegExp(/^58[1-3][1,3,5,7,9][DM]$/).test(列番データ)){
|
||||
viaData = "ごめん・なはり線[快速]";
|
||||
@@ -1265,44 +808,80 @@ export const injectJavascriptData: InjectJavascriptData = (
|
||||
getThrew(列番データ);
|
||||
if(trainDataList.find(e => e.id === 列番データ) !== undefined){
|
||||
const data = trainDataList.find(e => e.id === 列番データ);
|
||||
//{id,isWanman,trainName,viaData,ToData,TrainNumber,JRF,type,infoUrl,trainNumDistance,info,infogram}
|
||||
trainType = (()=>{
|
||||
switch(data.type){
|
||||
case "Normal":
|
||||
trainTypeColor = "black";
|
||||
return "普通";
|
||||
case "OneMan":
|
||||
trainTypeColor = "black";
|
||||
return "普通";
|
||||
case "Freight":
|
||||
trainTypeColor = "black";
|
||||
return "貨物";
|
||||
case "SPCL_Normal":
|
||||
trainTypeColor = "#297bff";
|
||||
return "臨時";
|
||||
case "SPCL_Rapid":
|
||||
trainTypeColor = "#297bff";
|
||||
return "臨時快速";
|
||||
case "SPCL_LTDEXP":
|
||||
trainTypeColor = "#297bff";
|
||||
return "臨時特急";
|
||||
case "LTDEXP":
|
||||
trainTypeColor = "red";
|
||||
return "特急";
|
||||
case "NightLTDEXP":
|
||||
trainTypeColor = "rgb(211, 0, 176)";
|
||||
return "寝台特急";
|
||||
case "OneManRapid":
|
||||
trainTypeColor = "rgba(0, 140, 255, 1)";
|
||||
return "快速";
|
||||
case "Rapid":
|
||||
trainTypeColor = "rgba(0, 140, 255, 1)";
|
||||
return "快速";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
})();
|
||||
isWanman = data.isWanman;
|
||||
//{id,trainName,viaData,ToData,TrainNumber,TrainNumberOverride,type,infoUrl,trainNumDistance,info,infogram,isEdit}
|
||||
|
||||
switch(data.type){
|
||||
case "Normal":
|
||||
trainTypeColor = "black";
|
||||
isWanman = false;
|
||||
trainType = "普通";
|
||||
break;
|
||||
case "OneMan":
|
||||
trainTypeColor = "black";
|
||||
isWanman = true;
|
||||
trainType = "普通";
|
||||
break;
|
||||
case "Rapid":
|
||||
trainTypeColor = "rgba(0, 140, 255, 1)";
|
||||
isWanman = false;
|
||||
trainType = "快速";
|
||||
break;
|
||||
case "OneManRapid":
|
||||
trainTypeColor = "rgba(0, 140, 255, 1)";
|
||||
isWanman = true;
|
||||
trainType = "快速";
|
||||
break;
|
||||
case "LTDEXP":
|
||||
trainTypeColor = "red";
|
||||
isWanman = false;
|
||||
trainType = "特急";
|
||||
break;
|
||||
case "NightLTDEXP":
|
||||
trainTypeColor = "#d300b0ff";
|
||||
isWanman = false;
|
||||
trainType = "寝台特急";
|
||||
break;
|
||||
case "SPCL":
|
||||
case "SPCL_Normal":
|
||||
trainTypeColor = "#008d07ff";
|
||||
isWanman = false;
|
||||
trainType = "臨時";
|
||||
break;
|
||||
case "SPCL_Rapid":
|
||||
trainTypeColor = "rgba(0, 81, 255, 1)";
|
||||
isWanman = false;
|
||||
trainType = "臨時快速";
|
||||
break;
|
||||
case "SPCL_EXP":
|
||||
trainTypeColor = "#a52e2eff";
|
||||
isWanman = false;
|
||||
trainType = "臨時特急";
|
||||
break;
|
||||
case "Party":
|
||||
trainTypeColor = "#ff7300ff";
|
||||
isWanman = false;
|
||||
trainType = "団体臨時";
|
||||
break;
|
||||
case "Freight":
|
||||
trainTypeColor = "#00869ecc";
|
||||
isWanman = false;
|
||||
trainType = "貨物";
|
||||
break;
|
||||
case "Forwarding":
|
||||
trainTypeColor = "#727272cc";
|
||||
isWanman = false;
|
||||
trainType = "回送";
|
||||
break;
|
||||
case "FreightForwarding":
|
||||
trainTypeColor = "#727272cc";
|
||||
isWanman = false;
|
||||
trainType = "単機回送";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
isEdit = data.isEdit;
|
||||
isSeason = data.isSeason;
|
||||
if(data.trainName != ""){
|
||||
trainName = data.trainName;
|
||||
if(data.trainNumDistance != null){
|
||||
@@ -1315,10 +894,12 @@ export const injectJavascriptData: InjectJavascriptData = (
|
||||
if(data.ToData != ""){
|
||||
ToData = data.ToData;
|
||||
}
|
||||
if(data.TrainNumberOverride){
|
||||
TrainNumberOverride = data.TrainNumberOverride;
|
||||
}
|
||||
}
|
||||
//列番付与
|
||||
const returnText1 = (isWanman ? "ワンマン " : "") + trainName + viaData;
|
||||
const returnText2 = (ToData ? ToData+"行 " : ToData)+ TrainNumber;
|
||||
行き先情報.innerText = "";
|
||||
${uiSetting === "tokyo" ? `
|
||||
let stationIDs = [];
|
||||
@@ -1337,19 +918,38 @@ export const injectJavascriptData: InjectJavascriptData = (
|
||||
getColors = stationLines.map(e => GetLineBarColor(e));
|
||||
}
|
||||
let yosan2Color = undefined;
|
||||
if(viaData == "(内子経由)"){
|
||||
yosan2Color ="#F5AC13";
|
||||
}
|
||||
else if(viaData == "(海経由)"){
|
||||
yosan2Color = "#9AA7D7";
|
||||
switch(viaData){
|
||||
case "(内子経由)":
|
||||
yosan2Color = "#F5AC13";
|
||||
break;
|
||||
case "(海経由)":
|
||||
yosan2Color = "#9AA7D7";
|
||||
break;
|
||||
case "牟岐線直通":
|
||||
yosan2Color = "#00b8bb";
|
||||
break;
|
||||
case "徳島線直通":
|
||||
yosan2Color = "#2d506e";
|
||||
break;
|
||||
case "高徳線直通":
|
||||
yosan2Color = "#87CA3B";
|
||||
break;
|
||||
case "鳴門線直通":
|
||||
yosan2Color = "#881F61";
|
||||
break;
|
||||
case "予土線":
|
||||
yosan2Color = "#008a5a";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const gradient = getColors.length > 1 ? "linear-gradient(130deg, " + getColors[0] + " 0%, "+ getColors[0]+"50%, "+ getColors[1]+"50%, " + getColors[1] + " 100%)" : getColors[0];
|
||||
|
||||
行き先情報.insertAdjacentHTML('beforebegin', "<div style='width:100%;display:flex;flex:1;flex-direction:"+(isLeft ? "column-reverse" : "column") + ";'><p style='font-size:6px;padding:0;color:black;text-align:center;'>" + TrainNumber + (JRF ? "":"レ") + "</p><div style='flex:1;'></div><p style='font-size:8px;font-weight:bold;padding:0;color: black;text-align:center;'>" + (isWanman ? "ワンマン " : "") + "</p><p style='font-size:6px;font-weight:bold;padding:0;color: black;text-align:center;border-style:solid;border-width: "+(!!yosan2Color ? "2px" : "0px")+";border-color:" + yosan2Color + "'>" + viaData + "</p><p style='font-size:8px;font-weight:bold;padding:0;color: black;text-align:center;'>" + trainName + "</p><div style='width:100%;background:" + gradient + ";'><p style='font-size:10px;font-weight:bold;padding:0;margin:0;color:white;align-items:center;align-content:center;text-align:center;text-shadow:1px 1px 0px #00000030, -1px -1px 0px #00000030,-1px 1px 0px #00000030, 1px -1px 0px #00000030,1px 0px 0px #00000030, -1px 0px 0px #00000030,0px 1px 0px #00000030, 0px -1px 0px #00000030;'>" + (ToData ? ToData + "行" : ToData) + "</p></div><div style='width:100%;background:" + trainTypeColor + ";border-radius:"+(isLeft ? "4px 4px 0 0" : "0 0 4px 4px")+";'><p style='font-size:10px;font-weight:bold;font-style:italic;padding:0;color: white;text-align:center;'>" + trainType + "</p></div><p style='font-size:8px;font-weight:bold;padding:0;text-align:center;color: "+(hasProblem ? "red":"black")+";'>" + (hasProblem ? "‼️停止中‼️" : "") + "</p></div>");
|
||||
行き先情報.insertAdjacentHTML('beforebegin', "<div style='width:100%;display:flex;flex:1;flex-direction:"+(isLeft ? "column-reverse" : "column") + ";'>" + ( isEdit ? "<div style='position:absolute;"+ (isLeft ? "right" : "left") + ":0;"+ (isLeft ? "bottom" : "top") + ":0;background-color:#00b8bb;border-radius:15px;padding:0px;padding-left:4px;padding-right:4px;'><i class='fa-solid fa-user-group fa-sm' style='color:white;width:100%;height:100%;'></i></div>" : isSeason ? "<div style='position:absolute;"+ (isLeft ? "right" : "left") + ":0;"+ (isLeft ? "bottom" : "top") + ":0;background-color:#00b8bb;border-radius:15px;padding:0px;padding-left:4px;padding-right:4px;'><i class='fa-solid fa-calendar fa-sm' style='color:white;width:100%;height:100%;'></i></div>" : "") + "<p style='font-size:6px;padding:0;color:black;text-align:center;'>" + (TrainNumberOverride ? TrainNumberOverride : TrainNumber) + "</p><div style='flex:1;'></div><p style='font-size:8px;font-weight:bold;padding:0;color: black;text-align:center;'>" + (isWanman ? "ワンマン " : "") + "</p><p style='font-size:6px;font-weight:bold;padding:0;color: black;text-align:center;border-style:solid;border-width: "+(!!yosan2Color ? "2px" : "0px")+";border-color:" + yosan2Color + "'>" + viaData + "</p><p style='font-size:8px;font-weight:bold;padding:0;color: black;text-align:center;'>" + trainName + "</p><div style='width:100%;background:" + gradient + ";'><p style='font-size:10px;font-weight:bold;padding:0;margin:0;color:white;align-items:center;align-content:center;text-align:center;text-shadow:1px 1px 0px #00000030, -1px -1px 0px #00000030,-1px 1px 0px #00000030, 1px -1px 0px #00000030,1px 0px 0px #00000030, -1px 0px 0px #00000030,0px 1px 0px #00000030, 0px -1px 0px #00000030;'>" + (ToData ? ToData + "行" : ToData) + "</p></div><div style='width:100%;background:" + trainTypeColor + ";border-radius:"+(isLeft ? "4px 4px 0 0" : "0 0 4px 4px")+";'><p style='font-size:10px;font-weight:bold;font-style:italic;padding:0;color: white;text-align:center;'>" + trainType + "</p></div><p style='font-size:8px;font-weight:bold;padding:0;text-align:center;color: "+(hasProblem ? "red":"black")+";'>" + (hasProblem ? "‼️停止中‼️" : "") + "</p></div>");
|
||||
`: `
|
||||
行き先情報.insertAdjacentHTML('beforebegin', "<p style='font-size:10px;font-weight:bold;padding:0;color: black;'>" + returnText1 + "</p>");
|
||||
行き先情報.insertAdjacentHTML('beforebegin', "<div style='display:inline-flex;flex-direction:row;'><p style='font-size:10px;font-weight: bold;padding:0;color:black;'>" + (ToData ? ToData + "行 " : ToData) + "</p><p style='font-size:10px;padding:0;color:black;'>" + TrainNumber + (JRF ? "":"レ") + "</p></div>");
|
||||
行き先情報.insertAdjacentHTML('beforebegin', "<div style='display:inline-flex;flex-direction:row;'><p style='font-size:10px;font-weight: bold;padding:0;color:black;'>" + (ToData ? ToData + "行 " : ToData) + "</p><p style='font-size:10px;padding:0;color:black;'>" + (TrainNumberOverride ? TrainNumberOverride : TrainNumber) + "</p></div>");
|
||||
行き先情報.insertAdjacentHTML('beforebegin', "<p style='font-size:10px;font-weight:bold;padding:0;color: "+(hasProblem ? "red":"black")+";'>" + (hasProblem ? "‼️停止中‼️" : "") + "</p>");
|
||||
`}
|
||||
}
|
||||
@@ -1359,34 +959,81 @@ export const injectJavascriptData: InjectJavascriptData = (
|
||||
`
|
||||
|
||||
|
||||
const setNewTrainItem = (element,hasProblem)=>{
|
||||
const setNewTrainItem = (element,hasProblem,type)=>{
|
||||
var 列番データ = element.getAttribute('offclick').split('"')[1];
|
||||
const JRFTemp = getJRF(列番データ);
|
||||
if(element.getAttribute('offclick').includes("express")){
|
||||
element.style.borderColor = 'rgba(255, 0, 0, 1)';
|
||||
}else if(element.getAttribute('offclick').includes("rapid")){
|
||||
element.style.borderColor = 'rgba(0, 140, 255, 1)';
|
||||
}else if(JRFTemp){
|
||||
element.style.borderColor = 'rgba(0, 134, 158, 0.8)';
|
||||
if(trainDataList.find(e => e.id === 列番データ) !== undefined){
|
||||
const data = trainDataList.find(e => e.id === 列番データ);
|
||||
switch (data.type) {
|
||||
case "Normal":
|
||||
element.style.borderColor = "black";
|
||||
element.style.backgroundColor = '#ffffffcc';
|
||||
break;
|
||||
case "OneMan":
|
||||
element.style.borderColor = "black";
|
||||
element.style.backgroundColor = '#ffffffcc';
|
||||
break;
|
||||
case "Rapid":
|
||||
element.style.borderColor = "rgba(0, 140, 255, 1)";
|
||||
element.style.backgroundColor = '#ffffffcc';
|
||||
break;
|
||||
case "OneManRapid":
|
||||
element.style.borderColor = "rgba(0, 140, 255, 1)";
|
||||
element.style.backgroundColor = '#ffffffcc';
|
||||
break;
|
||||
case "LTDEXP":
|
||||
element.style.borderColor = "red";
|
||||
element.style.backgroundColor = '#ffffffcc';
|
||||
break;
|
||||
case "NightLTDEXP":
|
||||
element.style.borderColor = "#d300b0ff";
|
||||
element.style.backgroundColor = '#ffffffcc';
|
||||
break;
|
||||
case "SPCL":
|
||||
case "SPCL_Normal":
|
||||
element.style.borderColor = "#008d07ff";
|
||||
element.style.backgroundColor = '#ffffffcc';
|
||||
break;
|
||||
case "SPCL_Rapid":
|
||||
element.style.borderColor = "#0051ffff";
|
||||
element.style.backgroundColor = '#ffffffcc';
|
||||
break;
|
||||
case "SPCL_EXP":
|
||||
element.style.borderColor = "#a52e2eff";
|
||||
element.style.backgroundColor = '#ffffffcc';
|
||||
break;
|
||||
case "Party":
|
||||
element.style.borderColor = "#ff7300ff";
|
||||
element.style.backgroundColor = '#ffd0a9ff';
|
||||
break;
|
||||
case "Freight":
|
||||
element.style.borderColor = "#00869ecc";
|
||||
element.style.backgroundColor = '#c7c7c7cc';
|
||||
break;
|
||||
case "Forwarding":
|
||||
element.style.borderColor = "#727272cc";
|
||||
element.style.backgroundColor = '#c7c7c7cc';
|
||||
break;
|
||||
case "FreightForwarding":
|
||||
element.style.borderColor = "#727272cc";
|
||||
element.style.backgroundColor = '#c7c7c7cc';
|
||||
break;
|
||||
default:
|
||||
element.style.borderColor = 'black';
|
||||
element.style.backgroundColor = '#ffffffcc';
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
element.style.borderColor = 'black';
|
||||
if(element.getAttribute('offclick').includes("express")){
|
||||
element.style.borderColor = '#ff0000ff';
|
||||
}else if(element.getAttribute('offclick').includes("rapid")){
|
||||
element.style.borderColor = '#008cffff';
|
||||
}else{
|
||||
element.style.borderColor = 'black';
|
||||
}
|
||||
}
|
||||
element.style.borderWidth = '2px';
|
||||
element.style.borderStyle = 'solid';
|
||||
element.style.borderRadius = '10%';
|
||||
switch(true){
|
||||
case 列番データ.indexOf("H") != -1:
|
||||
case 列番データ.indexOf("R") != -1:
|
||||
case 列番データ.indexOf("E") != -1:
|
||||
case 列番データ.indexOf("A") != -1:
|
||||
case 列番データ.indexOf("B") != -1:
|
||||
case !!JRFTemp:
|
||||
element.style.backgroundColor = 'rgba(199, 199, 199, 0.8)';
|
||||
break;
|
||||
default:
|
||||
element.style.backgroundColor = 'rgba(255, 255, 255, 0.8)';
|
||||
break;
|
||||
}
|
||||
if(hasProblem){
|
||||
element.style.boxShadow = '0 0 10px rgba(255, 0, 0, 0.9)';
|
||||
}else{
|
||||
@@ -1449,10 +1096,13 @@ const setStrings = () =>{
|
||||
i.style.position = "unset";
|
||||
i.style.display = "flex";
|
||||
i.style.flexDirection = "column";
|
||||
i.style.alignItems = "center";
|
||||
i.style.justifyContent = "center";
|
||||
i.style.flex = "1";
|
||||
i.style.backgroundColor = "#00000000";
|
||||
i.querySelectorAll(":scope > *").forEach(j=>{
|
||||
j.style.width = "100%";
|
||||
j.style.display = "flex";
|
||||
j.style.flex = "1";
|
||||
j.style.textAlign = "center";
|
||||
j.style.margin = "5px";
|
||||
j.style.padding = "5px";
|
||||
|
@@ -1,58 +1,54 @@
|
||||
import React, { useRef, useState, useEffect, useLayoutEffect } from "react";
|
||||
import {
|
||||
Platform,
|
||||
View,
|
||||
ScrollView,
|
||||
useWindowDimensions,
|
||||
LayoutAnimation,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
} from "react-native";
|
||||
import React, { useRef, useState, useEffect, useLayoutEffect, FC } from "react";
|
||||
import { Platform, View, ScrollView, LayoutAnimation } from "react-native";
|
||||
import Constants from "expo-constants";
|
||||
import {
|
||||
configureReanimatedLogger,
|
||||
ReanimatedLogLevel,
|
||||
} from "react-native-reanimated";
|
||||
import StatusbarDetect from "./StatusbarDetect";
|
||||
import StatusbarDetect from "@/StatusbarDetect";
|
||||
|
||||
import LED_vision from "./components/発車時刻表/LED_vidion";
|
||||
import { TitleBar } from "./components/Menu/TitleBar";
|
||||
import { FixedContentBottom } from "./components/Menu/FixedContentBottom";
|
||||
import { LED_vision } from "@/components/発車時刻表/LED_vidion";
|
||||
import { TitleBar } from "@/components/Menu/TitleBar";
|
||||
import { FixedContentBottom } from "@/components/Menu/FixedContentBottom";
|
||||
|
||||
import { lineList, stationIDPair } from "./lib/getStationList";
|
||||
import { useFavoriteStation } from "./stateBox/useFavoriteStation";
|
||||
import { lineList, stationIDPair } from "@/lib/getStationList";
|
||||
import { useFavoriteStation } from "@/stateBox/useFavoriteStation";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { useStationList } from "./stateBox/useStationList";
|
||||
import { useStationList } from "@/stateBox/useStationList";
|
||||
import { TopMenuButton } from "@/components/Menu/TopMenuButton";
|
||||
import { JRSTraInfoBox } from "@/components/Menu/JRSTraInfoBox";
|
||||
import MapView, { Marker } from "react-native-maps";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs";
|
||||
import { CarouselBox } from "./components/Menu/Carousel/CarouselBox";
|
||||
import { CarouselTypeChanger } from "./components/Menu/Carousel/CarouselTypeChanger";
|
||||
import { useUserPosition } from "./stateBox/useUserPosition";
|
||||
import { AS } from "./storageControl";
|
||||
import { lineList_LineWebID } from "./lib/getStationList";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { CarouselBox } from "@/components/Menu/Carousel/CarouselBox";
|
||||
import { CarouselTypeChanger } from "@/components/Menu/Carousel/CarouselTypeChanger";
|
||||
import { useUserPosition } from "@/stateBox/useUserPosition";
|
||||
import { AS } from "@/storageControl";
|
||||
import { lineList_LineWebID } from "@/lib/getStationList";
|
||||
import { StationProps } from "@/lib/CommonTypes";
|
||||
import { LocationObject } from "expo-location";
|
||||
configureReanimatedLogger({
|
||||
level: ReanimatedLogLevel.error, // Set the log level to error
|
||||
strict: true, // Reanimated runs in strict mode by default
|
||||
});
|
||||
export default function Menu(props) {
|
||||
|
||||
type props = {
|
||||
scrollRef: React.RefObject<ScrollView>;
|
||||
mapHeight: number;
|
||||
MapFullHeight: number;
|
||||
mapMode: boolean;
|
||||
setMapMode: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
};
|
||||
export const Menu: FC<props> = (props) => {
|
||||
const { scrollRef, mapHeight, MapFullHeight, mapMode, setMapMode } = props;
|
||||
const { navigate, addListener, isFocused } = useNavigation();
|
||||
const { navigate } = useNavigation();
|
||||
const { favoriteStation } = useFavoriteStation();
|
||||
const { originalStationList, getStationDataFromNameBase } = useStationList();
|
||||
const { height, width } = useWindowDimensions();
|
||||
const { bottom, left, right, top } = useSafeAreaInsets();
|
||||
const tabBarHeight = useBottomTabBarHeight();
|
||||
const [stationListMode, setStationListMode] = useState(
|
||||
/*<"position"|"favorite">*/ "position"
|
||||
);
|
||||
const [stationListMode, setStationListMode] = useState<
|
||||
"position" | "favorite"
|
||||
>("position");
|
||||
useEffect(() => {
|
||||
AS.getItem("stationListMode")
|
||||
.then((res) => setStationListMode(res))
|
||||
.catch((e) => {
|
||||
.catch(() => {
|
||||
// AS.setItem("stationListMode", "position");
|
||||
});
|
||||
}, []);
|
||||
@@ -92,11 +88,17 @@ export default function Menu(props) {
|
||||
};
|
||||
//現在地基準の駅名標リストアップ機能
|
||||
const { position, locationStatus } = useUserPosition();
|
||||
|
||||
const [nearPositionStation, setNearPositionStation] = useState<
|
||||
StationProps[][]
|
||||
>([]); //第三要素
|
||||
|
||||
useEffect(() => {
|
||||
if (!position) return () => {};
|
||||
makeCurrentStation(position);
|
||||
}, [position, stationListMode]);
|
||||
const makeCurrentStation = (location) => {
|
||||
|
||||
const makeCurrentStation = (location: LocationObject) => {
|
||||
if (!originalStationList) return () => {};
|
||||
const findStationEachLine = (selectLine) => {
|
||||
const searchArea = 0.055; //検索範囲
|
||||
@@ -128,7 +130,7 @@ export default function Menu(props) {
|
||||
return NearStation;
|
||||
};
|
||||
|
||||
let _stList = lineList
|
||||
let _stList: StationProps[] = lineList
|
||||
.map((d) => findStationEachLine(originalStationList[d]))
|
||||
.filter((d) => d.length > 0)
|
||||
.reduce((pre, current) => {
|
||||
@@ -137,7 +139,7 @@ export default function Menu(props) {
|
||||
}, []);
|
||||
if (_stList.length == 0) setNearPositionStation([]);
|
||||
else {
|
||||
let returnData = [];
|
||||
let returnData: StationProps[][] = [];
|
||||
_stList.forEach((d, index, array) => {
|
||||
const stationName = d.Station_JP;
|
||||
if (returnData.findIndex((d) => d[0].Station_JP == stationName) != -1)
|
||||
@@ -166,19 +168,17 @@ export default function Menu(props) {
|
||||
}
|
||||
};
|
||||
|
||||
const [nearPositionStation, setNearPositionStation] = useState([]); //第三要素
|
||||
|
||||
const [listIndex, setListIndex] = useState(0);
|
||||
|
||||
const [listUpStation, setListUpStation] = useState([]);
|
||||
const [listUpStation, setListUpStation] = useState<StationProps[][]>([]);
|
||||
const [isSearchMode, setisSearchMode] = useState(false);
|
||||
const [input, setInput] = React.useState("");
|
||||
const [input, setInput] = useState("");
|
||||
useLayoutEffect(() => {
|
||||
if (!!isSearchMode) {
|
||||
const returnData = [];
|
||||
if (!input || input == "") {
|
||||
Object.keys(lineList_LineWebID).forEach((d, indexBase) => {
|
||||
originalStationList[d].forEach((D, index) => {
|
||||
Object.keys(lineList_LineWebID).forEach((d) => {
|
||||
originalStationList[d].forEach((D) => {
|
||||
if (
|
||||
isSearchMode &&
|
||||
isSearchMode != stationIDPair[lineList_LineWebID[d]]
|
||||
@@ -196,7 +196,9 @@ export default function Menu(props) {
|
||||
const hoge = getStationDataFromNameBase(input);
|
||||
hoge.forEach((d, index, array) => {
|
||||
const stationName = d.Station_JP;
|
||||
if (returnData.findIndex((d1) => d1[0].Station_JP == stationName) != -1)
|
||||
if (
|
||||
returnData.findIndex((d1) => d1[0].Station_JP == stationName) != -1
|
||||
)
|
||||
return;
|
||||
returnData.push(array.filter((d2) => d2.Station_JP == stationName));
|
||||
});
|
||||
@@ -242,8 +244,8 @@ export default function Menu(props) {
|
||||
if (mapMode) {
|
||||
mapsRef?.current.fitToCoordinates(
|
||||
listUpStation.map((d) => ({
|
||||
latitude: parseFloat(d[0].lat),
|
||||
longitude: parseFloat(d[0].lng),
|
||||
latitude: d[0].lat,
|
||||
longitude: d[0].lng,
|
||||
})),
|
||||
{ edgePadding: { top: 80, bottom: 120, left: 50, right: 50 } } // Add margin values here
|
||||
);
|
||||
@@ -261,24 +263,7 @@ export default function Menu(props) {
|
||||
}}
|
||||
>
|
||||
<StatusbarDetect />
|
||||
{!mapMode ? (
|
||||
<TitleBar />
|
||||
) : (
|
||||
<></>
|
||||
// <Text
|
||||
// style={{
|
||||
// fontSize: 30,
|
||||
// color: "#0099CC",
|
||||
// fontWeight: "bold",
|
||||
// position: "absolute",
|
||||
// top: 0,
|
||||
// zIndex: 1000,
|
||||
// fontStyle: "italic",
|
||||
// }}
|
||||
// >
|
||||
// JRShikoku RailScope
|
||||
// </Text>
|
||||
)}
|
||||
{!mapMode ? <TitleBar /> : <></>}
|
||||
<ScrollView
|
||||
ref={scrollRef}
|
||||
snapToStart={false}
|
||||
@@ -334,8 +319,8 @@ export default function Menu(props) {
|
||||
<Marker
|
||||
key={index + StationNumber}
|
||||
coordinate={{
|
||||
latitude: parseFloat(lat),
|
||||
longitude: parseFloat(lng),
|
||||
latitude: lat,
|
||||
longitude: lng,
|
||||
}}
|
||||
image={require("@/assets/reccha-small.png")}
|
||||
onPress={() => {
|
||||
@@ -344,8 +329,8 @@ export default function Menu(props) {
|
||||
if (mapsRef.current) {
|
||||
mapsRef.current.animateToRegion(
|
||||
{
|
||||
latitude: parseFloat(lat),
|
||||
longitude: parseFloat(lng),
|
||||
latitude: lat,
|
||||
longitude: lng,
|
||||
latitudeDelta: 0.05,
|
||||
longitudeDelta: 0.05,
|
||||
},
|
||||
@@ -401,11 +386,7 @@ export default function Menu(props) {
|
||||
}}
|
||||
/>
|
||||
{listUpStation[listIndex] && (
|
||||
<LED_vision
|
||||
station={listUpStation[listIndex]}
|
||||
navigate={navigate}
|
||||
openStationACFromEachTrainInfo={() => {}}
|
||||
/>
|
||||
<LED_vision station={listUpStation[listIndex]} />
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
@@ -433,4 +414,4 @@ export default function Menu(props) {
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
};
|
59
ndView.tsx
59
ndView.tsx
@@ -1,12 +1,19 @@
|
||||
import React, { Ref, useRef, useState,useEffect } from "react";
|
||||
import { View, Platform, TouchableOpacity, StyleProp, ViewStyle,Linking } from "react-native";
|
||||
import React, { Ref, useRef, useState, useEffect } from "react";
|
||||
import {
|
||||
View,
|
||||
Platform,
|
||||
TouchableOpacity,
|
||||
StyleProp,
|
||||
ViewStyle,
|
||||
Linking,
|
||||
} from "react-native";
|
||||
import { WebView } from "react-native-webview";
|
||||
import Constants from "expo-constants";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
export default function tndView() {
|
||||
const webview = useRef<WebView>(null);
|
||||
const { navigate, addListener, isFocused } = useNavigation();
|
||||
const { navigate, addListener, isFocused } = useNavigation();
|
||||
const jsa = `
|
||||
document.querySelector('.sitettl').style.display = 'none';
|
||||
document.querySelector('.attention').style.display = 'none';
|
||||
@@ -16,6 +23,20 @@ document.querySelector('.map').style.display = 'block';
|
||||
document.querySelector('.map').style.marginLeft = '-5px';
|
||||
document.querySelector('.map').style.marginTop = '0px';
|
||||
|
||||
document.querySelector('.pageInformation h1.accent span').style.width = '100%';
|
||||
document.querySelector('.delay_status').style.width = 'calc(100vw - 4px)';
|
||||
document.querySelector('.reload').style.width = '100vw';
|
||||
document.querySelector('.delay_info').style.width = '100vw';
|
||||
document.querySelector('.related_lnk').style.width = '100%';
|
||||
document.querySelector('.related_lnk').style.padding = '0px';
|
||||
document.querySelector('.related_lnk .ttl').style.padding = '20px';
|
||||
document.querySelector('.related_lnk dl.lnk_item').style.float = 'none';
|
||||
document.querySelector('.related_lnk dl.lnk_item').style.overflow = 'visible';
|
||||
document.querySelector('.related_lnk dl.lnk_item').style.width = '100%';
|
||||
document.querySelectorAll('.attention').forEach((el) => {
|
||||
el.style.width = '100vw';
|
||||
});
|
||||
|
||||
|
||||
document.querySelector('.mapbase > img').style.width = '100vw';
|
||||
document.querySelector('.ml_station > img').style.width = '100vw';
|
||||
@@ -86,22 +107,22 @@ setInterval(() => {
|
||||
});
|
||||
}, 1000);
|
||||
`;
|
||||
const goToTrainMenu = () =>{
|
||||
if (Platform.OS === "web") {
|
||||
Linking.openURL("https://www.jr-shikoku.co.jp/info/");
|
||||
setTimeout(() => {
|
||||
// @ts-ignore
|
||||
navigate("topMenu", { screen: "menu" });
|
||||
}, 100);
|
||||
const goToTrainMenu = () => {
|
||||
if (Platform.OS === "web") {
|
||||
Linking.openURL("https://www.jr-shikoku.co.jp/info/");
|
||||
setTimeout(() => {
|
||||
// @ts-ignore
|
||||
navigate("topMenu", { screen: "menu" });
|
||||
}, 100);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
// @ts-ignore
|
||||
const unsubscribe = addListener("tabPress", goToTrainMenu);
|
||||
return unsubscribe;
|
||||
}, [addListener]);
|
||||
return;
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
// @ts-ignore
|
||||
const unsubscribe = addListener("tabPress", goToTrainMenu);
|
||||
return unsubscribe;
|
||||
}, [addListener]);
|
||||
|
||||
return (
|
||||
<View
|
||||
@@ -133,7 +154,7 @@ setInterval(() => {
|
||||
}
|
||||
|
||||
const ReloadButton = ({ onPress, top, LoadError = false }) => {
|
||||
const styles:StyleProp<ViewStyle> = {
|
||||
const styles: StyleProp<ViewStyle> = {
|
||||
position: "absolute",
|
||||
top,
|
||||
right: 10,
|
||||
|
@@ -1,70 +0,0 @@
|
||||
import trainList from "@/assets/originData/trainList";
|
||||
import { AS } from "@/storageControl";
|
||||
import React, { createContext, useContext, useEffect, useState } from "react";
|
||||
const initialState = {
|
||||
allTrainDiagram: undefined,
|
||||
setAllTrainDiagram: () => {},
|
||||
allCustonTrainData: [],
|
||||
};
|
||||
|
||||
const AllTrainDiagramContext = createContext(initialState);
|
||||
|
||||
export const useAllTrainDiagram = () => useContext(AllTrainDiagramContext);
|
||||
|
||||
export const AllTrainDiagramProvider = ({ children }) => {
|
||||
const [allTrainDiagram, setAllTrainDiagram] = useState(trainList);
|
||||
const [allCustonTrainData, setAllCustonTrainData] = useState([]); // カスタム列車データ
|
||||
const [keyList, setKeyList] = useState(); // 第二要素
|
||||
useEffect(
|
||||
() => allTrainDiagram && setKeyList(Object.keys(allTrainDiagram)),
|
||||
[allTrainDiagram]
|
||||
);
|
||||
useEffect(() => {
|
||||
fetch("https://n8n.haruk.in/webhook/JR-shikoku-diagram-migrate-original")
|
||||
.then((res) => res.json())
|
||||
.then((res) => res.data)
|
||||
.then((res) => {
|
||||
const data = {};
|
||||
res.forEach((d) => {
|
||||
const keys = Object.keys(d);
|
||||
data[keys] = d[keys];
|
||||
});
|
||||
return data;
|
||||
})
|
||||
.then((res) => {
|
||||
setAllTrainDiagram(res);
|
||||
AS.setItem("allTrainDiagram", JSON.stringify(res));
|
||||
})
|
||||
.catch((d) => {
|
||||
AS.getItem("allTrainDiagram")
|
||||
.then((d) => setAllTrainDiagram(JSON.parse(d)))
|
||||
.catch(() => {
|
||||
alert("初回の路線情報の取得に失敗しました。");
|
||||
});
|
||||
});
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
// カスタム列車データの取得
|
||||
fetch("https://n8n.haruk.in/webhook/jr-shikoku-position-custom-datalist")
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
setAllCustonTrainData(res[0].data);
|
||||
})
|
||||
.catch(() => {
|
||||
alert("カスタム列車データの取得に失敗しました。");
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<AllTrainDiagramContext.Provider
|
||||
value={{
|
||||
allTrainDiagram,
|
||||
setAllTrainDiagram,
|
||||
allCustonTrainData,
|
||||
keyList,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</AllTrainDiagramContext.Provider>
|
||||
);
|
||||
};
|
98
stateBox/useAllTrainDiagram.tsx
Normal file
98
stateBox/useAllTrainDiagram.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import trainList from "@/assets/originData/trainList";
|
||||
import useInterval from "@/lib/useInterval";
|
||||
import { AS } from "@/storageControl";
|
||||
import React, { createContext, FC, useContext, useEffect, useState } from "react";
|
||||
const initialState = {
|
||||
allTrainDiagram: {},
|
||||
setAllTrainDiagram: (e) => {},
|
||||
allCustomTrainData: [],
|
||||
keyList: [],
|
||||
};
|
||||
type initialStateType = {
|
||||
allTrainDiagram: { [key: string]: string };
|
||||
setAllTrainDiagram: (e) => void;
|
||||
allCustomTrainData: any[];
|
||||
keyList: string[];
|
||||
};
|
||||
|
||||
const AllTrainDiagramContext = createContext<initialStateType>(initialState);
|
||||
|
||||
export const useAllTrainDiagram = () => useContext(AllTrainDiagramContext);
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
export const AllTrainDiagramProvider:FC<Props> = ({ children }) => {
|
||||
const [allTrainDiagram, setAllTrainDiagram] = useState(trainList);
|
||||
const [allCustomTrainData, setAllCustomTrainData] = useState([]); // カスタム列車データ
|
||||
const [keyList, setKeyList] = useState<string[]>([]); // 第二要素
|
||||
useEffect(() => {
|
||||
if (allTrainDiagram && Object.keys(allTrainDiagram).length > 0)
|
||||
setKeyList(Object.keys(allTrainDiagram));
|
||||
else setKeyList([]);
|
||||
}, [allTrainDiagram]);
|
||||
const getTrainDiagram = () =>
|
||||
fetch("https://n8n.haruk.in/webhook/JR-shikoku-diagram-migrate-original")
|
||||
.then((res) => res.json())
|
||||
.then((res) => res.data)
|
||||
.then((res) => {
|
||||
const data = {};
|
||||
res.forEach((d) => {
|
||||
const keys = Object.keys(d)[0];
|
||||
data[keys] = d[keys];
|
||||
});
|
||||
//dataのkeyで並び替え
|
||||
const sortedData = Object.keys(data)
|
||||
.sort((a, b) => parseInt(a.replace(/[D,M]/, "")) - parseInt(b.replace(/[D,M]/, "")))
|
||||
.reduce((acc, key) => {
|
||||
acc[key] = data[key];
|
||||
return acc;
|
||||
}, {});
|
||||
return sortedData;
|
||||
})
|
||||
.then((res:any) => {
|
||||
setAllTrainDiagram(res);
|
||||
AS.setItem("allTrainDiagram", JSON.stringify(res));
|
||||
})
|
||||
.catch((d) => {
|
||||
AS.getItem("allTrainDiagram")
|
||||
.then((d) => setAllTrainDiagram(JSON.parse(d)))
|
||||
.catch(() => {
|
||||
alert("初回の路線情報の取得に失敗しました。");
|
||||
});
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
getTrainDiagram();
|
||||
}, []);
|
||||
useInterval(getTrainDiagram, 30000); //30秒毎に全在線列車取得
|
||||
|
||||
const getCustomTrainData = () => {
|
||||
fetch("https://n8n.haruk.in/webhook/jr-shikoku-position-custom-datalist")
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
setAllCustomTrainData(res[0].data);
|
||||
})
|
||||
.catch(() => {
|
||||
alert("カスタム列車データの取得に失敗しました。");
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// カスタム列車データの取得
|
||||
getCustomTrainData();
|
||||
}, []);
|
||||
useInterval(getCustomTrainData, 30000); // 30秒毎にカスタム列車データ取得
|
||||
|
||||
return (
|
||||
<AllTrainDiagramContext.Provider
|
||||
value={{
|
||||
allTrainDiagram,
|
||||
setAllTrainDiagram,
|
||||
allCustomTrainData,
|
||||
keyList,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</AllTrainDiagramContext.Provider>
|
||||
);
|
||||
};
|
@@ -1,19 +1,12 @@
|
||||
import React, { createContext, useContext, useState, useEffect } from "react";
|
||||
import React, {
|
||||
createContext,
|
||||
useContext,
|
||||
useState,
|
||||
useEffect,
|
||||
FC,
|
||||
} from "react";
|
||||
import useInterval from "../lib/useInterval";
|
||||
|
||||
const initialState = {
|
||||
areaInfo: "",
|
||||
setAreainfo: () => {},
|
||||
areaIconBadgeText: "",
|
||||
areaStationID: [],
|
||||
};
|
||||
|
||||
const AreaInfoContext = createContext(initialState);
|
||||
|
||||
export const useAreaInfo = () => {
|
||||
return useContext(AreaInfoContext);
|
||||
};
|
||||
|
||||
const setoStationID = [
|
||||
"Y00",
|
||||
"Y01",
|
||||
@@ -340,7 +333,30 @@ const areaStationPair = {
|
||||
yodo: { id: "G", stationID: yodoStationID },
|
||||
};
|
||||
|
||||
export const AreaInfoProvider = ({ children }) => {
|
||||
const initialState = {
|
||||
areaInfo: "",
|
||||
setAreaInfo: () => {},
|
||||
areaIconBadgeText: "",
|
||||
areaStationID: [],
|
||||
isInfo: false,
|
||||
setIsInfo: () => {},
|
||||
};
|
||||
type initialStateType = {
|
||||
areaInfo: string;
|
||||
setAreaInfo: (e: string) => void;
|
||||
areaIconBadgeText: string;
|
||||
areaStationID: string[];
|
||||
isInfo: boolean;
|
||||
setIsInfo: (e: boolean) => void;
|
||||
};
|
||||
|
||||
const AreaInfoContext = createContext<initialStateType>(initialState);
|
||||
|
||||
export const useAreaInfo = () => {
|
||||
return useContext(AreaInfoContext);
|
||||
};
|
||||
type props = { children: React.ReactNode };
|
||||
export const AreaInfoProvider: FC<props> = ({ children }) => {
|
||||
const [areaInfo, setAreaInfo] = useState("");
|
||||
const [areaIconBadgeText, setAreaIconBadgeText] = useState("");
|
||||
const [areaStationID, setAreaStationID] = useState([]);
|
||||
@@ -378,7 +394,9 @@ export const AreaInfoProvider = ({ children }) => {
|
||||
);
|
||||
});
|
||||
};
|
||||
useEffect(getAreaData, []);
|
||||
useEffect(() => {
|
||||
getAreaData();
|
||||
}, []);
|
||||
useInterval(getAreaData, 60000); //60秒毎に全在線列車取得
|
||||
return (
|
||||
<AreaInfoContext.Provider
|
@@ -1,13 +1,19 @@
|
||||
import React, { createContext, useContext, useState, useEffect } from "react";
|
||||
import React, {
|
||||
createContext,
|
||||
useContext,
|
||||
useState,
|
||||
useEffect,
|
||||
FC,
|
||||
} from "react";
|
||||
import { AS } from "../storageControl";
|
||||
import { useAllTrainDiagram } from "./useAllTrainDiagram";
|
||||
const initialState = {
|
||||
busAndTrainData: [],
|
||||
setBusAndTrainData: () => {},
|
||||
setBusAndTrainData: (e) => {},
|
||||
trainPairData: [],
|
||||
setTrainPairData: () => {},
|
||||
initializeTrainPairList: () => {},
|
||||
getInfluencedTrainData: () => {},
|
||||
setTrainPairData: (e) => {},
|
||||
initializeTrainPairList: (e) => {},
|
||||
getInfluencedTrainData: (e) => {},
|
||||
};
|
||||
|
||||
const BusAndTrainDataContext = createContext(initialState);
|
||||
@@ -15,11 +21,17 @@ const BusAndTrainDataContext = createContext(initialState);
|
||||
export const useBusAndTrainData = () => {
|
||||
return useContext(BusAndTrainDataContext);
|
||||
};
|
||||
|
||||
export const BusAndTrainDataProvider = ({ children }) => {
|
||||
type props = { children: React.ReactNode };
|
||||
export const BusAndTrainDataProvider: FC<props> = ({ children }) => {
|
||||
const { allTrainDiagram } = useAllTrainDiagram();
|
||||
const [busAndTrainData, setBusAndTrainData] = useState([]);
|
||||
const [trainPairData, setTrainPairData] = useState([]);
|
||||
const [busAndTrainData, setBusAndTrainData] = useState<
|
||||
{
|
||||
address: string;
|
||||
name: string;
|
||||
type: "station-data" | "bus-stop" | "train-info";
|
||||
}[]
|
||||
>([]);
|
||||
const [trainPairData, setTrainPairData] = useState<any[]>([]);
|
||||
useEffect(() => {
|
||||
AS.getItem("busAndTrain202403")
|
||||
.then((d) => {
|
||||
@@ -53,7 +65,7 @@ export const BusAndTrainDataProvider = ({ children }) => {
|
||||
});
|
||||
return trainPairList;
|
||||
};
|
||||
const getInfluencedTrainData = (trainNum) => {
|
||||
const getInfluencedTrainData = (trainNum: string) => {
|
||||
const trainPairList = initializeTrainPairList();
|
||||
|
||||
// 9253M ラマル
|
||||
@@ -101,9 +113,6 @@ export const BusAndTrainDataProvider = ({ children }) => {
|
||||
case "4452D":
|
||||
returnArray.push("4545D");
|
||||
break;
|
||||
case "4456D":
|
||||
returnArray.push("4549D");
|
||||
break;
|
||||
case "4466D":
|
||||
returnArray.push("561D");
|
||||
break;
|
||||
@@ -144,9 +153,6 @@ export const BusAndTrainDataProvider = ({ children }) => {
|
||||
case "4545D":
|
||||
returnArray.push("4452D");
|
||||
break;
|
||||
case "4549D":
|
||||
returnArray.push("4456D");
|
||||
break;
|
||||
case "561D":
|
||||
returnArray.push("4466D");
|
||||
break;
|
||||
@@ -278,6 +284,18 @@ export const BusAndTrainDataProvider = ({ children }) => {
|
||||
case "4368D":
|
||||
returnArray.push("576D");
|
||||
break;
|
||||
case "3710D":
|
||||
returnArray.push("710D");
|
||||
break;
|
||||
case "710D":
|
||||
returnArray.push("3710D");
|
||||
break;
|
||||
case "3751D":
|
||||
returnArray.push("751D");
|
||||
break;
|
||||
case "751D":
|
||||
returnArray.push("3751D");
|
||||
break;
|
||||
}
|
||||
if (new RegExp(/^4[1-9]\d\d[DM]$/).test(trainNum)) {
|
||||
if (allTrainDiagram["5" + trainNum.substring(1)])
|
@@ -1,94 +0,0 @@
|
||||
import React, {
|
||||
createContext,
|
||||
useContext,
|
||||
useState,
|
||||
useEffect,
|
||||
useRef,
|
||||
} from "react";
|
||||
import { HeaderConfig } from "../lib/HeaderConfig";
|
||||
|
||||
import useInterval from "../lib/useInterval";
|
||||
const initialState = {
|
||||
webview: {},
|
||||
currentTrain: [],
|
||||
setCurrentTrain: () => {},
|
||||
currentTrainLoading: "loading",
|
||||
setCurrentTrainLoading: () => {},
|
||||
getCurrentTrain: () => {},
|
||||
inject: (i) => {},
|
||||
};
|
||||
|
||||
const CurrentTrainContext = createContext(initialState);
|
||||
|
||||
export const useCurrentTrain = () => {
|
||||
return useContext(CurrentTrainContext);
|
||||
};
|
||||
|
||||
export const CurrentTrainProvider = ({ children }) => {
|
||||
const [currentTrain, setCurrentTrain] = useState([]); //現在在線中の全列車 { num: 列車番号, delay: 遅延時分(状態), Pos: 位置情報 }
|
||||
const [currentTrainLoading, setCurrentTrainLoading] = useState("loading"); // success, error, loading
|
||||
const getCurrentTrain = () => {
|
||||
fetch("https://n8n.haruk.in/webhook/c501550c-7d1b-4e50-927b-4429fe18931a")
|
||||
.then((response) => response.json())
|
||||
.then((d) => d.data)
|
||||
.then((d) =>
|
||||
d.map((x) => ({
|
||||
Index: x.Index,
|
||||
num: x.TrainNum,
|
||||
delay: x.delay,
|
||||
Pos: x.Pos,
|
||||
PosNum: x.PosNum,
|
||||
Direction: x.Direction,
|
||||
Type: x.Type,
|
||||
Line: x.Line,
|
||||
}))
|
||||
)
|
||||
.then((d) => {
|
||||
setCurrentTrain(d);
|
||||
setCurrentTrainLoading("success");
|
||||
})
|
||||
.catch(() => {
|
||||
//alert("現在の全在線列車取得エラー/再取得します");
|
||||
fetch(
|
||||
"https://script.google.com/macros/s/AKfycby9Y2-Bm75J_WkbZimi7iS8v5r9wMa9wtzpdwES9sOGF4i6HIYEJOM60W6gM1gXzt1o/exec",
|
||||
HeaderConfig
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((d) =>
|
||||
d.map((x) => ({ num: x.TrainNum, delay: x.delay, Pos: x.Pos }))
|
||||
)
|
||||
.then((d) => {
|
||||
setCurrentTrain(d);
|
||||
setCurrentTrainLoading("success");
|
||||
})
|
||||
.catch(() => {
|
||||
// エラー時の処理
|
||||
setCurrentTrainLoading("error");
|
||||
});
|
||||
});
|
||||
};
|
||||
const inject = (i) => {
|
||||
webview.current?.injectJavaScript(i);
|
||||
};
|
||||
|
||||
useEffect(getCurrentTrain, []); //初回だけ現在の全在線列車取得
|
||||
|
||||
useInterval(getCurrentTrain, 15000); //15秒毎に全在線列車取得
|
||||
|
||||
const webview = useRef();
|
||||
return (
|
||||
<CurrentTrainContext.Provider
|
||||
value={{
|
||||
webview,
|
||||
currentTrain,
|
||||
setCurrentTrain,
|
||||
currentTrainLoading,
|
||||
setCurrentTrainLoading,
|
||||
getCurrentTrain,
|
||||
inject,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</CurrentTrainContext.Provider>
|
||||
);
|
||||
};
|
292
stateBox/useCurrentTrain.tsx
Normal file
292
stateBox/useCurrentTrain.tsx
Normal file
@@ -0,0 +1,292 @@
|
||||
import React, {
|
||||
createContext,
|
||||
useContext,
|
||||
useState,
|
||||
useEffect,
|
||||
useRef,
|
||||
FC,
|
||||
} from "react";
|
||||
import { HeaderConfig } from "@/lib/HeaderConfig";
|
||||
|
||||
import useInterval from "@/lib/useInterval";
|
||||
import { useStationList } from "@/stateBox/useStationList";
|
||||
import { checkDuplicateTrainData } from "@/lib/checkDuplicateTrainData";
|
||||
import { getStationID } from "@/lib/eachTrainInfoCoreLib/getStationData";
|
||||
import { trainDataType } from "@/lib/trainPositionTextArray";
|
||||
import WebView from "react-native-webview";
|
||||
import { StationProps } from "@/lib/CommonTypes";
|
||||
type loading = "loading" | "success" | "error";
|
||||
const initialState = {
|
||||
webview: undefined,
|
||||
currentTrain: [],
|
||||
setCurrentTrain: (e) => {},
|
||||
currentTrainLoading: "loading" as loading,
|
||||
setCurrentTrainLoading: (e) => {},
|
||||
getCurrentTrain: () => {},
|
||||
inject: (i) => {},
|
||||
fixedPosition: null,
|
||||
setFixedPosition: (e) => {},
|
||||
setInjectData: (e) => {},
|
||||
getCurrentStationData: ((e) => {}) as (
|
||||
e: string
|
||||
) => trainDataType | undefined,
|
||||
getPosition: ((e) => {}) as (e: trainDataType) => string[] | undefined,
|
||||
};
|
||||
|
||||
type initialStateType = {
|
||||
webview: React.MutableRefObject<WebView<{}>> | null;
|
||||
currentTrain: trainDataType[];
|
||||
setCurrentTrain: (e: trainDataType[]) => void;
|
||||
currentTrainLoading: loading;
|
||||
setCurrentTrainLoading: (e: loading) => void;
|
||||
getCurrentTrain: () => void;
|
||||
inject: (i: string) => void;
|
||||
fixedPosition: { type: "station" | "train"; value: string } | null;
|
||||
setFixedPosition: (
|
||||
e: { type: "station" | "train"; value: string } | null
|
||||
) => void;
|
||||
setInjectData: (e: {
|
||||
type: "station" | "train";
|
||||
value: string;
|
||||
fixed: boolean;
|
||||
}) => void;
|
||||
getCurrentStationData: (e: string) => trainDataType | undefined;
|
||||
getPosition: (e: trainDataType) => string[] | undefined;
|
||||
};
|
||||
|
||||
const CurrentTrainContext = createContext<initialStateType>(initialState);
|
||||
|
||||
export const useCurrentTrain = () => {
|
||||
return useContext(CurrentTrainContext);
|
||||
};
|
||||
type props = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
export const CurrentTrainProvider: FC<props> = ({ children }) => {
|
||||
const webview = useRef<WebView>(null);
|
||||
const [currentTrain, setCurrentTrain] = useState<trainDataType[]>([]); //現在在線中の全列車 { num: 列車番号, delay: 遅延時分(状態), Pos: 位置情報 }
|
||||
const [currentTrainLoading, setCurrentTrainLoading] =
|
||||
useState<loading>("loading");
|
||||
|
||||
const { getInjectJavascriptAddress, stationList, originalStationList } =
|
||||
useStationList();
|
||||
|
||||
const [fixedPosition, setFixedPosition] = useState<{
|
||||
type: "station" | "train";
|
||||
value: string;
|
||||
}>({
|
||||
type: null,
|
||||
value: null,
|
||||
});
|
||||
const [_, setIntervalState] = useInterval(() => {
|
||||
if (!webview.current) return;
|
||||
if (fixedPosition.type == "station") {
|
||||
const script = getInjectJavascriptAddress(fixedPosition.value);
|
||||
inject(script);
|
||||
} else if (fixedPosition.type == "train") {
|
||||
const currentTrain = getCurrentStationData(fixedPosition.value);
|
||||
const values = getPosition(currentTrain);
|
||||
if (!values) return;
|
||||
if (values[0] == "M12" || values[1] == "M12") {
|
||||
const script = getInjectJavascriptAddress("M12");
|
||||
inject(script);
|
||||
return;
|
||||
}
|
||||
const script = getInjectJavascriptAddress(
|
||||
values[values.length == 2 ? currentTrain.Direction : 0]
|
||||
);
|
||||
inject(script);
|
||||
} else {
|
||||
inject(`setReload()`);
|
||||
}
|
||||
}, 10000);
|
||||
// useEffect(() => {
|
||||
// if (fixedPosition) {
|
||||
// setIntervalState.start();
|
||||
// } else {
|
||||
// setIntervalState.stop();
|
||||
// }
|
||||
// }, [fixedPosition]);
|
||||
|
||||
type getPositionFuncType = (
|
||||
currentTrainData: trainDataType
|
||||
) => string[] | undefined;
|
||||
const getPosition: getPositionFuncType = (currentTrainData) => {
|
||||
//currentTrainData = {Pos:"伊予若宮~伊予大洲"}; //test
|
||||
if (!currentTrainData) return;
|
||||
if (!currentTrainData?.Pos) return;
|
||||
if (currentTrainData?.Pos.match("~")) {
|
||||
const pos = currentTrainData?.Pos.replace("(下り)", "")
|
||||
.replace("(上り)", "")
|
||||
.replace("(徳島線)", "")
|
||||
.replace("(高徳線)", "")
|
||||
.replace("(坂出方)", "")
|
||||
.replace("(児島方)", "")
|
||||
.split("~");
|
||||
const direction = currentTrainData?.Direction || 0;
|
||||
if (pos[0] == "児島" && pos[1] == "宇多津") {
|
||||
if (direction == 0) {
|
||||
return ["Y09", "M12"];
|
||||
} else {
|
||||
return ["M12", "Y09"];
|
||||
}
|
||||
} else if (pos[1] == "児島" && pos[0] == "宇多津") {
|
||||
return ["Y09", "M12"];
|
||||
} else if (pos[0] == "伊予若宮" && pos[1] == "伊予白滝") {
|
||||
return ["S18", "S14"];
|
||||
} else if (pos[0] == "伊予白滝" && pos[1] == "伊予若宮") {
|
||||
return ["S14", "S18"];
|
||||
} else if (pos[0] == "伊予大洲" && pos[1] == "伊予若宮") {
|
||||
return ["U14", "+Iyo"];
|
||||
} else if (pos[0] == "伊予若宮" && pos[1] == "伊予大洲") {
|
||||
return ["-Iyo", "U14"];
|
||||
}
|
||||
const currentPosID = Object.keys(originalStationList).map((key) => {
|
||||
let firstStation = false;
|
||||
let firstStationID = "";
|
||||
let secondStation = false;
|
||||
let secondStationID = "";
|
||||
originalStationList[key].forEach((station: StationProps) => {
|
||||
if (station.Station_JP === pos[0]) {
|
||||
firstStation = true;
|
||||
firstStationID = station.StationNumber;
|
||||
}
|
||||
if (station.Station_JP === pos[1]) {
|
||||
secondStation = true;
|
||||
secondStationID = station.StationNumber;
|
||||
}
|
||||
});
|
||||
if (firstStation && secondStation) {
|
||||
return [firstStationID, secondStationID];
|
||||
} else return false;
|
||||
});
|
||||
const currentPos = currentPosID.filter((d) => d != false)[0];
|
||||
if (currentPos) {
|
||||
return direction == 0 ? currentPos.reverse() : currentPos;
|
||||
} else if (direction == 0) {
|
||||
return [
|
||||
getStationID(pos[1], stationList),
|
||||
getStationID(pos[0], stationList),
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
getStationID(pos[0], stationList),
|
||||
getStationID(pos[1], stationList),
|
||||
];
|
||||
}
|
||||
} else {
|
||||
return [getStationID(currentTrainData?.Pos, stationList)];
|
||||
}
|
||||
};
|
||||
type getCurrentStationDataFunc = (e: string) => trainDataType | undefined;
|
||||
const getCurrentStationData: getCurrentStationDataFunc = (e) => {
|
||||
//e:trainNumber
|
||||
if (!currentTrain.length) return;
|
||||
return checkDuplicateTrainData(
|
||||
currentTrain.filter((d) => d.num == e),
|
||||
stationList
|
||||
);
|
||||
};
|
||||
|
||||
type injectDataType = {
|
||||
type: "station" | "train";
|
||||
value: string;
|
||||
fixed: boolean;
|
||||
};
|
||||
type injectDataFuncType = (data: injectDataType) => void;
|
||||
const setInjectData: injectDataFuncType = ({ type, value, fixed }) => {
|
||||
let script;
|
||||
switch (type) {
|
||||
case "station":
|
||||
script = getInjectJavascriptAddress(value);
|
||||
break;
|
||||
case "train":
|
||||
const currentTrain = getCurrentStationData(value);
|
||||
const values = getPosition(currentTrain);
|
||||
if (!values) return;
|
||||
if (values[0] == "M12" || values[1] == "M12") {
|
||||
script = getInjectJavascriptAddress("M12");
|
||||
} else {
|
||||
const valuesIndex = values.length == 2 ? currentTrain.Direction : 0;
|
||||
script = getInjectJavascriptAddress(values[valuesIndex]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
inject(script);
|
||||
if (fixed) {
|
||||
setFixedPosition({ type, value });
|
||||
}
|
||||
};
|
||||
const getCurrentTrain = () => {
|
||||
fetch("https://n8n.haruk.in/webhook/c501550c-7d1b-4e50-927b-4429fe18931a")
|
||||
.then((response) => response.json())
|
||||
.then((d) => d.data)
|
||||
.then((d) =>
|
||||
d.map((x) => ({
|
||||
Index: x.Index,
|
||||
num: x.TrainNum,
|
||||
delay: x.delay,
|
||||
Pos: x.Pos,
|
||||
PosNum: x.PosNum,
|
||||
Direction: x.Direction,
|
||||
Type: x.Type,
|
||||
Line: x.Line,
|
||||
}))
|
||||
)
|
||||
.then((d) => {
|
||||
setCurrentTrain(d);
|
||||
setCurrentTrainLoading("success");
|
||||
})
|
||||
.catch(() => {
|
||||
//alert("現在の全在線列車取得エラー/再取得します");
|
||||
fetch(
|
||||
"https://script.google.com/macros/s/AKfycby9Y2-Bm75J_WkbZimi7iS8v5r9wMa9wtzpdwES9sOGF4i6HIYEJOM60W6gM1gXzt1o/exec",
|
||||
HeaderConfig
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((d) =>
|
||||
d.map((x) => ({ num: x.TrainNum, delay: x.delay, Pos: x.Pos }))
|
||||
)
|
||||
.then((d) => {
|
||||
setCurrentTrain(d);
|
||||
setCurrentTrainLoading("success");
|
||||
})
|
||||
.catch(() => {
|
||||
// エラー時の処理
|
||||
setCurrentTrainLoading("error");
|
||||
});
|
||||
});
|
||||
};
|
||||
const inject = (i) => {
|
||||
webview.current?.injectJavaScript(i);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getCurrentTrain();
|
||||
}, []); //初回だけ現在の全在線列車取得
|
||||
|
||||
const [_0, _1] = useInterval(() => {
|
||||
getCurrentTrain();
|
||||
}, 10000); //10秒毎に全在線列車取得
|
||||
|
||||
return (
|
||||
<CurrentTrainContext.Provider
|
||||
value={{
|
||||
webview,
|
||||
currentTrain,
|
||||
setCurrentTrain,
|
||||
currentTrainLoading,
|
||||
setCurrentTrainLoading,
|
||||
getCurrentTrain,
|
||||
inject,
|
||||
setInjectData,
|
||||
getCurrentStationData,
|
||||
getPosition,
|
||||
fixedPosition,
|
||||
setFixedPosition,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</CurrentTrainContext.Provider>
|
||||
);
|
||||
};
|
@@ -1,7 +1,7 @@
|
||||
import React, { createContext, useContext, useState, useEffect } from "react";
|
||||
import { useWindowDimensions } from "react-native";
|
||||
import * as ScreenOrientation from "expo-screen-orientation";
|
||||
const initialState = { isLandscape: false, setIsLandscape: () => {} };
|
||||
const initialState = { isLandscape: false, setIsLandscape: (e) => {} };
|
||||
|
||||
const DeviceOrientationChange = createContext(initialState);
|
||||
|
||||
@@ -18,8 +18,8 @@ export const DeviceOrientationChangeProvider = ({ children }) => {
|
||||
);
|
||||
};
|
||||
useEffect(() => {
|
||||
data();
|
||||
//ScreenOrientation.unlockAsync();
|
||||
//data();
|
||||
ScreenOrientation.unlockAsync();
|
||||
}, []);
|
||||
|
||||
// useEffect(() => {
|
@@ -6,8 +6,9 @@ import React, {
|
||||
useLayoutEffect,
|
||||
FC,
|
||||
} from "react";
|
||||
import { AS } from "../storageControl";
|
||||
import { useStationList } from "./useStationList";
|
||||
import { AS } from "@/storageControl";
|
||||
import { useStationList } from "@/stateBox/useStationList";
|
||||
import { StationProps } from "@/lib/CommonTypes";
|
||||
const initialState = {
|
||||
favoriteStation: [],
|
||||
setFavoriteStation: () => {},
|
||||
@@ -16,8 +17,8 @@ const initialState = {
|
||||
|
||||
type initialStateType = {
|
||||
favoriteStation: any[];
|
||||
setFavoriteStation: (d:any)=>void;
|
||||
lodAddMigration: ()=>void;
|
||||
setFavoriteStation: (d: any) => void;
|
||||
lodAddMigration: () => void;
|
||||
};
|
||||
const FavoriteStationContext = createContext<initialStateType>(initialState);
|
||||
|
||||
@@ -27,8 +28,8 @@ export const useFavoriteStation = () => {
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
export const FavoriteStationProvider:FC<Props> = ({ children }) => {
|
||||
const [favoriteStation, setFavoriteStation] = useState([]);
|
||||
export const FavoriteStationProvider: FC<Props> = ({ children }) => {
|
||||
const [favoriteStation, setFavoriteStation] = useState<StationProps[][]>([]);
|
||||
const { getStationDataFromName } = useStationList();
|
||||
const lodAddMigration = () => {
|
||||
const migration = favoriteStation.map((d) => {
|
||||
@@ -39,13 +40,13 @@ export const FavoriteStationProvider:FC<Props> = ({ children }) => {
|
||||
useEffect(() => {
|
||||
AS.getItem("favoriteStation")
|
||||
.then((d) => {
|
||||
const returnData = JSON.parse(d);
|
||||
const returnData: StationProps[][] = JSON.parse(d);
|
||||
setFavoriteStation(returnData);
|
||||
})
|
||||
.catch((error) => {
|
||||
// エラーログを記録(開発時のみ)
|
||||
if (__DEV__) {
|
||||
console.warn('お気に入り駅の読み込みに失敗しました:', error);
|
||||
console.warn("お気に入り駅の読み込みに失敗しました:", error);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
@@ -9,13 +9,13 @@ import {
|
||||
lineList,
|
||||
getStationList,
|
||||
lineList_LineWebID,
|
||||
} from "../lib/getStationList";
|
||||
|
||||
} from "@/lib/getStationList";
|
||||
import { StationProps } from "@/lib/CommonTypes";
|
||||
type initialStateType = {
|
||||
originalStationList: any[][];
|
||||
setOriginalStationList: React.Dispatch<React.SetStateAction<any[]>>;
|
||||
getStationDataFromName: (id: string) => any[];
|
||||
getStationDataFromId: (id: string) => any[];
|
||||
originalStationList: StationProps[][];
|
||||
setOriginalStationList: React.Dispatch<React.SetStateAction<StationProps[]>>;
|
||||
getStationDataFromName: (id: string) => StationProps[];
|
||||
getStationDataFromId: (id: string) => StationProps[];
|
||||
getStationDataFromNameBase: (name: string) => any[];
|
||||
stationList: any[];
|
||||
getInjectJavascriptAddress: (StationNumber: string) => string;
|
||||
@@ -74,10 +74,15 @@ export const StationListProvider: FC<Props> = ({ children }) => {
|
||||
Object.keys(originalStationList).forEach((key) => {
|
||||
originalStationList[key].forEach((station) => {
|
||||
if (!station.StationNumber) return;
|
||||
if (typeof station.StationNumber === "string" && station.StationNumber.includes(name)) {
|
||||
if (
|
||||
typeof station.StationNumber === "string" &&
|
||||
station.StationNumber.includes(name)
|
||||
) {
|
||||
if (!!station.jslodApi) returnArray.push(station);
|
||||
}
|
||||
else if (typeof station.Station_JP === "string" && station.Station_JP.includes(name)) {
|
||||
} else if (
|
||||
typeof station.Station_JP === "string" &&
|
||||
station.Station_JP.includes(name)
|
||||
) {
|
||||
if (!!station.jslodApi) returnArray.push(station);
|
||||
}
|
||||
});
|
||||
@@ -122,7 +127,9 @@ export const StationListProvider: FC<Props> = ({ children }) => {
|
||||
});
|
||||
}
|
||||
});
|
||||
return `MoveDisplayStation('${bootStationList[0].line}_${bootStationList[0].station.MyStation}_${bootStationList[0].station.Station_JP}');document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`;
|
||||
console.log(bootStationList[0]);
|
||||
if (bootStationList[0] === undefined) return "";
|
||||
return `MoveDisplayStation('${bootStationList[0].line}_${bootStationList[0].station.MyStation}_${bootStationList[0].station.Station_JP}');document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");setReload();`;
|
||||
};
|
||||
|
||||
return (
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import React, { createContext, useContext, useEffect, useState } from "react";
|
||||
import React, { createContext, FC, useContext, useEffect, useState } from "react";
|
||||
const initialState = {
|
||||
getTime: new Date(),
|
||||
setGetTime: () => {},
|
||||
setGetTime: (e) => {},
|
||||
loadingDelayData: true,
|
||||
setLoadingDelayData: (loading) => {},
|
||||
delayData: undefined,
|
||||
setDelayData: () => {},
|
||||
setDelayData: (e) => {},
|
||||
};
|
||||
|
||||
const TrainDelayDataContext = createContext(initialState);
|
||||
@@ -13,8 +13,10 @@ const TrainDelayDataContext = createContext(initialState);
|
||||
export const useTrainDelayData = () => {
|
||||
return useContext(TrainDelayDataContext);
|
||||
};
|
||||
|
||||
export const TrainDelayDataProvider = ({ children }) => {
|
||||
type props = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
export const TrainDelayDataProvider:FC<props> = ({ children }) => {
|
||||
const [delayData, setDelayData] = useState(undefined);
|
||||
const [getTime, setGetTime] = useState(new Date());
|
||||
const [loadingDelayData, setLoadingDelayData] = useState(true);
|
@@ -1,4 +1,10 @@
|
||||
import React, { createContext, useContext, useState, useEffect } from "react";
|
||||
import React, {
|
||||
createContext,
|
||||
useContext,
|
||||
useState,
|
||||
useEffect,
|
||||
FC,
|
||||
} from "react";
|
||||
|
||||
import { ASCore } from "../storageControl";
|
||||
|
||||
@@ -9,29 +15,29 @@ import { useNotification } from "../stateBox/useNotifications";
|
||||
|
||||
const initialState = {
|
||||
selectedLine: undefined,
|
||||
setSelectedLine: () => {},
|
||||
setSelectedLine: (e) => {},
|
||||
mapsStationData: undefined,
|
||||
setMapsStationData: () => {},
|
||||
setMapsStationData: (e) => {},
|
||||
iconSetting: undefined,
|
||||
setIconSetting: () => {},
|
||||
setIconSetting: (e) => {},
|
||||
mapSwitch: undefined,
|
||||
setMapSwitch: () => {},
|
||||
setMapSwitch: (e) => {},
|
||||
stationMenu: undefined,
|
||||
setStationMenu: () => {},
|
||||
setStationMenu: (e) => {},
|
||||
uiSetting: undefined,
|
||||
setUiSetting: () => {},
|
||||
setUiSetting: (e) => {},
|
||||
LoadError: false,
|
||||
setLoadError: () => {},
|
||||
setLoadError: (e) => {},
|
||||
trainInfo: {
|
||||
trainNum: undefined,
|
||||
limited: undefined,
|
||||
trainData: undefined,
|
||||
},
|
||||
setTrainInfo: () => {},
|
||||
setTrainInfo: (e) => {},
|
||||
trainMenu: "true",
|
||||
setTrainMenu: () => {},
|
||||
updatePermission : false,
|
||||
setUpdatePermission : () => {},
|
||||
setTrainMenu: (e) => {},
|
||||
updatePermission: false,
|
||||
setUpdatePermission: (e) => {},
|
||||
injectJavascript: "",
|
||||
};
|
||||
|
||||
@@ -40,33 +46,36 @@ const TrainMenuContext = createContext(initialState);
|
||||
export const useTrainMenu = () => {
|
||||
return useContext(TrainMenuContext);
|
||||
};
|
||||
|
||||
export const TrainMenuProvider = ({ children }) => {
|
||||
type props = { children: React.ReactNode };
|
||||
export const TrainMenuProvider: FC<props> = ({ children }) => {
|
||||
const { expoPushToken } = useNotification();
|
||||
const [selectedLine, setSelectedLine] = useState(undefined);
|
||||
const [mapsStationData, setMapsStationData] = useState(undefined);
|
||||
useEffect(() => {
|
||||
getStationList2().then(setMapsStationData);
|
||||
}, []);
|
||||
|
||||
type boolType = "true" | "false" | undefined;
|
||||
//画面表示関連
|
||||
const [iconSetting, setIconSetting] = useState(undefined);
|
||||
const [mapSwitch, setMapSwitch] = useState(undefined);
|
||||
const [stationMenu, setStationMenu] = useState(undefined);
|
||||
const [iconSetting, setIconSetting] = useState<boolType>(undefined);
|
||||
const [mapSwitch, setMapSwitch] = useState<boolType>(undefined);
|
||||
const [stationMenu, setStationMenu] = useState<boolType>(undefined);
|
||||
const [LoadError, setLoadError] = useState(false);
|
||||
|
||||
//更新権限所有確認
|
||||
const [updatePermission, setUpdatePermission] = useState(false);
|
||||
useEffect(()=>{
|
||||
fetch("https://n8n.haruk.in/webhook/data-edit-permission?token=" + expoPushToken).then((res)=>res.json())
|
||||
.then((res)=>{
|
||||
if(res.data == true){
|
||||
setUpdatePermission(true);
|
||||
}else{
|
||||
setUpdatePermission(false);
|
||||
}
|
||||
})
|
||||
}, [expoPushToken])
|
||||
useEffect(() => {
|
||||
fetch(
|
||||
"https://n8n.haruk.in/webhook/data-edit-permission?token=" + expoPushToken
|
||||
)
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
if (res.data == true) {
|
||||
setUpdatePermission(true);
|
||||
} else {
|
||||
setUpdatePermission(false);
|
||||
}
|
||||
});
|
||||
}, [expoPushToken]);
|
||||
|
||||
//列車情報表示関連
|
||||
const [trainInfo, setTrainInfo] = useState({
|
||||
@@ -94,7 +103,7 @@ export const TrainMenuProvider = ({ children }) => {
|
||||
//列車アイコンスイッチ
|
||||
ASCore({ k: "iconSwitch", s: setIconSetting, d: "true", u: true });
|
||||
//地図スイッチ
|
||||
ASCore({ k: "mapSwitch", s: setMapSwitch, d: "false", u: true });
|
||||
ASCore({ k: "mapSwitch", s: setMapSwitch, d: "true", u: true });
|
||||
//駅メニュースイッチ
|
||||
ASCore({ k: "stationSwitch", s: setStationMenu, d: "true", u: true });
|
||||
//列車メニュースイッチ
|
@@ -58,7 +58,9 @@ export const UserPositionProvider: FC<Props> = ({ children }) => {
|
||||
if (Platform.OS == "web") return;
|
||||
getLocationPermission();
|
||||
}, []);
|
||||
useEffect(getCurrentPosition, [locationStatus]);
|
||||
useEffect(() => {
|
||||
getCurrentPosition();
|
||||
}, [locationStatus]);
|
||||
useInterval(getCurrentPosition, 5000);
|
||||
|
||||
return (
|
||||
|
Reference in New Issue
Block a user