From c00034a11b4b3244afdfeecb6fa38f15b80501b6 Mon Sep 17 00:00:00 2001 From: harukin-expo-dev-env Date: Mon, 25 Aug 2025 15:54:40 +0000 Subject: [PATCH] =?UTF-8?q?=E9=A7=85=E6=99=82=E5=88=BB=E8=A1=A8=E3=81=AE?= =?UTF-8?q?=E3=82=B3=E3=82=A2=E6=83=85=E5=A0=B1=E3=82=92=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MenuPage.js | 14 +- Top.js | 15 +- .../StationDeteilView.js | 6 + .../StationDiagramButton.tsx | 40 +++ components/StationDiagram/ListView.tsx | 18 ++ components/StationDiagram/ListViewItem.tsx | 244 ++++++++++++++++++ .../StationDiagram/StationDiagramView.tsx | 114 ++++++++ lib/getStringConfig.ts | 2 +- lib/getTrainType.ts | 51 ++-- 9 files changed, 484 insertions(+), 20 deletions(-) create mode 100644 components/ActionSheetComponents/StationDeteilView/StationDiagramButton.tsx create mode 100644 components/StationDiagram/ListView.tsx create mode 100644 components/StationDiagram/ListViewItem.tsx create mode 100644 components/StationDiagram/StationDiagramView.tsx diff --git a/MenuPage.js b/MenuPage.js index 5102368..4e7647e 100644 --- a/MenuPage.js +++ b/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() { /> )} /> + - + ); } diff --git a/Top.js b/Top.js index 5f25b74..2925744 100644 --- a/Top.js +++ b/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} /> + - + { if (!props.payload) return <>; @@ -132,6 +133,11 @@ export const StationDeteilView = (props) => { onExit={onExit} /> )} + {!currentStation[0].StationTimeTable || ( 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) => { + const { navigate, onExit, currentStation } = props; + return ( + } + flex={1} + onPressButton={() => { + navigate("stDiagram", { + currentStation, + }); + onExit(); + }} + > + 時刻表v2 + + ); +}; diff --git a/components/StationDiagram/ListView.tsx b/components/StationDiagram/ListView.tsx new file mode 100644 index 0000000..1f0b296 --- /dev/null +++ b/components/StationDiagram/ListView.tsx @@ -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) => ( + + ))} + + ); +}; diff --git a/components/StationDiagram/ListViewItem.tsx b/components/StationDiagram/ListViewItem.tsx new file mode 100644 index 0000000..7e1e50e --- /dev/null +++ b/components/StationDiagram/ListViewItem.tsx @@ -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 ( + openTrainInfo()} + > + + {formattedTime} + + {d.type} + + + + + + {typeString} + + + {trainData?.trainName + + (trainData?.trainNumDistance !== null + ? ` ${parseInt(d.trainNumber) - trainData?.trainNumDistance}号` + : "")} + + + {trainData?.TrainNumber} + + + + {trainName} + + + + ); +}; diff --git a/components/StationDiagram/StationDiagramView.tsx b/components/StationDiagram/StationDiagramView.tsx new file mode 100644 index 0000000..49adcba --- /dev/null +++ b/components/StationDiagram/StationDiagramView.tsx @@ -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 = ({ 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([]); + 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 ( + + + {currentStation[0].Station_JP}駅 時刻表 + + + + + {/* + お気に入り登録した駅のうち、位置情報システムで移動可能な駅が表示されています。タップすることで位置情報システムの当該の駅に移動します。 + */} + goBack()} string="閉じる" /> + + ); +}; diff --git a/lib/getStringConfig.ts b/lib/getStringConfig.ts index 327c533..54f84a9 100644 --- a/lib/getStringConfig.ts +++ b/lib/getStringConfig.ts @@ -1,4 +1,4 @@ -type typeID = +export type typeID = | "Normal" | "OneMan" | "Rapid" diff --git a/lib/getTrainType.ts b/lib/getTrainType.ts index 7966b8a..4f3f951 100644 --- a/lib/getTrainType.ts +++ b/lib/getTrainType.ts @@ -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", + }; } };