Merge commit '01378c2f7e3004ecd500d6611117af4d343335c2' into feature/position-tracking-system
This commit is contained in:
14
MenuPage.js
14
MenuPage.js
@@ -19,6 +19,7 @@ import { useNavigation } from "@react-navigation/native";
|
|||||||
import { news } from "./config/newsUpdate";
|
import { news } from "./config/newsUpdate";
|
||||||
import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs";
|
import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs";
|
||||||
import GeneralWebView from "./GeneralWebView";
|
import GeneralWebView from "./GeneralWebView";
|
||||||
|
import { StationDiagramView } from "@/components/StationDiagram/StationDiagramView";
|
||||||
const Stack = createStackNavigator();
|
const Stack = createStackNavigator();
|
||||||
|
|
||||||
export function MenuPage() {
|
export function MenuPage() {
|
||||||
@@ -86,7 +87,7 @@ export function MenuPage() {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
console.warn('お気に入り駅の読み込みに失敗しました:', error);
|
console.warn("お気に入り駅の読み込みに失敗しました:", error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -112,6 +113,11 @@ export function MenuPage() {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="stDiagram"
|
||||||
|
options={{ ...optionData, gestureEnabled: false }}
|
||||||
|
component={StationDiagramView}
|
||||||
|
/>
|
||||||
<Stack.Screen name="news" options={optionData} component={News} />
|
<Stack.Screen name="news" options={optionData} component={News} />
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
name="setting"
|
name="setting"
|
||||||
@@ -133,7 +139,11 @@ 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.Screen
|
||||||
|
name="generalWebView"
|
||||||
|
options={optionData}
|
||||||
|
component={GeneralWebView}
|
||||||
|
/>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
15
Top.js
15
Top.js
@@ -14,6 +14,7 @@ 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";
|
import GeneralWebView from "./GeneralWebView";
|
||||||
|
import { StationDiagramView } from "@/components/StationDiagram/StationDiagramView";
|
||||||
const Stack = createStackNavigator();
|
const Stack = createStackNavigator();
|
||||||
export const Top = () => {
|
export const Top = () => {
|
||||||
const { webview } = useCurrentTrain();
|
const { webview } = useCurrentTrain();
|
||||||
@@ -37,7 +38,8 @@ export const Top = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!isFocused()) navigate("positions", { screen: "Apps" });
|
if (!isFocused()) navigate("positions", { screen: "Apps" });
|
||||||
else if (mapSwitch == "true") navigate("positions", { screen: "trainMenu" });
|
else if (mapSwitch == "true")
|
||||||
|
navigate("positions", { screen: "trainMenu" });
|
||||||
else webview.current?.injectJavaScript(`AccordionClassEvent()`);
|
else webview.current?.injectJavaScript(`AccordionClassEvent()`);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -64,8 +66,17 @@ export const Top = () => {
|
|||||||
options={{ ...optionData }}
|
options={{ ...optionData }}
|
||||||
component={TrainBase}
|
component={TrainBase}
|
||||||
/>
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="stDiagram"
|
||||||
|
options={{ ...optionData, gestureEnabled: false }}
|
||||||
|
component={StationDiagramView}
|
||||||
|
/>
|
||||||
<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="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"
|
||||||
|
@@ -19,6 +19,8 @@ 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";
|
import { StationTrainPositionButton } from "./StationDeteilView/StationTrainPositionButton";
|
||||||
|
import { StationDiagramButton } from "./StationDeteilView/StationDiagramButton";
|
||||||
|
import { useTrainMenu } from "@/stateBox/useTrainMenu";
|
||||||
|
|
||||||
export const StationDeteilView = (props) => {
|
export const StationDeteilView = (props) => {
|
||||||
if (!props.payload) return <></>;
|
if (!props.payload) return <></>;
|
||||||
@@ -26,6 +28,7 @@ export const StationDeteilView = (props) => {
|
|||||||
const { width } = useWindowDimensions();
|
const { width } = useWindowDimensions();
|
||||||
const { busAndTrainData } = useBusAndTrainData();
|
const { busAndTrainData } = useBusAndTrainData();
|
||||||
const [trainBus, setTrainBus] = useState();
|
const [trainBus, setTrainBus] = useState();
|
||||||
|
const { updatePermission } = useTrainMenu();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!currentStation) return () => {};
|
if (!currentStation) return () => {};
|
||||||
@@ -132,6 +135,11 @@ export const StationDeteilView = (props) => {
|
|||||||
onExit={onExit}
|
onExit={onExit}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{updatePermission &&<StationDiagramButton
|
||||||
|
navigate={navigate}
|
||||||
|
onExit={onExit}
|
||||||
|
currentStation={currentStation}
|
||||||
|
/>}
|
||||||
{!currentStation[0].StationTimeTable || (
|
{!currentStation[0].StationTimeTable || (
|
||||||
<StationTimeTableButton
|
<StationTimeTableButton
|
||||||
info={info}
|
info={info}
|
||||||
|
@@ -0,0 +1,40 @@
|
|||||||
|
import React, { FC } from "react";
|
||||||
|
import { Linking } from "react-native";
|
||||||
|
import { FontAwesome } from "@expo/vector-icons";
|
||||||
|
import { TicketBox } from "@/components/atom/TicketBox";
|
||||||
|
type Props = {
|
||||||
|
navigate: (screen: string, params?: object) => void;
|
||||||
|
onExit: () => void;
|
||||||
|
currentStation: {
|
||||||
|
Station_JP: string;
|
||||||
|
Station_EN: string;
|
||||||
|
StationName?: string;
|
||||||
|
MyStation?: string;
|
||||||
|
StationNumber: string;
|
||||||
|
DispNum?: string;
|
||||||
|
StationTimeTable: string;
|
||||||
|
StationMap?: string;
|
||||||
|
JrHpUrl?: string;
|
||||||
|
lat: number;
|
||||||
|
lng: number;
|
||||||
|
jslodApi: string;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
export const StationDiagramButton: FC<Props> = (props) => {
|
||||||
|
const { navigate, onExit, currentStation } = props;
|
||||||
|
return (
|
||||||
|
<TicketBox
|
||||||
|
backgroundColor={"#8F5902"}
|
||||||
|
icon={<FontAwesome name="table" color="white" size={50} />}
|
||||||
|
flex={1}
|
||||||
|
onPressButton={() => {
|
||||||
|
navigate("stDiagram", {
|
||||||
|
currentStation,
|
||||||
|
});
|
||||||
|
onExit();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
時刻表v2
|
||||||
|
</TicketBox>
|
||||||
|
);
|
||||||
|
};
|
355
components/StationDiagram/ExGridView.tsx
Normal file
355
components/StationDiagram/ExGridView.tsx
Normal file
@@ -0,0 +1,355 @@
|
|||||||
|
import { FC, useRef, useState, useCallback, useEffect } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
ScrollView,
|
||||||
|
useWindowDimensions,
|
||||||
|
Vibration,
|
||||||
|
} from "react-native";
|
||||||
|
import { ExGridViewItem } from "./ExGridViewItem";
|
||||||
|
import Animated, {
|
||||||
|
useAnimatedStyle,
|
||||||
|
useSharedValue,
|
||||||
|
runOnJS,
|
||||||
|
useAnimatedScrollHandler,
|
||||||
|
withTiming,
|
||||||
|
Easing,
|
||||||
|
FadeIn,
|
||||||
|
FadeOut,
|
||||||
|
BounceInUp,
|
||||||
|
FadeInUp,
|
||||||
|
FadeOutUp,
|
||||||
|
} from "react-native-reanimated";
|
||||||
|
import { Gesture, GestureDetector } from "react-native-gesture-handler";
|
||||||
|
import { ExGridViewTimePositionItem } from "./ExGridViewTimePositionItem";
|
||||||
|
import { useCurrentTrain } from "@/stateBox/useCurrentTrain";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
type hoge = {
|
||||||
|
trainNumber: string;
|
||||||
|
array: string;
|
||||||
|
name: string;
|
||||||
|
timeType: string;
|
||||||
|
time: string;
|
||||||
|
}[];
|
||||||
|
export const ExGridView: FC<{
|
||||||
|
data: hoge;
|
||||||
|
}> = ({ data }) => {
|
||||||
|
const groupedData: {
|
||||||
|
[d: number]: {
|
||||||
|
trainNumber: string;
|
||||||
|
array: string;
|
||||||
|
name: string;
|
||||||
|
timeType: string;
|
||||||
|
time: string;
|
||||||
|
isOperating: boolean;
|
||||||
|
}[];
|
||||||
|
} = {
|
||||||
|
"4": [],
|
||||||
|
"5": [],
|
||||||
|
"6": [],
|
||||||
|
"7": [],
|
||||||
|
"8": [],
|
||||||
|
"9": [],
|
||||||
|
"10": [],
|
||||||
|
"11": [],
|
||||||
|
"12": [],
|
||||||
|
"13": [],
|
||||||
|
"14": [],
|
||||||
|
"15": [],
|
||||||
|
"16": [],
|
||||||
|
"17": [],
|
||||||
|
"18": [],
|
||||||
|
"19": [],
|
||||||
|
"20": [],
|
||||||
|
"21": [],
|
||||||
|
"22": [],
|
||||||
|
"23": [],
|
||||||
|
"0": [],
|
||||||
|
"1": [],
|
||||||
|
"2": [],
|
||||||
|
"3": [],
|
||||||
|
};
|
||||||
|
const groupKeys = [
|
||||||
|
"4",
|
||||||
|
"5",
|
||||||
|
"6",
|
||||||
|
"7",
|
||||||
|
"8",
|
||||||
|
"9",
|
||||||
|
"10",
|
||||||
|
"11",
|
||||||
|
"12",
|
||||||
|
"13",
|
||||||
|
"14",
|
||||||
|
"15",
|
||||||
|
"16",
|
||||||
|
"17",
|
||||||
|
"18",
|
||||||
|
"19",
|
||||||
|
"20",
|
||||||
|
"21",
|
||||||
|
"22",
|
||||||
|
"23",
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
];
|
||||||
|
|
||||||
|
const { width } = useWindowDimensions();
|
||||||
|
const { currentTrain } = useCurrentTrain();
|
||||||
|
data.forEach((item) => {
|
||||||
|
let isOperating = false;
|
||||||
|
let [hour, minute] = dayjs()
|
||||||
|
.hour(parseInt(item.time.split(":")[0]))
|
||||||
|
.minute(parseInt(item.time.split(":")[1]))
|
||||||
|
.format("H:m")
|
||||||
|
.split(":");
|
||||||
|
if (currentTrain.findIndex((x) => x.num == item.trainNumber) != -1) {
|
||||||
|
const currentTrainTime = currentTrain.find(
|
||||||
|
(x) => x.num == item.trainNumber
|
||||||
|
)?.delay;
|
||||||
|
if (currentTrainTime != "入線") {
|
||||||
|
[hour, minute] = dayjs()
|
||||||
|
.hour(parseInt(hour))
|
||||||
|
.minute(parseInt(minute))
|
||||||
|
.add(parseInt(currentTrainTime), "minute")
|
||||||
|
.format("H:m")
|
||||||
|
.split(":");
|
||||||
|
}
|
||||||
|
isOperating = true;
|
||||||
|
}
|
||||||
|
groupedData[hour].push({ ...item, time: `${hour}:${minute}`, isOperating });
|
||||||
|
});
|
||||||
|
// ドラッグ位置を保持する共有値
|
||||||
|
const widthX = useSharedValue(width);
|
||||||
|
const savedWidthX = useSharedValue(width);
|
||||||
|
const isChanging = useSharedValue(false);
|
||||||
|
const [scrollEnabled, setScrollEnabled] = useState(true);
|
||||||
|
const scrollRef = useRef<Animated.ScrollView>(null);
|
||||||
|
const scrollRef2 = useRef<Animated.ScrollView>(null);
|
||||||
|
|
||||||
|
// ScrollViewの有効/無効を切り替える関数
|
||||||
|
const toggleScrollEnabled = useCallback((enabled: boolean) => {
|
||||||
|
setScrollEnabled(enabled);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// パンジェスチャー(ドラッグ)のハンドラー
|
||||||
|
const pinchGesture = Gesture.Pinch()
|
||||||
|
.onUpdate((e) => {
|
||||||
|
const calc = savedWidthX.value * e.scale;
|
||||||
|
widthX.value = calc > width ? calc : width;
|
||||||
|
//runOnJS(scrollToRightEnd)();
|
||||||
|
})
|
||||||
|
.onEnd(() => {
|
||||||
|
savedWidthX.value = widthX.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
const gesture = Gesture.Pan()
|
||||||
|
.minPointers(2) // 最低2本指
|
||||||
|
.maxPointers(2) // 最大2本指
|
||||||
|
.onStart(() => {
|
||||||
|
runOnJS(toggleScrollEnabled)(false);
|
||||||
|
})
|
||||||
|
.onEnd(() => {
|
||||||
|
runOnJS(toggleScrollEnabled)(true);
|
||||||
|
savedWidthX.value = widthX.value;
|
||||||
|
});
|
||||||
|
const longPressGesture = Gesture.Pan()
|
||||||
|
.minPointers(1)
|
||||||
|
.maxPointers(1)
|
||||||
|
.activateAfterLongPress(200)
|
||||||
|
.onStart(() => {
|
||||||
|
runOnJS(Vibration.vibrate)(30);
|
||||||
|
isChanging.value = true;
|
||||||
|
})
|
||||||
|
.onUpdate((e) => {
|
||||||
|
const calc = widthX.value + e.velocityY;
|
||||||
|
widthX.value = calc > width ? calc : width;
|
||||||
|
})
|
||||||
|
.onEnd(() => {
|
||||||
|
console.log("Long press ended");
|
||||||
|
isChanging.value = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// ジェスチャーを組み合わせる
|
||||||
|
const composed = Gesture.Simultaneous(
|
||||||
|
longPressGesture,
|
||||||
|
pinchGesture,
|
||||||
|
gesture
|
||||||
|
);
|
||||||
|
|
||||||
|
// アニメーションスタイル
|
||||||
|
const animatedStyle = useAnimatedStyle(() => ({
|
||||||
|
width: widthX.value,
|
||||||
|
backgroundColor: isChanging.value ? "#8adeffff" : "white",
|
||||||
|
}));
|
||||||
|
// 時ヘッダーを横にスクロールしたときの処理
|
||||||
|
const scrollX = useSharedValue(0);
|
||||||
|
const scrollHandler = useAnimatedScrollHandler({
|
||||||
|
onScroll: (event) => {
|
||||||
|
scrollX.value = event.contentOffset.x;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const stickyTextStyle = useAnimatedStyle(() => ({
|
||||||
|
transform: [{ translateX: scrollX.value }],
|
||||||
|
}));
|
||||||
|
const animatedLongPressStyle = useAnimatedStyle(() => ({
|
||||||
|
display: isChanging.value ? "flex" : "none",
|
||||||
|
}));
|
||||||
|
useEffect(() => {
|
||||||
|
const getCurrentTime = dayjs().hour();
|
||||||
|
setTimeout(() => {
|
||||||
|
const keyTime =
|
||||||
|
getCurrentTime - 4 <= 0 ? getCurrentTime + 24 : getCurrentTime;
|
||||||
|
const goTo = keyTime * 60;
|
||||||
|
if (goTo > 400) {
|
||||||
|
scrollRef2.current?.scrollTo({ y: goTo - 300, animated: true });
|
||||||
|
}
|
||||||
|
}, 400);
|
||||||
|
}, [scrollRef2]);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Animated.View
|
||||||
|
style={[
|
||||||
|
{
|
||||||
|
position: "absolute",
|
||||||
|
width,
|
||||||
|
backgroundColor: "#26d1baff",
|
||||||
|
zIndex: 500,
|
||||||
|
top: 0,
|
||||||
|
},
|
||||||
|
animatedLongPressStyle,
|
||||||
|
]}
|
||||||
|
entering={FadeInUp}
|
||||||
|
exiting={FadeOutUp}
|
||||||
|
>
|
||||||
|
<Text style={{ fontSize: 30, textAlign: "center", flex: 1 }}>
|
||||||
|
↑縮小 ・ 拡大↓
|
||||||
|
</Text>
|
||||||
|
</Animated.View>
|
||||||
|
<GestureDetector gesture={composed}>
|
||||||
|
<Animated.ScrollView
|
||||||
|
horizontal
|
||||||
|
nestedScrollEnabled
|
||||||
|
pinchGestureEnabled={false}
|
||||||
|
scrollEnabled={scrollEnabled}
|
||||||
|
onScroll={scrollHandler}
|
||||||
|
onContentSizeChange={(contentWidth) => {
|
||||||
|
// 現在のスクロール位置を取得
|
||||||
|
const currentScrollX = scrollX.value;
|
||||||
|
const containerWidth = width - 50;
|
||||||
|
|
||||||
|
// コンテンツが画面からはみ出している場合のみ右端にスクロール
|
||||||
|
if (currentScrollX + containerWidth > contentWidth) {
|
||||||
|
const newScrollX = Math.max(0, contentWidth - containerWidth);
|
||||||
|
scrollRef.current?.scrollTo({ x: newScrollX, animated: true });
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
ref={scrollRef}
|
||||||
|
contentContainerStyle={{
|
||||||
|
flexDirection: "column",
|
||||||
|
backgroundColor: "white",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Animated.View
|
||||||
|
style={[
|
||||||
|
{
|
||||||
|
width: width,
|
||||||
|
flexDirection: "row",
|
||||||
|
},
|
||||||
|
animatedStyle,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{Array.from({ length: 60 }, (_, i) => i + 1).map((num) => {
|
||||||
|
if (num % 5 === 0) {
|
||||||
|
return (
|
||||||
|
<Text
|
||||||
|
key={num}
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
textAlign: "left",
|
||||||
|
borderRightWidth: 0.5,
|
||||||
|
borderColor: "#ccc",
|
||||||
|
flexWrap: "nowrap",
|
||||||
|
fontSize: 12,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{num - 5}
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
} else return <></>;
|
||||||
|
})}
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
textAlign: "right",
|
||||||
|
borderRightWidth: 0.5,
|
||||||
|
borderColor: "#ccc",
|
||||||
|
flexWrap: "nowrap",
|
||||||
|
fontSize: 12,
|
||||||
|
width: 50,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
(分)
|
||||||
|
</Text>
|
||||||
|
</Animated.View>
|
||||||
|
<Animated.ScrollView
|
||||||
|
style={[{ width: width }, animatedStyle]}
|
||||||
|
pinchGestureEnabled={false}
|
||||||
|
minimumZoomScale={0.5}
|
||||||
|
maximumZoomScale={3.0}
|
||||||
|
scrollEnabled={scrollEnabled}
|
||||||
|
stickyHeaderIndices={
|
||||||
|
groupKeys.at(0) ? groupKeys.map((_, i) => i * 2) : []
|
||||||
|
}
|
||||||
|
ref={scrollRef2}
|
||||||
|
>
|
||||||
|
{groupKeys.map((hour) => [
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
padding: 5,
|
||||||
|
borderBottomWidth: 0.5,
|
||||||
|
borderTopWidth: 0.5,
|
||||||
|
borderBottomColor: "#ccc",
|
||||||
|
backgroundColor: "#f0f0f0",
|
||||||
|
}}
|
||||||
|
key={hour}
|
||||||
|
>
|
||||||
|
<Animated.Text
|
||||||
|
style={[
|
||||||
|
{
|
||||||
|
fontSize: 15,
|
||||||
|
zIndex: 1,
|
||||||
|
marginLeft: 0,
|
||||||
|
},
|
||||||
|
stickyTextStyle,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{hour}時台
|
||||||
|
</Animated.Text>
|
||||||
|
</View>,
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
position: "relative",
|
||||||
|
height: 50,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{groupedData[hour].map((d, i, array) => (
|
||||||
|
<ExGridViewItem
|
||||||
|
key={d.trainNumber + i}
|
||||||
|
d={d}
|
||||||
|
index={i}
|
||||||
|
width={widthX}
|
||||||
|
array={array}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
<ExGridViewTimePositionItem width={widthX} hour={hour} />
|
||||||
|
</View>,
|
||||||
|
])}
|
||||||
|
</Animated.ScrollView>
|
||||||
|
</Animated.ScrollView>
|
||||||
|
</GestureDetector>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
268
components/StationDiagram/ExGridViewItem.tsx
Normal file
268
components/StationDiagram/ExGridViewItem.tsx
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
import { migrateTrainName } from "@/lib/eachTrainInfoCoreLib/migrateTrainName";
|
||||||
|
import { getStringConfig, typeID } from "@/lib/getStringConfig";
|
||||||
|
import { getTrainType } from "@/lib/getTrainType";
|
||||||
|
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||||
|
import { FC, useEffect, useLayoutEffect, useMemo, useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TouchableOpacity,
|
||||||
|
useWindowDimensions,
|
||||||
|
} from "react-native";
|
||||||
|
import { customTrainDataDetector } from "../custom-train-data";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import { lineList } from "@/lib/getStationList";
|
||||||
|
import { useStationList } from "@/stateBox/useStationList";
|
||||||
|
import { SharedValue, useAnimatedStyle } from "react-native-reanimated";
|
||||||
|
import Animated from "react-native-reanimated";
|
||||||
|
import lineColorList from "@/assets/originData/lineColorList";
|
||||||
|
|
||||||
|
export const ExGridViewItem: FC<{
|
||||||
|
d: {
|
||||||
|
trainNumber: string;
|
||||||
|
array: string;
|
||||||
|
name: string;
|
||||||
|
timeType: string;
|
||||||
|
time: string;
|
||||||
|
isOperating: boolean;
|
||||||
|
};
|
||||||
|
index: number;
|
||||||
|
width: SharedValue<number>;
|
||||||
|
array: {
|
||||||
|
train: string;
|
||||||
|
lastStation: string;
|
||||||
|
time: string;
|
||||||
|
isThrough?: boolean;
|
||||||
|
}[];
|
||||||
|
}> = ({ d, index, width, array }) => {
|
||||||
|
const { allCustomTrainData } = useAllTrainDiagram();
|
||||||
|
const { originalStationList, stationList } = useStationList();
|
||||||
|
const { navigate, goBack } = useNavigation();
|
||||||
|
const [trainData, setTrainData] = useState<{
|
||||||
|
ToData: string;
|
||||||
|
TrainNumber: string;
|
||||||
|
id: string;
|
||||||
|
img: string;
|
||||||
|
info?: string;
|
||||||
|
infoUrl: string;
|
||||||
|
infogram: string;
|
||||||
|
isEdit: boolean;
|
||||||
|
isSeason: boolean;
|
||||||
|
trainName: string;
|
||||||
|
trainNumDistance?: number;
|
||||||
|
type: typeID;
|
||||||
|
viaData?: string;
|
||||||
|
uwasa?: string;
|
||||||
|
}>();
|
||||||
|
useEffect(() => {
|
||||||
|
if (allCustomTrainData) {
|
||||||
|
allCustomTrainData.forEach((x) => {
|
||||||
|
if (x.TrainNumber === d.trainNumber) {
|
||||||
|
setTrainData(x);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
const { color, name, data } = getTrainType(trainData?.type, true);
|
||||||
|
// 列車名、種別、フォントの取得
|
||||||
|
const [
|
||||||
|
typeString,
|
||||||
|
trainName,
|
||||||
|
fontAvailable,
|
||||||
|
isOneMan,
|
||||||
|
infogram,
|
||||||
|
isEdit,
|
||||||
|
uwasa,
|
||||||
|
vehicleFormation,
|
||||||
|
trainInfoUrl,
|
||||||
|
] = useMemo(() => {
|
||||||
|
const {
|
||||||
|
type,
|
||||||
|
trainName,
|
||||||
|
trainNumDistance,
|
||||||
|
infogram,
|
||||||
|
isEdit,
|
||||||
|
uwasa,
|
||||||
|
vehicleFormation,
|
||||||
|
trainInfoUrl,
|
||||||
|
} = customTrainDataDetector(d.trainNumber, allCustomTrainData);
|
||||||
|
const [typeString, fontAvailable, isOneMan] = getStringConfig(
|
||||||
|
type,
|
||||||
|
d.trainNumber
|
||||||
|
);
|
||||||
|
const trainData = d.array.split("#").filter((d) => d !== "");
|
||||||
|
switch (true) {
|
||||||
|
case trainData[trainData.length - 1] === undefined:
|
||||||
|
return [
|
||||||
|
typeString,
|
||||||
|
"",
|
||||||
|
fontAvailable,
|
||||||
|
isOneMan,
|
||||||
|
infogram,
|
||||||
|
isEdit,
|
||||||
|
uwasa,
|
||||||
|
vehicleFormation,
|
||||||
|
trainInfoUrl,
|
||||||
|
];
|
||||||
|
default:
|
||||||
|
// 行先がある場合は、行先を取得
|
||||||
|
const trainName = (d.timeType == "着" || d.timeType == "着編") ? trainData[0].split(",")[0] : trainData[trainData.length - 1].split(",")[0]
|
||||||
|
return [
|
||||||
|
typeString,
|
||||||
|
migrateTrainName(trainName),
|
||||||
|
fontAvailable,
|
||||||
|
isOneMan,
|
||||||
|
infogram,
|
||||||
|
isEdit,
|
||||||
|
uwasa,
|
||||||
|
vehicleFormation,
|
||||||
|
trainInfoUrl,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}, [d.array]);
|
||||||
|
const timeArray = d.time.split(":").map((s) => parseInt(s));
|
||||||
|
const formattedTime = dayjs()
|
||||||
|
.set("hour", timeArray[0])
|
||||||
|
.set("minute", timeArray[1])
|
||||||
|
.format("m");
|
||||||
|
let isSameTimeBefore = false;
|
||||||
|
if (index > 0) {
|
||||||
|
const beforeItem = array[index - 1];
|
||||||
|
const beforeTimeArray = beforeItem.time.split(":").map((s) => parseInt(s));
|
||||||
|
const beforeFormattedTime = dayjs()
|
||||||
|
.set("hour", beforeTimeArray[0])
|
||||||
|
.set("minute", beforeTimeArray[1])
|
||||||
|
.format("m");
|
||||||
|
isSameTimeBefore = beforeFormattedTime === formattedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
const openStationACFromEachTrainInfo = async (stationName) => {
|
||||||
|
await SheetManager.hide("EachTrainInfo");
|
||||||
|
const findStationEachLine = (selectLine) => {
|
||||||
|
let NearStation = selectLine.filter((d) => d.Station_JP == stationName);
|
||||||
|
return NearStation;
|
||||||
|
};
|
||||||
|
let returnDataBase = lineList
|
||||||
|
.map((d) => findStationEachLine(originalStationList[d]))
|
||||||
|
.filter((d) => d.length > 0)
|
||||||
|
.reduce((pre, current) => {
|
||||||
|
pre.push(...current);
|
||||||
|
return pre;
|
||||||
|
}, []);
|
||||||
|
if (returnDataBase.length) {
|
||||||
|
const payload = {
|
||||||
|
currentStation: returnDataBase,
|
||||||
|
navigate,
|
||||||
|
//@ts-ignore
|
||||||
|
useShow: () => SheetManager.show("StationDetailView", { payload }),
|
||||||
|
onExit: () => SheetManager.hide("StationDetailView"),
|
||||||
|
}; //@ts-ignore
|
||||||
|
setTimeout(() => SheetManager.show("StationDetailView", { payload }), 50);
|
||||||
|
} else {
|
||||||
|
SheetManager.hide("StationDetailView");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const openTrainInfo = () => {
|
||||||
|
let TrainNumber = "";
|
||||||
|
if (trainData.trainNumDistance != undefined) {
|
||||||
|
const timeInfo =
|
||||||
|
parseInt(trainData.TrainNumber.replace("M", "").replace("D", "")) -
|
||||||
|
trainData.trainNumDistance;
|
||||||
|
TrainNumber = timeInfo + "号";
|
||||||
|
}
|
||||||
|
const payload = {
|
||||||
|
data: {
|
||||||
|
trainNum: trainData.TrainNumber,
|
||||||
|
limited: `${data}:${trainData.trainName}${TrainNumber}`,
|
||||||
|
},
|
||||||
|
navigate,
|
||||||
|
openStationACFromEachTrainInfo,
|
||||||
|
from: d.isOperating ? null :"AllTrainIDList",
|
||||||
|
};
|
||||||
|
SheetManager.show("EachTrainInfo", {
|
||||||
|
//@ts-ignore
|
||||||
|
payload,
|
||||||
|
onClose: (data) => {
|
||||||
|
//alert(data);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const [stationColor, setStationColor] = useState(["gray"]);
|
||||||
|
useEffect(() => {
|
||||||
|
const Stations = stationList
|
||||||
|
.map((a) => a.filter((d) => d.StationName == trainName))
|
||||||
|
.reduce((newArray, e) => newArray.concat(e), []);
|
||||||
|
const StationNumbers =
|
||||||
|
Stations &&
|
||||||
|
Stations.filter((d) => d.StationNumber).map((d) => d.StationNumber);
|
||||||
|
|
||||||
|
if (StationNumbers) {
|
||||||
|
const stationLineColor = StationNumbers.map(
|
||||||
|
(d) => lineColorList[d.charAt(0)]
|
||||||
|
);
|
||||||
|
setStationColor(stationLineColor || ["gray"]);
|
||||||
|
}
|
||||||
|
}, [stationList]);
|
||||||
|
// if(typeString == "回送"){
|
||||||
|
// return<></>;
|
||||||
|
// }
|
||||||
|
const animatedStyle = useAnimatedStyle(() => {
|
||||||
|
const leftPosition =
|
||||||
|
((((width.value - 50) / 100) * parseInt(formattedTime)) / 60) * 100;
|
||||||
|
return {
|
||||||
|
left: leftPosition,
|
||||||
|
};
|
||||||
|
}, [formattedTime]);
|
||||||
|
return (
|
||||||
|
<View style={{ left: 0, height: 50 }}>
|
||||||
|
<Animated.View
|
||||||
|
style={[
|
||||||
|
{
|
||||||
|
flexDirection: "column",
|
||||||
|
//borderTopWidth: 1,
|
||||||
|
//borderBottomWidth: 0.5,
|
||||||
|
borderStyle: "solid",
|
||||||
|
borderColor: "darkgray",
|
||||||
|
opacity: d.timeType.includes("通") ? 0.5 : 1,
|
||||||
|
position: "absolute",
|
||||||
|
height: "100%",
|
||||||
|
width: 28,
|
||||||
|
top: isSameTimeBefore ? 10 : 0,
|
||||||
|
},
|
||||||
|
animatedStyle,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<TouchableOpacity style={{ flex: 1 }} onPress={() => openTrainInfo()}>
|
||||||
|
<View style={{ position: "relative" }}>
|
||||||
|
<Text style={{ fontSize: 20, color: color, opacity: isSameTimeBefore ? 0 : 1, fontWeight:d.isOperating ? "bold" : "thin", fontStyle:d.isOperating? "italic" :"normal" }}>{formattedTime}</Text>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 10,
|
||||||
|
position: "absolute",
|
||||||
|
bottom: 0,
|
||||||
|
right: 0,
|
||||||
|
fontWeight: "bold",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{d.timeType}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View style={{ flex: 1, flexDirection: "column" }}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 8,
|
||||||
|
flex: 1,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: stationColor[0],
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{trainName}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</Animated.View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
44
components/StationDiagram/ExGridViewTimePositionItem.tsx
Normal file
44
components/StationDiagram/ExGridViewTimePositionItem.tsx
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import { FC } from "react";
|
||||||
|
import { View } from "react-native";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { SharedValue, useAnimatedStyle } from "react-native-reanimated";
|
||||||
|
import Animated from "react-native-reanimated";
|
||||||
|
|
||||||
|
export const ExGridViewTimePositionItem: FC<{
|
||||||
|
width: SharedValue<number>;
|
||||||
|
hour: string;
|
||||||
|
}> = ({ width, hour }) => {
|
||||||
|
const date = dayjs();
|
||||||
|
const formattedTime = date.format("m");
|
||||||
|
const formattedHour = date.format("H");
|
||||||
|
|
||||||
|
// if(typeString == "回送"){
|
||||||
|
// return<></>;
|
||||||
|
// }
|
||||||
|
const animatedStyle = useAnimatedStyle(() => {
|
||||||
|
const leftPosition =
|
||||||
|
((((width.value - 50) / 100) * parseInt(formattedTime)) / 60) * 100;
|
||||||
|
return {
|
||||||
|
left: leftPosition,
|
||||||
|
};
|
||||||
|
}, [formattedTime]);
|
||||||
|
if (formattedHour != hour) return <></>;
|
||||||
|
return (
|
||||||
|
<View style={{ left: 0, height: 50, width: 1 }}>
|
||||||
|
<Animated.View
|
||||||
|
style={[
|
||||||
|
{
|
||||||
|
flexDirection: "column",
|
||||||
|
borderLeftWidth: 2,
|
||||||
|
//borderBottomWidth: 0.5,
|
||||||
|
borderStyle: "solid",
|
||||||
|
borderColor: "red",
|
||||||
|
position: "absolute",
|
||||||
|
height: "100%",
|
||||||
|
},
|
||||||
|
animatedStyle,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
43
components/StationDiagram/ListView.tsx
Normal file
43
components/StationDiagram/ListView.tsx
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { FC } from "react";
|
||||||
|
import { ListViewItem } from "@/components/StationDiagram/ListViewItem";
|
||||||
|
import { View, Text, ScrollView } from "react-native";
|
||||||
|
|
||||||
|
export const ListView: FC<{
|
||||||
|
data: {
|
||||||
|
trainNumber: string;
|
||||||
|
array: string;
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
time: string;
|
||||||
|
}[];
|
||||||
|
}> = ({ data }) => {
|
||||||
|
const groupedData = {};
|
||||||
|
const groupKeys = [];
|
||||||
|
data.forEach((item) => {
|
||||||
|
const hour = item.time.split(":")[0];
|
||||||
|
if (!groupedData[hour]) {
|
||||||
|
groupedData[hour] = [];
|
||||||
|
groupKeys.push(hour);
|
||||||
|
}
|
||||||
|
groupedData[hour].push(item);
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<ScrollView
|
||||||
|
style={{ backgroundColor: "white" }}
|
||||||
|
stickyHeaderIndices={
|
||||||
|
groupKeys.at(0) ? groupKeys.map((_, i) => i * 2) : []
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{groupKeys.map((hour) => [
|
||||||
|
<View style={{ backgroundColor: "white", padding: 5, borderBottomWidth: 0.5, borderTopWidth: 0.5, borderBottomColor: "#ccc" }} key={hour}>
|
||||||
|
<Text style={{ fontSize: 15 }}>{hour}時台</Text>
|
||||||
|
</View>,
|
||||||
|
<View>
|
||||||
|
{groupedData[hour].map((d, i) => (
|
||||||
|
<ListViewItem key={d.trainNumber + i} d={d} />
|
||||||
|
))}
|
||||||
|
</View>,
|
||||||
|
])}
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
};
|
244
components/StationDiagram/ListViewItem.tsx
Normal file
244
components/StationDiagram/ListViewItem.tsx
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
import { migrateTrainName } from "@/lib/eachTrainInfoCoreLib/migrateTrainName";
|
||||||
|
import { getStringConfig, typeID } from "@/lib/getStringConfig";
|
||||||
|
import { getTrainType } from "@/lib/getTrainType";
|
||||||
|
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||||
|
import { FC, useEffect, useMemo, useState } from "react";
|
||||||
|
import { View, Text, TouchableOpacity } from "react-native";
|
||||||
|
import { customTrainDataDetector } from "../custom-train-data";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import { lineList } from "@/lib/getStationList";
|
||||||
|
import { useStationList } from "@/stateBox/useStationList";
|
||||||
|
|
||||||
|
export const ListViewItem: FC<{
|
||||||
|
d: {
|
||||||
|
trainNumber: string;
|
||||||
|
array: string;
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
time: string;
|
||||||
|
};
|
||||||
|
}> = ({ d }) => {
|
||||||
|
const { allCustomTrainData } = useAllTrainDiagram();
|
||||||
|
const { navigate, goBack } = useNavigation();
|
||||||
|
const [trainData, setTrainData] = useState<{
|
||||||
|
ToData: string;
|
||||||
|
TrainNumber: string;
|
||||||
|
id: string;
|
||||||
|
img: string;
|
||||||
|
info?: string;
|
||||||
|
infoUrl: string;
|
||||||
|
infogram: string;
|
||||||
|
isEdit: boolean;
|
||||||
|
isSeason: boolean;
|
||||||
|
trainName: string;
|
||||||
|
trainNumDistance?: number;
|
||||||
|
type: typeID;
|
||||||
|
viaData?: string;
|
||||||
|
uwasa?: string;
|
||||||
|
}>();
|
||||||
|
useEffect(() => {
|
||||||
|
if (allCustomTrainData) {
|
||||||
|
allCustomTrainData.forEach((x) => {
|
||||||
|
if (x.TrainNumber === d.trainNumber) {
|
||||||
|
setTrainData(x);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
const { color, name, data } = getTrainType(trainData?.type, true);
|
||||||
|
const { originalStationList } = useStationList();
|
||||||
|
// 列車名、種別、フォントの取得
|
||||||
|
const [
|
||||||
|
typeString,
|
||||||
|
trainName,
|
||||||
|
fontAvailable,
|
||||||
|
isOneMan,
|
||||||
|
infogram,
|
||||||
|
isEdit,
|
||||||
|
uwasa,
|
||||||
|
vehicleFormation,
|
||||||
|
trainInfoUrl,
|
||||||
|
] = useMemo(() => {
|
||||||
|
const {
|
||||||
|
type,
|
||||||
|
trainName,
|
||||||
|
trainNumDistance,
|
||||||
|
infogram,
|
||||||
|
isEdit,
|
||||||
|
uwasa,
|
||||||
|
vehicleFormation,
|
||||||
|
trainInfoUrl,
|
||||||
|
} = customTrainDataDetector(d.trainNumber, allCustomTrainData);
|
||||||
|
const [typeString, fontAvailable, isOneMan] = getStringConfig(
|
||||||
|
type,
|
||||||
|
d.trainNumber
|
||||||
|
);
|
||||||
|
const trainData = d.array.split("#").filter((d) => d !== "");
|
||||||
|
switch (true) {
|
||||||
|
case trainData[trainData.length - 1] === undefined:
|
||||||
|
return [
|
||||||
|
typeString,
|
||||||
|
"",
|
||||||
|
fontAvailable,
|
||||||
|
isOneMan,
|
||||||
|
infogram,
|
||||||
|
isEdit,
|
||||||
|
uwasa,
|
||||||
|
vehicleFormation,
|
||||||
|
trainInfoUrl,
|
||||||
|
];
|
||||||
|
default:
|
||||||
|
// 行先がある場合は、行先を取得
|
||||||
|
return [
|
||||||
|
typeString,
|
||||||
|
migrateTrainName(
|
||||||
|
trainData[trainData.length - 1].split(",")[0] + "行き"
|
||||||
|
),
|
||||||
|
fontAvailable,
|
||||||
|
isOneMan,
|
||||||
|
infogram,
|
||||||
|
isEdit,
|
||||||
|
uwasa,
|
||||||
|
vehicleFormation,
|
||||||
|
trainInfoUrl,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}, [d.array]);
|
||||||
|
const timeArray = d.time.split(":").map((s) => parseInt(s));
|
||||||
|
const formattedTime = dayjs()
|
||||||
|
.set("hour", timeArray[0])
|
||||||
|
.set("minute", timeArray[1])
|
||||||
|
.format("HH:mm");
|
||||||
|
|
||||||
|
const openStationACFromEachTrainInfo = async (stationName) => {
|
||||||
|
await SheetManager.hide("EachTrainInfo");
|
||||||
|
const findStationEachLine = (selectLine) => {
|
||||||
|
let NearStation = selectLine.filter((d) => d.Station_JP == stationName);
|
||||||
|
return NearStation;
|
||||||
|
};
|
||||||
|
let returnDataBase = lineList
|
||||||
|
.map((d) => findStationEachLine(originalStationList[d]))
|
||||||
|
.filter((d) => d.length > 0)
|
||||||
|
.reduce((pre, current) => {
|
||||||
|
pre.push(...current);
|
||||||
|
return pre;
|
||||||
|
}, []);
|
||||||
|
if (returnDataBase.length) {
|
||||||
|
const payload = {
|
||||||
|
currentStation: returnDataBase,
|
||||||
|
navigate,
|
||||||
|
//@ts-ignore
|
||||||
|
useShow: () => SheetManager.show("StationDetailView", { payload }),
|
||||||
|
onExit: () => SheetManager.hide("StationDetailView"),
|
||||||
|
};//@ts-ignore
|
||||||
|
setTimeout(() => SheetManager.show("StationDetailView", { payload }), 50);
|
||||||
|
} else {
|
||||||
|
SheetManager.hide("StationDetailView");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const openTrainInfo = () => {
|
||||||
|
let TrainNumber = "";
|
||||||
|
if (trainData.trainNumDistance != undefined) {
|
||||||
|
const timeInfo =
|
||||||
|
parseInt(trainData.TrainNumber.replace("M", "").replace("D", "")) -
|
||||||
|
trainData.trainNumDistance;
|
||||||
|
TrainNumber = timeInfo + "号";
|
||||||
|
}
|
||||||
|
const payload = {
|
||||||
|
data: {
|
||||||
|
trainNum: trainData.TrainNumber,
|
||||||
|
limited: `${data}:${trainData.trainName}${TrainNumber}`,
|
||||||
|
},
|
||||||
|
navigate,
|
||||||
|
openStationACFromEachTrainInfo,
|
||||||
|
from: "AllTrainIDList",
|
||||||
|
};
|
||||||
|
SheetManager.show("EachTrainInfo", {
|
||||||
|
//@ts-ignore
|
||||||
|
payload,
|
||||||
|
onClose: (data) => {
|
||||||
|
//alert(data);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
marginHorizontal: 10,
|
||||||
|
borderTopWidth: 1,
|
||||||
|
borderBottomWidth: 0.5,
|
||||||
|
borderStyle: "solid",
|
||||||
|
borderColor: "darkgray",
|
||||||
|
padding: 10,
|
||||||
|
opacity: d.type.includes("通") ? 0.5 : 1,
|
||||||
|
}}
|
||||||
|
onPress={() => openTrainInfo()}
|
||||||
|
>
|
||||||
|
<View style={{ position: "relative" }}>
|
||||||
|
<Text style={{ fontSize: 30 }}>{formattedTime}</Text>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 10,
|
||||||
|
position: "absolute",
|
||||||
|
bottom: -3,
|
||||||
|
right: 0,
|
||||||
|
fontWeight: "bold",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{d.type}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View style={{ flex: 1, flexDirection: "column" }}>
|
||||||
|
<View style={{ flexDirection: "row" }}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 15,
|
||||||
|
fontFamily: fontAvailable ? "JR-Nishi" : undefined,
|
||||||
|
fontWeight: !fontAvailable ? "bold" : undefined,
|
||||||
|
paddingTop: fontAvailable ? 2 : 0,
|
||||||
|
paddingLeft: 10,
|
||||||
|
color: color,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{typeString}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: "bold",
|
||||||
|
flex: 1,
|
||||||
|
paddingLeft: 2,
|
||||||
|
color: color,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{trainData?.trainName +
|
||||||
|
(trainData?.trainNumDistance !== null
|
||||||
|
? ` ${parseInt(d.trainNumber) - trainData?.trainNumDistance}号`
|
||||||
|
: "")}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: "bold",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{trainData?.TrainNumber}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 15,
|
||||||
|
flex: 1,
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
fontWeight: "bold",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{trainName}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
};
|
454
components/StationDiagram/StationDiagramView.tsx
Normal file
454
components/StationDiagram/StationDiagramView.tsx
Normal file
@@ -0,0 +1,454 @@
|
|||||||
|
import { FC, useEffect, useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
ScrollView,
|
||||||
|
TextInput,
|
||||||
|
Keyboard,
|
||||||
|
KeyboardAvoidingView,
|
||||||
|
Platform,
|
||||||
|
TouchableOpacity,
|
||||||
|
LayoutAnimation,
|
||||||
|
} from "react-native";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import { BigButton } from "../atom/BigButton";
|
||||||
|
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||||
|
import { ListView } from "@/components/StationDiagram/ListView";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { ExGridView } from "./ExGridView";
|
||||||
|
import { Switch } from "react-native-elements";
|
||||||
|
import { customTrainDataDetector } from "../custom-train-data";
|
||||||
|
import { typeID } from "@/lib/getStringConfig";
|
||||||
|
import { colorString } from "@/lib/getTrainType";
|
||||||
|
|
||||||
|
type props = {
|
||||||
|
route: {
|
||||||
|
params: {
|
||||||
|
currentStation: {
|
||||||
|
Station_JP: string;
|
||||||
|
Station_EN: string;
|
||||||
|
StationName?: string;
|
||||||
|
MyStation?: string;
|
||||||
|
StationNumber: string;
|
||||||
|
DispNum?: string;
|
||||||
|
StationTimeTable: string;
|
||||||
|
StationMap?: string;
|
||||||
|
JrHpUrl?: string;
|
||||||
|
lat: number;
|
||||||
|
lng: number;
|
||||||
|
jslodApi: string;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export const StationDiagramView: FC<props> = ({ route }) => {
|
||||||
|
if (!route.params) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const { currentStation } = route.params;
|
||||||
|
// 必要な情報:駅情報、全ダイヤ、カスタム列車情報
|
||||||
|
// 表示モード:縦並びリスト、横並びグリッド(時刻分割)、横並び単純左詰め
|
||||||
|
// フィルタリング:終点路線、種別、行先、関係停車駅
|
||||||
|
|
||||||
|
const { keyList, allTrainDiagram, allCustomTrainData } = useAllTrainDiagram();
|
||||||
|
|
||||||
|
const { navigate, addListener, goBack, canGoBack } = useNavigation();
|
||||||
|
const [keyBoardVisible, setKeyBoardVisible] = useState(false);
|
||||||
|
const [input, setInput] = useState("");
|
||||||
|
const [selectedTypeList, setSelectedTypeList] = useState<typeID[]>([
|
||||||
|
"Normal",
|
||||||
|
"OneMan",
|
||||||
|
"Rapid",
|
||||||
|
"OneManRapid",
|
||||||
|
"LTDEXP",
|
||||||
|
"NightLTDEXP",
|
||||||
|
]);
|
||||||
|
type hoge = {
|
||||||
|
trainNumber: string;
|
||||||
|
array: string;
|
||||||
|
name: string;
|
||||||
|
timeType: string;
|
||||||
|
time: string;
|
||||||
|
}[];
|
||||||
|
const [showTypeFiltering, setShowTypeFiltering] = useState(false);
|
||||||
|
const [showLastStop, setShowLastStop] = useState(false);
|
||||||
|
const [threw, setIsThrew] = useState(false);
|
||||||
|
const [currentStationDiagram, setCurrentStationDiagram] = useState<hoge>([]);
|
||||||
|
useEffect(() => {
|
||||||
|
if (allTrainDiagram && currentStation.length > 0) {
|
||||||
|
const stationName = currentStation[0].Station_JP;
|
||||||
|
let returnDataArray: hoge = [];
|
||||||
|
keyList
|
||||||
|
.filter((s) => {
|
||||||
|
const boolData = allTrainDiagram[s];
|
||||||
|
let isStop = false;
|
||||||
|
let isInput = false;
|
||||||
|
|
||||||
|
boolData.split("#").forEach((d) => {
|
||||||
|
const [station, type, time] = d.split(",");
|
||||||
|
if (station === stationName) isStop = true;
|
||||||
|
if (station === input && type && !type.includes("通"))
|
||||||
|
isInput = true;
|
||||||
|
});
|
||||||
|
if (input && input.length > 0) {
|
||||||
|
return isInput && isStop;
|
||||||
|
}
|
||||||
|
return isStop;
|
||||||
|
})
|
||||||
|
.forEach((d) => {
|
||||||
|
allTrainDiagram[d]
|
||||||
|
.split("#")
|
||||||
|
.filter((d) => {
|
||||||
|
const [station, type, time] = d.split(",");
|
||||||
|
return station === stationName;
|
||||||
|
})
|
||||||
|
.forEach((x) => {
|
||||||
|
const [name, timeType, time] = x.split(",");
|
||||||
|
if (!name || !timeType || !time) return;
|
||||||
|
|
||||||
|
const { img, trainName, type, trainNumDistance, infogram } =
|
||||||
|
customTrainDataDetector(d, allCustomTrainData);
|
||||||
|
const arrayData = {
|
||||||
|
trainNumber: d,
|
||||||
|
array: allTrainDiagram[d],
|
||||||
|
name,
|
||||||
|
timeType,
|
||||||
|
time,
|
||||||
|
};
|
||||||
|
// //条件によってフィルタリング
|
||||||
|
if (!threw && timeType && timeType.includes("通")) return;
|
||||||
|
if (!showLastStop && timeType && timeType.includes("着")) return;
|
||||||
|
if (
|
||||||
|
selectedTypeList.length > 0 &&
|
||||||
|
selectedTypeList.findIndex((item) => item === type) === -1
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
selectedTypeList.findIndex(
|
||||||
|
(item) => item === "Forwarding"
|
||||||
|
) !== -1
|
||||||
|
) {
|
||||||
|
if (!d.match(/[A,B,R,H,E,T,L]/)) return;
|
||||||
|
} else if (
|
||||||
|
selectedTypeList.findIndex((item) => item === "SPCL") !== -1
|
||||||
|
) {
|
||||||
|
if (!d.match(/9\d\d\d[D,M,S]/)) return;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
returnDataArray.push(arrayData);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
setCurrentStationDiagram(
|
||||||
|
returnDataArray.sort((a, b) => {
|
||||||
|
const adjustTime = (t: string) => {
|
||||||
|
const [h, m] = t.split(":").map(Number);
|
||||||
|
// 4時未満は翌日の時刻とみなして+24時間
|
||||||
|
return h < 4
|
||||||
|
? dayjs().add(1, "day").hour(h).minute(m)
|
||||||
|
: dayjs().hour(h).minute(m);
|
||||||
|
};
|
||||||
|
const aa = adjustTime(a.time);
|
||||||
|
const bb = adjustTime(b.time);
|
||||||
|
const x = aa.isAfter(bb);
|
||||||
|
return x ? 1 : -1;
|
||||||
|
//return true;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, [currentStation, showLastStop, threw, input, selectedTypeList]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const showSubscription = Keyboard.addListener("keyboardDidShow", () => {
|
||||||
|
setKeyBoardVisible(true);
|
||||||
|
});
|
||||||
|
const hideSubscription = Keyboard.addListener("keyboardDidHide", () => {
|
||||||
|
setKeyBoardVisible(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
showSubscription.remove();
|
||||||
|
hideSubscription.remove();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
textAlign: "center",
|
||||||
|
fontSize: 20,
|
||||||
|
color: "white",
|
||||||
|
fontWeight: "bold",
|
||||||
|
paddingVertical: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{currentStation[0].Station_JP}駅 時刻表
|
||||||
|
</Text>
|
||||||
|
{/* <ListView data={currentStationDiagram} /> */}
|
||||||
|
<ExGridView data={currentStationDiagram} />
|
||||||
|
{/* <Text
|
||||||
|
style={{
|
||||||
|
backgroundColor: "white",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderStyle: "solid",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
お気に入り登録した駅のうち、位置情報システムで移動可能な駅が表示されています。タップすることで位置情報システムの当該の駅に移動します。
|
||||||
|
</Text> */}
|
||||||
|
<KeyboardAvoidingView
|
||||||
|
behavior="padding"
|
||||||
|
keyboardVerticalOffset={80}
|
||||||
|
enabled={Platform.OS === "ios"}
|
||||||
|
>
|
||||||
|
<ScrollView horizontal style={{ height: 35, flexDirection: "row" }}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
alignItems: "center",
|
||||||
|
marginHorizontal: 5,
|
||||||
|
backgroundColor: threw ? "white" : "#ffffff00",
|
||||||
|
alignSelf: "center",
|
||||||
|
borderColor: "white",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 100,
|
||||||
|
}}
|
||||||
|
onPress={() => {
|
||||||
|
setIsThrew(!threw);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: threw ? "#0099CC" : "white",
|
||||||
|
fontSize: 14,
|
||||||
|
margin: 5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
通過
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
alignItems: "center",
|
||||||
|
marginHorizontal: 5,
|
||||||
|
backgroundColor: showLastStop ? "white" : "#ffffff00",
|
||||||
|
alignSelf: "center",
|
||||||
|
borderColor: "white",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 100,
|
||||||
|
}}
|
||||||
|
onPress={() => {
|
||||||
|
setShowLastStop(!showLastStop);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: showLastStop ? "#0099CC" : "white",
|
||||||
|
fontSize: 14,
|
||||||
|
margin: 5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
当駅止
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
height: "auto",
|
||||||
|
borderLeftWidth: 1,
|
||||||
|
margin: 5,
|
||||||
|
borderColor: "white",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{showTypeFiltering ? (
|
||||||
|
<>
|
||||||
|
<TypeSelectorBox
|
||||||
|
selectedTypeList={selectedTypeList}
|
||||||
|
setSelectedTypeList={setSelectedTypeList}
|
||||||
|
typeName="普通"
|
||||||
|
typeID="Normal"
|
||||||
|
color="black"
|
||||||
|
relativeID={["OneMan"]}
|
||||||
|
/>
|
||||||
|
<TypeSelectorBox
|
||||||
|
selectedTypeList={selectedTypeList}
|
||||||
|
setSelectedTypeList={setSelectedTypeList}
|
||||||
|
typeName="快速"
|
||||||
|
typeID="Rapid"
|
||||||
|
color="#00b8d8cc"
|
||||||
|
relativeID={["OneManRapid"]}
|
||||||
|
/>
|
||||||
|
<TypeSelectorBox
|
||||||
|
selectedTypeList={selectedTypeList}
|
||||||
|
setSelectedTypeList={setSelectedTypeList}
|
||||||
|
typeName="特急"
|
||||||
|
typeID="LTDEXP"
|
||||||
|
color="red"
|
||||||
|
relativeID={["NightLTDEXP"]}
|
||||||
|
/>
|
||||||
|
<TypeSelectorBox
|
||||||
|
selectedTypeList={selectedTypeList}
|
||||||
|
setSelectedTypeList={setSelectedTypeList}
|
||||||
|
typeName="臨時"
|
||||||
|
typeID="SPCL"
|
||||||
|
color="#297bff"
|
||||||
|
relativeID={["SPCL_Normal", "SPCL_Rapid", "SPCL_EXP", "Party"]}
|
||||||
|
/>
|
||||||
|
<TypeSelectorBox
|
||||||
|
selectedTypeList={selectedTypeList}
|
||||||
|
setSelectedTypeList={setSelectedTypeList}
|
||||||
|
typeName="貨物"
|
||||||
|
typeID="Freight"
|
||||||
|
color="#00869ecc"
|
||||||
|
/>
|
||||||
|
<TypeSelectorBox
|
||||||
|
selectedTypeList={selectedTypeList}
|
||||||
|
setSelectedTypeList={setSelectedTypeList}
|
||||||
|
typeName="回送"
|
||||||
|
typeID="Forwarding"
|
||||||
|
color="#727272cc"
|
||||||
|
relativeID={["FreightForwarding"]}
|
||||||
|
/>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
alignItems: "center",
|
||||||
|
marginHorizontal: 5,
|
||||||
|
backgroundColor: "#ffffff00",
|
||||||
|
alignSelf: "center",
|
||||||
|
borderColor: "white",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 100,
|
||||||
|
}}
|
||||||
|
onPress={() => {
|
||||||
|
LayoutAnimation.configureNext(
|
||||||
|
LayoutAnimation.Presets.easeInEaseOut
|
||||||
|
);
|
||||||
|
setShowTypeFiltering(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
fontSize: 14,
|
||||||
|
margin: 5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
alignItems: "center",
|
||||||
|
marginHorizontal: 5,
|
||||||
|
backgroundColor: "#ffffff00",
|
||||||
|
alignSelf: "center",
|
||||||
|
borderColor: "white",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 100,
|
||||||
|
}}
|
||||||
|
onPress={() => {
|
||||||
|
LayoutAnimation.configureNext(
|
||||||
|
LayoutAnimation.Presets.easeInEaseOut
|
||||||
|
);
|
||||||
|
setShowTypeFiltering(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
fontSize: 14,
|
||||||
|
margin: 5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
>
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
</ScrollView>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
height: 35,
|
||||||
|
margin: 5,
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#F4F4F4",
|
||||||
|
flexDirection: "row",
|
||||||
|
paddingLeft: 10,
|
||||||
|
paddingRight: 10,
|
||||||
|
borderRadius: 25,
|
||||||
|
borderColor: "#F4F4F4",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextInput
|
||||||
|
placeholder="駅名を入力して停車駅でフィルタリングします。"
|
||||||
|
onFocus={() => setKeyBoardVisible(true)}
|
||||||
|
onEndEditing={() => {}}
|
||||||
|
onChange={(ret) => setInput(ret.nativeEvent.text)}
|
||||||
|
value={input}
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</KeyboardAvoidingView>
|
||||||
|
{keyBoardVisible || (
|
||||||
|
<BigButton onPress={() => goBack()} string="閉じる" />
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TypeSelectorBox: FC<{
|
||||||
|
selectedTypeList: typeID[];
|
||||||
|
setSelectedTypeList: (list: typeID[]) => void;
|
||||||
|
typeName: string;
|
||||||
|
typeID: typeID;
|
||||||
|
color: colorString;
|
||||||
|
relativeID?: typeID[];
|
||||||
|
}> = (props) => {
|
||||||
|
const {
|
||||||
|
selectedTypeList,
|
||||||
|
setSelectedTypeList,
|
||||||
|
typeName,
|
||||||
|
typeID,
|
||||||
|
relativeID,
|
||||||
|
color,
|
||||||
|
} = props;
|
||||||
|
const isSelected =
|
||||||
|
selectedTypeList.findIndex((item) => item === typeID) !== -1;
|
||||||
|
return (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={{
|
||||||
|
alignItems: "center",
|
||||||
|
marginHorizontal: 5,
|
||||||
|
opacity: isSelected ? 1 : 0.8,
|
||||||
|
backgroundColor: isSelected ? "white" : color,
|
||||||
|
alignSelf: "center",
|
||||||
|
borderColor: color,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 100,
|
||||||
|
}}
|
||||||
|
onPress={() => {
|
||||||
|
if (selectedTypeList.findIndex((item) => item === typeID) === -1) {
|
||||||
|
setSelectedTypeList([
|
||||||
|
...selectedTypeList,
|
||||||
|
typeID,
|
||||||
|
...(relativeID ?? []),
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
setSelectedTypeList(
|
||||||
|
selectedTypeList.filter(
|
||||||
|
(item) => item !== typeID && !relativeID?.includes(item)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: isSelected ? color : "white",
|
||||||
|
fontSize: 14,
|
||||||
|
margin: 5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{typeName}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
};
|
@@ -1,11 +1,17 @@
|
|||||||
type nameString =
|
import { typeID } from "./getStringConfig";
|
||||||
| "Rapid"
|
|
||||||
| "LTDEXP"
|
export type colorString =
|
||||||
| "NightLTDEXP"
|
| "aqua"
|
||||||
| "SPCL"
|
| "red"
|
||||||
| "Normal"
|
| "#297bff"
|
||||||
| string;
|
| "#ff7300ff"
|
||||||
type colorString = "aqua" | "red" | "#297bff" | "#ff7300ff" | "#00869ecc" | "#727272cc" | "white" | "pink";
|
| "#00869ecc"
|
||||||
|
| "#727272cc"
|
||||||
|
| "#00b8d8cc"
|
||||||
|
| "#e000b0ff"
|
||||||
|
| "white"
|
||||||
|
| "black"
|
||||||
|
| "pink";
|
||||||
type trainTypeString =
|
type trainTypeString =
|
||||||
| "快速"
|
| "快速"
|
||||||
| "特急"
|
| "特急"
|
||||||
@@ -21,24 +27,35 @@ type trainTypeString =
|
|||||||
| "単機回送"
|
| "単機回送"
|
||||||
| "その他";
|
| "その他";
|
||||||
type trainTypeDataString = "rapid" | "express" | "normal" | "notService";
|
type trainTypeDataString = "rapid" | "express" | "normal" | "notService";
|
||||||
type getTrainType = (d: nameString) => {
|
type getTrainType = (
|
||||||
|
d: typeID,
|
||||||
|
isWhiteMode?: boolean
|
||||||
|
) => {
|
||||||
color: colorString;
|
color: colorString;
|
||||||
name: trainTypeString;
|
name: trainTypeString;
|
||||||
data: trainTypeDataString;
|
data: trainTypeDataString;
|
||||||
};
|
};
|
||||||
export const getTrainType: getTrainType = (nameString) => {
|
export const getTrainType: getTrainType = (nameString, whiteMode) => {
|
||||||
switch (nameString) {
|
switch (nameString) {
|
||||||
case "Normal":
|
case "Normal":
|
||||||
return { color: "white", name: "普通列車", data: "normal" };
|
return {
|
||||||
|
color: whiteMode ? "black" : "white",
|
||||||
|
name: "普通列車",
|
||||||
|
data: "normal",
|
||||||
|
};
|
||||||
case "OneMan":
|
case "OneMan":
|
||||||
return { color: "white", name: "普通列車(ワンマン)", data: "normal" };
|
return {
|
||||||
|
color: whiteMode ? "black" : "white",
|
||||||
|
name: "普通列車(ワンマン)",
|
||||||
|
data: "normal",
|
||||||
|
};
|
||||||
case "Rapid":
|
case "Rapid":
|
||||||
case "OneManRapid":
|
case "OneManRapid":
|
||||||
return { color: "aqua", name: "快速", data: "rapid" };
|
return { color: whiteMode ? "#00b8d8cc" : "aqua", name: "快速", data: "rapid" };
|
||||||
case "LTDEXP":
|
case "LTDEXP":
|
||||||
return { color: "red", name: "特急", data: "express" };
|
return { color: "red", name: "特急", data: "express" };
|
||||||
case "NightLTDEXP":
|
case "NightLTDEXP":
|
||||||
return { color: "pink", name: "寝台特急", data: "express" };
|
return { color: whiteMode ? "#e000b0ff":"pink", name: "寝台特急", data: "express" };
|
||||||
case "SPCL":
|
case "SPCL":
|
||||||
case "SPCL_Normal":
|
case "SPCL_Normal":
|
||||||
return { color: "#297bff", name: "臨時", data: "normal" };
|
return { color: "#297bff", name: "臨時", data: "normal" };
|
||||||
@@ -55,6 +72,10 @@ export const getTrainType: getTrainType = (nameString) => {
|
|||||||
case "FreightForwarding":
|
case "FreightForwarding":
|
||||||
return { color: "#727272cc", name: "単機回送", data: "notService" };
|
return { color: "#727272cc", name: "単機回送", data: "notService" };
|
||||||
default:
|
default:
|
||||||
return { color: "white", name: "その他", data: "normal" };
|
return {
|
||||||
|
color: whiteMode ? "black" : "white",
|
||||||
|
name: "その他",
|
||||||
|
data: "normal",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -6,6 +6,7 @@ const initialState = {
|
|||||||
allTrainDiagram: undefined,
|
allTrainDiagram: undefined,
|
||||||
setAllTrainDiagram: () => {},
|
setAllTrainDiagram: () => {},
|
||||||
allCustomTrainData: [],
|
allCustomTrainData: [],
|
||||||
|
keyList: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const AllTrainDiagramContext = createContext(initialState);
|
const AllTrainDiagramContext = createContext(initialState);
|
||||||
|
Reference in New Issue
Block a user