Merge commit '58d3eae1d7797a74febc752f4185337a6eb95dad'
This commit is contained in:
commit
1fc5220405
2
App.js
2
App.js
@ -17,6 +17,7 @@ import { DeviceOrientationChangeProvider } from "./stateBox/useDeviceOrientation
|
|||||||
import { TrainMenuProvider } from "./stateBox/useTrainMenu";
|
import { TrainMenuProvider } from "./stateBox/useTrainMenu";
|
||||||
import { buildProvidersTree } from "./lib/providerTreeProvider";
|
import { buildProvidersTree } from "./lib/providerTreeProvider";
|
||||||
import { StationListProvider } from "./stateBox/useStationList";
|
import { StationListProvider } from "./stateBox/useStationList";
|
||||||
|
import { NotificationProvider } from "./stateBox/useNotifications";
|
||||||
|
|
||||||
LogBox.ignoreLogs([
|
LogBox.ignoreLogs([
|
||||||
"ViewPropTypes will be removed",
|
"ViewPropTypes will be removed",
|
||||||
@ -33,6 +34,7 @@ export default function App() {
|
|||||||
useEffect(() => UpdateAsync(), []);
|
useEffect(() => UpdateAsync(), []);
|
||||||
|
|
||||||
const ProviderTree = buildProvidersTree([
|
const ProviderTree = buildProvidersTree([
|
||||||
|
NotificationProvider,
|
||||||
StationListProvider,
|
StationListProvider,
|
||||||
FavoriteStationProvider,
|
FavoriteStationProvider,
|
||||||
TrainDelayDataProvider,
|
TrainDelayDataProvider,
|
||||||
|
7
Apps.js
7
Apps.js
@ -2,6 +2,7 @@ import React from "react";
|
|||||||
import { NavigationContainer } from "@react-navigation/native";
|
import { NavigationContainer } from "@react-navigation/native";
|
||||||
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
|
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
|
||||||
import { Platform } from "react-native";
|
import { Platform } from "react-native";
|
||||||
|
import { useFonts } from "expo-font";
|
||||||
import TNDView from "./ndView";
|
import TNDView from "./ndView";
|
||||||
import { initIcon } from "./lib/initIcon";
|
import { initIcon } from "./lib/initIcon";
|
||||||
import { Top } from "./Top";
|
import { Top } from "./Top";
|
||||||
@ -24,11 +25,15 @@ export function AppContainer() {
|
|||||||
tabBarBadgeStyle: style,
|
tabBarBadgeStyle: style,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const [fontLoaded, error] = useFonts({
|
||||||
|
"JR-Nishi": require("./assets/fonts/jr-nishi.otf"),
|
||||||
|
"Zou": require("./assets/fonts/DelaGothicOne-Regular.ttf"),
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<NavigationContainer name="Root" style={{ flex: 1 }} ref={navigationRef}>
|
<NavigationContainer name="Root" style={{ flex: 1 }} ref={navigationRef}>
|
||||||
<Tab.Navigator
|
<Tab.Navigator
|
||||||
tabBarOptions={{ keyboardHidesTabBar: Platform.OS === "android" }}
|
tabBarOptions={{ keyboardHidesTabBar: Platform.OS === "android" }}
|
||||||
initialRouteName="login"
|
initialRouteName="menuPage"
|
||||||
lazy={false}
|
lazy={false}
|
||||||
>
|
>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
|
16
MenuPage.js
16
MenuPage.js
@ -21,6 +21,16 @@ export function MenuPage() {
|
|||||||
const { getCurrentTrain } = useCurrentTrain();
|
const { getCurrentTrain } = useCurrentTrain();
|
||||||
const navigation = useNavigation();
|
const navigation = useNavigation();
|
||||||
const { addListener } = navigation;
|
const { addListener } = navigation;
|
||||||
|
useEffect(() => {
|
||||||
|
AS.getItem("startPage")
|
||||||
|
.then((res) => {
|
||||||
|
if (res == "true") navigation.navigate("login");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
//6.0以降false
|
||||||
|
AS.setItem("startPage", "true");
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unsubscribe = addListener("tabPress", (e) => {
|
const unsubscribe = addListener("tabPress", (e) => {
|
||||||
AS.getItem("favoriteStation")
|
AS.getItem("favoriteStation")
|
||||||
@ -70,11 +80,7 @@ export function MenuPage() {
|
|||||||
options={{ ...optionData, gestureEnabled: false }}
|
options={{ ...optionData, gestureEnabled: false }}
|
||||||
component={AllTrainDiagramView}
|
component={AllTrainDiagramView}
|
||||||
/>
|
/>
|
||||||
<Stack.Screen
|
<Stack.Screen name="howto" options={optionData} component={HowTo} />
|
||||||
name="howto"
|
|
||||||
options={optionData}
|
|
||||||
component={HowTo}
|
|
||||||
/>
|
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
2
app.json
2
app.json
@ -50,7 +50,7 @@
|
|||||||
},
|
},
|
||||||
"assetBundlePatterns": ["**/*"],
|
"assetBundlePatterns": ["**/*"],
|
||||||
"ios": {
|
"ios": {
|
||||||
"buildNumber": "38",
|
"buildNumber": "39",
|
||||||
"supportsTablet": false,
|
"supportsTablet": false,
|
||||||
"bundleIdentifier": "jrshikokuinfo.xprocess.hrkn",
|
"bundleIdentifier": "jrshikokuinfo.xprocess.hrkn",
|
||||||
"config": {
|
"config": {
|
||||||
|
BIN
assets/configuration/showSetting0.jpg
Normal file
BIN
assets/configuration/showSetting0.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 146 KiB |
BIN
assets/configuration/showSetting1.jpg
Normal file
BIN
assets/configuration/showSetting1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
BIN
assets/fonts/DelaGothicOne-Regular.ttf
Normal file
BIN
assets/fonts/DelaGothicOne-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/jr-nishi.otf
Normal file
BIN
assets/fonts/jr-nishi.otf
Normal file
Binary file not shown.
@ -46,7 +46,10 @@ export const EachStopList = ({
|
|||||||
.set("minute", parseInt(time.split(":")[1]))
|
.set("minute", parseInt(time.split(":")[1]))
|
||||||
.add(isNaN(currentTrainData?.delay) ? 0 : currentTrainData.delay, "minute");
|
.add(isNaN(currentTrainData?.delay) ? 0 : currentTrainData.delay, "minute");
|
||||||
const timeString = se == "通過" ? "" : dates.format("HH:mm").split(":");
|
const timeString = se == "通過" ? "" : dates.format("HH:mm").split(":");
|
||||||
|
const onClickStateText = (string) => {
|
||||||
|
if (string != "通過") return;
|
||||||
|
alert("この駅は通過駅です");
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<TouchableWithoutFeedback
|
<TouchableWithoutFeedback
|
||||||
onPress={() =>
|
onPress={() =>
|
||||||
@ -140,6 +143,7 @@ export const EachStopList = ({
|
|||||||
: "red",
|
: "red",
|
||||||
width: 60,
|
width: 60,
|
||||||
}}
|
}}
|
||||||
|
onPress={() => onClickStateText(se)}
|
||||||
>
|
>
|
||||||
{se == "通過" ? "レ" : `${timeString[0]}:${timeString[1]}`}
|
{se == "通過" ? "レ" : `${timeString[0]}:${timeString[1]}`}
|
||||||
</Text>
|
</Text>
|
||||||
|
@ -6,30 +6,46 @@ type stateBox = {
|
|||||||
title: string;
|
title: string;
|
||||||
style?: ViewStyle;
|
style?: ViewStyle;
|
||||||
mode?: number;
|
mode?: number;
|
||||||
|
endText?: string;
|
||||||
};
|
};
|
||||||
export const StateBox: FC<stateBox> = ({ text, title, style, mode }) => (
|
export const StateBox: FC<stateBox> = (props) => {
|
||||||
<View style={{ ...(mode == 2 ? boxStyle2 : boxStyle), ...style }}>
|
const { text, title, style, mode, endText } = props;
|
||||||
<Text style={{ fontSize: 12, color: "#0099CC" }}>{title}</Text>
|
return (
|
||||||
<View style={{ flex: 1 }} />
|
<View style={{ ...(mode == 2 ? boxStyle2 : boxStyle), ...style }}>
|
||||||
<View style={{ flexDirection: mode == 2 ? "row" : "column" }}>
|
<Text style={{ fontSize: 12, color: "#0099CC" }}>{title}</Text>
|
||||||
{text?.match("~") ? (
|
<View style={{ flex: 1 }} />
|
||||||
<>
|
<View style={{ flexDirection: mode == 2 ? "row" : "column" }}>
|
||||||
<Text style={mode == 2 ? boxTextStyle2 : boxTextStyle}>
|
{text?.match("~") ? (
|
||||||
{text.split("~")[0]}
|
<>
|
||||||
|
<Text style={mode == 2 ? boxTextStyle2 : boxTextStyle}>
|
||||||
|
{text.split("~")[0]}
|
||||||
|
</Text>
|
||||||
|
<Text style={{ color: "#0099CC", textAlign: "right" }}>
|
||||||
|
{mode == 2 ? "→" : "↓"}
|
||||||
|
</Text>
|
||||||
|
<Text style={mode == 2 ? boxTextStyle2 : boxTextStyle}>
|
||||||
|
{text.split("~")[1]}
|
||||||
|
</Text>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<Text style={mode == 2 ? boxTextStyle2 : boxTextStyle}>{text}</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
{endText && (
|
||||||
|
<View style={{ flexDirection: mode == 2 ? "row" : "column" }}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
...{ ...(mode == 2 ? boxTextStyle2 : boxTextStyle) },
|
||||||
|
fontSize: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{endText}
|
||||||
</Text>
|
</Text>
|
||||||
<Text style={{ color: "#0099CC", textAlign: "right" }}>
|
</View>
|
||||||
{mode == 2 ? "→" : "↓"}
|
|
||||||
</Text>
|
|
||||||
<Text style={mode == 2 ? boxTextStyle2 : boxTextStyle}>
|
|
||||||
{text.split("~")[1]}
|
|
||||||
</Text>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<Text style={mode == 2 ? boxTextStyle2 : boxTextStyle}>{text}</Text>
|
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
);
|
||||||
);
|
};
|
||||||
const boxStyle: ViewStyle = {
|
const boxStyle: ViewStyle = {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
backgroundColor: "white",
|
backgroundColor: "white",
|
||||||
|
@ -6,6 +6,12 @@ import { getStationList2 } from "../../../lib/getStationList2";
|
|||||||
import { useCurrentTrain } from "../../../stateBox/useCurrentTrain";
|
import { useCurrentTrain } from "../../../stateBox/useCurrentTrain";
|
||||||
import { SheetManager } from "react-native-actions-sheet";
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
import { trainPosition } from "../../../lib/trainPositionTextArray";
|
import { trainPosition } from "../../../lib/trainPositionTextArray";
|
||||||
|
import { TrainPositionDataPush } from "../../発車時刻表/LED_inside_Component/TrainPositionDataPush";
|
||||||
|
import { getStationID } from "../../../lib/eachTrainInfoCoreLib/getStationData";
|
||||||
|
import { useStationList } from "../../../stateBox/useStationList";
|
||||||
|
import { lineList } from "../../../lib/getStationList";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const TrainDataView = ({
|
export const TrainDataView = ({
|
||||||
currentTrainData,
|
currentTrainData,
|
||||||
@ -15,20 +21,59 @@ export const TrainDataView = ({
|
|||||||
mode = 0,
|
mode = 0,
|
||||||
navigate,
|
navigate,
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
|
const { stationList } = useStationList();
|
||||||
|
|
||||||
const { width, height } = useWindowDimensions();
|
const { width, height } = useWindowDimensions();
|
||||||
const { isLandscape } = useDeviceOrientationChange();
|
const { isLandscape } = useDeviceOrientationChange();
|
||||||
const { inject } = useCurrentTrain();
|
const { inject } = useCurrentTrain();
|
||||||
const [mapsStationData, setMapsStationData] = useState(undefined);
|
const [mapsStationData, setMapsStationData] = useState(undefined);
|
||||||
|
|
||||||
|
const [platformNumber, setPlatformNumber] = useState();
|
||||||
|
const [platformDescription, setPlatformDescription] = useState();
|
||||||
|
useEffect(() => {
|
||||||
|
//currentTrainData.Pos = "鴨川~端岡"; //test
|
||||||
|
if (!currentTrainData) return;
|
||||||
|
fetch(
|
||||||
|
`https://n8n.haruk.in/webhook/JR-shikoku-PosID?PosNum=${currentTrainData?.PosNum}&Line=${currentTrainData?.Line}`
|
||||||
|
)
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((data) => {
|
||||||
|
setPlatformNumber(data?.type == "Station" ? data?.platform : undefined);
|
||||||
|
setPlatformDescription(
|
||||||
|
data?.type == "Station" ? data?.description : undefined
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}, [currentTrainData]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getStationList2().then(setMapsStationData);
|
getStationList2().then(setMapsStationData);
|
||||||
}, []);
|
}, []);
|
||||||
const onLine = !!currentPosition?.toString().length;
|
const onLine = !!currentPosition?.toString().length;
|
||||||
const trainPositionText = (trainData) => {
|
const trainPositionText = (trainData) => {
|
||||||
const { isBetween, Pos } = trainPosition(trainData);
|
const { isBetween, Pos: PosData } = trainPosition(trainData);
|
||||||
if (isBetween === true) return `${Pos.from}~${Pos.to}`;
|
const { from, to, Pos } = PosData;
|
||||||
else return Pos.Pos == "" ? "" : `${Pos.Pos}`;
|
if (isBetween === true) return `${from}~${to}`;
|
||||||
|
if (Pos == "") return "";
|
||||||
|
return `${Pos}${platformNumber ? ` ${platformNumber}番線` : ""}`;
|
||||||
};
|
};
|
||||||
return (
|
const [dialog, setDialog] = useState(false);
|
||||||
|
const [deleteDialog, setDeleteDialog] = useState(false);
|
||||||
|
const [posInput, setPosInput] = useState("");
|
||||||
|
const [descInput, setDescInput] = useState("");
|
||||||
|
const [stationInput, setStationInput] = useState("");
|
||||||
|
const [stationNumberInput, setStationNumberInput] = useState("");
|
||||||
|
return (<>
|
||||||
|
<TrainPositionDataPush
|
||||||
|
dialog={dialog}
|
||||||
|
setDialog={setDialog}
|
||||||
|
currentTrainData={currentTrainData}
|
||||||
|
stationInput={stationInput}
|
||||||
|
stationNumberInput={stationNumberInput}
|
||||||
|
posInput={posInput}
|
||||||
|
descInput={descInput}
|
||||||
|
setPosInput={setPosInput}
|
||||||
|
setDescInput={setDescInput}
|
||||||
|
station={{Station_JP:trainPositionText(currentTrainData),StationNumber:currentPosition[0]}} />
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
@ -40,8 +85,30 @@ export const TrainDataView = ({
|
|||||||
>
|
>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={{ flex: 1, flexDirection: "row" }}
|
style={{ flex: 1, flexDirection: "row" }}
|
||||||
disabled={!onLine}
|
//disabled={!onLine}
|
||||||
|
onLongPress={() => {
|
||||||
|
const { isBetween, Pos } = trainPosition(currentTrainData);
|
||||||
|
if (isBetween === true) {
|
||||||
|
if (platformNumber == undefined && platformDescription == undefined)
|
||||||
|
return;
|
||||||
|
setStationInput(`${Pos.from}→${Pos.to}間`);
|
||||||
|
setStationNumberInput(
|
||||||
|
getStationID(currentTrainData?.Pos, stationList)
|
||||||
|
);
|
||||||
|
setPosInput(platformNumber?.toString() || "");
|
||||||
|
setDeleteDialog(true);
|
||||||
|
} else {
|
||||||
|
setStationInput(Pos.Pos);
|
||||||
|
setStationNumberInput(
|
||||||
|
getStationID(currentTrainData?.Pos, stationList)
|
||||||
|
);
|
||||||
|
setDescInput(platformDescription || "");
|
||||||
|
setPosInput(platformNumber?.toString() || "");
|
||||||
|
setDialog(true);
|
||||||
|
}
|
||||||
|
}}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
|
if(!onLine) return;
|
||||||
const test = [];
|
const test = [];
|
||||||
Object.keys(mapsStationData).forEach((d) => {
|
Object.keys(mapsStationData).forEach((d) => {
|
||||||
mapsStationData[d].forEach((x) => {
|
mapsStationData[d].forEach((x) => {
|
||||||
@ -67,6 +134,7 @@ export const TrainDataView = ({
|
|||||||
mode={mode}
|
mode={mode}
|
||||||
title={`現在地 ${currentPosition?.toString()}${onLine ? "▶️" : ""}`}
|
title={`現在地 ${currentPosition?.toString()}${onLine ? "▶️" : ""}`}
|
||||||
text={trainPositionText(currentTrainData)}
|
text={trainPositionText(currentTrainData)}
|
||||||
|
endText={platformDescription ? `${platformDescription}` : ""}
|
||||||
style={
|
style={
|
||||||
onLine
|
onLine
|
||||||
? { borderWidth: 1, borderColor: "red", borderStyle: "solid" }
|
? { borderWidth: 1, borderColor: "red", borderStyle: "solid" }
|
||||||
@ -110,5 +178,6 @@ export const TrainDataView = ({
|
|||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
import { SheetManager } from "react-native-actions-sheet";
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
import { AS } from "../../storageControl";
|
import { AS } from "../../storageControl";
|
||||||
import trainList from "../../assets/originData/trainList";
|
import trainList from "../../assets/originData/trainList";
|
||||||
import { lineList, lineListPair } from "../../lib/getStationList";
|
import { lineListPair } from "../../lib/getStationList";
|
||||||
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
|
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
|
||||||
import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData";
|
import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData";
|
||||||
import { getTrainType } from "../../lib/getTrainType";
|
import { getTrainType } from "../../lib/getTrainType";
|
||||||
@ -46,7 +46,7 @@ export const EachTrainInfoCore = ({
|
|||||||
}) => {
|
}) => {
|
||||||
// const [actionSheetHorizonalScroll, setActionSheetHorizonalScroll] = useState(false);
|
// const [actionSheetHorizonalScroll, setActionSheetHorizonalScroll] = useState(false);
|
||||||
const { currentTrain } = useCurrentTrain();
|
const { currentTrain } = useCurrentTrain();
|
||||||
const { originalStationList } = useStationList();
|
const { originalStationList, stationList } = useStationList();
|
||||||
const { setTrainInfo } = useTrainMenu();
|
const { setTrainInfo } = useTrainMenu();
|
||||||
const [currentTrainData, setCurrentTrainData] = useState();
|
const [currentTrainData, setCurrentTrainData] = useState();
|
||||||
|
|
||||||
@ -56,7 +56,8 @@ export const EachTrainInfoCore = ({
|
|||||||
if (!currentTrain.length) return;
|
if (!currentTrain.length) return;
|
||||||
setCurrentTrainData(
|
setCurrentTrainData(
|
||||||
checkDuplicateTrainData(
|
checkDuplicateTrainData(
|
||||||
currentTrain.filter((d) => d.num == data.trainNum)
|
currentTrain.filter((d) => d.num == data.trainNum),
|
||||||
|
stationList
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}, [currentTrain, data.trainNum]);
|
}, [currentTrain, data.trainNum]);
|
||||||
@ -86,15 +87,6 @@ export const EachTrainInfoCore = ({
|
|||||||
const [showThrew, setShowThrew] = useState(false);
|
const [showThrew, setShowThrew] = useState(false);
|
||||||
const [haveThrough, setHaveThrough] = useState(false);
|
const [haveThrough, setHaveThrough] = useState(false);
|
||||||
|
|
||||||
const stationList =
|
|
||||||
originalStationList &&
|
|
||||||
lineList.map((d) =>
|
|
||||||
originalStationList[d].map((a) => ({
|
|
||||||
StationNumber: a.StationNumber,
|
|
||||||
StationName: a.Station_JP,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
|
|
||||||
// 使用例
|
// 使用例
|
||||||
const stopStationIDList = trainDataWidhThrough.map((i) => {
|
const stopStationIDList = trainDataWidhThrough.map((i) => {
|
||||||
const [station, se, time] = i.split(",");
|
const [station, se, time] = i.split(",");
|
||||||
@ -343,6 +335,7 @@ export const EachTrainInfoCore = ({
|
|||||||
.then((d) => {
|
.then((d) => {
|
||||||
if (d) setTrainPositionSwitch(d);
|
if (d) setTrainPositionSwitch(d);
|
||||||
})
|
})
|
||||||
|
//6.0で変更
|
||||||
.catch(() => AS.setItem("trainPositionSwitch", "false"));
|
.catch(() => AS.setItem("trainPositionSwitch", "false"));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ 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";
|
||||||
|
import { OneManText } from "./HeaderTextParts/OneManText";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
data: { trainNum: string; limited: string };
|
data: { trainNum: string; limited: string };
|
||||||
@ -16,10 +17,11 @@ type Props = {
|
|||||||
tailStation: { id: string }[];
|
tailStation: { id: string }[];
|
||||||
navigate: any;
|
navigate: any;
|
||||||
from: string;
|
from: string;
|
||||||
|
fontLoaded: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const textConfig: TextStyle = {
|
const textConfig: TextStyle = {
|
||||||
fontSize: 20,
|
fontSize: 18,
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
color: "white",
|
color: "white",
|
||||||
};
|
};
|
||||||
@ -34,36 +36,127 @@ export const HeaderText: FC<Props> = ({
|
|||||||
navigate,
|
navigate,
|
||||||
from,
|
from,
|
||||||
}) => {
|
}) => {
|
||||||
const trainName = useMemo(() => {
|
const { limited, trainNum } = data;
|
||||||
if (!data.limited) return "";
|
|
||||||
const limitedArray = data.limited.split(":");
|
|
||||||
const type = getType(limitedArray[0]);
|
|
||||||
|
|
||||||
|
// 貨物の判定
|
||||||
|
const freightDetect = (num:string)=>{
|
||||||
|
switch(num){
|
||||||
|
case "71":
|
||||||
|
return "貨物 東京(タ)→高松(タ)";
|
||||||
|
case "73":
|
||||||
|
case "75":
|
||||||
|
return "貨物 大阪(タ)→高松(タ)";
|
||||||
|
case "3079":
|
||||||
|
return "貨物 高松(タ)→伊予三島";
|
||||||
|
case "3071":
|
||||||
|
case "3077":
|
||||||
|
return "貨物 高松(タ)→新居浜";
|
||||||
|
case "3073":
|
||||||
|
return "貨物 高松(タ)→松山貨物";
|
||||||
|
case "70":
|
||||||
|
return "貨物 高松(タ)→東京(タ)";
|
||||||
|
case "74":
|
||||||
|
case "76":
|
||||||
|
return "貨物 高松(タ)→大阪(タ)";
|
||||||
|
case "3078":
|
||||||
|
return "貨物 伊予三島→高松(タ)";
|
||||||
|
case "3070":
|
||||||
|
return "貨物 新居浜→高松(タ)";
|
||||||
|
case "3076":
|
||||||
|
return "貨物 新居浜→高松(タ)";
|
||||||
|
case "3072":
|
||||||
|
return "貨物 松山貨物→高松(タ)";
|
||||||
|
case "9070":
|
||||||
|
return "貨物 臨時";
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列車名、種別、フォントの取得
|
||||||
|
const [typeName, trainName, fontAvailable] = useMemo(() => {
|
||||||
|
if (!limited) return "";
|
||||||
|
const limitedArray = limited.split(":");
|
||||||
|
const [type, fontAvailable] = (() => {
|
||||||
|
const d = getType(limitedArray[0]);
|
||||||
|
switch (true) {
|
||||||
|
case !!d:
|
||||||
|
return [d, true];
|
||||||
|
case !!trainNum.includes("T"):
|
||||||
|
return ["単機回送", false];
|
||||||
|
case !!trainNum.includes("R"):
|
||||||
|
case !!trainNum.includes("E"):
|
||||||
|
case !!trainNum.includes("L"):
|
||||||
|
case !!trainNum.includes("A"):
|
||||||
|
case !!trainNum.includes("B"):
|
||||||
|
return ["回送", false];
|
||||||
|
case !!trainNum.includes("H"):
|
||||||
|
return ["試運転", false];
|
||||||
|
case !!trainNum.match("D"):
|
||||||
|
case !!trainNum.match("M"):
|
||||||
|
return ["普通", true];
|
||||||
|
case !!freightDetect(trainNum):
|
||||||
|
return [freightDetect(trainNum), false];
|
||||||
|
default:
|
||||||
|
return ["", false];
|
||||||
|
}
|
||||||
|
})();
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case !!limitedArray[1]:
|
case !!limitedArray[1]:
|
||||||
// 特急の場合は、列車名を取得
|
// 特急の場合は、列車名を取得
|
||||||
return type + migrateTrainName(limitedArray[1]);
|
return [type, migrateTrainName(limitedArray[1]), fontAvailable];
|
||||||
case trainData.length == 0:
|
case trainData.length == 0:
|
||||||
// 特急以外の場合は、列車番号を取得
|
// 特急以外の場合は、列車番号を取得
|
||||||
return type;
|
|
||||||
|
return [type, "", fontAvailable];
|
||||||
default:
|
default:
|
||||||
// 行先がある場合は、行先を取得
|
// 行先がある場合は、行先を取得
|
||||||
return (
|
return [
|
||||||
type +
|
type,
|
||||||
migrateTrainName(
|
migrateTrainName(
|
||||||
trainData[trainData.length - 1].split(",")[0] + "行き"
|
trainData[trainData.length - 1].split(",")[0] + "行き"
|
||||||
)
|
),
|
||||||
);
|
fontAvailable,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}, [data.limited, trainData]);
|
}, [limited, trainData]);
|
||||||
|
|
||||||
|
// 1人運転の判定
|
||||||
|
const isOneMan = useMemo(() => {
|
||||||
|
const OneManRegex = new RegExp(/^4[1-9]\d\d[DM]$/);
|
||||||
|
const OneManRegex2 = new RegExp(/^5[1-7]\d\d[DM]$/);
|
||||||
|
return !!(
|
||||||
|
OneManRegex.test(trainNum) ||
|
||||||
|
OneManRegex2.test(trainNum) ||
|
||||||
|
trainNum === "3621D"
|
||||||
|
);
|
||||||
|
}, [trainNum]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{ padding: 10, flexDirection: "row", alignItems: "center" }}>
|
<View style={{ padding: 10, flexDirection: "row", alignItems: "center" }}>
|
||||||
<TrainIconStatus {...{ data, navigate, from}}/>
|
<TrainIconStatus {...{ data, navigate, from }} />
|
||||||
<Text style={textConfig}>{trainName}</Text>
|
<View
|
||||||
|
style={{ borderRadius: 5, flexDirection: "row", alignItems: "center" }}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 20,
|
||||||
|
color: "white",
|
||||||
|
fontFamily: fontAvailable ? "JR-Nishi" : undefined,
|
||||||
|
fontWeight: !fontAvailable ?"bold":undefined,
|
||||||
|
marginRight: 5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{typeName}
|
||||||
|
</Text>
|
||||||
|
{isOneMan && <OneManText />}
|
||||||
|
<Text style={textConfig}>{trainName}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
<View style={{ flex: 1 }} />
|
<View style={{ flex: 1 }} />
|
||||||
<Text style={textConfig}>
|
<Text style={textConfig}>
|
||||||
{showHeadStation.map((d) => `${headStation[d].id} + `)}
|
{showHeadStation.map((d) => `${headStation[d].id} + `)}
|
||||||
{data.trainNum}
|
{trainNum}
|
||||||
{showTailStation.map((d) => ` + ${tailStation[d].id}`)}
|
{showTailStation.map((d) => ` + ${tailStation[d].id}`)}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
import React, { FC } from "react";
|
||||||
|
import { Text, View } from "react-native";
|
||||||
|
export const OneManText: FC = () => {
|
||||||
|
const styles = {
|
||||||
|
fontSize: 12,
|
||||||
|
margin: -2,
|
||||||
|
color: "white",
|
||||||
|
fontFamily: "Zou",
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<View style={{ flexDirection: "column", marginRight: 7 }}>
|
||||||
|
<Text style={{ ...styles, marginRight: 5 }}>ワン</Text>
|
||||||
|
<Text style={{ ...styles, marginLeft: 5 }}>マン</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
@ -5,6 +5,7 @@ import dayjs from "dayjs";
|
|||||||
import { useInterval } from "../../../lib/useInterval";
|
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";
|
||||||
|
|
||||||
type GlyphNames = ComponentProps<typeof Ionicons>["name"];
|
type GlyphNames = ComponentProps<typeof Ionicons>["name"];
|
||||||
|
|
||||||
@ -20,8 +21,14 @@ type apt = {
|
|||||||
export const TrainIconStatus: FC<Props> = ({ data, navigate, from }) => {
|
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("");
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!data.trainNum) return;
|
if (!data.trainNum) return;
|
||||||
|
const { trainIcon, infoUrl } = customTrainDataDetector(data.trainNum);
|
||||||
|
if (trainIcon) setTrainIcon(trainIcon);
|
||||||
|
|
||||||
|
if (infoUrl) setAddress(infoUrl);
|
||||||
|
|
||||||
switch (data.trainNum) {
|
switch (data.trainNum) {
|
||||||
case "32D":
|
case "32D":
|
||||||
case "36D":
|
case "36D":
|
||||||
@ -33,11 +40,6 @@ export const TrainIconStatus: FC<Props> = ({ data, navigate, from }) => {
|
|||||||
case "45D":
|
case "45D":
|
||||||
case "49D":
|
case "49D":
|
||||||
case "57D":
|
case "57D":
|
||||||
setTrainIcon(
|
|
||||||
`https://n8n.haruk.in/webhook/dosan-anpanman-pictures.png?trainNum=${
|
|
||||||
data.trainNum
|
|
||||||
}&day=${dayjs().format("yyyy-MM-DD")}`
|
|
||||||
);
|
|
||||||
fetch(
|
fetch(
|
||||||
`https://n8n.haruk.in/webhook/dosan-anpanman?trainNum=${
|
`https://n8n.haruk.in/webhook/dosan-anpanman?trainNum=${
|
||||||
data.trainNum
|
data.trainNum
|
||||||
@ -72,7 +74,7 @@ export const TrainIconStatus: FC<Props> = ({ data, navigate, from }) => {
|
|||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
navigate("howto", {
|
navigate("howto", {
|
||||||
info: "https://www.jr-eki.com/aptrain/naani/dosan/jikoku.html",
|
info: address,
|
||||||
goTo: from == "LED" ? "menu" : from,
|
goTo: from == "LED" ? "menu" : from,
|
||||||
});
|
});
|
||||||
SheetManager.hide("EachTrainInfo");
|
SheetManager.hide("EachTrainInfo");
|
||||||
@ -81,11 +83,15 @@ export const TrainIconStatus: FC<Props> = ({ data, navigate, from }) => {
|
|||||||
{move ? (
|
{move ? (
|
||||||
<Image
|
<Image
|
||||||
source={{ uri: trainIcon }}
|
source={{ uri: trainIcon }}
|
||||||
style={{ height: 30, width: 30, margin: 5 }}
|
style={{ height: 34, width: 30, marginRight: 5 }}
|
||||||
resizeMethod="resize"
|
resizeMethod="scale"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Ionicons {...anpanmanStatus} size={30} style={{ margin: 5 }} />
|
<Ionicons
|
||||||
|
{...anpanmanStatus}
|
||||||
|
size={30}
|
||||||
|
style={{ marginRight: 5 }}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
)}
|
)}
|
||||||
|
@ -8,6 +8,8 @@ import {
|
|||||||
TextInput,
|
TextInput,
|
||||||
Platform,
|
Platform,
|
||||||
Keyboard,
|
Keyboard,
|
||||||
|
ScrollView,
|
||||||
|
Linking,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import { useAllTrainDiagram } from "../stateBox/useAllTrainDiagram";
|
import { useAllTrainDiagram } from "../stateBox/useAllTrainDiagram";
|
||||||
|
|
||||||
@ -16,12 +18,26 @@ import { getTrainType } from "../lib/getTrainType";
|
|||||||
import { SheetManager } from "react-native-actions-sheet";
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
import { useNavigation } from "@react-navigation/native";
|
import { useNavigation } from "@react-navigation/native";
|
||||||
import { BigButton } from "./atom/BigButton";
|
import { BigButton } from "./atom/BigButton";
|
||||||
|
import { Switch } from "react-native-elements";
|
||||||
export default function AllTrainDiagramView() {
|
export default function AllTrainDiagramView() {
|
||||||
const { navigate } = useNavigation();
|
const { navigate } = useNavigation();
|
||||||
const { keyList } = useAllTrainDiagram();
|
const { keyList, allTrainDiagram } = 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 [useRegex, setUseRegex] = useState(false);
|
||||||
|
const regexTextStyle = {
|
||||||
|
color: "white",
|
||||||
|
fontSize: 20,
|
||||||
|
margin: 3,
|
||||||
|
padding: 3,
|
||||||
|
};
|
||||||
|
const regexTextButtonStyle = {
|
||||||
|
...regexTextStyle,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "white",
|
||||||
|
borderRadius: 3,
|
||||||
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const showSubscription = Keyboard.addListener("keyboardDidShow", () => {
|
const showSubscription = Keyboard.addListener("keyboardDidShow", () => {
|
||||||
setKeyBoardVisible(true);
|
setKeyBoardVisible(true);
|
||||||
@ -59,7 +75,23 @@ export default function AllTrainDiagramView() {
|
|||||||
<View style={{ backgroundColor: "#0099CC", height: "100%" }}>
|
<View style={{ backgroundColor: "#0099CC", height: "100%" }}>
|
||||||
<FlatList
|
<FlatList
|
||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
data={keyList?.filter((d) => d.includes(input))}
|
data={keyList?.filter((d) => {
|
||||||
|
if (useStationName) {
|
||||||
|
const ls = input.split(",").map((stationName) => {
|
||||||
|
return allTrainDiagram[d].includes(stationName);
|
||||||
|
});
|
||||||
|
return !ls.includes(false);
|
||||||
|
}
|
||||||
|
if (useRegex) {
|
||||||
|
try {
|
||||||
|
const regex = new RegExp(input);
|
||||||
|
return regex.test(d);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return d.includes(input);
|
||||||
|
})}
|
||||||
renderItem={({ item }) => <Item {...{ openTrainInfo, id: item }} />}
|
renderItem={({ item }) => <Item {...{ openTrainInfo, id: item }} />}
|
||||||
keyExtractor={(item) => item}
|
keyExtractor={(item) => item}
|
||||||
//initialNumToRender={100}
|
//initialNumToRender={100}
|
||||||
@ -69,6 +101,87 @@ export default function AllTrainDiagramView() {
|
|||||||
keyboardVerticalOffset={80}
|
keyboardVerticalOffset={80}
|
||||||
enabled={Platform.OS === "ios"}
|
enabled={Platform.OS === "ios"}
|
||||||
>
|
>
|
||||||
|
<View style={{ height: 35, flexDirection: "row" }}>
|
||||||
|
<Switch
|
||||||
|
value={useRegex}
|
||||||
|
onValueChange={() => {
|
||||||
|
setUseRegex(!useRegex);
|
||||||
|
setUseStationName(false);
|
||||||
|
}}
|
||||||
|
color="red"
|
||||||
|
style={{ margin: 5 }}
|
||||||
|
/>
|
||||||
|
<Text style={{ color: "white", fontSize: 20, margin: 5 }}>
|
||||||
|
正規表現を使用
|
||||||
|
</Text>
|
||||||
|
<Switch
|
||||||
|
value={useStationName}
|
||||||
|
onValueChange={() => {
|
||||||
|
setUseRegex(false);
|
||||||
|
setUseStationName(!useStationName);
|
||||||
|
}}
|
||||||
|
color="red"
|
||||||
|
style={{ margin: 5 }}
|
||||||
|
/>
|
||||||
|
<Text style={{ color: "white", fontSize: 20, margin: 5 }}>
|
||||||
|
駅名で検索
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<ScrollView
|
||||||
|
style={{
|
||||||
|
height: 35,
|
||||||
|
flexDirection: "row",
|
||||||
|
backgroundColor: "#0099CC",
|
||||||
|
margin: 5,
|
||||||
|
display: useRegex ? "flex" : "none",
|
||||||
|
}}
|
||||||
|
horizontal={true}
|
||||||
|
>
|
||||||
|
<Text style={regexTextStyle}>正規表現のサンプル:</Text>
|
||||||
|
<Text style={regexTextButtonStyle} onPress={() => setInput("D")}>
|
||||||
|
気動車を選択
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={regexTextButtonStyle}
|
||||||
|
onPress={() => setInput("3\\d\\d\\dM")}
|
||||||
|
>
|
||||||
|
マリンライナーを選択
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={regexTextButtonStyle}
|
||||||
|
onPress={() => setInput("[4,5]\\d\\d\\d[D,M]")}
|
||||||
|
>
|
||||||
|
ワンマン列車を選択
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={regexTextButtonStyle}
|
||||||
|
onPress={() => setInput("^\\d?\\dM")}
|
||||||
|
>
|
||||||
|
しおかぜを選択
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={regexTextButtonStyle}
|
||||||
|
onPress={() => setInput("^\\d?[0,2,4,6,8]D")}
|
||||||
|
>
|
||||||
|
下り南風を選択
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={regexTextButtonStyle}
|
||||||
|
onPress={() => setInput("^([\\d])+\\1")}
|
||||||
|
>
|
||||||
|
数字が二桁揃っている列車を選択
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={{ ...regexTextButtonStyle, backgroundColor: "green" }}
|
||||||
|
onPress={() =>
|
||||||
|
Linking.openURL(
|
||||||
|
"https://qiita.com/tossh/items/635aea9a529b9deb3038"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
参考資料(Qiita)
|
||||||
|
</Text>
|
||||||
|
</ScrollView>
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
height: 35,
|
height: 35,
|
||||||
|
@ -18,7 +18,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 } = useStationList();
|
const { originalStationList, stationList } = useStationList();
|
||||||
const {
|
const {
|
||||||
setSelectedLine,
|
setSelectedLine,
|
||||||
mapsStationData: stationData,
|
mapsStationData: stationData,
|
||||||
@ -96,7 +96,8 @@ export const AppsWebView = ({ openStationACFromEachTrainInfo }) => {
|
|||||||
trainNum,
|
trainNum,
|
||||||
limited,
|
limited,
|
||||||
trainData: checkDuplicateTrainData(
|
trainData: checkDuplicateTrainData(
|
||||||
currentTrain.filter((a) => a.num == trainNum)
|
currentTrain.filter((a) => a.num == trainNum),
|
||||||
|
stationList
|
||||||
),
|
),
|
||||||
}); //遅延情報は未実装
|
}); //遅延情報は未実装
|
||||||
if (isLandscape) return;
|
if (isLandscape) return;
|
||||||
|
149
components/Settings/NotificationSettings.js
Normal file
149
components/Settings/NotificationSettings.js
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { View, Text, TouchableOpacity, ScrollView,Clipboard } from "react-native";
|
||||||
|
|
||||||
|
import { CheckBox } from "react-native-elements";
|
||||||
|
import { AS } from "../../storageControl";
|
||||||
|
import { useNotification } from "../../stateBox/useNotifications";
|
||||||
|
|
||||||
|
export const NotificationSettings = ({ navigate }) => {
|
||||||
|
const { expoPushToken } = useNotification();
|
||||||
|
const [traInfoEX, setTraInfoEX] = useState(false);
|
||||||
|
const [informations, setInformations] = useState(false);
|
||||||
|
const [strangeTrain, setStrangeTrain] = useState(false);
|
||||||
|
useEffect(() => {
|
||||||
|
AS.getItem("traInfoEX").then(setTraInfoEX);
|
||||||
|
AS.getItem("informations").then(setInformations);
|
||||||
|
AS.getItem("strangeTrain").then(setStrangeTrain);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
||||||
|
<View style={{ backgroundColor: "#0099CC", flexDirection: "row" }}>
|
||||||
|
<View style={{ flex: 1 }}>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => {
|
||||||
|
navigate("settingTopPage");
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
flexDirection: "column",
|
||||||
|
flex: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<View style={{ flex: 1 }} />
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
textAlign: "left",
|
||||||
|
textAlignVertical: "center",
|
||||||
|
color: "white",
|
||||||
|
padding: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
< 設定/送信
|
||||||
|
</Text>
|
||||||
|
<View style={{ flex: 1 }} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
textAlign: "center",
|
||||||
|
color: "white",
|
||||||
|
padding: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
通知設定(β)
|
||||||
|
</Text>
|
||||||
|
<View style={{ flex: 1 }}>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => {
|
||||||
|
fetch(
|
||||||
|
"https://n8n.haruk.in/webhook/jr-shikoku-notification-configurations",
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
token: expoPushToken,
|
||||||
|
traInfoEX,
|
||||||
|
informations,
|
||||||
|
strangeTrain,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
).then(() => {
|
||||||
|
Promise.all([
|
||||||
|
AS.setItem("traInfoEX", traInfoEX.toString()),
|
||||||
|
AS.setItem("informations", informations.toString()),
|
||||||
|
AS.setItem("strangeTrain", strangeTrain.toString()),
|
||||||
|
]).then(()=>alert("通知の設定を保存、登録しました"));
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
flexDirection: "column",
|
||||||
|
flex: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<View style={{ flex: 1 }} />
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
textAlign: "right",
|
||||||
|
textAlignVertical: "center",
|
||||||
|
color: "pink",
|
||||||
|
padding: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
登録実行
|
||||||
|
</Text>
|
||||||
|
<View style={{ flex: 1 }} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<ScrollView style={{ flex: 1, backgroundColor: "white" }}>
|
||||||
|
<SimpleSwitch
|
||||||
|
bool={traInfoEX}
|
||||||
|
setBool={setTraInfoEX}
|
||||||
|
str="遅延速報EX"
|
||||||
|
/>
|
||||||
|
<SimpleSwitch
|
||||||
|
bool={informations}
|
||||||
|
setBool={setInformations}
|
||||||
|
str="運行情報"
|
||||||
|
/>
|
||||||
|
<SimpleSwitch
|
||||||
|
bool={strangeTrain}
|
||||||
|
setBool={setStrangeTrain}
|
||||||
|
str="怪レい列車"
|
||||||
|
/>
|
||||||
|
<Text style={{fontWeight: "bold", padding: 10 }} onPress={()=>{
|
||||||
|
Clipboard.setString(expoPushToken);
|
||||||
|
}}>
|
||||||
|
通知を受け取りたい項目を選択してください。チェックボックスを選び、右上の「登録実行」を押すと設定が反映され、通知が届くようになります。
|
||||||
|
</Text>
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const SimpleSwitch = ({ bool, setBool, str }) => (
|
||||||
|
<View style={{ flexDirection: "row" }}>
|
||||||
|
<CheckBox
|
||||||
|
checked={bool == "true" ? true : false}
|
||||||
|
checkedColor="red"
|
||||||
|
onPress={() => setBool(bool == "true" ? "false" : "true")}
|
||||||
|
containerStyle={{
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#00000000",
|
||||||
|
borderColor: "white",
|
||||||
|
alignContent: "center",
|
||||||
|
}}
|
||||||
|
textStyle={{ fontSize: 20, fontWeight: "normal" }}
|
||||||
|
title={str}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
@ -11,11 +11,20 @@ import {
|
|||||||
import * as Updates from "expo-updates";
|
import * as Updates from "expo-updates";
|
||||||
import { useWindowDimensions } from "react-native";
|
import { useWindowDimensions } from "react-native";
|
||||||
import { ListItem } from "native-base";
|
import { ListItem } from "native-base";
|
||||||
|
import { SwitchArea } from "../atom/SwitchArea";
|
||||||
|
import { useNotification } from "../../stateBox/useNotifications";
|
||||||
|
|
||||||
const versionCode = "5.5.1";
|
const versionCode = "5.6";
|
||||||
|
|
||||||
export const SettingTopPage = ({ navigate, testNFC, updateAndReload }) => {
|
export const SettingTopPage = ({
|
||||||
|
navigate,
|
||||||
|
testNFC,
|
||||||
|
startPage,
|
||||||
|
setStartPage,
|
||||||
|
updateAndReload,
|
||||||
|
}) => {
|
||||||
const { width } = useWindowDimensions();
|
const { width } = useWindowDimensions();
|
||||||
|
const { expoPushToken } = useNotification();
|
||||||
return (
|
return (
|
||||||
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
||||||
<View style={{ backgroundColor: "#0099CC", flexDirection: "row" }}>
|
<View style={{ backgroundColor: "#0099CC", flexDirection: "row" }}>
|
||||||
@ -100,6 +109,15 @@ export const SettingTopPage = ({ navigate, testNFC, updateAndReload }) => {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={{ flex: 1, borderTopWidth: 1, borderColor: "gray" }}>
|
<View style={{ flex: 1, borderTopWidth: 1, borderColor: "gray" }}>
|
||||||
|
<SwitchArea
|
||||||
|
str="起動時に表示する画面"
|
||||||
|
bool={startPage}
|
||||||
|
setBool={setStartPage}
|
||||||
|
falseImage={require("../../assets/configuration/showSetting0.jpg")}
|
||||||
|
trueImage={require("../../assets/configuration/showSetting1.jpg")}
|
||||||
|
falseText={"リンクメニュー"}
|
||||||
|
trueText={"列車位置情報"}
|
||||||
|
/>
|
||||||
<ListItem
|
<ListItem
|
||||||
style={{ flexDirection: "row" }}
|
style={{ flexDirection: "row" }}
|
||||||
onPress={() => navigate("FavoriteSettings")}
|
onPress={() => navigate("FavoriteSettings")}
|
||||||
@ -128,6 +146,35 @@ export const SettingTopPage = ({ navigate, testNFC, updateAndReload }) => {
|
|||||||
{">"}
|
{">"}
|
||||||
</Text>
|
</Text>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
<ListItem
|
||||||
|
style={{ flexDirection: "row" }}
|
||||||
|
onPress={() => navigate("NotificationSettings")}
|
||||||
|
disabled={expoPushToken == ""}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 20,
|
||||||
|
alignItems: "center",
|
||||||
|
alignContent: "center",
|
||||||
|
textAlign: "center",
|
||||||
|
textAlignVertical: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
通知設定{expoPushToken == "" ? "(通知設定をオンにしてください)" : "(β)"}
|
||||||
|
</Text>
|
||||||
|
<View style={{ flex: 1 }} />
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 20,
|
||||||
|
alignItems: "center",
|
||||||
|
alignContent: "center",
|
||||||
|
textAlign: "center",
|
||||||
|
textAlignVertical: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{">"}
|
||||||
|
</Text>
|
||||||
|
</ListItem>
|
||||||
<ListItem
|
<ListItem
|
||||||
style={{ flexDirection: "row" }}
|
style={{ flexDirection: "row" }}
|
||||||
onPress={() => navigate("LayoutSettings")}
|
onPress={() => navigate("LayoutSettings")}
|
||||||
|
@ -22,6 +22,7 @@ import { SettingTopPage } from "./SettingTopPage";
|
|||||||
import { LayoutSettings } from "./LayoutSettings";
|
import { LayoutSettings } from "./LayoutSettings";
|
||||||
import { FavoriteSettings } from "./FavoriteSettings";
|
import { FavoriteSettings } from "./FavoriteSettings";
|
||||||
import { WidgetSettings } from "./WidgetSettings";
|
import { WidgetSettings } from "./WidgetSettings";
|
||||||
|
import { NotificationSettings } from "./NotificationSettings";
|
||||||
|
|
||||||
const Stack = createStackNavigator();
|
const Stack = createStackNavigator();
|
||||||
export default function Setting(props) {
|
export default function Setting(props) {
|
||||||
@ -35,6 +36,7 @@ export default function Setting(props) {
|
|||||||
const [trainMenu, setTrainMenu] = useState(false);
|
const [trainMenu, setTrainMenu] = useState(false);
|
||||||
const [trainPosition, setTrainPosition] = useState(false);
|
const [trainPosition, setTrainPosition] = useState(false);
|
||||||
const [headerSize, setHeaderSize] = useState("default");
|
const [headerSize, setHeaderSize] = useState("default");
|
||||||
|
const [startPage, setStartPage] = useState(false);
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
AS.getItem("iconSwitch").then(setIconSetting);
|
AS.getItem("iconSwitch").then(setIconSetting);
|
||||||
AS.getItem("mapSwitch").then(setMapSwitch);
|
AS.getItem("mapSwitch").then(setMapSwitch);
|
||||||
@ -43,6 +45,7 @@ export default function Setting(props) {
|
|||||||
AS.getItem("trainSwitch").then(setTrainMenu);
|
AS.getItem("trainSwitch").then(setTrainMenu);
|
||||||
AS.getItem("trainPositionSwitch").then(setTrainPosition);
|
AS.getItem("trainPositionSwitch").then(setTrainPosition);
|
||||||
AS.getItem("headerSize").then(setHeaderSize);
|
AS.getItem("headerSize").then(setHeaderSize);
|
||||||
|
AS.getItem("startPage").then(setStartPage);
|
||||||
}, []);
|
}, []);
|
||||||
const testNFC = async () => {
|
const testNFC = async () => {
|
||||||
const result = await ExpoFelicaReader.scan();
|
const result = await ExpoFelicaReader.scan();
|
||||||
@ -57,6 +60,7 @@ export default function Setting(props) {
|
|||||||
AS.setItem("trainSwitch", trainMenu.toString()),
|
AS.setItem("trainSwitch", trainMenu.toString()),
|
||||||
AS.setItem("trainPositionSwitch", trainPosition.toString()),
|
AS.setItem("trainPositionSwitch", trainPosition.toString()),
|
||||||
AS.setItem("headerSize", headerSize),
|
AS.setItem("headerSize", headerSize),
|
||||||
|
AS.setItem("startPage", startPage.toString()),
|
||||||
]).then(() => Updates.reloadAsync());
|
]).then(() => Updates.reloadAsync());
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
@ -75,19 +79,9 @@ export default function Setting(props) {
|
|||||||
<SettingTopPage
|
<SettingTopPage
|
||||||
{...props}
|
{...props}
|
||||||
navigate={navigate}
|
navigate={navigate}
|
||||||
iconSetting={iconSetting}
|
|
||||||
setIconSetting={setIconSetting}
|
|
||||||
mapSwitch={mapSwitch}
|
|
||||||
setMapSwitch={setMapSwitch}
|
|
||||||
stationMenu={stationMenu}
|
|
||||||
setStationMenu={setStationMenu}
|
|
||||||
usePDFView={usePDFView}
|
|
||||||
setUsePDFView={setUsePDFView}
|
|
||||||
trainMenu={trainMenu}
|
|
||||||
setTrainMenu={setTrainMenu}
|
|
||||||
trainPosition={trainPosition}
|
|
||||||
setTrainPosition={setTrainPosition}
|
|
||||||
testNFC={testNFC}
|
testNFC={testNFC}
|
||||||
|
startPage={startPage}
|
||||||
|
setStartPage={setStartPage}
|
||||||
updateAndReload={updateAndReload}
|
updateAndReload={updateAndReload}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -125,6 +119,23 @@ export default function Setting(props) {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Stack.Screen>
|
</Stack.Screen>
|
||||||
|
<Stack.Screen
|
||||||
|
name="NotificationSettings"
|
||||||
|
options={{
|
||||||
|
//gestureEnabled: true,
|
||||||
|
...TransitionPresets.SlideFromRightIOS,
|
||||||
|
cardOverlayEnabled: true,
|
||||||
|
headerTransparent: true,
|
||||||
|
headerShown: false,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{(props) => (
|
||||||
|
<NotificationSettings
|
||||||
|
{...props}
|
||||||
|
navigate={navigate}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Stack.Screen>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
name="WidgetSettings"
|
name="WidgetSettings"
|
||||||
options={{
|
options={{
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import dayjs from "dayjs";
|
||||||
export const customTrainDataDetector = (TrainNumber: string) => {
|
export const customTrainDataDetector = (TrainNumber: string) => {
|
||||||
switch (TrainNumber) {
|
switch (TrainNumber) {
|
||||||
//しおかぜメイン
|
//しおかぜメイン
|
||||||
@ -22,7 +23,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "しおかぜ",
|
trainName: "しおかぜ",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s8000nr.png",
|
trainIcon: "https://storage.haruk.in/s8000nr.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html",
|
||||||
trainNumDistance: 0,
|
trainNumDistance: 0,
|
||||||
info: "いしづちと併結 / 8000系で運転",
|
info: "いしづちと併結 / 8000系で運転",
|
||||||
};
|
};
|
||||||
@ -30,19 +33,22 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "しおかぜ",
|
trainName: "しおかぜ",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s8000nr.png",
|
trainIcon: "https://storage.haruk.in/s8000nr.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html",
|
||||||
trainNumDistance: 0,
|
trainNumDistance: 0,
|
||||||
info: "8000系で運転",
|
info: "8000系で運転",
|
||||||
};
|
};
|
||||||
//8000 アンパン
|
//8000 アンパン
|
||||||
|
case "10M":
|
||||||
case "22M":
|
case "22M":
|
||||||
case "9M":
|
case "9M":
|
||||||
case "10M":
|
|
||||||
case "21M":
|
case "21M":
|
||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "しおかぜ",
|
trainName: "しおかぜ",
|
||||||
trainIcon: "http://www.trainfrontview.net/f/s8000ap.png",
|
trainIcon: "https://storage.haruk.in/s8000ap.png",
|
||||||
|
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
|
||||||
trainNumDistance: 0,
|
trainNumDistance: 0,
|
||||||
info: "いしづちと併結 / アンパンマン列車で運転",
|
info: "いしづちと併結 / アンパンマン列車で運転",
|
||||||
};
|
};
|
||||||
@ -58,7 +64,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "しおかぜ",
|
trainName: "しおかぜ",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s8600.png",
|
trainIcon: "https://storage.haruk.in/s8600.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html",
|
||||||
trainNumDistance: 0,
|
trainNumDistance: 0,
|
||||||
info: "いしづちと併結 / 8600系で運転",
|
info: "いしづちと併結 / 8600系で運転",
|
||||||
};
|
};
|
||||||
@ -86,7 +94,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "いしづち",
|
trainName: "いしづち",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s8000no.png",
|
trainIcon: "https://storage.haruk.in/s8000no.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
|
||||||
trainNumDistance: 1000,
|
trainNumDistance: 1000,
|
||||||
info: "しおかぜと併結 / 8000系で運転",
|
info: "しおかぜと併結 / 8000系で運転",
|
||||||
};
|
};
|
||||||
@ -99,7 +109,8 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "いしづち",
|
trainName: "いしづち",
|
||||||
trainIcon: "http://www.trainfrontview.net/f/s8000ap.png",
|
trainIcon: "https://storage.haruk.in/s8000ap.png",
|
||||||
|
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
|
||||||
trainNumDistance: 1000,
|
trainNumDistance: 1000,
|
||||||
info: "しおかぜと併結 / アンパンマン列車で運転",
|
info: "しおかぜと併結 / アンパンマン列車で運転",
|
||||||
};
|
};
|
||||||
@ -116,7 +127,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "いしづち",
|
trainName: "いしづち",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s8600_isz.png",
|
trainIcon: "https://storage.haruk.in/s8600_isz.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
|
||||||
trainNumDistance: 1000,
|
trainNumDistance: 1000,
|
||||||
info: "しおかぜと併結 / 8600系で運転",
|
info: "しおかぜと併結 / 8600系で運転",
|
||||||
};
|
};
|
||||||
@ -127,7 +140,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "モーニングEXP高松",
|
trainName: "モーニングEXP高松",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s8000no.png",
|
trainIcon: "https://storage.haruk.in/s8000nr.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/morning.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "8000系で運転",
|
info: "8000系で運転",
|
||||||
};
|
};
|
||||||
@ -136,7 +151,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "モーニングEXP松山",
|
trainName: "モーニングEXP松山",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s8600_isz.png",
|
trainIcon: "https://storage.haruk.in/s8600_isz.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/morning.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "8600系で運転",
|
info: "8600系で運転",
|
||||||
};
|
};
|
||||||
@ -147,7 +164,8 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "いしづち",
|
trainName: "いしづち",
|
||||||
trainIcon: "http://www.trainfrontview.net/f/s8000ap.png",
|
trainIcon: "https://storage.haruk.in/s8000ap.png",
|
||||||
|
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
|
||||||
trainNumDistance: 940,
|
trainNumDistance: 940,
|
||||||
info: "アンパンマン列車で運転",
|
info: "アンパンマン列車で運転",
|
||||||
};
|
};
|
||||||
@ -158,7 +176,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "いしづち",
|
trainName: "いしづち",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s8600_isz.png",
|
trainIcon: "https://storage.haruk.in/s8600_isz.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
|
||||||
trainNumDistance: 940,
|
trainNumDistance: 940,
|
||||||
info: "8600系で運転",
|
info: "8600系で運転",
|
||||||
};
|
};
|
||||||
@ -171,7 +191,8 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "南風",
|
trainName: "南風",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s2700.png",
|
trainIcon: "https://storage.haruk.in/s2700.png",
|
||||||
|
infoUrl: "http://jr-shikoku.co.jp/01_trainbus/vehicle-info/nanpu.html",
|
||||||
trainNumDistance: 30,
|
trainNumDistance: 30,
|
||||||
info: "しまんとと併結 / 2700系で運転",
|
info: "しまんとと併結 / 2700系で運転",
|
||||||
};
|
};
|
||||||
@ -180,7 +201,8 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "南風",
|
trainName: "南風",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s2700.png",
|
trainIcon: "https://storage.haruk.in/s2700.png",
|
||||||
|
infoUrl: "http://jr-shikoku.co.jp/01_trainbus/vehicle-info/nanpu.html",
|
||||||
trainNumDistance: 30,
|
trainNumDistance: 30,
|
||||||
info: "うずしおと併結 / 2700系で運転",
|
info: "うずしおと併結 / 2700系で運転",
|
||||||
};
|
};
|
||||||
@ -199,7 +221,8 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "南風",
|
trainName: "南風",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s2700.png",
|
trainIcon: "https://storage.haruk.in/s2700.png",
|
||||||
|
infoUrl: "http://jr-shikoku.co.jp/01_trainbus/vehicle-info/nanpu.html",
|
||||||
trainNumDistance: 30,
|
trainNumDistance: 30,
|
||||||
info: "2700系で運転",
|
info: "2700系で運転",
|
||||||
};
|
};
|
||||||
@ -210,22 +233,30 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "南風",
|
trainName: "南風",
|
||||||
trainIcon: "http://www.trainfrontview.net/f/s2700apr.png",
|
trainIcon: `https://n8n.haruk.in/webhook/dosan-anpanman-pictures.png?trainNum=${TrainNumber}&day=${dayjs().format(
|
||||||
|
"yyyy-MM-DD"
|
||||||
|
)}`,
|
||||||
|
infoUrl: "https://www.jr-eki.com/aptrain/naani/dosan/train.html",
|
||||||
trainNumDistance: 30,
|
trainNumDistance: 30,
|
||||||
info: "うずしおと連結 / アンパンマン列車で運転",
|
info: "うずしおと連結 / アンパンマン列車で運転",
|
||||||
};
|
};
|
||||||
case "32D":
|
case "32D":
|
||||||
|
case "36D":
|
||||||
case "44D":
|
case "44D":
|
||||||
case "48D":
|
case "48D":
|
||||||
case "56D":
|
case "56D":
|
||||||
case "33D":
|
case "33D":
|
||||||
|
case "37D":
|
||||||
case "45D":
|
case "45D":
|
||||||
case "49D":
|
case "49D":
|
||||||
case "57D":
|
case "57D":
|
||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "南風",
|
trainName: "南風",
|
||||||
trainIcon: "http://www.trainfrontview.net/f/s2700apr.png",
|
trainIcon: `https://n8n.haruk.in/webhook/dosan-anpanman-pictures.png?trainNum=${TrainNumber}&day=${dayjs().format(
|
||||||
|
"yyyy-MM-DD"
|
||||||
|
)}`,
|
||||||
|
infoUrl: "https://www.jr-eki.com/aptrain/naani/dosan/train.html",
|
||||||
trainNumDistance: 30,
|
trainNumDistance: 30,
|
||||||
info: "アンパンマン列車で運転",
|
info: "アンパンマン列車で運転",
|
||||||
};
|
};
|
||||||
@ -239,7 +270,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "うずしお",
|
trainName: "うずしお",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s2700_uzu.png",
|
trainIcon: "https://storage.haruk.in/s2700_uzu.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html",
|
||||||
trainNumDistance: 5000,
|
trainNumDistance: 5000,
|
||||||
info: "南風と併結 / 高松-宇多津間進行方向逆転 / 2700系で運転",
|
info: "南風と併結 / 高松-宇多津間進行方向逆転 / 2700系で運転",
|
||||||
};
|
};
|
||||||
@ -255,7 +288,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "うずしお",
|
trainName: "うずしお",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s2700_uzu.png",
|
trainIcon: "https://storage.haruk.in/s2700_uzu.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html",
|
||||||
trainNumDistance: 3000,
|
trainNumDistance: 3000,
|
||||||
info: "2700系で運転",
|
info: "2700系で運転",
|
||||||
};
|
};
|
||||||
@ -273,7 +308,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "うずしお",
|
trainName: "うずしお",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s2700_uzu.png",
|
trainIcon: "https://storage.haruk.in/s2700_uzu.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html",
|
||||||
trainNumDistance: 3000,
|
trainNumDistance: 3000,
|
||||||
info: "2700系で運転",
|
info: "2700系で運転",
|
||||||
};
|
};
|
||||||
@ -292,7 +329,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "うずしお",
|
trainName: "うずしお",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s2600.png",
|
trainIcon: "https://storage.haruk.in/s2600.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html",
|
||||||
trainNumDistance: 3000,
|
trainNumDistance: 3000,
|
||||||
info: "2600系で運転",
|
info: "2600系で運転",
|
||||||
};
|
};
|
||||||
@ -303,7 +342,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "うずしお",
|
trainName: "うずしお",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s185tu_uzu.png",
|
trainIcon: "https://storage.haruk.in/s185tu_uzu.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html",
|
||||||
trainNumDistance: 3000,
|
trainNumDistance: 3000,
|
||||||
info: "キハ185系で運転",
|
info: "キハ185系で運転",
|
||||||
};
|
};
|
||||||
@ -380,7 +421,8 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "Rapid",
|
type: "Rapid",
|
||||||
trainName: "マリンライナー",
|
trainName: "マリンライナー",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s5001.png",
|
trainIcon: "https://storage.haruk.in/s5001.png",
|
||||||
|
infoUrl: "http://jr-shikoku.co.jp/01_trainbus/vehicle-info/marine.html",
|
||||||
trainNumDistance: 3100,
|
trainNumDistance: 3100,
|
||||||
info: "",
|
info: "",
|
||||||
};
|
};
|
||||||
@ -392,7 +434,8 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "Rapid",
|
type: "Rapid",
|
||||||
trainName: "マリンライナー",
|
trainName: "マリンライナー",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s5001k.png",
|
trainIcon: "https://storage.haruk.in/s5001k.png",
|
||||||
|
infoUrl: "http://jr-shikoku.co.jp/01_trainbus/vehicle-info/marine.html",
|
||||||
trainNumDistance: 3100,
|
trainNumDistance: 3100,
|
||||||
info: "",
|
info: "",
|
||||||
};
|
};
|
||||||
@ -403,7 +446,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "NightLTDEXP",
|
type: "NightLTDEXP",
|
||||||
trainName: "サンライズ瀬戸",
|
trainName: "サンライズ瀬戸",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/w285.png",
|
trainIcon: "https://storage.haruk.in/w285.png",
|
||||||
|
infoUrl:
|
||||||
|
"https://www.jr-odekake.net/train/sunriseseto_izumo/index.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
};
|
};
|
||||||
@ -412,7 +457,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "NightLTDEXP",
|
type: "NightLTDEXP",
|
||||||
trainName: "サンライズ瀬戸",
|
trainName: "サンライズ瀬戸",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/w285.png",
|
trainIcon: "https://storage.haruk.in/w285.png",
|
||||||
|
infoUrl:
|
||||||
|
"https://www.jr-odekake.net/train/sunriseseto_izumo/index.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "琴平延長運転日",
|
info: "琴平延長運転日",
|
||||||
};
|
};
|
||||||
@ -446,7 +493,8 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "宇和海",
|
trainName: "宇和海",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s2000_uwa.png",
|
trainIcon: "https://storage.haruk.in/s2000_uwa.png",
|
||||||
|
infoUrl: "http://jr-shikoku.co.jp/01_trainbus/vehicle-info/uwakai.html",
|
||||||
trainNumDistance: 1050,
|
trainNumDistance: 1050,
|
||||||
info: "2000系で運転",
|
info: "2000系で運転",
|
||||||
};
|
};
|
||||||
@ -462,7 +510,8 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "宇和海",
|
trainName: "宇和海",
|
||||||
trainIcon: "http://www.trainfrontview.net/f/s2002a.png",
|
trainIcon: "https://storage.haruk.in/s2002a.png",
|
||||||
|
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
|
||||||
trainNumDistance: 1050,
|
trainNumDistance: 1050,
|
||||||
info: "アンパン列車で運転",
|
info: "アンパン列車で運転",
|
||||||
};
|
};
|
||||||
@ -474,7 +523,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "しまんと",
|
trainName: "しまんと",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s2700_smn.png",
|
trainIcon: "https://storage.haruk.in/s2700_smn.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/shimanto.html",
|
||||||
trainNumDistance: 2000,
|
trainNumDistance: 2000,
|
||||||
info: "2700系で運転",
|
info: "2700系で運転",
|
||||||
};
|
};
|
||||||
@ -485,7 +536,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "しまんと",
|
trainName: "しまんと",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s2700_smn.png",
|
trainIcon: "https://storage.haruk.in/s2000_smn.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/shimanto.html",
|
||||||
trainNumDistance: 2000,
|
trainNumDistance: 2000,
|
||||||
info: "南風と併結 / 2700系で運転",
|
info: "南風と併結 / 2700系で運転",
|
||||||
};
|
};
|
||||||
@ -502,7 +555,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "あしずり",
|
trainName: "あしずり",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s2000_asi.png",
|
trainIcon: "https://storage.haruk.in/s2000_asi.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/ashizuri.html",
|
||||||
trainNumDistance: 2070,
|
trainNumDistance: 2070,
|
||||||
info: "2000系で運転",
|
info: "2000系で運転",
|
||||||
};
|
};
|
||||||
@ -518,7 +573,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "あしずり",
|
trainName: "あしずり",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s2700_asi.png",
|
trainIcon: "https://storage.haruk.in/s2700_asi.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/ashizuri.html",
|
||||||
trainNumDistance: 2070,
|
trainNumDistance: 2070,
|
||||||
info: "2700系で運転",
|
info: "2700系で運転",
|
||||||
};
|
};
|
||||||
@ -538,7 +595,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "剣山",
|
trainName: "剣山",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s185tu.png",
|
trainIcon: "https://storage.haruk.in/s185tu.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/vehicle-info/tsurugisan.html",
|
||||||
trainNumDistance: 4000,
|
trainNumDistance: 4000,
|
||||||
info: "キハ185系で運転",
|
info: "キハ185系で運転",
|
||||||
};
|
};
|
||||||
@ -549,7 +608,8 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "むろと",
|
trainName: "むろと",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s185_mrt.png",
|
trainIcon: "https://storage.haruk.in/s185_mrt.png",
|
||||||
|
infoUrl: "http://jr-shikoku.co.jp/01_trainbus/vehicle-info/muroto.html",
|
||||||
trainNumDistance: 5050,
|
trainNumDistance: 5050,
|
||||||
info: "キハ185系で運転",
|
info: "キハ185系で運転",
|
||||||
};
|
};
|
||||||
@ -560,7 +620,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "よしのがわトロッコ",
|
trainName: "よしのがわトロッコ",
|
||||||
trainIcon: "http://www.trainfrontview.net/f/s185to_ai.png",
|
trainIcon: "https://storage.haruk.in/s185to_ai.png",
|
||||||
|
infoUrl:
|
||||||
|
"http://jr-shikoku.co.jp/01_trainbus/event_train/yoshino_torokko.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
};
|
};
|
||||||
@ -574,7 +636,9 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "アンパンマントロッコ",
|
trainName: "アンパンマントロッコ",
|
||||||
trainIcon: "http://www.trainfrontview.net/f/s32to4.png",
|
trainIcon: "https://storage.haruk.in/s32to4.png",
|
||||||
|
infoUrl:
|
||||||
|
"https://www.jr-eki.com/aptrain/naani/torokko_seto/jikoku.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
};
|
};
|
||||||
@ -582,12 +646,21 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
//伊予灘ものがたり
|
//伊予灘ものがたり
|
||||||
case "8091D":
|
case "8091D":
|
||||||
case "8093D":
|
case "8093D":
|
||||||
|
return {
|
||||||
|
type: "LTDEXP",
|
||||||
|
trainName: "伊予灘ものがたり",
|
||||||
|
trainIcon: "https://storage.haruk.in/s185iyor.png",
|
||||||
|
infoUrl: "https://iyonadamonogatari.com/",
|
||||||
|
trainNumDistance: null,
|
||||||
|
info: "",
|
||||||
|
};
|
||||||
case "8092D":
|
case "8092D":
|
||||||
case "8094D":
|
case "8094D":
|
||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "伊予灘ものがたり",
|
trainName: "伊予灘ものがたり",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s185iyoy.png",
|
trainIcon: "https://storage.haruk.in/s185iyoy.png",
|
||||||
|
infoUrl: "https://iyonadamonogatari.com/",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
};
|
};
|
||||||
@ -598,7 +671,8 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "四国まんなか千年ものがたり",
|
trainName: "四国まんなか千年ものがたり",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s185mm1.png",
|
trainIcon: "https://storage.haruk.in/s185mm1.png",
|
||||||
|
infoUrl: "https://www.jr-shikoku.co.jp/sennenmonogatari/",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
};
|
};
|
||||||
@ -611,19 +685,35 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "時代の夜明けのものがたり",
|
trainName: "時代の夜明けのものがたり",
|
||||||
trainIcon: "http://www.trainfrontview.net/b/s185ym1.png",
|
trainIcon: "https://storage.haruk.in/s185ym1.png",
|
||||||
|
infoUrl: "https://www.jr-shikoku.co.jp/yoakenomonogatari/index.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return {
|
if (
|
||||||
type: "Normal",
|
new RegExp(/^4[1-9]\d\d[DM]$/).test(TrainNumber) ||
|
||||||
trainName: "",
|
new RegExp(/^5[1-7]\d\d[DM]$/).test(TrainNumber) ||
|
||||||
trainIcon: null,
|
TrainNumber === "3621D"
|
||||||
trainNumDistance: null,
|
)
|
||||||
info: null,
|
return {
|
||||||
};
|
type: "OneMan",
|
||||||
|
trainName: "",
|
||||||
|
trainIcon: null,
|
||||||
|
infoUrl: null,
|
||||||
|
trainNumDistance: null,
|
||||||
|
info: null,
|
||||||
|
};
|
||||||
|
else
|
||||||
|
return {
|
||||||
|
type: "Normal",
|
||||||
|
trainName: "",
|
||||||
|
trainIcon: null,
|
||||||
|
infoUrl: null,
|
||||||
|
trainNumDistance: null,
|
||||||
|
info: null,
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -82,7 +82,7 @@ export default function TrainMenu({ style }) {
|
|||||||
d={d}
|
d={d}
|
||||||
navigate={navigate}
|
navigate={navigate}
|
||||||
webview={webview}
|
webview={webview}
|
||||||
key={index + indexBase}
|
key={D.StationNumber+d}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</MapView>
|
</MapView>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { FC, useEffect, useState } from "react";
|
import React, { FC, useEffect, useState } from "react";
|
||||||
import { Linking, TouchableOpacity } from "react-native";
|
import { Linking, TouchableOpacity, Text } from "react-native";
|
||||||
|
import { Dialog, Button, Input } from "react-native-elements";
|
||||||
import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData";
|
import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData";
|
||||||
import { getTrainDelayStatus } from "../../lib/getTrainDelayStatus";
|
import { getTrainDelayStatus } from "../../lib/getTrainDelayStatus";
|
||||||
import { getTrainType } from "../../lib/getTrainType";
|
import { getTrainType } from "../../lib/getTrainType";
|
||||||
@ -11,7 +12,10 @@ import { LastStation } from "./LED_inside_Component/LastStation";
|
|||||||
import { StatusAndDelay } from "./LED_inside_Component/StatusAndDelay";
|
import { StatusAndDelay } from "./LED_inside_Component/StatusAndDelay";
|
||||||
import { TrainName } from "./LED_inside_Component/TrainName";
|
import { TrainName } from "./LED_inside_Component/TrainName";
|
||||||
import { customTrainDataDetector } from "../custom-train-data";
|
import { customTrainDataDetector } from "../custom-train-data";
|
||||||
import { trainDataType, trainPosition } from "../../lib/trainPositionTextArray";
|
import { TrainPosition } from "./LED_inside_Component/TrainPosition";
|
||||||
|
import { TrainPositionDataPush } from "./LED_inside_Component/TrainPositionDataPush";
|
||||||
|
import { TrainPositionDataDelete } from "./LED_inside_Component/TrainPositionDataDelete";
|
||||||
|
import { useStationList } from "../../stateBox/useStationList";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
d: {
|
d: {
|
||||||
@ -23,6 +27,7 @@ type Props = {
|
|||||||
trainDescriptionSwitch: boolean;
|
trainDescriptionSwitch: boolean;
|
||||||
station: {
|
station: {
|
||||||
Station_JP: string;
|
Station_JP: string;
|
||||||
|
StationNumber: string;
|
||||||
};
|
};
|
||||||
navigate: (screen: string, data?: any) => void;
|
navigate: (screen: string, data?: any) => void;
|
||||||
openStationACFromEachTrainInfo: (station: string) => void;
|
openStationACFromEachTrainInfo: (station: string) => void;
|
||||||
@ -37,6 +42,7 @@ export const EachData: FC<Props> = (props) => {
|
|||||||
openStationACFromEachTrainInfo,
|
openStationACFromEachTrainInfo,
|
||||||
} = props;
|
} = props;
|
||||||
const { currentTrain } = useCurrentTrain();
|
const { currentTrain } = useCurrentTrain();
|
||||||
|
const { stationList } = useStationList();
|
||||||
const openTrainInfo = (d: {
|
const openTrainInfo = (d: {
|
||||||
train: string;
|
train: string;
|
||||||
lastStation: string;
|
lastStation: string;
|
||||||
@ -67,21 +73,26 @@ export const EachData: FC<Props> = (props) => {
|
|||||||
|
|
||||||
const getTrainDataFromCurrentTrain = (trainNum: string) => {
|
const getTrainDataFromCurrentTrain = (trainNum: string) => {
|
||||||
const customTrainData = customTrainDataDetector(d.train);
|
const customTrainData = customTrainDataDetector(d.train);
|
||||||
if (customTrainData.type != "Normal") return customTrainData;
|
switch (customTrainData.type) {
|
||||||
const currentTrainData = currentTrain.filter((a) => a.num == trainNum);
|
case "Normal":
|
||||||
if (currentTrainData.length == 0) return customTrainData;
|
case "OneMan":
|
||||||
else if (currentTrainData[0].Type.includes("rapid:")) {
|
const currentTrainData = currentTrain.filter((a) => a.num == trainNum);
|
||||||
const typeText = currentTrainData[0].Type.split(":");
|
if (currentTrainData.length == 0) return customTrainData;
|
||||||
const returnData = {
|
else if (currentTrainData[0].Type.includes("rapid:")) {
|
||||||
type: "Rapid",
|
const typeText = currentTrainData[0].Type.split(":");
|
||||||
trainName: typeText[1].replace("\r", ""),
|
const returnData = {
|
||||||
trainIcon: null,
|
type: "Rapid",
|
||||||
trainNumDistance: null,
|
trainName: typeText[1].replace("\r", ""),
|
||||||
info: "",
|
trainIcon: null,
|
||||||
};
|
trainNumDistance: null,
|
||||||
return returnData;
|
info: "",
|
||||||
|
};
|
||||||
|
return returnData;
|
||||||
|
}
|
||||||
|
return customTrainData;
|
||||||
|
default:
|
||||||
|
return customTrainData;
|
||||||
}
|
}
|
||||||
return customTrainData;
|
|
||||||
};
|
};
|
||||||
const [train, setTrain] = useState(getTrainDataFromCurrentTrain(d.train));
|
const [train, setTrain] = useState(getTrainDataFromCurrentTrain(d.train));
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -89,35 +100,44 @@ export const EachData: FC<Props> = (props) => {
|
|||||||
}, [currentTrain, d.train, trainDescriptionSwitch]);
|
}, [currentTrain, d.train, trainDescriptionSwitch]);
|
||||||
// 土讃線複数存在対策
|
// 土讃線複数存在対策
|
||||||
const currentTrainData = checkDuplicateTrainData(
|
const currentTrainData = checkDuplicateTrainData(
|
||||||
currentTrain.filter((a) => a.num == d.train)
|
currentTrain.filter((a) => a.num == d.train),
|
||||||
|
stationList
|
||||||
);
|
);
|
||||||
const trainDelayStatus = `${getTrainDelayStatus(
|
const trainDelayStatus = `${getTrainDelayStatus(
|
||||||
currentTrainData,
|
currentTrainData,
|
||||||
station.Station_JP
|
station.Station_JP
|
||||||
)}`;
|
)}`;
|
||||||
const trainPositionText = (trainData: trainDataType) => {
|
|
||||||
const { isBetween, Pos } = trainPosition(trainData);
|
|
||||||
if (isBetween === true) return `現在地:${Pos.from}→${Pos.to}間を走行中`;
|
|
||||||
else return Pos.Pos == "" ? "" : `現在地:${Pos.Pos}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const [platformNumber, setPlatformNumber] = useState<number>();
|
const [platformNumber, setPlatformNumber] = useState<number>();
|
||||||
const [platformDescription, setPlatformDescription] = useState<string>();
|
const [platformDescription, setPlatformDescription] = useState<string>();
|
||||||
useEffect(() => {
|
|
||||||
fetch(
|
|
||||||
`https://n8n.haruk.in/webhook/JR-shikoku-PosID?PosNum=${currentTrainData?.PosNum}&Line=${currentTrainData?.Line}`
|
|
||||||
)
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((data) => {
|
|
||||||
setPlatformNumber(data?.type == "Station" ? data?.platform : undefined);
|
|
||||||
setPlatformDescription(
|
|
||||||
data?.type == "Station" ? data?.description : undefined
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}, [currentTrainData, currentTrain]);
|
|
||||||
|
|
||||||
|
const [dialog, setDialog] = useState(false);
|
||||||
|
const [deleteDialog, setDeleteDialog] = useState(false);
|
||||||
|
const [posInput, setPosInput] = useState("");
|
||||||
|
const [descInput, setDescInput] = useState("");
|
||||||
|
const [stationInput, setStationInput] = useState("");
|
||||||
|
const [stationNumberInput, setStationNumberInput] = useState("");
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<TrainPositionDataDelete
|
||||||
|
dialog={deleteDialog}
|
||||||
|
setDialog={setDeleteDialog}
|
||||||
|
currentTrainData={currentTrainData}
|
||||||
|
stationInput={stationInput}
|
||||||
|
stationNumberInput={stationNumberInput}
|
||||||
|
/>
|
||||||
|
<TrainPositionDataPush
|
||||||
|
dialog={dialog}
|
||||||
|
setDialog={setDialog}
|
||||||
|
currentTrainData={currentTrainData}
|
||||||
|
stationInput={stationInput}
|
||||||
|
stationNumberInput={stationNumberInput}
|
||||||
|
posInput={posInput}
|
||||||
|
descInput={descInput}
|
||||||
|
setPosInput={setPosInput}
|
||||||
|
setDescInput={setDescInput}
|
||||||
|
station={station}
|
||||||
|
/>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={{
|
style={{
|
||||||
alignContent: "center",
|
alignContent: "center",
|
||||||
@ -142,19 +162,20 @@ export const EachData: FC<Props> = (props) => {
|
|||||||
<StatusAndDelay trainDelayStatus={trainDelayStatus} />
|
<StatusAndDelay trainDelayStatus={trainDelayStatus} />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
{trainDescriptionSwitch && (
|
{trainDescriptionSwitch && (
|
||||||
<Description
|
<TrainPosition
|
||||||
info={`${
|
trainIDSwitch={trainIDSwitch}
|
||||||
trainIDSwitch
|
currentTrainData={currentTrainData}
|
||||||
? currentTrainData?.PosNum + currentTrainData?.Line
|
setStationInput={setStationInput}
|
||||||
: trainPositionText(currentTrainData)
|
setStationNumberInput={setStationNumberInput}
|
||||||
} ${platformNumber ? platformNumber + "番線" : ""} ${
|
setDescInput={setDescInput}
|
||||||
platformDescription ? "("+platformDescription+")" : ""
|
setPosInput={setPosInput}
|
||||||
}`}
|
setDialog={setDialog}
|
||||||
onLongClick={() => {
|
setDeleteDialog={setDeleteDialog}
|
||||||
Linking.openURL(
|
setPlatformDescription={setPlatformDescription}
|
||||||
"https://nexcloud.haruk.in/apps/forms/s/TEkBQW5WLcYjLyAzGxncQLtw"
|
setPlatformNumber={setPlatformNumber}
|
||||||
);
|
platformDescription={platformDescription}
|
||||||
}}
|
platformNumber={platformNumber}
|
||||||
|
key={d.train + "-trainPosition"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{trainDescriptionSwitch && !!train.info && (
|
{trainDescriptionSwitch && !!train.info && (
|
||||||
|
120
components/発車時刻表/LED_inside_Component/TrainPosition.tsx
Normal file
120
components/発車時刻表/LED_inside_Component/TrainPosition.tsx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
import React, { FC, useEffect } from "react";
|
||||||
|
import { Text, TextStyle, View, TouchableOpacity } from "react-native";
|
||||||
|
import { useStationList } from "../../../stateBox/useStationList";
|
||||||
|
import {
|
||||||
|
trainDataType,
|
||||||
|
trainPosition,
|
||||||
|
} from "../../../lib/trainPositionTextArray";
|
||||||
|
import { lineList } from "../../../lib/getStationList";
|
||||||
|
import { getStationID } from "../../../lib/eachTrainInfoCoreLib/getStationData";
|
||||||
|
import { useCurrentTrain } from "../../../stateBox/useCurrentTrain";
|
||||||
|
|
||||||
|
const descriptionStyle: TextStyle = {
|
||||||
|
fontSize: parseInt("16%"),
|
||||||
|
fontWeight: "bold",
|
||||||
|
};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
numberOfLines?: number;
|
||||||
|
trainIDSwitch: boolean;
|
||||||
|
currentTrainData: trainDataType;
|
||||||
|
setStationInput: (station: string) => void;
|
||||||
|
setStationNumberInput: (station: string) => void;
|
||||||
|
setDescInput: (desc: string) => void;
|
||||||
|
setPosInput: (pos: string) => void;
|
||||||
|
setDialog: (dialog: boolean) => void;
|
||||||
|
setDeleteDialog: (dialog: boolean) => void;
|
||||||
|
platformDescription: string;
|
||||||
|
platformNumber: number;
|
||||||
|
setPlatformDescription: (desc: string) => void;
|
||||||
|
setPlatformNumber: (num: number) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TrainPosition: FC<Props> = ({
|
||||||
|
numberOfLines = 0,
|
||||||
|
trainIDSwitch,
|
||||||
|
currentTrainData,
|
||||||
|
setStationInput,
|
||||||
|
setStationNumberInput,
|
||||||
|
setDescInput,
|
||||||
|
setPosInput,
|
||||||
|
setDialog,
|
||||||
|
setDeleteDialog,
|
||||||
|
setPlatformDescription,
|
||||||
|
setPlatformNumber,
|
||||||
|
platformDescription,
|
||||||
|
platformNumber,
|
||||||
|
}) => {
|
||||||
|
const { currentTrain } = useCurrentTrain();
|
||||||
|
const { stationList } = useStationList();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch(
|
||||||
|
`https://n8n.haruk.in/webhook/JR-shikoku-PosID?PosNum=${currentTrainData?.PosNum}&Line=${currentTrainData?.Line}`
|
||||||
|
)
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((data: { type: string; platform: number; description: string }) => {
|
||||||
|
setPlatformNumber(data?.type == "Station" ? data?.platform : undefined);
|
||||||
|
setPlatformDescription(
|
||||||
|
data?.type == "Station" ? data?.description : undefined
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}, [currentTrainData, currentTrain]);
|
||||||
|
|
||||||
|
const trainPositionText = (trainData: trainDataType) => {
|
||||||
|
const { isBetween, Pos } = trainPosition(trainData);
|
||||||
|
if (isBetween === true) return `現在地:${Pos.from}→${Pos.to}間を走行中`;
|
||||||
|
else return Pos.Pos == "" ? "" : `現在地:${Pos.Pos}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
alignContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
width: "94%",
|
||||||
|
marginVertical: 5,
|
||||||
|
marginHorizontal: "3%",
|
||||||
|
backgroundColor: "#000",
|
||||||
|
flexDirection: "row",
|
||||||
|
overflow: "hidden",
|
||||||
|
}}
|
||||||
|
onLongPress={() => {
|
||||||
|
const { isBetween, Pos } = trainPosition(currentTrainData);
|
||||||
|
if (isBetween === true) {
|
||||||
|
if (platformNumber == undefined && platformDescription == undefined)
|
||||||
|
return;
|
||||||
|
setStationInput(`${Pos.from}→${Pos.to}間`);
|
||||||
|
setStationNumberInput(
|
||||||
|
getStationID(currentTrainData?.Pos, stationList)
|
||||||
|
);
|
||||||
|
setPosInput(platformNumber?.toString() || "");
|
||||||
|
setDeleteDialog(true);
|
||||||
|
} else {
|
||||||
|
setStationInput(Pos.Pos);
|
||||||
|
setStationNumberInput(
|
||||||
|
getStationID(currentTrainData?.Pos, stationList)
|
||||||
|
);
|
||||||
|
setDescInput(platformDescription || "");
|
||||||
|
setPosInput(platformNumber?.toString() || "");
|
||||||
|
setDialog(true);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<View style={{ flex: 4, flexDirection: "row" }}>
|
||||||
|
<Text
|
||||||
|
style={{ ...descriptionStyle, color: "green" }}
|
||||||
|
numberOfLines={numberOfLines}
|
||||||
|
>
|
||||||
|
{`${
|
||||||
|
trainIDSwitch
|
||||||
|
? currentTrainData?.PosNum + currentTrainData?.Line
|
||||||
|
: trainPositionText(currentTrainData)
|
||||||
|
} ${platformNumber ? platformNumber + "番線" : ""} ${
|
||||||
|
platformDescription ? "(" + platformDescription + ")" : ""
|
||||||
|
}`}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,46 @@
|
|||||||
|
import React, { FC } from "react";
|
||||||
|
import { Text } from "react-native";
|
||||||
|
import { Dialog, Button } from "react-native-elements";
|
||||||
|
import { trainDataType } from "../../../lib/trainPositionTextArray";
|
||||||
|
type Props = {
|
||||||
|
dialog: boolean;
|
||||||
|
setDialog: (dialog: boolean) => void;
|
||||||
|
currentTrainData: trainDataType;
|
||||||
|
stationInput: string;
|
||||||
|
stationNumberInput: string;
|
||||||
|
};
|
||||||
|
export const TrainPositionDataDelete: FC<Props> = ({
|
||||||
|
dialog,
|
||||||
|
setDialog,
|
||||||
|
currentTrainData,
|
||||||
|
stationInput,
|
||||||
|
stationNumberInput,
|
||||||
|
}) => {
|
||||||
|
const sendPlatformData = () => {
|
||||||
|
fetch(`https://n8n.haruk.in/webhook/JR-shikoku-PosID`, {
|
||||||
|
method: "DELETE",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({
|
||||||
|
PosId: currentTrainData?.PosNum,
|
||||||
|
lineName: currentTrainData?.Line,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
alert("位置情報データ削除要求を送信しました。");
|
||||||
|
setDialog(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
alert("位置情報データ削除要求の送信に失敗しました。");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Dialog isVisible={dialog} onBackdropPress={() => setDialog(false)}>
|
||||||
|
<Text>以下のデータを誤情報として削除要求を出しますか?</Text>
|
||||||
|
<Text>路線: {currentTrainData?.Line}</Text>
|
||||||
|
<Text>地点ID: {currentTrainData?.PosNum}</Text>
|
||||||
|
<Text>駅名: {stationInput}</Text>
|
||||||
|
<Text>駅ナンバー: {stationNumberInput}</Text>
|
||||||
|
<Button title="送信" onPress={sendPlatformData} />
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,77 @@
|
|||||||
|
import React, { FC, useState } from "react";
|
||||||
|
import { Text } from "react-native";
|
||||||
|
import { Dialog, Input, Button } from "react-native-elements";
|
||||||
|
import { trainDataType } from "../../../lib/trainPositionTextArray";
|
||||||
|
import { useCurrentTrain } from "../../../stateBox/useCurrentTrain";
|
||||||
|
type Props = {
|
||||||
|
dialog: boolean;
|
||||||
|
setDialog: (dialog: boolean) => void;
|
||||||
|
currentTrainData: trainDataType;
|
||||||
|
stationInput: string;
|
||||||
|
stationNumberInput: string;
|
||||||
|
posInput: string;
|
||||||
|
descInput: string;
|
||||||
|
setPosInput: (pos: string) => void;
|
||||||
|
setDescInput: (desc: string) => void;
|
||||||
|
station: {
|
||||||
|
Station_JP: string;
|
||||||
|
StationNumber: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export const TrainPositionDataPush: FC<Props> = ({
|
||||||
|
dialog,
|
||||||
|
setDialog,
|
||||||
|
currentTrainData,
|
||||||
|
stationInput,
|
||||||
|
stationNumberInput,
|
||||||
|
posInput,
|
||||||
|
descInput,
|
||||||
|
setPosInput,
|
||||||
|
setDescInput,
|
||||||
|
station,
|
||||||
|
}) => {
|
||||||
|
const sendPlatformData = () => {
|
||||||
|
fetch(`https://n8n.haruk.in/webhook/JR-shikoku-PosID`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({
|
||||||
|
PosId: currentTrainData?.PosNum,
|
||||||
|
lineName: currentTrainData?.Line,
|
||||||
|
PlatformNum: parseInt(posInput),
|
||||||
|
Description: descInput,
|
||||||
|
StationName: station.Station_JP,
|
||||||
|
StationId: station.StationNumber,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
alert("位置情報データを送信しました。");
|
||||||
|
setDialog(false);
|
||||||
|
setPosInput("");
|
||||||
|
setDescInput("");
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
alert("位置情報データの送信に失敗しました。");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Dialog isVisible={dialog} onBackdropPress={() => setDialog(false)}>
|
||||||
|
<Text>路線: {currentTrainData?.Line}</Text>
|
||||||
|
<Text>地点ID: {currentTrainData?.PosNum}</Text>
|
||||||
|
<Text>駅名: {stationInput}</Text>
|
||||||
|
<Text>駅ナンバー: {stationNumberInput}</Text>
|
||||||
|
<Input
|
||||||
|
label="番線"
|
||||||
|
inputMode="numeric"
|
||||||
|
value={posInput}
|
||||||
|
onChangeText={setPosInput}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
label="参考情報"
|
||||||
|
inputMode="text"
|
||||||
|
value={descInput}
|
||||||
|
onChangeText={setDescInput}
|
||||||
|
/>
|
||||||
|
<Button title="送信" onPress={sendPlatformData} />
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
@ -206,6 +206,7 @@ export default function LED_vision(props) {
|
|||||||
openStationACFromEachTrainInfo,
|
openStationACFromEachTrainInfo,
|
||||||
}}
|
}}
|
||||||
station={station[0]}
|
station={station[0]}
|
||||||
|
key={d.train}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{areaString != "" && isInfoArea && (
|
{areaString != "" && isInfoArea && (
|
||||||
|
@ -1 +1 @@
|
|||||||
export const news = "2024-11-22";
|
export const news = "2025-01-09";
|
||||||
|
10
howto.js
10
howto.js
@ -2,11 +2,17 @@ import React from "react";
|
|||||||
import { View } from "react-native";
|
import { View } from "react-native";
|
||||||
import { WebView } from "react-native-webview";
|
import { WebView } from "react-native-webview";
|
||||||
import { BigButton } from "./components/atom/BigButton";
|
import { BigButton } from "./components/atom/BigButton";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
export default ({ navigation: { navigate }, route }) => {
|
export default ({ navigation: { navigate }, route }) => {
|
||||||
const { info, goTo, useShow } = route.params;
|
const { info, goTo, useShow } = route.params;
|
||||||
|
const { goBack } = useNavigation();
|
||||||
const onExit = () => {
|
const onExit = () => {
|
||||||
navigate(goTo || "Apps");
|
if(goTo != "NearTrainDiagramView") {
|
||||||
useShow && useShow();
|
navigate(goTo || "Apps");
|
||||||
|
useShow && useShow();
|
||||||
|
} else {
|
||||||
|
goBack();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<View style={styles}>
|
<View style={styles}>
|
||||||
|
@ -1,8 +1,71 @@
|
|||||||
import { trainDataType } from "./trainPositionTextArray";
|
import { trainDataType } from "./trainPositionTextArray";
|
||||||
|
import { getStationID } from "./eachTrainInfoCoreLib/getStationData";
|
||||||
|
import { stationIDPair } from "../lib/getStationList2";
|
||||||
|
|
||||||
export const checkDuplicateTrainData = (currentTrainArray: trainDataType[]) => {
|
export const checkDuplicateTrainData = (
|
||||||
const notNyujoData = currentTrainArray.filter((d) => d.delay !== "入線");
|
currentTrainArray: trainDataType[],
|
||||||
|
stationList: any[]
|
||||||
|
) => {
|
||||||
|
const notSameLineData = checkSameTrain(currentTrainArray, stationList);
|
||||||
|
const notNyujoData = notSameLineData.filter((d) => d.delay !== "入線");
|
||||||
if (currentTrainArray.length == 1) return currentTrainArray[0];
|
if (currentTrainArray.length == 1) return currentTrainArray[0];
|
||||||
if (notNyujoData.length == 0) return currentTrainArray[0];
|
if (notNyujoData.length == 0) return currentTrainArray[0];
|
||||||
else return notNyujoData[0];
|
else return notNyujoData[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 二つのデータを比較して、正しい路線を反映しているデータだけを返す関数
|
||||||
|
const checkSameTrain = (
|
||||||
|
currentTrainArray: trainDataType[],
|
||||||
|
stationList: any[]
|
||||||
|
) => {
|
||||||
|
const trueLineData = currentTrainArray
|
||||||
|
.map((d) => {
|
||||||
|
if (d.Pos.match("~")) {
|
||||||
|
const [topST, downST] = d.Pos.replace("(下り)", "")
|
||||||
|
.replace("(上り)", "")
|
||||||
|
.split("~");
|
||||||
|
const stopStationList = [topST, downST].map((i) => {
|
||||||
|
return stationList.map((a) => a.filter((d) => d.StationName == i));
|
||||||
|
});
|
||||||
|
const x = stopStationList.map((i, index, array) => {
|
||||||
|
if (index == array.length - 1) return;
|
||||||
|
|
||||||
|
const firstItem = array[index];
|
||||||
|
const secondItem = array[index + 1];
|
||||||
|
let betweenStationLine = "";
|
||||||
|
let baseStationNumberFirst = "";
|
||||||
|
let baseStationNumberSecond = "";
|
||||||
|
Object.keys(stationIDPair).forEach((d, index2, array) => {
|
||||||
|
if (!d) return;
|
||||||
|
const haveFirst = firstItem[index2];
|
||||||
|
const haveSecond = secondItem[index2];
|
||||||
|
if (haveFirst.length && haveSecond.length) {
|
||||||
|
betweenStationLine = d;
|
||||||
|
baseStationNumberFirst = haveFirst[0].StationNumber;
|
||||||
|
baseStationNumberSecond = haveSecond[0].StationNumber;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return betweenStationLine;
|
||||||
|
});
|
||||||
|
return x;
|
||||||
|
} else {
|
||||||
|
const ST = d.Pos.replace("(下り)", "").replace("(上り)", "");
|
||||||
|
const stopStationList = stationList.map((a) =>
|
||||||
|
a.filter((d) => d.StationName == ST)
|
||||||
|
);
|
||||||
|
|
||||||
|
const string = Object.keys(stationIDPair).map((d, index2, array) => {
|
||||||
|
if (!d) return;
|
||||||
|
if (!stopStationList[index2].length) return;
|
||||||
|
return d;
|
||||||
|
});
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map((x) => x.filter((d) => d != undefined));
|
||||||
|
const returnData = currentTrainArray.filter((d, index) => {
|
||||||
|
return d.Line == trueLineData[index][0];
|
||||||
|
});
|
||||||
|
return returnData;
|
||||||
|
};
|
||||||
|
@ -12,6 +12,7 @@ type trainTypeString =
|
|||||||
| "寝台特急"
|
| "寝台特急"
|
||||||
| "臨時"
|
| "臨時"
|
||||||
| "普通列車"
|
| "普通列車"
|
||||||
|
| "普通列車(ワンマン)"
|
||||||
| "その他";
|
| "その他";
|
||||||
type trainTypeDataString = "rapid" | "express" | "normal";
|
type trainTypeDataString = "rapid" | "express" | "normal";
|
||||||
type getTrainType = (d: nameString) => {
|
type getTrainType = (d: nameString) => {
|
||||||
@ -29,6 +30,8 @@ export const getTrainType: getTrainType = (nameString) => {
|
|||||||
return { color: "red", name: "寝台特急", data: "express" };
|
return { color: "red", name: "寝台特急", data: "express" };
|
||||||
case "SPCL":
|
case "SPCL":
|
||||||
return { color: "blue", name: "臨時", data: "normal" };
|
return { color: "blue", name: "臨時", data: "normal" };
|
||||||
|
case "OneMan":
|
||||||
|
return { color: "white", name: "普通列車(ワンマン)", data: "normal" };
|
||||||
case "Normal":
|
case "Normal":
|
||||||
return { color: "white", name: "普通列車", data: "normal" };
|
return { color: "white", name: "普通列車", data: "normal" };
|
||||||
default:
|
default:
|
||||||
|
4
menu.js
4
menu.js
@ -362,10 +362,10 @@ const JRSTraInfoBox = () => {
|
|||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
) : delayData ? (
|
) : delayData ? (
|
||||||
delayData.map((d) => {
|
delayData.map((d,index,array) => {
|
||||||
let data = d.split(" ");
|
let data = d.split(" ");
|
||||||
return (
|
return (
|
||||||
<View style={{ flexDirection: "row" }} key={data[1] + "key"}>
|
<View style={{ flexDirection: "row" }} key={data[1] + "key"+index}>
|
||||||
<Text style={{ flex: 15, fontSize: 18 }}>
|
<Text style={{ flex: 15, fontSize: 18 }}>
|
||||||
{data[0].replace("\n", "")}
|
{data[0].replace("\n", "")}
|
||||||
</Text>
|
</Text>
|
||||||
|
143
stateBox/useNotifications.tsx
Normal file
143
stateBox/useNotifications.tsx
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
import React, {
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
FC,
|
||||||
|
useRef,
|
||||||
|
} from "react";
|
||||||
|
// 6.0でライブラリ変更
|
||||||
|
import { Platform, Clipboard } from "react-native";
|
||||||
|
// 6.0でライブラリ更新、tsの型定義が変わった
|
||||||
|
import * as Notifications from "expo-notifications";
|
||||||
|
import * as Device from "expo-device";
|
||||||
|
import Constants from "expo-constants";
|
||||||
|
type initialStateType = {
|
||||||
|
expoPushToken: string;
|
||||||
|
};
|
||||||
|
const initialState = {
|
||||||
|
expoPushToken: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
Notifications.setNotificationHandler({
|
||||||
|
handleNotification: async () => ({
|
||||||
|
shouldShowAlert: true,
|
||||||
|
shouldPlaySound: true,
|
||||||
|
shouldSetBadge: true,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleRegistrationError(errorMessage: string) {
|
||||||
|
console.log(errorMessage);
|
||||||
|
//throw new Error(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function registerForPushNotificationsAsync() {
|
||||||
|
if (Platform.OS === "android") {
|
||||||
|
Notifications.setNotificationChannelAsync("default", {
|
||||||
|
name: "default",
|
||||||
|
importance: Notifications.AndroidImportance.MAX,
|
||||||
|
vibrationPattern: [0, 250, 250, 250],
|
||||||
|
lightColor: "#FF231F7C",
|
||||||
|
});
|
||||||
|
Notifications.setNotificationChannelAsync("運行情報", {
|
||||||
|
name: "運行情報",
|
||||||
|
importance: Notifications.AndroidImportance.MAX,
|
||||||
|
vibrationPattern: [0, 250, 250, 250],
|
||||||
|
lightColor: "#FF231F7C",
|
||||||
|
});
|
||||||
|
Notifications.setNotificationChannelAsync("遅延速報EX", {
|
||||||
|
name: "遅延速報EX",
|
||||||
|
importance: Notifications.AndroidImportance.MAX,
|
||||||
|
vibrationPattern: [0, 250, 250, 250],
|
||||||
|
lightColor: "#FF231F7C",
|
||||||
|
});
|
||||||
|
Notifications.setNotificationChannelAsync("怪レい列車BOT", {
|
||||||
|
name: "怪レい列車BOT",
|
||||||
|
importance: Notifications.AndroidImportance.MAX,
|
||||||
|
vibrationPattern: [0, 250, 250, 250],
|
||||||
|
lightColor: "#FF231F7C",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Device.isDevice) {
|
||||||
|
const { status: existingStatus } =
|
||||||
|
await Notifications.getPermissionsAsync();
|
||||||
|
let finalStatus = existingStatus;
|
||||||
|
if (existingStatus !== "granted") {
|
||||||
|
const { status } = await Notifications.requestPermissionsAsync();
|
||||||
|
finalStatus = status;
|
||||||
|
}
|
||||||
|
if (finalStatus !== "granted") {
|
||||||
|
handleRegistrationError(
|
||||||
|
"Permission not granted to get push token for push notification!"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const projectId =
|
||||||
|
Constants?.expoConfig?.extra?.eas?.projectId ??
|
||||||
|
Constants?.easConfig?.projectId;
|
||||||
|
if (!projectId) {
|
||||||
|
handleRegistrationError("Project ID not found");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const pushTokenString = (
|
||||||
|
await Notifications.getExpoPushTokenAsync({
|
||||||
|
projectId,
|
||||||
|
})
|
||||||
|
).data;
|
||||||
|
console.log(pushTokenString);
|
||||||
|
return pushTokenString;
|
||||||
|
} catch (e) {
|
||||||
|
handleRegistrationError(`${e}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
handleRegistrationError("Must use physical device for push notifications");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const NotificationContext = createContext<initialStateType>(initialState);
|
||||||
|
type Props = {
|
||||||
|
children: React.ReactNode;
|
||||||
|
};
|
||||||
|
export const useNotification = () => {
|
||||||
|
return useContext(NotificationContext);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const NotificationProvider: FC<Props> = ({ children }) => {
|
||||||
|
const [expoPushToken, setExpoPushToken] = useState("");
|
||||||
|
const [notification, setNotification] = useState<
|
||||||
|
Notifications.Notification | undefined
|
||||||
|
>(undefined);
|
||||||
|
const notificationListener = useRef<Notifications.EventSubscription>();
|
||||||
|
const responseListener = useRef<Notifications.EventSubscription>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
registerForPushNotificationsAsync()
|
||||||
|
.then((token) => setExpoPushToken(token ?? ""))
|
||||||
|
.catch((error) => setExpoPushToken(`${error}`));
|
||||||
|
|
||||||
|
notificationListener.current =
|
||||||
|
Notifications.addNotificationReceivedListener((notification) => {
|
||||||
|
setNotification(notification);
|
||||||
|
});
|
||||||
|
|
||||||
|
responseListener.current =
|
||||||
|
Notifications.addNotificationResponseReceivedListener((response) => {
|
||||||
|
console.log(response);
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
notificationListener.current &&
|
||||||
|
Notifications.removeNotificationSubscription(
|
||||||
|
notificationListener.current
|
||||||
|
);
|
||||||
|
responseListener.current &&
|
||||||
|
Notifications.removeNotificationSubscription(responseListener.current);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<NotificationContext.Provider value={{ expoPushToken }}>
|
||||||
|
{children}
|
||||||
|
</NotificationContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
@ -6,16 +6,19 @@ import React, {
|
|||||||
FC,
|
FC,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { getStationList } from "../lib/getStationList";
|
import { getStationList } from "../lib/getStationList";
|
||||||
|
import { lineList } from "../lib/getStationList";
|
||||||
|
|
||||||
type initialStateType = {
|
type initialStateType = {
|
||||||
originalStationList: any[];
|
originalStationList: any[][];
|
||||||
setOriginalStationList: React.Dispatch<React.SetStateAction<any[]>>;
|
setOriginalStationList: React.Dispatch<React.SetStateAction<any[]>>;
|
||||||
getStationData: (id: string) => void;
|
getStationData: (id: string) => void;
|
||||||
|
stationList: any[];
|
||||||
};
|
};
|
||||||
const initialState = {
|
const initialState = {
|
||||||
originalStationList: [],
|
originalStationList: [[]],
|
||||||
setOriginalStationList: () => {},
|
setOriginalStationList: () => {},
|
||||||
getStationData: () => {},
|
getStationData: () => {},
|
||||||
|
stationList: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const StationListContext = createContext<initialStateType>(initialState);
|
const StationListContext = createContext<initialStateType>(initialState);
|
||||||
@ -42,10 +45,23 @@ export const StationListProvider: FC<Props> = ({ children }) => {
|
|||||||
});
|
});
|
||||||
return returnArray;
|
return returnArray;
|
||||||
};
|
};
|
||||||
|
const [stationList, setStationList] = useState<any[][]>([[]]);
|
||||||
|
useEffect(()=>{
|
||||||
|
if(originalStationList.length === 0) return;
|
||||||
|
const stationList =
|
||||||
|
originalStationList &&
|
||||||
|
lineList.map((d) =>
|
||||||
|
originalStationList[d].map((a) => ({
|
||||||
|
StationNumber: a.StationNumber,
|
||||||
|
StationName: a.Station_JP,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
setStationList(stationList)
|
||||||
|
},[originalStationList])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StationListContext.Provider
|
<StationListContext.Provider
|
||||||
value={{ originalStationList, setOriginalStationList, getStationData }}
|
value={{ originalStationList, setOriginalStationList, getStationData, stationList }}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</StationListContext.Provider>
|
</StationListContext.Provider>
|
||||||
|
@ -72,6 +72,7 @@ export const TrainMenuProvider = ({ children }) => {
|
|||||||
//列車アイコンスイッチ
|
//列車アイコンスイッチ
|
||||||
ASCore({ k: "iconSwitch", s: setIconSetting, d: "true", u: true });
|
ASCore({ k: "iconSwitch", s: setIconSetting, d: "true", u: true });
|
||||||
//地図スイッチ
|
//地図スイッチ
|
||||||
|
//6.0.0以降true
|
||||||
ASCore({ k: "mapSwitch", s: setMapSwitch, d: "false", u: true });
|
ASCore({ k: "mapSwitch", s: setMapSwitch, d: "false", u: true });
|
||||||
//駅メニュースイッチ
|
//駅メニュースイッチ
|
||||||
ASCore({ k: "stationSwitch", s: setStationMenu, d: "true", u: true });
|
ASCore({ k: "stationSwitch", s: setStationMenu, d: "true", u: true });
|
||||||
|
Loading…
Reference in New Issue
Block a user