Merge commit '012544beebf66d416d7a93f252e599ce201bcb47' into develop

This commit is contained in:
harukin-expo-dev-env 2025-07-05 09:43:54 +00:00
commit 19db27a378
14 changed files with 375 additions and 244 deletions

View File

@ -44,7 +44,8 @@ export const EachTrainInfoCore = ({
}) => { }) => {
const { currentTrain } = useCurrentTrain(); const { currentTrain } = useCurrentTrain();
const { originalStationList, stationList } = useStationList(); const { originalStationList, stationList } = useStationList();
const { allTrainDiagram: trainList } = useAllTrainDiagram(); const { allTrainDiagram: trainList, allCustonTrainData } =
useAllTrainDiagram();
const { setTrainInfo } = useTrainMenu(); const { setTrainInfo } = useTrainMenu();
const [currentTrainData, setCurrentTrainData] = useState(); const [currentTrainData, setCurrentTrainData] = useState();
@ -322,7 +323,7 @@ export const EachTrainInfoCore = ({
}, []); }, []);
const openTrainInfo = (d) => { const openTrainInfo = (d) => {
const train = customTrainDataDetector(d); const train = customTrainDataDetector(d, allCustonTrainData);
let TrainNumber = ""; let TrainNumber = "";
if (train.trainNumDistance != undefined) { if (train.trainNumDistance != undefined) {
const timeInfo = const timeInfo =

View File

@ -1,8 +1,6 @@
import React, { CSSProperties, FC, useEffect, useMemo, useState } from "react"; import React, { CSSProperties, FC, useEffect, useMemo, useState } from "react";
import { Text, View, LayoutAnimation, TextStyle, TouchableOpacity } from "react-native"; import { Text, View, TextStyle, TouchableOpacity } from "react-native";
import { Ionicons } from "@expo/vector-icons";
import { SheetManager } from "react-native-actions-sheet"; import { SheetManager } from "react-native-actions-sheet";
import { getType } from "../../../lib/eachTrainInfoCoreLib/getType";
import { migrateTrainName } from "../../../lib/eachTrainInfoCoreLib/migrateTrainName"; import { migrateTrainName } from "../../../lib/eachTrainInfoCoreLib/migrateTrainName";
import { TrainIconStatus } from "./trainIconStatus"; import { TrainIconStatus } from "./trainIconStatus";
import { TrainViewIcon } from "./trainViewIcon"; import { TrainViewIcon } from "./trainViewIcon";
@ -10,6 +8,7 @@ import { OneManText } from "./HeaderTextParts/OneManText";
import { customTrainDataDetector } from "@/components/custom-train-data"; import { customTrainDataDetector } from "@/components/custom-train-data";
import { InfogramText } from "@/components/ActionSheetComponents/EachTrainInfoCore/HeaderTextParts/InfogramText"; import { InfogramText } from "@/components/ActionSheetComponents/EachTrainInfoCore/HeaderTextParts/InfogramText";
import { useTrainMenu } from "@/stateBox/useTrainMenu"; import { useTrainMenu } from "@/stateBox/useTrainMenu";
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
import { useNotification } from "@/stateBox/useNotifications"; import { useNotification } from "@/stateBox/useNotifications";
type Props = { type Props = {
@ -40,17 +39,21 @@ export const HeaderText: FC<Props> = ({
tailStation, tailStation,
navigate, navigate,
from, from,
scrollHandlers scrollHandlers,
}) => { }) => {
const { limited, trainNum } = data; const { limited, trainNum } = data;
const { updatePermission } = useTrainMenu(); const { updatePermission } = useTrainMenu();
const {expoPushToken} = useNotification(); const { allCustonTrainData } = useAllTrainDiagram();
const { expoPushToken } = useNotification();
// 列車名、種別、フォントの取得 // 列車名、種別、フォントの取得
const [typeName, trainName, fontAvailable, isOneMan, infogram] = const [typeName, trainName, fontAvailable, isOneMan, infogram] =
useMemo(() => { useMemo(() => {
const customTrainData = customTrainDataDetector(trainNum); const customTrainData = customTrainDataDetector(
trainNum,
allCustonTrainData
);
const [type, fontAvailable, isOneMan] = (() => { const [type, fontAvailable, isOneMan] = (() => {
switch (customTrainData.type) { switch (customTrainData.type) {
case "LTDEXP": case "LTDEXP":
@ -123,14 +126,23 @@ export const HeaderText: FC<Props> = ({
}, [trainData]); }, [trainData]);
return ( return (
<View style={{ padding: 10, flexDirection: "row", alignItems: "center" }} onTouchStart={()=>scrollHandlers.ref.current?.scrollTo({ y: 0, animated: true })}> <View
style={{ padding: 10, flexDirection: "row", alignItems: "center" }}
onTouchStart={() =>
scrollHandlers.ref.current?.scrollTo({ y: 0, animated: true })
}
>
<TrainIconStatus {...{ data, navigate, from }} /> <TrainIconStatus {...{ data, navigate, from }} />
<TouchableOpacity <TouchableOpacity
style={{ borderRadius: 5, flexDirection: "row", alignItems: "center" }} style={{ borderRadius: 5, flexDirection: "row", alignItems: "center" }}
onLongPress={() => { onLongPress={() => {
navigate("generalWebView", { navigate("generalWebView", {
uri: "https://jr-shikoku-data-post-system.pages.dev?trainNum=" + trainNum + "&token=" + expoPushToken, uri:
useExitButton: false "https://jr-shikoku-data-post-system.pages.dev?trainNum=" +
trainNum +
"&token=" +
expoPushToken,
useExitButton: false,
}); });
SheetManager.hide("EachTrainInfo"); SheetManager.hide("EachTrainInfo");
}} }}

View File

@ -6,6 +6,7 @@ import { useInterval } from "../../../lib/useInterval";
import { Icon } from "@expo/vector-icons/build/createIconSet"; import { Icon } from "@expo/vector-icons/build/createIconSet";
import { SheetManager } from "react-native-actions-sheet"; import { SheetManager } from "react-native-actions-sheet";
import { customTrainDataDetector } from "../../custom-train-data"; import { customTrainDataDetector } from "../../custom-train-data";
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
type GlyphNames = ComponentProps<typeof Ionicons>["name"]; type GlyphNames = ComponentProps<typeof Ionicons>["name"];
@ -22,11 +23,14 @@ export const TrainIconStatus: FC<Props> = ({ data, navigate, from }) => {
const [trainIcon, setTrainIcon] = useState(null); const [trainIcon, setTrainIcon] = useState(null);
const [anpanmanStatus, setAnpanmanStatus] = useState<apt>(); const [anpanmanStatus, setAnpanmanStatus] = useState<apt>();
const [address, setAddress] = useState(""); const [address, setAddress] = useState("");
const { allCustonTrainData } = useAllTrainDiagram();
useEffect(() => { useEffect(() => {
if (!data.trainNum) return; if (!data.trainNum) return;
const { trainIcon, infoUrl } = customTrainDataDetector(data.trainNum); const { img, infoUrl } = customTrainDataDetector(
if (trainIcon) setTrainIcon(trainIcon); data.trainNum,
allCustonTrainData
);
if (img) setTrainIcon(img);
if (infoUrl) setAddress(infoUrl); if (infoUrl) setAddress(infoUrl);
switch (data.trainNum) { switch (data.trainNum) {
@ -57,31 +61,31 @@ export const TrainIconStatus: FC<Props> = ({ data, navigate, from }) => {
} }
}); });
break; break;
case "2074D": case "2074D":
case "2076D": case "2076D":
case "2080D": case "2080D":
case "2082D": case "2082D":
case "2071D": case "2071D":
case "2073D": case "2073D":
case "2079D": case "2079D":
case "2081D": case "2081D":
fetch( fetch(
`https://n8n.haruk.in/webhook/dosan-anpanman-first?trainNum=${ `https://n8n.haruk.in/webhook/dosan-anpanman-first?trainNum=${
data.trainNum data.trainNum
}&month=${dayjs().format("M")}&day=${dayjs().format("D")}` }&month=${dayjs().format("M")}&day=${dayjs().format("D")}`
) )
.then((d) => d.json()) .then((d) => d.json())
.then((d) => { .then((d) => {
console.log(d); console.log(d);
if (d.trainStatus == "") { if (d.trainStatus == "") {
//setAnpanmanStatus({name:"checkmark-circle-outline",color:"blue"}); //setAnpanmanStatus({name:"checkmark-circle-outline",color:"blue"});
} else if (d.trainStatus == "▲") { } else if (d.trainStatus == "▲") {
setAnpanmanStatus({ name: "warning-outline", color: "yellow" }); setAnpanmanStatus({ name: "warning-outline", color: "yellow" });
} else if (d.trainStatus == "×") { } else if (d.trainStatus == "×") {
//setAnpanmanStatus({ name: "close-circle-outline", color: "red" }); //setAnpanmanStatus({ name: "close-circle-outline", color: "red" });
} }
}); });
break; break;
} }
}, [data.trainNum]); }, [data.trainNum]);
const [move, setMove] = useState(true); const [move, setMove] = useState(true);
@ -104,6 +108,7 @@ export const TrainIconStatus: FC<Props> = ({ data, navigate, from }) => {
}); });
SheetManager.hide("EachTrainInfo"); SheetManager.hide("EachTrainInfo");
}} }}
disabled={!address}
> >
{move ? ( {move ? (
<Image <Image

View File

@ -135,9 +135,7 @@ export const StationDeteilView = (props) => {
useShow={useShow} useShow={useShow}
/> />
)} )}
{!currentStation[0].StationMap || ( <StationMapButton stationMap={currentStation[0].StationMap || `https://www.google.co.jp/maps/place/${currentStation[0].lat},${currentStation[0].lng}`} />
<StationMapButton stationMap={currentStation[0].StationMap} />
)}
{!trainBus || ( {!trainBus || (
<TrainBusButton <TrainBusButton
address={trainBus.address} address={trainBus.address}

View File

@ -21,7 +21,7 @@ import { BigButton } from "./atom/BigButton";
import { Switch } from "react-native-elements"; import { Switch } from "react-native-elements";
export default function AllTrainDiagramView() { export default function AllTrainDiagramView() {
const { goBack, navigate } = useNavigation(); const { goBack, navigate } = useNavigation();
const { keyList, allTrainDiagram } = useAllTrainDiagram(); const { keyList, allTrainDiagram, allCustonTrainData } = useAllTrainDiagram();
const [input, setInput] = useState(""); // 文字入力 const [input, setInput] = useState(""); // 文字入力
const [keyBoardVisible, setKeyBoardVisible] = useState(false); const [keyBoardVisible, setKeyBoardVisible] = useState(false);
const [useStationName, setUseStationName] = useState(false); const [useStationName, setUseStationName] = useState(false);
@ -53,7 +53,7 @@ export default function AllTrainDiagramView() {
}, []); }, []);
const openTrainInfo = (d) => { const openTrainInfo = (d) => {
const train = customTrainDataDetector(d); const train = customTrainDataDetector(d, allCustonTrainData);
let TrainNumber = ""; let TrainNumber = "";
if (train.trainNumDistance != undefined) { if (train.trainNumDistance != undefined) {
const timeInfo = const timeInfo =
@ -74,6 +74,7 @@ export default function AllTrainDiagramView() {
return ( return (
<View style={{ backgroundColor: "#0099CC", height: "100%" }}> <View style={{ backgroundColor: "#0099CC", height: "100%" }}>
<FlatList <FlatList
contentContainerStyle={{ justifyContent: "flex-end", flexGrow: 1 }}
style={{ flex: 1 }} style={{ flex: 1 }}
data={keyList?.filter((d) => { data={keyList?.filter((d) => {
if (useStationName) { if (useStationName) {
@ -93,6 +94,14 @@ export default function AllTrainDiagramView() {
return d.includes(input); return d.includes(input);
})} })}
renderItem={({ item }) => <Item {...{ openTrainInfo, id: item }} />} renderItem={({ item }) => <Item {...{ openTrainInfo, id: item }} />}
ListEmptyComponent={
<View style={{ flex: 1, alignItems: "center", marginTop: 50 }}>
<Text style={{ color: "white", fontSize: 20 }}>
検索結果がありません
</Text>
</View>
}
keyExtractor={(item) => item} keyExtractor={(item) => item}
//initialNumToRender={100} //initialNumToRender={100}
/> />

View File

@ -2,7 +2,13 @@ import React from "react";
import { Platform, LayoutAnimation } from "react-native"; import { Platform, LayoutAnimation } from "react-native";
import { WebView } from "react-native-webview"; import { WebView } from "react-native-webview";
import { lineList, stationNamePair } from "../../lib/getStationList"; import {
lineList,
lineList_LineWebID,
lineListPair,
stationIDPair,
stationNamePair,
} from "../../lib/getStationList";
import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData"; import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData";
import { useFavoriteStation } from "../../stateBox/useFavoriteStation"; import { useFavoriteStation } from "../../stateBox/useFavoriteStation";
import { useCurrentTrain } from "../../stateBox/useCurrentTrain"; import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
@ -17,7 +23,7 @@ export const AppsWebView = ({ openStationACFromEachTrainInfo }) => {
const { navigate } = useNavigation(); const { navigate } = useNavigation();
const { favoriteStation } = useFavoriteStation(); const { favoriteStation } = useFavoriteStation();
const { isLandscape } = useDeviceOrientationChange(); const { isLandscape } = useDeviceOrientationChange();
const { originalStationList, stationList } = useStationList(); const { originalStationList, stationList, getInjectJavascriptAddress } = useStationList();
const { const {
setSelectedLine, setSelectedLine,
mapsStationData: stationData, mapsStationData: stationData,
@ -129,20 +135,11 @@ export const AppsWebView = ({ openStationACFromEachTrainInfo }) => {
const onLoadEnd = () => { const onLoadEnd = () => {
if (once) return () => {}; if (once) return () => {};
if (!stationData) return () => {}; if (!stationData) return () => {};
if (!originalStationList) return () => {};
if (favoriteStation.length < 1) return () => {}; if (favoriteStation.length < 1) return () => {};
const getStationLine = (now) => { const string = getInjectJavascriptAddress(favoriteStation[0][0].StationNumber);
const returnData = Object.keys(stationData).filter((d) => { if (!string) return () => {};
const cache = stationData[d].findIndex( webview.current?.injectJavaScript(string);
(data) => data.Station_JP == now.Station_JP
);
return cache != -1;
});
return returnData[0];
};
const lineName = getStationLine(favoriteStation[0][0]);
webview.current?.injectJavaScript(
`MoveDisplayStation('${lineName}_${favoriteStation[0][0].MyStation}_${favoriteStation[0][0].Station_JP}')`
);
once = true; once = true;
}; };

View File

@ -1,6 +1,7 @@
import React, { FC } from "react"; import React, { FC } from "react";
import { Marker } from "react-native-maps"; import { Marker } from "react-native-maps";
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
import { useStationList } from "@/stateBox/useStationList";
type Props = { type Props = {
index: number; index: number;
indexBase: number; indexBase: number;
@ -13,7 +14,8 @@ type Props = {
export const MapPin: FC<Props> = (props) => { export const MapPin: FC<Props> = (props) => {
const { index, indexBase, latlng, D, d, navigate, webview } = props; const { index, indexBase, latlng, D, d, navigate, webview } = props;
const {goBack} = useNavigation(); const { goBack } = useNavigation();
const { getInjectJavascriptAddress } = useStationList();
return ( return (
<Marker <Marker
key={index + indexBase} key={index + indexBase}
@ -22,10 +24,9 @@ export const MapPin: FC<Props> = (props) => {
longitude: parseFloat(latlng[1]), longitude: parseFloat(latlng[1]),
}} }}
onPress={() => { onPress={() => {
webview.current?.injectJavaScript( const address = getInjectJavascriptAddress(D.StationNumber);
`MoveDisplayStation('${d}_${D.MyStation}_${D.Station_JP}'); if (!address) return;
document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");` webview.current?.injectJavaScript(address);
);
if (navigate) goBack(); if (navigate) goBack();
}} }}
image={require("../../assets/reccha-small.png")} image={require("../../assets/reccha-small.png")}

View File

@ -1,6 +1,19 @@
import dayjs from "dayjs"; import dayjs from "dayjs";
export const customTrainDataDetector = (TrainNumber: string) => { export const customTrainDataDetector = (
const trainGetText = `?trainNum=${TrainNumber}&month=${dayjs().format("M")}&day=${dayjs().format("D")}`; TrainNumber: string,
allCustonTrainData?: any[]
) => {
if (allCustonTrainData && allCustonTrainData.length > 0) {
const customTrain = allCustonTrainData.find(
(train) => train.TrainNumber === TrainNumber
);
if (customTrain) {
return customTrain;
}
}
const trainGetText = `?trainNum=${TrainNumber}&month=${dayjs().format(
"M"
)}&day=${dayjs().format("D")}`;
switch (TrainNumber) { switch (TrainNumber) {
//しおかぜメイン //しおかぜメイン
//8000 ノーマル //8000 ノーマル
@ -24,23 +37,23 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "しおかぜ", trainName: "しおかぜ",
trainIcon: "https://storage.haruk.in/s8000nr.png", img: "https://storage.haruk.in/s8000nr.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html",
trainNumDistance: 0, trainNumDistance: 0,
info: "いしづちと併結 / 8000系で運転", info: "いしづちと併結 / 8000系で運転",
infogram: "" infogram: "",
}; };
case "2M": case "2M":
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "しおかぜ", trainName: "しおかぜ",
trainIcon: "https://storage.haruk.in/s8000nr.png", img: "https://storage.haruk.in/s8000nr.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html",
trainNumDistance: 0, trainNumDistance: 0,
info: "8000系で運転", info: "8000系で運転",
infogram: "" infogram: "",
}; };
//8000 アンパン //8000 アンパン
case "10M": case "10M":
@ -50,11 +63,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "しおかぜ", trainName: "しおかぜ",
trainIcon: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`, img: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`,
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html", infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
trainNumDistance: 0, trainNumDistance: 0,
info: "いしづちと併結 / アンパンマン列車で運転", info: "いしづちと併結 / アンパンマン列車で運転",
infogram: "" infogram: "",
}; };
//8600 //8600
case "8M": case "8M":
@ -68,12 +81,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "しおかぜ", trainName: "しおかぜ",
trainIcon: "https://storage.haruk.in/s8600.png", img: "https://storage.haruk.in/s8600.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html",
trainNumDistance: 0, trainNumDistance: 0,
info: "いしづちと併結 / 8600系で運転", info: "いしづちと併結 / 8600系で運転",
infogram: "" infogram: "",
}; };
//いしづちメイン //いしづちメイン
@ -99,12 +112,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "いしづち", trainName: "いしづち",
trainIcon: "https://storage.haruk.in/s8000no.png", img: "https://storage.haruk.in/s8000no.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
trainNumDistance: 1000, trainNumDistance: 1000,
info: "しおかぜと併結 / 8000系で運転", info: "しおかぜと併結 / 8000系で運転",
infogram: "" infogram: "",
}; };
//8000 アンパン //8000 アンパン
@ -115,11 +128,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "いしづち", trainName: "いしづち",
trainIcon: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`, img: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`,
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html", infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
trainNumDistance: 1000, trainNumDistance: 1000,
info: "しおかぜと併結 / アンパンマン列車で運転", info: "しおかぜと併結 / アンパンマン列車で運転",
infogram: "" infogram: "",
}; };
//8600 //8600
@ -134,12 +147,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "いしづち", trainName: "いしづち",
trainIcon: "https://storage.haruk.in/s8600_isz.png", img: "https://storage.haruk.in/s8600_isz.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
trainNumDistance: 1000, trainNumDistance: 1000,
info: "しおかぜと併結 / 8600系で運転", info: "しおかぜと併結 / 8600系で運転",
infogram: "" infogram: "",
}; };
//MEXP //MEXP
@ -148,24 +161,24 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "モーニングEXP高松", trainName: "モーニングEXP高松",
trainIcon: "https://storage.haruk.in/s8000nr.png", img: "https://storage.haruk.in/s8000nr.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/morning.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/morning.html",
trainNumDistance: null, trainNumDistance: null,
info: "8000系で運転", info: "8000系で運転",
infogram: "" infogram: "",
}; };
//8600 //8600
case "1091M": case "1091M":
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "モーニングEXP松山", trainName: "モーニングEXP松山",
trainIcon: "https://storage.haruk.in/s8600_isz.png", img: "https://storage.haruk.in/s8600_isz.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/morning.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/morning.html",
trainNumDistance: null, trainNumDistance: null,
info: "8600系で運転", info: "8600系で運転",
infogram: "" infogram: "",
}; };
//三桁いしづち //三桁いしづち
//8000 アンパン //8000 アンパン
@ -174,11 +187,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "いしづち", trainName: "いしづち",
trainIcon: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`, img: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`,
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html", infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
trainNumDistance: 940, trainNumDistance: 940,
info: "アンパンマン列車で運転", info: "アンパンマン列車で運転",
infogram: "" infogram: "",
}; };
//8600 //8600
case "1043M": case "1043M":
@ -186,23 +199,23 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "いしづち", trainName: "いしづち",
trainIcon: "https://storage.haruk.in/s8600_isz.png", img: "https://storage.haruk.in/s8600_isz.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
trainNumDistance: 940, trainNumDistance: 940,
info: "8600系で運転", info: "8600系で運転",
infogram: "" infogram: "",
}; };
case "1046M": case "1046M":
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "いしづち", trainName: "いしづち",
trainIcon: "https://storage.haruk.in/s8600_isz.png", img: "https://storage.haruk.in/s8600_isz.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
trainNumDistance: 940, trainNumDistance: 940,
info: "8600系で運転", info: "8600系で運転",
infogram: "" infogram: "",
}; };
//南風 2700ーマル //南風 2700ーマル
@ -227,11 +240,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "南風", trainName: "南風",
trainIcon: "https://storage.haruk.in/s2700.png", img: "https://storage.haruk.in/s2700.png",
infoUrl: "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/nanpu.html", infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/nanpu.html",
trainNumDistance: 30, trainNumDistance: 30,
info: "2700系で運転", info: "2700系で運転",
infogram: "" infogram: "",
}; };
//2700アンパン //2700アンパン
@ -248,11 +262,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "南風", trainName: "南風",
trainIcon: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`, img: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`,
infoUrl: "https://www.jr-eki.com/aptrain/naani/dosan/train.html", infoUrl: "https://www.jr-eki.com/aptrain/naani/dosan/train.html",
trainNumDistance: 30, trainNumDistance: 30,
info: "アンパンマン列車で運転", info: "アンパンマン列車で運転",
infogram: "" infogram: "",
}; };
//うずしお //うずしお
@ -273,12 +287,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "うずしお", trainName: "うずしお",
trainIcon: "https://storage.haruk.in/s2700_uzu.png", img: "https://storage.haruk.in/s2700_uzu.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html",
trainNumDistance: 3000, trainNumDistance: 3000,
info: "2700系で運転", info: "2700系で運転",
infogram: "" infogram: "",
}; };
//2700 二両編成 //2700 二両編成
@ -295,12 +309,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "うずしお", trainName: "うずしお",
trainIcon: "https://storage.haruk.in/s2700_uzu.png", img: "https://storage.haruk.in/s2700_uzu.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html",
trainNumDistance: 3000, trainNumDistance: 3000,
info: "2700系で運転", info: "2700系で運転",
infogram: "" infogram: "",
}; };
//2600 //2600
@ -317,15 +331,14 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "うずしお", trainName: "うずしお",
trainIcon: "https://storage.haruk.in/s2600.png", img: "https://storage.haruk.in/s2600.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html",
trainNumDistance: 3000, trainNumDistance: 3000,
info: "2600系で運転", info: "2600系で運転",
infogram: "" infogram: "",
}; };
//マリンライナー //マリンライナー
case "3104M": case "3104M":
case "3106M": case "3106M":
@ -398,11 +411,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "Rapid", type: "Rapid",
trainName: "マリンライナー", trainName: "マリンライナー",
trainIcon: "https://storage.haruk.in/s5001.png", img: "https://storage.haruk.in/s5001.png",
infoUrl: "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/marine.html", infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/marine.html",
trainNumDistance: 3100, trainNumDistance: 3100,
info: "", info: "",
infogram: "" infogram: "",
}; };
case "3102M": case "3102M":
case "3101M": case "3101M":
@ -412,22 +426,23 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "Rapid", type: "Rapid",
trainName: "マリンライナー", trainName: "マリンライナー",
trainIcon: "https://storage.haruk.in/s5001k.png", img: "https://storage.haruk.in/s5001k.png",
infoUrl: "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/marine.html", infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/marine.html",
trainNumDistance: 3100, trainNumDistance: 3100,
info: "", info: "",
infogram: "" infogram: "",
}; };
//下りサンポート //下りサンポート
case "1219M": case "1219M":
return { return {
type: "Normal", type: "Normal",
trainName: "南風リレー", trainName: "南風リレー",
trainIcon: "", img: "",
infoUrl: "", infoUrl: "",
trainNumDistance: null, trainNumDistance: null,
info: " 土曜・休日は多度津-琴平間運休", info: " 土曜・休日は多度津-琴平間運休",
infogram: "" infogram: "",
}; };
case "111M": case "111M":
@ -443,11 +458,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "Rapid", type: "Rapid",
trainName: "サンポート南風リレー", trainName: "サンポート南風リレー",
trainIcon: null, img: null,
infoUrl: null, infoUrl: null,
trainNumDistance: null, trainNumDistance: null,
info: null, info: null,
infogram: "" infogram: "",
}; };
case "5109M": case "5109M":
case "5135M": case "5135M":
@ -455,32 +470,32 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "OneManRapid", type: "OneManRapid",
trainName: "サンポート南風リレー", trainName: "サンポート南風リレー",
trainIcon: null, img: null,
infoUrl: null, infoUrl: null,
trainNumDistance: null, trainNumDistance: null,
info: null, info: null,
infogram: "" infogram: "",
}; };
case "137M": case "137M":
return { return {
type: "Rapid", type: "Rapid",
trainName: "サンポート", trainName: "サンポート",
trainIcon: null, img: null,
infoUrl: null, infoUrl: null,
trainNumDistance: null, trainNumDistance: null,
info: "土曜・休日運休", info: "土曜・休日運休",
infogram: "" infogram: "",
}; };
//上りサンポート //上りサンポート
case "116M": case "116M":
return { return {
type: "Normal", type: "Normal",
trainName: "南風リレー", trainName: "南風リレー",
trainIcon: null, img: null,
infoUrl: null, infoUrl: null,
trainNumDistance: null, trainNumDistance: null,
info: null, info: null,
infogram: "" infogram: "",
}; };
case "130M": case "130M":
@ -494,11 +509,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "Rapid", type: "Rapid",
trainName: "サンポート南風リレー", trainName: "サンポート南風リレー",
trainIcon: "", img: "",
infoUrl: "", infoUrl: "",
trainNumDistance: null, trainNumDistance: null,
info: "", info: "",
infogram: "" infogram: "",
}; };
case "5118M": case "5118M":
case "5120M": case "5120M":
@ -508,11 +523,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "OneManRapid", type: "OneManRapid",
trainName: "サンポート南風リレー", trainName: "サンポート南風リレー",
trainIcon: null, img: null,
infoUrl: null, infoUrl: null,
trainNumDistance: null, trainNumDistance: null,
info: null, info: null,
infogram: "" infogram: "",
}; };
//サンライズ瀬戸 //サンライズ瀬戸
@ -521,24 +536,24 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "NightLTDEXP", type: "NightLTDEXP",
trainName: "サンライズ瀬戸", trainName: "サンライズ瀬戸",
trainIcon: "https://storage.haruk.in/w285.png", img: "https://storage.haruk.in/w285.png",
infoUrl: infoUrl:
"https://www.jr-odekake.net/train/sunriseseto_izumo/index.html", "https://www.jr-odekake.net/train/sunriseseto_izumo/index.html",
trainNumDistance: null, trainNumDistance: null,
info: "", info: "",
infogram: "ブ" infogram: "ブ",
}; };
case "8041M": //琴平延長高松迄 case "8041M": //琴平延長高松迄
case "8031M": //琴平延長高松以降 case "8031M": //琴平延長高松以降
return { return {
type: "NightLTDEXP", type: "NightLTDEXP",
trainName: "サンライズ瀬戸", trainName: "サンライズ瀬戸",
trainIcon: "https://storage.haruk.in/w285.png", img: "https://storage.haruk.in/w285.png",
infoUrl: infoUrl:
"https://www.jr-odekake.net/train/sunriseseto_izumo/index.html", "https://www.jr-odekake.net/train/sunriseseto_izumo/index.html",
trainNumDistance: null, trainNumDistance: null,
info: "琴平延長運転日", info: "琴平延長運転日",
infogram: "ブ" infogram: "ブ",
}; };
//宇和海 //宇和海
@ -572,11 +587,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "宇和海", trainName: "宇和海",
trainIcon: "https://storage.haruk.in/s2000_uwa.png", img: "https://storage.haruk.in/s2000_uwa.png",
infoUrl: "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uwakai.html", infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uwakai.html",
trainNumDistance: 1050, trainNumDistance: 1050,
info: "2000系で運転", info: "2000系で運転",
infogram: "" infogram: "",
}; };
//2000 アンパン込み //2000 アンパン込み
case "1058D": case "1058D":
@ -588,11 +604,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "宇和海", trainName: "宇和海",
trainIcon: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`, img: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`,
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html", infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
trainNumDistance: 1050, trainNumDistance: 1050,
info: "アンパン列車で運転", info: "アンパン列車で運転",
infogram: "" infogram: "",
}; };
//しまんと //しまんと
case "2002D": case "2002D":
@ -602,12 +618,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "しまんと", trainName: "しまんと",
trainIcon: "https://storage.haruk.in/s2700_smn.png", img: "https://storage.haruk.in/s2700_smn.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shimanto.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shimanto.html",
trainNumDistance: 2000, trainNumDistance: 2000,
info: "2700系で運転", info: "2700系で運転",
infogram: "" infogram: "",
}; };
//あしずり 2000 //あしずり 2000
@ -622,12 +638,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "あしずり", trainName: "あしずり",
trainIcon: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`, img: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`,
infoUrl: infoUrl:
"https://www.jr-eki.com/aptrain/naani/first-generation/jikoku.html", "https://www.jr-eki.com/aptrain/naani/first-generation/jikoku.html",
trainNumDistance: 2070, trainNumDistance: 2070,
info: "2000系で運転", info: "2000系で運転",
infogram: "" infogram: "",
}; };
//あしずり 2700 //あしずり 2700
@ -638,24 +654,24 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "あしずり", trainName: "あしずり",
trainIcon: "https://storage.haruk.in/s2700_asi.png", img: "https://storage.haruk.in/s2700_asi.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ashizuri.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ashizuri.html",
trainNumDistance: 2070, trainNumDistance: 2070,
info: "2700系で運転", info: "2700系で運転",
infogram: "" infogram: "",
}; };
case "2072D": case "2072D":
case "2083D": case "2083D":
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "あしずり", trainName: "あしずり",
trainIcon: "https://storage.haruk.in/s2700_asi.png", img: "https://storage.haruk.in/s2700_asi.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ashizuri.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ashizuri.html",
trainNumDistance: 2070, trainNumDistance: 2070,
info: "2700系で運転", info: "2700系で運転",
infogram: "" infogram: "",
}; };
//剣山 //剣山
@ -669,12 +685,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "剣山", trainName: "剣山",
trainIcon: "https://storage.haruk.in/s185tu.png", img: "https://storage.haruk.in/s185tu.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/tsurugisan.html", "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/tsurugisan.html",
trainNumDistance: 4000, trainNumDistance: 4000,
info: "キハ185系で運転", info: "キハ185系で運転",
infogram: "" infogram: "",
}; };
//よしのがわトロッコ //よしのがわトロッコ
@ -683,12 +699,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "よしのがわトロッコ", trainName: "よしのがわトロッコ",
trainIcon: "https://storage.haruk.in/s185to_ai.png", img: "https://storage.haruk.in/s185to_ai.png",
infoUrl: infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/event_train/yoshino_torokko.html", "https://www.jr-shikoku.co.jp/01_trainbus/event_train/yoshino_torokko.html",
trainNumDistance: null, trainNumDistance: null,
info: "", info: "",
infogram: "" infogram: "",
}; };
//岡山高松アントロ //岡山高松アントロ
@ -700,12 +716,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "アンパンマントロッコ", trainName: "アンパンマントロッコ",
trainIcon: "https://storage.haruk.in/s32to4.png", img: "https://storage.haruk.in/s32to4.png",
infoUrl: infoUrl:
"https://www.jr-eki.com/aptrain/naani/torokko_seto/jikoku.html", "https://www.jr-eki.com/aptrain/naani/torokko_seto/jikoku.html",
trainNumDistance: null, trainNumDistance: null,
info: "", info: "",
infogram: "" infogram: "",
}; };
//伊予灘ものがたり //伊予灘ものがたり
@ -714,22 +730,22 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "伊予灘ものがたり", trainName: "伊予灘ものがたり",
trainIcon: "https://storage.haruk.in/s185iyor.png", img: "https://storage.haruk.in/s185iyor.png",
infoUrl: "https://iyonadamonogatari.com/", infoUrl: "https://iyonadamonogatari.com/",
trainNumDistance: null, trainNumDistance: null,
info: "", info: "",
infogram: "" infogram: "",
}; };
case "8092D": case "8092D":
case "8094D": case "8094D":
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "伊予灘ものがたり", trainName: "伊予灘ものがたり",
trainIcon: "https://storage.haruk.in/s185iyoy.png", img: "https://storage.haruk.in/s185iyoy.png",
infoUrl: "https://iyonadamonogatari.com/", infoUrl: "https://iyonadamonogatari.com/",
trainNumDistance: null, trainNumDistance: null,
info: "", info: "",
infogram: "" infogram: "",
}; };
//千年ものがたり //千年ものがたり
@ -738,11 +754,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "四国まんなか千年ものがたり", trainName: "四国まんなか千年ものがたり",
trainIcon: "https://storage.haruk.in/s185mm1.png", img: "https://storage.haruk.in/s185mm1.png",
infoUrl: "https://www.jr-shikoku.co.jp/sennenmonogatari/", infoUrl: "https://www.jr-shikoku.co.jp/sennenmonogatari/",
trainNumDistance: null, trainNumDistance: null,
info: "", info: "",
infogram: "" infogram: "",
}; };
//夜明けものがたり //夜明けものがたり
@ -753,67 +769,67 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "LTDEXP", type: "LTDEXP",
trainName: "時代の夜明けのものがたり", trainName: "時代の夜明けのものがたり",
trainIcon: "https://storage.haruk.in/s185ym1.png", img: "https://storage.haruk.in/s185ym1.png",
infoUrl: "https://www.jr-shikoku.co.jp/yoakenomonogatari/index.html", infoUrl: "https://www.jr-shikoku.co.jp/yoakenomonogatari/index.html",
trainNumDistance: null, trainNumDistance: null,
info: "", info: "",
infogram: "" infogram: "",
}; };
case "9174M": case "9174M":
return { return {
type: "SPCL_Rapid", type: "SPCL_Rapid",
trainName: "マリンライナー94号", trainName: "マリンライナー94号",
trainIcon: "https://storage.haruk.in/s5001.png", img: "https://storage.haruk.in/s5001.png",
infoUrl: "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/marine.html", infoUrl:
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/marine.html",
trainNumDistance: null, trainNumDistance: null,
info: "臨時列車 4/12,13,19のみ運転", info: "臨時列車 4/12,13,19のみ運転",
infogram: "" infogram: "",
}; };
case "9395D": case "9395D":
return { return {
type: "SPCL_Normal", type: "SPCL_Normal",
trainName: "", trainName: "",
trainIcon: "https://storage.haruk.in/s1500.png", img: "https://storage.haruk.in/s1500.png",
infoUrl: null, infoUrl: null,
trainNumDistance: null, trainNumDistance: null,
info: "臨時列車 4/12,13,19のみ運転", info: "臨時列車 4/12,13,19のみ運転",
infogram: "" infogram: "",
};
case "9662D":
case "9665D":
return {
type: "SPCL_Normal",
trainName: "れんげ号",
img: "",
infoUrl: null,
trainNumDistance: null,
info: "臨時列車 4/29のみ運転",
infogram: "",
};
case "9664D":
case "9663D":
return {
type: "SPCL_Normal",
trainName: "わらぐろ号",
img: "",
infoUrl: null,
trainNumDistance: null,
info: "臨時列車 4/29のみ運転",
infogram: "",
}; };
case "9662D":
case "9665D":
return {
type: "SPCL_Normal",
trainName: "れんげ号",
trainIcon: "",
infoUrl: null,
trainNumDistance: null,
info: "臨時列車 4/29のみ運転",
infogram: ""
};
case "9664D":
case "9663D":
return {
type: "SPCL_Normal",
trainName: "わらぐろ号",
trainIcon: "",
infoUrl: null,
trainNumDistance: null,
info: "臨時列車 4/29のみ運転",
infogram: ""
};
default: default:
if(getJRF(TrainNumber) !== null){ if (getJRF(TrainNumber) !== null) {
return { return {
type: "Freight", type: "Freight",
trainName: getJRF(TrainNumber), trainName: getJRF(TrainNumber),
trainIcon: "https://storage.haruk.in/ef210a.png", img: "https://storage.haruk.in/ef210a.png",
infoUrl: null, infoUrl: null,
trainNumDistance: null, trainNumDistance: null,
info: "", info: "",
infogram: "", infogram: "",
}; };
} } else if (
else if (
new RegExp(/^4[1-9]\d\d[DM]$/).test(TrainNumber) || new RegExp(/^4[1-9]\d\d[DM]$/).test(TrainNumber) ||
new RegExp(/^5[1-7]\d\d[DM]$/).test(TrainNumber) || new RegExp(/^5[1-7]\d\d[DM]$/).test(TrainNumber) ||
new RegExp(/^3[2-9]\d\d[DM]$/).test(TrainNumber) new RegExp(/^3[2-9]\d\d[DM]$/).test(TrainNumber)
@ -821,38 +837,38 @@ export const customTrainDataDetector = (TrainNumber: string) => {
return { return {
type: "OneMan", type: "OneMan",
trainName: "", trainName: "",
trainIcon: null, img: null,
infoUrl: null, infoUrl: null,
trainNumDistance: null, trainNumDistance: null,
info: null, info: null,
infogram: "" infogram: "",
}; };
else if ( else if (
new RegExp(/^[1-9]\d\d[DM]$/).test(TrainNumber) || new RegExp(/^[1-9]\d\d[DM]$/).test(TrainNumber) ||
new RegExp(/^1[26]\d\d[DM]$/).test(TrainNumber) || new RegExp(/^1[26]\d\d[DM]$/).test(TrainNumber) ||
new RegExp(/^58\d\d[DM]$/).test(TrainNumber) || new RegExp(/^58\d\d[DM]$/).test(TrainNumber) ||
new RegExp(/^6\d\d\d[DM]$/).test(TrainNumber) new RegExp(/^6\d\d\d[DM]$/).test(TrainNumber)
){ ) {
return { return {
type: "Normal", type: "Normal",
trainName: "", trainName: "",
trainIcon: null, img: null,
infoUrl: null, infoUrl: null,
trainNumDistance: null, trainNumDistance: null,
info: null, info: null,
infogram: "" infogram: "",
}; };
} else { } else {
return { return {
type: "Other", type: "Other",
trainName: "", trainName: "",
trainIcon: null, img: null,
infoUrl: null, infoUrl: null,
trainNumDistance: null, trainNumDistance: null,
info: null, info: null,
infogram: "" infogram: "",
}; };
} }
} }
}; };
export const getJRF = (num: string) => { export const getJRF = (num: string) => {

View File

@ -4,12 +4,13 @@ import MapView from "react-native-maps";
import { useCurrentTrain } from "../stateBox/useCurrentTrain"; import { useCurrentTrain } from "../stateBox/useCurrentTrain";
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
import lineColorList from "../assets/originData/lineColorList"; import lineColorList from "../assets/originData/lineColorList";
import { lineListPair, stationIDPair } from "../lib/getStationList"; import { lineList_LineWebID, lineListPair, stationIDPair } from "../lib/getStationList";
import { SheetManager } from "react-native-actions-sheet"; import { SheetManager } from "react-native-actions-sheet";
import { useTrainMenu } from "../stateBox/useTrainMenu"; import { useTrainMenu } from "../stateBox/useTrainMenu";
import { MapPin } from "./TrainMenu/MapPin"; import { MapPin } from "./TrainMenu/MapPin";
import { UsefulBox } from "./TrainMenu/UsefulBox"; import { UsefulBox } from "./TrainMenu/UsefulBox";
import { MapsButton } from "./TrainMenu/MapsButton"; import { MapsButton } from "./TrainMenu/MapsButton";
import { useStationList } from "@/stateBox/useStationList";
export default function TrainMenu({ style }) { export default function TrainMenu({ style }) {
const { webview } = useCurrentTrain(); const { webview } = useCurrentTrain();
const mapRef = useRef(); const mapRef = useRef();
@ -20,22 +21,19 @@ export default function TrainMenu({ style }) {
setSelectedLine, setSelectedLine,
mapsStationData: stationData, mapsStationData: stationData,
} = useTrainMenu(); } = useTrainMenu();
const { originalStationList } = useStationList();
useEffect(() => { useEffect(() => {
const stationPinData = []; const stationPinData = [];
Object.keys(stationData).forEach((d, indexBase) => { Object.keys(originalStationList).forEach((d, indexBase) => {
stationData[d].forEach((D, index) => { originalStationList[d].forEach((D, index) => {
if (!D.StationMap) return null; if (selectedLine && selectedLine != lineList_LineWebID[d]) return;
if (selectedLine && selectedLine != d) return; const latlng = [D.lat,D.lng];
const latlng = D.StationMap.replace(
"https://www.google.co.jp/maps/place/",
""
).split(",");
if (latlng.length == 0) return null; if (latlng.length == 0) return null;
stationPinData.push({ D, d, latlng, indexBase: 0, index }); stationPinData.push({ D, d, latlng, indexBase: 0, index });
}); });
}); });
setStationPin(stationPinData); setStationPin(stationPinData);
}, [stationData, selectedLine]); }, [originalStationList, selectedLine]);
useLayoutEffect(() => { useLayoutEffect(() => {
mapRef.current.fitToCoordinates( mapRef.current.fitToCoordinates(
stationPin.map(({ latlng }) => ({ stationPin.map(({ latlng }) => ({

View File

@ -18,6 +18,7 @@ import { TrainPositionDataDelete } from "./LED_inside_Component/TrainPositionDat
import { useStationList } from "../../stateBox/useStationList"; import { useStationList } from "../../stateBox/useStationList";
import useInterval from "@/lib/useInterval"; import useInterval from "@/lib/useInterval";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
type Props = { type Props = {
d: { d: {
@ -45,6 +46,7 @@ export const EachData: FC<Props> = (props) => {
} = props; } = props;
const { currentTrain } = useCurrentTrain(); const { currentTrain } = useCurrentTrain();
const { stationList } = useStationList(); const { stationList } = useStationList();
const { allCustonTrainData } = useAllTrainDiagram();
const openTrainInfo = (d: { const openTrainInfo = (d: {
train: string; train: string;
lastStation: string; lastStation: string;
@ -74,7 +76,10 @@ export const EachData: FC<Props> = (props) => {
}; };
const getTrainDataFromCurrentTrain = (trainNum: string) => { const getTrainDataFromCurrentTrain = (trainNum: string) => {
const customTrainData = customTrainDataDetector(d.train); const customTrainData = customTrainDataDetector(
d.train,
allCustonTrainData
);
switch (customTrainData.type) { switch (customTrainData.type) {
case "Normal": case "Normal":
case "OneMan": case "OneMan":
@ -122,21 +127,22 @@ export const EachData: FC<Props> = (props) => {
const [isShow, setIsShow] = useState(true); const [isShow, setIsShow] = useState(true);
const [isDepartureNow, setIsDepartureNow] = useState(false); const [isDepartureNow, setIsDepartureNow] = useState(false);
useEffect(()=>{ useEffect(() => {
const currentTime = dayjs(); const currentTime = dayjs();
const trainTime = currentTime.set("hour", parseInt(d.time.split(":")[0])).set("minute", parseInt(d.time.split(":")[1])); const trainTime = currentTime
.set("hour", parseInt(d.time.split(":")[0]))
.set("minute", parseInt(d.time.split(":")[1]));
const diff = trainTime.diff(currentTime, "minute"); const diff = trainTime.diff(currentTime, "minute");
if (diff < 2) setIsDepartureNow(true); if (diff < 2) setIsDepartureNow(true);
else setIsDepartureNow(false); else setIsDepartureNow(false);
return()=>{ return () => {
setIsDepartureNow(false); setIsDepartureNow(false);
setIsShow(true); setIsShow(true);
} };
}, [d.time,currentTrainData]); }, [d.time, currentTrainData]);
useInterval(()=>{ useInterval(() => {
if (isDepartureNow) { if (isDepartureNow) {
setIsShow(!isShow); setIsShow(!isShow);
} }
}, 800); }, 800);
return ( return (
@ -172,7 +178,7 @@ export const EachData: FC<Props> = (props) => {
opacity: isShow ? 1 : 0.5, opacity: isShow ? 1 : 0.5,
}} }}
onPress={() => openTrainInfo(d)} onPress={() => openTrainInfo(d)}
key={ d.train + "-eachData" } key={d.train + "-eachData"}
> >
<TrainName <TrainName
trainName={train.trainName} trainName={train.trainName}
@ -186,7 +192,14 @@ export const EachData: FC<Props> = (props) => {
<StatusAndDelay trainDelayStatus={trainDelayStatus} /> <StatusAndDelay trainDelayStatus={trainDelayStatus} />
</TouchableOpacity> </TouchableOpacity>
{!!isDepartureNow && ( {!!isDepartureNow && (
<Description info={d.lastStation == "当駅止" ? "この列車は当駅止です。間もなく到着します。":"列車の出発時刻です。"} key={d.train + "-description"} /> <Description
info={
d.lastStation == "当駅止"
? "この列車は当駅止です。間もなく到着します。"
: "列車の出発時刻です。"
}
key={d.train + "-description"}
/>
)} )}
{trainDescriptionSwitch && ( {trainDescriptionSwitch && (
<TrainPosition <TrainPosition

View File

@ -40,6 +40,17 @@ export const lineListPair = {
N: "鳴門線(池谷-鳴門間)[N]", N: "鳴門線(池谷-鳴門間)[N]",
M: "瀬戸大橋線(児島-宇多津間)[M]", M: "瀬戸大橋線(児島-宇多津間)[M]",
}; };
export const lineList_LineWebID = {
"予讃線(高松-松山間)[Y]" : "yosan",
"予讃線(松山-宇和島間)[U]" : "uwajima",
"予讃線/愛ある伊予灘線(向井原-伊予大洲間)[S]" : "uwajima2",
"土讃線(多度津-高知間)[D]" : "dosan",
"土讃線(高知-窪川間)[K]" : "dosan2",
"高徳線(高松-徳島間)[T]" : "koutoku",
"徳島線(徳島-阿波池田間)[B]" : "tokushima",
"鳴門線(池谷-鳴門間)[N]" : "naruto",
"瀬戸大橋線(児島-宇多津間)[M]" : "seto",
};
export const getStationList2 = async () => { export const getStationList2 = async () => {
return { return {
yosan, yosan,
@ -167,6 +178,11 @@ export const getStationList = async () => {
, ,
stationList["日英対応表"] stationList["日英対応表"]
); );
stationList["予讃線(松山-宇和島間)[U]"] = addStationPosition(
concatBetweenStations(stationList["予讃線(松山-宇和島間)[U]"]),
,
stationList["日英対応表"]
);
stationList["予讃線/愛ある伊予灘線(向井原-伊予大洲間)[S]"] = stationList["予讃線/愛ある伊予灘線(向井原-伊予大洲間)[S]"] =
addStationPosition( addStationPosition(
concatBetweenStations( concatBetweenStations(

View File

@ -1266,6 +1266,9 @@ export const injectJavascriptData: InjectJavascriptData = (
isWanman = data.isWanman; isWanman = data.isWanman;
if(data.trainName != ""){ if(data.trainName != ""){
trainName = data.trainName; trainName = data.trainName;
if(data.trainNumDistance != null){
trainName += parseInt(.replace("M", "").replace("D", "")) - data.trainNumDistance+"号";
}
} }
if(data.viaData != ""){ if(data.viaData != ""){
viaData = data.viaData; viaData = data.viaData;

View File

@ -4,6 +4,7 @@ import React, { createContext, useContext, useEffect, useState } from "react";
const initialState = { const initialState = {
allTrainDiagram: undefined, allTrainDiagram: undefined,
setAllTrainDiagram: () => {}, setAllTrainDiagram: () => {},
allCustonTrainData: [],
}; };
const AllTrainDiagramContext = createContext(initialState); const AllTrainDiagramContext = createContext(initialState);
@ -12,6 +13,7 @@ export const useAllTrainDiagram = () => useContext(AllTrainDiagramContext);
export const AllTrainDiagramProvider = ({ children }) => { export const AllTrainDiagramProvider = ({ children }) => {
const [allTrainDiagram, setAllTrainDiagram] = useState(trainList); const [allTrainDiagram, setAllTrainDiagram] = useState(trainList);
const [allCustonTrainData, setAllCustonTrainData] = useState([]); // カスタム列車データ
const [keyList, setKeyList] = useState(); // 第二要素 const [keyList, setKeyList] = useState(); // 第二要素
useEffect( useEffect(
() => allTrainDiagram && setKeyList(Object.keys(allTrainDiagram)), () => allTrainDiagram && setKeyList(Object.keys(allTrainDiagram)),
@ -41,10 +43,26 @@ export const AllTrainDiagramProvider = ({ children }) => {
}); });
}); });
}, []); }, []);
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 ( return (
<AllTrainDiagramContext.Provider <AllTrainDiagramContext.Provider
value={{ allTrainDiagram, setAllTrainDiagram, keyList }} value={{
allTrainDiagram,
setAllTrainDiagram,
allCustonTrainData,
keyList,
}}
> >
{children} {children}
</AllTrainDiagramContext.Provider> </AllTrainDiagramContext.Provider>

View File

@ -5,7 +5,11 @@ import React, {
useEffect, useEffect,
FC, FC,
} from "react"; } from "react";
import { lineList, getStationList } from "../lib/getStationList"; import {
lineList,
getStationList,
lineList_LineWebID,
} from "../lib/getStationList";
type initialStateType = { type initialStateType = {
originalStationList: any[][]; originalStationList: any[][];
@ -13,6 +17,7 @@ type initialStateType = {
getStationDataFromName: (id: string) => any[]; getStationDataFromName: (id: string) => any[];
getStationDataFromId: (id: string) => any[]; getStationDataFromId: (id: string) => any[];
stationList: any[]; stationList: any[];
getInjectJavascriptAddress: (StationNumber: string) => string;
}; };
const initialState = { const initialState = {
originalStationList: [[]], originalStationList: [[]],
@ -20,6 +25,7 @@ const initialState = {
getStationDataFromName: () => [], getStationDataFromName: () => [],
getStationDataFromId: () => [], getStationDataFromId: () => [],
stationList: [], stationList: [],
getInjectJavascriptAddress: (StationNumber: string) => "",
}; };
const StationListContext = createContext<initialStateType>(initialState); const StationListContext = createContext<initialStateType>(initialState);
@ -40,7 +46,10 @@ export const StationListProvider: FC<Props> = ({ children }) => {
Object.keys(originalStationList).forEach((key) => { Object.keys(originalStationList).forEach((key) => {
originalStationList[key].forEach((station) => { originalStationList[key].forEach((station) => {
if (station.StationNumber === id) { if (station.StationNumber === id) {
returnArray = [...returnArray, ...getStationDataFromName(station.Station_JP)]; returnArray = [
...returnArray,
...getStationDataFromName(station.Station_JP),
];
} }
}); });
}); });
@ -58,21 +67,56 @@ export const StationListProvider: FC<Props> = ({ children }) => {
return returnArray; return returnArray;
}; };
const [stationList, setStationList] = useState<any[][]>([[]]); const [stationList, setStationList] = useState<any[][]>([[]]);
useEffect(()=>{ useEffect(() => {
if(originalStationList.length === 0) return; if (originalStationList.length === 0) return;
const stationList = const stationList = lineList.map((d) =>
lineList.map((d) => originalStationList[d].map((a) => ({
originalStationList[d].map((a) => ({ StationNumber: a.StationNumber,
StationNumber: a.StationNumber, StationName: a.Station_JP,
StationName: a.Station_JP, }))
})) );
); setStationList(stationList);
setStationList(stationList); }, [originalStationList]);
},[originalStationList])
const getInjectJavascriptAddress = (StationNumber: string) => {
const bootStationList = [];
Object.keys(originalStationList).forEach((d) => {
let findNearStations = false;
originalStationList[d].forEach((x) => {
let lineName = lineList_LineWebID[d];
if (findNearStations) {
if (x.MyStation) {
bootStationList.push({ line: lineName, station: x });
findNearStations = false;
}
return;
}
if (x.StationNumber == StationNumber) {
console.log(originalStationList[d]);
if (!x.MyStation) findNearStations = true;
else bootStationList.push({ line: lineName, station: x });
}
});
if (StationNumber == "M12") {
bootStationList.push({
line: "seto",
station: { Station_JP: "児島", MyStation: "0" },
});
}
});
return `MoveDisplayStation('${bootStationList[0].line}_${bootStationList[0].station.MyStation}_${bootStationList[0].station.Station_JP}');document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`;
};
return ( return (
<StationListContext.Provider <StationListContext.Provider
value={{ originalStationList, setOriginalStationList, getStationDataFromName, getStationDataFromId, stationList }} value={{
originalStationList,
setOriginalStationList,
getStationDataFromName,
getStationDataFromId,
stationList,
getInjectJavascriptAddress,
}}
> >
{children} {children}
</StationListContext.Provider> </StationListContext.Provider>