import React, { useEffect, useState } from "react"; import { View, Text, TouchableOpacity, StyleSheet, useWindowDimensions, BackHandler, Linking, } from "react-native"; import { SheetManager, useScrollHandlers } from "react-native-actions-sheet"; import { getTrainType } from "../../lib/getTrainType"; import { customTrainDataDetector } from "../custom-train-data"; import { useDeviceOrientationChange } from "../../stateBox/useDeviceOrientationChange"; import { EachStopList } from "./EachTrainInfo/EachStopList"; import { DataFromButton } from "./EachTrainInfo/DataFromButton"; import { DynamicHeaderScrollView } from "../DynamicHeaderScrollView"; import { LongHeader } from "./EachTrainInfo/LongHeader"; import { ShortHeader } from "./EachTrainInfo/ShortHeader"; import { ScrollStickyContent } from "./EachTrainInfo/ScrollStickyContent"; import { ShowSpecialTrain } from "./EachTrainInfo/ShowSpecialTrain"; import { useTrainMenu } from "../../stateBox/useTrainMenu"; import { HeaderText } from "./EachTrainInfoCore/HeaderText"; import { useStationList } from "../../stateBox/useStationList"; import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram"; // Custom hooks import { useTrainDiagramData } from "./EachTrainInfoCore/hooks/useTrainDiagramData"; import { useThroughStations } from "./EachTrainInfoCore/hooks/useThroughStations"; import { useNearbyTrains } from "./EachTrainInfoCore/hooks/useNearbyTrains"; import { useStopStationIDs } from "./EachTrainInfoCore/hooks/useStopStationIDs"; import { useTrainPosition } from "./EachTrainInfoCore/hooks/useTrainPosition"; import { useAutoScroll } from "./EachTrainInfoCore/hooks/useAutoScroll"; import { useExtendedStations } from "./EachTrainInfoCore/hooks/useExtendedStations"; export const EachTrainInfoCore = ({ actionSheetRef, data, openStationACFromEachTrainInfo, from, navigate, }) => { const { stationList } = useStationList(); const { allCustomTrainData } = useAllTrainDiagram(); const { setTrainInfo } = useTrainMenu(); const { height } = useWindowDimensions(); const { isLandscape } = useDeviceOrientationChange(); const scrollHandlers = actionSheetRef //@ts-ignore ? useScrollHandlers("scrollview-1", actionSheetRef) : null; // Custom hooks for data management const { trainData, setTrainData, trueTrainID } = useTrainDiagramData( data.trainNum ); const { trainDataWithThrough, haveThrough } = useThroughStations(trainData); const { headStation, tailStation, nearTrainIDList } = useNearbyTrains( data.trainNum, trainData ); const stopStationIDList = useStopStationIDs(trainDataWithThrough); const { currentTrainData, currentPosition, points, pointsDisplay } = useTrainPosition(data.trainNum, stopStationIDList); const { showHeadStation, showTailStation, extendToHeadStation, extendToTailStation, } = useExtendedStations(trainData, setTrainData); // UI state const [showThrew, setShowThrew] = useState(false); const [isJumped, setIsJumped] = useState(false); // Auto scroll to current position useAutoScroll( points, trainDataWithThrough, scrollHandlers, isJumped, setIsJumped, setShowThrew ); // Back button handler useEffect(() => { const backAction = () => { SheetManager.hide("EachTrainInfo"); return true; }; const backHandler = BackHandler.addEventListener( "hardwareBackPress", backAction ); return () => backHandler.remove(); }, []); const customTrainType = getTrainType({ type: customTrainDataDetector(data.trainNum, allCustomTrainData).type, }); const openTrainInfo = (trainNum) => { const train = customTrainDataDetector(trainNum, allCustomTrainData); let trainNumber = ""; if (train.train_num_distance && !isNaN(Number(train.train_num_distance))) { const numericPart = parseInt(trainNum.replace("M", "").replace("D", "")); trainNumber = `${numericPart - Number(train.train_num_distance)}号`; } const limitedData = getTrainType({ type: train.type }); const payload = { data: { trainNum, limited: `${limitedData.data}:${train.train_name}${trainNumber}`, }, navigate, from: from === "LED" ? "LED2" : "NearTrainDiagramView", }; if (isLandscape) { setTrainInfo(payload.data); } else { SheetManager.hide("EachTrainInfo").then(() => { setTimeout(() => { // @ts-expect-error - SheetManager payload type is too restrictive SheetManager.show("EachTrainInfo", { payload }); }, 200); }); } }; return ( } longHeader={ } topStickyContent={ } > {customTrainType.data === "notService" && ( この列車には乗車できません。 )} {headStation.length > 0 && headStation.map( (item, index) => !showHeadStation.includes(index) && ( extendToHeadStation(item.station, item.dia, index) } style={styles.extendStationButton} key={`${item.station}-head${index}`} > 「本当の始発駅」を表示 ) )} {!trainData.length && ( Linking.openURL(`https://twitter.com/search?q=${data.trainNum}`) } style={styles.twitterSearchButton} > Twitterで検索 )} {trainDataWithThrough.map((item, index, array) => item.split(",")[1] === "提" ? ( ) : ( ) )} 時刻が斜体,青色になっている時刻はコミュニティで追加されている独自データです。 {tailStation.length > 0 && tailStation.map( ({ station, dia }, index) => !showTailStation.includes(index) && ( extendToTailStation(station, dia, index)} style={styles.extendStationButton} key={`${station}-tail${index}`} > 「本当の終着駅」を表示 ) )} ); }; const styles = StyleSheet.create({ header: { justifyContent: "center", alignItems: "center", left: 0, right: 0, position: "absolute", zIndex: 1, backgroundColor: "f0f0f0", }, headerText: { color: "#fff", fontSize: 25, fontWeight: "bold", textAlign: "center", }, extendStationButton: { padding: 10, flexDirection: "row", borderColor: "blue", borderWidth: 1, margin: 10, borderRadius: 5, alignItems: "center", }, extendStationText: { fontSize: 18, fontWeight: "bold", color: "black", }, twitterSearchButton: { padding: 10, flexDirection: "row", borderColor: "blue", borderWidth: 1, margin: 10, borderRadius: 5, alignItems: "center", backgroundColor: "#ffffffc2", }, customDataNote: { backgroundColor: "#ffffffc2", }, bottomSpacer: { flexDirection: "row", padding: 8, borderBottomWidth: 1, borderBottomColor: "#f0f0f0", backgroundColor: "#ffffffc2", flex: 1, }, });