駅時刻表のコア情報を作成
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 { useBottomTabBarHeight } from "@react-navigation/bottom-tabs";
|
||||
import GeneralWebView from "./GeneralWebView";
|
||||
import { StationDiagramView } from "@/components/StationDiagram/StationDiagramView";
|
||||
const Stack = createStackNavigator();
|
||||
|
||||
export function MenuPage() {
|
||||
@@ -86,7 +87,7 @@ export function MenuPage() {
|
||||
})
|
||||
.catch((error) => {
|
||||
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="setting"
|
||||
@@ -133,7 +139,11 @@ export function MenuPage() {
|
||||
component={AllTrainDiagramView}
|
||||
/>
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
15
Top.js
15
Top.js
@@ -14,6 +14,7 @@ import { AS } from "./storageControl";
|
||||
import { news } from "./config/newsUpdate";
|
||||
import { Linking, Platform } from "react-native";
|
||||
import GeneralWebView from "./GeneralWebView";
|
||||
import { StationDiagramView } from "@/components/StationDiagram/StationDiagramView";
|
||||
const Stack = createStackNavigator();
|
||||
export const Top = () => {
|
||||
const { webview } = useCurrentTrain();
|
||||
@@ -37,7 +38,8 @@ export const Top = () => {
|
||||
return;
|
||||
}
|
||||
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()`);
|
||||
return;
|
||||
};
|
||||
@@ -64,8 +66,17 @@ export const Top = () => {
|
||||
options={{ ...optionData }}
|
||||
component={TrainBase}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="stDiagram"
|
||||
options={{ ...optionData, gestureEnabled: false }}
|
||||
component={StationDiagramView}
|
||||
/>
|
||||
<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="trainMenu"
|
||||
|
@@ -19,6 +19,7 @@ import { 駅構内図 } from "./StationDeteilView/StationInsideMapButton";
|
||||
import { WebSiteButton } from "./StationDeteilView/WebSiteButton";
|
||||
import { StationTimeTableButton } from "./StationDeteilView/StationTimeTableButton";
|
||||
import { StationTrainPositionButton } from "./StationDeteilView/StationTrainPositionButton";
|
||||
import { StationDiagramButton } from "./StationDeteilView/StationDiagramButton";
|
||||
|
||||
export const StationDeteilView = (props) => {
|
||||
if (!props.payload) return <></>;
|
||||
@@ -132,6 +133,11 @@ export const StationDeteilView = (props) => {
|
||||
onExit={onExit}
|
||||
/>
|
||||
)}
|
||||
<StationDiagramButton
|
||||
navigate={navigate}
|
||||
onExit={onExit}
|
||||
currentStation={currentStation}
|
||||
/>
|
||||
{!currentStation[0].StationTimeTable || (
|
||||
<StationTimeTableButton
|
||||
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>
|
||||
);
|
||||
};
|
18
components/StationDiagram/ListView.tsx
Normal file
18
components/StationDiagram/ListView.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { FC } from "react";
|
||||
import { ListViewItem } from "@/components/StationDiagram/ListViewItem";
|
||||
|
||||
export const ListView: FC<{ data: {
|
||||
trainNumber: string;
|
||||
array: string;
|
||||
name: string;
|
||||
type: string;
|
||||
time: string;
|
||||
}[]; }> = ({ data }) => {
|
||||
return (
|
||||
<>
|
||||
{data.map((d, i) => (
|
||||
<ListViewItem key={d.trainNumber + i} d={d} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
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>
|
||||
);
|
||||
};
|
114
components/StationDiagram/StationDiagramView.tsx
Normal file
114
components/StationDiagram/StationDiagramView.tsx
Normal file
@@ -0,0 +1,114 @@
|
||||
import { FC, useEffect, useState } from "react";
|
||||
import { View, Text, ScrollView } 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";
|
||||
|
||||
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 { allTrainDiagram } = useAllTrainDiagram();
|
||||
|
||||
const { navigate, addListener, goBack, canGoBack } = useNavigation();
|
||||
type hoge = {
|
||||
trainNumber: string;
|
||||
array: string;
|
||||
name: string;
|
||||
type: string;
|
||||
time: string;
|
||||
}[];
|
||||
const [currentStationDiagram, setCurrentStationDiagram] = useState<hoge>([]);
|
||||
useEffect(() => {
|
||||
if (allTrainDiagram && currentStation.length > 0) {
|
||||
const stationName = currentStation[0].Station_JP;
|
||||
let returnDataArray = [];
|
||||
Object.keys(allTrainDiagram).forEach((d) => {
|
||||
if (allTrainDiagram[d].includes(stationName)) {
|
||||
allTrainDiagram[d]
|
||||
.split("#")
|
||||
.filter((d) => d.includes(stationName))
|
||||
.forEach((x) => {
|
||||
const [name, type, time] = x.split(",");
|
||||
if (!name || !type || !time) return;
|
||||
const arrayData = {
|
||||
trainNumber: d,
|
||||
array: allTrainDiagram[d],
|
||||
name,
|
||||
type,
|
||||
time,
|
||||
};
|
||||
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;
|
||||
}));
|
||||
}
|
||||
}, []);
|
||||
return (
|
||||
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
||||
<Text
|
||||
style={{
|
||||
textAlign: "center",
|
||||
fontSize: 20,
|
||||
color: "white",
|
||||
fontWeight: "bold",
|
||||
paddingVertical: 10,
|
||||
}}
|
||||
>
|
||||
{currentStation[0].Station_JP}駅 時刻表
|
||||
</Text>
|
||||
<ScrollView style={{ backgroundColor: "white" }}>
|
||||
<ListView data={currentStationDiagram} />
|
||||
</ScrollView>
|
||||
{/* <Text
|
||||
style={{
|
||||
backgroundColor: "white",
|
||||
borderWidth: 1,
|
||||
borderStyle: "solid",
|
||||
}}
|
||||
>
|
||||
お気に入り登録した駅のうち、位置情報システムで移動可能な駅が表示されています。タップすることで位置情報システムの当該の駅に移動します。
|
||||
</Text> */}
|
||||
<BigButton onPress={() => goBack()} string="閉じる" />
|
||||
</View>
|
||||
);
|
||||
};
|
@@ -1,4 +1,4 @@
|
||||
type typeID =
|
||||
export type typeID =
|
||||
| "Normal"
|
||||
| "OneMan"
|
||||
| "Rapid"
|
||||
|
@@ -1,11 +1,17 @@
|
||||
type nameString =
|
||||
| "Rapid"
|
||||
| "LTDEXP"
|
||||
| "NightLTDEXP"
|
||||
| "SPCL"
|
||||
| "Normal"
|
||||
| string;
|
||||
type colorString = "aqua" | "red" | "#297bff" | "#ff7300ff" | "#00869ecc" | "#727272cc" | "white" | "pink";
|
||||
import { typeID } from "./getStringConfig";
|
||||
|
||||
type colorString =
|
||||
| "aqua"
|
||||
| "red"
|
||||
| "#297bff"
|
||||
| "#ff7300ff"
|
||||
| "#00869ecc"
|
||||
| "#727272cc"
|
||||
| "#00b8d8cc"
|
||||
| "#e000b0ff"
|
||||
| "white"
|
||||
| "black"
|
||||
| "pink";
|
||||
type trainTypeString =
|
||||
| "快速"
|
||||
| "特急"
|
||||
@@ -21,24 +27,35 @@ type trainTypeString =
|
||||
| "単機回送"
|
||||
| "その他";
|
||||
type trainTypeDataString = "rapid" | "express" | "normal" | "notService";
|
||||
type getTrainType = (d: nameString) => {
|
||||
type getTrainType = (
|
||||
d: typeID,
|
||||
isWhiteMode?: boolean
|
||||
) => {
|
||||
color: colorString;
|
||||
name: trainTypeString;
|
||||
data: trainTypeDataString;
|
||||
};
|
||||
export const getTrainType: getTrainType = (nameString) => {
|
||||
export const getTrainType: getTrainType = (nameString, whiteMode) => {
|
||||
switch (nameString) {
|
||||
case "Normal":
|
||||
return { color: "white", name: "普通列車", data: "normal" };
|
||||
return {
|
||||
color: whiteMode ? "black" : "white",
|
||||
name: "普通列車",
|
||||
data: "normal",
|
||||
};
|
||||
case "OneMan":
|
||||
return { color: "white", name: "普通列車(ワンマン)", data: "normal" };
|
||||
return {
|
||||
color: whiteMode ? "black" : "white",
|
||||
name: "普通列車(ワンマン)",
|
||||
data: "normal",
|
||||
};
|
||||
case "Rapid":
|
||||
case "OneManRapid":
|
||||
return { color: "aqua", name: "快速", data: "rapid" };
|
||||
return { color: whiteMode ? "#00b8d8cc" : "aqua", name: "快速", data: "rapid" };
|
||||
case "LTDEXP":
|
||||
return { color: "red", name: "特急", data: "express" };
|
||||
case "NightLTDEXP":
|
||||
return { color: "pink", name: "寝台特急", data: "express" };
|
||||
return { color: whiteMode ? "#e000b0ff":"pink", name: "寝台特急", data: "express" };
|
||||
case "SPCL":
|
||||
case "SPCL_Normal":
|
||||
return { color: "#297bff", name: "臨時", data: "normal" };
|
||||
@@ -55,6 +72,10 @@ export const getTrainType: getTrainType = (nameString) => {
|
||||
case "FreightForwarding":
|
||||
return { color: "#727272cc", name: "単機回送", data: "notService" };
|
||||
default:
|
||||
return { color: "white", name: "その他", data: "normal" };
|
||||
return {
|
||||
color: whiteMode ? "black" : "white",
|
||||
name: "その他",
|
||||
data: "normal",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user