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

View File

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

View File

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

View File

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

View File

@ -21,7 +21,7 @@ import { BigButton } from "./atom/BigButton";
import { Switch } from "react-native-elements";
export default function AllTrainDiagramView() {
const { goBack, navigate } = useNavigation();
const { keyList, allTrainDiagram } = useAllTrainDiagram();
const { keyList, allTrainDiagram, allCustonTrainData } = useAllTrainDiagram();
const [input, setInput] = useState(""); // 文字入力
const [keyBoardVisible, setKeyBoardVisible] = useState(false);
const [useStationName, setUseStationName] = useState(false);
@ -53,7 +53,7 @@ export default function AllTrainDiagramView() {
}, []);
const openTrainInfo = (d) => {
const train = customTrainDataDetector(d);
const train = customTrainDataDetector(d, allCustonTrainData);
let TrainNumber = "";
if (train.trainNumDistance != undefined) {
const timeInfo =
@ -74,6 +74,7 @@ export default function AllTrainDiagramView() {
return (
<View style={{ backgroundColor: "#0099CC", height: "100%" }}>
<FlatList
contentContainerStyle={{ justifyContent: "flex-end", flexGrow: 1 }}
style={{ flex: 1 }}
data={keyList?.filter((d) => {
if (useStationName) {
@ -93,6 +94,14 @@ export default function AllTrainDiagramView() {
return d.includes(input);
})}
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}
//initialNumToRender={100}
/>

View File

@ -2,7 +2,13 @@ import React from "react";
import { Platform, LayoutAnimation } from "react-native";
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 { useFavoriteStation } from "../../stateBox/useFavoriteStation";
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
@ -17,7 +23,7 @@ export const AppsWebView = ({ openStationACFromEachTrainInfo }) => {
const { navigate } = useNavigation();
const { favoriteStation } = useFavoriteStation();
const { isLandscape } = useDeviceOrientationChange();
const { originalStationList, stationList } = useStationList();
const { originalStationList, stationList, getInjectJavascriptAddress } = useStationList();
const {
setSelectedLine,
mapsStationData: stationData,
@ -129,20 +135,11 @@ export const AppsWebView = ({ openStationACFromEachTrainInfo }) => {
const onLoadEnd = () => {
if (once) return () => {};
if (!stationData) return () => {};
if (!originalStationList) return () => {};
if (favoriteStation.length < 1) return () => {};
const getStationLine = (now) => {
const returnData = Object.keys(stationData).filter((d) => {
const cache = stationData[d].findIndex(
(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}')`
);
const string = getInjectJavascriptAddress(favoriteStation[0][0].StationNumber);
if (!string) return () => {};
webview.current?.injectJavaScript(string);
once = true;
};

View File

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

View File

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

View File

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

View File

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

View File

@ -40,6 +40,17 @@ export const lineListPair = {
N: "鳴門線(池谷-鳴門間)[N]",
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 () => {
return {
yosan,
@ -167,6 +178,11 @@ export const getStationList = async () => {
,
stationList["日英対応表"]
);
stationList["予讃線(松山-宇和島間)[U]"] = addStationPosition(
concatBetweenStations(stationList["予讃線(松山-宇和島間)[U]"]),
,
stationList["日英対応表"]
);
stationList["予讃線/愛ある伊予灘線(向井原-伊予大洲間)[S]"] =
addStationPosition(
concatBetweenStations(

View File

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

View File

@ -4,6 +4,7 @@ import React, { createContext, useContext, useEffect, useState } from "react";
const initialState = {
allTrainDiagram: undefined,
setAllTrainDiagram: () => {},
allCustonTrainData: [],
};
const AllTrainDiagramContext = createContext(initialState);
@ -12,6 +13,7 @@ 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)),
@ -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 (
<AllTrainDiagramContext.Provider
value={{ allTrainDiagram, setAllTrainDiagram, keyList }}
value={{
allTrainDiagram,
setAllTrainDiagram,
allCustonTrainData,
keyList,
}}
>
{children}
</AllTrainDiagramContext.Provider>

View File

@ -5,7 +5,11 @@ import React, {
useEffect,
FC,
} from "react";
import { lineList, getStationList } from "../lib/getStationList";
import {
lineList,
getStationList,
lineList_LineWebID,
} from "../lib/getStationList";
type initialStateType = {
originalStationList: any[][];
@ -13,6 +17,7 @@ type initialStateType = {
getStationDataFromName: (id: string) => any[];
getStationDataFromId: (id: string) => any[];
stationList: any[];
getInjectJavascriptAddress: (StationNumber: string) => string;
};
const initialState = {
originalStationList: [[]],
@ -20,6 +25,7 @@ const initialState = {
getStationDataFromName: () => [],
getStationDataFromId: () => [],
stationList: [],
getInjectJavascriptAddress: (StationNumber: string) => "",
};
const StationListContext = createContext<initialStateType>(initialState);
@ -40,7 +46,10 @@ export const StationListProvider: FC<Props> = ({ children }) => {
Object.keys(originalStationList).forEach((key) => {
originalStationList[key].forEach((station) => {
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;
};
const [stationList, setStationList] = useState<any[][]>([[]]);
useEffect(()=>{
if(originalStationList.length === 0) return;
const stationList =
lineList.map((d) =>
originalStationList[d].map((a) => ({
StationNumber: a.StationNumber,
StationName: a.Station_JP,
}))
);
setStationList(stationList);
},[originalStationList])
useEffect(() => {
if (originalStationList.length === 0) return;
const stationList = lineList.map((d) =>
originalStationList[d].map((a) => ({
StationNumber: a.StationNumber,
StationName: a.Station_JP,
}))
);
setStationList(stationList);
}, [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 (
<StationListContext.Provider
value={{ originalStationList, setOriginalStationList, getStationDataFromName, getStationDataFromId, stationList }}
value={{
originalStationList,
setOriginalStationList,
getStationDataFromName,
getStationDataFromId,
stationList,
getInjectJavascriptAddress,
}}
>
{children}
</StationListContext.Provider>