278 lines
8.8 KiB
TypeScript
278 lines
8.8 KiB
TypeScript
import React, {
|
||
createContext,
|
||
useContext,
|
||
useState,
|
||
useEffect,
|
||
useRef,
|
||
FC,
|
||
} from "react";
|
||
import { HeaderConfig } from "@/lib/HeaderConfig";
|
||
|
||
import useInterval from "@/lib/useInterval";
|
||
import { useStationList } from "@/stateBox/useStationList";
|
||
import { checkDuplicateTrainData } from "@/lib/checkDuplicateTrainData";
|
||
import { getStationID } from "@/lib/eachTrainInfoCoreLib/getStationData";
|
||
import { trainDataType } from "@/lib/trainPositionTextArray";
|
||
type loading = "loading" | "success" | "error";
|
||
const initialState = {
|
||
webview: undefined,
|
||
currentTrain: [],
|
||
setCurrentTrain: (e) => {},
|
||
currentTrainLoading: "loading" as loading,
|
||
setCurrentTrainLoading: (e) => {},
|
||
getCurrentTrain: () => {},
|
||
inject: (i) => {},
|
||
fixedPosition: null,
|
||
setFixedPosition: (e) => {},
|
||
setInjectData: (e) => {},
|
||
getCurrentStationData: ((e) => {}) as (e: string) => trainDataType | undefined,
|
||
getPosition: ((e) => {}) as (e: trainDataType) => string[] | undefined,
|
||
};
|
||
|
||
type initialStateType = {
|
||
webview: React.MutableRefObject<any>;
|
||
currentTrain: trainDataType[];
|
||
setCurrentTrain: (e: trainDataType[]) => void;
|
||
currentTrainLoading: loading;
|
||
setCurrentTrainLoading: (e: loading) => void;
|
||
getCurrentTrain: () => void;
|
||
inject: (i: string) => void;
|
||
fixedPosition: { type: "station" | "train"; value: string } | null;
|
||
setFixedPosition: (e: { type: "station" | "train"; value: string } | null) => void;
|
||
setInjectData: (e: { type: "station" | "train"; value: string; fixed: boolean }) => void;
|
||
getCurrentStationData: (e: string) => trainDataType | undefined;
|
||
getPosition: (e: trainDataType) => string[] | undefined;
|
||
};
|
||
|
||
const CurrentTrainContext = createContext<initialStateType>(initialState);
|
||
|
||
export const useCurrentTrain = () => {
|
||
return useContext(CurrentTrainContext);
|
||
};
|
||
type props = {
|
||
children: React.ReactNode;
|
||
}
|
||
export const CurrentTrainProvider:FC<props> = ({ children }) => {
|
||
const [currentTrain, setCurrentTrain] = useState<trainDataType[]>([]); //現在在線中の全列車 { num: 列車番号, delay: 遅延時分(状態), Pos: 位置情報 }
|
||
const [currentTrainLoading, setCurrentTrainLoading] =
|
||
useState<loading>("loading");
|
||
|
||
const { getInjectJavascriptAddress, stationList, originalStationList } =
|
||
useStationList();
|
||
|
||
const [fixedPosition, setFixedPosition] = useState<{
|
||
type: "station" | "train";
|
||
value: string;
|
||
}>({
|
||
type: null,
|
||
value: null,
|
||
});
|
||
const [_, setIntervalState] = useInterval(
|
||
() => {
|
||
if (!webview.current) return;
|
||
if (fixedPosition.type == "station") {
|
||
const script = getInjectJavascriptAddress(fixedPosition.value);
|
||
inject(script);
|
||
} else if (fixedPosition.type == "train") {
|
||
const currentTrain = getCurrentStationData(fixedPosition.value);
|
||
const values = getPosition(currentTrain);
|
||
if (!values) return;
|
||
if (values[0] == "M12" || values[1] == "M12") {
|
||
const script = getInjectJavascriptAddress("M12");
|
||
inject(script);
|
||
return;
|
||
}
|
||
|
||
const script = getInjectJavascriptAddress(
|
||
values[values.length == 2 ? currentTrain.Direction : 0]
|
||
);
|
||
inject(script);
|
||
}
|
||
else{
|
||
inject(`setReload()`);
|
||
}
|
||
},
|
||
10000, //60000,
|
||
true
|
||
);
|
||
// useEffect(() => {
|
||
// if (fixedPosition) {
|
||
// setIntervalState.start();
|
||
// } else {
|
||
// setIntervalState.stop();
|
||
// }
|
||
// }, [fixedPosition]);
|
||
|
||
type getPositionFuncType = (currentTrainData: trainDataType) => string[] | undefined;
|
||
const getPosition: getPositionFuncType = (currentTrainData) => {
|
||
//currentTrainData.Pos = "鴨川~端岡"; //test
|
||
if (!currentTrainData) return;
|
||
if (!currentTrainData?.Pos) return;
|
||
if (currentTrainData?.Pos.match("~")) {
|
||
const pos = currentTrainData?.Pos.replace("(下り)", "")
|
||
.replace("(上り)", "")
|
||
.replace("(徳島線)", "")
|
||
.replace("(高徳線)", "")
|
||
.split("~");
|
||
const direction = currentTrainData?.Direction || 0;
|
||
if (pos[0] == "児島" && pos[1] == "宇多津") {
|
||
return ["M12", "Y09"];
|
||
} else if (pos[1] == "児島" && pos[0] == "宇多津") {
|
||
return ["Y09", "M12"];
|
||
} else if (pos[0] == "伊予若宮" && pos[1] == "伊予白滝") {
|
||
return ["S18", "S14"];
|
||
} else if (pos[0] == "伊予白滝" && pos[1] == "伊予若宮") {
|
||
return ["S14", "S18"];
|
||
} else if (pos[0] == "伊予大洲" && pos[1] == "伊予若宮") {
|
||
return ["U14", "U14"];
|
||
} else if (pos[0] == "伊予若宮" && pos[1] == "伊予大洲") {
|
||
return ["U14", "U14"];
|
||
}
|
||
const currentPosID = Object.keys(originalStationList).map((key) => {
|
||
let firstStation = false;
|
||
let firstStationID = "";
|
||
let secondStation = false;
|
||
let secondStationID = "";
|
||
originalStationList[key].forEach((station) => {
|
||
if (station.Station_JP === pos[0]) {
|
||
firstStation = true;
|
||
firstStationID = station.StationNumber;
|
||
}
|
||
if (station.Station_JP === pos[1]) {
|
||
secondStation = true;
|
||
secondStationID = station.StationNumber;
|
||
}
|
||
});
|
||
if (firstStation && secondStation) {
|
||
return [firstStationID, secondStationID];
|
||
} else return false;
|
||
});
|
||
const currentPos = currentPosID.filter((d) => d != false)[0];
|
||
if (currentPos) {
|
||
return direction == 0 ? currentPos.reverse() : currentPos;
|
||
} else if (direction == 0) {
|
||
return [
|
||
getStationID(pos[1], stationList),
|
||
getStationID(pos[0], stationList),
|
||
];
|
||
} else {
|
||
return [
|
||
getStationID(pos[0], stationList),
|
||
getStationID(pos[1], stationList),
|
||
];
|
||
}
|
||
} else {
|
||
return [getStationID(currentTrainData?.Pos, stationList)];
|
||
}
|
||
};
|
||
const getCurrentStationData: (e: string) => trainDataType | undefined = (
|
||
e
|
||
) => {
|
||
//e:trainNumber
|
||
if (!currentTrain.length) return;
|
||
return checkDuplicateTrainData(
|
||
currentTrain.filter((d) => d.num == e),
|
||
stationList
|
||
);
|
||
};
|
||
|
||
type injectDataType = {
|
||
type: "station" | "train";
|
||
value: string;
|
||
fixed: boolean;
|
||
};
|
||
type injectDataFuncType = (data: injectDataType) => void;
|
||
const setInjectData: injectDataFuncType = ({ type, value, fixed }) => {
|
||
if (type === "station") {
|
||
const script = getInjectJavascriptAddress(value);
|
||
inject(script);
|
||
} else if (type === "train") {
|
||
const currentTrain = getCurrentStationData(value);
|
||
const values = getPosition(currentTrain);
|
||
if (!values) return;
|
||
let script;
|
||
if (values[0] == "M12" || values[1] == "M12") {
|
||
script = getInjectJavascriptAddress("M12");
|
||
} else {
|
||
const valuesIndex = values.length == 2 ? currentTrain.Direction : 0;
|
||
script = getInjectJavascriptAddress(values[valuesIndex]);
|
||
}
|
||
inject(script);
|
||
}
|
||
if (fixed) {
|
||
setFixedPosition({ type, value });
|
||
}
|
||
};
|
||
const getCurrentTrain = () => {
|
||
fetch("https://n8n.haruk.in/webhook/c501550c-7d1b-4e50-927b-4429fe18931a")
|
||
.then((response) => response.json())
|
||
.then((d) => d.data)
|
||
.then((d) =>
|
||
d.map((x) => ({
|
||
Index: x.Index,
|
||
num: x.TrainNum,
|
||
delay: x.delay,
|
||
Pos: x.Pos,
|
||
PosNum: x.PosNum,
|
||
Direction: x.Direction,
|
||
Type: x.Type,
|
||
Line: x.Line,
|
||
}))
|
||
)
|
||
.then((d) => {
|
||
setCurrentTrain(d);
|
||
setCurrentTrainLoading("success");
|
||
})
|
||
.catch(() => {
|
||
//alert("現在の全在線列車取得エラー/再取得します");
|
||
fetch(
|
||
"https://script.google.com/macros/s/AKfycby9Y2-Bm75J_WkbZimi7iS8v5r9wMa9wtzpdwES9sOGF4i6HIYEJOM60W6gM1gXzt1o/exec",
|
||
HeaderConfig
|
||
)
|
||
.then((response) => response.json())
|
||
.then((d) =>
|
||
d.map((x) => ({ num: x.TrainNum, delay: x.delay, Pos: x.Pos }))
|
||
)
|
||
.then((d) => {
|
||
setCurrentTrain(d);
|
||
setCurrentTrainLoading("success");
|
||
})
|
||
.catch(() => {
|
||
// エラー時の処理
|
||
setCurrentTrainLoading("error");
|
||
});
|
||
});
|
||
};
|
||
const inject = (i) => {
|
||
webview.current?.injectJavaScript(i);
|
||
};
|
||
|
||
useEffect(() => {
|
||
getCurrentTrain();
|
||
}, []); //初回だけ現在の全在線列車取得
|
||
|
||
useInterval(getCurrentTrain, 15000); //15秒毎に全在線列車取得
|
||
|
||
const webview = useRef();
|
||
return (
|
||
<CurrentTrainContext.Provider
|
||
value={{
|
||
webview,
|
||
currentTrain,
|
||
setCurrentTrain,
|
||
currentTrainLoading,
|
||
setCurrentTrainLoading,
|
||
getCurrentTrain,
|
||
inject,
|
||
setInjectData,
|
||
getCurrentStationData,
|
||
getPosition,
|
||
fixedPosition,
|
||
setFixedPosition,
|
||
}}
|
||
>
|
||
{children}
|
||
</CurrentTrainContext.Provider>
|
||
);
|
||
};
|