Compare commits
119 Commits
5cda45740c
...
70976c0554
Author | SHA1 | Date | |
---|---|---|---|
|
70976c0554 | ||
|
8a7285bb20 | ||
|
efc1631a78 | ||
|
b512efd3ec | ||
|
54fba616b5 | ||
|
59d7d425e5 | ||
|
934f9ce2c2 | ||
|
d586bc562f | ||
|
72e7894725 | ||
|
3da4986a7c | ||
|
249f09bbc7 | ||
|
9478f2df8d | ||
|
6b39a3f723 | ||
|
caa4694c94 | ||
|
fdea8be0b4 | ||
|
36ac66df3e | ||
|
156912302d | ||
|
67d2bf6c98 | ||
|
19db27a378 | ||
|
012544beeb | ||
|
218f9d5093 | ||
|
65123424a3 | ||
|
28b23efc5e | ||
|
3488c5e8d5 | ||
|
bb41118e39 | ||
|
d8453608c9 | ||
|
e6430c27a6 | ||
|
570a55f430 | ||
|
c98407527b | ||
|
b143e4251d | ||
|
c526055dda | ||
|
61aca4c75e | ||
|
c92f02fa0e | ||
|
8e7ccba5cc | ||
|
ed6f00f3fd | ||
|
7500aaa66f | ||
|
b5b9558136 | ||
|
7b4badb9b0 | ||
|
dfc2fa5c89 | ||
|
f2d49cbbf2 | ||
|
c8356fad2f | ||
|
5c143779e2 | ||
|
a7ccb0b41f | ||
|
c0f7a9b931 | ||
|
a305aa7202 | ||
|
45b41dcef0 | ||
|
0ce2b70669 | ||
|
6ad46c0e63 | ||
|
c43778c3c5 | ||
|
7395c7e8f4 | ||
|
af30d1cbb0 | ||
|
aefbf68401 | ||
|
c52cb1c91f | ||
|
52ca9d03a8 | ||
|
0d595c7f67 | ||
|
d6b701bdb1 | ||
|
59082c7873 | ||
|
2f65cd6a6f | ||
|
73ed5480c1 | ||
|
6a58263e94 | ||
|
7ca4cf95e6 | ||
|
c41c61bba7 | ||
|
a0f1c64041 | ||
|
44e542c0f1 | ||
|
5616c7ed96 | ||
|
8212148fb2 | ||
|
7500582165 | ||
|
d5cfe06086 | ||
|
1795ab274b | ||
|
0206bb4cf8 | ||
|
e9f845f448 | ||
|
611f233361 | ||
|
31bf3a7228 | ||
|
13580a57d4 | ||
|
bd2248e1a9 | ||
|
8c17a5b3da | ||
|
fbcded3d23 | ||
|
b3cc5b6ede | ||
|
85de99e32d | ||
|
c9481fb0c2 | ||
|
fa758c144f | ||
|
99ba90f324 | ||
|
427e06967c | ||
|
f26da93193 | ||
|
015e4e54ed | ||
|
7232c40af1 | ||
|
35bb460b54 | ||
|
748350178d | ||
|
2c505c4b17 | ||
|
6d51db98fa | ||
|
ac06ca6c75 | ||
|
3b98882d80 | ||
|
f922edb973 | ||
|
97a6bbc619 | ||
|
934938287d | ||
|
44f8be994e | ||
|
cf025d3add | ||
|
190be0fa67 | ||
|
5ef720f475 | ||
|
fdacc00f93 | ||
|
49ed69d541 | ||
|
bb0ae86f67 | ||
|
b108029868 | ||
|
27dde29010 | ||
|
38dc92ab37 | ||
|
b64138178c | ||
|
577e793af9 | ||
|
423625c08a | ||
|
99831e8d39 | ||
|
95bad60631 | ||
|
db2547028d | ||
|
e6c0fe94c0 | ||
|
715c0ddf94 | ||
|
d059798f85 | ||
|
62e9a43f2b | ||
|
9bf047bff0 | ||
|
c5e76a9a7a | ||
|
9ba1f5d50b | ||
|
6fbaf2b8ff |
4
App.js
4
App.js
@@ -18,6 +18,7 @@ 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";
|
import { NotificationProvider } from "./stateBox/useNotifications";
|
||||||
|
import { UserPositionProvider } from "./stateBox/useUserPosition";
|
||||||
|
|
||||||
LogBox.ignoreLogs([
|
LogBox.ignoreLogs([
|
||||||
"ViewPropTypes will be removed",
|
"ViewPropTypes will be removed",
|
||||||
@@ -34,13 +35,14 @@ export default function App() {
|
|||||||
useEffect(() => UpdateAsync(), []);
|
useEffect(() => UpdateAsync(), []);
|
||||||
|
|
||||||
const ProviderTree = buildProvidersTree([
|
const ProviderTree = buildProvidersTree([
|
||||||
|
AllTrainDiagramProvider,
|
||||||
NotificationProvider,
|
NotificationProvider,
|
||||||
|
UserPositionProvider,
|
||||||
StationListProvider,
|
StationListProvider,
|
||||||
FavoriteStationProvider,
|
FavoriteStationProvider,
|
||||||
TrainDelayDataProvider,
|
TrainDelayDataProvider,
|
||||||
CurrentTrainProvider,
|
CurrentTrainProvider,
|
||||||
AreaInfoProvider,
|
AreaInfoProvider,
|
||||||
AllTrainDiagramProvider,
|
|
||||||
BusAndTrainDataProvider,
|
BusAndTrainDataProvider,
|
||||||
TrainMenuProvider,
|
TrainMenuProvider,
|
||||||
SheetProvider,
|
SheetProvider,
|
||||||
|
30
GeneralWebView.tsx
Normal file
30
GeneralWebView.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import React, { CSSProperties } from "react";
|
||||||
|
import { View, ViewProps } from "react-native";
|
||||||
|
import { WebView } from "react-native-webview";
|
||||||
|
import { BigButton } from "./components/atom/BigButton";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
export default ({ route }) => {
|
||||||
|
if (!route.params) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const { uri, useExitButton = true } = route.params;
|
||||||
|
const { goBack } = useNavigation();
|
||||||
|
return (
|
||||||
|
<View style={styles}>
|
||||||
|
<WebView
|
||||||
|
useWebKit
|
||||||
|
source={{ uri }}
|
||||||
|
onMessage={(event) => {
|
||||||
|
const { data } = event.nativeEvent;
|
||||||
|
const {type} = JSON.parse(data);
|
||||||
|
if (type === "windowClose") return goBack();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{useExitButton && <BigButton onPress={goBack} string="閉じる" />}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
const styles: ViewProps["style"] = {
|
||||||
|
height: "100%",
|
||||||
|
backgroundColor: "#0099CC",
|
||||||
|
};
|
52
MenuPage.js
52
MenuPage.js
@@ -1,5 +1,10 @@
|
|||||||
import React, { useEffect } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { createStackNavigator } from "@react-navigation/stack";
|
import { createStackNavigator } from "@react-navigation/stack";
|
||||||
|
import { useWindowDimensions, Platform } from "react-native";
|
||||||
|
import Constants from "expo-constants";
|
||||||
|
|
||||||
|
import { Dimensions, StatusBar } from "react-native";
|
||||||
|
|
||||||
import { SheetManager } from "react-native-actions-sheet";
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
import { AS } from "./storageControl";
|
import { AS } from "./storageControl";
|
||||||
import TrainBase from "./components/trainbaseview";
|
import TrainBase from "./components/trainbaseview";
|
||||||
@@ -10,14 +15,16 @@ import Setting from "./components/Settings/settings";
|
|||||||
import { useFavoriteStation } from "./stateBox/useFavoriteStation";
|
import { useFavoriteStation } from "./stateBox/useFavoriteStation";
|
||||||
import { optionData } from "./lib/stackOption";
|
import { optionData } from "./lib/stackOption";
|
||||||
import AllTrainDiagramView from "./components/AllTrainDiagramView";
|
import AllTrainDiagramView from "./components/AllTrainDiagramView";
|
||||||
import { useCurrentTrain } from "./stateBox/useCurrentTrain";
|
|
||||||
import { useNavigation } from "@react-navigation/native";
|
import { useNavigation } from "@react-navigation/native";
|
||||||
import { news } from "./config/newsUpdate";
|
import { news } from "./config/newsUpdate";
|
||||||
|
import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs";
|
||||||
|
import GeneralWebView from "./GeneralWebView";
|
||||||
const Stack = createStackNavigator();
|
const Stack = createStackNavigator();
|
||||||
|
|
||||||
export function MenuPage() {
|
export function MenuPage() {
|
||||||
const { favoriteStation, setFavoriteStation } = useFavoriteStation();
|
const { favoriteStation, setFavoriteStation } = useFavoriteStation();
|
||||||
const { getCurrentTrain } = useCurrentTrain();
|
const { height, width } = useWindowDimensions();
|
||||||
|
const tabBarHeight = useBottomTabBarHeight();
|
||||||
const navigation = useNavigation();
|
const navigation = useNavigation();
|
||||||
const { addListener } = navigation;
|
const { addListener } = navigation;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -42,8 +49,34 @@ export function MenuPage() {
|
|||||||
})
|
})
|
||||||
.catch((error) => console.error("Error fetching icon setting:", error));
|
.catch((error) => console.error("Error fetching icon setting:", error));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const scrollRef = useRef(null);
|
||||||
|
const [mapMode, setMapMode] = useState(false);
|
||||||
|
const [mapHeight, setMapHeight] = useState(0);
|
||||||
|
useEffect(() => {
|
||||||
|
const MapHeight =
|
||||||
|
height -
|
||||||
|
tabBarHeight +
|
||||||
|
(Platform.OS == "android" ? Constants.statusBarHeight : 0) -
|
||||||
|
100 -
|
||||||
|
((((width / 100) * 80) / 20) * 9 + 10 + 30);
|
||||||
|
setMapHeight(MapHeight);
|
||||||
|
}, [height, tabBarHeight, width]);
|
||||||
|
const [MapFullHeight, setMapFullHeight] = useState(0);
|
||||||
|
useEffect(() => {
|
||||||
|
const MapFullHeight =
|
||||||
|
height -
|
||||||
|
tabBarHeight +
|
||||||
|
(Platform.OS == "android" ? Constants.statusBarHeight : 0);
|
||||||
|
setMapFullHeight(MapFullHeight);
|
||||||
|
}, [height, tabBarHeight, width]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unsubscribe = addListener("tabPress", (e) => {
|
const unsubscribe = addListener("tabPress", (e) => {
|
||||||
|
scrollRef.current.scrollTo({
|
||||||
|
y: mapHeight - 80,
|
||||||
|
animated: true,
|
||||||
|
});
|
||||||
|
setMapMode(false);
|
||||||
AS.getItem("favoriteStation")
|
AS.getItem("favoriteStation")
|
||||||
.then((d) => {
|
.then((d) => {
|
||||||
const returnData = JSON.parse(d);
|
const returnData = JSON.parse(d);
|
||||||
@@ -55,7 +88,7 @@ export function MenuPage() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return unsubscribe;
|
return unsubscribe;
|
||||||
}, [navigation]);
|
}, [navigation, mapHeight]);
|
||||||
return (
|
return (
|
||||||
<Stack.Navigator>
|
<Stack.Navigator>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
@@ -65,7 +98,15 @@ export function MenuPage() {
|
|||||||
gestureEnabled: true,
|
gestureEnabled: true,
|
||||||
headerTransparent: true,
|
headerTransparent: true,
|
||||||
}}
|
}}
|
||||||
children={() => <Menu getCurrentTrain={getCurrentTrain} />}
|
children={() => (
|
||||||
|
<Menu
|
||||||
|
scrollRef={scrollRef}
|
||||||
|
mapHeight={mapHeight}
|
||||||
|
MapFullHeight={MapFullHeight}
|
||||||
|
mapMode={mapMode}
|
||||||
|
setMapMode={setMapMode}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
<Stack.Screen name="news" options={optionData} component={News} />
|
<Stack.Screen name="news" options={optionData} component={News} />
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
@@ -88,6 +129,7 @@ export function MenuPage() {
|
|||||||
component={AllTrainDiagramView}
|
component={AllTrainDiagramView}
|
||||||
/>
|
/>
|
||||||
<Stack.Screen name="howto" options={optionData} component={HowTo} />
|
<Stack.Screen name="howto" options={optionData} component={HowTo} />
|
||||||
|
<Stack.Screen name="generalWebView" options={optionData} component={GeneralWebView} />
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
6
Top.js
6
Top.js
@@ -13,13 +13,14 @@ import { useTrainMenu } from "./stateBox/useTrainMenu";
|
|||||||
import { AS } from "./storageControl";
|
import { AS } from "./storageControl";
|
||||||
import { news } from "./config/newsUpdate";
|
import { news } from "./config/newsUpdate";
|
||||||
import { Linking, Platform } from "react-native";
|
import { Linking, Platform } from "react-native";
|
||||||
|
import GeneralWebView from "./GeneralWebView";
|
||||||
const Stack = createStackNavigator();
|
const Stack = createStackNavigator();
|
||||||
export const Top = () => {
|
export const Top = () => {
|
||||||
const { webview } = useCurrentTrain();
|
const { webview } = useCurrentTrain();
|
||||||
const { navigate, addListener, isFocused } = useNavigation();
|
const { navigate, addListener, isFocused } = useNavigation();
|
||||||
|
|
||||||
//地図用
|
//地図用
|
||||||
const { injectJavaScript, mapSwitch } = useTrainMenu();
|
const { mapSwitch } = useTrainMenu();
|
||||||
|
|
||||||
const goToFavoriteList = () =>
|
const goToFavoriteList = () =>
|
||||||
navigate("positions", { screen: "favoriteList" });
|
navigate("positions", { screen: "favoriteList" });
|
||||||
@@ -44,7 +45,7 @@ export const Top = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unsubscribe = addListener("tabPress", goToTrainMenu);
|
const unsubscribe = addListener("tabPress", goToTrainMenu);
|
||||||
return unsubscribe;
|
return unsubscribe;
|
||||||
}, [addListener, mapSwitch, injectJavaScript]);
|
}, [addListener, mapSwitch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack.Navigator detachInactiveScreens={false}>
|
<Stack.Navigator detachInactiveScreens={false}>
|
||||||
@@ -64,6 +65,7 @@ export const Top = () => {
|
|||||||
component={TrainBase}
|
component={TrainBase}
|
||||||
/>
|
/>
|
||||||
<Stack.Screen name="howto" options={optionData} component={HowTo} />
|
<Stack.Screen name="howto" options={optionData} component={HowTo} />
|
||||||
|
<Stack.Screen name="generalWebView" options={optionData} component={GeneralWebView} />
|
||||||
<Stack.Screen name="news" options={optionData} component={News} />
|
<Stack.Screen name="news" options={optionData} component={News} />
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
name="trainMenu"
|
name="trainMenu"
|
||||||
|
4
app.json
4
app.json
@@ -7,7 +7,7 @@
|
|||||||
"android",
|
"android",
|
||||||
"web"
|
"web"
|
||||||
],
|
],
|
||||||
"version": "6.0.1",
|
"version": "6.0.2",
|
||||||
"orientation": "default",
|
"orientation": "default",
|
||||||
"icon": "./assets/icons/s8600.png",
|
"icon": "./assets/icons/s8600.png",
|
||||||
"splash": {
|
"splash": {
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"**/*"
|
"**/*"
|
||||||
],
|
],
|
||||||
"ios": {
|
"ios": {
|
||||||
"buildNumber": "47",
|
"buildNumber": "48",
|
||||||
"supportsTablet": false,
|
"supportsTablet": false,
|
||||||
"bundleIdentifier": "jrshikokuinfo.xprocess.hrkn",
|
"bundleIdentifier": "jrshikokuinfo.xprocess.hrkn",
|
||||||
"config": {
|
"config": {
|
||||||
|
BIN
assets/configuration/layout_default.jpg
Normal file
BIN
assets/configuration/layout_default.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
assets/configuration/layout_tokyo.jpg
Normal file
BIN
assets/configuration/layout_tokyo.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
@@ -921,15 +921,4 @@
|
|||||||
"581D":"徳島,発,20:30#阿波富田,発,20:33#二軒屋,発,20:36#文化の森,発,20:39#地蔵橋,発,20:42#中田,発,20:47#南小松島,発,20:51#阿波赤石,発,20:55#立江,発,20:58#羽ノ浦,発,21:07#西原,発,21:10#阿波中島,発,21:14#阿南,着,21:18#",
|
"581D":"徳島,発,20:30#阿波富田,発,20:33#二軒屋,発,20:36#文化の森,発,20:39#地蔵橋,発,20:42#中田,発,20:47#南小松島,発,20:51#阿波赤石,発,20:55#立江,発,20:58#羽ノ浦,発,21:07#西原,発,21:10#阿波中島,発,21:14#阿南,着,21:18#",
|
||||||
"583D":"徳島,発,21:30#阿波富田,発,21:33#二軒屋,発,21:36#文化の森,発,21:38#地蔵橋,発,21:42#中田,発,21:46#南小松島,発,21:50#阿波赤石,発,21:54#立江,発,21:57#羽ノ浦,発,22:14#西原,発,22:17#阿波中島,発,22:20#阿南,発,22:26#見能林,発,22:29#阿波橘,発,22:32#桑野,発,22:37#新野,発,22:41#阿波福井,発,22:45#由岐,発,22:54#木岐,発,22:58#北河内,発,23:03#日和佐,発,23:06#山河内,発,23:14#辺川,発,23:23#牟岐,着,23:29#",
|
"583D":"徳島,発,21:30#阿波富田,発,21:33#二軒屋,発,21:36#文化の森,発,21:38#地蔵橋,発,21:42#中田,発,21:46#南小松島,発,21:50#阿波赤石,発,21:54#立江,発,21:57#羽ノ浦,発,22:14#西原,発,22:17#阿波中島,発,22:20#阿南,発,22:26#見能林,発,22:29#阿波橘,発,22:32#桑野,発,22:37#新野,発,22:41#阿波福井,発,22:45#由岐,発,22:54#木岐,発,22:58#北河内,発,23:03#日和佐,発,23:06#山河内,発,23:14#辺川,発,23:23#牟岐,着,23:29#",
|
||||||
"585D":"徳島,発,22:55#阿波富田,発,22:58#二軒屋,発,23:01#文化の森,発,23:03#地蔵橋,発,23:07#中田,発,23:11#南小松島,発,23:15#阿波赤石,発,23:19#立江,発,23:22#羽ノ浦,発,23:26#西原,発,23:29#阿波中島,発,23:32#阿南,着,23:36#",
|
"585D":"徳島,発,22:55#阿波富田,発,22:58#二軒屋,発,23:01#文化の森,発,23:03#地蔵橋,発,23:07#中田,発,23:11#南小松島,発,23:15#阿波赤石,発,23:19#立江,発,23:22#羽ノ浦,発,23:26#西原,発,23:29#阿波中島,発,23:32#阿南,着,23:36#",
|
||||||
|
|
||||||
// 臨時列車
|
|
||||||
"9395D":"臨時列車,提,https://www.jr-shikoku.co.jp/03_news/pdf/20250314_20250413_tomorrow_together_worldtour.pdf#高松,発,22:10#昭和町,発,22:13#栗林公園北口,発,22:16#栗林,発,22:19#木太町,発,22:23#屋島,発,22:36#古高松南,発,22:39#八栗口,発,22:43#讃岐牟礼,発,22:45#志度,発,22:49#オレンジタウン,発,22:53#造田,発,22:57#神前,発,23:00#讃岐津田,発,23:06#鶴羽,発,23:10#丹生,発,23:15#三本松,着,23:18#",
|
|
||||||
"9174M":"臨時列車,提,https://www.jr-shikoku.co.jp/03_news/pdf/20250314_20250413_tomorrow_together_worldtour.pdf#高松,発,22:00#坂出,発,22:16#児島,発,22:39#茶屋町,発,22:48#早島,発,22:55#妹尾,発,22:59#岡山,着,23:06#",
|
|
||||||
|
|
||||||
// わらぐろ号/れんげ号
|
|
||||||
"9662D":"宇和れんげまつり臨時列車,提,https://www.jr-shikoku.co.jp/03_news/pdf/20250124_20250629_rinji_spring.pdf#宇和島,発,10:00#北宇和島,発,10:03#高光,発,10:07#伊予吉田,発,10:21#立間,発,10:50#下宇和,発,10:36#卯之町,発,10:39#上宇和,発,10:42#伊予石城,発,10:46#双岩,発,10:53#八幡浜,着,10:58#",
|
|
||||||
"9664D":"宇和れんげまつり臨時列車,提,https://www.jr-shikoku.co.jp/03_news/pdf/20250124_20250629_rinji_spring.pdf#卯之町,発,11:18#上宇和,発,11:21#伊予石城,発,11:25#双岩,発,11:34#八幡浜,着,11:39#",
|
|
||||||
"9663D":"宇和れんげまつり臨時列車,提,https://www.jr-shikoku.co.jp/03_news/pdf/20250124_20250629_rinji_spring.pdf#八幡浜,発,10:07#双岩,発,10:16#伊予石城,発,10:23#上宇和,発,10:27#卯之町,着,10:30#",
|
|
||||||
"9665D":"宇和れんげまつり臨時列車,提,https://www.jr-shikoku.co.jp/03_news/pdf/20250124_20250629_rinji_spring.pdf#八幡浜,発,13:38#双岩,発,13:45#伊予石城,発,13:52#上宇和,発,13:56#卯之町,発,14:07#下宇和,発,14:10#立間,発,14:18#伊予吉田,発,14:25#高光,発,14:31#北宇和島,発,14:35#宇和島,着,14:37#",
|
|
||||||
|
|
||||||
}
|
}
|
@@ -1,6 +1,29 @@
|
|||||||
{
|
{
|
||||||
"type": "FeatureCollection",
|
"type": "FeatureCollection",
|
||||||
"features": [
|
"features": [
|
||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
"name": "阿波池田",
|
||||||
|
"uri": "https://uedayou.net/jrslod/四国旅客鉄道/土讃線/阿波池田",
|
||||||
|
"color": "E25885"
|
||||||
|
},
|
||||||
|
"type": "Feature",
|
||||||
|
"geometry": {
|
||||||
|
"type": "LineString",
|
||||||
|
"coordinates": [
|
||||||
|
[133.80429, 34.02714],
|
||||||
|
[133.80515, 34.02656]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
"name": "阿波池田",
|
||||||
|
"uri": "https://uedayou.net/jrslod/四国旅客鉄道/土讃線/阿波池田"
|
||||||
|
},
|
||||||
|
"type": "Feature",
|
||||||
|
"geometry": { "type": "Point", "coordinates": [133.80429, 34.02714] }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"properties": {
|
"properties": {
|
||||||
"name": "佃",
|
"name": "佃",
|
||||||
@@ -561,6 +584,29 @@
|
|||||||
"type": "Feature",
|
"type": "Feature",
|
||||||
"geometry": { "type": "Point", "coordinates": [134.53819, 34.08082] }
|
"geometry": { "type": "Point", "coordinates": [134.53819, 34.08082] }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
"name": "徳島",
|
||||||
|
"uri": "https://uedayou.net/jrslod/四国旅客鉄道/高徳線/徳島",
|
||||||
|
"color": "9ACD32"
|
||||||
|
},
|
||||||
|
"type": "Feature",
|
||||||
|
"geometry": {
|
||||||
|
"type": "LineString",
|
||||||
|
"coordinates": [
|
||||||
|
[134.55251, 34.07404],
|
||||||
|
[134.55049, 34.07498]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
"name": "徳島",
|
||||||
|
"uri": "https://uedayou.net/jrslod/四国旅客鉄道/高徳線/徳島"
|
||||||
|
},
|
||||||
|
"type": "Feature",
|
||||||
|
"geometry": { "type": "Point", "coordinates": [134.55251, 34.07404] }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"properties": {
|
"properties": {
|
||||||
"name": "徳島線",
|
"name": "徳島線",
|
||||||
|
@@ -33,7 +33,7 @@ export const LandscapeTrainInfo = (props) => {
|
|||||||
stickyHeaderIndices={[1]}
|
stickyHeaderIndices={[1]}
|
||||||
scrollEventThrottle={16}
|
scrollEventThrottle={16}
|
||||||
onScroll={(d) => {
|
onScroll={(d) => {
|
||||||
console.log(d.nativeEvent.contentOffset.y);
|
// Handle scroll events
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<View style={{ height: 0 }} />
|
<View style={{ height: 0 }} />
|
||||||
|
@@ -1,13 +1,14 @@
|
|||||||
import { Text, TouchableOpacity } from "react-native";
|
import { Text, TouchableOpacity } from "react-native";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||||
export const ShowSpecialTrain = ({
|
export const ShowSpecialTrain = ({
|
||||||
isTrainDataNothing,
|
isTrainDataNothing,
|
||||||
setTrainData,
|
setTrainData,
|
||||||
trainList,
|
|
||||||
trueTrainID,
|
trueTrainID,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { allTrainDiagram } = useAllTrainDiagram();
|
||||||
const replaceSpecialTrainDetail = (trainNum) => {
|
const replaceSpecialTrainDetail = (trainNum) => {
|
||||||
let TD = trainList[trainNum];
|
let TD = allTrainDiagram[trainNum];
|
||||||
if (!TD) return;
|
if (!TD) return;
|
||||||
setTrainData(TD.split("#").filter((d) => d != ""));
|
setTrainData(TD.split("#").filter((d) => d != ""));
|
||||||
};
|
};
|
||||||
|
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
|
|||||||
import { View, TouchableOpacity, useWindowDimensions } from "react-native";
|
import { View, TouchableOpacity, useWindowDimensions } from "react-native";
|
||||||
import { StateBox } from "./StateBox";
|
import { StateBox } from "./StateBox";
|
||||||
import { useDeviceOrientationChange } from "../../../stateBox/useDeviceOrientationChange";
|
import { useDeviceOrientationChange } from "../../../stateBox/useDeviceOrientationChange";
|
||||||
import { getStationList2 } from "../../../lib/getStationList2";
|
import { getStationList2 } from "../../../lib/getStationList";
|
||||||
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";
|
||||||
|
@@ -12,8 +12,7 @@ import {
|
|||||||
import { SheetManager } from "react-native-actions-sheet";
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
import { useScrollHandlers } from "react-native-actions-sheet";
|
import { useScrollHandlers } from "react-native-actions-sheet";
|
||||||
import { AS } from "../../storageControl";
|
import { AS } from "../../storageControl";
|
||||||
import trainList from "../../assets/originData/trainList";
|
import { lineListPair, stationIDPair } 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";
|
||||||
@@ -34,7 +33,7 @@ import { ShowSpecialTrain } from "./EachTrainInfo/ShowSpecialTrain";
|
|||||||
import { useTrainMenu } from "../../stateBox/useTrainMenu";
|
import { useTrainMenu } from "../../stateBox/useTrainMenu";
|
||||||
import { HeaderText } from "./EachTrainInfoCore/HeaderText";
|
import { HeaderText } from "./EachTrainInfoCore/HeaderText";
|
||||||
import { useStationList } from "../../stateBox/useStationList";
|
import { useStationList } from "../../stateBox/useStationList";
|
||||||
import { stationIDPair } from "../../lib/getStationList2";
|
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||||
|
|
||||||
export const EachTrainInfoCore = ({
|
export const EachTrainInfoCore = ({
|
||||||
actionSheetRef,
|
actionSheetRef,
|
||||||
@@ -45,6 +44,8 @@ export const EachTrainInfoCore = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { currentTrain } = useCurrentTrain();
|
const { currentTrain } = useCurrentTrain();
|
||||||
const { originalStationList, stationList } = useStationList();
|
const { originalStationList, stationList } = useStationList();
|
||||||
|
const { allTrainDiagram: trainList, allCustonTrainData } =
|
||||||
|
useAllTrainDiagram();
|
||||||
const { setTrainInfo } = useTrainMenu();
|
const { setTrainInfo } = useTrainMenu();
|
||||||
const [currentTrainData, setCurrentTrainData] = useState();
|
const [currentTrainData, setCurrentTrainData] = useState();
|
||||||
|
|
||||||
@@ -170,12 +171,12 @@ export const EachTrainInfoCore = ({
|
|||||||
const position = points.findIndex((d) => d == true);
|
const position = points.findIndex((d) => d == true);
|
||||||
let isThrew = false;
|
let isThrew = false;
|
||||||
if (position == -1) return () => {};
|
if (position == -1) return () => {};
|
||||||
|
setShowThrew(true);
|
||||||
if (trainDataWidhThrough[position].split(",")[1] == "通過") {
|
if (trainDataWidhThrough[position].split(",")[1] == "通過") {
|
||||||
LayoutAnimation.configureNext({
|
LayoutAnimation.configureNext({
|
||||||
duration: 400,
|
duration: 400,
|
||||||
update: { type: "easeInEaseOut", springDamping: 0.6 },
|
update: { type: "easeInEaseOut", springDamping: 0.6 },
|
||||||
});
|
});
|
||||||
setShowThrew(true);
|
|
||||||
isThrew = true;
|
isThrew = true;
|
||||||
}
|
}
|
||||||
if (position < 5) {
|
if (position < 5) {
|
||||||
@@ -215,9 +216,8 @@ export const EachTrainInfoCore = ({
|
|||||||
if (!data.trainNum) return;
|
if (!data.trainNum) return;
|
||||||
const NearTrainList = getInfluencedTrainData(data.trainNum);
|
const NearTrainList = getInfluencedTrainData(data.trainNum);
|
||||||
if (NearTrainList.length == 0) return;
|
if (NearTrainList.length == 0) return;
|
||||||
const returnArray = NearTrainList.map((d) => d.id);
|
|
||||||
const TDArray = NearTrainList.map((d) => d.TrainData);
|
const TDArray = NearTrainList.map((d) => d.TrainData);
|
||||||
setNearTrainIDList(returnArray);
|
setNearTrainIDList(NearTrainList.map((d) => d.id));
|
||||||
if (trainData.length == 0) return;
|
if (trainData.length == 0) return;
|
||||||
if (TDArray.length == 0) return;
|
if (TDArray.length == 0) return;
|
||||||
let head = [];
|
let head = [];
|
||||||
@@ -241,10 +241,8 @@ export const EachTrainInfoCore = ({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
if (head) setHeadStation(head);
|
setHeadStation(head || []);
|
||||||
else setHeadStation([]);
|
setTailStation(tail || []);
|
||||||
if (tail) setTailStation(tail);
|
|
||||||
else setTailStation([]);
|
|
||||||
}, [trainData, data]);
|
}, [trainData, data]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -325,7 +323,7 @@ export const EachTrainInfoCore = ({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const openTrainInfo = (d) => {
|
const openTrainInfo = (d) => {
|
||||||
const train = customTrainDataDetector(d);
|
const train = customTrainDataDetector(d, allCustonTrainData);
|
||||||
let TrainNumber = "";
|
let TrainNumber = "";
|
||||||
if (train.trainNumDistance != undefined) {
|
if (train.trainNumDistance != undefined) {
|
||||||
const timeInfo =
|
const timeInfo =
|
||||||
@@ -390,7 +388,6 @@ export const EachTrainInfoCore = ({
|
|||||||
<DynamicHeaderScrollView
|
<DynamicHeaderScrollView
|
||||||
from={from}
|
from={from}
|
||||||
styles={styles}
|
styles={styles}
|
||||||
actionSheetRef={actionSheetRef}
|
|
||||||
scrollHandlers={scrollHandlers}
|
scrollHandlers={scrollHandlers}
|
||||||
containerProps={{
|
containerProps={{
|
||||||
style: {
|
style: {
|
||||||
@@ -458,7 +455,6 @@ export const EachTrainInfoCore = ({
|
|||||||
<ShowSpecialTrain
|
<ShowSpecialTrain
|
||||||
isTrainDataNothing={trainData.length == 0}
|
isTrainDataNothing={trainData.length == 0}
|
||||||
setTrainData={setTrainData}
|
setTrainData={setTrainData}
|
||||||
trainList={trainList}
|
|
||||||
trueTrainID={trueTrainID}
|
trueTrainID={trueTrainID}
|
||||||
/>
|
/>
|
||||||
{!trainData.length && (
|
{!trainData.length && (
|
||||||
|
@@ -1,14 +1,15 @@
|
|||||||
import React, { CSSProperties, FC, useEffect, useMemo, useState } from "react";
|
import React, { CSSProperties, FC, useEffect, useMemo, useState } from "react";
|
||||||
import { Text, View, LayoutAnimation, TextStyle } from "react-native";
|
import { Text, View, TextStyle, TouchableOpacity } from "react-native";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
|
||||||
import { SheetManager } from "react-native-actions-sheet";
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
import { getType } from "../../../lib/eachTrainInfoCoreLib/getType";
|
|
||||||
import { migrateTrainName } from "../../../lib/eachTrainInfoCoreLib/migrateTrainName";
|
import { migrateTrainName } from "../../../lib/eachTrainInfoCoreLib/migrateTrainName";
|
||||||
import { TrainIconStatus } from "./trainIconStatus";
|
import { TrainIconStatus } from "./trainIconStatus";
|
||||||
import { TrainViewIcon } from "./trainViewIcon";
|
import { TrainViewIcon } from "./trainViewIcon";
|
||||||
import { OneManText } from "./HeaderTextParts/OneManText";
|
import { OneManText } from "./HeaderTextParts/OneManText";
|
||||||
import { customTrainDataDetector } from "@/components/custom-train-data";
|
import { customTrainDataDetector } from "@/components/custom-train-data";
|
||||||
import { InfogramText } from "@/components/ActionSheetComponents/EachTrainInfoCore/HeaderTextParts/InfogramText";
|
import { InfogramText } from "@/components/ActionSheetComponents/EachTrainInfoCore/HeaderTextParts/InfogramText";
|
||||||
|
import { useTrainMenu } from "@/stateBox/useTrainMenu";
|
||||||
|
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||||
|
import { useNotification } from "@/stateBox/useNotifications";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
data: { trainNum: string; limited: string };
|
data: { trainNum: string; limited: string };
|
||||||
@@ -38,14 +39,21 @@ export const HeaderText: FC<Props> = ({
|
|||||||
tailStation,
|
tailStation,
|
||||||
navigate,
|
navigate,
|
||||||
from,
|
from,
|
||||||
scrollHandlers
|
scrollHandlers,
|
||||||
}) => {
|
}) => {
|
||||||
const { limited, trainNum } = data;
|
const { limited, trainNum } = data;
|
||||||
|
|
||||||
|
const { updatePermission } = useTrainMenu();
|
||||||
|
const { allCustonTrainData } = useAllTrainDiagram();
|
||||||
|
const { expoPushToken } = useNotification();
|
||||||
|
|
||||||
// 列車名、種別、フォントの取得
|
// 列車名、種別、フォントの取得
|
||||||
const [typeName, trainName, fontAvailable, isOneMan, infogram] =
|
const [typeName, trainName, fontAvailable, isOneMan, infogram] =
|
||||||
useMemo(() => {
|
useMemo(() => {
|
||||||
const customTrainData = customTrainDataDetector(trainNum);
|
const customTrainData = customTrainDataDetector(
|
||||||
|
trainNum,
|
||||||
|
allCustonTrainData
|
||||||
|
);
|
||||||
const [type, fontAvailable, isOneMan] = (() => {
|
const [type, fontAvailable, isOneMan] = (() => {
|
||||||
switch (customTrainData.type) {
|
switch (customTrainData.type) {
|
||||||
case "LTDEXP":
|
case "LTDEXP":
|
||||||
@@ -118,10 +126,27 @@ export const HeaderText: FC<Props> = ({
|
|||||||
}, [trainData]);
|
}, [trainData]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{ padding: 10, flexDirection: "row", alignItems: "center" }} onTouchStart={()=>scrollHandlers.ref.current?.scrollTo({ y: 0, animated: true })}>
|
<View
|
||||||
|
style={{ padding: 10, flexDirection: "row", alignItems: "center" }}
|
||||||
|
onTouchStart={() =>
|
||||||
|
scrollHandlers.ref.current?.scrollTo({ y: 0, animated: true })
|
||||||
|
}
|
||||||
|
>
|
||||||
<TrainIconStatus {...{ data, navigate, from }} />
|
<TrainIconStatus {...{ data, navigate, from }} />
|
||||||
<View
|
<TouchableOpacity
|
||||||
style={{ borderRadius: 5, flexDirection: "row", alignItems: "center" }}
|
style={{ borderRadius: 5, flexDirection: "row", alignItems: "center" }}
|
||||||
|
onLongPress={() => {
|
||||||
|
navigate("generalWebView", {
|
||||||
|
uri:
|
||||||
|
"https://jr-shikoku-data-post-system.pages.dev?trainNum=" +
|
||||||
|
trainNum +
|
||||||
|
"&token=" +
|
||||||
|
expoPushToken,
|
||||||
|
useExitButton: false,
|
||||||
|
});
|
||||||
|
SheetManager.hide("EachTrainInfo");
|
||||||
|
}}
|
||||||
|
disabled={!updatePermission}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
@@ -137,7 +162,7 @@ export const HeaderText: FC<Props> = ({
|
|||||||
{isOneMan && <OneManText />}
|
{isOneMan && <OneManText />}
|
||||||
<Text style={textConfig}>{trainName}</Text>
|
<Text style={textConfig}>{trainName}</Text>
|
||||||
<InfogramText infogram={infogram} />
|
<InfogramText infogram={infogram} />
|
||||||
</View>
|
</TouchableOpacity>
|
||||||
|
|
||||||
<View style={{ flex: 1 }} />
|
<View style={{ flex: 1 }} />
|
||||||
<Text style={textConfig}>
|
<Text style={textConfig}>
|
||||||
|
@@ -6,6 +6,7 @@ import { useInterval } from "../../../lib/useInterval";
|
|||||||
import { Icon } from "@expo/vector-icons/build/createIconSet";
|
import { Icon } from "@expo/vector-icons/build/createIconSet";
|
||||||
import { SheetManager } from "react-native-actions-sheet";
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
import { customTrainDataDetector } from "../../custom-train-data";
|
import { customTrainDataDetector } from "../../custom-train-data";
|
||||||
|
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||||
|
|
||||||
type GlyphNames = ComponentProps<typeof Ionicons>["name"];
|
type GlyphNames = ComponentProps<typeof Ionicons>["name"];
|
||||||
|
|
||||||
@@ -22,11 +23,14 @@ export const TrainIconStatus: FC<Props> = ({ data, navigate, from }) => {
|
|||||||
const [trainIcon, setTrainIcon] = useState(null);
|
const [trainIcon, setTrainIcon] = useState(null);
|
||||||
const [anpanmanStatus, setAnpanmanStatus] = useState<apt>();
|
const [anpanmanStatus, setAnpanmanStatus] = useState<apt>();
|
||||||
const [address, setAddress] = useState("");
|
const [address, setAddress] = useState("");
|
||||||
|
const { allCustonTrainData } = useAllTrainDiagram();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!data.trainNum) return;
|
if (!data.trainNum) return;
|
||||||
const { trainIcon, infoUrl } = customTrainDataDetector(data.trainNum);
|
const { img, infoUrl } = customTrainDataDetector(
|
||||||
if (trainIcon) setTrainIcon(trainIcon);
|
data.trainNum,
|
||||||
|
allCustonTrainData
|
||||||
|
);
|
||||||
|
if (img) setTrainIcon(img);
|
||||||
if (infoUrl) setAddress(infoUrl);
|
if (infoUrl) setAddress(infoUrl);
|
||||||
|
|
||||||
switch (data.trainNum) {
|
switch (data.trainNum) {
|
||||||
@@ -47,7 +51,6 @@ export const TrainIconStatus: FC<Props> = ({ data, navigate, from }) => {
|
|||||||
)
|
)
|
||||||
.then((d) => d.json())
|
.then((d) => d.json())
|
||||||
.then((d) => {
|
.then((d) => {
|
||||||
console.log(d);
|
|
||||||
if (d.trainStatus == "〇") {
|
if (d.trainStatus == "〇") {
|
||||||
//setAnpanmanStatus({name:"checkmark-circle-outline",color:"blue"});
|
//setAnpanmanStatus({name:"checkmark-circle-outline",color:"blue"});
|
||||||
} else if (d.trainStatus == "▲") {
|
} else if (d.trainStatus == "▲") {
|
||||||
@@ -57,31 +60,30 @@ export const TrainIconStatus: FC<Props> = ({ data, navigate, from }) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "2074D":
|
case "2074D":
|
||||||
case "2076D":
|
case "2076D":
|
||||||
case "2080D":
|
case "2080D":
|
||||||
case "2082D":
|
case "2082D":
|
||||||
case "2071D":
|
case "2071D":
|
||||||
case "2073D":
|
case "2073D":
|
||||||
case "2079D":
|
case "2079D":
|
||||||
case "2081D":
|
case "2081D":
|
||||||
fetch(
|
fetch(
|
||||||
`https://n8n.haruk.in/webhook/dosan-anpanman-first?trainNum=${
|
`https://n8n.haruk.in/webhook/dosan-anpanman-first?trainNum=${
|
||||||
data.trainNum
|
data.trainNum
|
||||||
}&month=${dayjs().format("M")}&day=${dayjs().format("D")}`
|
}&month=${dayjs().format("M")}&day=${dayjs().format("D")}`
|
||||||
)
|
)
|
||||||
.then((d) => d.json())
|
.then((d) => d.json())
|
||||||
.then((d) => {
|
.then((d) => {
|
||||||
console.log(d);
|
if (d.trainStatus == "〇") {
|
||||||
if (d.trainStatus == "〇") {
|
//setAnpanmanStatus({name:"checkmark-circle-outline",color:"blue"});
|
||||||
//setAnpanmanStatus({name:"checkmark-circle-outline",color:"blue"});
|
} else if (d.trainStatus == "▲") {
|
||||||
} else if (d.trainStatus == "▲") {
|
setAnpanmanStatus({ name: "warning-outline", color: "yellow" });
|
||||||
setAnpanmanStatus({ name: "warning-outline", color: "yellow" });
|
} else if (d.trainStatus == "×") {
|
||||||
} else if (d.trainStatus == "×") {
|
//setAnpanmanStatus({ name: "close-circle-outline", color: "red" });
|
||||||
//setAnpanmanStatus({ name: "close-circle-outline", color: "red" });
|
}
|
||||||
}
|
});
|
||||||
});
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}, [data.trainNum]);
|
}, [data.trainNum]);
|
||||||
const [move, setMove] = useState(true);
|
const [move, setMove] = useState(true);
|
||||||
@@ -104,6 +106,7 @@ export const TrainIconStatus: FC<Props> = ({ data, navigate, from }) => {
|
|||||||
});
|
});
|
||||||
SheetManager.hide("EachTrainInfo");
|
SheetManager.hide("EachTrainInfo");
|
||||||
}}
|
}}
|
||||||
|
disabled={!address}
|
||||||
>
|
>
|
||||||
{move ? (
|
{move ? (
|
||||||
<Image
|
<Image
|
||||||
|
146
components/ActionSheetComponents/SocialMenu.tsx
Normal file
146
components/ActionSheetComponents/SocialMenu.tsx
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
import React, { useRef } from "react";
|
||||||
|
import { View, Platform, Text } from "react-native";
|
||||||
|
import ActionSheet ,{ ScrollView } from "react-native-actions-sheet";
|
||||||
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||||
|
import { ListItem } from "@rneui/themed";
|
||||||
|
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
||||||
|
import { Linking } from "react-native";
|
||||||
|
import TouchableScale from "react-native-touchable-scale";
|
||||||
|
export const Social = () => {
|
||||||
|
const actionSheetRef = useRef(null);
|
||||||
|
const insets = useSafeAreaInsets();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ActionSheet
|
||||||
|
gestureEnabled
|
||||||
|
CustomHeaderComponent={<></>}
|
||||||
|
ref={actionSheetRef}
|
||||||
|
isModal={Platform.OS == "ios"}
|
||||||
|
containerStyle={
|
||||||
|
Platform.OS == "android"
|
||||||
|
? {
|
||||||
|
paddingBottom: insets.bottom,
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
useBottomSafeAreaPadding={Platform.OS == "android"}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#0099CC",
|
||||||
|
borderTopRadius: 5,
|
||||||
|
borderColor: "dark",
|
||||||
|
borderWidth: 1,
|
||||||
|
height: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<View style={{ height: 26, width: "100%", backgroundColor: "#0099CC" }}>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
height: 6,
|
||||||
|
width: 45,
|
||||||
|
borderRadius: 100,
|
||||||
|
backgroundColor: "#f0f0f0",
|
||||||
|
marginVertical: 10,
|
||||||
|
alignSelf: "center",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View
|
||||||
|
style={{ padding: 10, flexDirection: "row", alignItems: "center" }}
|
||||||
|
>
|
||||||
|
<MaterialCommunityIcons
|
||||||
|
name="web"
|
||||||
|
style={{ padding: 5 }}
|
||||||
|
color="white"
|
||||||
|
size={30}
|
||||||
|
/>
|
||||||
|
<Text style={{ fontSize: 30, fontWeight: "bold", color: "white" }}>
|
||||||
|
JR四国公式SNS一族
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<ScrollView
|
||||||
|
style={{
|
||||||
|
padding: 10,
|
||||||
|
backgroundColor: "white",
|
||||||
|
borderBottomLeftRadius: 10,
|
||||||
|
borderBottomRightRadius: 10,
|
||||||
|
flex:1
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
url: "https://twitter.com/jr_shikoku_info",
|
||||||
|
name: "JR四国列車運行情報",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
url: "https://twitter.com/JRshikoku_eigyo",
|
||||||
|
name: "JR四国営業部【公式】",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "https://twitter.com/JRshikoku_tokyo",
|
||||||
|
name: "JR四国 東京営業情報【公式】",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "https://twitter.com/JRshikoku_osaka",
|
||||||
|
name: "JR四国 大阪営業部【公式】",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "https://twitter.com/jrs_matsuyama",
|
||||||
|
name: "JR四国 松山駅 【公式】",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "https://twitter.com/jrshikoku_kochi",
|
||||||
|
name: "JR四国 高知駅【公式】",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "https://twitter.com/jr_tokust",
|
||||||
|
name: "JR四国 徳島駅【公式】",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "https://twitter.com/jrshikoku_uwjm",
|
||||||
|
name: "JR四国 宇和島駅【公式】",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "https://twitter.com/jrshikoku_wkama",
|
||||||
|
name: "JR四国 ワープ高松支店【公式】",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "https://twitter.com/JRshikoku_wkoch",
|
||||||
|
name: "JR四国 ワープ高知支店【公式】",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "https://twitter.com/Yoakemonogatari",
|
||||||
|
name: "志国土佐 時代の夜明けのものがたり【公式】",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "https://twitter.com/Smile_Eki_Chan",
|
||||||
|
name: "すまいるえきちゃん♡JR四国【公式】",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "https://twitter.com/sper_ponchan",
|
||||||
|
name: "しこくたぬきのぽんちゃん 【四国家サポーターズクラブ】",
|
||||||
|
},
|
||||||
|
].map((d) => (
|
||||||
|
<ListItem
|
||||||
|
bottomDivider
|
||||||
|
onPress={() => Linking.openURL(d.url)}
|
||||||
|
key={d.url}
|
||||||
|
friction={90} //
|
||||||
|
tension={100} // These props are passed to the parent component (here TouchableScale)
|
||||||
|
activeScale={0.95} //
|
||||||
|
Component={TouchableScale}
|
||||||
|
>
|
||||||
|
<ListItem.Content>
|
||||||
|
<ListItem.Title>{d.name}</ListItem.Title>
|
||||||
|
</ListItem.Content>
|
||||||
|
<ListItem.Chevron />
|
||||||
|
</ListItem>
|
||||||
|
))}
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
</ActionSheet>
|
||||||
|
);
|
||||||
|
};
|
51
components/ActionSheetComponents/SpecialTrainInfo.tsx
Normal file
51
components/ActionSheetComponents/SpecialTrainInfo.tsx
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import React, { useRef } from "react";
|
||||||
|
import { View, Platform } from "react-native";
|
||||||
|
import ActionSheet from "react-native-actions-sheet";
|
||||||
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||||
|
|
||||||
|
import { SpecialTrainInfoBox } from "../Menu/SpecialTrainInfoBox";
|
||||||
|
export const SpecialTrainInfo = ({ payload }) => {
|
||||||
|
const { navigate } = payload;
|
||||||
|
const actionSheetRef = useRef(null);
|
||||||
|
const insets = useSafeAreaInsets();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ActionSheet
|
||||||
|
gestureEnabled
|
||||||
|
CustomHeaderComponent={<></>}
|
||||||
|
ref={actionSheetRef}
|
||||||
|
isModal={Platform.OS == "ios"}
|
||||||
|
containerStyle={
|
||||||
|
Platform.OS == "android"
|
||||||
|
? {
|
||||||
|
paddingBottom: insets.bottom,
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
useBottomSafeAreaPadding={Platform.OS == "android"}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#0099CC",
|
||||||
|
borderTopRadius: 5,
|
||||||
|
borderColor: "dark",
|
||||||
|
borderWidth: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<View style={{ height: 26, width: "100%", backgroundColor: "#0099CC" }}>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
height: 6,
|
||||||
|
width: 45,
|
||||||
|
borderRadius: 100,
|
||||||
|
backgroundColor: "#f0f0f0",
|
||||||
|
marginVertical: 10,
|
||||||
|
alignSelf: "center",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<SpecialTrainInfoBox navigate={navigate} />
|
||||||
|
</View>
|
||||||
|
</ActionSheet>
|
||||||
|
);
|
||||||
|
};
|
@@ -2,19 +2,14 @@ import React, { useState, useEffect } from "react";
|
|||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Linking,
|
Linking,
|
||||||
Text,
|
|
||||||
TouchableOpacity,
|
|
||||||
BackHandler,
|
BackHandler,
|
||||||
Platform,
|
Platform,
|
||||||
|
useWindowDimensions,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import AutoHeightImage from "react-native-auto-height-image";
|
|
||||||
import { FontAwesome, Foundation, Ionicons } from "@expo/vector-icons";
|
|
||||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||||
import ActionSheet, { SheetManager } from "react-native-actions-sheet";
|
import ActionSheet, { SheetManager } from "react-native-actions-sheet";
|
||||||
import Sign from "../../components/駅名表/Sign";
|
import Sign from "../../components/駅名表/Sign";
|
||||||
|
|
||||||
import { TicketBox } from "../atom/TicketBox";
|
|
||||||
import { widthPercentageToDP as wp } from "react-native-responsive-screen";
|
|
||||||
import { getPDFViewURL } from "../../lib/getPdfViewURL";
|
import { getPDFViewURL } from "../../lib/getPdfViewURL";
|
||||||
import { useBusAndTrainData } from "../../stateBox/useBusAndTrainData";
|
import { useBusAndTrainData } from "../../stateBox/useBusAndTrainData";
|
||||||
import { AS } from "../../storageControl";
|
import { AS } from "../../storageControl";
|
||||||
@@ -23,17 +18,19 @@ import { TrainBusButton } from "./StationDeteilView/TrainBusButton";
|
|||||||
import { 駅構内図 } from "./StationDeteilView/StationInsideMapButton";
|
import { 駅構内図 } from "./StationDeteilView/StationInsideMapButton";
|
||||||
import { WebSiteButton } from "./StationDeteilView/WebSiteButton";
|
import { WebSiteButton } from "./StationDeteilView/WebSiteButton";
|
||||||
import { StationTimeTableButton } from "./StationDeteilView/StationTimeTableButton";
|
import { StationTimeTableButton } from "./StationDeteilView/StationTimeTableButton";
|
||||||
|
import { StationTrainPositionButton } from "./StationDeteilView/StationTrainPositionButton";
|
||||||
|
|
||||||
export const StationDeteilView = (props) => {
|
export const StationDeteilView = (props) => {
|
||||||
if (!props.payload) return <></>;
|
if (!props.payload) return <></>;
|
||||||
const { currentStation, navigate, onExit, goTo, useShow } = props.payload;
|
const { currentStation, navigate, onExit, goTo, useShow } = props.payload;
|
||||||
|
const { width } = useWindowDimensions();
|
||||||
const { busAndTrainData } = useBusAndTrainData();
|
const { busAndTrainData } = useBusAndTrainData();
|
||||||
const [trainBus, setTrainBus] = useState();
|
const [trainBus, setTrainBus] = useState();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!currentStation) return () => {};
|
if (!currentStation) return () => {};
|
||||||
const data = busAndTrainData.filter((d) =>
|
const data = busAndTrainData.filter(
|
||||||
d.name === currentStation[0].Station_JP
|
(d) => d.name === currentStation[0].Station_JP
|
||||||
);
|
);
|
||||||
if (data.length == 0) {
|
if (data.length == 0) {
|
||||||
setTrainBus();
|
setTrainBus();
|
||||||
@@ -89,73 +86,84 @@ export const StationDeteilView = (props) => {
|
|||||||
</View>
|
</View>
|
||||||
<View>
|
<View>
|
||||||
{currentStation && (
|
{currentStation && (
|
||||||
<View style={{ margin: 10, marginHorizontal: wp("10%") }}>
|
<>
|
||||||
<Sign
|
<View style={{ margin: 10, marginHorizontal: width * 0.1 }}>
|
||||||
currentStation={currentStation}
|
<Sign
|
||||||
oP={() => {
|
stationID={currentStation[0].StationNumber}
|
||||||
usePDFView == "true"
|
oP={() => {
|
||||||
? Linking.openURL(currentStation[0].StationTimeTable)
|
usePDFView == "true"
|
||||||
: navigate("howto", {
|
? Linking.openURL(currentStation[0].StationTimeTable)
|
||||||
info,
|
: navigate("howto", {
|
||||||
|
info,
|
||||||
|
goTo,
|
||||||
|
useShow,
|
||||||
|
});
|
||||||
|
onExit();
|
||||||
|
}}
|
||||||
|
oLP={() =>
|
||||||
|
Linking.openURL(currentStation[0].StationTimeTable)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={{ flexDirection: "row" }}>
|
||||||
|
<StationTrainPositionButton
|
||||||
|
stationNumber={currentStation[0].StationNumber}
|
||||||
|
onExit={onExit}
|
||||||
|
navigate={navigate}
|
||||||
|
/>
|
||||||
|
{currentStation[0].JrHpUrl &&
|
||||||
|
currentStation[0].StationNumber != "M12" && (
|
||||||
|
<駅構内図 //児島例外/
|
||||||
|
navigate={navigate}
|
||||||
|
goTo={goTo}
|
||||||
|
useShow={useShow}
|
||||||
|
address={currentStation[0].JrHpUrl}
|
||||||
|
onExit={onExit}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
<View style={{ flexDirection: "row" }}>
|
||||||
|
{!currentStation[0].JrHpUrl || (
|
||||||
|
<WebSiteButton
|
||||||
|
navigate={navigate}
|
||||||
|
info={currentStation[0].JrHpUrl}
|
||||||
|
goTo={goTo}
|
||||||
|
useShow={useShow}
|
||||||
|
onExit={onExit}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{!currentStation[0].StationTimeTable || (
|
||||||
|
<StationTimeTableButton
|
||||||
|
info={info}
|
||||||
|
address={currentStation[0].StationTimeTable}
|
||||||
|
usePDFView={usePDFView}
|
||||||
|
navigate={navigate}
|
||||||
|
onExit={onExit}
|
||||||
|
goTo={goTo}
|
||||||
|
useShow={useShow}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<StationMapButton
|
||||||
|
stationMap={
|
||||||
|
currentStation[0].StationMap ||
|
||||||
|
`https://www.google.co.jp/maps/place/${currentStation[0].lat},${currentStation[0].lng}`
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{!trainBus || (
|
||||||
|
<TrainBusButton
|
||||||
|
address={trainBus.address}
|
||||||
|
press={() => {
|
||||||
|
navigate("howto", {
|
||||||
|
info: trainBus.address,
|
||||||
goTo,
|
goTo,
|
||||||
useShow,
|
useShow,
|
||||||
});
|
});
|
||||||
onExit();
|
onExit();
|
||||||
}}
|
}}
|
||||||
oLP={() => Linking.openURL(currentStation[0].StationTimeTable)}
|
/>
|
||||||
/>
|
)}
|
||||||
</View>
|
</View>
|
||||||
)}
|
</>
|
||||||
{currentStation &&
|
|
||||||
currentStation[0].JrHpUrl &&
|
|
||||||
currentStation[0].StationNumber != "M12" && (
|
|
||||||
<駅構内図 //児島例外/
|
|
||||||
navigate={navigate}
|
|
||||||
goTo={goTo}
|
|
||||||
useShow={useShow}
|
|
||||||
address={currentStation[0].JrHpUrl}
|
|
||||||
onExit={onExit}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{currentStation && (
|
|
||||||
<View style={{ flexDirection: "row" }}>
|
|
||||||
{!currentStation[0].JrHpUrl || (
|
|
||||||
<WebSiteButton
|
|
||||||
navigate={navigate}
|
|
||||||
info={currentStation[0].JrHpUrl}
|
|
||||||
goTo={goTo}
|
|
||||||
useShow={useShow}
|
|
||||||
onExit={onExit}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{!currentStation[0].StationTimeTable || (
|
|
||||||
<StationTimeTableButton
|
|
||||||
info={info}
|
|
||||||
address={currentStation[0].StationTimeTable}
|
|
||||||
usePDFView={usePDFView}
|
|
||||||
navigate={navigate}
|
|
||||||
onExit={onExit}
|
|
||||||
goTo={goTo}
|
|
||||||
useShow={useShow}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{!currentStation[0].StationMap || (
|
|
||||||
<StationMapButton stationMap={currentStation[0].StationMap} />
|
|
||||||
)}
|
|
||||||
{!trainBus || (
|
|
||||||
<TrainBusButton
|
|
||||||
address={trainBus.address}
|
|
||||||
press={() => {
|
|
||||||
navigate("howto", {
|
|
||||||
info: trainBus.address,
|
|
||||||
goTo,
|
|
||||||
useShow,
|
|
||||||
});
|
|
||||||
onExit();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
@@ -19,6 +19,7 @@ export const 駅構内図:FC<Props> = (props) => {
|
|||||||
alignContent: "center",
|
alignContent: "center",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
margin: 2,
|
margin: 2,
|
||||||
|
flex: 1,
|
||||||
}}
|
}}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
navigate("howto", { info, goTo, useShow });
|
navigate("howto", { info, goTo, useShow });
|
||||||
|
@@ -0,0 +1,54 @@
|
|||||||
|
import { FC } from "react";
|
||||||
|
import { TouchableOpacity, View, Text, Linking } from "react-native";
|
||||||
|
import { useStationList } from "@/stateBox/useStationList";
|
||||||
|
import { useCurrentTrain } from "@/stateBox/useCurrentTrain";
|
||||||
|
import AntDesign from "react-native-vector-icons/AntDesign";
|
||||||
|
type Props = {
|
||||||
|
stationNumber: string;
|
||||||
|
onExit: () => void;
|
||||||
|
navigate?: (screen: string, params: { screen: string }) => void;
|
||||||
|
};
|
||||||
|
export const StationTrainPositionButton: FC<Props> = (props) => {
|
||||||
|
const { stationNumber, onExit, navigate } = props;
|
||||||
|
const {
|
||||||
|
inject,
|
||||||
|
} = useCurrentTrain();
|
||||||
|
const { getInjectJavascriptAddress } = useStationList();
|
||||||
|
return (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
height: 50,
|
||||||
|
backgroundColor: "#0099CC",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
margin: 2,
|
||||||
|
flex: 1
|
||||||
|
}}
|
||||||
|
onPress={() => {
|
||||||
|
navigate("positions", { screen: "Apps" });
|
||||||
|
const script = getInjectJavascriptAddress(stationNumber);
|
||||||
|
inject(script);
|
||||||
|
onExit();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<View style={{ flex: 1 }} />
|
||||||
|
<AntDesign
|
||||||
|
name={"barchart"}
|
||||||
|
size={20}
|
||||||
|
color={"white"}
|
||||||
|
style={{ marginHorizontal: 5, marginVertical: 5 }}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
textAlign: "center",
|
||||||
|
textAlignVertical: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
走行位置に移動
|
||||||
|
</Text>
|
||||||
|
<View style={{ flex: 1 }} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
};
|
@@ -11,8 +11,7 @@ import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|||||||
import { useTrainMenu } from "../../stateBox/useTrainMenu";
|
import { useTrainMenu } from "../../stateBox/useTrainMenu";
|
||||||
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
|
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
|
||||||
import lineColorList from "../../assets/originData/lineColorList";
|
import lineColorList from "../../assets/originData/lineColorList";
|
||||||
import { stationIDPair } from "../../lib/getStationList2";
|
import { stationIDPair, lineListPair } from "../../lib/getStationList";
|
||||||
import { lineListPair } from "../../lib/getStationList";
|
|
||||||
|
|
||||||
export const TrainMenuLineSelector = () => {
|
export const TrainMenuLineSelector = () => {
|
||||||
const {
|
const {
|
||||||
@@ -20,7 +19,7 @@ export const TrainMenuLineSelector = () => {
|
|||||||
setSelectedLine,
|
setSelectedLine,
|
||||||
mapsStationData: stationData,
|
mapsStationData: stationData,
|
||||||
} = useTrainMenu();
|
} = useTrainMenu();
|
||||||
const { webview } = useCurrentTrain();
|
const { webview } = useCurrentTrain();
|
||||||
const actionSheetRef = useRef(null);
|
const actionSheetRef = useRef(null);
|
||||||
const insets = useSafeAreaInsets();
|
const insets = useSafeAreaInsets();
|
||||||
const platformIs = Platform.OS == "android";
|
const platformIs = Platform.OS == "android";
|
||||||
@@ -55,7 +54,7 @@ export const TrainMenuLineSelector = () => {
|
|||||||
onPress={() => {
|
onPress={() => {
|
||||||
SheetManager.hide("TrainMenuLineSelector");
|
SheetManager.hide("TrainMenuLineSelector");
|
||||||
const s = selectedLine == d ? undefined : d;
|
const s = selectedLine == d ? undefined : d;
|
||||||
if(!s) return;
|
if (!s) return;
|
||||||
setSelectedLine(s);
|
setSelectedLine(s);
|
||||||
Object.keys(stationData).forEach((data, indexBase) => {
|
Object.keys(stationData).forEach((data, indexBase) => {
|
||||||
stationData[data].forEach((D, index) => {
|
stationData[data].forEach((D, index) => {
|
||||||
@@ -66,7 +65,7 @@ export const TrainMenuLineSelector = () => {
|
|||||||
""
|
""
|
||||||
).split(",");
|
).split(",");
|
||||||
if (latlng.length == 0) return null;
|
if (latlng.length == 0) return null;
|
||||||
if (index == 0 ) {
|
if (index == 0) {
|
||||||
webview.current
|
webview.current
|
||||||
?.injectJavaScript(`MoveDisplayStation('${data}_${D.MyStation}_${D.Station_JP}');
|
?.injectJavaScript(`MoveDisplayStation('${data}_${D.MyStation}_${D.Station_JP}');
|
||||||
document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`);
|
document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`);
|
||||||
|
@@ -4,11 +4,15 @@ import { JRSTraInfo } from "./JRSTraInfo";
|
|||||||
import { StationDeteilView } from "./StationDeteilView";
|
import { StationDeteilView } from "./StationDeteilView";
|
||||||
import { TrainMenuLineSelector } from "./TrainMenuLineSelector";
|
import { TrainMenuLineSelector } from "./TrainMenuLineSelector";
|
||||||
import { TrainIconUpdate } from "./TrainIconUpdate";
|
import { TrainIconUpdate } from "./TrainIconUpdate";
|
||||||
|
import { SpecialTrainInfo } from "./SpecialTrainInfo";
|
||||||
|
import { Social } from "./SocialMenu";
|
||||||
|
|
||||||
registerSheet("EachTrainInfo", EachTrainInfo);
|
registerSheet("EachTrainInfo", EachTrainInfo);
|
||||||
registerSheet("JRSTraInfo", JRSTraInfo);
|
registerSheet("JRSTraInfo", JRSTraInfo);
|
||||||
registerSheet("StationDetailView", StationDeteilView);
|
registerSheet("StationDetailView", StationDeteilView);
|
||||||
registerSheet("TrainMenuLineSelector", TrainMenuLineSelector);
|
registerSheet("TrainMenuLineSelector", TrainMenuLineSelector);
|
||||||
registerSheet("TrainIconUpdate", TrainIconUpdate);
|
registerSheet("TrainIconUpdate", TrainIconUpdate);
|
||||||
|
registerSheet("SpecialTrainInfo", SpecialTrainInfo);
|
||||||
|
registerSheet("Social", Social);
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
@@ -21,7 +21,7 @@ import { BigButton } from "./atom/BigButton";
|
|||||||
import { Switch } from "react-native-elements";
|
import { Switch } from "react-native-elements";
|
||||||
export default function AllTrainDiagramView() {
|
export default function AllTrainDiagramView() {
|
||||||
const { goBack, navigate } = useNavigation();
|
const { goBack, navigate } = useNavigation();
|
||||||
const { keyList, allTrainDiagram } = useAllTrainDiagram();
|
const { keyList, allTrainDiagram, allCustonTrainData } = useAllTrainDiagram();
|
||||||
const [input, setInput] = useState(""); // 文字入力
|
const [input, setInput] = useState(""); // 文字入力
|
||||||
const [keyBoardVisible, setKeyBoardVisible] = useState(false);
|
const [keyBoardVisible, setKeyBoardVisible] = useState(false);
|
||||||
const [useStationName, setUseStationName] = useState(false);
|
const [useStationName, setUseStationName] = useState(false);
|
||||||
@@ -53,7 +53,7 @@ export default function AllTrainDiagramView() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const openTrainInfo = (d) => {
|
const openTrainInfo = (d) => {
|
||||||
const train = customTrainDataDetector(d);
|
const train = customTrainDataDetector(d, allCustonTrainData);
|
||||||
let TrainNumber = "";
|
let TrainNumber = "";
|
||||||
if (train.trainNumDistance != undefined) {
|
if (train.trainNumDistance != undefined) {
|
||||||
const timeInfo =
|
const timeInfo =
|
||||||
@@ -74,6 +74,7 @@ export default function AllTrainDiagramView() {
|
|||||||
return (
|
return (
|
||||||
<View style={{ backgroundColor: "#0099CC", height: "100%" }}>
|
<View style={{ backgroundColor: "#0099CC", height: "100%" }}>
|
||||||
<FlatList
|
<FlatList
|
||||||
|
contentContainerStyle={{ justifyContent: "flex-end", flexGrow: 1 }}
|
||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
data={keyList?.filter((d) => {
|
data={keyList?.filter((d) => {
|
||||||
if (useStationName) {
|
if (useStationName) {
|
||||||
@@ -93,6 +94,14 @@ export default function AllTrainDiagramView() {
|
|||||||
return d.includes(input);
|
return d.includes(input);
|
||||||
})}
|
})}
|
||||||
renderItem={({ item }) => <Item {...{ openTrainInfo, id: item }} />}
|
renderItem={({ item }) => <Item {...{ openTrainInfo, id: item }} />}
|
||||||
|
ListEmptyComponent={
|
||||||
|
<View style={{ flex: 1, alignItems: "center", marginTop: 50 }}>
|
||||||
|
<Text style={{ color: "white", fontSize: 20 }}>
|
||||||
|
検索結果がありません。
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
}
|
||||||
|
|
||||||
keyExtractor={(item) => item}
|
keyExtractor={(item) => item}
|
||||||
//initialNumToRender={100}
|
//initialNumToRender={100}
|
||||||
/>
|
/>
|
||||||
|
@@ -11,7 +11,7 @@ export const getDelayData = async () => {
|
|||||||
// Fetch data from the server
|
// Fetch data from the server
|
||||||
const time = dayjs().format("HH:mm");
|
const time = dayjs().format("HH:mm");
|
||||||
const delayString = await fetch(
|
const delayString = await fetch(
|
||||||
"https://script.google.com/macros/s/AKfycbyKxch7z7l8e07LXulRHqxjVoIiB13kcgvoToLE-rqlxLmLSKdlmqz0FI1F2EuA7Zfg/exec"
|
"https://script.google.com/macros/s/AKfycbw-0RDLAu8EQAEWA860tk4KVW6VOr3iIU900AcWEfqIP16gtNUG1XO_A3oBfAGiNeCf/exec"
|
||||||
)
|
)
|
||||||
.then((response) => response.text())
|
.then((response) => response.text())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
|
@@ -36,8 +36,7 @@ export default function Apps() {
|
|||||||
const { isLandscape } = useDeviceOrientationChange();
|
const { isLandscape } = useDeviceOrientationChange();
|
||||||
const handleLayout = () => {};
|
const handleLayout = () => {};
|
||||||
const { originalStationList } = useStationList();
|
const { originalStationList } = useStationList();
|
||||||
const { setInjectJavaScript, mapSwitch, trainInfo, setTrainInfo } =
|
const { mapSwitch, trainInfo, setTrainInfo } = useTrainMenu();
|
||||||
useTrainMenu();
|
|
||||||
|
|
||||||
const openStationACFromEachTrainInfo = async (stationName) => {
|
const openStationACFromEachTrainInfo = async (stationName) => {
|
||||||
await SheetManager.hide("EachTrainInfo");
|
await SheetManager.hide("EachTrainInfo");
|
||||||
@@ -60,7 +59,7 @@ export default function Apps() {
|
|||||||
useShow: () => SheetManager.show("StationDetailView", { payload }),
|
useShow: () => SheetManager.show("StationDetailView", { payload }),
|
||||||
onExit: () => SheetManager.hide("StationDetailView"),
|
onExit: () => SheetManager.hide("StationDetailView"),
|
||||||
};
|
};
|
||||||
setTimeout(()=>SheetManager.show("StationDetailView", { payload }),50);
|
setTimeout(() => SheetManager.show("StationDetailView", { payload }), 50);
|
||||||
} else {
|
} else {
|
||||||
SheetManager.hide("StationDetailView");
|
SheetManager.hide("StationDetailView");
|
||||||
}
|
}
|
||||||
@@ -110,7 +109,6 @@ export default function Apps() {
|
|||||||
{isLandscape || (
|
{isLandscape || (
|
||||||
<MapsButton
|
<MapsButton
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
setInjectJavaScript("");
|
|
||||||
navigate("trainMenu", { webview });
|
navigate("trainMenu", { webview });
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@@ -2,7 +2,13 @@ import React from "react";
|
|||||||
import { Platform, LayoutAnimation } from "react-native";
|
import { Platform, LayoutAnimation } from "react-native";
|
||||||
import { WebView } from "react-native-webview";
|
import { WebView } from "react-native-webview";
|
||||||
|
|
||||||
import { lineList } from "../../lib/getStationList";
|
import {
|
||||||
|
lineList,
|
||||||
|
lineList_LineWebID,
|
||||||
|
lineListPair,
|
||||||
|
stationIDPair,
|
||||||
|
stationNamePair,
|
||||||
|
} from "../../lib/getStationList";
|
||||||
import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData";
|
import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData";
|
||||||
import { useFavoriteStation } from "../../stateBox/useFavoriteStation";
|
import { useFavoriteStation } from "../../stateBox/useFavoriteStation";
|
||||||
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
|
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
|
||||||
@@ -11,14 +17,13 @@ import { SheetManager } from "react-native-actions-sheet";
|
|||||||
|
|
||||||
import { useNavigation } from "@react-navigation/native";
|
import { useNavigation } from "@react-navigation/native";
|
||||||
import { useTrainMenu } from "../../stateBox/useTrainMenu";
|
import { useTrainMenu } from "../../stateBox/useTrainMenu";
|
||||||
import { stationNamePair } from "../../lib/getStationList2";
|
|
||||||
import { useStationList } from "../../stateBox/useStationList";
|
import { useStationList } from "../../stateBox/useStationList";
|
||||||
export const AppsWebView = ({ openStationACFromEachTrainInfo }) => {
|
export const AppsWebView = ({ openStationACFromEachTrainInfo }) => {
|
||||||
const { webview, currentTrain } = useCurrentTrain();
|
const { webview, currentTrain } = useCurrentTrain();
|
||||||
const { navigate } = useNavigation();
|
const { navigate } = useNavigation();
|
||||||
const { favoriteStation } = useFavoriteStation();
|
const { favoriteStation } = useFavoriteStation();
|
||||||
const { isLandscape } = useDeviceOrientationChange();
|
const { isLandscape } = useDeviceOrientationChange();
|
||||||
const { originalStationList, stationList } = useStationList();
|
const { originalStationList, stationList, getInjectJavascriptAddress } = useStationList();
|
||||||
const {
|
const {
|
||||||
setSelectedLine,
|
setSelectedLine,
|
||||||
mapsStationData: stationData,
|
mapsStationData: stationData,
|
||||||
@@ -130,20 +135,11 @@ export const AppsWebView = ({ openStationACFromEachTrainInfo }) => {
|
|||||||
const onLoadEnd = () => {
|
const onLoadEnd = () => {
|
||||||
if (once) return () => {};
|
if (once) return () => {};
|
||||||
if (!stationData) return () => {};
|
if (!stationData) return () => {};
|
||||||
|
if (!originalStationList) return () => {};
|
||||||
if (favoriteStation.length < 1) return () => {};
|
if (favoriteStation.length < 1) return () => {};
|
||||||
const getStationLine = (now) => {
|
const string = getInjectJavascriptAddress(favoriteStation[0][0].StationNumber);
|
||||||
const returnData = Object.keys(stationData).filter((d) => {
|
if (!string) return () => {};
|
||||||
const cache = stationData[d].findIndex(
|
webview?.current.injectJavaScript(string);
|
||||||
(data) => data.Station_JP == now.Station_JP
|
|
||||||
);
|
|
||||||
return cache != -1;
|
|
||||||
});
|
|
||||||
return returnData[0];
|
|
||||||
};
|
|
||||||
const lineName = getStationLine(favoriteStation[0][0]);
|
|
||||||
webview.current?.injectJavaScript(
|
|
||||||
`MoveDisplayStation('${lineName}_${favoriteStation[0][0].MyStation}_${favoriteStation[0][0].Station_JP}')`
|
|
||||||
);
|
|
||||||
once = true;
|
once = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -6,7 +6,6 @@ import { AS } from "../storageControl";
|
|||||||
export const DynamicHeaderScrollView = (props) => {
|
export const DynamicHeaderScrollView = (props) => {
|
||||||
const {
|
const {
|
||||||
children,
|
children,
|
||||||
actionSheetRef = {},
|
|
||||||
containerProps = {},
|
containerProps = {},
|
||||||
shortHeader = <></>,
|
shortHeader = <></>,
|
||||||
longHeader = <></>,
|
longHeader = <></>,
|
||||||
|
@@ -8,11 +8,13 @@ import { useNavigation } from "@react-navigation/native";
|
|||||||
import { useTrainMenu } from "../stateBox/useTrainMenu";
|
import { useTrainMenu } from "../stateBox/useTrainMenu";
|
||||||
import { FavoriteListItem } from "./atom/FavoriteListItem";
|
import { FavoriteListItem } from "./atom/FavoriteListItem";
|
||||||
import { BigButton } from "./atom/BigButton";
|
import { BigButton } from "./atom/BigButton";
|
||||||
|
import { useStationList } from "@/stateBox/useStationList";
|
||||||
export const FavoriteList: FC = () => {
|
export const FavoriteList: FC = () => {
|
||||||
const { favoriteStation } = useFavoriteStation();
|
const { favoriteStation } = useFavoriteStation();
|
||||||
const { webview } = useCurrentTrain();
|
const { webview } = useCurrentTrain();
|
||||||
const { navigate, addListener, goBack, canGoBack } = useNavigation();
|
const { navigate, addListener, goBack, canGoBack } = useNavigation();
|
||||||
const { mapsStationData: stationData } = useTrainMenu();
|
const { mapsStationData: stationData } = useTrainMenu();
|
||||||
|
const { getInjectJavascriptAddress } = useStationList();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unsubscribe = addListener("tabPress", goToTrainMenu);
|
const unsubscribe = addListener("tabPress", goToTrainMenu);
|
||||||
@@ -38,27 +40,16 @@ export const FavoriteList: FC = () => {
|
|||||||
</Text>
|
</Text>
|
||||||
<ScrollView style={{ height: "100%", backgroundColor: "white" }}>
|
<ScrollView style={{ height: "100%", backgroundColor: "white" }}>
|
||||||
{favoriteStation
|
{favoriteStation
|
||||||
.filter((d) => d[0].StationMap)
|
|
||||||
.map((currentStation) => {
|
.map((currentStation) => {
|
||||||
return (
|
return (
|
||||||
<FavoriteListItem
|
<FavoriteListItem
|
||||||
currentStation={currentStation}
|
currentStation={currentStation}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
const getStationLine = (now) => {
|
const scriptString = getInjectJavascriptAddress(
|
||||||
const returnData = Object.keys(stationData).filter((d) => {
|
currentStation[0].StationNumber
|
||||||
const cache = stationData[d].findIndex(
|
|
||||||
(data) => data.Station_JP == now.Station_JP
|
|
||||||
);
|
|
||||||
return cache != -1;
|
|
||||||
});
|
|
||||||
return returnData[0];
|
|
||||||
};
|
|
||||||
const lineName = getStationLine(currentStation[0]);
|
|
||||||
|
|
||||||
webview.current?.injectJavaScript(
|
|
||||||
`MoveDisplayStation('${lineName}_${currentStation[0].MyStation}_${currentStation[0].Station_JP}');
|
|
||||||
document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`
|
|
||||||
);
|
);
|
||||||
|
if (!scriptString) return;
|
||||||
|
webview.current?.injectJavaScript(scriptString);
|
||||||
goBack();
|
goBack();
|
||||||
if (canGoBack()) goBack();
|
if (canGoBack()) goBack();
|
||||||
}}
|
}}
|
||||||
|
186
components/Menu/Carousel/CarouselBox.tsx
Normal file
186
components/Menu/Carousel/CarouselBox.tsx
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
import Sign from "@/components/駅名表/Sign";
|
||||||
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
|
import { AS } from "@/storageControl";
|
||||||
|
import {
|
||||||
|
useWindowDimensions,
|
||||||
|
View,
|
||||||
|
LayoutAnimation,
|
||||||
|
TouchableOpacity,
|
||||||
|
Text,
|
||||||
|
ScrollView,
|
||||||
|
} from "react-native";
|
||||||
|
import Carousel, { ICarouselInstance } from "react-native-reanimated-carousel";
|
||||||
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
|
import { StationNumber } from "../StationPagination";
|
||||||
|
import { SimpleDot } from "../SimpleDot";
|
||||||
|
export const CarouselBox = ({
|
||||||
|
originalStationList,
|
||||||
|
listUpStation,
|
||||||
|
nearPositionStation,
|
||||||
|
setListIndex,
|
||||||
|
listIndex,
|
||||||
|
navigate,
|
||||||
|
stationListMode,
|
||||||
|
isSearchMode
|
||||||
|
}) => {
|
||||||
|
const carouselRef = useRef<ICarouselInstance>(null);
|
||||||
|
const { height, width } = useWindowDimensions();
|
||||||
|
const [dotButton, setDotButton] = useState(false);
|
||||||
|
const carouselBadgeScrollViewRef = useRef<ScrollView>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!carouselBadgeScrollViewRef.current) return;
|
||||||
|
const dotSize = dotButton ? 28 : 24;
|
||||||
|
const scrollToIndex = dotSize * listIndex - width / 2 + dotSize - 5;
|
||||||
|
carouselBadgeScrollViewRef.current.scrollTo({
|
||||||
|
x: scrollToIndex,
|
||||||
|
animated: true,
|
||||||
|
});
|
||||||
|
}, [listIndex, dotButton, width, carouselBadgeScrollViewRef]);
|
||||||
|
const oPSign = () => {
|
||||||
|
const payload = {
|
||||||
|
currentStation: listUpStation[listIndex],
|
||||||
|
navigate,
|
||||||
|
goTo: "menu",
|
||||||
|
//@ts-ignore
|
||||||
|
useShow: () => SheetManager.show("StationDetailView", { payload }),
|
||||||
|
onExit: () => SheetManager.hide("StationDetailView"),
|
||||||
|
};
|
||||||
|
//@ts-ignore
|
||||||
|
SheetManager.show("StationDetailView", { payload });
|
||||||
|
};
|
||||||
|
const oLPSign = () => {
|
||||||
|
LayoutAnimation.configureNext({
|
||||||
|
duration: 600,
|
||||||
|
update: { type: "spring", springDamping: 0.5 },
|
||||||
|
});
|
||||||
|
AS.setItem(
|
||||||
|
"CarouselSettings/activeDotSettings",
|
||||||
|
!dotButton ? "true" : "false"
|
||||||
|
);
|
||||||
|
setDotButton(!dotButton);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
AS.getItem("CarouselSettings/activeDotSettings").then((data) => {
|
||||||
|
setDotButton(data === "true");
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
const RenderItem = ({ item, index }) => {
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#0000",
|
||||||
|
width,
|
||||||
|
flexDirection: "row",
|
||||||
|
marginLeft: 0,
|
||||||
|
marginRight: 0,
|
||||||
|
}}
|
||||||
|
key={item[0].StationNumber}
|
||||||
|
>
|
||||||
|
<View style={{ flex: 1 }} />
|
||||||
|
{item[0].StationNumber != "null" ? (
|
||||||
|
<Sign
|
||||||
|
stationID={item[0].StationNumber}
|
||||||
|
isCurrentStation={item == nearPositionStation}
|
||||||
|
oP={oPSign}
|
||||||
|
oLP={oLPSign}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
width: width * 0.8,
|
||||||
|
height: ((width * 0.8) / 20) * 9,
|
||||||
|
borderColor: "#0099CC",
|
||||||
|
borderWidth: 1,
|
||||||
|
backgroundColor: "white",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={{ color: "#0099CC", fontSize: 20 }}>
|
||||||
|
{!!isSearchMode ? "路線検索モードです。上に並んでいる路線を選んでみましょう!" :stationListMode == "position"
|
||||||
|
? "現在地の近くに駅がありません。"
|
||||||
|
: "お気に入りリストがありません。お気に入りの駅を追加しよう!"}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
<View style={{ flex: 1 }} />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<View style={{ flex: 1, paddingTop: 10 }}>
|
||||||
|
<Carousel
|
||||||
|
ref={carouselRef}
|
||||||
|
data={
|
||||||
|
listUpStation.length > 0
|
||||||
|
? listUpStation
|
||||||
|
: [[{ StationNumber: "null" }]]
|
||||||
|
}
|
||||||
|
height={(((width / 100) * 80) / 20) * 9 + 10}
|
||||||
|
pagingEnabled={true}
|
||||||
|
snapEnabled={true}
|
||||||
|
loop={false}
|
||||||
|
width={width}
|
||||||
|
style={{ width: width, alignContent: "center" }}
|
||||||
|
mode="parallax"
|
||||||
|
modeConfig={{
|
||||||
|
parallaxScrollingScale: 1,
|
||||||
|
parallaxScrollingOffset: 100,
|
||||||
|
parallaxAdjacentItemScale: 0.8,
|
||||||
|
}}
|
||||||
|
scrollAnimationDuration={600}
|
||||||
|
onSnapToItem={setListIndex}
|
||||||
|
renderItem={RenderItem}
|
||||||
|
overscrollEnabled={false}
|
||||||
|
defaultIndex={listIndex >= listUpStation.length ? 0 : listIndex}
|
||||||
|
/>
|
||||||
|
<ScrollView
|
||||||
|
horizontal
|
||||||
|
showsHorizontalScrollIndicator={false}
|
||||||
|
contentContainerStyle={{
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
paddingVertical: 2,
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
minWidth: width,
|
||||||
|
}}
|
||||||
|
ref={(scrollViewRef) => {
|
||||||
|
// ScrollViewのrefを保存
|
||||||
|
if (scrollViewRef) {
|
||||||
|
carouselBadgeScrollViewRef.current = scrollViewRef;
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{originalStationList &&
|
||||||
|
listUpStation.map((d, index) => {
|
||||||
|
const active = index == listIndex;
|
||||||
|
const numberKey = d[0].StationNumber + index;
|
||||||
|
return dotButton ? (
|
||||||
|
<StationNumber
|
||||||
|
onPress={() => setListIndex(index)}
|
||||||
|
currentStation={d}
|
||||||
|
active={active}
|
||||||
|
key={numberKey}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<SimpleDot
|
||||||
|
onPress={() => setListIndex(index)}
|
||||||
|
active={active}
|
||||||
|
key={numberKey}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
174
components/Menu/Carousel/CarouselTypeChanger.tsx
Normal file
174
components/Menu/Carousel/CarouselTypeChanger.tsx
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
import { AS } from "@/storageControl";
|
||||||
|
import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs";
|
||||||
|
import React, { useEffect, useRef } from "react";
|
||||||
|
import { useWindowDimensions } from "react-native";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
TouchableOpacity,
|
||||||
|
Text,
|
||||||
|
LayoutAnimation,
|
||||||
|
KeyboardAvoidingView,
|
||||||
|
Platform,
|
||||||
|
} from "react-native";
|
||||||
|
import Ionicons from "react-native-vector-icons/Ionicons";
|
||||||
|
import { SearchUnitBox } from "@/components/Menu/RailScope/SearchUnitBox";
|
||||||
|
|
||||||
|
export const CarouselTypeChanger = ({
|
||||||
|
locationStatus,
|
||||||
|
position,
|
||||||
|
mapsRef,
|
||||||
|
scrollRef,
|
||||||
|
stationListMode,
|
||||||
|
setStationListMode,
|
||||||
|
setSelectedCurrentStation,
|
||||||
|
mapMode,
|
||||||
|
setMapMode,
|
||||||
|
isSearchMode,
|
||||||
|
setisSearchMode,
|
||||||
|
}) => {
|
||||||
|
const tabBarHeight = useBottomTabBarHeight();
|
||||||
|
const { height, width } = useWindowDimensions();
|
||||||
|
const returnToDefaultMode = () => {
|
||||||
|
LayoutAnimation.configureNext({
|
||||||
|
duration: 300,
|
||||||
|
create: {
|
||||||
|
type: LayoutAnimation.Types.easeInEaseOut,
|
||||||
|
property: LayoutAnimation.Properties.opacity,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
type: LayoutAnimation.Types.easeInEaseOut,
|
||||||
|
property: LayoutAnimation.Properties.opacity,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
setMapMode(false);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<KeyboardAvoidingView
|
||||||
|
behavior="padding"
|
||||||
|
keyboardVerticalOffset={80}
|
||||||
|
enabled={Platform.OS === "ios"}
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
height: 40,
|
||||||
|
flexDirection: "row",
|
||||||
|
position: mapMode ? "absolute" : "relative",
|
||||||
|
bottom: mapMode ? 0 : undefined,
|
||||||
|
zIndex: 1000,
|
||||||
|
backgroundColor: "white",
|
||||||
|
}}
|
||||||
|
key={"carouselTypeChanger"}
|
||||||
|
>
|
||||||
|
<SearchUnitBox
|
||||||
|
isSearchMode={isSearchMode}
|
||||||
|
setisSearchMode={setisSearchMode}
|
||||||
|
/>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor:
|
||||||
|
stationListMode == "position" ? "#0099CC" : "#0099CC80",
|
||||||
|
padding: 5,
|
||||||
|
alignItems: "center",
|
||||||
|
flexDirection: "row",
|
||||||
|
marginHorizontal: 5,
|
||||||
|
borderTopLeftRadius: 20,
|
||||||
|
borderTopRightRadius: 20,
|
||||||
|
borderBottomLeftRadius: mapMode ? 0 : 20,
|
||||||
|
borderBottomRightRadius: mapMode ? 0 : 20,
|
||||||
|
}}
|
||||||
|
disabled={!locationStatus}
|
||||||
|
onPressIn={() => {
|
||||||
|
if (!position) return;
|
||||||
|
returnToDefaultMode();
|
||||||
|
setStationListMode("position");
|
||||||
|
AS.setItem("stationListMode", "position");
|
||||||
|
setSelectedCurrentStation(0);
|
||||||
|
}}
|
||||||
|
onPress={() => {
|
||||||
|
if (!position) return;
|
||||||
|
returnToDefaultMode();
|
||||||
|
setStationListMode("position");
|
||||||
|
AS.setItem("stationListMode", "position");
|
||||||
|
setSelectedCurrentStation(0);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name="locate-outline"
|
||||||
|
size={14}
|
||||||
|
color="white"
|
||||||
|
style={{ margin: 5 }}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: "bold",
|
||||||
|
flex: 1,
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
現在地基準
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
padding: 5,
|
||||||
|
alignItems: "center",
|
||||||
|
flexDirection: "row",
|
||||||
|
marginHorizontal: 5,
|
||||||
|
borderRadius: 50,
|
||||||
|
}}
|
||||||
|
onPressIn={() => returnToDefaultMode()}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name={!mapMode ? "menu" : "chevron-up-outline"}
|
||||||
|
size={30}
|
||||||
|
color="#0099CC"
|
||||||
|
style={{ marginHorizontal: 5 }}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor:
|
||||||
|
stationListMode == "favorite" ? "#0099CC" : "#0099CC80",
|
||||||
|
padding: 5,
|
||||||
|
alignItems: "center",
|
||||||
|
flexDirection: "row",
|
||||||
|
marginHorizontal: 5,
|
||||||
|
borderTopLeftRadius: 20,
|
||||||
|
borderTopRightRadius: 20,
|
||||||
|
borderBottomLeftRadius: mapMode ? 0 : 20,
|
||||||
|
borderBottomRightRadius: mapMode ? 0 : 20,
|
||||||
|
}}
|
||||||
|
onPressIn={() => {
|
||||||
|
returnToDefaultMode();
|
||||||
|
// お気に入りリスト更新
|
||||||
|
setStationListMode("favorite");
|
||||||
|
AS.setItem("stationListMode", "favorite");
|
||||||
|
setSelectedCurrentStation(0);
|
||||||
|
}}
|
||||||
|
onPress={() => {
|
||||||
|
returnToDefaultMode();
|
||||||
|
// お気に入りリスト更新
|
||||||
|
setStationListMode("favorite");
|
||||||
|
AS.setItem("stationListMode", "favorite");
|
||||||
|
setSelectedCurrentStation(0);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ionicons name="star" size={14} color="white" style={{ margin: 5 }} />
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: "bold",
|
||||||
|
flex: 1,
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
お気に入りリスト
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</KeyboardAvoidingView>
|
||||||
|
);
|
||||||
|
};
|
@@ -6,10 +6,12 @@ import {
|
|||||||
MaterialCommunityIcons,
|
MaterialCommunityIcons,
|
||||||
} from "@expo/vector-icons";
|
} from "@expo/vector-icons";
|
||||||
import { ListItem } from "@rneui/themed";
|
import { ListItem } from "@rneui/themed";
|
||||||
import TouchableScale from 'react-native-touchable-scale';
|
import TouchableScale from "react-native-touchable-scale";
|
||||||
import Icon from "react-native-vector-icons/Entypo";
|
import Icon from "react-native-vector-icons/Entypo";
|
||||||
import { TextBox } from "../atom/TextBox";
|
import { TextBox } from "../atom/TextBox";
|
||||||
import { TicketBox } from "../atom/TicketBox";
|
import { TicketBox } from "../atom/TicketBox";
|
||||||
|
import { SpecialTrainInfoBox } from "./SpecialTrainInfoBox";
|
||||||
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
|
|
||||||
export const FixedContentBottom = (props) => {
|
export const FixedContentBottom = (props) => {
|
||||||
return (
|
return (
|
||||||
@@ -54,7 +56,9 @@ export const FixedContentBottom = (props) => {
|
|||||||
backgroundColor="red"
|
backgroundColor="red"
|
||||||
flex={1}
|
flex={1}
|
||||||
onPressButton={() =>
|
onPressButton={() =>
|
||||||
Linking.openURL("https://xprocess.haruk.in/JR-shikoku-Apps-Common/2025-update-status")
|
Linking.openURL(
|
||||||
|
"https://xprocess.haruk.in/JR-shikoku-Apps-Common/2025-update-status"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Text style={{ color: "white", fontWeight: "bold", fontSize: 20 }}>
|
<Text style={{ color: "white", fontWeight: "bold", fontSize: 20 }}>
|
||||||
@@ -82,7 +86,9 @@ export const FixedContentBottom = (props) => {
|
|||||||
backgroundColor="#0099CC"
|
backgroundColor="#0099CC"
|
||||||
flex={1}
|
flex={1}
|
||||||
onPressButton={() =>
|
onPressButton={() =>
|
||||||
Linking.openURL("https://www.jr-shikoku.co.jp/sp/index.html#menu-box")
|
SheetManager.show("SpecialTrainInfo", {
|
||||||
|
payload: { navigate: props.navigate },
|
||||||
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Text style={{ color: "white", fontWeight: "bold", fontSize: 20 }}>
|
<Text style={{ color: "white", fontWeight: "bold", fontSize: 20 }}>
|
||||||
@@ -179,105 +185,20 @@ export const FixedContentBottom = (props) => {
|
|||||||
<Text style={{ color: "white" }}>(通話料がかかります)</Text>
|
<Text style={{ color: "white" }}>(通話料がかかります)</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
<View
|
<TextBox
|
||||||
style={{
|
backgroundColor="#0099CC"
|
||||||
backgroundColor: "#0099CC",
|
flex={1}
|
||||||
borderRadius: 10,
|
onPressButton={() =>
|
||||||
margin: 10,
|
SheetManager.show("Social")
|
||||||
borderColor: "black",
|
}
|
||||||
borderWidth: 2,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<View
|
<Text style={{ color: "white", fontWeight: "bold", fontSize: 20 }}>
|
||||||
style={{ padding: 10, flexDirection: "row", alignItems: "center" }}
|
ソーシャルメディア
|
||||||
>
|
</Text>
|
||||||
<MaterialCommunityIcons
|
<Text style={{ color: "white", fontSize: 18 }}>
|
||||||
name="twitter"
|
JR四国のSNS一覧です。
|
||||||
style={{ padding: 5 }}
|
</Text>
|
||||||
color="white"
|
</TextBox>
|
||||||
size={30}
|
|
||||||
/>
|
|
||||||
<Text style={{ fontSize: 30, fontWeight: "bold", color: "white" }}>
|
|
||||||
JR四国公式Twitter一族
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
<View
|
|
||||||
style={{
|
|
||||||
padding: 10,
|
|
||||||
backgroundColor: "white",
|
|
||||||
borderBottomLeftRadius: 10,
|
|
||||||
borderBottomRightRadius: 10,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{[
|
|
||||||
{
|
|
||||||
url: "https://twitter.com/jr_shikoku_info",
|
|
||||||
name: "JR四国列車運行情報",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "https://twitter.com/JRshikoku_eigyo",
|
|
||||||
name: "JR四国営業部【公式】",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: "https://twitter.com/JRshikoku_tokyo",
|
|
||||||
name: "JR四国 東京営業情報【公式】",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: "https://twitter.com/JRshikoku_osaka",
|
|
||||||
name: "JR四国 大阪営業部【公式】",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: "https://twitter.com/jrs_matsuyama",
|
|
||||||
name: "JR四国 松山駅 【公式】",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: "https://twitter.com/jrshikoku_kochi",
|
|
||||||
name: "JR四国 高知駅【公式】",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: "https://twitter.com/jr_tokust",
|
|
||||||
name: "JR四国 徳島駅【公式】",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: "https://twitter.com/jrshikoku_uwjm",
|
|
||||||
name: "JR四国 宇和島駅【公式】",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: "https://twitter.com/jrshikoku_wkama",
|
|
||||||
name: "JR四国 ワープ高松支店【公式】",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: "https://twitter.com/JRshikoku_wkoch",
|
|
||||||
name: "JR四国 ワープ高知支店【公式】",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: "https://twitter.com/Yoakemonogatari",
|
|
||||||
name: "志国土佐 時代の夜明けのものがたり【公式】",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: "https://twitter.com/Smile_Eki_Chan",
|
|
||||||
name: "すまいるえきちゃん♡JR四国【公式】",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: "https://twitter.com/sper_ponchan",
|
|
||||||
name: "しこくたぬきのぽんちゃん 【四国家サポーターズクラブ】",
|
|
||||||
},
|
|
||||||
].map((d) => (
|
|
||||||
<ListItem bottomDivider onPress={() => Linking.openURL(d.url)}
|
|
||||||
key={d.url}friction={90} //
|
|
||||||
tension={100} // These props are passed to the parent component (here TouchableScale)
|
|
||||||
activeScale={0.95} //
|
|
||||||
Component={TouchableScale}
|
|
||||||
>
|
|
||||||
<ListItem.Content>
|
|
||||||
<ListItem.Title>{d.name}</ListItem.Title>
|
|
||||||
</ListItem.Content>
|
|
||||||
<ListItem.Chevron />
|
|
||||||
</ListItem>
|
|
||||||
))}
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<Text style={{ fontWeight: "bold", fontSize: 20 }}>上級者向け機能</Text>
|
<Text style={{ fontWeight: "bold", fontSize: 20 }}>上級者向け機能</Text>
|
||||||
<TextBox
|
<TextBox
|
||||||
backgroundColor="#8c00d6"
|
backgroundColor="#8c00d6"
|
||||||
|
111
components/Menu/JRSTraInfoBox.tsx
Normal file
111
components/Menu/JRSTraInfoBox.tsx
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TouchableOpacity,
|
||||||
|
ScrollView,
|
||||||
|
StyleProp,
|
||||||
|
ViewStyle,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
|
import LottieView from "lottie-react-native";
|
||||||
|
import { useTrainDelayData } from "@/stateBox/useTrainDelayData";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
export const JRSTraInfoBox = () => {
|
||||||
|
const { getTime, delayData, loadingDelayData, setLoadingDelayData } =
|
||||||
|
useTrainDelayData();
|
||||||
|
const styles: { [key: string]: StyleProp<ViewStyle> } = {
|
||||||
|
touch: {
|
||||||
|
backgroundColor: "#0099CC",
|
||||||
|
borderRadius: 5,
|
||||||
|
margin: 10,
|
||||||
|
borderColor: "black",
|
||||||
|
borderWidth: 2,
|
||||||
|
overflow: "hidden",
|
||||||
|
},
|
||||||
|
scroll: {
|
||||||
|
backgroundColor: "#0099CC",
|
||||||
|
borderRadius: 5,
|
||||||
|
maxHeight: 300,
|
||||||
|
},
|
||||||
|
bottom: {
|
||||||
|
position: "absolute",
|
||||||
|
top: 250,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "100%",
|
||||||
|
height: 50,
|
||||||
|
backgroundColor: "#007FCC88",
|
||||||
|
},
|
||||||
|
box: {
|
||||||
|
padding: 10,
|
||||||
|
backgroundColor: "white",
|
||||||
|
borderBottomLeftRadius: 5,
|
||||||
|
borderBottomRightRadius: 5,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => SheetManager.show("JRSTraInfo")}
|
||||||
|
style={styles.touch}
|
||||||
|
>
|
||||||
|
<ScrollView scrollEnabled={false} style={styles.scroll}>
|
||||||
|
<View
|
||||||
|
style={{ padding: 10, flexDirection: "row", alignItems: "center" }}
|
||||||
|
>
|
||||||
|
<Text style={{ fontSize: 30, fontWeight: "bold", color: "white" }}>
|
||||||
|
列車遅延速報EX
|
||||||
|
</Text>
|
||||||
|
<View style={{ flex: 1 }} />
|
||||||
|
<Text style={{ fontSize: 30, fontWeight: "bold", color: "white" }}>
|
||||||
|
{getTime ? dayjs(getTime).format("HH:mm") : NaN}
|
||||||
|
</Text>
|
||||||
|
<Ionicons
|
||||||
|
name="reload"
|
||||||
|
color="white"
|
||||||
|
size={30}
|
||||||
|
style={{ margin: 5 }}
|
||||||
|
onPress={() => setLoadingDelayData(true)}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={styles.box}>
|
||||||
|
{loadingDelayData ? (
|
||||||
|
<View style={{ alignItems: "center" }}>
|
||||||
|
<LottieView
|
||||||
|
autoPlay
|
||||||
|
loop
|
||||||
|
style={{ width: 150, height: 150, backgroundColor: "#fff" }}
|
||||||
|
source={require("@/assets/51690-loading-diamonds.json")}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
) : delayData ? (
|
||||||
|
delayData.map((d, index, array) => {
|
||||||
|
let data = d.split(" ");
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
style={{ flexDirection: "row" }}
|
||||||
|
key={data[1] + "key" + index}
|
||||||
|
>
|
||||||
|
<Text style={{ flex: 15, fontSize: 18 }}>
|
||||||
|
{data[0].replace("\n", "")}
|
||||||
|
</Text>
|
||||||
|
<Text style={{ flex: 5, fontSize: 18 }}>{data[1]}</Text>
|
||||||
|
<Text style={{ flex: 6, fontSize: 18 }}>{data[3]}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
<Text>現在、5分以上の遅れはありません。</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
<View style={styles.bottom}>
|
||||||
|
<View style={{ flex: 1 }} />
|
||||||
|
<Text style={{ color: "white", fontWeight: "bold", fontSize: 20 }}>
|
||||||
|
詳細を見る
|
||||||
|
</Text>
|
||||||
|
<View style={{ flex: 1 }} />
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
};
|
114
components/Menu/RailScope/SearchUnitBox.tsx
Normal file
114
components/Menu/RailScope/SearchUnitBox.tsx
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {
|
||||||
|
TouchableOpacity,
|
||||||
|
Text,
|
||||||
|
View,
|
||||||
|
LayoutAnimation,
|
||||||
|
TextInput,
|
||||||
|
KeyboardAvoidingView,
|
||||||
|
Platform,
|
||||||
|
} from "react-native";
|
||||||
|
import Ionicons from "react-native-vector-icons/Ionicons";
|
||||||
|
import { useWindowDimensions } from "react-native";
|
||||||
|
import lineColorList from "@/assets/originData/lineColorList";
|
||||||
|
import { lineList_LineWebID, stationIDPair } from "@/lib/getStationList";
|
||||||
|
export const SearchUnitBox = ({ isSearchMode, setisSearchMode }) => {
|
||||||
|
const { height, width } = useWindowDimensions();
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
bottom: !!isSearchMode ? 0 : 60,
|
||||||
|
right: 0,
|
||||||
|
padding: !!isSearchMode ? 5 : 10,
|
||||||
|
margin: !!isSearchMode ? 0 : 10,
|
||||||
|
backgroundColor: "#0099CC",
|
||||||
|
borderRadius: !!isSearchMode ? 5 : 50,
|
||||||
|
width: !!isSearchMode ? width : 50,
|
||||||
|
zIndex: 1000,
|
||||||
|
}}
|
||||||
|
disabled={!!isSearchMode}
|
||||||
|
onPress={() => {
|
||||||
|
LayoutAnimation.configureNext({
|
||||||
|
duration: 100,
|
||||||
|
update: { type: "easeInEaseOut", springDamping: 0.6 },
|
||||||
|
});
|
||||||
|
setisSearchMode(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{!isSearchMode && <Ionicons name="search" size={30} color="white" />}
|
||||||
|
{!!isSearchMode && (
|
||||||
|
<View style={{ backgroundColor: "#0099CC" }}>
|
||||||
|
|
||||||
|
<View style={{ flexDirection: "row", alignItems: "center" }}>
|
||||||
|
<TouchableOpacity onPress={() => {
|
||||||
|
LayoutAnimation.configureNext({
|
||||||
|
duration: 100,
|
||||||
|
update: { type: "easeInEaseOut", springDamping: 0.6 },
|
||||||
|
});
|
||||||
|
setisSearchMode(false);
|
||||||
|
}}>
|
||||||
|
<Ionicons
|
||||||
|
name="arrow-back"
|
||||||
|
size={20}
|
||||||
|
color="white"
|
||||||
|
style={{ marginRight: 10 }}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
{Object.keys(lineList_LineWebID).map((d) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: lineColorList[stationIDPair[lineList_LineWebID[d]]],
|
||||||
|
padding: 5,
|
||||||
|
marginHorizontal: 2,
|
||||||
|
borderRadius: 10,
|
||||||
|
borderColor: "white",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderStyle: "solid",
|
||||||
|
alignItems: "center",
|
||||||
|
opacity: isSearchMode == stationIDPair[lineList_LineWebID[d]] ? 1 : !isSearchMode ? 1 : 0.5,
|
||||||
|
zIndex: 10,
|
||||||
|
}}
|
||||||
|
onPress={() => {
|
||||||
|
const id = stationIDPair[lineList_LineWebID[d]];
|
||||||
|
const s = isSearchMode == id ? undefined : id;
|
||||||
|
if (!s) return;
|
||||||
|
setisSearchMode(s);
|
||||||
|
}}
|
||||||
|
key={stationIDPair[lineList_LineWebID[d]]}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={{ color: "white", fontWeight: "bold", fontSize: 20 }}
|
||||||
|
>
|
||||||
|
{stationIDPair[lineList_LineWebID[d]]}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
))}
|
||||||
|
{/* <View
|
||||||
|
style={{
|
||||||
|
backgroundColor: "white",
|
||||||
|
borderRadius: 25,
|
||||||
|
height: 30,
|
||||||
|
paddingRight: 10,
|
||||||
|
paddingLeft: 10,
|
||||||
|
flex: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextInput
|
||||||
|
placeholder="駅名を入力してフィルタリングします。"
|
||||||
|
//onFocus={() => setKeyBoardVisible(true)}
|
||||||
|
onEndEditing={() => {}}
|
||||||
|
//onChange={(ret) => setInput(ret.nativeEvent.text)}
|
||||||
|
//value={input}
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
/>
|
||||||
|
</View> */}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</TouchableOpacity>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
66
components/Menu/SpecialTrainInfoBox.tsx
Normal file
66
components/Menu/SpecialTrainInfoBox.tsx
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { FC, useEffect, useLayoutEffect, useState } from "react";
|
||||||
|
import { View, Text, TouchableOpacity } from "react-native";
|
||||||
|
import { getPDFViewURL } from "@/lib/getPdfViewURL";
|
||||||
|
import { ScrollView, SheetManager } from "react-native-actions-sheet";
|
||||||
|
|
||||||
|
type props = {
|
||||||
|
navigate: (screen: string, params?: object) => void;
|
||||||
|
};
|
||||||
|
export const SpecialTrainInfoBox: FC<props> = ({ navigate }) => {
|
||||||
|
const [specialData, setSpecialData] = useState([]);
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
fetch("https://n8n.haruk.in/webhook/sptrainfo")
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((data) => setSpecialData(data.data))
|
||||||
|
.catch((err) => console.log(err));
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#0099CC",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<View style={{ flexDirection: "row", alignItems: "center" }}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 30,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "white",
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
paddingVertical: 5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
臨時列車情報
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<ScrollView
|
||||||
|
style={{
|
||||||
|
backgroundColor: "white",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{specialData.map((d) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => {
|
||||||
|
navigate("howto", {
|
||||||
|
info: getPDFViewURL("https://www.jr-shikoku.co.jp" + d.address),
|
||||||
|
goTo: "menu",
|
||||||
|
});
|
||||||
|
SheetManager.hide("SpecialTrainInfo");
|
||||||
|
}}
|
||||||
|
onLongPress={() => alert(d.description)}
|
||||||
|
key={d.address}
|
||||||
|
style={{
|
||||||
|
padding: 10,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomColor: "#ccc",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={{ color: "black", fontSize: 20 }}>{d.text}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
))}
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
@@ -1,18 +1,25 @@
|
|||||||
import { View, TouchableOpacity, Linking } from "react-native";
|
import { View, TouchableOpacity, Linking,Platform, Image, useWindowDimensions } from "react-native";
|
||||||
import AutoHeightImage from "react-native-auto-height-image";
|
import Constants from "expo-constants";
|
||||||
import { widthPercentageToDP as wp } from "react-native-responsive-screen";
|
|
||||||
|
|
||||||
export const TitleBar = () => {
|
export const TitleBar = () => {
|
||||||
|
const { width } = useWindowDimensions();
|
||||||
return (
|
return (
|
||||||
<View style={{ alignItems: "center" }}>
|
<View
|
||||||
|
style={{
|
||||||
|
alignItems: "center",
|
||||||
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
zIndex: 100,
|
||||||
|
paddingTop: Platform.OS == "ios" ? Constants.statusBarHeight : 0,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
onPress={() => Linking.openURL("https://www.jr-shikoku.co.jp")}
|
onPress={() => Linking.openURL("https://www.jr-shikoku.co.jp")}
|
||||||
>
|
>
|
||||||
<AutoHeightImage
|
<Image source={require("../../assets/Header.png")} style={{ width: width, resizeMode: "contain", backgroundColor: "white", height: 80 }} />
|
||||||
source={require("../../assets/Header.png")}
|
|
||||||
resizeMode="contain"
|
|
||||||
width={wp("100%")}
|
|
||||||
/>
|
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
52
components/Menu/TopMenuButton.tsx
Normal file
52
components/Menu/TopMenuButton.tsx
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Linking, View } from "react-native";
|
||||||
|
import { UsefulBox } from "@/components/TrainMenu/UsefulBox";
|
||||||
|
import MaterialCommunityIcons from "@expo/vector-icons/build/MaterialCommunityIcons";
|
||||||
|
export const TopMenuButton = () => {
|
||||||
|
const buttonList:{
|
||||||
|
backgroundColor: string;
|
||||||
|
icon: keyof typeof MaterialCommunityIcons.glyphMap;
|
||||||
|
onPress: () => void;
|
||||||
|
title: string;
|
||||||
|
}[] = [
|
||||||
|
{
|
||||||
|
backgroundColor: "#F89038",
|
||||||
|
icon: "train-car",
|
||||||
|
onPress: () =>
|
||||||
|
Linking.openURL("https://www.jr-shikoku.co.jp/01_trainbus/sp/"),
|
||||||
|
title: "駅・鉄道情報",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
backgroundColor: "#EA4752",
|
||||||
|
icon: "google-spreadsheet",
|
||||||
|
onPress: () =>
|
||||||
|
Linking.openURL(
|
||||||
|
"https://www.jr-shikoku.co.jp/01_trainbus/jikoku/sp/#mainprice-box"
|
||||||
|
),
|
||||||
|
title: "運賃表",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
backgroundColor: "#91C31F",
|
||||||
|
icon: "clipboard-list-outline",
|
||||||
|
onPress: () => Linking.openURL("https://www.jr-shikoku.co.jp/e5489/"),
|
||||||
|
title: "予約",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={{ flexDirection: "row" }}>
|
||||||
|
{buttonList.map((d, index) => (
|
||||||
|
<UsefulBox
|
||||||
|
backgroundColor={d.backgroundColor}
|
||||||
|
icon={d.icon}
|
||||||
|
flex={1}
|
||||||
|
onPressButton={d.onPress}
|
||||||
|
key={index + d.icon}
|
||||||
|
>
|
||||||
|
{d.title}
|
||||||
|
</UsefulBox>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
@@ -2,44 +2,18 @@ import React, { useEffect, useState } from "react";
|
|||||||
import Icon from "react-native-vector-icons/Entypo";
|
import Icon from "react-native-vector-icons/Entypo";
|
||||||
import { View, Text, TouchableOpacity, LayoutAnimation } from "react-native";
|
import { View, Text, TouchableOpacity, LayoutAnimation } from "react-native";
|
||||||
import lineColorList from "../../../assets/originData/lineColorList";
|
import lineColorList from "../../../assets/originData/lineColorList";
|
||||||
|
import Ionicons from "react-native-vector-icons/Ionicons";
|
||||||
import { AS } from "../../../storageControl";
|
import { AS } from "../../../storageControl";
|
||||||
|
|
||||||
export const FavoriteSettingsItem = ({
|
export const FavoriteSettingsItem = ({ currentStation }) => {
|
||||||
currentStation,
|
|
||||||
setFavoriteStation,
|
|
||||||
index,
|
|
||||||
array,
|
|
||||||
}) => {
|
|
||||||
const lineIDs = [];
|
const lineIDs = [];
|
||||||
const EachIDs = [];
|
const EachIDs = [];
|
||||||
console.log(currentStation);
|
|
||||||
currentStation.forEach((d) => {
|
currentStation.forEach((d) => {
|
||||||
if (!d.StationNumber) return;
|
if (!d.StationNumber) return;
|
||||||
const textArray = d.StationNumber.split("");
|
const textArray = d.StationNumber.split("");
|
||||||
lineIDs.push(textArray.filter((s) => "A" < s && s < "Z").join(""));
|
lineIDs.push(textArray.filter((s) => "A" < s && s < "Z").join(""));
|
||||||
EachIDs.push(textArray.filter((s) => "0" <= s && s <= "9").join(""));
|
EachIDs.push(textArray.filter((s) => "0" <= s && s <= "9").join(""));
|
||||||
});
|
});
|
||||||
const [head, setHead] = useState(false);
|
|
||||||
const [tail, setTail] = useState(false);
|
|
||||||
useEffect(() => {
|
|
||||||
switch (true) {
|
|
||||||
case array.length == 1:
|
|
||||||
setHead(true);
|
|
||||||
setTail(true);
|
|
||||||
break;
|
|
||||||
case index == 0:
|
|
||||||
setHead(true);
|
|
||||||
setTail(false);
|
|
||||||
break;
|
|
||||||
case index == array.length - 1:
|
|
||||||
setHead(false);
|
|
||||||
setTail(true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
setHead(false);
|
|
||||||
setTail(false);
|
|
||||||
}
|
|
||||||
}, [array]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{ flexDirection: "row", backgroundColor: "white" }}>
|
<View style={{ flexDirection: "row", backgroundColor: "white" }}>
|
||||||
@@ -47,7 +21,7 @@ export const FavoriteSettingsItem = ({
|
|||||||
style={{
|
style={{
|
||||||
width: 35,
|
width: 35,
|
||||||
position: "relative",
|
position: "relative",
|
||||||
marginHorizontal: 15,
|
marginHorizontal: 10,
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
height: "101%",
|
height: "101%",
|
||||||
}}
|
}}
|
||||||
@@ -91,43 +65,15 @@ export const FavoriteSettingsItem = ({
|
|||||||
>
|
>
|
||||||
<Text style={{ fontSize: 20 }}>{currentStation[0].Station_JP}</Text>
|
<Text style={{ fontSize: 20 }}>{currentStation[0].Station_JP}</Text>
|
||||||
<View style={{ flex: 1 }} />
|
<View style={{ flex: 1 }} />
|
||||||
<TouchableOpacity
|
</View>
|
||||||
style={{ marginHorizontal: 10, marginVertical: 4, width: 30 }}
|
<View
|
||||||
onPress={() => {
|
style={{
|
||||||
console.log("up");
|
alignContent: "center",
|
||||||
LayoutAnimation.configureNext(
|
alignItems: "center",
|
||||||
LayoutAnimation.Presets.easeInEaseOut
|
alignSelf: "center",
|
||||||
);
|
}}
|
||||||
const removedStation = [...array].filter((d, i) => {
|
>
|
||||||
if (i == index) return false;
|
<Ionicons name={"reorder-two"} size={20} style={{ marginHorizontal: 10 }} />
|
||||||
return true;
|
|
||||||
});
|
|
||||||
removedStation.splice(index - 1, 0, currentStation);
|
|
||||||
setFavoriteStation(removedStation);
|
|
||||||
|
|
||||||
AS.setItem("favoriteStation", JSON.stringify(removedStation));
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{head ? null : <Icon name="chevron-up" size={26} />}
|
|
||||||
</TouchableOpacity>
|
|
||||||
<TouchableOpacity
|
|
||||||
style={{ marginHorizontal: 10, marginVertical: 4, width: 30 }}
|
|
||||||
onPress={() => {
|
|
||||||
console.log("down");
|
|
||||||
LayoutAnimation.configureNext(
|
|
||||||
LayoutAnimation.Presets.easeInEaseOut
|
|
||||||
);
|
|
||||||
const removedStation = [...array].filter((d, i) => {
|
|
||||||
if (i == index) return false;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
removedStation.splice(index + 1, 0, currentStation);
|
|
||||||
setFavoriteStation(removedStation);
|
|
||||||
AS.setItem("favoriteStation", JSON.stringify(removedStation));
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{tail ? null : <Icon name="chevron-down" size={26} />}
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
@@ -1,31 +1,58 @@
|
|||||||
import React from "react";
|
import React, { useCallback } from "react";
|
||||||
import { View, Text, TouchableOpacity, ScrollView } from "react-native";
|
import { View, Text, StyleSheet } from "react-native";
|
||||||
|
import Animated, { useAnimatedRef } from "react-native-reanimated";
|
||||||
import { useNavigation } from "@react-navigation/native";
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import Sortable from "react-native-sortables";
|
||||||
import { useFavoriteStation } from "../../stateBox/useFavoriteStation";
|
import { useFavoriteStation } from "../../stateBox/useFavoriteStation";
|
||||||
import { CheckBox } from "react-native-elements";
|
|
||||||
import { FavoriteSettingsItem } from "./FavoliteSettings/FavoiliteSettingsItem";
|
import { FavoriteSettingsItem } from "./FavoliteSettings/FavoiliteSettingsItem";
|
||||||
import { SheetHeaderItem } from "@/components/atom/SheetHeaderItem";
|
import { SheetHeaderItem } from "@/components/atom/SheetHeaderItem";
|
||||||
|
import { AS } from "@/storageControl";
|
||||||
|
|
||||||
export const FavoriteSettings = () => {
|
export const FavoriteSettings = () => {
|
||||||
const { favoriteStation, setFavoriteStation } = useFavoriteStation();
|
const { favoriteStation, setFavoriteStation } = useFavoriteStation();
|
||||||
|
const scrollableRef = useAnimatedRef();
|
||||||
const { goBack } = useNavigation();
|
const { goBack } = useNavigation();
|
||||||
|
const renderItem = useCallback((props) => {
|
||||||
|
const { item, index } = props;
|
||||||
|
return (
|
||||||
|
<FavoriteSettingsItem currentStation={item} key={item[0].StationNumber} />
|
||||||
|
);
|
||||||
|
}, []);
|
||||||
return (
|
return (
|
||||||
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
||||||
<SheetHeaderItem
|
<SheetHeaderItem
|
||||||
title="お気に入り設定"
|
title="お気に入り設定"
|
||||||
LeftItem={{ title: "< 設定", onPress: goBack }}
|
LeftItem={{ title: "< 設定", onPress: goBack }}
|
||||||
/>
|
/>
|
||||||
<ScrollView style={{ flex: 1, backgroundColor: "white" }}>
|
<Animated.ScrollView
|
||||||
{favoriteStation.map((currentStation, index, array) => (
|
style={{ flex: 1, backgroundColor: "white" }}
|
||||||
<FavoriteSettingsItem
|
contentContainerStyle={styles.contentContainer}
|
||||||
currentStation={currentStation}
|
ref={scrollableRef}
|
||||||
setFavoriteStation={setFavoriteStation}
|
>
|
||||||
index={index}
|
<Sortable.Grid
|
||||||
array={array}
|
columnGap={0}
|
||||||
key={currentStation[0].StationNumber}
|
columns={1}
|
||||||
/>
|
data={favoriteStation}
|
||||||
))}
|
renderItem={renderItem}
|
||||||
</ScrollView>
|
rowGap={0}
|
||||||
|
scrollableRef={scrollableRef} // required for auto scroll
|
||||||
|
snapOffsetY={0}
|
||||||
|
onDragEnd={(newOrder) => {
|
||||||
|
const newFavoriteStation = newOrder.indexToKey.map(
|
||||||
|
(item, index, array) => {
|
||||||
|
let returnData = [];
|
||||||
|
favoriteStation.forEach((station) => {
|
||||||
|
if (station[0].StationNumber === item) returnData = station;
|
||||||
|
});
|
||||||
|
return returnData;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
setFavoriteStation(newFavoriteStation);
|
||||||
|
AS.setItem("favoriteStation", JSON.stringify(newFavoriteStation));
|
||||||
|
}}
|
||||||
|
keyExtractor={(item) => item[0].StationNumber}
|
||||||
|
/>
|
||||||
|
</Animated.ScrollView>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: "white",
|
backgroundColor: "white",
|
||||||
@@ -39,20 +66,19 @@ export const FavoriteSettings = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const SimpleSwitch = ({ bool, setBool, str }) => (
|
const styles = StyleSheet.create({
|
||||||
<View style={{ flexDirection: "row" }}>
|
card: {
|
||||||
<CheckBox
|
alignItems: "center",
|
||||||
checked={bool == "true" ? true : false}
|
backgroundColor: "#36877F",
|
||||||
checkedColor="red"
|
borderRadius: 10,
|
||||||
onPress={() => setBool(bool == "true" ? "false" : "true")}
|
height: 100,
|
||||||
containerStyle={{
|
justifyContent: "center",
|
||||||
flex: 1,
|
},
|
||||||
backgroundColor: "#00000000",
|
contentContainer: {
|
||||||
borderColor: "white",
|
padding: 10,
|
||||||
alignContent: "center",
|
},
|
||||||
}}
|
text: {
|
||||||
textStyle={{ fontSize: 20, fontWeight: "normal" }}
|
color: "white",
|
||||||
title={str}
|
fontWeight: "bold",
|
||||||
/>
|
},
|
||||||
</View>
|
});
|
||||||
);
|
|
||||||
|
@@ -18,6 +18,8 @@ export const LayoutSettings = ({
|
|||||||
setUsePDFView,
|
setUsePDFView,
|
||||||
trainMenu,
|
trainMenu,
|
||||||
setTrainMenu,
|
setTrainMenu,
|
||||||
|
uiSetting,
|
||||||
|
setUiSetting,
|
||||||
trainPosition,
|
trainPosition,
|
||||||
setTrainPosition,
|
setTrainPosition,
|
||||||
headerSize,
|
headerSize,
|
||||||
@@ -38,6 +40,17 @@ export const LayoutSettings = ({
|
|||||||
falseText={"本家\n(文字アイコン)"}
|
falseText={"本家\n(文字アイコン)"}
|
||||||
trueText={"オリジナル\n(車種アイコン)"}
|
trueText={"オリジナル\n(車種アイコン)"}
|
||||||
/>
|
/>
|
||||||
|
<SwitchArea
|
||||||
|
str="列車表示"
|
||||||
|
bool={uiSetting}
|
||||||
|
setBool={setUiSetting}
|
||||||
|
falseImage={require("../../assets/configuration/layout_default.jpg")}
|
||||||
|
trueImage={require("../../assets/configuration/layout_tokyo.jpg")}
|
||||||
|
falseText={"本家"}
|
||||||
|
trueText={"オリジナル"}
|
||||||
|
falseValue="default"
|
||||||
|
trueValue="tokyo"
|
||||||
|
/>
|
||||||
<SwitchArea
|
<SwitchArea
|
||||||
str="トップメニュー表示"
|
str="トップメニュー表示"
|
||||||
bool={mapSwitch}
|
bool={mapSwitch}
|
||||||
|
@@ -17,7 +17,7 @@ import { SwitchArea } from "../atom/SwitchArea";
|
|||||||
import { useNotification } from "../../stateBox/useNotifications";
|
import { useNotification } from "../../stateBox/useNotifications";
|
||||||
import { SheetHeaderItem } from "@/components/atom/SheetHeaderItem";
|
import { SheetHeaderItem } from "@/components/atom/SheetHeaderItem";
|
||||||
|
|
||||||
const versionCode = "6.0.2";
|
const versionCode = "6.1.0"; // Update this version code as needed
|
||||||
|
|
||||||
export const SettingTopPage = ({
|
export const SettingTopPage = ({
|
||||||
testNFC,
|
testNFC,
|
||||||
|
@@ -39,6 +39,7 @@ export default function Setting(props) {
|
|||||||
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);
|
const [startPage, setStartPage] = useState(false);
|
||||||
|
const [uiSetting, setUiSetting] = useState("tokyo");
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
AS.getItem("iconSwitch").then(setIconSetting);
|
AS.getItem("iconSwitch").then(setIconSetting);
|
||||||
AS.getItem("mapSwitch").then(setMapSwitch);
|
AS.getItem("mapSwitch").then(setMapSwitch);
|
||||||
@@ -48,6 +49,7 @@ export default function Setting(props) {
|
|||||||
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);
|
AS.getItem("startPage").then(setStartPage);
|
||||||
|
AS.getItem("uiSetting").then(setUiSetting);
|
||||||
}, []);
|
}, []);
|
||||||
const testNFC = async () => {
|
const testNFC = async () => {
|
||||||
//const result = await ExpoFelicaReader.scan();
|
//const result = await ExpoFelicaReader.scan();
|
||||||
@@ -63,6 +65,7 @@ export default function Setting(props) {
|
|||||||
AS.setItem("trainPositionSwitch", trainPosition.toString()),
|
AS.setItem("trainPositionSwitch", trainPosition.toString()),
|
||||||
AS.setItem("headerSize", headerSize),
|
AS.setItem("headerSize", headerSize),
|
||||||
AS.setItem("startPage", startPage.toString()),
|
AS.setItem("startPage", startPage.toString()),
|
||||||
|
AS.setItem("uiSetting", uiSetting),
|
||||||
]).then(() => Updates.reloadAsync());
|
]).then(() => Updates.reloadAsync());
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
@@ -114,6 +117,8 @@ export default function Setting(props) {
|
|||||||
setTrainMenu={setTrainMenu}
|
setTrainMenu={setTrainMenu}
|
||||||
trainPosition={trainPosition}
|
trainPosition={trainPosition}
|
||||||
setTrainPosition={setTrainPosition}
|
setTrainPosition={setTrainPosition}
|
||||||
|
uiSetting={uiSetting}
|
||||||
|
setUiSetting={setUiSetting}
|
||||||
testNFC={testNFC}
|
testNFC={testNFC}
|
||||||
updateAndReload={updateAndReload}
|
updateAndReload={updateAndReload}
|
||||||
headerSize={headerSize}
|
headerSize={headerSize}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import React, { FC } from "react";
|
import React, { FC } from "react";
|
||||||
import { Marker } from "react-native-maps";
|
import { Marker } from "react-native-maps";
|
||||||
import { useNavigation } from "@react-navigation/native";
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import { useStationList } from "@/stateBox/useStationList";
|
||||||
type Props = {
|
type Props = {
|
||||||
index: number;
|
index: number;
|
||||||
indexBase: number;
|
indexBase: number;
|
||||||
@@ -13,7 +14,8 @@ type Props = {
|
|||||||
|
|
||||||
export const MapPin: FC<Props> = (props) => {
|
export const MapPin: FC<Props> = (props) => {
|
||||||
const { index, indexBase, latlng, D, d, navigate, webview } = props;
|
const { index, indexBase, latlng, D, d, navigate, webview } = props;
|
||||||
const {goBack} = useNavigation();
|
const { goBack } = useNavigation();
|
||||||
|
const { getInjectJavascriptAddress } = useStationList();
|
||||||
return (
|
return (
|
||||||
<Marker
|
<Marker
|
||||||
key={index + indexBase}
|
key={index + indexBase}
|
||||||
@@ -22,10 +24,9 @@ export const MapPin: FC<Props> = (props) => {
|
|||||||
longitude: parseFloat(latlng[1]),
|
longitude: parseFloat(latlng[1]),
|
||||||
}}
|
}}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
webview.current?.injectJavaScript(
|
const address = getInjectJavascriptAddress(D.StationNumber);
|
||||||
`MoveDisplayStation('${d}_${D.MyStation}_${D.Station_JP}');
|
if (!address) return;
|
||||||
document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`
|
webview.current?.injectJavaScript(address);
|
||||||
);
|
|
||||||
if (navigate) goBack();
|
if (navigate) goBack();
|
||||||
}}
|
}}
|
||||||
image={require("../../assets/reccha-small.png")}
|
image={require("../../assets/reccha-small.png")}
|
||||||
|
@@ -8,6 +8,8 @@ export const SwitchArea = ({
|
|||||||
trueImage,
|
trueImage,
|
||||||
falseText,
|
falseText,
|
||||||
trueText,
|
trueText,
|
||||||
|
falseValue = false,
|
||||||
|
trueValue = true,
|
||||||
children,
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
@@ -37,7 +39,7 @@ export const SwitchArea = ({
|
|||||||
bool={bool}
|
bool={bool}
|
||||||
setBool={setBool}
|
setBool={setBool}
|
||||||
color="red"
|
color="red"
|
||||||
value={false}
|
value={falseValue}
|
||||||
image={falseImage}
|
image={falseImage}
|
||||||
subText={falseText}
|
subText={falseText}
|
||||||
/>
|
/>
|
||||||
@@ -45,7 +47,7 @@ export const SwitchArea = ({
|
|||||||
bool={bool}
|
bool={bool}
|
||||||
setBool={setBool}
|
setBool={setBool}
|
||||||
color="red"
|
color="red"
|
||||||
value={true}
|
value={trueValue}
|
||||||
image={trueImage}
|
image={trueImage}
|
||||||
subText={trueText}
|
subText={trueText}
|
||||||
/>
|
/>
|
||||||
|
@@ -1,22 +0,0 @@
|
|||||||
import { TouchableOpacity, Text } from "react-native";
|
|
||||||
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
|
||||||
export const UsefulBox = (props) => {
|
|
||||||
const { icon, backgroundColor, flex, onPressButton, children } = props;
|
|
||||||
return (
|
|
||||||
<TouchableOpacity
|
|
||||||
style={{
|
|
||||||
flex: flex,
|
|
||||||
backgroundColor: backgroundColor,
|
|
||||||
padding: 10,
|
|
||||||
alignItems: "center",
|
|
||||||
margin: 2,
|
|
||||||
}}
|
|
||||||
onPress={onPressButton}
|
|
||||||
>
|
|
||||||
<MaterialCommunityIcons name={icon} color="white" size={50} />
|
|
||||||
<Text style={{ color: "white", fontWeight: "bold", fontSize: 18 }}>
|
|
||||||
{children}
|
|
||||||
</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
);
|
|
||||||
};
|
|
@@ -1,5 +1,19 @@
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
export const customTrainDataDetector = (TrainNumber: string) => {
|
export const customTrainDataDetector = (
|
||||||
|
TrainNumber: string,
|
||||||
|
allCustonTrainData?: any[]
|
||||||
|
) => {
|
||||||
|
if (allCustonTrainData && allCustonTrainData.length > 0) {
|
||||||
|
const customTrain = allCustonTrainData.find(
|
||||||
|
(train) => train.TrainNumber === TrainNumber
|
||||||
|
);
|
||||||
|
if (customTrain) {
|
||||||
|
return customTrain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const trainGetText = `?trainNum=${TrainNumber}&month=${dayjs().format(
|
||||||
|
"M"
|
||||||
|
)}&day=${dayjs().format("D")}`;
|
||||||
switch (TrainNumber) {
|
switch (TrainNumber) {
|
||||||
//しおかぜメイン
|
//しおかぜメイン
|
||||||
//8000 ノーマル
|
//8000 ノーマル
|
||||||
@@ -23,23 +37,23 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "しおかぜ",
|
trainName: "しおかぜ",
|
||||||
trainIcon: "https://storage.haruk.in/s8000nr.png",
|
img: "https://storage.haruk.in/s8000nr.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html",
|
||||||
trainNumDistance: 0,
|
trainNumDistance: 0,
|
||||||
info: "いしづちと併結 / 8000系で運転",
|
info: "いしづちと併結 / 8000系で運転",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
case "2M":
|
case "2M":
|
||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "しおかぜ",
|
trainName: "しおかぜ",
|
||||||
trainIcon: "https://storage.haruk.in/s8000nr.png",
|
img: "https://storage.haruk.in/s8000nr.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html",
|
||||||
trainNumDistance: 0,
|
trainNumDistance: 0,
|
||||||
info: "8000系で運転",
|
info: "8000系で運転",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
//8000 アンパン
|
//8000 アンパン
|
||||||
case "10M":
|
case "10M":
|
||||||
@@ -49,11 +63,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "しおかぜ",
|
trainName: "しおかぜ",
|
||||||
trainIcon: `https://n8n.haruk.in/webhook/anpanman-pictures.png?trainNum=${TrainNumber}`,
|
img: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`,
|
||||||
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
|
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
|
||||||
trainNumDistance: 0,
|
trainNumDistance: 0,
|
||||||
info: "いしづちと併結 / アンパンマン列車で運転",
|
info: "いしづちと併結 / アンパンマン列車で運転",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
//8600
|
//8600
|
||||||
case "8M":
|
case "8M":
|
||||||
@@ -67,12 +81,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "しおかぜ",
|
trainName: "しおかぜ",
|
||||||
trainIcon: "https://storage.haruk.in/s8600.png",
|
img: "https://storage.haruk.in/s8600.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shiokaze.html",
|
||||||
trainNumDistance: 0,
|
trainNumDistance: 0,
|
||||||
info: "いしづちと併結 / 8600系で運転",
|
info: "いしづちと併結 / 8600系で運転",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
|
|
||||||
//いしづちメイン
|
//いしづちメイン
|
||||||
@@ -98,12 +112,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "いしづち",
|
trainName: "いしづち",
|
||||||
trainIcon: "https://storage.haruk.in/s8000no.png",
|
img: "https://storage.haruk.in/s8000no.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
|
||||||
trainNumDistance: 1000,
|
trainNumDistance: 1000,
|
||||||
info: "しおかぜと併結 / 8000系で運転",
|
info: "しおかぜと併結 / 8000系で運転",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
//8000 アンパン
|
//8000 アンパン
|
||||||
@@ -114,11 +128,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "いしづち",
|
trainName: "いしづち",
|
||||||
trainIcon: `https://n8n.haruk.in/webhook/anpanman-pictures.png?trainNum=${TrainNumber}`,
|
img: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`,
|
||||||
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
|
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
|
||||||
trainNumDistance: 1000,
|
trainNumDistance: 1000,
|
||||||
info: "しおかぜと併結 / アンパンマン列車で運転",
|
info: "しおかぜと併結 / アンパンマン列車で運転",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
//8600
|
//8600
|
||||||
@@ -133,12 +147,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "いしづち",
|
trainName: "いしづち",
|
||||||
trainIcon: "https://storage.haruk.in/s8600_isz.png",
|
img: "https://storage.haruk.in/s8600_isz.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
|
||||||
trainNumDistance: 1000,
|
trainNumDistance: 1000,
|
||||||
info: "しおかぜと併結 / 8600系で運転",
|
info: "しおかぜと併結 / 8600系で運転",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
//MEXP
|
//MEXP
|
||||||
@@ -147,24 +161,24 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "モーニングEXP高松",
|
trainName: "モーニングEXP高松",
|
||||||
trainIcon: "https://storage.haruk.in/s8000nr.png",
|
img: "https://storage.haruk.in/s8000nr.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/morning.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/morning.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "8000系で運転",
|
info: "8000系で運転",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
//8600
|
//8600
|
||||||
case "1091M":
|
case "1091M":
|
||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "モーニングEXP松山",
|
trainName: "モーニングEXP松山",
|
||||||
trainIcon: "https://storage.haruk.in/s8600_isz.png",
|
img: "https://storage.haruk.in/s8600_isz.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/morning.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/morning.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "8600系で運転",
|
info: "8600系で運転",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
//三桁いしづち
|
//三桁いしづち
|
||||||
//8000 アンパン
|
//8000 アンパン
|
||||||
@@ -173,11 +187,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "いしづち",
|
trainName: "いしづち",
|
||||||
trainIcon: `https://n8n.haruk.in/webhook/anpanman-pictures.png?trainNum=${TrainNumber}`,
|
img: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`,
|
||||||
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
|
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
|
||||||
trainNumDistance: 940,
|
trainNumDistance: 940,
|
||||||
info: "アンパンマン列車で運転",
|
info: "アンパンマン列車で運転",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
//8600
|
//8600
|
||||||
case "1043M":
|
case "1043M":
|
||||||
@@ -185,23 +199,23 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "いしづち",
|
trainName: "いしづち",
|
||||||
trainIcon: "https://storage.haruk.in/s8600_isz.png",
|
img: "https://storage.haruk.in/s8600_isz.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
|
||||||
trainNumDistance: 940,
|
trainNumDistance: 940,
|
||||||
info: "8600系で運転",
|
info: "8600系で運転",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
case "1046M":
|
case "1046M":
|
||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "いしづち",
|
trainName: "いしづち",
|
||||||
trainIcon: "https://storage.haruk.in/s8600_isz.png",
|
img: "https://storage.haruk.in/s8600_isz.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ishizuchi.html",
|
||||||
trainNumDistance: 940,
|
trainNumDistance: 940,
|
||||||
info: "8600系で運転",
|
info: "8600系で運転",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
|
|
||||||
//南風 2700ノーマル
|
//南風 2700ノーマル
|
||||||
@@ -226,11 +240,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "南風",
|
trainName: "南風",
|
||||||
trainIcon: "https://storage.haruk.in/s2700.png",
|
img: "https://storage.haruk.in/s2700.png",
|
||||||
infoUrl: "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/nanpu.html",
|
infoUrl:
|
||||||
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/nanpu.html",
|
||||||
trainNumDistance: 30,
|
trainNumDistance: 30,
|
||||||
info: "2700系で運転",
|
info: "2700系で運転",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
|
|
||||||
//2700アンパン
|
//2700アンパン
|
||||||
@@ -247,11 +262,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "南風",
|
trainName: "南風",
|
||||||
trainIcon: `https://n8n.haruk.in/webhook/anpanman-pictures.png?trainNum=${TrainNumber}`,
|
img: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`,
|
||||||
infoUrl: "https://www.jr-eki.com/aptrain/naani/dosan/train.html",
|
infoUrl: "https://www.jr-eki.com/aptrain/naani/dosan/train.html",
|
||||||
trainNumDistance: 30,
|
trainNumDistance: 30,
|
||||||
info: "アンパンマン列車で運転",
|
info: "アンパンマン列車で運転",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
|
|
||||||
//うずしお
|
//うずしお
|
||||||
@@ -272,12 +287,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "うずしお",
|
trainName: "うずしお",
|
||||||
trainIcon: "https://storage.haruk.in/s2700_uzu.png",
|
img: "https://storage.haruk.in/s2700_uzu.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html",
|
||||||
trainNumDistance: 3000,
|
trainNumDistance: 3000,
|
||||||
info: "2700系で運転",
|
info: "2700系で運転",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
//2700 二両編成
|
//2700 二両編成
|
||||||
@@ -294,12 +309,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "うずしお",
|
trainName: "うずしお",
|
||||||
trainIcon: "https://storage.haruk.in/s2700_uzu.png",
|
img: "https://storage.haruk.in/s2700_uzu.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html",
|
||||||
trainNumDistance: 3000,
|
trainNumDistance: 3000,
|
||||||
info: "2700系で運転",
|
info: "2700系で運転",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
//2600
|
//2600
|
||||||
@@ -316,15 +331,14 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "うずしお",
|
trainName: "うずしお",
|
||||||
trainIcon: "https://storage.haruk.in/s2600.png",
|
img: "https://storage.haruk.in/s2600.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uzushio.html",
|
||||||
trainNumDistance: 3000,
|
trainNumDistance: 3000,
|
||||||
info: "2600系で運転",
|
info: "2600系で運転",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//マリンライナー
|
//マリンライナー
|
||||||
case "3104M":
|
case "3104M":
|
||||||
case "3106M":
|
case "3106M":
|
||||||
@@ -397,11 +411,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "Rapid",
|
type: "Rapid",
|
||||||
trainName: "マリンライナー",
|
trainName: "マリンライナー",
|
||||||
trainIcon: "https://storage.haruk.in/s5001.png",
|
img: "https://storage.haruk.in/s5001.png",
|
||||||
infoUrl: "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/marine.html",
|
infoUrl:
|
||||||
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/marine.html",
|
||||||
trainNumDistance: 3100,
|
trainNumDistance: 3100,
|
||||||
info: "",
|
info: "",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
case "3102M":
|
case "3102M":
|
||||||
case "3101M":
|
case "3101M":
|
||||||
@@ -411,22 +426,23 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "Rapid",
|
type: "Rapid",
|
||||||
trainName: "マリンライナー",
|
trainName: "マリンライナー",
|
||||||
trainIcon: "https://storage.haruk.in/s5001k.png",
|
img: "https://storage.haruk.in/s5001k.png",
|
||||||
infoUrl: "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/marine.html",
|
infoUrl:
|
||||||
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/marine.html",
|
||||||
trainNumDistance: 3100,
|
trainNumDistance: 3100,
|
||||||
info: "",
|
info: "",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
//下りサンポート
|
//下りサンポート
|
||||||
case "1219M":
|
case "1219M":
|
||||||
return {
|
return {
|
||||||
type: "Normal",
|
type: "Normal",
|
||||||
trainName: "南風リレー",
|
trainName: "南風リレー",
|
||||||
trainIcon: "",
|
img: "",
|
||||||
infoUrl: "",
|
infoUrl: "",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: " 土曜・休日は多度津-琴平間運休",
|
info: " 土曜・休日は多度津-琴平間運休",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
case "111M":
|
case "111M":
|
||||||
@@ -442,11 +458,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "Rapid",
|
type: "Rapid",
|
||||||
trainName: "サンポート南風リレー",
|
trainName: "サンポート南風リレー",
|
||||||
trainIcon: null,
|
img: null,
|
||||||
infoUrl: null,
|
infoUrl: null,
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: null,
|
info: null,
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
case "5109M":
|
case "5109M":
|
||||||
case "5135M":
|
case "5135M":
|
||||||
@@ -454,32 +470,32 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "OneManRapid",
|
type: "OneManRapid",
|
||||||
trainName: "サンポート南風リレー",
|
trainName: "サンポート南風リレー",
|
||||||
trainIcon: null,
|
img: null,
|
||||||
infoUrl: null,
|
infoUrl: null,
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: null,
|
info: null,
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
case "137M":
|
case "137M":
|
||||||
return {
|
return {
|
||||||
type: "Rapid",
|
type: "Rapid",
|
||||||
trainName: "サンポート",
|
trainName: "サンポート",
|
||||||
trainIcon: null,
|
img: null,
|
||||||
infoUrl: null,
|
infoUrl: null,
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "土曜・休日運休",
|
info: "土曜・休日運休",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
//上りサンポート
|
//上りサンポート
|
||||||
case "116M":
|
case "116M":
|
||||||
return {
|
return {
|
||||||
type: "Normal",
|
type: "Normal",
|
||||||
trainName: "南風リレー",
|
trainName: "南風リレー",
|
||||||
trainIcon: null,
|
img: null,
|
||||||
infoUrl: null,
|
infoUrl: null,
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: null,
|
info: null,
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
case "130M":
|
case "130M":
|
||||||
@@ -493,11 +509,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "Rapid",
|
type: "Rapid",
|
||||||
trainName: "サンポート南風リレー",
|
trainName: "サンポート南風リレー",
|
||||||
trainIcon: "",
|
img: "",
|
||||||
infoUrl: "",
|
infoUrl: "",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
case "5118M":
|
case "5118M":
|
||||||
case "5120M":
|
case "5120M":
|
||||||
@@ -507,11 +523,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "OneManRapid",
|
type: "OneManRapid",
|
||||||
trainName: "サンポート南風リレー",
|
trainName: "サンポート南風リレー",
|
||||||
trainIcon: null,
|
img: null,
|
||||||
infoUrl: null,
|
infoUrl: null,
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: null,
|
info: null,
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
//サンライズ瀬戸
|
//サンライズ瀬戸
|
||||||
@@ -520,24 +536,24 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "NightLTDEXP",
|
type: "NightLTDEXP",
|
||||||
trainName: "サンライズ瀬戸",
|
trainName: "サンライズ瀬戸",
|
||||||
trainIcon: "https://storage.haruk.in/w285.png",
|
img: "https://storage.haruk.in/w285.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-odekake.net/train/sunriseseto_izumo/index.html",
|
"https://www.jr-odekake.net/train/sunriseseto_izumo/index.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
infogram: "ブ"
|
infogram: "ブ",
|
||||||
};
|
};
|
||||||
case "8041M": //琴平延長高松迄
|
case "8041M": //琴平延長高松迄
|
||||||
case "8031M": //琴平延長高松以降
|
case "8031M": //琴平延長高松以降
|
||||||
return {
|
return {
|
||||||
type: "NightLTDEXP",
|
type: "NightLTDEXP",
|
||||||
trainName: "サンライズ瀬戸",
|
trainName: "サンライズ瀬戸",
|
||||||
trainIcon: "https://storage.haruk.in/w285.png",
|
img: "https://storage.haruk.in/w285.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-odekake.net/train/sunriseseto_izumo/index.html",
|
"https://www.jr-odekake.net/train/sunriseseto_izumo/index.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "琴平延長運転日",
|
info: "琴平延長運転日",
|
||||||
infogram: "ブ"
|
infogram: "ブ",
|
||||||
};
|
};
|
||||||
|
|
||||||
//宇和海
|
//宇和海
|
||||||
@@ -571,11 +587,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "宇和海",
|
trainName: "宇和海",
|
||||||
trainIcon: "https://storage.haruk.in/s2000_uwa.png",
|
img: "https://storage.haruk.in/s2000_uwa.png",
|
||||||
infoUrl: "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uwakai.html",
|
infoUrl:
|
||||||
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/uwakai.html",
|
||||||
trainNumDistance: 1050,
|
trainNumDistance: 1050,
|
||||||
info: "2000系で運転",
|
info: "2000系で運転",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
//2000 アンパン込み
|
//2000 アンパン込み
|
||||||
case "1058D":
|
case "1058D":
|
||||||
@@ -587,11 +604,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "宇和海",
|
trainName: "宇和海",
|
||||||
trainIcon: `https://n8n.haruk.in/webhook/anpanman-pictures.png?trainNum=${TrainNumber}`,
|
img: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`,
|
||||||
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
|
infoUrl: "https://www.jr-eki.com/aptrain/naani/yosan/train.html",
|
||||||
trainNumDistance: 1050,
|
trainNumDistance: 1050,
|
||||||
info: "アンパン列車で運転",
|
info: "アンパン列車で運転",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
//しまんと
|
//しまんと
|
||||||
case "2002D":
|
case "2002D":
|
||||||
@@ -601,12 +618,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "しまんと",
|
trainName: "しまんと",
|
||||||
trainIcon: "https://storage.haruk.in/s2700_smn.png",
|
img: "https://storage.haruk.in/s2700_smn.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shimanto.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/shimanto.html",
|
||||||
trainNumDistance: 2000,
|
trainNumDistance: 2000,
|
||||||
info: "2700系で運転",
|
info: "2700系で運転",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
//あしずり 2000
|
//あしずり 2000
|
||||||
@@ -621,12 +638,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "あしずり",
|
trainName: "あしずり",
|
||||||
trainIcon: `https://n8n.haruk.in/webhook/anpanman-pictures.png?trainNum=${TrainNumber}`,
|
img: `https://n8n.haruk.in/webhook/anpanman-pictures.png${trainGetText}`,
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-eki.com/aptrain/naani/first-generation/jikoku.html",
|
"https://www.jr-eki.com/aptrain/naani/first-generation/jikoku.html",
|
||||||
trainNumDistance: 2070,
|
trainNumDistance: 2070,
|
||||||
info: "2000系で運転",
|
info: "2000系で運転",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
//あしずり 2700
|
//あしずり 2700
|
||||||
@@ -637,24 +654,24 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "あしずり",
|
trainName: "あしずり",
|
||||||
trainIcon: "https://storage.haruk.in/s2700_asi.png",
|
img: "https://storage.haruk.in/s2700_asi.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ashizuri.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ashizuri.html",
|
||||||
trainNumDistance: 2070,
|
trainNumDistance: 2070,
|
||||||
info: "2700系で運転",
|
info: "2700系で運転",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
case "2072D":
|
case "2072D":
|
||||||
case "2083D":
|
case "2083D":
|
||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "あしずり",
|
trainName: "あしずり",
|
||||||
trainIcon: "https://storage.haruk.in/s2700_asi.png",
|
img: "https://storage.haruk.in/s2700_asi.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ashizuri.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/ashizuri.html",
|
||||||
trainNumDistance: 2070,
|
trainNumDistance: 2070,
|
||||||
info: "2700系で運転",
|
info: "2700系で運転",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
|
|
||||||
//剣山
|
//剣山
|
||||||
@@ -668,12 +685,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "剣山",
|
trainName: "剣山",
|
||||||
trainIcon: "https://storage.haruk.in/s185tu.png",
|
img: "https://storage.haruk.in/s185tu.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/tsurugisan.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/tsurugisan.html",
|
||||||
trainNumDistance: 4000,
|
trainNumDistance: 4000,
|
||||||
info: "キハ185系で運転",
|
info: "キハ185系で運転",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
//よしのがわトロッコ
|
//よしのがわトロッコ
|
||||||
@@ -682,12 +699,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "よしのがわトロッコ",
|
trainName: "よしのがわトロッコ",
|
||||||
trainIcon: "https://storage.haruk.in/s185to_ai.png",
|
img: "https://storage.haruk.in/s185to_ai.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/event_train/yoshino_torokko.html",
|
"https://www.jr-shikoku.co.jp/01_trainbus/event_train/yoshino_torokko.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
//岡山高松アントロ
|
//岡山高松アントロ
|
||||||
@@ -699,12 +716,12 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "アンパンマントロッコ",
|
trainName: "アンパンマントロッコ",
|
||||||
trainIcon: "https://storage.haruk.in/s32to4.png",
|
img: "https://storage.haruk.in/s32to4.png",
|
||||||
infoUrl:
|
infoUrl:
|
||||||
"https://www.jr-eki.com/aptrain/naani/torokko_seto/jikoku.html",
|
"https://www.jr-eki.com/aptrain/naani/torokko_seto/jikoku.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
|
|
||||||
//伊予灘ものがたり
|
//伊予灘ものがたり
|
||||||
@@ -713,22 +730,22 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "伊予灘ものがたり",
|
trainName: "伊予灘ものがたり",
|
||||||
trainIcon: "https://storage.haruk.in/s185iyor.png",
|
img: "https://storage.haruk.in/s185iyor.png",
|
||||||
infoUrl: "https://iyonadamonogatari.com/",
|
infoUrl: "https://iyonadamonogatari.com/",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
case "8092D":
|
case "8092D":
|
||||||
case "8094D":
|
case "8094D":
|
||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "伊予灘ものがたり",
|
trainName: "伊予灘ものがたり",
|
||||||
trainIcon: "https://storage.haruk.in/s185iyoy.png",
|
img: "https://storage.haruk.in/s185iyoy.png",
|
||||||
infoUrl: "https://iyonadamonogatari.com/",
|
infoUrl: "https://iyonadamonogatari.com/",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
|
|
||||||
//千年ものがたり
|
//千年ものがたり
|
||||||
@@ -737,11 +754,11 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "四国まんなか千年ものがたり",
|
trainName: "四国まんなか千年ものがたり",
|
||||||
trainIcon: "https://storage.haruk.in/s185mm1.png",
|
img: "https://storage.haruk.in/s185mm1.png",
|
||||||
infoUrl: "https://www.jr-shikoku.co.jp/sennenmonogatari/",
|
infoUrl: "https://www.jr-shikoku.co.jp/sennenmonogatari/",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
|
|
||||||
//夜明けものがたり
|
//夜明けものがたり
|
||||||
@@ -752,67 +769,67 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "LTDEXP",
|
type: "LTDEXP",
|
||||||
trainName: "時代の夜明けのものがたり",
|
trainName: "時代の夜明けのものがたり",
|
||||||
trainIcon: "https://storage.haruk.in/s185ym1.png",
|
img: "https://storage.haruk.in/s185ym1.png",
|
||||||
infoUrl: "https://www.jr-shikoku.co.jp/yoakenomonogatari/index.html",
|
infoUrl: "https://www.jr-shikoku.co.jp/yoakenomonogatari/index.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
case "9174M":
|
case "9174M":
|
||||||
return {
|
return {
|
||||||
type: "SPCL_Rapid",
|
type: "SPCL_Rapid",
|
||||||
trainName: "マリンライナー94号",
|
trainName: "マリンライナー94号",
|
||||||
trainIcon: "https://storage.haruk.in/s5001.png",
|
img: "https://storage.haruk.in/s5001.png",
|
||||||
infoUrl: "https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/marine.html",
|
infoUrl:
|
||||||
|
"https://www.jr-shikoku.co.jp/01_trainbus/vehicle-info/marine.html",
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "臨時列車 4/12,13,19のみ運転",
|
info: "臨時列車 4/12,13,19のみ運転",
|
||||||
infogram: "G"
|
infogram: "G",
|
||||||
};
|
};
|
||||||
case "9395D":
|
case "9395D":
|
||||||
return {
|
return {
|
||||||
type: "SPCL_Normal",
|
type: "SPCL_Normal",
|
||||||
trainName: "",
|
trainName: "",
|
||||||
trainIcon: "https://storage.haruk.in/s1500.png",
|
img: "https://storage.haruk.in/s1500.png",
|
||||||
infoUrl: null,
|
infoUrl: null,
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "臨時列車 4/12,13,19のみ運転",
|
info: "臨時列車 4/12,13,19のみ運転",
|
||||||
infogram: ""
|
infogram: "",
|
||||||
|
};
|
||||||
|
case "9662D":
|
||||||
|
case "9665D":
|
||||||
|
return {
|
||||||
|
type: "SPCL_Normal",
|
||||||
|
trainName: "れんげ号",
|
||||||
|
img: "",
|
||||||
|
infoUrl: null,
|
||||||
|
trainNumDistance: null,
|
||||||
|
info: "臨時列車 4/29のみ運転",
|
||||||
|
infogram: "",
|
||||||
|
};
|
||||||
|
case "9664D":
|
||||||
|
case "9663D":
|
||||||
|
return {
|
||||||
|
type: "SPCL_Normal",
|
||||||
|
trainName: "わらぐろ号",
|
||||||
|
img: "",
|
||||||
|
infoUrl: null,
|
||||||
|
trainNumDistance: null,
|
||||||
|
info: "臨時列車 4/29のみ運転",
|
||||||
|
infogram: "",
|
||||||
};
|
};
|
||||||
case "9662D":
|
|
||||||
case "9665D":
|
|
||||||
return {
|
|
||||||
type: "SPCL_Normal",
|
|
||||||
trainName: "れんげ号",
|
|
||||||
trainIcon: "",
|
|
||||||
infoUrl: null,
|
|
||||||
trainNumDistance: null,
|
|
||||||
info: "臨時列車 4/29のみ運転",
|
|
||||||
infogram: ""
|
|
||||||
};
|
|
||||||
case "9664D":
|
|
||||||
case "9663D":
|
|
||||||
return {
|
|
||||||
type: "SPCL_Normal",
|
|
||||||
trainName: "わらぐろ号",
|
|
||||||
trainIcon: "",
|
|
||||||
infoUrl: null,
|
|
||||||
trainNumDistance: null,
|
|
||||||
info: "臨時列車 4/29のみ運転",
|
|
||||||
infogram: ""
|
|
||||||
};
|
|
||||||
default:
|
default:
|
||||||
if(getJRF(TrainNumber) !== null){
|
if (getJRF(TrainNumber) !== null) {
|
||||||
return {
|
return {
|
||||||
type: "Freight",
|
type: "Freight",
|
||||||
trainName: getJRF(TrainNumber),
|
trainName: getJRF(TrainNumber),
|
||||||
trainIcon: "https://storage.haruk.in/ef210a.png",
|
img: "https://storage.haruk.in/ef210a.png",
|
||||||
infoUrl: null,
|
infoUrl: null,
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: "",
|
info: "",
|
||||||
infogram: "",
|
infogram: "",
|
||||||
};
|
};
|
||||||
}
|
} else if (
|
||||||
else if (
|
|
||||||
new RegExp(/^4[1-9]\d\d[DM]$/).test(TrainNumber) ||
|
new RegExp(/^4[1-9]\d\d[DM]$/).test(TrainNumber) ||
|
||||||
new RegExp(/^5[1-7]\d\d[DM]$/).test(TrainNumber) ||
|
new RegExp(/^5[1-7]\d\d[DM]$/).test(TrainNumber) ||
|
||||||
new RegExp(/^3[2-9]\d\d[DM]$/).test(TrainNumber)
|
new RegExp(/^3[2-9]\d\d[DM]$/).test(TrainNumber)
|
||||||
@@ -820,38 +837,38 @@ export const customTrainDataDetector = (TrainNumber: string) => {
|
|||||||
return {
|
return {
|
||||||
type: "OneMan",
|
type: "OneMan",
|
||||||
trainName: "",
|
trainName: "",
|
||||||
trainIcon: null,
|
img: null,
|
||||||
infoUrl: null,
|
infoUrl: null,
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: null,
|
info: null,
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
else if (
|
else if (
|
||||||
new RegExp(/^[1-9]\d\d[DM]$/).test(TrainNumber) ||
|
new RegExp(/^[1-9]\d\d[DM]$/).test(TrainNumber) ||
|
||||||
new RegExp(/^1[26]\d\d[DM]$/).test(TrainNumber) ||
|
new RegExp(/^1[26]\d\d[DM]$/).test(TrainNumber) ||
|
||||||
new RegExp(/^58\d\d[DM]$/).test(TrainNumber) ||
|
new RegExp(/^58\d\d[DM]$/).test(TrainNumber) ||
|
||||||
new RegExp(/^6\d\d\d[DM]$/).test(TrainNumber)
|
new RegExp(/^6\d\d\d[DM]$/).test(TrainNumber)
|
||||||
){
|
) {
|
||||||
return {
|
return {
|
||||||
type: "Normal",
|
type: "Normal",
|
||||||
trainName: "",
|
trainName: "",
|
||||||
trainIcon: null,
|
img: null,
|
||||||
infoUrl: null,
|
infoUrl: null,
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: null,
|
info: null,
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
type: "Other",
|
type: "Other",
|
||||||
trainName: "",
|
trainName: "",
|
||||||
trainIcon: null,
|
img: null,
|
||||||
infoUrl: null,
|
infoUrl: null,
|
||||||
trainNumDistance: null,
|
trainNumDistance: null,
|
||||||
info: null,
|
info: null,
|
||||||
infogram: ""
|
infogram: "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
export const getJRF = (num: string) => {
|
export const getJRF = (num: string) => {
|
||||||
|
@@ -4,13 +4,13 @@ import MapView from "react-native-maps";
|
|||||||
import { useCurrentTrain } from "../stateBox/useCurrentTrain";
|
import { useCurrentTrain } from "../stateBox/useCurrentTrain";
|
||||||
import { useNavigation } from "@react-navigation/native";
|
import { useNavigation } from "@react-navigation/native";
|
||||||
import lineColorList from "../assets/originData/lineColorList";
|
import lineColorList from "../assets/originData/lineColorList";
|
||||||
import { stationIDPair } from "../lib/getStationList2";
|
import { lineList_LineWebID, lineListPair, stationIDPair } from "../lib/getStationList";
|
||||||
import { lineListPair } from "../lib/getStationList";
|
|
||||||
import { SheetManager } from "react-native-actions-sheet";
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
import { useTrainMenu } from "../stateBox/useTrainMenu";
|
import { useTrainMenu } from "../stateBox/useTrainMenu";
|
||||||
import { MapPin } from "./TrainMenu/MapPin";
|
import { MapPin } from "./TrainMenu/MapPin";
|
||||||
import { UsefulBox } from "./TrainMenu/UsefulBox";
|
import { UsefulBox } from "./TrainMenu/UsefulBox";
|
||||||
import { MapsButton } from "./TrainMenu/MapsButton";
|
import { MapsButton } from "./TrainMenu/MapsButton";
|
||||||
|
import { useStationList } from "@/stateBox/useStationList";
|
||||||
export default function TrainMenu({ style }) {
|
export default function TrainMenu({ style }) {
|
||||||
const { webview } = useCurrentTrain();
|
const { webview } = useCurrentTrain();
|
||||||
const mapRef = useRef();
|
const mapRef = useRef();
|
||||||
@@ -19,35 +19,30 @@ export default function TrainMenu({ style }) {
|
|||||||
const {
|
const {
|
||||||
selectedLine,
|
selectedLine,
|
||||||
setSelectedLine,
|
setSelectedLine,
|
||||||
injectJavaScript,
|
|
||||||
setInjectJavaScript,
|
|
||||||
mapsStationData: stationData,
|
mapsStationData: stationData,
|
||||||
} = useTrainMenu();
|
} = useTrainMenu();
|
||||||
|
const { originalStationList } = useStationList();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const stationPinData = [];
|
const stationPinData = [];
|
||||||
Object.keys(stationData).forEach((d, indexBase) => {
|
Object.keys(lineList_LineWebID).forEach((d, indexBase) => {
|
||||||
stationData[d].forEach((D, index) => {
|
originalStationList[d].forEach((D, index) => {
|
||||||
if (!D.StationMap) return null;
|
if (selectedLine && selectedLine != lineList_LineWebID[d]) return;
|
||||||
if (selectedLine && selectedLine != d) return;
|
const latlng = [D.lat,D.lng];
|
||||||
const latlng = D.StationMap.replace(
|
|
||||||
"https://www.google.co.jp/maps/place/",
|
|
||||||
""
|
|
||||||
).split(",");
|
|
||||||
if (latlng.length == 0) return null;
|
if (latlng.length == 0) return null;
|
||||||
stationPinData.push({ D, d, latlng, indexBase: 0, index });
|
stationPinData.push({ D, d, latlng, indexBase: 0, index });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
setStationPin(stationPinData);
|
setStationPin(stationPinData);
|
||||||
}, [stationData, selectedLine]);
|
}, [originalStationList, selectedLine]);
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
mapRef.current.fitToCoordinates(
|
mapRef?.current.fitToCoordinates(
|
||||||
stationPin.map(({ latlng }) => ({
|
stationPin.map(({ latlng }) => ({
|
||||||
latitude: parseFloat(latlng[0]),
|
latitude: parseFloat(latlng[0]),
|
||||||
longitude: parseFloat(latlng[1]),
|
longitude: parseFloat(latlng[1]),
|
||||||
})),
|
})),
|
||||||
{ edgePadding: { top: 80, bottom: 120, left: 50, right: 50 } } // Add margin values here
|
{ edgePadding: { top: 80, bottom: 120, left: 50, right: 50 } } // Add margin values here
|
||||||
);
|
);
|
||||||
}, [stationPin]);
|
}, [stationPin,mapRef]);
|
||||||
return (
|
return (
|
||||||
<View style={{ height: "100%", backgroundColor: "#0099CC", ...style }}>
|
<View style={{ height: "100%", backgroundColor: "#0099CC", ...style }}>
|
||||||
<MapView
|
<MapView
|
||||||
@@ -75,7 +70,7 @@ export default function TrainMenu({ style }) {
|
|||||||
d={d}
|
d={d}
|
||||||
navigate={navigate}
|
navigate={navigate}
|
||||||
webview={webview}
|
webview={webview}
|
||||||
key={D.StationNumber + d}
|
key={D.Station_JP + D.StationNumber + d}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</MapView>
|
</MapView>
|
||||||
@@ -166,6 +161,7 @@ export default function TrainMenu({ style }) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
key={stationIDPair[d]}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
style={{ color: "white", fontWeight: "bold", fontSize: 20 }}
|
style={{ color: "white", fontWeight: "bold", fontSize: 20 }}
|
||||||
@@ -215,7 +211,6 @@ export default function TrainMenu({ style }) {
|
|||||||
<MapsButton
|
<MapsButton
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
goBack();
|
goBack();
|
||||||
webview.current?.injectJavaScript(injectJavaScript);
|
|
||||||
}}
|
}}
|
||||||
top={0}
|
top={0}
|
||||||
mapSwitch={"flex"}
|
mapSwitch={"flex"}
|
||||||
|
@@ -4,8 +4,7 @@ import { View, Text, TouchableOpacity, Linking } from "react-native";
|
|||||||
import { useCurrentTrain } from "../stateBox/useCurrentTrain";
|
import { useCurrentTrain } from "../stateBox/useCurrentTrain";
|
||||||
import { useNavigation } from "@react-navigation/native";
|
import { useNavigation } from "@react-navigation/native";
|
||||||
import lineColorList from "../assets/originData/lineColorList";
|
import lineColorList from "../assets/originData/lineColorList";
|
||||||
import { stationIDPair } from "../lib/getStationList2";
|
import { lineListPair, stationIDPair } from "../lib/getStationList";
|
||||||
import { lineListPair } from "../lib/getStationList";
|
|
||||||
import { SheetManager } from "react-native-actions-sheet";
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
import { useTrainMenu } from "../stateBox/useTrainMenu";
|
import { useTrainMenu } from "../stateBox/useTrainMenu";
|
||||||
//import { MapPin } from "./TrainMenu/MapPin";
|
//import { MapPin } from "./TrainMenu/MapPin";
|
||||||
@@ -20,8 +19,6 @@ export default function TrainMenu({ style }) {
|
|||||||
const {
|
const {
|
||||||
selectedLine,
|
selectedLine,
|
||||||
setSelectedLine,
|
setSelectedLine,
|
||||||
injectJavaScript,
|
|
||||||
setInjectJavaScript,
|
|
||||||
mapsStationData: stationData,
|
mapsStationData: stationData,
|
||||||
} = useTrainMenu();
|
} = useTrainMenu();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -216,7 +213,6 @@ export default function TrainMenu({ style }) {
|
|||||||
<MapsButton
|
<MapsButton
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
goBack();
|
goBack();
|
||||||
webview.current?.injectJavaScript(injectJavaScript);
|
|
||||||
}}
|
}}
|
||||||
top={0}
|
top={0}
|
||||||
mapSwitch={"flex"}
|
mapSwitch={"flex"}
|
||||||
|
@@ -16,6 +16,9 @@ import { TrainPosition } from "./LED_inside_Component/TrainPosition";
|
|||||||
import { TrainPositionDataPush } from "./LED_inside_Component/TrainPositionDataPush";
|
import { TrainPositionDataPush } from "./LED_inside_Component/TrainPositionDataPush";
|
||||||
import { TrainPositionDataDelete } from "./LED_inside_Component/TrainPositionDataDelete";
|
import { TrainPositionDataDelete } from "./LED_inside_Component/TrainPositionDataDelete";
|
||||||
import { useStationList } from "../../stateBox/useStationList";
|
import { useStationList } from "../../stateBox/useStationList";
|
||||||
|
import useInterval from "@/lib/useInterval";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
d: {
|
d: {
|
||||||
@@ -43,6 +46,7 @@ export const EachData: FC<Props> = (props) => {
|
|||||||
} = props;
|
} = props;
|
||||||
const { currentTrain } = useCurrentTrain();
|
const { currentTrain } = useCurrentTrain();
|
||||||
const { stationList } = useStationList();
|
const { stationList } = useStationList();
|
||||||
|
const { allCustonTrainData } = useAllTrainDiagram();
|
||||||
const openTrainInfo = (d: {
|
const openTrainInfo = (d: {
|
||||||
train: string;
|
train: string;
|
||||||
lastStation: string;
|
lastStation: string;
|
||||||
@@ -72,7 +76,10 @@ export const EachData: FC<Props> = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getTrainDataFromCurrentTrain = (trainNum: string) => {
|
const getTrainDataFromCurrentTrain = (trainNum: string) => {
|
||||||
const customTrainData = customTrainDataDetector(d.train);
|
const customTrainData = customTrainDataDetector(
|
||||||
|
d.train,
|
||||||
|
allCustonTrainData
|
||||||
|
);
|
||||||
switch (customTrainData.type) {
|
switch (customTrainData.type) {
|
||||||
case "Normal":
|
case "Normal":
|
||||||
case "OneMan":
|
case "OneMan":
|
||||||
@@ -117,26 +124,47 @@ export const EachData: FC<Props> = (props) => {
|
|||||||
const [descInput, setDescInput] = useState("");
|
const [descInput, setDescInput] = useState("");
|
||||||
const [stationInput, setStationInput] = useState("");
|
const [stationInput, setStationInput] = useState("");
|
||||||
const [stationNumberInput, setStationNumberInput] = useState("");
|
const [stationNumberInput, setStationNumberInput] = useState("");
|
||||||
|
|
||||||
|
const [isShow, setIsShow] = useState(true);
|
||||||
|
const [isDepartureNow, setIsDepartureNow] = useState(false);
|
||||||
|
useEffect(() => {
|
||||||
|
const currentTime = dayjs();
|
||||||
|
const trainTime = currentTime
|
||||||
|
.set("hour", parseInt(d.time.split(":")[0]))
|
||||||
|
.set("minute", parseInt(d.time.split(":")[1]));
|
||||||
|
const diff = trainTime.diff(currentTime, "minute");
|
||||||
|
if (diff < 2) setIsDepartureNow(true);
|
||||||
|
else setIsDepartureNow(false);
|
||||||
|
return () => {
|
||||||
|
setIsDepartureNow(false);
|
||||||
|
setIsShow(true);
|
||||||
|
};
|
||||||
|
}, [d.time, currentTrainData]);
|
||||||
|
useInterval(() => {
|
||||||
|
if (isDepartureNow) {
|
||||||
|
setIsShow(!isShow);
|
||||||
|
}
|
||||||
|
}, 800);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TrainPositionDataDelete
|
<TrainPositionDataDelete
|
||||||
dialog={deleteDialog}
|
dialog={deleteDialog}
|
||||||
setDialog={setDeleteDialog}
|
setDialog={setDeleteDialog}
|
||||||
currentTrainData={currentTrainData}
|
{...{ currentTrainData, stationInput, stationNumberInput }}
|
||||||
stationInput={stationInput}
|
|
||||||
stationNumberInput={stationNumberInput}
|
|
||||||
/>
|
/>
|
||||||
<TrainPositionDataPush
|
<TrainPositionDataPush
|
||||||
dialog={dialog}
|
dialog={dialog}
|
||||||
setDialog={setDialog}
|
setDialog={setDialog}
|
||||||
currentTrainData={currentTrainData}
|
{...{
|
||||||
stationInput={stationInput}
|
currentTrainData,
|
||||||
stationNumberInput={stationNumberInput}
|
stationInput,
|
||||||
posInput={posInput}
|
stationNumberInput,
|
||||||
descInput={descInput}
|
posInput,
|
||||||
setPosInput={setPosInput}
|
descInput,
|
||||||
setDescInput={setDescInput}
|
setPosInput,
|
||||||
station={station}
|
setDescInput,
|
||||||
|
station,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={{
|
style={{
|
||||||
@@ -147,8 +175,10 @@ export const EachData: FC<Props> = (props) => {
|
|||||||
marginHorizontal: "3%",
|
marginHorizontal: "3%",
|
||||||
backgroundColor: "#000",
|
backgroundColor: "#000",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
|
opacity: isShow ? 1 : 0.5,
|
||||||
}}
|
}}
|
||||||
onPress={() => openTrainInfo(d)}
|
onPress={() => openTrainInfo(d)}
|
||||||
|
key={d.train + "-eachData"}
|
||||||
>
|
>
|
||||||
<TrainName
|
<TrainName
|
||||||
trainName={train.trainName}
|
trainName={train.trainName}
|
||||||
@@ -161,6 +191,16 @@ export const EachData: FC<Props> = (props) => {
|
|||||||
<DependTime time={d.time} />
|
<DependTime time={d.time} />
|
||||||
<StatusAndDelay trainDelayStatus={trainDelayStatus} />
|
<StatusAndDelay trainDelayStatus={trainDelayStatus} />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
{!!isDepartureNow && (
|
||||||
|
<Description
|
||||||
|
info={
|
||||||
|
d.lastStation == "当駅止"
|
||||||
|
? "この列車は当駅止です。間もなく到着します。"
|
||||||
|
: "列車の出発時刻です。"
|
||||||
|
}
|
||||||
|
key={d.train + "-description"}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{trainDescriptionSwitch && (
|
{trainDescriptionSwitch && (
|
||||||
<TrainPosition
|
<TrainPosition
|
||||||
trainIDSwitch={trainIDSwitch}
|
trainIDSwitch={trainIDSwitch}
|
||||||
@@ -179,7 +219,7 @@ export const EachData: FC<Props> = (props) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{trainDescriptionSwitch && !!train.info && (
|
{trainDescriptionSwitch && !!train.info && (
|
||||||
<Description info={train.info} />
|
<Description info={train.info} key={d.train + "-description"} />
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@@ -1,48 +1,58 @@
|
|||||||
import { View, Text } from "react-native";
|
import { View, Text } from "react-native";
|
||||||
import { useCurrentTrain } from "../../../stateBox/useCurrentTrain";
|
import { useCurrentTrain } from "../../../stateBox/useCurrentTrain";
|
||||||
import LottieView from "lottie-react-native";
|
import LottieView from "lottie-react-native";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons, AntDesign } from "@expo/vector-icons";
|
||||||
|
import { useStationList } from "@/stateBox/useStationList";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
export const Header = ({ getCurrentTrain }) => {
|
export const Header = ({ station }) => {
|
||||||
const { currentTrainLoading, setCurrentTrainLoading } = useCurrentTrain();
|
const {
|
||||||
return (
|
currentTrainLoading,
|
||||||
<View
|
setCurrentTrainLoading,
|
||||||
style={{
|
getCurrentTrain,
|
||||||
alignContent: "center",
|
inject,
|
||||||
alignItems: "center",
|
} = useCurrentTrain();
|
||||||
width: "100%",
|
const { getInjectJavascriptAddress } = useStationList();
|
||||||
marginVertical: 10,
|
const { navigate } = useNavigation();
|
||||||
flexDirection: "row",
|
return (
|
||||||
}}
|
<View
|
||||||
>
|
style={{
|
||||||
<View style={{ flex: 1 }}></View>
|
alignContent: "center",
|
||||||
<View style={{}}>
|
alignItems: "center",
|
||||||
<Text style={{ fontSize: 25, color: "white", fontWeight: "bold" }}>
|
width: "100%",
|
||||||
次の列車
|
marginVertical: 10,
|
||||||
</Text>
|
flexDirection: "row",
|
||||||
<Text style={{ fontSize: 15, color: "white" }}>Next Train</Text>
|
}}
|
||||||
</View>
|
>
|
||||||
<View style={{ flex: 1, flexDirection: "row-reverse" }}>
|
<View style={{ flex: 1, flexDirection: "column", alignItems: "center" }}>
|
||||||
{currentTrainLoading == "loading" ? (
|
|
||||||
<LottieView
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
style={{ width: 40, height: 40, marginRight: 30 }}
|
|
||||||
source={require("../../../assets/51690-loading-diamonds.json")}
|
|
||||||
/>
|
|
||||||
) : currentTrainLoading == "error" ? (
|
|
||||||
<Ionicons
|
|
||||||
name="reload"
|
|
||||||
color="white"
|
|
||||||
size={30}
|
|
||||||
style={{ marginRight: 30 }}
|
|
||||||
onPress={() => {
|
|
||||||
setCurrentTrainLoading("loading");
|
|
||||||
getCurrentTrain();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</View>
|
|
||||||
</View>
|
</View>
|
||||||
);
|
<View style={{}}>
|
||||||
};
|
<Text style={{ fontSize: 25, color: "white", fontWeight: "bold" }}>
|
||||||
|
次の列車
|
||||||
|
</Text>
|
||||||
|
<Text style={{ fontSize: 15, color: "white" }}>Next Train</Text>
|
||||||
|
</View>
|
||||||
|
<View style={{ flex: 1, flexDirection: "row-reverse" }}>
|
||||||
|
{currentTrainLoading == "loading" ? (
|
||||||
|
<LottieView
|
||||||
|
autoPlay
|
||||||
|
loop
|
||||||
|
style={{ width: 40, height: 40, marginRight: 30 }}
|
||||||
|
source={require("../../../assets/51690-loading-diamonds.json")}
|
||||||
|
/>
|
||||||
|
) : currentTrainLoading == "error" ? (
|
||||||
|
<Ionicons
|
||||||
|
name="reload"
|
||||||
|
color="white"
|
||||||
|
size={30}
|
||||||
|
style={{ marginRight: 30 }}
|
||||||
|
onPress={() => {
|
||||||
|
setCurrentTrainLoading("loading");
|
||||||
|
getCurrentTrain();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
@@ -5,7 +5,6 @@ import {
|
|||||||
trainDataType,
|
trainDataType,
|
||||||
trainPosition,
|
trainPosition,
|
||||||
} from "../../../lib/trainPositionTextArray";
|
} from "../../../lib/trainPositionTextArray";
|
||||||
import { lineList } from "../../../lib/getStationList";
|
|
||||||
import { getStationID } from "../../../lib/eachTrainInfoCoreLib/getStationData";
|
import { getStationID } from "../../../lib/eachTrainInfoCoreLib/getStationData";
|
||||||
import { useCurrentTrain } from "../../../stateBox/useCurrentTrain";
|
import { useCurrentTrain } from "../../../stateBox/useCurrentTrain";
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { View } from "react-native";
|
import { View, useWindowDimensions } from "react-native";
|
||||||
import { widthPercentageToDP as wp } from "react-native-responsive-screen";
|
import dayjs from "dayjs";
|
||||||
import { useInterval } from "../../lib/useInterval";
|
import { useInterval } from "../../lib/useInterval";
|
||||||
import { objectIsEmpty } from "../../lib/objectIsEmpty";
|
import { objectIsEmpty } from "../../lib/objectIsEmpty";
|
||||||
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
|
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
|
||||||
@@ -10,8 +10,8 @@ import { Footer } from "./LED_Vision_Component/Footer";
|
|||||||
import { Header } from "./LED_Vision_Component/Header";
|
import { Header } from "./LED_Vision_Component/Header";
|
||||||
import { Description } from "./LED_inside_Component/Description";
|
import { Description } from "./LED_inside_Component/Description";
|
||||||
import { EachData } from "./EachData";
|
import { EachData } from "./EachData";
|
||||||
|
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||||
|
import { trainPosition } from "@/lib/trainPositionTextArray";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -43,13 +43,7 @@ import { EachData } from "./EachData";
|
|||||||
* 9062D 四国まんなか千年ものがたり(臨時?)
|
* 9062D 四国まんなか千年ものがたり(臨時?)
|
||||||
*/
|
*/
|
||||||
export default function LED_vision(props) {
|
export default function LED_vision(props) {
|
||||||
const {
|
const { station, navigate, openStationACFromEachTrainInfo } = props;
|
||||||
station,
|
|
||||||
trainDiagram,
|
|
||||||
getCurrentTrain,
|
|
||||||
navigate,
|
|
||||||
openStationACFromEachTrainInfo,
|
|
||||||
} = props;
|
|
||||||
const { currentTrain } = useCurrentTrain();
|
const { currentTrain } = useCurrentTrain();
|
||||||
const [stationDiagram, setStationDiagram] = useState({}); //当該駅の全時刻表
|
const [stationDiagram, setStationDiagram] = useState({}); //当該駅の全時刻表
|
||||||
const [finalSwitch, setFinalSwitch] = useState(false);
|
const [finalSwitch, setFinalSwitch] = useState(false);
|
||||||
@@ -57,36 +51,40 @@ export default function LED_vision(props) {
|
|||||||
const [trainDescriptionSwitch, setTrainDescriptionSwitch] = useState(false);
|
const [trainDescriptionSwitch, setTrainDescriptionSwitch] = useState(false);
|
||||||
const [isInfoArea, setIsInfoArea] = useState(false);
|
const [isInfoArea, setIsInfoArea] = useState(false);
|
||||||
const { areaInfo, areaStationID } = useAreaInfo();
|
const { areaInfo, areaStationID } = useAreaInfo();
|
||||||
|
const { allTrainDiagram } = useAllTrainDiagram();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
AS.getItem("LEDSettings/trainIDSwitch").then((data) => {
|
AS.getItem("LEDSettings/trainIDSwitch").then((data) => {
|
||||||
setTrainIDSwitch(data === "true");
|
setTrainIDSwitch(data === "true");
|
||||||
});
|
});
|
||||||
AS.getItem("LEDSettings/trainDescriptionSwitch").then((data) => {
|
AS.getItem("LEDSettings/trainDescriptionSwitch").then((data) => {
|
||||||
setTrainDescriptionSwitch(data == "true");
|
setTrainDescriptionSwitch(data === "true");
|
||||||
});
|
});
|
||||||
AS.getItem("LEDSettings/finalSwitch").then((data) => {
|
AS.getItem("LEDSettings/finalSwitch").then((data) => {
|
||||||
setFinalSwitch(data == "true");
|
setFinalSwitch(data === "true");
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 現在の駅に停車するダイヤを作成する副作用[列車ダイヤと現在駅情報]
|
// 現在の駅に停車するダイヤを作成する副作用[列車ダイヤと現在駅情報]
|
||||||
if (!trainDiagram) {
|
if (!allTrainDiagram) {
|
||||||
setStationDiagram({});
|
setStationDiagram({});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let returnData = {};
|
let returnData = {};
|
||||||
Object.keys(trainDiagram).forEach((key) => {
|
Object.keys(allTrainDiagram).forEach((key) => {
|
||||||
if (trainDiagram[key].match(station[0].Station_JP + ",")) {
|
if (allTrainDiagram[key].match(station[0].Station_JP + ",")) {
|
||||||
returnData[key] = trainDiagram[key];
|
returnData[key] = allTrainDiagram[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setStationDiagram(returnData);
|
setStationDiagram(returnData);
|
||||||
setIsInfoArea(station.some((s) => areaStationID.includes(s.StationNumber)));
|
setIsInfoArea(station.some((s) => areaStationID.includes(s.StationNumber)));
|
||||||
}, [trainDiagram, station]);
|
}, [allTrainDiagram, station]);
|
||||||
|
|
||||||
const [trainTimeAndNumber, setTrainTimeAndNumber] = useState(null);
|
/*
|
||||||
|
{lastStation: "当駅止", time: "12:34", train: "1234M"}
|
||||||
|
*/
|
||||||
|
const [trainTimeAndNumber, setTrainTimeAndNumber] = useState([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
//現在の駅に停車する列車から時刻を切り出してLEDベースにフォーマット
|
//現在の駅に停車する列車から時刻を切り出してLEDベースにフォーマット
|
||||||
@@ -100,34 +98,36 @@ export default function LED_vision(props) {
|
|||||||
if (!trainTimeAndNumber) return () => {};
|
if (!trainTimeAndNumber) return () => {};
|
||||||
if (!currentTrain) return () => {};
|
if (!currentTrain) return () => {};
|
||||||
const data = trainTimeAndNumber
|
const data = trainTimeAndNumber
|
||||||
.filter((d) => currentTrain.map((m) => m.num).includes(d.train))
|
.filter((d) => currentTrain.map((m) => m.num).includes(d.train)) //現在の列車に絞る[ToDo]
|
||||||
.filter(timeFiltering)
|
.filter(timeFiltering)
|
||||||
.filter((d) => !!finalSwitch || d.lastStation != "当駅止");
|
.filter((d) => !!finalSwitch || d.lastStation != "当駅止");
|
||||||
setSelectedTrain(data);
|
setSelectedTrain(data);
|
||||||
}, [trainTimeAndNumber, currentTrain, finalSwitch]);
|
}, [trainTimeAndNumber, currentTrain, finalSwitch]);
|
||||||
|
|
||||||
const getTime = (stationDiagram, station) => {
|
const getTime = (stationDiagram, station) => {
|
||||||
const returnData = Object.keys(stationDiagram).map((trainNum) => {
|
const returnData = Object.keys(stationDiagram)
|
||||||
let trainData = {};
|
.map((trainNum) => {
|
||||||
stationDiagram[trainNum].split("#").forEach((data) => {
|
let trainData = {};
|
||||||
if (data.match("着")) {
|
stationDiagram[trainNum].split("#").forEach((data) => {
|
||||||
trainData.lastStation = data.split(",着,")[0];
|
if (data.match("着")) {
|
||||||
}
|
trainData.lastStation = data.split(",着,")[0];
|
||||||
if (data.split(",")[0] === station.Station_JP) {
|
|
||||||
if (data.match(",発,")) {
|
|
||||||
trainData.time = data.split(",発,")[1];
|
|
||||||
} else if(data.match(",着,")){
|
|
||||||
trainData.time = data.split(",着,")[1];
|
|
||||||
trainData.lastStation = "当駅止";
|
|
||||||
}
|
}
|
||||||
}
|
if (data.split(",")[0] === station.Station_JP) {
|
||||||
});
|
if (data.match(",発,")) {
|
||||||
return {
|
trainData.time = data.split(",発,")[1];
|
||||||
train: trainNum,
|
} else if (data.match(",着,")) {
|
||||||
time: trainData.time,
|
trainData.time = data.split(",着,")[1];
|
||||||
lastStation: trainData.lastStation,
|
trainData.lastStation = "当駅止";
|
||||||
};
|
}
|
||||||
}).filter((d) => d.time);
|
}
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
train: trainNum,
|
||||||
|
time: trainData.time,
|
||||||
|
lastStation: trainData.lastStation,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter((d) => d.time);
|
||||||
return returnData.sort((a, b) => {
|
return returnData.sort((a, b) => {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case parseInt(a.time.split(":")[0]) < parseInt(b.time.split(":")[0]):
|
case parseInt(a.time.split(":")[0]) < parseInt(b.time.split(":")[0]):
|
||||||
@@ -145,16 +145,40 @@ export default function LED_vision(props) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const timeFiltering = (d) => {
|
const timeFiltering = (d) => {
|
||||||
const date = new Date();
|
|
||||||
const newDate = new Date();
|
|
||||||
let data = d.time.split(":");
|
|
||||||
let delay = isNaN(currentTrain.filter((t) => t.num == d.train)[0].delay)
|
|
||||||
? 0
|
|
||||||
: currentTrain.filter((t) => t.num == d.train)[0].delay;
|
|
||||||
|
|
||||||
date.setHours(parseInt(data[0]));
|
const baseTime = 2;
|
||||||
date.setMinutes(parseInt(data[1]) + parseInt(delay));
|
|
||||||
return !(newDate > date);
|
if (currentTrain.filter((t) => t.num == d.train).length == 0) {
|
||||||
|
const date = dayjs();
|
||||||
|
const trainTime = date
|
||||||
|
.hour(parseInt(d.time.split(":")[0]))
|
||||||
|
.minute(parseInt(d.time.split(":")[1]));
|
||||||
|
|
||||||
|
if (date.isAfter(trainTime)) {
|
||||||
|
return false;
|
||||||
|
} else if (trainTime.diff(date) < baseTime * 60 * 60 * 1000) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
const Pos = trainPosition(
|
||||||
|
currentTrain.filter((t) => t.num == d.train)[0]
|
||||||
|
);
|
||||||
|
const nextPos = Pos.isBetween ? Pos.Pos.to : Pos.Pos.Pos;
|
||||||
|
const PrePos = Pos.isBetween ? Pos.Pos.from : "";
|
||||||
|
if (station[0].Station_JP == nextPos) {
|
||||||
|
if(d.lastStation != "当駅止") return true;
|
||||||
|
} else if (station[0].Station_JP == PrePos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const date = dayjs();
|
||||||
|
let [h, m] = d.time.split(":");
|
||||||
|
let delay = isNaN(currentTrain.filter((t) => t.num == d.train)[0].delay)
|
||||||
|
? 0
|
||||||
|
: currentTrain.filter((t) => t.num == d.train)[0].delay;
|
||||||
|
const db = date.hour(parseInt(h)).minute(parseInt(m) + parseInt(delay));
|
||||||
|
return !date.isAfter(db);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const [areaString, setAreaString] = useState("");
|
const [areaString, setAreaString] = useState("");
|
||||||
@@ -186,18 +210,19 @@ export default function LED_vision(props) {
|
|||||||
}
|
}
|
||||||
setAreaStringLength(areaInfo.length);
|
setAreaStringLength(areaInfo.length);
|
||||||
}, [areaInfo]);
|
}, [areaInfo]);
|
||||||
|
const { width } = useWindowDimensions();
|
||||||
|
const adjustedWidth = width * 0.98;
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
width: wp("98%"),
|
width: adjustedWidth,
|
||||||
/* height: wp("98%")/10*9, */ backgroundColor: "#432",
|
/* height: wp("98%")/10*9, */ backgroundColor: "#432",
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
margin: 10,
|
margin: 10,
|
||||||
marginHorizontal: wp("1%"),
|
marginHorizontal: width * 0.01,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Header getCurrentTrain={getCurrentTrain} />
|
<Header station={station[0]} />
|
||||||
{selectedTrain.map((d) => (
|
{selectedTrain.map((d) => (
|
||||||
<EachData
|
<EachData
|
||||||
{...{
|
{...{
|
||||||
|
@@ -1,9 +1,22 @@
|
|||||||
import React, { CSSProperties, FC } from "react";
|
import React, { CSSProperties, FC } from "react";
|
||||||
import { widthPercentageToDP as wp } from "react-native-responsive-screen";
|
import {
|
||||||
import { Platform, Text, TextStyle, View, ViewStyle } from "react-native";
|
Platform,
|
||||||
|
Text,
|
||||||
|
TextStyle,
|
||||||
|
useWindowDimensions,
|
||||||
|
View,
|
||||||
|
ViewStyle,
|
||||||
|
} from "react-native";
|
||||||
import { StationName } from "./StationName";
|
import { StationName } from "./StationName";
|
||||||
import lineColorList from "../../assets/originData/lineColorList";
|
import lineColorList from "../../assets/originData/lineColorList";
|
||||||
export const NextPreStationLine = ({ nexStation, preStation, isMatsuyama }) => {
|
export const NextPreStationLine = ({ nexStation, preStation, isMatsuyama }) => {
|
||||||
|
const 下枠フレーム: ViewStyle = {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: "row",
|
||||||
|
alignContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={下枠フレーム}>
|
<View style={下枠フレーム}>
|
||||||
<View style={下枠フレーム}>
|
<View style={下枠フレーム}>
|
||||||
@@ -49,12 +62,40 @@ type FCimport = {
|
|||||||
children: string;
|
children: string;
|
||||||
};
|
};
|
||||||
const BottomSideArrow: FC<FCimport> = ({ isMatsuyama, children }) => {
|
const BottomSideArrow: FC<FCimport> = ({ isMatsuyama, children }) => {
|
||||||
|
const 下枠左右マーク: TextStyle = {
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: parseInt("20%"),
|
||||||
|
color: "white",
|
||||||
|
paddingHorizontal: 5,
|
||||||
|
textAlignVertical: "center",
|
||||||
|
};
|
||||||
return !isMatsuyama && <Text style={下枠左右マーク}>{children}</Text>;
|
return !isMatsuyama && <Text style={下枠左右マーク}>{children}</Text>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const BottomStationNumberView: FC<FCimport> = ({ isMatsuyama, children }) => {
|
const BottomStationNumberView: FC<FCimport> = ({ isMatsuyama, children }) => {
|
||||||
|
const { width } = useWindowDimensions();
|
||||||
const lineID = children.slice(0, 1);
|
const lineID = children.slice(0, 1);
|
||||||
const lineName = children.slice(1);
|
const lineName = children.slice(1);
|
||||||
|
const 下枠駅ナンバー: ViewStyle = {
|
||||||
|
alignContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
width: width * 0.08,
|
||||||
|
height: width * 0.08,
|
||||||
|
margin: width * 0.01,
|
||||||
|
backgroundColor: "white",
|
||||||
|
borderWidth: parseInt("3%"),
|
||||||
|
borderRadius: parseInt("100%"),
|
||||||
|
};
|
||||||
|
const 下枠駅ナンバーB: ViewStyle = {
|
||||||
|
alignContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
width: width * 0.07,
|
||||||
|
height: width * 0.07,
|
||||||
|
margin: width * 0.02,
|
||||||
|
backgroundColor: "white",
|
||||||
|
borderWidth: parseInt("3%"),
|
||||||
|
borderRadius: parseInt("100%"),
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
@@ -77,37 +118,3 @@ const BottomStationNumberView: FC<FCimport> = ({ isMatsuyama, children }) => {
|
|||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const 下枠フレーム: ViewStyle = {
|
|
||||||
flex: 1,
|
|
||||||
flexDirection: "row",
|
|
||||||
alignContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
};
|
|
||||||
const 下枠左右マーク: TextStyle = {
|
|
||||||
fontWeight: "bold",
|
|
||||||
fontSize: parseInt("20%"),
|
|
||||||
color: "white",
|
|
||||||
paddingHorizontal: 5,
|
|
||||||
textAlignVertical: "center",
|
|
||||||
};
|
|
||||||
const 下枠駅ナンバー: ViewStyle = {
|
|
||||||
alignContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
width: wp("8%"),
|
|
||||||
height: wp("8%"),
|
|
||||||
margin: wp("1%"),
|
|
||||||
backgroundColor: "white",
|
|
||||||
borderWidth: parseInt("3%"),
|
|
||||||
borderRadius: parseInt("100%"),
|
|
||||||
};
|
|
||||||
const 下枠駅ナンバーB: ViewStyle = {
|
|
||||||
alignContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
width: wp("7%"),
|
|
||||||
height: wp("7%"),
|
|
||||||
margin: wp("2%"),
|
|
||||||
backgroundColor: "white",
|
|
||||||
borderWidth: parseInt("3%"),
|
|
||||||
borderRadius: parseInt("100%"),
|
|
||||||
};
|
|
||||||
|
@@ -1,6 +1,10 @@
|
|||||||
import React, { useRef, useState, useEffect, useLayoutEffect } from "react";
|
import React, { useRef, useState, useEffect, useLayoutEffect } from "react";
|
||||||
import { View, Text, TouchableOpacity } from "react-native";
|
import {
|
||||||
import { widthPercentageToDP as wp } from "react-native-responsive-screen";
|
View,
|
||||||
|
Text,
|
||||||
|
TouchableOpacity,
|
||||||
|
useWindowDimensions,
|
||||||
|
} from "react-native";
|
||||||
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
||||||
import LottieView from "lottie-react-native";
|
import LottieView from "lottie-react-native";
|
||||||
import { useInterval } from "../../lib/useInterval";
|
import { useInterval } from "../../lib/useInterval";
|
||||||
@@ -15,7 +19,14 @@ import { AddressText } from "./AddressText";
|
|||||||
import { useStationList } from "../../stateBox/useStationList";
|
import { useStationList } from "../../stateBox/useStationList";
|
||||||
|
|
||||||
export default function Sign(props) {
|
export default function Sign(props) {
|
||||||
const { currentStation, oP, oLP, isCurrentStation = false } = props;
|
const { oP, oLP, isCurrentStation = false, stationID } = props;
|
||||||
|
|
||||||
|
const { width, height } = useWindowDimensions();
|
||||||
|
const { getStationDataFromId } = useStationList();
|
||||||
|
if (!stationID) {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
const [currentStationData] = useState(getStationDataFromId(stationID));
|
||||||
const { favoriteStation, setFavoriteStation } = useFavoriteStation();
|
const { favoriteStation, setFavoriteStation } = useFavoriteStation();
|
||||||
const [nexPrePosition, setNexPrePosition] = useState(0);
|
const [nexPrePosition, setNexPrePosition] = useState(0);
|
||||||
const { originalStationList } = useStationList();
|
const { originalStationList } = useStationList();
|
||||||
@@ -26,48 +37,40 @@ export default function Sign(props) {
|
|||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const isFavorite = favoriteStation.filter((d) => {
|
const isFavorite = favoriteStation.filter((d) => {
|
||||||
const compare = JSON.stringify(d);
|
const compare = JSON.stringify(d);
|
||||||
const current = JSON.stringify(currentStation);
|
const current = JSON.stringify(currentStationData);
|
||||||
if (compare === current) {
|
return compare === current;
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
setTestButtonStatus(isFavorite.length == 0 ? false : true);
|
setTestButtonStatus(isFavorite.length == 0 ? false : true);
|
||||||
}, [favoriteStation, currentStation]);
|
}, [favoriteStation, currentStationData]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const isFavorite = favoriteStation.filter((d) => {
|
const isFavorite = favoriteStation.filter((d) => {
|
||||||
const compare = JSON.stringify(d);
|
const compare = JSON.stringify(d);
|
||||||
const current = JSON.stringify(currentStation);
|
const current = JSON.stringify(currentStationData);
|
||||||
if (compare === current) {
|
return compare === current;
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
setTestButtonStatus(isFavorite.length == 0 ? false : true);
|
setTestButtonStatus(isFavorite.length == 0 ? false : true);
|
||||||
}, [favoriteStation, currentStation]);
|
}, [favoriteStation, currentStationData]);
|
||||||
|
|
||||||
useInterval(() => {
|
useInterval(() => {
|
||||||
if (currentStation.length == 1) {
|
if (currentStationData.length == 1) {
|
||||||
setNexPrePosition(0);
|
setNexPrePosition(0);
|
||||||
return () => {};
|
return () => {};
|
||||||
}
|
}
|
||||||
setNexPrePosition(
|
setNexPrePosition(
|
||||||
nexPrePosition + 1 == currentStation.length ? 0 : nexPrePosition + 1
|
nexPrePosition + 1 == currentStationData.length ? 0 : nexPrePosition + 1
|
||||||
);
|
);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setNexPrePosition(0);
|
setNexPrePosition(0);
|
||||||
getPreNextStation(currentStation[0]);
|
getPreNextStation(currentStationData[0]);
|
||||||
if (currentStation.length == 1) return () => {};
|
if (currentStationData.length == 1) return () => {};
|
||||||
getPreNextStation(currentStation[1]);
|
getPreNextStation(currentStationData[1]);
|
||||||
}, [currentStation]);
|
}, [currentStationData]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!currentStation[nexPrePosition]) return () => {};
|
if (!currentStationData[nexPrePosition]) return () => {};
|
||||||
getPreNextStation(currentStation[nexPrePosition]);
|
getPreNextStation(currentStationData[nexPrePosition]);
|
||||||
}, [nexPrePosition]);
|
}, [nexPrePosition]);
|
||||||
const getPreNextStation = (now) => {
|
const getPreNextStation = (now) => {
|
||||||
const lineList = [
|
const lineList = [
|
||||||
@@ -101,25 +104,81 @@ export default function Sign(props) {
|
|||||||
if (returnData[1]) setNexStation(returnData[1]);
|
if (returnData[1]) setNexStation(returnData[1]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const isMatsuyama = currentStation[0].StationNumber == "Y55";
|
const isMatsuyama = currentStationData[0].StationNumber == "Y55";
|
||||||
//const isMatsuyama = true;
|
//const isMatsuyama = true;
|
||||||
const favoliteChanger = () => {
|
const favoliteChanger = () => {
|
||||||
if (testButtonStatus) {
|
if (testButtonStatus) {
|
||||||
const otherData = favoriteStation.filter((d) => {
|
const otherData = favoriteStation.filter((d) => {
|
||||||
const compare = JSON.stringify(d);
|
const compare = JSON.stringify(d);
|
||||||
const current = JSON.stringify(currentStation);
|
const current = JSON.stringify(currentStationData);
|
||||||
return compare !== current;
|
return compare !== current;
|
||||||
});
|
});
|
||||||
AS.setItem("favoriteStation", JSON.stringify(otherData));
|
AS.setItem("favoriteStation", JSON.stringify(otherData));
|
||||||
setFavoriteStation(otherData);
|
setFavoriteStation(otherData);
|
||||||
} else {
|
} else {
|
||||||
let ret = favoriteStation;
|
let ret = favoriteStation;
|
||||||
ret.push(currentStation);
|
ret.push(currentStationData);
|
||||||
AS.setItem("favoriteStation", JSON.stringify(ret));
|
AS.setItem("favoriteStation", JSON.stringify(ret));
|
||||||
setFavoriteStation(ret);
|
setFavoriteStation(ret);
|
||||||
}
|
}
|
||||||
setTestButtonStatus(!testButtonStatus);
|
setTestButtonStatus(!testButtonStatus);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const styleSheet = {
|
||||||
|
外枠: {
|
||||||
|
width: width * 0.8,
|
||||||
|
height: ((width * 0.8) / 20) * 9,
|
||||||
|
borderColor: "#0099CC",
|
||||||
|
borderWidth: 1,
|
||||||
|
backgroundColor: "white",
|
||||||
|
},
|
||||||
|
外枠B: {
|
||||||
|
width: width * 0.8,
|
||||||
|
height: ((width * 0.8) / 20) * 9,
|
||||||
|
borderWidth: 0,
|
||||||
|
},
|
||||||
|
下帯: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: "8%",
|
||||||
|
left: "0%",
|
||||||
|
width: "100%",
|
||||||
|
height: "27%",
|
||||||
|
backgroundColor: "#0099CC",
|
||||||
|
},
|
||||||
|
下帯B: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: "0%",
|
||||||
|
left: "0%",
|
||||||
|
width: "100%",
|
||||||
|
height: "26%",
|
||||||
|
backgroundColor: "#454545",
|
||||||
|
},
|
||||||
|
JRStyle: {
|
||||||
|
position: "absolute",
|
||||||
|
top: "2%",
|
||||||
|
left: "2%",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: parseInt("25%"),
|
||||||
|
color: "#0099CC",
|
||||||
|
},
|
||||||
|
下帯内容: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: "8%",
|
||||||
|
height: "27%",
|
||||||
|
width: "100%",
|
||||||
|
alignItems: "center",
|
||||||
|
flexDirection: "column",
|
||||||
|
},
|
||||||
|
下帯内容B: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: "0%",
|
||||||
|
height: "26%",
|
||||||
|
width: "100%",
|
||||||
|
alignItems: "center",
|
||||||
|
flexDirection: "column",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={styleSheet[isMatsuyama ? "外枠B" : "外枠"]}
|
style={styleSheet[isMatsuyama ? "外枠B" : "外枠"]}
|
||||||
@@ -131,15 +190,19 @@ export default function Sign(props) {
|
|||||||
autoPlay
|
autoPlay
|
||||||
loop
|
loop
|
||||||
style={{
|
style={{
|
||||||
width: wp("80%"),
|
width: width * 0.8,
|
||||||
height: (wp("80%") / 20) * 9,
|
height: ((width * 0.8) / 20) * 9,
|
||||||
backgroundColor: "#fff",
|
backgroundColor: "#fff",
|
||||||
}}
|
}}
|
||||||
source={require("../../assets/StationSign.json")}
|
source={require("../../assets/StationSign.json")}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<StationNumberMaker {...{ currentStation, isMatsuyama }} />
|
<StationNumberMaker
|
||||||
<StationNameArea {...{ currentStation, isMatsuyama }} />
|
{...{ currentStation: currentStationData, isMatsuyama }}
|
||||||
|
/>
|
||||||
|
<StationNameArea
|
||||||
|
{...{ currentStation: currentStationData, isMatsuyama }}
|
||||||
|
/>
|
||||||
{isCurrentStation ? (
|
{isCurrentStation ? (
|
||||||
<View style={{ position: "absolute", right: 0, top: 0 }}>
|
<View style={{ position: "absolute", right: 0, top: 0 }}>
|
||||||
<MaterialCommunityIcons
|
<MaterialCommunityIcons
|
||||||
@@ -163,62 +226,7 @@ export default function Sign(props) {
|
|||||||
<View style={styleSheet[isMatsuyama ? "下帯内容B" : "下帯内容"]}>
|
<View style={styleSheet[isMatsuyama ? "下帯内容B" : "下帯内容"]}>
|
||||||
<NextPreStationLine {...{ nexStation, preStation, isMatsuyama }} />
|
<NextPreStationLine {...{ nexStation, preStation, isMatsuyama }} />
|
||||||
</View>
|
</View>
|
||||||
<AddressText {...{ currentStation, isMatsuyama }} />
|
<AddressText {...{ currentStation: currentStationData, isMatsuyama }} />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styleSheet = {
|
|
||||||
外枠: {
|
|
||||||
width: wp("80%"),
|
|
||||||
height: (wp("80%") / 20) * 9,
|
|
||||||
borderColor: "#0099CC",
|
|
||||||
borderWidth: 1,
|
|
||||||
backgroundColor: "white",
|
|
||||||
},
|
|
||||||
外枠B: {
|
|
||||||
width: wp("80%"),
|
|
||||||
height: (wp("80%") / 20) * 9,
|
|
||||||
borderWidth: 0,
|
|
||||||
},
|
|
||||||
下帯: {
|
|
||||||
position: "absolute",
|
|
||||||
bottom: "8%",
|
|
||||||
left: "0%",
|
|
||||||
width: "100%",
|
|
||||||
height: "27%",
|
|
||||||
backgroundColor: "#0099CC",
|
|
||||||
},
|
|
||||||
下帯B: {
|
|
||||||
position: "absolute",
|
|
||||||
bottom: "0%",
|
|
||||||
left: "0%",
|
|
||||||
width: "100%",
|
|
||||||
height: "26%",
|
|
||||||
backgroundColor: "#454545",
|
|
||||||
},
|
|
||||||
JRStyle: {
|
|
||||||
position: "absolute",
|
|
||||||
top: "2%",
|
|
||||||
left: "2%",
|
|
||||||
fontWeight: "bold",
|
|
||||||
fontSize: parseInt("25%"),
|
|
||||||
color: "#0099CC",
|
|
||||||
},
|
|
||||||
下帯内容: {
|
|
||||||
position: "absolute",
|
|
||||||
bottom: "8%",
|
|
||||||
height: "27%",
|
|
||||||
width: "100%",
|
|
||||||
alignItems: "center",
|
|
||||||
flexDirection: "column",
|
|
||||||
},
|
|
||||||
下帯内容B: {
|
|
||||||
position: "absolute",
|
|
||||||
bottom: "0%",
|
|
||||||
height: "26%",
|
|
||||||
width: "100%",
|
|
||||||
alignItems: "center",
|
|
||||||
flexDirection: "column",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
@@ -1,10 +1,11 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Text, View } from "react-native";
|
import { Text, View } from "react-native";
|
||||||
import { widthPercentageToDP as wp } from "react-native-responsive-screen";
|
import { useWindowDimensions } from "react-native";
|
||||||
import lineColorList from "../../assets/originData/lineColorList";
|
import lineColorList from "../../assets/originData/lineColorList";
|
||||||
|
|
||||||
export const StationNumberMaker = (props) => {
|
export const StationNumberMaker = (props) => {
|
||||||
const { currentStation, isMatsuyama } = props;
|
const { currentStation, isMatsuyama } = props;
|
||||||
|
const { width } = useWindowDimensions();
|
||||||
const getTop = (array: number[], index: number) => {
|
const getTop = (array: number[], index: number) => {
|
||||||
if (array.length == 1) return 20;
|
if (array.length == 1) return 20;
|
||||||
else if (index == 0) return 5;
|
else if (index == 0) return 5;
|
||||||
@@ -24,8 +25,8 @@ export const StationNumberMaker = (props) => {
|
|||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
top: `${getTop(array, index)}%`,
|
top: `${getTop(array, index)}%`,
|
||||||
right: "10%",
|
right: "10%",
|
||||||
width: wp("10%"),
|
width: (width / 100 * 10),
|
||||||
height: wp("10%"),
|
height: (width / 100 * 10),
|
||||||
borderColor: lineColorList[lineID],
|
borderColor: lineColorList[lineID],
|
||||||
backgroundColor: "white",
|
backgroundColor: "white",
|
||||||
borderWidth: parseInt("3%"),
|
borderWidth: parseInt("3%"),
|
||||||
|
@@ -1 +1 @@
|
|||||||
export const news = "2025-03-06";
|
export const news = "2025-07-09";
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import { trainDataType } from "./trainPositionTextArray";
|
import { trainDataType } from "./trainPositionTextArray";
|
||||||
import { getStationID } from "./eachTrainInfoCoreLib/getStationData";
|
import { stationIDPair } from "../lib/getStationList";
|
||||||
import { stationIDPair } from "../lib/getStationList2";
|
|
||||||
|
|
||||||
export const checkDuplicateTrainData = (
|
export const checkDuplicateTrainData = (
|
||||||
currentTrainArray: trainDataType[],
|
currentTrainArray: trainDataType[],
|
||||||
|
@@ -40,6 +40,52 @@ export const lineListPair = {
|
|||||||
N: "鳴門線(池谷-鳴門間)[N]",
|
N: "鳴門線(池谷-鳴門間)[N]",
|
||||||
M: "瀬戸大橋線(児島-宇多津間)[M]",
|
M: "瀬戸大橋線(児島-宇多津間)[M]",
|
||||||
};
|
};
|
||||||
|
export const lineList_LineWebID = {
|
||||||
|
"予讃線(高松-松山間)[Y]" : "yosan",
|
||||||
|
"予讃線(松山-宇和島間)[U]" : "uwajima",
|
||||||
|
"予讃線/愛ある伊予灘線(向井原-伊予大洲間)[S]" : "uwajima2",
|
||||||
|
"土讃線(多度津-高知間)[D]" : "dosan",
|
||||||
|
"土讃線(高知-窪川間)[K]" : "dosan2",
|
||||||
|
"高徳線(高松-徳島間)[T]" : "koutoku",
|
||||||
|
"徳島線(徳島-阿波池田間)[B]" : "tokushima",
|
||||||
|
"鳴門線(池谷-鳴門間)[N]" : "naruto",
|
||||||
|
"瀬戸大橋線(児島-宇多津間)[M]" : "seto",
|
||||||
|
};
|
||||||
|
export const getStationList2 = async () => {
|
||||||
|
return {
|
||||||
|
yosan,
|
||||||
|
uwajima,
|
||||||
|
uwajima2,
|
||||||
|
dosan,
|
||||||
|
dosan2,
|
||||||
|
koutoku,
|
||||||
|
tokushima,
|
||||||
|
naruto,
|
||||||
|
seto,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export const stationIDPair = {
|
||||||
|
yosan: "Y",
|
||||||
|
uwajima: "U",
|
||||||
|
uwajima2: "S",
|
||||||
|
dosan: "D",
|
||||||
|
dosan2: "K",
|
||||||
|
koutoku: "T",
|
||||||
|
tokushima: "B",
|
||||||
|
naruto: "N",
|
||||||
|
seto: "M",
|
||||||
|
};
|
||||||
|
export const stationNamePair = {
|
||||||
|
"予讃線(高松 - 松山)": "yosan",
|
||||||
|
"予讃線・内子線(松山 - 内子 - 宇和島)": "uwajima",
|
||||||
|
"予讃線・伊予灘線(向井原 - 伊予大洲)": "uwajima2",
|
||||||
|
"土讃線(多度津 - 高知)": "dosan",
|
||||||
|
"土讃線(高知 - 窪川)": "dosan2",
|
||||||
|
"高徳線(高松 - 徳島)": "koutoku",
|
||||||
|
"徳島線(徳島 - 阿波池田)": "tokushima",
|
||||||
|
"鳴門線(池谷 - 鳴門)": "naruto",
|
||||||
|
"瀬戸大橋線(児島 - 宇多津)": "seto",
|
||||||
|
};
|
||||||
|
|
||||||
export const getStationList = async () => {
|
export const getStationList = async () => {
|
||||||
if (status) return status;
|
if (status) return status;
|
||||||
@@ -132,6 +178,11 @@ export const getStationList = async () => {
|
|||||||
予讃線,
|
予讃線,
|
||||||
stationList["日英対応表"]
|
stationList["日英対応表"]
|
||||||
);
|
);
|
||||||
|
stationList["予讃線(松山-宇和島間)[U]"] = addStationPosition(
|
||||||
|
concatBetweenStations(stationList["予讃線(松山-宇和島間)[U]"]),
|
||||||
|
内子線,
|
||||||
|
stationList["日英対応表"]
|
||||||
|
);
|
||||||
stationList["予讃線/愛ある伊予灘線(向井原-伊予大洲間)[S]"] =
|
stationList["予讃線/愛ある伊予灘線(向井原-伊予大洲間)[S]"] =
|
||||||
addStationPosition(
|
addStationPosition(
|
||||||
concatBetweenStations(
|
concatBetweenStations(
|
||||||
@@ -160,15 +211,11 @@ export const getStationList = async () => {
|
|||||||
鳴門線,
|
鳴門線,
|
||||||
stationList["日英対応表"]
|
stationList["日英対応表"]
|
||||||
);
|
);
|
||||||
const tokushimaCurrent = addStationPosition(
|
stationList["徳島線(徳島-阿波池田間)[B]"] = addStationPosition(
|
||||||
concatBetweenStations(stationList["徳島線(徳島-阿波池田間)[B]"]),
|
concatBetweenStations(stationList["徳島線(徳島-阿波池田間)[B]"]),
|
||||||
徳島線,
|
徳島線,
|
||||||
stationList["日英対応表"]
|
stationList["日英対応表"]
|
||||||
);
|
);
|
||||||
stationList["徳島線(徳島-阿波池田間)[B]"] = [
|
|
||||||
tokushimaCurrent[tokushimaCurrent.length - 1],
|
|
||||||
...tokushimaCurrent,
|
|
||||||
];
|
|
||||||
stationList["徳島線(徳島-阿波池田間)[B]"].pop();
|
stationList["徳島線(徳島-阿波池田間)[B]"].pop();
|
||||||
stationList["瀬戸大橋線(児島-宇多津間)[M]"] = [
|
stationList["瀬戸大橋線(児島-宇多津間)[M]"] = [
|
||||||
{
|
{
|
||||||
|
@@ -1,46 +0,0 @@
|
|||||||
import yosan from "../assets/originData/yosan";
|
|
||||||
import uwajima from "../assets/originData/uwajima";
|
|
||||||
import uwajima2 from "../assets/originData/uwajima2";
|
|
||||||
import dosan from "../assets/originData/dosan";
|
|
||||||
import dosan2 from "../assets/originData/dosan2";
|
|
||||||
import koutoku from "../assets/originData/koutoku";
|
|
||||||
import tokushima from "../assets/originData/tokushima";
|
|
||||||
import naruto from "../assets/originData/naruto";
|
|
||||||
import seto from "../assets/originData/seto";
|
|
||||||
export const getStationList2 = async () => {
|
|
||||||
return {
|
|
||||||
yosan,
|
|
||||||
uwajima,
|
|
||||||
uwajima2,
|
|
||||||
dosan,
|
|
||||||
dosan2,
|
|
||||||
koutoku,
|
|
||||||
tokushima,
|
|
||||||
naruto,
|
|
||||||
seto,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const stationIDPair = {
|
|
||||||
yosan: "Y",
|
|
||||||
uwajima: "U",
|
|
||||||
uwajima2: "S",
|
|
||||||
dosan: "D",
|
|
||||||
dosan2: "K",
|
|
||||||
koutoku: "T",
|
|
||||||
tokushima: "B",
|
|
||||||
naruto: "N",
|
|
||||||
seto: "M",
|
|
||||||
};
|
|
||||||
|
|
||||||
export const stationNamePair = {
|
|
||||||
"予讃線(高松 - 松山)": "yosan",
|
|
||||||
"予讃線・内子線(松山 - 内子 - 宇和島)": "uwajima",
|
|
||||||
"予讃線・伊予灘線(向井原 - 伊予大洲)": "uwajima2",
|
|
||||||
"土讃線(多度津 - 高知)": "dosan",
|
|
||||||
"土讃線(高知 - 窪川)": "dosan2",
|
|
||||||
"高徳線(高松 - 徳島)": "koutoku",
|
|
||||||
"徳島線(徳島 - 阿波池田)": "tokushima",
|
|
||||||
"鳴門線(池谷 - 鳴門)": "naruto",
|
|
||||||
"瀬戸大橋線(児島 - 宇多津)": "seto",
|
|
||||||
};
|
|
@@ -5,7 +5,7 @@ type nameString =
|
|||||||
| "SPCL"
|
| "SPCL"
|
||||||
| "Normal"
|
| "Normal"
|
||||||
| string;
|
| string;
|
||||||
type colorString = "aqua" | "red" | "#297bff" | "white";
|
type colorString = "aqua" | "red" | "#297bff" | "white" | "pink";
|
||||||
type trainTypeString =
|
type trainTypeString =
|
||||||
| "快速"
|
| "快速"
|
||||||
| "特急"
|
| "特急"
|
||||||
@@ -28,7 +28,7 @@ export const getTrainType: getTrainType = (nameString) => {
|
|||||||
case "LTDEXP":
|
case "LTDEXP":
|
||||||
return { color: "red", name: "特急", data: "express" };
|
return { color: "red", name: "特急", data: "express" };
|
||||||
case "NightLTDEXP":
|
case "NightLTDEXP":
|
||||||
return { color: "red", name: "寝台特急", data: "express" };
|
return { color: "pink", name: "寝台特急", data: "express" };
|
||||||
case "SPCL":
|
case "SPCL":
|
||||||
case "SPCL_Rapid":
|
case "SPCL_Rapid":
|
||||||
case "SPCL_EXP":
|
case "SPCL_EXP":
|
||||||
|
File diff suppressed because it is too large
Load Diff
692
menu.js
692
menu.js
@@ -1,71 +1,106 @@
|
|||||||
import React, { useRef, useState, useEffect } from "react";
|
import React, { useRef, useState, useEffect, useLayoutEffect } from "react";
|
||||||
import Carousel from "react-native-reanimated-carousel";
|
|
||||||
import {
|
import {
|
||||||
Platform,
|
Platform,
|
||||||
View,
|
View,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
Linking,
|
useWindowDimensions,
|
||||||
|
LayoutAnimation,
|
||||||
Text,
|
Text,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
LayoutAnimation,
|
|
||||||
Dimensions,
|
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import Constants from "expo-constants";
|
import Constants from "expo-constants";
|
||||||
import * as Location from "expo-location";
|
import {
|
||||||
|
configureReanimatedLogger,
|
||||||
|
ReanimatedLogLevel,
|
||||||
|
} from "react-native-reanimated";
|
||||||
import StatusbarDetect from "./StatusbarDetect";
|
import StatusbarDetect from "./StatusbarDetect";
|
||||||
import { widthPercentageToDP as wp } from "react-native-responsive-screen";
|
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
|
||||||
import LottieView from "lottie-react-native";
|
|
||||||
import { parseAllTrainDiagram } from "./lib/parseAllTrainDiagram";
|
|
||||||
import trainList from "./assets/originData/trainList";
|
|
||||||
|
|
||||||
import LED_vision from "./components/発車時刻表/LED_vidion";
|
import LED_vision from "./components/発車時刻表/LED_vidion";
|
||||||
import Sign from "./components/駅名表/Sign";
|
|
||||||
import { TitleBar } from "./components/Menu/TitleBar";
|
import { TitleBar } from "./components/Menu/TitleBar";
|
||||||
import { FixedContentBottom } from "./components/Menu/FixedContentBottom";
|
import { FixedContentBottom } from "./components/Menu/FixedContentBottom";
|
||||||
|
|
||||||
import { UsefulBox } from "./components/atom/UsefulBox";
|
import { lineList, stationIDPair } from "./lib/getStationList";
|
||||||
import { lineList } from "./lib/getStationList";
|
|
||||||
import useInterval from "./lib/useInterval";
|
|
||||||
import { HeaderConfig } from "./lib/HeaderConfig";
|
|
||||||
import { useFavoriteStation } from "./stateBox/useFavoriteStation";
|
import { useFavoriteStation } from "./stateBox/useFavoriteStation";
|
||||||
import { SheetManager } from "react-native-actions-sheet";
|
|
||||||
import { useTrainDelayData } from "./stateBox/useTrainDelayData";
|
|
||||||
import { useNavigation } from "@react-navigation/native";
|
import { useNavigation } from "@react-navigation/native";
|
||||||
import { useStationList } from "./stateBox/useStationList";
|
import { useStationList } from "./stateBox/useStationList";
|
||||||
import { StationNumber } from "./components/Menu/StationPagination";
|
import { TopMenuButton } from "@/components/Menu/TopMenuButton";
|
||||||
import lineColorList from "./assets/originData/lineColorList";
|
import { JRSTraInfoBox } from "@/components/Menu/JRSTraInfoBox";
|
||||||
|
import MapView, { Marker } from "react-native-maps";
|
||||||
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||||
|
import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs";
|
||||||
|
import { CarouselBox } from "./components/Menu/Carousel/CarouselBox";
|
||||||
|
import { CarouselTypeChanger } from "./components/Menu/Carousel/CarouselTypeChanger";
|
||||||
|
import { useUserPosition } from "./stateBox/useUserPosition";
|
||||||
import { AS } from "./storageControl";
|
import { AS } from "./storageControl";
|
||||||
import { SimpleDot } from "./components/Menu/SimpleDot";
|
import { lineList_LineWebID } from "./lib/getStationList";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
export default function Menu({ getCurrentTrain }) {
|
import { SearchUnitBox } from "./components/Menu/RailScope/SearchUnitBox";
|
||||||
const { navigate } = useNavigation();
|
configureReanimatedLogger({
|
||||||
|
level: ReanimatedLogLevel.error, // Set the log level to error
|
||||||
|
strict: true, // Reanimated runs in strict mode by default
|
||||||
|
});
|
||||||
|
export default function Menu(props) {
|
||||||
|
const { scrollRef, mapHeight, MapFullHeight, mapMode, setMapMode } = props;
|
||||||
|
const { navigate, addListener, isFocused } = useNavigation();
|
||||||
const { favoriteStation } = useFavoriteStation();
|
const { favoriteStation } = useFavoriteStation();
|
||||||
const { originalStationList } = useStationList();
|
const { originalStationList } = useStationList();
|
||||||
|
const { height, width } = useWindowDimensions();
|
||||||
//位置情報
|
const { bottom, left, right, top } = useSafeAreaInsets();
|
||||||
const [locationStatus, setLocationStatus] = useState(null);
|
const tabBarHeight = useBottomTabBarHeight();
|
||||||
|
const [stationListMode, setStationListMode] = useState(
|
||||||
|
/*<"position"|"favorite">*/ "position"
|
||||||
|
);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Platform.OS == "web") return;
|
AS.getItem("stationListMode")
|
||||||
Location.requestForegroundPermissionsAsync().then((data) => {
|
.then((res) => setStationListMode(res))
|
||||||
setLocationStatus(
|
.catch((e) => {
|
||||||
Platform.OS == "ios"
|
// AS.setItem("stationListMode", "position");
|
||||||
? data.status == "granted"
|
});
|
||||||
: data.android.accuracy == "fine"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}, []);
|
}, []);
|
||||||
|
const mapsRef = useRef(null);
|
||||||
const getCurrentPosition = () => {
|
const returnToTop = (bool = true) => {
|
||||||
if (!locationStatus) return () => {};
|
scrollRef?.current.scrollTo({
|
||||||
Location.getCurrentPositionAsync({}).then((location) =>
|
y: mapHeight > 80 ? mapHeight - 80 : 0,
|
||||||
makeCurrentStation(location)
|
animated: bool,
|
||||||
);
|
});
|
||||||
};
|
};
|
||||||
|
const goToMap = () => {
|
||||||
|
scrollRef?.current.scrollTo({
|
||||||
|
y: 0,
|
||||||
|
animated: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
returnToTop(false);
|
||||||
|
}, 10);
|
||||||
|
}, [mapHeight]);
|
||||||
|
const [scrollStartPosition, setScrollStartPosition] = useState(0);
|
||||||
|
const onScrollBeginDrag = (e) => {
|
||||||
|
LayoutAnimation.configureNext({
|
||||||
|
duration: 300,
|
||||||
|
create: {
|
||||||
|
type: LayoutAnimation.Types.easeInEaseOut,
|
||||||
|
property: LayoutAnimation.Properties.opacity,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
type: LayoutAnimation.Types.easeInEaseOut,
|
||||||
|
property: LayoutAnimation.Properties.opacity,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
setScrollStartPosition(e.nativeEvent.contentOffset.y);
|
||||||
|
setMapMode(false);
|
||||||
|
};
|
||||||
|
//現在地基準の駅名標リストアップ機能
|
||||||
|
const { position, locationStatus } = useUserPosition();
|
||||||
|
useEffect(() => {
|
||||||
|
if (!position) return () => {};
|
||||||
|
makeCurrentStation(position);
|
||||||
|
}, [position, stationListMode]);
|
||||||
const makeCurrentStation = (location) => {
|
const makeCurrentStation = (location) => {
|
||||||
if (!originalStationList) return () => {};
|
if (!originalStationList) return () => {};
|
||||||
const findStationEachLine = (selectLine) => {
|
const findStationEachLine = (selectLine) => {
|
||||||
const searchArea = 0.002;
|
const searchArea = 0.055; //検索範囲
|
||||||
const _calcDistance = (from, to) => {
|
const _calcDistance = (from, to) => {
|
||||||
let lat = Math.abs(from.lat - to.lat);
|
let lat = Math.abs(from.lat - to.lat);
|
||||||
let lng = Math.abs(from.lng - to.lng);
|
let lng = Math.abs(from.lng - to.lng);
|
||||||
@@ -78,98 +113,135 @@ export default function Menu({ getCurrentTrain }) {
|
|||||||
lng: location.coords.longitude,
|
lng: location.coords.longitude,
|
||||||
}) < searchArea
|
}) < searchArea
|
||||||
);
|
);
|
||||||
|
//NearStationを距離の近い順にソート
|
||||||
|
NearStation.sort((a, b) => {
|
||||||
|
return (
|
||||||
|
_calcDistance(a, {
|
||||||
|
lat: location.coords.latitude,
|
||||||
|
lng: location.coords.longitude,
|
||||||
|
}) -
|
||||||
|
_calcDistance(b, {
|
||||||
|
lat: location.coords.latitude,
|
||||||
|
lng: location.coords.longitude,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
return NearStation;
|
return NearStation;
|
||||||
};
|
};
|
||||||
|
|
||||||
let returnDataBase = lineList
|
let _stList = lineList
|
||||||
.map((d) => findStationEachLine(originalStationList[d]))
|
.map((d) => findStationEachLine(originalStationList[d]))
|
||||||
.filter((d) => d.length > 0)
|
.filter((d) => d.length > 0)
|
||||||
.reduce((pre, current) => {
|
.reduce((pre, current) => {
|
||||||
pre.push(...current);
|
pre.push(...current);
|
||||||
return pre;
|
return pre;
|
||||||
}, []);
|
}, []);
|
||||||
if (returnDataBase.length) {
|
if (_stList.length == 0) setNearPositionStation([]);
|
||||||
let currentStation = currentStation == undefined ? [] : currentStation;
|
else {
|
||||||
if (currentStation.toString() != returnDataBase.toString()) {
|
let returnData = [];
|
||||||
setCurrentStation(returnDataBase);
|
_stList.forEach((d, index, array) => {
|
||||||
}
|
const stationName = d.Station_JP;
|
||||||
} else {
|
if (returnData.findIndex((d) => d[0].Station_JP == stationName) != -1)
|
||||||
setCurrentStation(undefined);
|
return;
|
||||||
|
returnData.push(array.filter((d2) => d2.Station_JP == stationName));
|
||||||
|
});
|
||||||
|
//returnDataを距離の近い順にソート
|
||||||
|
returnData.sort((a, b) => {
|
||||||
|
const _calcDistance = (from, to) => {
|
||||||
|
let lat = Math.abs(from.lat - to.lat);
|
||||||
|
let lng = Math.abs(from.lng - to.lng);
|
||||||
|
return Math.sqrt(lat * lat + lng * lng);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
_calcDistance(a[0], {
|
||||||
|
lat: location.coords.latitude,
|
||||||
|
lng: location.coords.longitude,
|
||||||
|
}) -
|
||||||
|
_calcDistance(b[0], {
|
||||||
|
lat: location.coords.latitude,
|
||||||
|
lng: location.coords.longitude,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
setNearPositionStation(returnData);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(getCurrentPosition, [locationStatus]);
|
const [nearPositionStation, setNearPositionStation] = useState([]); //第三要素
|
||||||
useInterval(getCurrentPosition, 5000);
|
|
||||||
|
|
||||||
const [currentStation, setCurrentStation] = useState(undefined); //第三要素
|
const [listIndex, setListIndex] = useState(0);
|
||||||
|
|
||||||
const carouselRef = useRef();
|
const [listUpStation, setListUpStation] = useState([]);
|
||||||
const [selectedCurrentStation, setSelectedCurrentStation] = useState(0);
|
const [isSearchMode, setisSearchMode] = useState(false);
|
||||||
|
useLayoutEffect(() => {
|
||||||
const [allStationData, setAllStationData] = useState([]);
|
if (!!isSearchMode) {
|
||||||
|
const returnData = [];
|
||||||
|
Object.keys(lineList_LineWebID).forEach((d, indexBase) => {
|
||||||
|
originalStationList[d].forEach((D, index) => {
|
||||||
|
if (
|
||||||
|
isSearchMode &&
|
||||||
|
isSearchMode != stationIDPair[lineList_LineWebID[d]]
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
const latlng = [D.lat, D.lng];
|
||||||
|
if (latlng.length == 0) return null;
|
||||||
|
if (D.StationNumber == undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
returnData.push([D]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if (JSON.stringify(returnData) == JSON.stringify(listUpStation)) return;
|
||||||
|
setListUpStation(returnData);
|
||||||
|
} else if (stationListMode == "position") {
|
||||||
|
const returnData = nearPositionStation.filter((d) => d != undefined);
|
||||||
|
if (JSON.stringify(returnData) == JSON.stringify(listUpStation)) return;
|
||||||
|
setListUpStation(returnData);
|
||||||
|
} else {
|
||||||
|
const returnData = favoriteStation.filter((d) => d != undefined);
|
||||||
|
if (JSON.stringify(returnData) == JSON.stringify(listUpStation)) return;
|
||||||
|
setListUpStation(returnData);
|
||||||
|
}
|
||||||
|
}, [nearPositionStation, favoriteStation, stationListMode, isSearchMode]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setAllStationData(
|
if (listUpStation.length == 0) {
|
||||||
[currentStation, ...favoriteStation].filter((d) => d != undefined)
|
setListIndex(0);
|
||||||
);
|
|
||||||
}, [currentStation, favoriteStation]);
|
|
||||||
useEffect(() => {
|
|
||||||
if (allStationData.length == 0) {
|
|
||||||
setSelectedCurrentStation(0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (allStationData[selectedCurrentStation] == undefined) {
|
if (listUpStation.length == 1) {
|
||||||
const count = selectedCurrentStation - 1;
|
setListIndex(0);
|
||||||
setSelectedCurrentStation(count);
|
return;
|
||||||
}
|
}
|
||||||
}, [selectedCurrentStation, currentStation, allStationData]);
|
if (listUpStation[listIndex] == undefined) {
|
||||||
|
const count = listIndex - 1;
|
||||||
|
setMapMode(false);
|
||||||
|
setListIndex(count);
|
||||||
|
}
|
||||||
|
}, [listIndex, listUpStation, isSearchMode]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!carouselRef.current) return;
|
if (originalStationList == undefined) return;
|
||||||
carouselRef?.current.scrollTo({
|
if (listUpStation.length == 0) return;
|
||||||
count: selectedCurrentStation - carouselRef.current.getCurrentIndex(),
|
if (listUpStation[listIndex] == undefined) return;
|
||||||
animated: true,
|
const { lat, lng } = listUpStation[listIndex][0];
|
||||||
});
|
const mapRegion = {
|
||||||
}, [selectedCurrentStation]);
|
latitude: lat,
|
||||||
|
longitude: lng,
|
||||||
//全列車ダイヤリストを作成するuseEffect
|
latitudeDelta: 0.05,
|
||||||
const [trainDiagram, setTrainDiagram] = useState(null); // 全列車のダイヤを列番ベースで整理
|
longitudeDelta: 0.05,
|
||||||
useEffect(() => {
|
|
||||||
//全列車リストを生成する副作用[無条件初回実行]
|
|
||||||
setTrainDiagram(trainList);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const oPSign = () => {
|
|
||||||
const payload = {
|
|
||||||
currentStation:
|
|
||||||
originalStationList &&
|
|
||||||
allStationData.length != 0 &&
|
|
||||||
allStationData[selectedCurrentStation],
|
|
||||||
navigate: navigate,
|
|
||||||
goTo: "menu",
|
|
||||||
useShow: () => SheetManager.show("StationDetailView", { payload }),
|
|
||||||
onExit: () => SheetManager.hide("StationDetailView"),
|
|
||||||
};
|
};
|
||||||
SheetManager.show("StationDetailView", { payload });
|
if (mapMode) {
|
||||||
};
|
mapsRef?.current.fitToCoordinates(
|
||||||
|
listUpStation.map((d) => ({
|
||||||
|
latitude: parseFloat(d[0].lat),
|
||||||
|
longitude: parseFloat(d[0].lng),
|
||||||
|
})),
|
||||||
|
{ edgePadding: { top: 80, bottom: 120, left: 50, right: 50 } } // Add margin values here
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
mapsRef.current.animateToRegion(mapRegion, 1000);
|
||||||
|
}
|
||||||
|
}, [listIndex, listUpStation]);
|
||||||
|
|
||||||
const [dotButton, setDotButton] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
AS.getItem("CarouselSettings/activeDotSettings").then((data) => {
|
|
||||||
setDotButton(data === "true");
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
const oLPSign = () => {
|
|
||||||
LayoutAnimation.configureNext({
|
|
||||||
duration: 600,
|
|
||||||
update: { type: "spring", springDamping: 0.5 },
|
|
||||||
});
|
|
||||||
AS.setItem(
|
|
||||||
"CarouselSettings/activeDotSettings",
|
|
||||||
!dotButton ? "true" : "false"
|
|
||||||
);
|
|
||||||
setDotButton(!dotButton);
|
|
||||||
};
|
|
||||||
const width = Dimensions.get("window").width;
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
@@ -179,247 +251,175 @@ export default function Menu({ getCurrentTrain }) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<StatusbarDetect />
|
<StatusbarDetect />
|
||||||
<TitleBar />
|
{!mapMode ? (
|
||||||
<ScrollView>
|
<TitleBar />
|
||||||
<TopMenuButton />
|
) : (
|
||||||
{originalStationList.length != 0 && allStationData.length != 0 && (
|
<></>
|
||||||
<View style={{ flex: 1, paddingTop: 10 }}>
|
// <Text
|
||||||
<Carousel
|
// style={{
|
||||||
ref={carouselRef}
|
// fontSize: 30,
|
||||||
data={originalStationList && allStationData}
|
// color: "#0099CC",
|
||||||
height={(wp("80%") / 20) * 9 + 10}
|
// fontWeight: "bold",
|
||||||
pagingEnabled={true}
|
// position: "absolute",
|
||||||
snapEnabled={true}
|
// top: 0,
|
||||||
loop={false}
|
// zIndex: 1000,
|
||||||
width={width}
|
// fontStyle: "italic",
|
||||||
style={{ width: width, alignContent: "center" }}
|
// }}
|
||||||
mode="parallax"
|
// >
|
||||||
modeConfig={{
|
// JRShikoku RailScope
|
||||||
parallaxScrollingScale: 1,
|
// </Text>
|
||||||
parallaxScrollingOffset: 100,
|
)}
|
||||||
parallaxAdjacentItemScale: 0.8,
|
<ScrollView
|
||||||
|
ref={scrollRef}
|
||||||
|
snapToStart={false}
|
||||||
|
snapToEnd={false}
|
||||||
|
decelerationRate={"normal"}
|
||||||
|
snapToOffsets={[mapHeight - 80]}
|
||||||
|
contentContainerStyle={{
|
||||||
|
position: "relative",
|
||||||
|
}}
|
||||||
|
onScrollBeginDrag={onScrollBeginDrag}
|
||||||
|
onScrollEndDrag={(e) => {
|
||||||
|
if (e.nativeEvent.contentOffset.y < mapHeight - 80) {
|
||||||
|
if (scrollStartPosition > e.nativeEvent.contentOffset.y) {
|
||||||
|
goToMap();
|
||||||
|
} else {
|
||||||
|
returnToTop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MapView
|
||||||
|
ref={mapsRef}
|
||||||
|
style={{ width: "100%", height: mapMode ? MapFullHeight : mapHeight }}
|
||||||
|
showsUserLocation={true}
|
||||||
|
loadingEnabled={true}
|
||||||
|
showsMyLocationButton={false}
|
||||||
|
moveOnMarkerPress={false}
|
||||||
|
showsCompass={false}
|
||||||
|
//provider={PROVIDER_GOOGLE}
|
||||||
|
initialRegion={{
|
||||||
|
latitude: 33.774519,
|
||||||
|
longitude: 133.533306,
|
||||||
|
latitudeDelta: 1.8, //小さくなるほどズーム
|
||||||
|
longitudeDelta: 1.8,
|
||||||
|
}}
|
||||||
|
onTouchStart={() => {
|
||||||
|
LayoutAnimation.configureNext({
|
||||||
|
duration: 300,
|
||||||
|
create: {
|
||||||
|
type: LayoutAnimation.Types.easeInEaseOut,
|
||||||
|
property: LayoutAnimation.Properties.opacity,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
type: LayoutAnimation.Types.easeInEaseOut,
|
||||||
|
property: LayoutAnimation.Properties.opacity,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
setMapMode(true);
|
||||||
|
goToMap();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{listUpStation.map(([{ lat, lng, StationNumber }], index) => (
|
||||||
|
<Marker
|
||||||
|
key={index + StationNumber}
|
||||||
|
coordinate={{
|
||||||
|
latitude: parseFloat(lat),
|
||||||
|
longitude: parseFloat(lng),
|
||||||
}}
|
}}
|
||||||
onSnapToItem={setSelectedCurrentStation}
|
image={require("@/assets/reccha-small.png")}
|
||||||
renderItem={({ item, index }) => {
|
onPress={() => {
|
||||||
return (
|
setMapMode(false);
|
||||||
<View
|
setListIndex(index);
|
||||||
style={{
|
if (mapsRef.current) {
|
||||||
backgroundColor: "#0000",
|
mapsRef.current.animateToRegion(
|
||||||
width: width,
|
{
|
||||||
flexDirection: "row",
|
latitude: parseFloat(lat),
|
||||||
marginLeft: 0,
|
longitude: parseFloat(lng),
|
||||||
marginRight: 0,
|
latitudeDelta: 0.05,
|
||||||
}}
|
longitudeDelta: 0.05,
|
||||||
key={item[0].StationNumber}
|
},
|
||||||
>
|
1000
|
||||||
<View style={{ flex: 1 }} />
|
);
|
||||||
<Sign
|
}
|
||||||
currentStation={item}
|
LayoutAnimation.configureNext({
|
||||||
isCurrentStation={item == currentStation}
|
duration: 300,
|
||||||
oP={oPSign}
|
create: {
|
||||||
oLP={oLPSign}
|
type: LayoutAnimation.Types.easeInEaseOut,
|
||||||
/>
|
property: LayoutAnimation.Properties.opacity,
|
||||||
<View style={{ flex: 1 }} />
|
},
|
||||||
</View>
|
update: {
|
||||||
);
|
type: LayoutAnimation.Types.easeInEaseOut,
|
||||||
|
property: LayoutAnimation.Properties.opacity,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
returnToTop();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<View
|
))}
|
||||||
style={{
|
</MapView>
|
||||||
flexDirection: "row",
|
{!mapMode && (
|
||||||
justifyContent: "center",
|
<CarouselTypeChanger
|
||||||
alignContent: "center",
|
{...{
|
||||||
alignItems: "center",
|
locationStatus,
|
||||||
}}
|
position,
|
||||||
>
|
mapsRef,
|
||||||
{originalStationList &&
|
scrollRef,
|
||||||
allStationData.map((d, index) => {
|
stationListMode,
|
||||||
const active = index == selectedCurrentStation;
|
setStationListMode,
|
||||||
const numberIndex = d[0].StationNumber;
|
setSelectedCurrentStation: setListIndex,
|
||||||
if (dotButton) {
|
mapMode,
|
||||||
return (
|
setMapMode,
|
||||||
<StationNumber
|
isSearchMode,
|
||||||
onPress={() => setSelectedCurrentStation(index)}
|
setisSearchMode,
|
||||||
currentStation={d}
|
}}
|
||||||
active={active}
|
/>
|
||||||
index={numberIndex}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<SimpleDot
|
|
||||||
onPress={() => setSelectedCurrentStation(index)}
|
|
||||||
active={active}
|
|
||||||
index={numberIndex}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
)}
|
)}
|
||||||
{allStationData.length != 0 &&
|
|
||||||
originalStationList.length != 0 &&
|
{originalStationList.length != 0 && (
|
||||||
allStationData[selectedCurrentStation] && (
|
<>
|
||||||
<LED_vision
|
<CarouselBox
|
||||||
station={
|
{...{
|
||||||
originalStationList && allStationData[selectedCurrentStation]
|
originalStationList,
|
||||||
}
|
listUpStation,
|
||||||
trainDiagram={trainDiagram}
|
nearPositionStation,
|
||||||
getCurrentTrain={getCurrentTrain}
|
setListIndex,
|
||||||
navigate={navigate}
|
listIndex,
|
||||||
openStationACFromEachTrainInfo={() => {}}
|
navigate,
|
||||||
|
stationListMode,
|
||||||
|
isSearchMode
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
{listUpStation[listIndex] && (
|
||||||
|
<LED_vision
|
||||||
|
station={listUpStation[listIndex]}
|
||||||
|
navigate={navigate}
|
||||||
|
openStationACFromEachTrainInfo={() => {}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<TopMenuButton />
|
||||||
<JRSTraInfoBox />
|
<JRSTraInfoBox />
|
||||||
<FixedContentBottom navigate={navigate} />
|
<FixedContentBottom navigate={navigate} />
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
{mapMode && (
|
||||||
|
<CarouselTypeChanger
|
||||||
|
{...{
|
||||||
|
locationStatus,
|
||||||
|
position,
|
||||||
|
mapsRef,
|
||||||
|
stationListMode,
|
||||||
|
setStationListMode,
|
||||||
|
setSelectedCurrentStation: setListIndex,
|
||||||
|
mapMode,
|
||||||
|
setMapMode,
|
||||||
|
isSearchMode,
|
||||||
|
setisSearchMode,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const TopMenuButton = () => {
|
|
||||||
const buttonList = [
|
|
||||||
{
|
|
||||||
backgroundColor: "#F89038",
|
|
||||||
icon: "train-car",
|
|
||||||
onPress: () =>
|
|
||||||
Linking.openURL("https://www.jr-shikoku.co.jp/01_trainbus/sp/"),
|
|
||||||
title: "駅・鉄道情報",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
backgroundColor: "#EA4752",
|
|
||||||
icon: "google-spreadsheet",
|
|
||||||
onPress: () =>
|
|
||||||
Linking.openURL(
|
|
||||||
"https://www.jr-shikoku.co.jp/01_trainbus/jikoku/sp/#mainprice-box"
|
|
||||||
),
|
|
||||||
title: "運賃表",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
backgroundColor: "#91C31F",
|
|
||||||
icon: "clipboard-list-outline",
|
|
||||||
onPress: () => Linking.openURL("https://www.jr-shikoku.co.jp/e5489/"),
|
|
||||||
title: "予約",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
return (
|
|
||||||
<View style={{ flexDirection: "row" }}>
|
|
||||||
{buttonList.map((d, index) => (
|
|
||||||
<UsefulBox
|
|
||||||
backgroundColor={d.backgroundColor}
|
|
||||||
icon={d.icon}
|
|
||||||
flex={1}
|
|
||||||
onPressButton={d.onPress}
|
|
||||||
key={index + d.icon}
|
|
||||||
>
|
|
||||||
{d.title}
|
|
||||||
</UsefulBox>
|
|
||||||
))}
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const JRSTraInfoBox = () => {
|
|
||||||
const { getTime, delayData, loadingDelayData, setLoadingDelayData } =
|
|
||||||
useTrainDelayData();
|
|
||||||
const styles = {
|
|
||||||
touch: {
|
|
||||||
backgroundColor: "#0099CC",
|
|
||||||
borderRadius: 5,
|
|
||||||
margin: 10,
|
|
||||||
borderColor: "black",
|
|
||||||
borderWidth: 2,
|
|
||||||
overflow: "hidden",
|
|
||||||
},
|
|
||||||
scroll: {
|
|
||||||
backgroundColor: "#0099CC",
|
|
||||||
borderRadius: 5,
|
|
||||||
maxHeight: 300,
|
|
||||||
},
|
|
||||||
bottom: {
|
|
||||||
position: "absolute",
|
|
||||||
top: 250,
|
|
||||||
alignItems: "center",
|
|
||||||
width: "100%",
|
|
||||||
height: 50,
|
|
||||||
backgroundColor: "#007FCC88",
|
|
||||||
},
|
|
||||||
box: {
|
|
||||||
padding: 10,
|
|
||||||
backgroundColor: "white",
|
|
||||||
borderBottomLeftRadius: 5,
|
|
||||||
borderBottomRightRadius: 5,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={() => SheetManager.show("JRSTraInfo")}
|
|
||||||
style={styles.touch}
|
|
||||||
>
|
|
||||||
<ScrollView scrollEnabled={false} style={styles.scroll}>
|
|
||||||
<View
|
|
||||||
style={{ padding: 10, flexDirection: "row", alignItems: "center" }}
|
|
||||||
>
|
|
||||||
<Text style={{ fontSize: 30, fontWeight: "bold", color: "white" }}>
|
|
||||||
列車遅延速報EX
|
|
||||||
</Text>
|
|
||||||
<View style={{ flex: 1 }} />
|
|
||||||
<Text style={{ fontSize: 30, fontWeight: "bold", color: "white" }}>
|
|
||||||
{getTime
|
|
||||||
? getTime.toLocaleTimeString("ja-JP").split(":")[0] +
|
|
||||||
":" +
|
|
||||||
getTime.toLocaleTimeString("ja-JP").split(":")[1]
|
|
||||||
: NaN}
|
|
||||||
</Text>
|
|
||||||
<Ionicons
|
|
||||||
name="reload"
|
|
||||||
color="white"
|
|
||||||
size={30}
|
|
||||||
style={{ margin: 5 }}
|
|
||||||
onPress={() => {
|
|
||||||
setLoadingDelayData(true);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
<View style={styles.box}>
|
|
||||||
{loadingDelayData ? (
|
|
||||||
<View style={{ alignItems: "center" }}>
|
|
||||||
<LottieView
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
style={{ width: 150, height: 150, backgroundColor: "#fff" }}
|
|
||||||
source={require("./assets/51690-loading-diamonds.json")}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
) : delayData ? (
|
|
||||||
delayData.map((d, index, array) => {
|
|
||||||
let data = d.split(" ");
|
|
||||||
return (
|
|
||||||
<View
|
|
||||||
style={{ flexDirection: "row" }}
|
|
||||||
key={data[1] + "key" + index}
|
|
||||||
>
|
|
||||||
<Text style={{ flex: 15, fontSize: 18 }}>
|
|
||||||
{data[0].replace("\n", "")}
|
|
||||||
</Text>
|
|
||||||
<Text style={{ flex: 5, fontSize: 18 }}>{data[1]}</Text>
|
|
||||||
<Text style={{ flex: 6, fontSize: 18 }}>{data[3]}</Text>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
) : (
|
|
||||||
<Text>現在、5分以上の遅れはありません。</Text>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
</ScrollView>
|
|
||||||
<View style={styles.bottom}>
|
|
||||||
<View style={{ flex: 1 }} />
|
|
||||||
<Text style={{ color: "white", fontWeight: "bold", fontSize: 20 }}>
|
|
||||||
詳細を見る
|
|
||||||
</Text>
|
|
||||||
<View style={{ flex: 1 }} />
|
|
||||||
</View>
|
|
||||||
</TouchableOpacity>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
@@ -1,7 +1,10 @@
|
|||||||
|
import trainList from "@/assets/originData/trainList";
|
||||||
|
import { AS } from "@/storageControl";
|
||||||
import React, { createContext, useContext, useEffect, useState } from "react";
|
import React, { createContext, useContext, useEffect, useState } from "react";
|
||||||
const initialState = {
|
const initialState = {
|
||||||
allTrainDiagram: undefined,
|
allTrainDiagram: undefined,
|
||||||
setAllTrainDiagram: () => {},
|
setAllTrainDiagram: () => {},
|
||||||
|
allCustonTrainData: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const AllTrainDiagramContext = createContext(initialState);
|
const AllTrainDiagramContext = createContext(initialState);
|
||||||
@@ -9,24 +12,15 @@ const AllTrainDiagramContext = createContext(initialState);
|
|||||||
export const useAllTrainDiagram = () => useContext(AllTrainDiagramContext);
|
export const useAllTrainDiagram = () => useContext(AllTrainDiagramContext);
|
||||||
|
|
||||||
export const AllTrainDiagramProvider = ({ children }) => {
|
export const AllTrainDiagramProvider = ({ children }) => {
|
||||||
const [allTrainDiagram, setAllTrainDiagram] = useState();
|
const [allTrainDiagram, setAllTrainDiagram] = useState(trainList);
|
||||||
|
const [allCustonTrainData, setAllCustonTrainData] = useState([]); // カスタム列車データ
|
||||||
const [keyList, setKeyList] = useState(); // 第二要素
|
const [keyList, setKeyList] = useState(); // 第二要素
|
||||||
useEffect(
|
useEffect(
|
||||||
() => allTrainDiagram && setKeyList(Object.keys(allTrainDiagram)),
|
() => allTrainDiagram && setKeyList(Object.keys(allTrainDiagram)),
|
||||||
[allTrainDiagram]
|
[allTrainDiagram]
|
||||||
);
|
);
|
||||||
const customData = {
|
|
||||||
"9395D":"臨時列車,提,https://www.jr-shikoku.co.jp/03_news/pdf/20250314_20250413_tomorrow_together_worldtour.pdf#高松,発,22:10#昭和町,発,22:13#栗林公園北口,発,22:16#栗林,発,22:19#木太町,発,22:23#屋島,発,22:36#古高松南,発,22:39#八栗口,発,22:43#讃岐牟礼,発,22:45#志度,発,22:49#オレンジタウン,発,22:53#造田,発,22:57#神前,発,23:00#讃岐津田,発,23:06#鶴羽,発,23:10#丹生,発,23:15#三本松,着,23:18#",
|
|
||||||
"9174M":"臨時列車,提,https://www.jr-shikoku.co.jp/03_news/pdf/20250314_20250413_tomorrow_together_worldtour.pdf#高松,発,22:00#坂出,発,22:16#児島,発,22:39#茶屋町,発,22:48#早島,発,22:55#妹尾,発,22:59#岡山,着,23:06#",
|
|
||||||
"9662D":"宇和れんげまつり臨時列車,提,https://www.jr-shikoku.co.jp/03_news/pdf/20250124_20250629_rinji_spring.pdf#宇和島,発,10:00#北宇和島,発,10:03#高光,発,10:07#伊予吉田,発,10:21#立間,発,10:50#下宇和,発,10:36#卯之町,発,10:39#上宇和,発,10:42#伊予石城,発,10:46#双岩,発,10:53#八幡浜,着,10:58#",
|
|
||||||
"9664D":"宇和れんげまつり臨時列車,提,https://www.jr-shikoku.co.jp/03_news/pdf/20250124_20250629_rinji_spring.pdf#卯之町,発,11:18#上宇和,発,11:21#伊予石城,発,11:25#双岩,発,11:34#八幡浜,着,11:39#",
|
|
||||||
"9663D":"宇和れんげまつり臨時列車,提,https://www.jr-shikoku.co.jp/03_news/pdf/20250124_20250629_rinji_spring.pdf#八幡浜,発,10:07#双岩,発,10:16#伊予石城,発,10:23#上宇和,発,10:27#卯之町,着,10:30#",
|
|
||||||
"9665D":"宇和れんげまつり臨時列車,提,https://www.jr-shikoku.co.jp/03_news/pdf/20250124_20250629_rinji_spring.pdf#八幡浜,発,13:38#双岩,発,13:45#伊予石城,発,13:52#上宇和,発,13:56#卯之町,発,14:07#下宇和,発,14:10#立間,発,14:18#伊予吉田,発,14:25#高光,発,14:31#北宇和島,発,14:35#宇和島,着,14:37#",
|
|
||||||
};
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch(
|
fetch("https://n8n.haruk.in/webhook/JR-shikoku-diagram-migrate-original")
|
||||||
"https://n8n.haruk.in/webhook/CrowdTh%E2%82%AC71m3Ra7!ngLead%E2%82%ACr$"
|
|
||||||
)
|
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then((res) => res.data)
|
.then((res) => res.data)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
@@ -38,34 +32,37 @@ export const AllTrainDiagramProvider = ({ children }) => {
|
|||||||
return data;
|
return data;
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
Object.assign(res, customData);
|
|
||||||
setAllTrainDiagram(res);
|
setAllTrainDiagram(res);
|
||||||
|
AS.setItem("allTrainDiagram", JSON.stringify(res));
|
||||||
})
|
})
|
||||||
.catch((d) => {
|
.catch((d) => {
|
||||||
alert("allTrainDiagram取得エラー/再取得します");
|
AS.getItem("allTrainDiagram")
|
||||||
alert(d);
|
.then((d) => setAllTrainDiagram(JSON.parse(d)))
|
||||||
fetch(
|
.catch(() => {
|
||||||
"https://script.google.com/macros/s/AKfycbx_s7RB-xTy-iAslFJg7LfplLV09-hjDXEjdi9kCP_JT45wq17Af_IPOKIOqIfaNDg/exec"
|
alert("初回の路線情報の取得に失敗しました。");
|
||||||
)
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((res) => {
|
|
||||||
const data = {};
|
|
||||||
res.forEach((d) => {
|
|
||||||
const keys = Object.keys(d);
|
|
||||||
data[keys] = d[keys];
|
|
||||||
});
|
|
||||||
return data;
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
Object.assign(res, customData);
|
|
||||||
setAllTrainDiagram(res);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
useEffect(() => {
|
||||||
|
// カスタム列車データの取得
|
||||||
|
fetch("https://n8n.haruk.in/webhook/jr-shikoku-position-custom-datalist")
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((res) => {
|
||||||
|
setAllCustonTrainData(res[0].data);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
alert("カスタム列車データの取得に失敗しました。");
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AllTrainDiagramContext.Provider
|
<AllTrainDiagramContext.Provider
|
||||||
value={{ allTrainDiagram, setAllTrainDiagram,keyList }}
|
value={{
|
||||||
|
allTrainDiagram,
|
||||||
|
setAllTrainDiagram,
|
||||||
|
allCustonTrainData,
|
||||||
|
keyList,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</AllTrainDiagramContext.Provider>
|
</AllTrainDiagramContext.Provider>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import React, { createContext, useContext, useState, useEffect } from "react";
|
import React, { createContext, useContext, useState, useEffect } from "react";
|
||||||
import trainList from "../assets/originData/trainList";
|
|
||||||
import { AS } from "../storageControl";
|
import { AS } from "../storageControl";
|
||||||
|
import { useAllTrainDiagram } from "./useAllTrainDiagram";
|
||||||
const initialState = {
|
const initialState = {
|
||||||
busAndTrainData: [],
|
busAndTrainData: [],
|
||||||
setBusAndTrainData: () => {},
|
setBusAndTrainData: () => {},
|
||||||
@@ -17,6 +17,7 @@ export const useBusAndTrainData = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const BusAndTrainDataProvider = ({ children }) => {
|
export const BusAndTrainDataProvider = ({ children }) => {
|
||||||
|
const { allTrainDiagram } = useAllTrainDiagram();
|
||||||
const [busAndTrainData, setBusAndTrainData] = useState([]);
|
const [busAndTrainData, setBusAndTrainData] = useState([]);
|
||||||
const [trainPairData, setTrainPairData] = useState([]);
|
const [trainPairData, setTrainPairData] = useState([]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -79,7 +80,7 @@ export const BusAndTrainDataProvider = ({ children }) => {
|
|||||||
case "139M":
|
case "139M":
|
||||||
returnArray.push("143M");
|
returnArray.push("143M");
|
||||||
break;
|
break;
|
||||||
// 土讃線琴平界隈
|
// 土讃線琴平界隈
|
||||||
case "1263M":
|
case "1263M":
|
||||||
returnArray.push("4263M");
|
returnArray.push("4263M");
|
||||||
break;
|
break;
|
||||||
@@ -130,7 +131,7 @@ export const BusAndTrainDataProvider = ({ children }) => {
|
|||||||
case "484D":
|
case "484D":
|
||||||
returnArray.push("583D");
|
returnArray.push("583D");
|
||||||
break;
|
break;
|
||||||
// reverse.
|
// reverse.
|
||||||
case "525D":
|
case "525D":
|
||||||
returnArray.push("4430D");
|
returnArray.push("4430D");
|
||||||
break;
|
break;
|
||||||
@@ -173,7 +174,7 @@ export const BusAndTrainDataProvider = ({ children }) => {
|
|||||||
case "583D":
|
case "583D":
|
||||||
returnArray.push("484D");
|
returnArray.push("484D");
|
||||||
break;
|
break;
|
||||||
//上り
|
//上り
|
||||||
case "4520D":
|
case "4520D":
|
||||||
returnArray.push("4314D");
|
returnArray.push("4314D");
|
||||||
break;
|
break;
|
||||||
@@ -215,7 +216,7 @@ export const BusAndTrainDataProvider = ({ children }) => {
|
|||||||
break;
|
break;
|
||||||
case "564D":
|
case "564D":
|
||||||
returnArray.push("475D");
|
returnArray.push("475D");
|
||||||
break;
|
break;
|
||||||
case "568D":
|
case "568D":
|
||||||
returnArray.push("5479D");
|
returnArray.push("5479D");
|
||||||
break;
|
break;
|
||||||
@@ -225,7 +226,7 @@ export const BusAndTrainDataProvider = ({ children }) => {
|
|||||||
case "576D":
|
case "576D":
|
||||||
returnArray.push("4368D");
|
returnArray.push("4368D");
|
||||||
break;
|
break;
|
||||||
// reverse.
|
// reverse.
|
||||||
case "4314D":
|
case "4314D":
|
||||||
returnArray.push("4520D");
|
returnArray.push("4520D");
|
||||||
break;
|
break;
|
||||||
@@ -278,12 +279,12 @@ export const BusAndTrainDataProvider = ({ children }) => {
|
|||||||
returnArray.push("576D");
|
returnArray.push("576D");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(new RegExp(/^4[1-9]\d\d[DM]$/).test(trainNum)){
|
if (new RegExp(/^4[1-9]\d\d[DM]$/).test(trainNum)) {
|
||||||
if (trainList["5" + trainNum.substring(1)])
|
if (allTrainDiagram["5" + trainNum.substring(1)])
|
||||||
returnArray.push("5" + trainNum.substring(1));
|
returnArray.push("5" + trainNum.substring(1));
|
||||||
}
|
}
|
||||||
if(new RegExp(/^5[1-7]\d\d[DM]$/).test(trainNum)){
|
if (new RegExp(/^5[1-7]\d\d[DM]$/).test(trainNum)) {
|
||||||
if (trainList["4" + trainNum.substring(1)])
|
if (allTrainDiagram["4" + trainNum.substring(1)])
|
||||||
returnArray.push("4" + trainNum.substring(1));
|
returnArray.push("4" + trainNum.substring(1));
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
@@ -291,22 +292,24 @@ export const BusAndTrainDataProvider = ({ children }) => {
|
|||||||
new RegExp(/^4[1-9]\d\d[DM]$/).test(trainNum) ||
|
new RegExp(/^4[1-9]\d\d[DM]$/).test(trainNum) ||
|
||||||
new RegExp(/^5[1-7]\d\d[DM]$/).test(trainNum)
|
new RegExp(/^5[1-7]\d\d[DM]$/).test(trainNum)
|
||||||
) {
|
) {
|
||||||
if (trainList[trainNum.substring(1)]) {
|
if (allTrainDiagram[trainNum.substring(1)]) {
|
||||||
returnArray.push(trainNum.substring(1));
|
returnArray.push(trainNum.substring(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (new RegExp(/^[1-9]\d\d[DM]$/).test(trainNum)) {
|
if (new RegExp(/^[1-9]\d\d[DM]$/).test(trainNum)) {
|
||||||
// 列番がxxDの場合は4xxDと5xxDの列番を検索
|
// 列番がxxDの場合は4xxDと5xxDの列番を検索
|
||||||
if (trainList["4" + trainNum]) returnArray.push("4" + trainNum);
|
if (allTrainDiagram["4" + trainNum]) returnArray.push("4" + trainNum);
|
||||||
if (trainList["5" + trainNum]) returnArray.push("5" + trainNum);
|
if (allTrainDiagram["5" + trainNum]) returnArray.push("5" + trainNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!returnArray.length) return [];
|
if (!returnArray.length) return [];
|
||||||
const TDArray = returnArray.filter(d => trainList.hasOwnProperty(d)).map((d) => {
|
const TDArray = returnArray
|
||||||
const TD = trainList[d];
|
.filter((d) => allTrainDiagram.hasOwnProperty(d))
|
||||||
if (!TD) return;
|
.map((d) => {
|
||||||
return { id: d, TrainData: TD.split("#").filter((d) => d != "") };
|
const TD = allTrainDiagram[d];
|
||||||
});
|
if (!TD) return;
|
||||||
|
return { id: d, TrainData: TD.split("#").filter((d) => d != "") };
|
||||||
|
});
|
||||||
return TDArray;
|
return TDArray;
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
|
@@ -15,6 +15,7 @@ const initialState = {
|
|||||||
currentTrainLoading: "loading",
|
currentTrainLoading: "loading",
|
||||||
setCurrentTrainLoading: () => {},
|
setCurrentTrainLoading: () => {},
|
||||||
getCurrentTrain: () => {},
|
getCurrentTrain: () => {},
|
||||||
|
inject: (i) => {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const CurrentTrainContext = createContext(initialState);
|
const CurrentTrainContext = createContext(initialState);
|
||||||
|
@@ -29,10 +29,10 @@ type Props = {
|
|||||||
};
|
};
|
||||||
export const FavoriteStationProvider:FC<Props> = ({ children }) => {
|
export const FavoriteStationProvider:FC<Props> = ({ children }) => {
|
||||||
const [favoriteStation, setFavoriteStation] = useState([]);
|
const [favoriteStation, setFavoriteStation] = useState([]);
|
||||||
const { getStationData } = useStationList();
|
const { getStationDataFromName } = useStationList();
|
||||||
const lodAddMigration = () => {
|
const lodAddMigration = () => {
|
||||||
const migration = favoriteStation.map((d) => {
|
const migration = favoriteStation.map((d) => {
|
||||||
return getStationData(d[0].Station_JP);
|
return getStationDataFromName(d[0].Station_JP);
|
||||||
});
|
});
|
||||||
setFavoriteStation(migration);
|
setFavoriteStation(migration);
|
||||||
};
|
};
|
||||||
|
@@ -5,20 +5,27 @@ import React, {
|
|||||||
useEffect,
|
useEffect,
|
||||||
FC,
|
FC,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { getStationList } from "../lib/getStationList";
|
import {
|
||||||
import { lineList } from "../lib/getStationList";
|
lineList,
|
||||||
|
getStationList,
|
||||||
|
lineList_LineWebID,
|
||||||
|
} 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;
|
getStationDataFromName: (id: string) => any[];
|
||||||
|
getStationDataFromId: (id: string) => any[];
|
||||||
stationList: any[];
|
stationList: any[];
|
||||||
|
getInjectJavascriptAddress: (StationNumber: string) => string;
|
||||||
};
|
};
|
||||||
const initialState = {
|
const initialState = {
|
||||||
originalStationList: [[]],
|
originalStationList: [[]],
|
||||||
setOriginalStationList: () => {},
|
setOriginalStationList: () => {},
|
||||||
getStationData: () => {},
|
getStationDataFromName: () => [],
|
||||||
|
getStationDataFromId: () => [],
|
||||||
stationList: [],
|
stationList: [],
|
||||||
|
getInjectJavascriptAddress: (StationNumber: string) => "",
|
||||||
};
|
};
|
||||||
|
|
||||||
const StationListContext = createContext<initialStateType>(initialState);
|
const StationListContext = createContext<initialStateType>(initialState);
|
||||||
@@ -34,7 +41,21 @@ export const StationListProvider: FC<Props> = ({ children }) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getStationList().then(setOriginalStationList);
|
getStationList().then(setOriginalStationList);
|
||||||
}, []);
|
}, []);
|
||||||
const getStationData: (name: string) => void = (name) => {
|
const getStationDataFromId: (id: string) => any[] = (id) => {
|
||||||
|
let returnArray = [];
|
||||||
|
Object.keys(originalStationList).forEach((key) => {
|
||||||
|
originalStationList[key].forEach((station) => {
|
||||||
|
if (station.StationNumber === id) {
|
||||||
|
returnArray = [
|
||||||
|
...returnArray,
|
||||||
|
...getStationDataFromName(station.Station_JP),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return returnArray;
|
||||||
|
};
|
||||||
|
const getStationDataFromName: (name: string) => any[] = (name) => {
|
||||||
const returnArray = [];
|
const returnArray = [];
|
||||||
Object.keys(originalStationList).forEach((key) => {
|
Object.keys(originalStationList).forEach((key) => {
|
||||||
originalStationList[key].forEach((station) => {
|
originalStationList[key].forEach((station) => {
|
||||||
@@ -46,22 +67,55 @@ export const StationListProvider: FC<Props> = ({ children }) => {
|
|||||||
return returnArray;
|
return returnArray;
|
||||||
};
|
};
|
||||||
const [stationList, setStationList] = useState<any[][]>([[]]);
|
const [stationList, setStationList] = useState<any[][]>([[]]);
|
||||||
useEffect(()=>{
|
useEffect(() => {
|
||||||
if(originalStationList.length === 0) return;
|
if (originalStationList.length === 0) return;
|
||||||
const stationList =
|
const stationList = lineList.map((d) =>
|
||||||
originalStationList &&
|
originalStationList[d].map((a) => ({
|
||||||
lineList.map((d) =>
|
StationNumber: a.StationNumber,
|
||||||
originalStationList[d].map((a) => ({
|
StationName: a.Station_JP,
|
||||||
StationNumber: a.StationNumber,
|
}))
|
||||||
StationName: a.Station_JP,
|
);
|
||||||
}))
|
setStationList(stationList);
|
||||||
);
|
}, [originalStationList]);
|
||||||
setStationList(stationList)
|
|
||||||
},[originalStationList])
|
const getInjectJavascriptAddress = (StationNumber: string) => {
|
||||||
|
const bootStationList = [];
|
||||||
|
Object.keys(originalStationList).forEach((d) => {
|
||||||
|
let findNearStations = false;
|
||||||
|
originalStationList[d].forEach((x) => {
|
||||||
|
let lineName = lineList_LineWebID[d];
|
||||||
|
if (findNearStations) {
|
||||||
|
if (x.MyStation) {
|
||||||
|
bootStationList.push({ line: lineName, station: x });
|
||||||
|
findNearStations = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (x.StationNumber == StationNumber) {
|
||||||
|
if (!x.MyStation) findNearStations = true;
|
||||||
|
else bootStationList.push({ line: lineName, station: x });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (StationNumber == "M12") {
|
||||||
|
bootStationList.push({
|
||||||
|
line: "seto",
|
||||||
|
station: { Station_JP: "児島", MyStation: "0" },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return `MoveDisplayStation('${bootStationList[0].line}_${bootStationList[0].station.MyStation}_${bootStationList[0].station.Station_JP}');document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StationListContext.Provider
|
<StationListContext.Provider
|
||||||
value={{ originalStationList, setOriginalStationList, getStationData, stationList }}
|
value={{
|
||||||
|
originalStationList,
|
||||||
|
setOriginalStationList,
|
||||||
|
getStationDataFromName,
|
||||||
|
getStationDataFromId,
|
||||||
|
stationList,
|
||||||
|
getInjectJavascriptAddress,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</StationListContext.Provider>
|
</StationListContext.Provider>
|
||||||
|
68
stateBox/useTopMenu.tsx
Normal file
68
stateBox/useTopMenu.tsx
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import React, {
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
FC,
|
||||||
|
} from "react";
|
||||||
|
import { lineList, getStationList } from "../lib/getStationList";
|
||||||
|
|
||||||
|
type initialStateType = {
|
||||||
|
originalStationList: any[][];
|
||||||
|
setOriginalStationList: React.Dispatch<React.SetStateAction<any[]>>;
|
||||||
|
getStationData: (id: string) => void;
|
||||||
|
stationList: any[];
|
||||||
|
};
|
||||||
|
const initialState = {
|
||||||
|
originalStationList: [[]],
|
||||||
|
setOriginalStationList: () => {},
|
||||||
|
getStationData: () => {},
|
||||||
|
stationList: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const TopMenuContext = createContext<initialStateType>(initialState);
|
||||||
|
type Props = {
|
||||||
|
children: React.ReactNode;
|
||||||
|
};
|
||||||
|
export const useTopMenu = () => {
|
||||||
|
return useContext(TopMenuContext);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TopMenuProvider: FC<Props> = ({ children }) => {
|
||||||
|
const [originalStationList, setOriginalStationList] = useState<any[]>([]);
|
||||||
|
useEffect(() => {
|
||||||
|
getStationList().then(setOriginalStationList);
|
||||||
|
}, []);
|
||||||
|
const getStationData: (name: string) => void = (name) => {
|
||||||
|
const returnArray = [];
|
||||||
|
Object.keys(originalStationList).forEach((key) => {
|
||||||
|
originalStationList[key].forEach((station) => {
|
||||||
|
if (station.Station_JP === name) {
|
||||||
|
if (!!station.jslodApi) returnArray.push(station);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
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 (
|
||||||
|
<TopMenuContext.Provider
|
||||||
|
value={{ originalStationList, setOriginalStationList, getStationData, stationList }}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</TopMenuContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
@@ -3,7 +3,7 @@ const initialState = {
|
|||||||
getTime: new Date(),
|
getTime: new Date(),
|
||||||
setGetTime: () => {},
|
setGetTime: () => {},
|
||||||
loadingDelayData: true,
|
loadingDelayData: true,
|
||||||
setLoadingDelayData: () => {},
|
setLoadingDelayData: (loading) => {},
|
||||||
delayData: undefined,
|
delayData: undefined,
|
||||||
setDelayData: () => {},
|
setDelayData: () => {},
|
||||||
};
|
};
|
||||||
@@ -20,7 +20,7 @@ export const TrainDelayDataProvider = ({ children }) => {
|
|||||||
const [loadingDelayData, setLoadingDelayData] = useState(true);
|
const [loadingDelayData, setLoadingDelayData] = useState(true);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch(
|
fetch(
|
||||||
"https://script.google.com/macros/s/AKfycbyKxch7z7l8e07LXulRHqxjVoIiB13kcgvoToLE-rqlxLmLSKdlmqz0FI1F2EuA7Zfg/exec"
|
"https://script.google.com/macros/s/AKfycbw-0RDLAu8EQAEWA860tk4KVW6VOr3iIU900AcWEfqIP16gtNUG1XO_A3oBfAGiNeCf/exec"
|
||||||
)
|
)
|
||||||
.then((response) => response.text())
|
.then((response) => response.text())
|
||||||
.then((data) => setDelayData(data !== "" ? data.split("^") : null))
|
.then((data) => setDelayData(data !== "" ? data.split("^") : null))
|
||||||
|
@@ -2,22 +2,24 @@ import React, { createContext, useContext, useState, useEffect } from "react";
|
|||||||
|
|
||||||
import { ASCore } from "../storageControl";
|
import { ASCore } from "../storageControl";
|
||||||
|
|
||||||
import { getStationList2 } from "../lib/getStationList2";
|
import { getStationList2 } from "../lib/getStationList";
|
||||||
import { injectJavascriptData } from "../lib/webViewInjectjavascript";
|
import { injectJavascriptData } from "../lib/webViewInjectjavascript";
|
||||||
|
|
||||||
|
import { useNotification } from "../stateBox/useNotifications";
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
selectedLine: undefined,
|
selectedLine: undefined,
|
||||||
setSelectedLine: () => {},
|
setSelectedLine: () => {},
|
||||||
mapsStationData: undefined,
|
mapsStationData: undefined,
|
||||||
setMapsStationData: () => {},
|
setMapsStationData: () => {},
|
||||||
injectJavaScript: "",
|
|
||||||
setInjectJavaScript: () => {},
|
|
||||||
iconSetting: undefined,
|
iconSetting: undefined,
|
||||||
setIconSetting: () => {},
|
setIconSetting: () => {},
|
||||||
mapSwitch: undefined,
|
mapSwitch: undefined,
|
||||||
setMapSwitch: () => {},
|
setMapSwitch: () => {},
|
||||||
stationMenu: undefined,
|
stationMenu: undefined,
|
||||||
setStationMenu: () => {},
|
setStationMenu: () => {},
|
||||||
|
uiSetting: undefined,
|
||||||
|
setUiSetting: () => {},
|
||||||
LoadError: false,
|
LoadError: false,
|
||||||
setLoadError: () => {},
|
setLoadError: () => {},
|
||||||
trainInfo: {
|
trainInfo: {
|
||||||
@@ -28,6 +30,8 @@ const initialState = {
|
|||||||
setTrainInfo: () => {},
|
setTrainInfo: () => {},
|
||||||
trainMenu: "true",
|
trainMenu: "true",
|
||||||
setTrainMenu: () => {},
|
setTrainMenu: () => {},
|
||||||
|
updatePermission : false,
|
||||||
|
setUpdatePermission : () => {},
|
||||||
injectJavascript: "",
|
injectJavascript: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -38,10 +42,9 @@ export const useTrainMenu = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const TrainMenuProvider = ({ children }) => {
|
export const TrainMenuProvider = ({ children }) => {
|
||||||
|
const { expoPushToken } = useNotification();
|
||||||
const [selectedLine, setSelectedLine] = useState(undefined);
|
const [selectedLine, setSelectedLine] = useState(undefined);
|
||||||
const [mapsStationData, setMapsStationData] = useState(undefined);
|
const [mapsStationData, setMapsStationData] = useState(undefined);
|
||||||
const [injectJavaScript, setInjectJavaScript] = useState();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getStationList2().then(setMapsStationData);
|
getStationList2().then(setMapsStationData);
|
||||||
}, []);
|
}, []);
|
||||||
@@ -52,6 +55,19 @@ export const TrainMenuProvider = ({ children }) => {
|
|||||||
const [stationMenu, setStationMenu] = useState(undefined);
|
const [stationMenu, setStationMenu] = useState(undefined);
|
||||||
const [LoadError, setLoadError] = useState(false);
|
const [LoadError, setLoadError] = useState(false);
|
||||||
|
|
||||||
|
//更新権限所有確認
|
||||||
|
const [updatePermission, setUpdatePermission] = useState(false);
|
||||||
|
useEffect(()=>{
|
||||||
|
fetch("https://n8n.haruk.in/webhook/data-edit-permission?token=" + expoPushToken).then((res)=>res.json())
|
||||||
|
.then((res)=>{
|
||||||
|
if(res.data == true){
|
||||||
|
setUpdatePermission(true);
|
||||||
|
}else{
|
||||||
|
setUpdatePermission(false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, [expoPushToken])
|
||||||
|
|
||||||
//列車情報表示関連
|
//列車情報表示関連
|
||||||
const [trainInfo, setTrainInfo] = useState({
|
const [trainInfo, setTrainInfo] = useState({
|
||||||
trainNum: undefined,
|
trainNum: undefined,
|
||||||
@@ -62,12 +78,16 @@ export const TrainMenuProvider = ({ children }) => {
|
|||||||
//駅情報画面用
|
//駅情報画面用
|
||||||
const [trainMenu, setTrainMenu] = useState("true");
|
const [trainMenu, setTrainMenu] = useState("true");
|
||||||
|
|
||||||
|
//GUIデザインベース
|
||||||
|
const [uiSetting, setUiSetting] = useState("tokyo");
|
||||||
|
|
||||||
//地図表示テキスト
|
//地図表示テキスト
|
||||||
const injectJavascript = injectJavascriptData(
|
const injectJavascript = injectJavascriptData(
|
||||||
mapSwitch,
|
mapSwitch,
|
||||||
iconSetting,
|
iconSetting,
|
||||||
stationMenu,
|
stationMenu,
|
||||||
trainMenu
|
trainMenu,
|
||||||
|
uiSetting
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -79,6 +99,8 @@ export const TrainMenuProvider = ({ children }) => {
|
|||||||
ASCore({ k: "stationSwitch", s: setStationMenu, d: "true", u: true });
|
ASCore({ k: "stationSwitch", s: setStationMenu, d: "true", u: true });
|
||||||
//列車メニュースイッチ
|
//列車メニュースイッチ
|
||||||
ASCore({ k: "trainSwitch", s: setTrainMenu, d: "true", u: true });
|
ASCore({ k: "trainSwitch", s: setTrainMenu, d: "true", u: true });
|
||||||
|
//GUIデザインベーススイッチ
|
||||||
|
ASCore({ k: "uiSetting", s: setUiSetting, d: "tokyo", u: true });
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -88,20 +110,22 @@ export const TrainMenuProvider = ({ children }) => {
|
|||||||
setSelectedLine,
|
setSelectedLine,
|
||||||
mapsStationData,
|
mapsStationData,
|
||||||
setMapsStationData,
|
setMapsStationData,
|
||||||
injectJavaScript,
|
|
||||||
setInjectJavaScript,
|
|
||||||
iconSetting,
|
iconSetting,
|
||||||
setIconSetting,
|
setIconSetting,
|
||||||
mapSwitch,
|
mapSwitch,
|
||||||
setMapSwitch,
|
setMapSwitch,
|
||||||
stationMenu,
|
stationMenu,
|
||||||
setStationMenu,
|
setStationMenu,
|
||||||
|
uiSetting,
|
||||||
|
setUiSetting,
|
||||||
LoadError,
|
LoadError,
|
||||||
setLoadError,
|
setLoadError,
|
||||||
trainInfo,
|
trainInfo,
|
||||||
setTrainInfo,
|
setTrainInfo,
|
||||||
trainMenu,
|
trainMenu,
|
||||||
setTrainMenu,
|
setTrainMenu,
|
||||||
|
updatePermission,
|
||||||
|
setUpdatePermission,
|
||||||
injectJavascript,
|
injectJavascript,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
76
stateBox/useUserPosition.tsx
Normal file
76
stateBox/useUserPosition.tsx
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import React, {
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
FC,
|
||||||
|
} from "react";
|
||||||
|
import {
|
||||||
|
LocationObject,
|
||||||
|
requestForegroundPermissionsAsync,
|
||||||
|
getCurrentPositionAsync,
|
||||||
|
} from "expo-location";
|
||||||
|
import { Platform } from "react-native";
|
||||||
|
import useInterval from "@/lib/useInterval";
|
||||||
|
|
||||||
|
type initialStateType = {
|
||||||
|
position: LocationObject | undefined;
|
||||||
|
getCurrentPosition: () => void;
|
||||||
|
locationStatus: boolean | null;
|
||||||
|
getLocationPermission: () => void;
|
||||||
|
};
|
||||||
|
const initialState = {
|
||||||
|
position: undefined,
|
||||||
|
getCurrentPosition: () => {},
|
||||||
|
locationStatus: null,
|
||||||
|
getLocationPermission: () => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
const UserPositionContext = createContext<initialStateType>(initialState);
|
||||||
|
type Props = {
|
||||||
|
children: React.ReactNode;
|
||||||
|
};
|
||||||
|
export const useUserPosition = () => {
|
||||||
|
return useContext(UserPositionContext);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const UserPositionProvider: FC<Props> = ({ children }) => {
|
||||||
|
//位置情報
|
||||||
|
const [locationStatus, setLocationStatus] = useState<boolean | null>(null);
|
||||||
|
const [position, setPosition] = useState<LocationObject | undefined>(
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
|
||||||
|
const getLocationPermission = async () => {
|
||||||
|
return requestForegroundPermissionsAsync().then((data) => {
|
||||||
|
setLocationStatus(
|
||||||
|
Platform.OS == "ios"
|
||||||
|
? data.status == "granted"
|
||||||
|
: data.android.accuracy == "fine"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const getCurrentPosition = () => {
|
||||||
|
if (!locationStatus) return () => {};
|
||||||
|
getCurrentPositionAsync({}).then((location) => setPosition(location));
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
if (Platform.OS == "web") return;
|
||||||
|
getLocationPermission();
|
||||||
|
}, []);
|
||||||
|
useEffect(getCurrentPosition, [locationStatus]);
|
||||||
|
useInterval(getCurrentPosition, 5000);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<UserPositionContext.Provider
|
||||||
|
value={{
|
||||||
|
position,
|
||||||
|
getCurrentPosition,
|
||||||
|
locationStatus,
|
||||||
|
getLocationPermission,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</UserPositionContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
Reference in New Issue
Block a user