import React, { useRef, useState, useEffect } from "react"; import Carousel from "react-native-snap-carousel"; import { Platform, View, LayoutAnimation, ScrollView, Linking, Text, TouchableOpacity, } from "react-native"; import Constants from "expo-constants"; import { ListItem } from "native-base"; import Icon from "react-native-vector-icons/Entypo"; import * as Location from "expo-location"; import StatusbarDetect from "./StatusbarDetect"; import { useNavigation } from "@react-navigation/native"; import AutoHeightImage from "react-native-auto-height-image"; import { widthPercentageToDP as wp } from "react-native-responsive-screen"; import { FontAwesome, Foundation, Ionicons, MaterialCommunityIcons, } from "@expo/vector-icons"; import LottieView from "lottie-react-native"; import { StationDeteilView } from "./components/ActionSheetComponents/StationDeteilView"; import LED_vision from "./components/発車時刻表/LED_vidion"; import Sign from "./components/駅名表/Sign"; import { UsefulBox } from "./components/atom/UsefulBox"; import { TicketBox } from "./components/atom/TicketBox"; import { TextBox } from "./components/atom/TextBox"; import { getStationList, lineList } from "./lib/getStationList"; import { JRSTraInfo } from "./components/ActionSheetComponents/JRSTraInfo"; import useInterval from "./lib/useInterval"; export default function Menu(props) { const { navigation: { navigate }, favoriteStation, setFavoriteStation, } = props; const JRSTraInfoEXAcSR = useRef(null); const StationBoardAcSR = useRef(null); const navigation = useNavigation(); //位置情報 const [location, setLocation] = useState(null); const [locationStatus, setLocationStatus] = useState(null); useEffect(() => { Location.requestForegroundPermissionsAsync().then((data) => { setLocationStatus(data.status); }); }, []); useEffect(() => { if (locationStatus !== "granted") return () => {}; getCurrentPosition(); }, [locationStatus]); const getCurrentPosition = () => { Location.getCurrentPositionAsync({}).then((location) => setLocation(location) ); }; useInterval(() => { if (locationStatus !== "granted") return () => {}; getCurrentPosition(); }, 5000); const [originalStationList, setOriginalStationList] = useState(); useEffect(() => { getStationList().then(setOriginalStationList); }, []); const [locationAndFavorite, setLocationAndFavorite] = useState([]); useEffect(() => { if (!favoriteStation) return () => {}; const data = favoriteStation.filter((d) => JSON.stringify(d) === JSON.stringify(currentStation) ? false : true ); setLocationAndFavorite(data); }, [currentStation, favoriteStation]); useEffect(() => { if (!(selectedCurrentStation < favoriteStation.length)) { setSelectedCurrentStation(favoriteStation.length - 1); carouselRef.current.snapToItem(favoriteStation.length - 1); } }, [favoriteStation]); const [stationName, setStationName] = useState(undefined); const [currentStation, setCurrentStation] = useState(undefined); useEffect(() => { if (!location) return () => {}; if (!originalStationList) return () => {}; const findStationEachLine = (selectLine) => { const searchArea = 0.0015; const _calcDistance = (from, to) => { let lat = Math.abs(from.lat - to.lat); let lng = Math.abs(from.lng - to.lng); return Math.sqrt(lat * lat + lng * lng); }; let NearStation = selectLine.filter( (d) => _calcDistance(d, { lat: location.coords.latitude, lng: location.coords.longitude, }) < searchArea ); return NearStation; }; let returnDataBase = lineList .map((d) => findStationEachLine(originalStationList[d])) .filter((d) => d.length > 0) .reduce((pre, current) => { pre.push(...current); return pre; }, []); LayoutAnimation.easeInEaseOut(); if (returnDataBase.length) { let currentStation = currentStation == undefined ? [] : currentStation; if (currentStation.toString() != returnDataBase.toString()) { setCurrentStation(returnDataBase); } } else { setCurrentStation(undefined); StationBoardAcSR.current?.hide(); } }, [location, originalStationList]); const [count, setCount] = useState(0); const [delayData, setDelayData] = useState(undefined); const [getTime, setGetTime] = useState(new Date()); const [loadingDelayData, setLoadingDelayData] = useState(true); const carouselRef = useRef(); const scrollRef = useRef(); const [isScroll, setIsScroll] = useState(true); const [selectedCurrentStation, setSelectedCurrentStation] = useState(0); useEffect(() => { fetch( "https://script.google.com/macros/s/AKfycbyKxch7z7l8e07LXulRHqxjVoIiB13kcgvoToLE-rqlxLmLSKdlmqz0FI1F2EuA7Zfg/exec" ) .then((response) => response.text()) .then((data) => setDelayData(data !== "" ? data.split("^") : null)) .then(LayoutAnimation.easeInEaseOut) .then(() => setGetTime(new Date())) .finally(() => setLoadingDelayData(false)); }, [loadingDelayData]); return ( Linking.openURL( "https://www.jr-shikoku.co.jp/02_information/suspension/sp/" ) } > 新型コロナウイルスに関するお知らせ 列車の運行計画・混雑状況・感染症対策への取り組み { setSelectedCurrentStation(d); }} renderItem={({ item, index }) => { return ( ); }} /> {(currentStation || originalStationList) && ( )} } flex={1} onPressButton={() => Linking.openURL("https://www.jr-eki.com/ticket/brand") } > トクトク切符 } flex={1} onPressButton={() => Linking.openURL( "https://www.jr-shikoku.co.jp/01_trainbus/event_train/sp/" ) } > 観光列車 } flex={1} onPressButton={() => Linking.openURL("https://www.jr-eki.com/tour/brand") } > 旅行ツアー Linking.openURL("https://www.jr-eki.com/smart-eki/index.html") } > スマートえきちゃん JR四国のチケットレススマホアプリです。 Linking.openURL( "https://www.jr-shikoku.co.jp/sp/index.html#menu-box" ) } > 臨時列車などのお知らせ 区間縮小・計画運休・イベント・季節臨時列車など Linking.openURL("https://www.jr-shikoku.co.jp/03_news/press/") } > ニュースリリース 公式プレス記事はこちら Linking.openURL("https://www.jr-shikoku.co.jp/teiki/") } > 定期運賃計算 通常/学生/快て〜き等はこちら Linking.openURL("https://www.jr-shikoku.co.jp/04_company/group/sp/") } > JR四国のお店・サービス JR四国グループの施設をご案内 Linking.openURL("https://www.jr-odekake.net/smt/")} > 時刻・運賃計算 (マイ・ダイヤ) マイ・ダイヤはJR西日本提供のサービスです。 Linking.openURL("tel:0570-00-4592")} > JR四国案内センター 0570-00-4592 (8:00~20:00 年中無休) (通話料がかかります) JR四国公式Twitter一族 {((data) => data.map((d) => ( Linking.openURL(d.url)}> {d.name} )))([ { url: "https://twitter.com/JRshikoku_eigyo", name: "JR四国営業部【公式】", }, { url: "https://twitter.com/JRshikoku_tokyo", name: "JR四国 東京営業情報【公式】", }, { url: "https://twitter.com/JRshikoku_osaka", name: "JR四国 大阪営業部【公式】", }, { url: "https://twitter.com/jr_shikoku_info", name: "JR四国列車運行情報【公式】", }, { url: "https://twitter.com/Smile_Eki_Chan", name: "すまいるえきちゃん♡JR四国【公式】", }, { url: "https://twitter.com/jrs_matsuyama", name: "JR四国 松山駅 【公式】", }, { url: "https://twitter.com/jrshikoku_kochi", name: "JR四国 高知駅【公式】", }, { url: "https://twitter.com/jr_tokust", name: "JR四国 徳島駅【公式】", }, { url: "https://twitter.com/jrshikoku_uwjm", name: "JR四国 宇和島駅【公式】", }, { url: "https://twitter.com/JRshikoku_wkoch", name: "JR四国 ワープ高知支店【公式】", }, { url: "https://twitter.com/jrshikoku_nihaw", name: "JR四国 ワープ新居浜営業所【公式】", }, { url: "https://twitter.com/Yoakemonogatari", name: "志国土佐 時代の夜明けのものがたり【公式】", }, ])} このアプリについて このアプリはXprocess(HARUKIN)が製作しているJR四国の完全非公式アシストアプリケーションです。このアプリに関することでのJR四国公式へ問合せすることはお控えください。以下のTwitterよりお願いします。 Linking.openURL("https://twitter.com/Xprocess_main") } > XprocessのTwitter 制作運営のTwitterです。 navigate("setting")} > アプリの設定 アプリの設定画面を表示します。 {/* */} ); } const TitleBar = () => { return ( Linking.openURL("https://www.jr-shikoku.co.jp")} > ); }; const TopMenuButton = () => { const buttonList = [ { backgroundColor: "#F89038", icon: "train-car", onPress: () => Linking.openURL("https://www.jr-shikoku.co.jp/01_trainbus/sp/"), title: "駅・鉄道情報", }, { backgroundColor: "#EA4752", icon: "google-spreadsheet", onPress: () => Linking.openURL( "https://www.jr-shikoku.co.jp/01_trainbus/jikoku/sp/#mainprice-box" ), title: "運賃表", }, { backgroundColor: "#91C31F", icon: "clipboard-list-outline", onPress: () => Linking.openURL("https://www.jr-shikoku.co.jp/e5489/"), title: "予約", }, ]; return ( {buttonList.map((d, index) => ( {d.title} ))} ); }; const JRSTraInfoBox = (props) => { const { JRSTraInfoEXAcSR, getTime, setLoadingDelayData, loadingDelayData, delayData, } = props; const styles = { touch: { backgroundColor: "#0099CC", borderRadius: 5, margin: 10, borderColor: "black", borderWidth: 2, overflow: "hidden", }, scroll: { backgroundColor: "#0099CC", borderRadius: 5, maxHeight: 300, }, bottom: { position: "absolute", top: 250, alignItems: "center", width: "100%", height: 50, backgroundColor: "#007FCC88", }, box: { padding: 10, backgroundColor: "white", borderBottomLeftRadius: 5, borderBottomRightRadius: 5, }, }; return ( 列車遅延速報EX {getTime ? getTime.toLocaleTimeString("ja-JP").split(":")[0] + ":" + getTime.toLocaleTimeString("ja-JP").split(":")[1] : NaN} { LayoutAnimation.easeInEaseOut(); setLoadingDelayData(true); }} /> {loadingDelayData ? ( ) : delayData ? ( delayData.map((d, index) => { let data = d.split(" "); return ( {data[0].replace("\n", "")} {data[1]} {data[3]} ); }) ) : ( 現在、5分以上の遅れはありません。 )} 詳細を見る ); };