Merge commit '15bb692676e546e59ce418c8b7e2847ca7345ceb'

This commit is contained in:
harukin-DeskMini 2022-09-30 00:15:36 +09:00
commit 5474b3eab2
20 changed files with 3104 additions and 1294 deletions

185
App.js
View File

@ -1,57 +1,158 @@
import React, { useEffect, useRef } from 'react'; import React, { useEffect, useRef } from "react";
import { NavigationContainer } from '@react-navigation/native'; import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator,TransitionPresets ,} from '@react-navigation/stack'; import {
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; createStackNavigator,
import { AntDesign, Ionicons } from '@expo/vector-icons'; TransitionPresets,
import {ToastAndroid, Platform, UIManager,} from 'react-native'; } from "@react-navigation/stack";
import { UpdateAsync } from './UpdateAsync.js'; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import Apps from './Apps'; import { AntDesign, Ionicons } from "@expo/vector-icons";
import tndView from './ndView'; import { ToastAndroid, Platform, UIManager } from "react-native";
import trainbase from './trainbaseview'; import { UpdateAsync } from "./UpdateAsync.js";
import howto from './howto'; import Apps from "./Apps";
import menu from './menu'; import tndView from "./ndView";
import News from './components/news.js'; import trainbase from "./trainbaseview";
import TestArea from './TestArea.js'; import howto from "./howto";
import Setting from './components/settings.js'; import menu from "./menu";
import News from "./components/news.js";
import TestArea from "./TestArea.js";
import Setting from "./components/settings.js";
import trainMenu from "./components/trainMenu.js";
const Stack = createStackNavigator(); const Stack = createStackNavigator();
const Tab = createBottomTabNavigator(); const Tab = createBottomTabNavigator();
if (Platform.OS === 'android') { if (Platform.OS === "android") {
if (UIManager.setLayoutAnimationEnabledExperimental) { if (UIManager.setLayoutAnimationEnabledExperimental) {
UIManager.setLayoutAnimationEnabledExperimental(true); UIManager.setLayoutAnimationEnabledExperimental(true);
} }
} }
export default function App(){ export default function App() {
const navigationRef = useRef(); const navigationRef = useRef();
var platform = Platform.OS === "android" ? 70 : 50; var platform = Platform.OS === "android" ? 70 : 50;
useEffect(()=>UpdateAsync(),[]) useEffect(() => UpdateAsync(), []);
return( return (
<NavigationContainer name= "Root" ref={navigationRef} style={{flex:1}}> <NavigationContainer name="Root" ref={navigationRef} style={{ flex: 1 }}>
<Tab.Navigator> <Tab.Navigator>
<Stack.Screen name="login" component={top} options={{ tabBarLabel: '位置情報',headerTransparent:true,gestureEnabled:true,tabBarIcon: ({ color, size }) => (<AntDesign name="barchart" size={32} />),}}/> <Stack.Screen
<Stack.Screen name="menuPage" component={menuPage} options={{ tabBarLabel: 'リンク',headerTransparent:true,gestureEnabled:true,tabBarIcon: ({ color, size }) => (<Ionicons name="ios-radio" size={32}/>),}}/> name="login"
<Stack.Screen name="home" component={tndView} options={{ tabBarLabel: '運行情報',headerTransparent:true,gestureEnabled:true,tabBarIcon: ({ color, size }) => (<Ionicons name="md-train" size={32}/>),}}/> component={top}
options={{
</Tab.Navigator> tabBarLabel: "位置情報",
</NavigationContainer> headerTransparent: true,
gestureEnabled: true,
) tabBarIcon: ({ color, size }) => (
<AntDesign name="barchart" size={32} />
),
}}
/>
<Stack.Screen
name="menuPage"
component={menuPage}
options={{
tabBarLabel: "リンク",
headerTransparent: true,
gestureEnabled: true,
tabBarIcon: ({ color, size }) => (
<Ionicons name="ios-radio" size={32} />
),
}}
/>
<Stack.Screen
name="home"
component={tndView}
options={{
tabBarLabel: "運行情報",
headerTransparent: true,
gestureEnabled: true,
tabBarIcon: ({ color, size }) => (
<Ionicons name="md-train" size={32} />
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
} }
function top(){ function top() {
return( return (
<Stack.Navigator> <Stack.Navigator>
<Stack.Screen name="Apps" component={Apps} options={{headerShown: false,gestureEnabled:true,headerTransparent:true,}}/> <Stack.Screen
<Stack.Screen name="trainbase" component={trainbase} options={{ title: 'トレインビジョン',gestureEnabled:true,...TransitionPresets.SlideFromRightIOS}}/> name="Apps"
<Stack.Screen name="howto" component={howto} options={{ title: '使い方',gestureEnabled:true,...TransitionPresets.ModalPresentationIOS,cardOverlayEnabled:true,headerTransparent:true,headerShown:false}}/> component={Apps}
<Stack.Screen name="test" component={TestArea} options={{}}/> options={{
<Stack.Screen name="news" component={News} options={{gestureEnabled:true,...TransitionPresets.ModalPresentationIOS,cardOverlayEnabled:true,headerTransparent:true,headerShown:false}} /> headerShown: false,
gestureEnabled: true,
headerTransparent: true,
}}
/>
<Stack.Screen
name="trainbase"
component={trainbase}
options={{
title: "トレインビジョン",
gestureEnabled: true,
...TransitionPresets.SlideFromRightIOS,
}}
/>
<Stack.Screen
name="howto"
component={howto}
options={{
title: "使い方",
gestureEnabled: true,
...TransitionPresets.ModalPresentationIOS,
cardOverlayEnabled: true,
headerTransparent: true,
headerShown: false,
}}
/>
<Stack.Screen name="test" component={TestArea} options={{}} />
<Stack.Screen
name="news"
component={News}
options={{
gestureEnabled: true,
...TransitionPresets.ModalPresentationIOS,
cardOverlayEnabled: true,
headerTransparent: true,
headerShown: false,
}}
/>
<Stack.Screen
name="trainMenu"
component={trainMenu}
options={{
gestureEnabled: true,
...TransitionPresets.ModalPresentationIOS,
cardOverlayEnabled: true,
headerTransparent: true,
headerShown: false,
}}
/>
</Stack.Navigator> </Stack.Navigator>
) );
} }
function menuPage(){ function menuPage() {
return( return (
<Stack.Navigator> <Stack.Navigator>
<Stack.Screen name="menu" component={menu} options={{headerShown: false,gestureEnabled:true,headerTransparent:true,}}/> <Stack.Screen
<Stack.Screen name="setting" component={Setting} options={{gestureEnabled:true,...TransitionPresets.ModalPresentationIOS,cardOverlayEnabled:true,headerTransparent:true,headerShown:false}} /> name="menu"
component={menu}
options={{
headerShown: false,
gestureEnabled: true,
headerTransparent: true,
}}
/>
<Stack.Screen
name="setting"
component={Setting}
options={{
gestureEnabled: true,
...TransitionPresets.ModalPresentationIOS,
cardOverlayEnabled: true,
headerTransparent: true,
headerShown: false,
}}
/>
</Stack.Navigator> </Stack.Navigator>
) );
} }

168
Apps.js
View File

@ -1,5 +1,11 @@
import React, { useEffect, useRef, useState } from "react"; import React, { useEffect, useRef, useState } from "react";
import { View, Platform, ToastAndroid } from "react-native"; import {
View,
Platform,
ToastAndroid,
Text,
TouchableOpacity,
} from "react-native";
import { WebView } from "react-native-webview"; import { WebView } from "react-native-webview";
import Constants from "expo-constants"; import Constants from "expo-constants";
import AsyncStorage from "@react-native-async-storage/async-storage"; import AsyncStorage from "@react-native-async-storage/async-storage";
@ -8,8 +14,6 @@ import { news } from "./config/newsUpdate";
import StatusbarDetect from './StatusbarDetect'; import StatusbarDetect from './StatusbarDetect';
var Status = StatusbarDetect(); */ var Status = StatusbarDetect(); */
export var webview = null;
export default function Apps(props) { export default function Apps(props) {
const { const {
navigation: { navigate }, navigation: { navigate },
@ -17,13 +21,81 @@ export default function Apps(props) {
var urlcache = ""; var urlcache = "";
const webview = useRef(); const webview = useRef();
const [iconSetting, setIconSetting] = useState(undefined); const [iconSetting, setIconSetting] = useState(undefined);
const [mapSwitch, setMapSwitch] = useState(undefined);
const bootData = ` const [stationData, setStationData] = useState(undefined);
document.getElementById('header').querySelector('a').style.display = 'none'; useEffect(() => {
document.getElementById('header').style.height = '50px'; const HeaderConfig = {
document.getElementById('main').style.paddingTop = '54px'; headers: { referer: "https://train.jr-shikoku.co.jp/sp.html" },
};
document.getElementById('headerStr').style.display = 'none'; Promise.all([
fetch(
"https://train.jr-shikoku.co.jp/g?arg1=station&arg2=yosan",
HeaderConfig
).then((response) => response.json()),
fetch(
"https://train.jr-shikoku.co.jp/g?arg1=station&arg2=uwajima",
HeaderConfig
).then((response) => response.json()),
fetch(
"https://train.jr-shikoku.co.jp/g?arg1=station&arg2=uwajima2",
HeaderConfig
).then((response) => response.json()),
fetch(
"https://train.jr-shikoku.co.jp/g?arg1=station&arg2=dosan",
HeaderConfig
).then((response) => response.json()),
fetch(
"https://train.jr-shikoku.co.jp/g?arg1=station&arg2=dosan2",
HeaderConfig
).then((response) => response.json()),
fetch(
"https://train.jr-shikoku.co.jp/g?arg1=station&arg2=koutoku",
HeaderConfig
).then((response) => response.json()),
fetch(
"https://train.jr-shikoku.co.jp/g?arg1=station&arg2=tokushima",
HeaderConfig
).then((response) => response.json()),
fetch(
"https://train.jr-shikoku.co.jp/g?arg1=station&arg2=naruto",
HeaderConfig
).then((response) => response.json()),
]).then((values) => {
let stationList = {};
[
stationList.yosan,
stationList.uwajima,
stationList.uwajima2,
stationList.dosan,
stationList.dosan2,
stationList.koutoku,
stationList.tokushima,
stationList.naruto,
] = values;
setStationData(stationList);
});
}, []);
const topMenu =
mapSwitch != "true"
? `
document.getElementById('header').querySelector('a').style.display = 'none';
document.getElementById('header').style.height = '50px';
document.getElementById('main').style.paddingTop = '54px';
document.getElementById('headerStr').style.display = 'none';
`
: `
document.getElementsByClassName('accordionClass')[0].style.display = 'none';
document.getElementById('header').style.display = 'none';
document.getElementById('main').style.paddingTop = '0px';
document.getElementById('headerStr').style.display = 'none';
`;
const bootData =
topMenu +
`
const setReload = () =>{ const setReload = () =>{
try{ try{
document.getElementById('refreshIcon').click(); document.getElementById('refreshIcon').click();
@ -700,7 +772,30 @@ observer.observe(target, {
}); });
`; `;
const injectJavascriptData = bootData + trainIconMaker + textInsert; const modal_content = `
const modal_content = document.getElementById('modal_content'); // body要素を監視
const modal_observer = new MutationObserver( (mutations) => {
// observer.disconnect(); // 監視を終了
for(let d of modal_content.getElementsByTagName("button") ){
const data = d.onclick.toString().split("\\"")[1];
d.onclick = () => window.ReactNativeWebView.postMessage(data)
}
});
// 監視を開始
modal_observer.observe(modal_content, {
//attributes: true, // 属性変化の監視
//attributeOldValue: true, // 変化前の属性値を matation.oldValue に格納する
//characterData: true, // テキストノードの変化を監視
//characterDataOldValue: true, // 変化前のテキストを matation.oldValue に格納する
childList: true, // 子ノードの変化を監視
//subtree: true // 子孫ノードも監視対象に含める
});
`;
const injectJavascriptData =
bootData + modal_content + trainIconMaker + textInsert;
useEffect(() => { useEffect(() => {
AsyncStorage.getItem("status") AsyncStorage.getItem("status")
@ -729,6 +824,22 @@ observer.observe(target, {
Updates.reloadAsync() Updates.reloadAsync()
) )
); );
AsyncStorage.getItem("mapSwitch")
.then((d) => {
if (d) {
setMapSwitch(d);
} else {
AsyncStorage.setItem("mapSwitch", "false").then(() =>
Updates.reloadAsync()
);
}
})
.catch((d) =>
AsyncStorage.setItem("mapSwitch", "false").then(() =>
Updates.reloadAsync()
)
);
}, []); }, []);
return ( return (
@ -773,9 +884,46 @@ observer.observe(target, {
} }
} }
}} }}
onMessage={(event) => {}} onMessage={(event) => {
console.log(event.nativeEvent.data);
navigate("trainbase", { info: event.nativeEvent.data });
}}
injectedJavaScript={injectJavascriptData} injectedJavaScript={injectJavascriptData}
/> />
<TouchableOpacity
onPress={() => navigate("trainMenu", { webview, stationData })}
style={{
position: "absolute",
top: Platform.OS == "ios" ? Constants.statusBarHeight : 0,
left: 10,
width: 50,
height: 50,
backgroundColor: "#0099CC",
borderColor: "white",
borderStyle: "solid",
borderWidth: 1,
borderRadius: 50,
alignContent: "center",
alignSelf: "center",
alignItems: "center",
display: mapSwitch == "true" ? "flex" : "none",
}}
>
<View style={{ flex: 1 }} />
<Text
style={{
textAlign: "center",
width: "auto",
height: "auto",
textAlignVertical: "center",
fontWeight: "bold",
color: "white",
}}
>
</Text>
<View style={{ flex: 1 }} />
</TouchableOpacity>
</View> </View>
); );
} }

View File

@ -1,16 +1,10 @@
import React from 'react'; import React from "react";
import {Platform, StatusBar, View} from 'react-native'; import { Platform, StatusBar, View } from "react-native";
export default function StatusbarDetect() { export default function StatusbarDetect() {
if(Platform.OS == "ios"){ if (Platform.OS == "ios") {
return ( return <StatusBar barStyle="dark-content" />;
<StatusBar barStyle="dark-content"/> } else if (Platform.OS == "android") {
); return <View />;
} }
else if(Platform.OS == "android"){
return (
<View/>
);
}
} }

View File

@ -1,49 +1,74 @@
import React, { Component, useEffect, useState } from 'react'; import React, { Component, useEffect, useState } from "react";
import {StatusBar,View,ScrollView,Linking,Text } from 'react-native'; import { StatusBar, View, ScrollView, Linking, Text } from "react-native";
import Constants from 'expo-constants'; import Constants from "expo-constants";
import { ListItem } from 'react-native-elements'; import { ListItem } from "react-native-elements";
import Icon from 'react-native-vector-icons/Entypo'; import Icon from "react-native-vector-icons/Entypo";
import StatusbarDetect from './StatusbarDetect'; import StatusbarDetect from "./StatusbarDetect";
var Status = StatusbarDetect(); var Status = StatusbarDetect();
let a=[]; let a = [];
export default function TestArea(props) { export default function TestArea(props) {
const [data,setdata] = useState(null); const [data, setdata] = useState(null);
useEffect(()=>{ useEffect(() => {
data==null ? test().then(res=>{ data == null
//console.log(res); ? test().then((res) => {
setdata(res); //console.log(res);
}):null setdata(res);
},[data]) })
: null;
}, [data]);
return ( return (
<View style={{height:"100%",paddingTop: Constants.statusBarHeight,}}> <View style={{ height: "100%", paddingTop: Constants.statusBarHeight }}>
{Status} {Status}
<ScrollView> <ScrollView>
<Text>TEST AREA!!</Text> <Text>TEST AREA!!</Text>
{data} {data}
</ScrollView> </ScrollView>
</View> </View>
); );
} }
async function test(){ async function test() {
return fetch('https://train.jr-shikoku.co.jp/g?arg1=train&arg2=train', { return fetch("https://train.jr-shikoku.co.jp/g?arg1=train&arg2=train", {
headers: { headers: {
'authority': 'train.jr-shikoku.co.jp', authority: "train.jr-shikoku.co.jp",
'cache-control': 'no-cache', "cache-control": "no-cache",
'pragma': 'no-cache', pragma: "no-cache",
'if-modified-since': 'Thu, 01 Jun 1970 00:00:00 GMT', "if-modified-since": "Thu, 01 Jun 1970 00:00:00 GMT",
'accept': '*/*', accept: "*/*",
'sec-fetch-site': 'same-origin', "sec-fetch-site": "same-origin",
'sec-fetch-mode': 'cors', "sec-fetch-mode": "cors",
'referer': 'https://train.jr-shikoku.co.jp/sp.html' referer: "https://train.jr-shikoku.co.jp/sp.html",
} },
}).then(res=>res.json()).then(D=>{ })
let d =[]; .then((res) => res.json())
D.forEach(element => { .then((D) => {
console.log(element) let d = [];
d.push(<ListItem title={"Direction:"+element.Direction+" Index:"+element.Index+" Line:"+element.Line+" Pos:"+element.Pos+" PosNum:"+element.PosNum+" TrainNum:"+element.TrainNum+" Type:"+element.Type+" Delay:"+element.delay}/>); D.forEach((element) => {
console.log(element);
d.push(
<ListItem
title={
"Direction:" +
element.Direction +
" Index:" +
element.Index +
" Line:" +
element.Line +
" Pos:" +
element.Pos +
" PosNum:" +
element.PosNum +
" TrainNum:" +
element.TrainNum +
" Type:" +
element.Type +
" Delay:" +
element.delay
}
/>
);
});
a = d;
return d;
}); });
a=d;
return d;
});
} }

View File

@ -1,11 +1,25 @@
import { ToastAndroid, } from 'react-native'; import { ToastAndroid } from "react-native";
import * as Updates from 'expo-updates'; import * as Updates from "expo-updates";
export function UpdateAsync(){ export const UpdateAsync = () =>
Updates.checkForUpdateAsync().then(update=>{ Updates.checkForUpdateAsync()
if (update.isAvailable) { .then((update) => {
ToastAndroid.showWithGravityAndOffset('アプリのデータを更新しています。',ToastAndroid.LONG,ToastAndroid.BOTTOM,25,50,); if (!update.isAvailable) return;
Updates.fetchUpdateAsync().then(()=>Updates.reloadAsync()); ToastAndroid.showWithGravityAndOffset(
} "アプリのデータを更新しています。",
}).catch(e=>ToastAndroid.showWithGravityAndOffset(e.toString(),ToastAndroid.LONG,ToastAndroid.BOTTOM,25,50,)) ToastAndroid.LONG,
} ToastAndroid.BOTTOM,
25,
50
);
Updates.fetchUpdateAsync().then(() => Updates.reloadAsync());
})
.catch((e) =>
ToastAndroid.showWithGravityAndOffset(
e.toString(),
ToastAndroid.LONG,
ToastAndroid.BOTTOM,
25,
50
)
);

View File

@ -3,11 +3,8 @@
"name": "JR四国運行状況", "name": "JR四国運行状況",
"slug": "jrshikoku", "slug": "jrshikoku",
"privacy": "public", "privacy": "public",
"platforms": [ "platforms": ["ios", "android"],
"ios", "version": "4.4",
"android"
],
"version": "4.2",
"orientation": "portrait", "orientation": "portrait",
"icon": "./assets/icon.png", "icon": "./assets/icon.png",
"splash": { "splash": {
@ -18,19 +15,25 @@
"updates": { "updates": {
"fallbackToCacheTimeout": 0 "fallbackToCacheTimeout": 0
}, },
"assetBundlePatterns": [ "assetBundlePatterns": ["**/*"],
"**/*"
],
"ios": { "ios": {
"buildNumber": "20", "buildNumber": "22",
"supportsTablet": true, "supportsTablet": true,
"bundleIdentifier": "jrshikokuinfo.xprocess.hrkn" "bundleIdentifier": "jrshikokuinfo.xprocess.hrkn",
"config": {
"googleMapsApiKey": "AIzaSyAVGDTjBkR_0wkQiNkoo5WDLhqXCjrjk8Y"
}
}, },
"android": { "android": {
"package": "jrshikokuinfo.xprocess.hrkn", "package": "jrshikokuinfo.xprocess.hrkn",
"versionCode": 14, "versionCode": 16,
"permissions": ["ACCESS_FINE_LOCATION"], "permissions": ["ACCESS_FINE_LOCATION"],
"googleServicesFile": "./google-services.json" "googleServicesFile": "./google-services.json",
"config": {
"googleMaps": {
"apiKey": "AIzaSyAmFb-Yj033bXZWlSzNrfq_0jc1PgRrWcE"
}
}
} }
} }
} }

View File

@ -0,0 +1,80 @@
export const StationDeteilView = (props) => {
return (
<ActionSheet
ref={StationBoardAcSR}
gestureEnabled
CustomHeaderComponent={() => {}}
>
<View
style={{
backgroundColor: "white",
borderRadius: 5,
borderColor: "dark",
borderWidth: 1,
}}
>
<View style={{ height: 26, width: "100%" }}>
<View
style={{
height: 6,
width: 45,
borderRadius: 100,
backgroundColor: "#f0f0f0",
marginVertical: 10,
alignSelf: "center",
}}
/>
</View>
<ScrollView>
{currentStation && (
<Sign
currentStation={currentStation}
originalStationList={originalStationList}
oP={() => Linking.openURL(currentStation[0].StationTimeTable)}
/>
)}
{currentStation && (
<View style={{ flexDirection: "row" }}>
{!currentStation[0].JrHpUrl || (
<TicketBox
backgroundColor={"#AD7FA8"}
icon={<Foundation name="web" color="white" size={50} />}
flex={1}
onPressButton={() =>
Linking.openURL(currentStation[0].JrHpUrl)
}
>
web
</TicketBox>
)}
{!currentStation[0].StationTimeTable || (
<TicketBox
backgroundColor={"#8F5902"}
icon={<FontAwesome name="table" color="white" size={50} />}
flex={1}
onPressButton={() =>
Linking.openURL(currentStation[0].StationTimeTable)
}
>
時刻表
</TicketBox>
)}
{!currentStation[0].StationMap || (
<TicketBox
backgroundColor={"#888A85"}
icon={<Ionicons name="map" color="white" size={50} />}
flex={1}
onPressButton={() =>
Linking.openURL(currentStation[0].StationMap)
}
>
GoogleMap
</TicketBox>
)}
</View>
)}
</ScrollView>
</View>
</ActionSheet>
);
};

View File

@ -1,398 +1,586 @@
export const customTrainDataDetector = (TrainNumber) =>{ export const customTrainDataDetector = (TrainNumber) => {
switch(TrainNumber){ switch (TrainNumber) {
//しおかぜメイン //しおかぜメイン
//8000 ノーマル //8000 ノーマル
case "2M": case "2M":
case "4M": case "4M":
case "6M": case "6M":
case "14M": case "14M":
case "16M": case "16M":
case "18M": case "18M":
case "26M": case "26M":
case "28M": case "28M":
case "30M": case "30M":
case "1M": case "1M":
case "3M": case "3M":
case "5M": case "5M":
case "13M": case "13M":
case "15M": case "15M":
case "17M": case "17M":
case "25M": case "25M":
case "27M": case "27M":
case "29M": case "29M":
return {type:"LTDEXP",trainName:"しおかぜ",trainIcon:'http://www.trainfrontview.net/b/s8000nr.png',trainNumDistance:0,info:"いしづちと併結 / 8000系で運転"}; return {
//8000 アンパン type: "LTDEXP",
case "10M": trainName: "しおかぜ",
case "22M": trainIcon: "http://www.trainfrontview.net/b/s8000nr.png",
case "9M": trainNumDistance: 0,
case "21M": info: "いしづちと併結 / 8000系で運転",
return {type:"LTDEXP",trainName:"しおかぜ",trainIcon:'http://www.trainfrontview.net/f/s8000ap.png',trainNumDistance:0,info:"いしづちと併結 / アンパンマン列車で運転"}; };
//8600 //8000 アンパン
case "8M": case "10M":
case "12M": case "22M":
case "20M": case "9M":
case "24M": case "21M":
case "7M": return {
case "11M": type: "LTDEXP",
case "19M": trainName: "しおかぜ",
case "23M": trainIcon: "http://www.trainfrontview.net/f/s8000ap.png",
return {type:"LTDEXP",trainName:"しおかぜ",trainIcon:'http://www.trainfrontview.net/b/s8600.png',trainNumDistance:0,info:"いしづちと併結 / 8600系で運転"}; trainNumDistance: 0,
info: "いしづちと併結 / アンパンマン列車で運転",
};
//8600
case "8M":
case "12M":
case "20M":
case "24M":
case "7M":
case "11M":
case "19M":
case "23M":
return {
type: "LTDEXP",
trainName: "しおかぜ",
trainIcon: "http://www.trainfrontview.net/b/s8600.png",
trainNumDistance: 0,
info: "いしづちと併結 / 8600系で運転",
};
//いしづちメイン //いしづちメイン
//8000 ノーマル //8000 ノーマル
case "1004M": case "1004M":
case "1006M": case "1006M":
case "1014M": case "1014M":
case "1016M": case "1016M":
case "1018M": case "1018M":
case "1026M": case "1026M":
case "1028M": case "1028M":
case "1030M": case "1030M":
case "1001M": case "1001M":
case "1003M": case "1003M":
case "1005M": case "1005M":
case "1013M": case "1013M":
case "1015M": case "1015M":
case "1017M": case "1017M":
case "1025M": case "1025M":
case "1027M": case "1027M":
case "1029M": case "1029M":
return {type:"LTDEXP",trainName:"いしづち",trainIcon:'http://www.trainfrontview.net/b/s8000no.png',trainNumDistance:1000,info:"しおかぜと併結 / 8000系で運転"}; return {
type: "LTDEXP",
trainName: "いしづち",
trainIcon: "http://www.trainfrontview.net/b/s8000no.png",
trainNumDistance: 1000,
info: "しおかぜと併結 / 8000系で運転",
};
//8000 アンパン //8000 アンパン
case "1010M": case "1010M":
case "1022M": case "1022M":
case "1009M": case "1009M":
case "1021M": case "1021M":
return {type:"LTDEXP",trainName:"いしづち",trainIcon:'http://www.trainfrontview.net/f/s8000ap.png',trainNumDistance:1000,info:"しおかぜと併結 / アンパンマン列車で運転"}; return {
type: "LTDEXP",
trainName: "いしづち",
trainIcon: "http://www.trainfrontview.net/f/s8000ap.png",
trainNumDistance: 1000,
info: "しおかぜと併結 / アンパンマン列車で運転",
};
//8600 //8600
case "1008M": case "1008M":
case "1012M": case "1012M":
case "1020M": case "1020M":
case "1024M": case "1024M":
case "1007M": case "1007M":
case "1011M": case "1011M":
case "1019M": case "1019M":
case "1023M": case "1023M":
return {type:"LTDEXP",trainName:"いしづち",trainIcon:'http://www.trainfrontview.net/b/s8600_isz.png',trainNumDistance:1000,info:"しおかぜと併結 / 8600系で運転"}; return {
type: "LTDEXP",
trainName: "いしづち",
trainIcon: "http://www.trainfrontview.net/b/s8600_isz.png",
trainNumDistance: 1000,
info: "しおかぜと併結 / 8600系で運転",
};
//MEXP //MEXP
//8000 //8000
case "1092M": case "1092M":
return {type:"LTDEXP",trainName:"モーニングEXP高松",trainIcon:'http://www.trainfrontview.net/b/s8000no.png',trainNumDistance:null,info:"8000系で運転"}; return {
//8600 type: "LTDEXP",
case "1091M": trainName: "モーニングEXP高松",
return {type:"LTDEXP",trainName:"モーニングEXP松山",trainIcon:'http://www.trainfrontview.net/b/s8600_isz.png',trainNumDistance:null,info:"8600系で運転"}; trainIcon: "http://www.trainfrontview.net/b/s8000no.png",
//三桁いしづち trainNumDistance: null,
//8000 アンパン info: "8000系で運転",
case "1041M": };
case "1044M": //8600
return {type:"LTDEXP",trainName:"いしづち",trainIcon:'http://www.trainfrontview.net/f/s8000ap.png',trainNumDistance:940,info:"アンパンマン列車で運転"}; case "1091M":
//8600 return {
case "1043M": type: "LTDEXP",
case "1042M": trainName: "モーニングEXP松山",
case "1046M": trainIcon: "http://www.trainfrontview.net/b/s8600_isz.png",
return {type:"LTDEXP",trainName:"いしづち",trainIcon:'http://www.trainfrontview.net/b/s8600_isz.png',trainNumDistance:940,info:"8600系で運転"}; trainNumDistance: null,
info: "8600系で運転",
};
//三桁いしづち
//8000 アンパン
case "1041M":
case "1044M":
return {
type: "LTDEXP",
trainName: "いしづち",
trainIcon: "http://www.trainfrontview.net/f/s8000ap.png",
trainNumDistance: 940,
info: "アンパンマン列車で運転",
};
//8600
case "1043M":
case "1042M":
case "1046M":
return {
type: "LTDEXP",
trainName: "いしづち",
trainIcon: "http://www.trainfrontview.net/b/s8600_isz.png",
trainNumDistance: 940,
info: "8600系で運転",
};
//南風 2700ーマル //南風 2700ーマル
case "34D": case "34D":
case "38D": case "38D":
case "40D": case "40D":
case "42D": case "42D":
case "46D": case "46D":
case "50D": case "50D":
case "52D": case "52D":
case "54D": case "54D":
case "58D": case "58D":
case "31D": case "31D":
case "35D": case "35D":
case "39D": case "39D":
case "41D": case "41D":
case "43D": case "43D":
case "47D": case "47D":
case "51D": case "51D":
case "53D": case "53D":
case "55D": case "55D":
return {type:"LTDEXP",trainName:"南風",trainIcon:'http://www.trainfrontview.net/b/s2700.png',trainNumDistance:30,info:"2700系で運転"}; return {
//2700アンパン type: "LTDEXP",
case "32D": trainName: "南風",
case "36D": trainIcon: "http://www.trainfrontview.net/b/s2700.png",
case "44D": trainNumDistance: 30,
case "48D": info: "2700系で運転",
case "56D": };
case "33D": //2700アンパン
case "37D": case "32D":
case "45D": case "36D":
case "49D": case "44D":
case "57D": case "48D":
return {type:"LTDEXP",trainName:"南風",trainIcon:'http://www.trainfrontview.net/f/s2700apr.png',trainNumDistance:30,info:"アンパンマン列車で運転"}; case "56D":
break; case "33D":
case "37D":
case "45D":
case "49D":
case "57D":
return {
type: "LTDEXP",
trainName: "南風",
trainIcon: "http://www.trainfrontview.net/f/s2700apr.png",
trainNumDistance: 30,
info: "アンパンマン列車で運転",
};
break;
//うずしお
//2700
case "5006D":
case "5022D":
case "5013D":
case "5029D":
return {
type: "LTDEXP",
trainName: "うずしお",
trainIcon: "http://www.trainfrontview.net/b/s2700_uzu.png",
trainNumDistance: 5000,
info: "南風と宇多津で併結 / 高松-宇多津間進行方向逆転 / 2700系で運転",
};
case "3002D":
case "3004D":
case "3010D":
case "3012D":
case "3016D":
case "3018D":
case "3024D":
case "3028D":
case "3030D":
case "3003D":
case "3005D":
case "3007D":
case "3015D":
case "3019D":
case "3021D":
case "3025D":
case "3027D":
case "3031D":
case "3033D":
return {
type: "LTDEXP",
trainName: "うずしお",
trainIcon: "http://www.trainfrontview.net/b/s2700_uzu.png",
trainNumDistance: 3000,
info: "2700系で運転",
};
//2600
case "3008D":
case "3014D":
case "3020D":
case "3026D":
case "3001D":
case "3011D":
case "3017D":
case "3023D":
return {
type: "LTDEXP",
trainName: "うずしお",
trainIcon: "http://www.trainfrontview.net/b/s2600.png",
trainNumDistance: 3000,
info: "2600系で運転",
};
//うずしお //キハ185
//2700 case "3009D":
case "5006D": case "3032D":
case "5022D": return {
case "5013D": type: "LTDEXP",
case "5029D": trainName: "うずしお",
return {type:"LTDEXP",trainName:"うずしお",trainIcon:'http://www.trainfrontview.net/b/s2700_uzu.png',trainNumDistance:5000,info:"南風と宇多津で併結 / 高松-宇多津間進行方向逆転 / 2700系で運転"}; trainIcon: "http://www.trainfrontview.net/b/s185tu_uzu.png",
case "3002D": trainNumDistance: 3000,
case "3004D": info: "キハ185系で運転",
case "3010D": };
case "3012D":
case "3016D":
case "3018D":
case "3024D":
case "3028D":
case "3030D":
case "3003D":
case "3005D":
case "3007D":
case "3015D":
case "3019D":
case "3021D":
case "3025D":
case "3027D":
case "3031D":
case "3033D":
return {type:"LTDEXP",trainName:"うずしお",trainIcon:'http://www.trainfrontview.net/b/s2700_uzu.png',trainNumDistance:3000,info:"2700系で運転"};
//2600 //マリンライナー
case "3008D": case "3104M":
case "3014D": case "3106M":
case "3020D": case "3108M":
case "3026D": case "3110M":
case "3001D": case "3112M":
case "3011D": case "3114M":
case "3017D": case "3116M":
case "3023D": case "3118M":
return {type:"LTDEXP",trainName:"うずしお",trainIcon:'http://www.trainfrontview.net/b/s2600.png',trainNumDistance:3000,info:"2600系で運転"}; case "3120M":
case "3122M":
case "3124M":
case "3126M":
case "3128M":
case "3130M":
case "3132M":
case "3134M":
case "3136M":
case "3138M":
case "3140M":
case "3142M":
case "3144M":
case "3146M":
case "3148M":
case "3150M":
case "3152M":
case "3154M":
case "3156M":
case "3158M":
case "3160M":
case "3162M":
case "3164M":
case "3166M":
case "3168M":
case "3170M":
case "3105M":
case "3107M":
case "3109M":
case "3111M":
case "3113M":
case "3115M":
case "3117M":
case "3119M":
case "3121M":
case "3123M":
case "3125M":
case "3127M":
case "3129M":
case "3131M":
case "3133M":
case "3135M":
case "3137M":
case "3139M":
case "3141M":
case "3143M":
case "3145M":
case "3147M":
case "3149M":
case "3151M":
case "3153M":
case "3155M":
case "3157M":
case "3159M":
case "3161M":
case "3163M":
case "3165M":
case "3167M":
case "3169M":
case "3175M":
return {
type: "Rapid",
trainName: "マリンライナー",
trainIcon: "http://www.trainfrontview.net/b/s5001.png",
trainNumDistance: 3100,
info: "",
};
case "3102M":
case "3101M":
case "3103M":
case "3171M":
case "3173M":
return {
type: "Rapid",
trainName: "マリンライナー",
trainIcon: "http://www.trainfrontview.net/b/s5001k.png",
trainNumDistance: 3100,
info: "",
};
//キハ185 //サンライズ瀬戸
case "3009D": case "5032M":
case "3032D": case "5031M":
return {type:"LTDEXP",trainName:"うずしお",trainIcon:'http://www.trainfrontview.net/b/s185tu_uzu.png',trainNumDistance:3000,info:"キハ185系で運転"}; return {
type: "NightLTDEXP",
trainName: "サンライズ瀬戸",
trainIcon: "http://www.trainfrontview.net/b/w285.png",
trainNumDistance: null,
info: "",
};
case "8041M": //琴平延長高松迄
case "8031M": //琴平延長高松以降
return {
type: "NightLTDEXP",
trainName: "サンライズ瀬戸",
trainIcon: "http://www.trainfrontview.net/b/w285.png",
trainNumDistance: null,
info: "琴平延長運転日",
};
//マリンライナー //宇和海
case "3104M": //2000 ノーマル
case "3106M": case "1052D":
case "3108M": case "1056D":
case "3110M": case "1058D":
case "3112M": case "1064D":
case "3114M": case "1070D":
case "3116M": case "1074D":
case "3118M": case "1076D":
case "3120M": case "1078D":
case "3122M": case "1080D":
case "3124M": case "1082D":
case "3126M": case "1051D":
case "3128M": case "1059D":
case "3130M": case "1065D":
case "3132M": case "1069D":
case "3134M": case "1071D":
case "3136M": case "1073D":
case "3138M": case "1075D":
case "3140M": case "1077D":
case "3142M": case "1079D":
case "3144M": case "1053D":
case "3146M": return {
case "3148M": type: "LTDEXP",
case "3150M": trainName: "宇和海",
case "3152M": trainIcon: "http://www.trainfrontview.net/b/s2000_uwa.png",
case "3154M": trainNumDistance: 1050,
case "3156M": info: "2000系で運転",
case "3158M": };
case "3160M": //2000 アンパン込み
case "3162M": case "1054D":
case "3164M": case "1060D":
case "3166M": case "1062D":
case "3168M": case "1066D":
case "3170M": case "1068D":
case "3105M": case "1072D":
case "3107M": case "1055D":
case "3109M": case "1057D":
case "3111M": case "1061D":
case "3113M": case "1063D":
case "3115M": case "1067D":
case "3117M": case "1081D":
case "3119M": return {
case "3121M": type: "LTDEXP",
case "3123M": trainName: "宇和海",
case "3125M": trainIcon: "http://www.trainfrontview.net/f/s2002a.png",
case "3127M": trainNumDistance: 1050,
case "3129M": info: "アンパン列車で運転",
case "3131M": };
case "3133M": //しまんと
case "3135M": case "2002D":
case "3137M": case "2004D":
case "3139M": case "2006D":
case "3141M": case "2008D":
case "3143M": case "2001D":
case "3145M": case "2003D":
case "3147M": case "2005D":
case "3149M": case "2007D":
case "3151M": return {
case "3153M": type: "LTDEXP",
case "3155M": trainName: "しまんと",
case "3157M": trainIcon: "http://www.trainfrontview.net/b/s2700_smn.png",
case "3159M": trainNumDistance: 2000,
case "3161M": info: "2700系で運転",
case "3163M": };
case "3165M":
case "3167M":
case "3169M":
case "3175M":
return {type:"Rapid",trainName:"マリンライナー",trainIcon:'http://www.trainfrontview.net/b/s5001.png',trainNumDistance:3100,info:""};
case "3102M":
case "3101M":
case "3103M":
case "3171M":
case "3173M":
return {type:"Rapid",trainName:"マリンライナー",trainIcon:'http://www.trainfrontview.net/b/s5001k.png',trainNumDistance:3100,info:""};
//サンライズ瀬戸 //あしずり 2000
case "5032M": case "2074D":
case "5031M": case "2076D":
return {type:"NightLTDEXP",trainName:"サンライズ瀬戸",trainIcon:'http://www.trainfrontview.net/b/w285.png',trainNumDistance:null,info:""}; case "2080D":
case "8041M": //琴平延長高松迄 case "2084D":
case "8031M": //琴平延長高松以降 case "2086D":
return {type:"NightLTDEXP",trainName:"サンライズ瀬戸",trainIcon:'http://www.trainfrontview.net/b/w285.png',trainNumDistance:null,info:"琴平延長運転日"}; case "2071D":
case "2075D":
case "2077D":
case "2081D":
case "2083D":
return {
type: "LTDEXP",
trainName: "あしずり",
trainIcon: "http://www.trainfrontview.net/b/s2000_asi.png",
trainNumDistance: 2070,
info: "2000系で運転",
};
//宇和海 //あしずり 2700
//2000 ノーマル case "2078D":
case "1052D": case "2082D":
case "1056D": case "2088D":
case "1058D": case "2073D":
case "1064D": case "2079D":
case "1070D": case "2085D":
case "1074D": case "2072D":
case "1076D": return {
case "1078D": type: "LTDEXP",
case "1080D": trainName: "あしずり",
case "1082D": trainIcon: "http://www.trainfrontview.net/b/s2700_asi.png",
case "1051D": trainNumDistance: 2070,
case "1059D": info: "2700系で運転",
case "1065D": };
case "1069D":
case "1071D":
case "1073D":
case "1075D":
case "1077D":
case "1079D":
case "1053D":
return {type:"LTDEXP",trainName:"宇和海",trainIcon:'http://www.trainfrontview.net/b/s2000_uwa.png',trainNumDistance:1050,info:"2000系で運転"};
//2000 アンパン込み
case "1054D":
case "1060D":
case "1062D":
case "1066D":
case "1068D":
case "1072D":
case "1055D":
case "1057D":
case "1061D":
case "1063D":
case "1067D":
case "1081D":
return {type:"LTDEXP",trainName:"宇和海",trainIcon:'http://www.trainfrontview.net/f/s2002a.png',trainNumDistance:1050,info:"アンパン列車で運転"};
//しまんと
case "2002D":
case "2004D":
case "2006D":
case "2008D":
case "2001D":
case "2003D":
case "2005D":
case "2007D":
return {type:"LTDEXP",trainName:"しまんと",trainIcon:'http://www.trainfrontview.net/b/s2700_smn.png',trainNumDistance:2000,info:"2700系で運転"};
//あしずり 2000 //剣山
case "2074D": case "4002D":
case "2076D": case "4004D":
case "2080D": case "4006D":
case "2084D": case "4008D":
case "2086D": case "4010D":
case "2071D": case "4001D":
case "2075D": case "4003D":
case "2077D": case "4005D":
case "2081D": case "4007D":
case "2083D": case "4009D":
return {type:"LTDEXP",trainName:"あしずり",trainIcon:'http://www.trainfrontview.net/b/s2000_asi.png',trainNumDistance:2070,info:"2000系で運転"}; case "4011D":
return {
type: "LTDEXP",
trainName: "剣山",
trainIcon: "http://www.trainfrontview.net/b/s185tu.png",
trainNumDistance: 4000,
info: "キハ185系で運転",
};
//むろと
case "5051D":
case "5052D":
return {
type: "LTDEXP",
trainName: "むろと",
trainIcon: "http://www.trainfrontview.net/b/s185_mrt.png",
trainNumDistance: 5050,
info: "キハ185系で運転",
};
//あしずり 2700 //よしのがわトロッコ
case "2078D": case "8452D":
case "2082D": case "8451D":
case "2088D": return {
case "2073D": type: "LTDEXP",
case "2079D": trainName: "よしのがわトロッコ",
case "2085D": trainIcon: "http://www.trainfrontview.net/f/s185to_ai.png",
case "2072D": trainNumDistance: null,
return {type:"LTDEXP",trainName:"あしずり",trainIcon:'http://www.trainfrontview.net/b/s2700_asi.png',trainNumDistance:2070,info:"2700系で運転"}; info: "",
};
//剣山 //岡山高松アントロ
case "4002D": case "8176D":
case "4004D": case "8179D":
case "4006D": //岡山琴平アントロ
case "4008D": case "8277D":
case "4010D": case "8278D":
case "4001D": return {
case "4003D": type: "LTDEXP",
case "4005D": trainName: "アンパンマントロッコ",
case "4007D": trainIcon: "http://www.trainfrontview.net/f/s32to4.png",
case "4009D": trainNumDistance: null,
case "4011D": info: "",
return {type:"LTDEXP",trainName:"剣山",trainIcon:'http://www.trainfrontview.net/b/s185tu.png',trainNumDistance:4000,info:"キハ185系で運転"}; };
//むろと //伊予灘ものがたり
case "5051D": case "8901D":
case "5052D": case "8903D":
return {type:"LTDEXP",trainName:"むろと",trainIcon:'http://www.trainfrontview.net/b/s185_mrt.png',trainNumDistance:5050,info:"キハ185系で運転"}; case "8902D":
case "8904D":
return {
type: "LTDEXP",
trainName: "伊予灘ものがたり",
trainIcon: "http://www.trainfrontview.net/b/s185iyoy.png",
trainNumDistance: null,
info: "",
};
//千年ものがたり
case "8011D":
case "8012D":
return {
type: "LTDEXP",
trainName: "四国まんなか千年ものがたり",
trainIcon: "http://www.trainfrontview.net/b/s185mm1.png",
trainNumDistance: null,
info: "",
};
//夜明けものがたり
case "8053D":
case "8054D":
case "8062D":
case "8063D":
return {
type: "LTDEXP",
trainName: "時代の夜明けのものがたり",
trainIcon: "http://www.trainfrontview.net/b/s185ym1.png",
trainNumDistance: null,
info: "",
};
//よしのがわトロッコ default:
case "8452D": return {
case "8451D": type: "Normal",
return {type:"LTDEXP",trainName:"よしのがわトロッコ",trainIcon:'http://www.trainfrontview.net/f/s185to_ai.png',trainNumDistance:null,info:""}; trainName: "",
trainIcon: null,
trainNumDistance: null,
//岡山高松アントロ info: null,
case "8176D": };
case "8179D": break;
//岡山琴平アントロ }
case "8277D": };
case "8278D":
return {type:"LTDEXP",trainName:"アンパンマントロッコ",trainIcon:'http://www.trainfrontview.net/f/s32to4.png',trainNumDistance:null,info:""};
//伊予灘ものがたり
case "8901D":
case "8903D":
case "8902D":
case "8904D":
return {type:"LTDEXP",trainName:"伊予灘ものがたり",trainIcon:'http://www.trainfrontview.net/b/s185iyoy.png',trainNumDistance:null,info:""};
//千年ものがたり
case "8011D":
case "8012D":
return {type:"LTDEXP",trainName:"四国まんなか千年ものがたり",trainIcon:'http://www.trainfrontview.net/b/s185mm1.png',trainNumDistance:null,info:""};
//夜明けものがたり
case "8053D":
case "8054D":
case "8062D":
case "8063D":
return {type:"LTDEXP",trainName:"時代の夜明けのものがたり",trainIcon:'http://www.trainfrontview.net/b/s185ym1.png',trainNumDistance:null,info:""};
default:
return {type:"Normal",trainName:"",trainIcon:null,trainNumDistance:null,info:null};
break;
}
}

View File

@ -1,52 +1,136 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from "react";
import {View,Text,TouchableOpacity } from 'react-native'; import { View, Text, TouchableOpacity } from "react-native";
import * as Updates from 'expo-updates'; import * as Updates from "expo-updates";
import StatusbarDetect from '../StatusbarDetect'; import StatusbarDetect from "../StatusbarDetect";
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from "@react-native-async-storage/async-storage";
var Status = StatusbarDetect(); var Status = StatusbarDetect();
import { Switch } from 'react-native-elements'; import { Switch } from "react-native-elements";
export default function Setting(props){ export default function Setting(props) {
const { navigation: { navigate } } = props; const {
const [iconSetting, setIconSetting] = useState(undefined) navigation: { navigate },
useEffect(()=>{ } = props;
AsyncStorage.getItem("iconSwitch").then( d =>{ const [iconSetting, setIconSetting] = useState(undefined);
setIconSetting(d) const [mapSwitch, setMapSwitch] = useState(undefined);
}) useEffect(() => {
},[]) AsyncStorage.getItem("iconSwitch").then((d) => {
console.log(iconSetting); setIconSetting(d);
return( });
<View style={{height:"100%",backgroundColor:"#0099CC"}}> AsyncStorage.getItem("mapSwitch").then((d) => {
<View style={{flex:1,backgroundColor:"white"}}> setMapSwitch(d);
<View style={{backgroundColor:"#0099CC"}}> });
<Text style={{fontSize:30,fontWeight:"bold",textAlign:"center",color:"white",padding:10}}>設定画面</Text> }, []);
</View> console.log(iconSetting);
<View style={{flex:1}} > return (
<View style={{flexDirection:"row",padding:10}}> <View style={{ height: "100%", backgroundColor: "#0099CC" }}>
<Text style={{fontSize:25,alignItems:"center",alignContent:"center",textAlign:"center",textAlignVertical:"center"}}>列車アイコンを表示する</Text> <View style={{ flex: 1, backgroundColor: "white" }}>
<View style={{flex:1}} /> <View style={{ backgroundColor: "#0099CC" }}>
<Switch value={iconSetting == "true" ? true : false} color={iconSetting == "true" ? "red": null} onValueChange={(value)=>setIconSetting(value.toString())}/> <Text
</View> style={{
<View style={{flexDirection:"row",padding:10}}> fontSize: 30,
<Text style={{fontSize:25,alignItems:"center",alignContent:"center",textAlign:"center",textAlignVertical:"center"}}>channel: {Updates.channel}</Text> fontWeight: "bold",
<View style={{flex:1}} /> textAlign: "center",
</View> color: "white",
<View style={{flexDirection:"row",padding:10}}> padding: 10,
<Text style={{fontSize:25,alignItems:"center",alignContent:"center",textAlign:"center",textAlignVertical:"center"}}>releaseChannel: {Updates.releaseChannel}</Text> }}
<View style={{flex:1}} /> >
</View> 設定画面
</Text>
</View>
</View>
<TouchableOpacity style={{padding:10,flexDirection:"row",borderColor:"white",borderWidth:1,margin:10,borderRadius:5,alignItems:"center"}} onPress={()=>{
AsyncStorage.setItem("iconSwitch",iconSetting.toString()).then(()=>{
Updates.reloadAsync()
})
}}>
<View style={{flex:1}} />
<Text style={{fontSize:25,fontWeight:"bold",color:"white"}}>設定を保存して再読み込み</Text>
<View style={{flex:1}} />
</TouchableOpacity>
</View> </View>
) <View style={{ flex: 1 }}>
<View style={{ flexDirection: "row", padding: 10 }}>
<Text
style={{
fontSize: 25,
alignItems: "center",
alignContent: "center",
textAlign: "center",
textAlignVertical: "center",
}}
>
列車アイコンを表示する
</Text>
<View style={{ flex: 1 }} />
<Switch
value={iconSetting == "true" ? true : false}
color={iconSetting == "true" ? "red" : null}
onValueChange={(value) => setIconSetting(value.toString())}
/>
</View>
<View style={{ flexDirection: "row", padding: 10 }}>
<Text
style={{
fontSize: 25,
alignItems: "center",
alignContent: "center",
textAlign: "center",
textAlignVertical: "center",
}}
>
マップを表示する(beta)
</Text>
<View style={{ flex: 1 }} />
<Switch
value={mapSwitch == "true" ? true : false}
color={mapSwitch == "true" ? "red" : null}
onValueChange={(value) => setMapSwitch(value.toString())}
/>
</View>
<View style={{ flexDirection: "row", padding: 10 }}>
<Text
style={{
fontSize: 25,
alignItems: "center",
alignContent: "center",
textAlign: "center",
textAlignVertical: "center",
}}
>
内部バージョン: 4.4
</Text>
<View style={{ flex: 1 }} />
</View>
<View style={{ flexDirection: "row", padding: 10 }}>
<Text
style={{
fontSize: 25,
alignItems: "center",
alignContent: "center",
textAlign: "center",
textAlignVertical: "center",
}}
>
releaseChannel: {Updates.releaseChannel}
</Text>
<View style={{ flex: 1 }} />
</View>
</View>
</View>
<TouchableOpacity
style={{
padding: 10,
flexDirection: "row",
borderColor: "white",
borderWidth: 1,
margin: 10,
borderRadius: 5,
alignItems: "center",
}}
onPress={() => {
Promise.all([
AsyncStorage.setItem("iconSwitch", iconSetting.toString()),
AsyncStorage.setItem("mapSwitch", mapSwitch.toString()),
]).then(() => {
Updates.reloadAsync();
});
}}
>
<View style={{ flex: 1 }} />
<Text style={{ fontSize: 25, fontWeight: "bold", color: "white" }}>
設定を保存して再読み込み
</Text>
<View style={{ flex: 1 }} />
</TouchableOpacity>
</View>
);
} }

145
components/trainMenu.js Normal file
View File

@ -0,0 +1,145 @@
import React, { useState, useEffect, useRef } from "react";
import { View, Text, TouchableOpacity, Linking } from "react-native";
import { WebView } from "react-native-webview";
import StatusbarDetect from "../StatusbarDetect";
import AsyncStorage from "@react-native-async-storage/async-storage";
import MapView, { Marker, Geojson, PROVIDER_GOOGLE } from "react-native-maps";
import {
FontAwesome,
Fontisto,
Foundation,
Ionicons,
MaterialCommunityIcons,
} from "@expo/vector-icons";
var Status = StatusbarDetect();
export default function trainMenu({
route: {
params: { webview, stationData },
},
navigation: { navigate },
}) {
const mapRef = useRef();
return (
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
<MapView
style={{ flex: 1, width: "100%", height: "100%" }}
showsUserLocation={true}
loadingEnabled={true}
showsMyLocationButton={false}
moveOnMarkerPress={false}
showsCompass={false}
ref={mapRef}
//provider={PROVIDER_GOOGLE}
initialRegion={{
latitude: 33.774519,
longitude: 133.533306,
latitudeDelta: 1.8, //小さくなるほどズーム
longitudeDelta: 1.8,
}}
>
{stationData &&
Object.keys(stationData).map((d) =>
stationData[d].map((D, index) => {
if (!D.StationMap) return null;
const latlng = D.StationMap.replace(
"https://www.google.co.jp/maps/place/",
""
).split(",");
if (latlng.length == 0) return null;
return (
<Marker
key={index}
coordinate={{
latitude: parseFloat(latlng[0]),
longitude: parseFloat(latlng[1]),
}}
onPress={() => {
webview.current?.injectJavaScript(
`MoveDisplayStation('${d}_${D.MyStation}_${D.Station_JP}')`
);
navigate("Apps");
}}
></Marker>
);
})
)}
</MapView>
<View style={{ flexDirection: "row" }}>
<UsefulBox
backgroundColor={"#F89038"}
icon="train-car"
flex={1}
onPressButton={() => navigate("howto")}
>
使い方
</UsefulBox>
<UsefulBox
backgroundColor={"#EA4752"}
icon="star"
flex={1}
onPressButton={() =>
/* Linking.openURL(
"https://www.jr-shikoku.co.jp/01_trainbus/jikoku/sp/#mainprice-box"
) */
alert("お気に入り駅登録機能は現在開発中です!レイアウト募集中!")
}
>
お気に入り
</UsefulBox>
<UsefulBox
backgroundColor={"#91C31F"}
icon="clipboard-list-outline"
flex={1}
onPressButton={() =>
Linking.openURL(
"https://nexcloud.haruk.in/apps/forms/ZRHjWFF7znr5Xjr2"
)
}
>
この機能のフィードバック
</UsefulBox>
</View>
<TouchableOpacity
style={{
padding: 10,
flexDirection: "row",
borderColor: "white",
borderWidth: 1,
margin: 10,
borderRadius: 5,
alignItems: "center",
}}
onPress={() => {
AsyncStorage.setItem("status", "2022/04/14");
navigate("Apps");
}}
>
<View style={{ flex: 1 }} />
<Text style={{ fontSize: 25, fontWeight: "bold", color: "white" }}>
閉じる
</Text>
<View style={{ flex: 1 }} />
</TouchableOpacity>
</View>
);
}
const UsefulBox = (props) => {
const { icon, backgroundColor, flex, onPressButton, children } = props;
return (
<TouchableOpacity
style={{
flex: flex,
backgroundColor: backgroundColor,
padding: 10,
alignItems: "center",
margin: 2,
}}
onPress={onPressButton}
>
<MaterialCommunityIcons name={icon} color="white" size={50} />
<Text style={{ color: "white", fontWeight: "bold", fontSize: 18 }}>
{children}
</Text>
</TouchableOpacity>
);
};

View File

@ -1,8 +1,19 @@
import React, { Component, useRef, useState, useEffect } from 'react'; import React, { Component, useRef, useState, useEffect } from "react";
import {StatusBar,View,LayoutAnimation,ScrollView,Linking,Text,TouchableOpacity } from 'react-native'; import {
import { Switch } from 'react-native-elements'; StatusBar,
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen'; View,
import { customTrainDataDetector } from '../custom-train-data'; LayoutAnimation,
ScrollView,
Linking,
Text,
TouchableOpacity,
} from "react-native";
import { Switch } from "react-native-elements";
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
} from "react-native-responsive-screen";
import { customTrainDataDetector } from "../custom-train-data";
let diagramData = undefined; let diagramData = undefined;
@ -35,222 +46,362 @@ let diagramData = undefined;
* 9031M サンライズ瀬戸琴平(延長)(臨時) * 9031M サンライズ瀬戸琴平(延長)(臨時)
* 9062D 四国まんなか千年ものがたり(臨時) * 9062D 四国まんなか千年ものがたり(臨時)
*/ */
export default function LED_vision(props){ export default function LED_vision(props) {
const HeaderConfig = { const HeaderConfig = {
headers:{ headers: {
'referer': 'https://train.jr-shikoku.co.jp/sp.html' referer: "https://train.jr-shikoku.co.jp/sp.html",
} },
} };
const [trainDiagram,setTrainDiagram] = useState(null); const [trainDiagram, setTrainDiagram] = useState(null);
const [stationDiagram,setStationDiagram] = useState(null); const [stationDiagram, setStationDiagram] = useState(null);
const [currentTrain, setCurrentTrain] = useState(null); const [currentTrain, setCurrentTrain] = useState(null);
const [finalSwitch, setFinalSwitch] = useState(false); const [finalSwitch, setFinalSwitch] = useState(false);
const [trainIDSwitch, setTrainIDSwitch] = useState(false); const [trainIDSwitch, setTrainIDSwitch] = useState(false);
const [trainDescriptionSwitch, setTrainDescriptionSwitch] = useState(false); const [trainDescriptionSwitch, setTrainDescriptionSwitch] = useState(false);
useEffect(()=>{ useEffect(() => {
fetch('https://train.jr-shikoku.co.jp/g?arg1=station&arg2=traintimeinfo&arg3=dia', HeaderConfig).then(response => response.text()).then(d=>{ fetch(
const val = d.replace("[\r\n","").split(',\r\n'); "https://train.jr-shikoku.co.jp/g?arg1=station&arg2=traintimeinfo&arg3=dia",
let returnData = {}; HeaderConfig
val.forEach(element =>{
try{
let data = JSON.parse(element);
Object.keys(data).forEach( key => returnData[key] = data[key] );
}catch(e){
}
})
return(returnData);
}).then((trainDiagram)=>{
let returnData = {};
if(trainDiagram){
Object.keys(trainDiagram).forEach( key => {
if(trainDiagram[key].match(props.station.Station_JP) ){
returnData[key] = trainDiagram[key];
}
});
}
setTrainDiagram(trainDiagram);
setStationDiagram(returnData);
})
},[]);
const getTime = ()=>{
const returnData = [];
const date = new Date();
Object.keys(stationDiagram).forEach((d)=>{
let a = (() =>{
let returnData = {};
stationDiagram[d].split("#").forEach((data)=>{
if(data.match("着")){
returnData.lastStation = data.split(",着,")[0];
}
if(data.match(props.station.Station_JP)){
if(data.match(",発,")){
returnData.time = data.split(",発,")[1];
}
else{
returnData.time = data.split(",着,")[1];
returnData.lastStation = "当駅止"
}
}
})
return returnData;
})();
returnData.push({train:d,time:a.time,lastStation:a.lastStation});
})
return (returnData.sort((a,b)=> {
if(parseInt(a.time.split(":")[0]) < parseInt(b.time.split(":")[0])){
return -1;
}
else if(parseInt(a.time.split(":")[0]) > parseInt(b.time.split(":")[0])){
return 1;
}
else if(parseInt(a.time.split(":")[1]) < parseInt(b.time.split(":")[1])){
return -1;
}
else if(parseInt(a.time.split(":")[1]) > parseInt(b.time.split(":")[1])){
return 1;
}
}))
};
const trainTimeAndNumber = stationDiagram != null ? getTime() : null;
useEffect(()=>{
const getCurrentTrain = () =>fetch("https://train.jr-shikoku.co.jp/g?arg1=train&arg2=train", HeaderConfig).then(response => response.json()).then(d=>d.map(x=>({num:x.TrainNum,delay:x.delay}))).then(d=>setCurrentTrain(d));
getCurrentTrain();
const currentTrainInterval = setInterval(()=>getCurrentTrain(),15000)
return ()=>clearInterval(currentTrainInterval);
},[])
const filtering = d => currentTrain.map(m=>m.num).includes(d.train)
console.log(new Date())
const timeFiltering = d => {
const date = new Date();
const newDate = new Date();
let data = d.time.split(":");
let delay = isNaN(currentTrain.filter(data =>data.num == d.train)[0].delay) ? 0 : currentTrain.filter(data =>data.num == d.train)[0].delay;
date.setHours(parseInt(data[0]));
date.setMinutes(parseInt(data[1])+parseInt(delay));
console.log(date);
console.log(newDate)
if(!(newDate > date)){
return true;
}
return false;
}
const finalFiltering = d =>{
if(finalSwitch){
return true;
}
else{
if(d.lastStation == "当駅止"){
return false;
}
return true;
}
}
return(
<View style={{ width: wp("98%"),/* height: wp("98%")/10*9, */backgroundColor:"#432",borderWidth:1,margin:10,marginHorizontal:wp("1%")}} >
<View style={{alignContent:"center",alignItems:"center",width:"100%",marginVertical:10,flexDirection:"row"}}>
<View style={{flex:1}}>
</View>
<View style={{}}>
<Text style={{fontSize:25,color:"white",fontWeight:"bold"}}>次の列車</Text>
<Text style={{fontSize:15,color:"white"}}>Next Train</Text>
</View>
<View style={{flex:1}}>
</View>
</View>
{trainTimeAndNumber ? currentTrain && trainTimeAndNumber.filter(filtering).filter(timeFiltering).filter(finalFiltering).map((d,index)=>
[<View style={{alignContent:"center",alignItems:"center",width:"94%",marginVertical:5,marginHorizontal:"3%",backgroundColor:"#000",flexDirection:"row"}}>
<View style={{flex:9}}>
<Text style={{fontSize:(()=>{
if(customTrainDataDetector(d.train).trainName.length > 6){
return 15;
}
else{
return 20
}
})(),color:(()=>{
switch(customTrainDataDetector(d.train).type){
case "Rapid":
return "aqua";
case "LTDEXP":
return "red";
case "NightLTDEXP":
return "red";
case "Normal":
return "white";
}
})(),fontWeight:"bold"}}>{trainIDSwitch ? d.train : (()=>{
switch(customTrainDataDetector(d.train).type){
case "Rapid":
return "快速";
case "LTDEXP":
return "特急";
case "NightLTDEXP":
return "寝台特急";
case "Normal":
return "普通列車";
}
})()+" "+customTrainDataDetector(d.train).trainName+(()=>{
if(customTrainDataDetector(d.train).trainNumDistance != null){
return parseInt(d.train.replace("M","").replace("D","")) - customTrainDataDetector(d.train).trainNumDistance + "号";
}
else{
return "";
}
})()}</Text>
</View>
<View style={{flex:4,flexDirection:"row"}}>
<Text style={{fontSize: d.lastStation.length > 4 ? 15 : 20,color:"white",fontWeight:"bold"}}>{d.lastStation}</Text>
</View>
<View style={{flex:3}}>
<Text style={{fontSize:20,color:"white",fontWeight:"bold"}}>{d.time}</Text>
</View>
<View style={{flex:4}}>
<Text style={{fontSize:20,color:"white",fontWeight:"bold"}}>{(()=>{
let data= currentTrain.filter(data=>data.num==d.train)[0].delay;
if(isNaN(data)){
return data;
}
else if(data == 0){
return "定刻通り"
}
else{
return data+"分遅れ"
}
})()}</Text>
</View>
</View>,Boolean(trainDescriptionSwitch) && Boolean(customTrainDataDetector(d.train).info) &&
<View style={{alignContent:"center",alignItems:"center",width:"94%",marginVertical:5,marginHorizontal:"3%",backgroundColor:"#000",flexDirection:"row"}}>
<View style={{flex:4}}>
<Text style={{fontSize:20,color:"green",fontWeight:"bold"}}> &gt; {customTrainDataDetector(d.train).info}</Text>
</View>
</View>
]
)
: null}
<View style={{flexDirection:"row",padding:10}}>
<Text style={{alignItems:"center",alignContent:"center",textAlign:"center",textAlignVertical:"center",color:"white"}}>種別名 / 列番</Text>
<Switch value={trainIDSwitch} onValueChange={(value)=>setTrainIDSwitch(!trainIDSwitch)}/>
<View style={{flex:1}} />
<Text style={{alignItems:"center",alignContent:"center",textAlign:"center",textAlignVertical:"center",color:"white"}}>列車情報</Text>
<Switch value={trainDescriptionSwitch} onValueChange={(value)=>setTrainDescriptionSwitch(!trainDescriptionSwitch)}/>
<View style={{flex:1}} />
<Text style={{alignItems:"center",alignContent:"center",textAlign:"center",textAlignVertical:"center",color:"white"}}>当駅止表示</Text>
<Switch value={finalSwitch} onValueChange={(value)=>setFinalSwitch(!finalSwitch)}/>
</View>
</View>
) )
.then((response) => response.text())
.then((d) => {
const val = d.replace("[\r\n", "").split(",\r\n");
let returnData = {};
val.forEach((element) => {
try {
let data = JSON.parse(element);
Object.keys(data).forEach((key) => (returnData[key] = data[key]));
} catch (e) {}
});
return returnData;
})
.then((trainDiagram) => {
let returnData = {};
if (trainDiagram) {
Object.keys(trainDiagram).forEach((key) => {
if (trainDiagram[key].match(props.station.Station_JP)) {
returnData[key] = trainDiagram[key];
}
});
}
setTrainDiagram(trainDiagram);
setStationDiagram(returnData);
});
}, []);
const getTime = () => {
const returnData = [];
const date = new Date();
Object.keys(stationDiagram).forEach((d) => {
let a = (() => {
let returnData = {};
stationDiagram[d].split("#").forEach((data) => {
if (data.match("着")) {
returnData.lastStation = data.split(",着,")[0];
}
if (data.match(props.station.Station_JP)) {
if (data.match(",発,")) {
returnData.time = data.split(",発,")[1];
} else {
returnData.time = data.split(",着,")[1];
returnData.lastStation = "当駅止";
}
}
});
return returnData;
})();
returnData.push({ train: d, time: a.time, lastStation: a.lastStation });
});
return returnData.sort((a, b) => {
if (parseInt(a.time.split(":")[0]) < parseInt(b.time.split(":")[0])) {
return -1;
} else if (
parseInt(a.time.split(":")[0]) > parseInt(b.time.split(":")[0])
) {
return 1;
} else if (
parseInt(a.time.split(":")[1]) < parseInt(b.time.split(":")[1])
) {
return -1;
} else if (
parseInt(a.time.split(":")[1]) > parseInt(b.time.split(":")[1])
) {
return 1;
}
});
};
const trainTimeAndNumber = stationDiagram != null ? getTime() : null;
useEffect(() => {
const getCurrentTrain = () =>
fetch(
"https://train.jr-shikoku.co.jp/g?arg1=train&arg2=train",
HeaderConfig
)
.then((response) => response.json())
.then((d) => d.map((x) => ({ num: x.TrainNum, delay: x.delay })))
.then((d) => setCurrentTrain(d));
getCurrentTrain();
const currentTrainInterval = setInterval(() => getCurrentTrain(), 15000);
return () => clearInterval(currentTrainInterval);
}, []);
const filtering = (d) => currentTrain.map((m) => m.num).includes(d.train);
console.log(new Date());
const timeFiltering = (d) => {
const date = new Date();
const newDate = new Date();
let data = d.time.split(":");
let delay = isNaN(
currentTrain.filter((data) => data.num == d.train)[0].delay
)
? 0
: currentTrain.filter((data) => data.num == d.train)[0].delay;
date.setHours(parseInt(data[0]));
date.setMinutes(parseInt(data[1]) + parseInt(delay));
console.log(date);
console.log(newDate);
if (!(newDate > date)) {
return true;
}
return false;
};
const finalFiltering = (d) => {
if (finalSwitch) {
return true;
} else {
if (d.lastStation == "当駅止") {
return false;
}
return true;
}
};
return (
<View
style={{
width: wp("98%"),
/* height: wp("98%")/10*9, */ backgroundColor: "#432",
borderWidth: 1,
margin: 10,
marginHorizontal: wp("1%"),
}}
>
<View
style={{
alignContent: "center",
alignItems: "center",
width: "100%",
marginVertical: 10,
flexDirection: "row",
}}
>
<View style={{ flex: 1 }}></View>
<View style={{}}>
<Text style={{ fontSize: 25, color: "white", fontWeight: "bold" }}>
次の列車
</Text>
<Text style={{ fontSize: 15, color: "white" }}>Next Train</Text>
</View>
<View style={{ flex: 1 }}></View>
</View>
{trainTimeAndNumber
? currentTrain &&
trainTimeAndNumber
.filter(filtering)
.filter(timeFiltering)
.filter(finalFiltering)
.map((d, index) => [
<View
style={{
alignContent: "center",
alignItems: "center",
width: "94%",
marginVertical: 5,
marginHorizontal: "3%",
backgroundColor: "#000",
flexDirection: "row",
}}
>
<View style={{ flex: 9 }}>
<Text
style={{
fontSize: (() => {
if (
customTrainDataDetector(d.train).trainName.length > 6
) {
return 15;
} else {
return 20;
}
})(),
color: (() => {
switch (customTrainDataDetector(d.train).type) {
case "Rapid":
return "aqua";
case "LTDEXP":
return "red";
case "NightLTDEXP":
return "red";
case "Normal":
return "white";
}
})(),
fontWeight: "bold",
}}
>
{trainIDSwitch
? d.train
: (() => {
switch (customTrainDataDetector(d.train).type) {
case "Rapid":
return "快速";
case "LTDEXP":
return "特急";
case "NightLTDEXP":
return "寝台特急";
case "Normal":
return "普通列車";
}
})() +
" " +
customTrainDataDetector(d.train).trainName +
(() => {
if (
customTrainDataDetector(d.train).trainNumDistance !=
null
) {
return (
parseInt(
d.train.replace("M", "").replace("D", "")
) -
customTrainDataDetector(d.train)
.trainNumDistance +
"号"
);
} else {
return "";
}
})()}
</Text>
</View>
<View style={{ flex: 4, flexDirection: "row" }}>
<Text
style={{
fontSize: d.lastStation.length > 4 ? 15 : 20,
color: "white",
fontWeight: "bold",
}}
>
{d.lastStation}
</Text>
</View>
<View style={{ flex: 3 }}>
<Text
style={{ fontSize: 20, color: "white", fontWeight: "bold" }}
>
{d.time}
</Text>
</View>
<View style={{ flex: 4 }}>
<Text
style={{ fontSize: 20, color: "white", fontWeight: "bold" }}
>
{(() => {
let data = currentTrain.filter(
(data) => data.num == d.train
)[0].delay;
if (isNaN(data)) {
return data;
} else if (data == 0) {
return "定刻通り";
} else {
return data + "分遅れ";
}
})()}
</Text>
</View>
</View>,
Boolean(trainDescriptionSwitch) &&
Boolean(customTrainDataDetector(d.train).info) && (
<View
style={{
alignContent: "center",
alignItems: "center",
width: "94%",
marginVertical: 5,
marginHorizontal: "3%",
backgroundColor: "#000",
flexDirection: "row",
}}
>
<View style={{ flex: 4 }}>
<Text
style={{
fontSize: 20,
color: "green",
fontWeight: "bold",
}}
>
{" "}
&gt; {customTrainDataDetector(d.train).info}
</Text>
</View>
</View>
),
])
: null}
<View style={{ flexDirection: "row", padding: 10 }}>
<Text
style={{
alignItems: "center",
alignContent: "center",
textAlign: "center",
textAlignVertical: "center",
color: "white",
}}
>
種別名 / 列番
</Text>
<Switch
value={trainIDSwitch}
onValueChange={(value) => setTrainIDSwitch(!trainIDSwitch)}
/>
<View style={{ flex: 1 }} />
<Text
style={{
alignItems: "center",
alignContent: "center",
textAlign: "center",
textAlignVertical: "center",
color: "white",
}}
>
列車情報
</Text>
<Switch
value={trainDescriptionSwitch}
onValueChange={(value) =>
setTrainDescriptionSwitch(!trainDescriptionSwitch)
}
/>
<View style={{ flex: 1 }} />
<Text
style={{
alignItems: "center",
alignContent: "center",
textAlign: "center",
textAlignVertical: "center",
color: "white",
}}
>
当駅止表示
</Text>
<Switch
value={finalSwitch}
onValueChange={(value) => setFinalSwitch(!finalSwitch)}
/>
</View>
</View>
);
} }

View File

@ -1,106 +1,311 @@
import React, { Component, useRef, useState, useEffect } from 'react'; import React, { Component, useRef, useState, useEffect } from "react";
import {StatusBar,View,LayoutAnimation,ScrollView,Linking,Text,TouchableOpacity } from 'react-native'; import {
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen'; StatusBar,
View,
LayoutAnimation,
ScrollView,
Linking,
Text,
TouchableOpacity,
} from "react-native";
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
} from "react-native-responsive-screen";
export default function Sign(props) {
export default function Sign(props){ const { currentStation, originalStationList, oP } = props;
const {currentStation, originalStationList, oP} = props; const getPreNextStation = (now) => {
const getPreNextStation = (now) =>{ const lineList = [
const lineList = ["予讃線", "松宇線", "伊予灘線", "土讃線", "窪川線", "高徳線", "徳島線", "鳴門線"]; "予讃線",
let returnData; "松宇線",
lineList.forEach(d=>{ "伊予灘線",
let cache = originalStationList[d].findIndex( data => data.StationNumber == now.StationNumber); "土讃線",
if(cache != -1){ "窪川線",
returnData = [originalStationList[d][cache-1],originalStationList[d][cache+1]] "高徳線",
"徳島線",
"鳴門線",
];
let returnData;
lineList.forEach((d) => {
let cache = originalStationList[d].findIndex(
(data) => data.StationNumber == now.StationNumber
);
if (cache != -1) {
returnData = [
originalStationList[d][cache - 1],
originalStationList[d][cache + 1],
];
}
});
return returnData;
};
const [nexPrePosition, setNexPrePosition] = useState(0);
useEffect(() => {
if (currentStation) {
if (currentStation.length > 1) {
let stationCount = setInterval(() => {
LayoutAnimation.easeInEaseOut();
if (nexPrePosition + 1 == currentStation.length) {
setNexPrePosition(0);
} else {
setNexPrePosition(nexPrePosition + 1);
} }
}, 1000);
}) return () => clearInterval(stationCount);
return returnData; }
} }
const [nexPrePosition, setNexPrePosition] = useState(0); }, [currentStation]);
useEffect(()=>{ return (
if(currentStation){ <TouchableOpacity
if(currentStation.length > 1){ style={{
let stationCount = setInterval(()=>{ width: wp("80%"),
LayoutAnimation.easeInEaseOut(); height: (wp("80%") / 20) * 9,
if(nexPrePosition+1 == currentStation.length){ borderColor: "#2E94BB",
setNexPrePosition(0) borderWidth: 1,
} margin: 10,
else{ marginHorizontal: wp("10%"),
setNexPrePosition(nexPrePosition+1); }}
} /* onPress={()=> !stationName.今.JrHpUrl || Linking.openURL(stationName.今.JrHpUrl)} */ onPress={
oP
},1000) }
return ()=>clearInterval(stationCount); >
} <View
} style={{
},[currentStation]) position: "absolute",
return( bottom: "0%",
<TouchableOpacity style={{ width: wp("80%"), height: wp("80%")/20*9,borderColor:"#2E94BB",borderWidth:1,margin:10,marginHorizontal:wp("10%")}} /* onPress={()=> !stationName.今.JrHpUrl || Linking.openURL(stationName.今.JrHpUrl)} */onPress={oP}> left: "0%",
<View style={{position:"absolute",bottom:"0%",left:"0%",width:"100%",height:'30%',backgroundColor:"#2E94BB"}} /> width: "100%",
<Text style={{position:"absolute",top:"2%",left:"2%",fontWeight:"bold",fontSize:parseInt("30%"),color:"#2E94BB"}}>JR</Text> height: "30%",
{currentStation.map((d,index,array)=> backgroundColor: "#2E94BB",
<View style={{position:"absolute",alignContent:"center",alignItems:"center",top:(()=>{ }}
if(array.length == 1) return 20; />
else if(index == 0) return 5; <Text
else if(index == 1) return 35; style={{
position: "absolute",
top: "2%",
left: "2%",
fontWeight: "bold",
fontSize: parseInt("30%"),
color: "#2E94BB",
}}
>
JR
</Text>
{currentStation.map((d, index, array) => (
<View
style={{
position: "absolute",
alignContent: "center",
alignItems: "center",
top:
(() => {
if (array.length == 1) return 20;
else if (index == 0) return 5;
else if (index == 1) return 35;
else return 20; else return 20;
})()+"%",right:'10%',width:wp("10%"),height:wp("10%"),borderColor:"#2E94BB",borderWidth:parseInt("2%"),borderRadius:parseInt("100%")}} > })() + "%",
<View style={{flex:1}} /> right: "10%",
<Text style={{fontSize:parseInt("20%")}}>{d.StationNumber}</Text> width: wp("10%"),
<View style={{flex:1}} /> height: wp("10%"),
borderColor: "#2E94BB",
borderWidth: parseInt("2%"),
borderRadius: parseInt("100%"),
}}
>
<View style={{ flex: 1 }} />
<Text style={{ fontSize: parseInt("20%") }}>{d.StationNumber}</Text>
<View style={{ flex: 1 }} />
</View>
))}
<View
style={{
position: "absolute",
top: "10%",
alignContent: "center",
flexDirection: "row",
}}
>
<View style={{ flex: 1 }} />
<View style={{ alignItems: "center" }}>
{/* <Text style={{fontWeight:"bold",fontSize:parseInt("15%"),color:"#005170"}}>{stationName.今.LineName}</Text> */}
<Text
style={{
fontWeight: "bold",
fontSize: parseInt("40%"),
color: "#005170",
}}
>
{currentStation[0].Station_JP}
</Text>
<Text
style={{
fontWeight: "bold",
fontSize: parseInt("15%"),
color: "#005170",
}}
>
{currentStation[0].Station_EN}
</Text>
</View>
<View style={{ flex: 1 }} />
</View>
<View
style={{
position: "absolute",
bottom: "0%",
height: "30%",
width: "100%",
alignItems: "center",
flexDirection: "column",
}}
>
{(() => {
return currentStation.map((currentStation) => {
let [preStation, nexStation] = getPreNextStation(currentStation);
return (
<View
style={{
flex: 1,
flexDirection: "row",
alignContent: "center",
}}
>
<View
style={{
flex: 1,
flexDirection: "row",
alignContent: "center",
}}
>
{preStation && [
<Text
style={{
fontWeight: "bold",
fontSize: parseInt("20%"),
color: "white",
paddingHorizontal: 10,
textAlignVertical: "center",
}}
>
</Text>,
<View
style={{
alignContent: "center",
alignItems: "center",
width: wp("8%"),
height: wp("8%"),
margin: wp("1%"),
borderColor: "white",
borderWidth: parseInt("2%"),
borderRadius: parseInt("100%"),
}}
>
<View style={{ flex: 1 }} />
<Text
style={{ fontSize: parseInt("10%"), color: "white" }}
>
{preStation.StationNumber}
</Text>
<View style={{ flex: 1 }} />
</View>,
<View style={{ flex: 1, alignItems: "flex-start" }}>
<Text
style={{
fontWeight: "bold",
fontSize: parseInt("15%"),
color: "white",
flex: 1,
textAlignVertical: "center",
}}
>
{preStation.Station_JP}
</Text>
<Text
style={{
fontWeight: "bold",
fontSize: parseInt("15%"),
color: "white",
flex: 1,
textAlignVertical: "center",
}}
>
{preStation.Station_EN}
</Text>
</View>,
]}
</View>
<View
style={{
flex: 1,
flexDirection: "row",
alignContent: "center",
}}
>
{nexStation && [
<View style={{ flex: 1, alignItems: "flex-end" }}>
<Text
style={{
fontWeight: "bold",
fontSize: parseInt("15%"),
color: "white",
flex: 1,
textAlignVertical: "center",
}}
>
{nexStation.Station_JP}
</Text>
<Text
style={{
fontWeight: "bold",
fontSize: parseInt("15%"),
color: "white",
flex: 1,
textAlignVertical: "center",
}}
>
{nexStation.Station_EN}
</Text>
</View>,
<View
style={{
alignContent: "center",
alignItems: "center",
width: wp("8%"),
height: wp("8%"),
margin: wp("1%"),
borderColor: "white",
borderWidth: parseInt("2%"),
borderRadius: parseInt("100%"),
}}
>
<View style={{ flex: 1 }} />
<Text
style={{ fontSize: parseInt("10%"), color: "white" }}
>
{nexStation.StationNumber}
</Text>
<View style={{ flex: 1 }} />
</View>,
<Text
style={{
fontWeight: "bold",
fontSize: parseInt("20%"),
color: "white",
paddingHorizontal: 10,
textAlignVertical: "center",
}}
>
</Text>,
]}
</View>
</View> </View>
)} );
<View style={{position:"absolute",top:"10%",alignContent:"center",flexDirection:"row"}}> })[nexPrePosition];
<View style={{flex:1}}/> })()}
<View style={{alignItems:"center"}}> </View>
{/* <Text style={{fontWeight:"bold",fontSize:parseInt("15%"),color:"#005170"}}>{stationName.今.LineName}</Text> */} </TouchableOpacity>
<Text style={{fontWeight:"bold",fontSize:parseInt("40%"),color:"#005170"}}>{currentStation[0].Station_JP}</Text> );
<Text style={{fontWeight:"bold",fontSize:parseInt("15%"),color:"#005170"}}>{currentStation[0].Station_EN}</Text>
</View>
<View style={{flex:1}}/>
</View>
<View style={{position:"absolute",bottom:"0%",height:"30%",width:"100%",alignItems:"center",flexDirection:"column"}}>
{(()=>{return currentStation.map(currentStation =>{
let [preStation, nexStation] = getPreNextStation(currentStation)
return(
<View style={{flex:1,flexDirection:"row",alignContent:"center"}}>
<View style={{flex:1,flexDirection:"row",alignContent:"center"}}>
{preStation &&
[<Text style={{fontWeight:"bold",fontSize:parseInt("20%"),color:"white",paddingHorizontal:10,textAlignVertical:"center"}}></Text>,
<View style={{alignContent:"center",alignItems:"center",width:wp("8%"),height:wp("8%"),margin:wp("1%"),borderColor:"white",borderWidth:parseInt("2%"),borderRadius:parseInt("100%")}} >
<View style={{flex:1}} />
<Text style={{fontSize:parseInt("10%"),color:"white"}}>{preStation.StationNumber}</Text>
<View style={{flex:1}} />
</View>,
<View style={{flex:1,alignItems:"flex-start"}}>
<Text style={{fontWeight:"bold",fontSize:parseInt("15%"),color:"white",flex:1,textAlignVertical:"center"}}>{preStation.Station_JP}</Text>
<Text style={{fontWeight:"bold",fontSize:parseInt("15%"),color:"white",flex:1,textAlignVertical:"center"}}>{preStation.Station_EN}</Text>
</View>]}
</View>
<View style={{flex:1,flexDirection:"row",alignContent:"center"}}>
{nexStation &&
[<View style={{flex:1,alignItems:"flex-end"}}>
<Text style={{fontWeight:"bold",fontSize:parseInt("15%"),color:"white",flex:1,textAlignVertical:"center"}}>{nexStation.Station_JP}</Text>
<Text style={{fontWeight:"bold",fontSize:parseInt("15%"),color:"white",flex:1,textAlignVertical:"center"}}>{nexStation.Station_EN}</Text>
</View>,
<View style={{alignContent:"center",alignItems:"center",width:wp("8%"),height:wp("8%"),margin:wp("1%"),borderColor:"white",borderWidth:parseInt("2%"),borderRadius:parseInt("100%")}} >
<View style={{flex:1}} />
<Text style={{fontSize:parseInt("10%"),color:"white"}}>{nexStation.StationNumber}</Text>
<View style={{flex:1}} />
</View>,
<Text style={{fontWeight:"bold",fontSize:parseInt("20%"),color:"white",paddingHorizontal:10,textAlignVertical:"center"}}></Text>]}
</View>
</View>
)
})[nexPrePosition]
})()}
</View>
</TouchableOpacity>
)
} }

View File

@ -1 +1 @@
export const news = "2022-6-11"; export const news = "2022-9-30";

View File

@ -10,11 +10,11 @@
"preview": { "preview": {
"distribution": "internal" "distribution": "internal"
}, },
"mapsbuild":{ "mapsbuild": {
"releaseChannel": "mapsbuild" "releaseChannel": "mapsbuild"
}, },
"production": { "production": {
"releaseChannel": "release" "releaseChannel": "aliexpress"
} }
}, },
"submit": { "submit": {

View File

@ -1,16 +1,30 @@
const WEBVIEW = "WEBVIEW"; const WEBVIEW = "WEBVIEW";
import React, { Component } from 'react'; import React, { Component } from "react";
import { StatusBar,View} from 'react-native'; import { StatusBar, View, TouchableOpacity, Text } from "react-native";
import {WebView} from 'react-native-webview'; import { WebView } from "react-native-webview";
export default class howto extends Component { export default ({ navigation: { navigate } }) => (
render() { <View style={{ height: "100%", backgroundColor: "#0099CC" }}>
return ( <WebView
<View style={{height:"100%"}}> useWebKit={true}
<View style={{alignItems:"center"}}> source={{ uri: "https://train.jr-shikoku.co.jp/usage.htm" }}
<View style={{ width:60,height:8,marginTop:15,marginBottom:10, backgroundColor: "gray", padding: 0, borderRadius: 20, borderWidth: 1, borderColor: "gray", overflow: "hidden"}}/> />
</View> <TouchableOpacity
<WebView useWebKit={true} source={{uri: 'https://train.jr-shikoku.co.jp/usage.htm'}}/> style={{
</View> padding: 10,
); flexDirection: "row",
} borderColor: "white",
} borderWidth: 1,
margin: 10,
borderRadius: 5,
alignItems: "center",
}}
onPress={() => navigate("Apps")}
>
<View style={{ flex: 1 }} />
<Text style={{ fontSize: 25, fontWeight: "bold", color: "white" }}>
閉じる
</Text>
<View style={{ flex: 1 }} />
</TouchableOpacity>
</View>
);

1330
menu.js

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,25 @@
import React, { Component } from 'react'; import React, { Component } from "react";
import { StatusBar,View,Linking,Platform,Text} from 'react-native'; import { StatusBar, View, Linking, Platform, Text } from "react-native";
import {WebView} from 'react-native-webview'; import { WebView } from "react-native-webview";
import Constants from 'expo-constants'; import Constants from "expo-constants";
import { TouchableOpacity } from 'react-native-gesture-handler'; import { TouchableOpacity } from "react-native-gesture-handler";
export default function tndView () { export default function tndView() {
return ( return (
<View style={{backgroundColor: '#309AC3', height:"100%",paddingTop: Platform.OS == "ios" ? Constants.statusBarHeight: 0,}}> <View
style={{
backgroundColor: "#309AC3",
height: "100%",
paddingTop: Platform.OS == "ios" ? Constants.statusBarHeight : 0,
}}
>
<WebView <WebView
useWebKit={true} useWebKit={true}
source={{uri: 'https://www.jr-shikoku.co.jp/info/'}} source={{ uri: "https://www.jr-shikoku.co.jp/info/" }}
originWhitelist={['https://www.jr-shikoku.co.jp']} originWhitelist={["https://www.jr-shikoku.co.jp"]}
mixedContentMode={'compatibility'} mixedContentMode={"compatibility"}
javaScriptEnabled={true} javaScriptEnabled={true}
injectedJavaScript={jsa}/> injectedJavaScript={jsa}
/>
</View> </View>
); );
} }
@ -20,4 +27,3 @@ const jsa = `
document.querySelector('.sitettl').style.display = 'none'; document.querySelector('.sitettl').style.display = 'none';
document.querySelector('.attention').style.display = 'none'; document.querySelector('.attention').style.display = 'none';
`; `;

View File

@ -29,6 +29,7 @@
"react-native-auto-height-image": "^3.2.4", "react-native-auto-height-image": "^3.2.4",
"react-native-elements": "^3.4.2", "react-native-elements": "^3.4.2",
"react-native-gesture-handler": "~2.2.1", "react-native-gesture-handler": "~2.2.1",
"react-native-maps": "0.30.2",
"react-native-reanimated": "~2.8.0", "react-native-reanimated": "~2.8.0",
"react-native-remote-svg": "^2.0.6", "react-native-remote-svg": "^2.0.6",
"react-native-responsive-screen": "^1.4.2", "react-native-responsive-screen": "^1.4.2",

View File

@ -1,14 +1,34 @@
const WEBVIEW = "WEBVIEW"; import React, { Component, useRef } from "react";
import React, { Component } from 'react'; import { StatusBar, Platform, View } from "react-native";
import { StatusBar,View} from 'react-native'; import { WebView } from "react-native-webview";
import {WebView} from 'react-native-webview';
export default function trainbase({route, navigation}) { export default function TrainBase({ route }) {
const { info } = route.params; const { info } = route.params;
const webview = useRef();
const jss = `document.getElementById('Footer').style.display = 'none';
${
Platform.OS == "ios" &&
`document.getElementsByTagName("html")[0].style['font-size'] = '11px';`
}`;
//const jss = `alert("ほげ")`;
console.log(info);
return ( return (
<View style={{height:"100%"}}> <View style={{ height: "100%" }}>
<WebView source={{uri: info}} useWebKit={true} originWhitelist={['https://train.jr-shikoku.co.jp']}injectedJavaScript={jss}/> {Platform.OS == "ios" && <StatusBar barStyle="dark-content" />}
<WebView
//useWebKit={true}
ref={webview}
source={{ uri: "https://train.jr-shikoku.co.jp/" + info }}
originWhitelist={[
"https://train.jr-shikoku.co.jp",
"https://train.jr-shikoku.co.jp/sp.html",
]}
mixedContentMode={"compatibility"}
javaScriptEnabled={true}
injectedJavaScript={jss}
setSupportMultipleWindows={false}
onMessage={(event) => {}}
/>
</View> </View>
); );
} }
const jss = `document.getElementById('Footer').style.display = 'none';`;

View File

@ -2977,6 +2977,11 @@
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
"@types/geojson@^7946.0.7":
version "7946.0.8"
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca"
integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==
"@types/graceful-fs@^4.1.2": "@types/graceful-fs@^4.1.2":
version "4.1.5" version "4.1.5"
resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15"
@ -8618,6 +8623,14 @@ react-native-iphone-x-helper@^1.3.0:
resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz#20c603e9a0e765fd6f97396638bdeb0e5a60b010" resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz#20c603e9a0e765fd6f97396638bdeb0e5a60b010"
integrity sha512-HOf0jzRnq2/aFUcdCJ9w9JGzN3gdEg0zFE4FyYlp4jtidqU03D5X7ZegGKfT1EWteR0gPBGp9ye5T5FvSWi9Yg== integrity sha512-HOf0jzRnq2/aFUcdCJ9w9JGzN3gdEg0zFE4FyYlp4jtidqU03D5X7ZegGKfT1EWteR0gPBGp9ye5T5FvSWi9Yg==
react-native-maps@0.30.2:
version "0.30.2"
resolved "https://registry.yarnpkg.com/react-native-maps/-/react-native-maps-0.30.2.tgz#2f1cf4ab79892a43060774bda8786ce6ab8e3616"
integrity sha512-WVv5e7aWdnNJugqNSG/87U+12Pg4RFWU7x/UigTPG1FEUZx2TbYKChL6xZCMGPOv5m5b4Z7bMeKJnZosg+yPyQ==
dependencies:
"@types/geojson" "^7946.0.7"
deprecated-react-native-prop-types "^2.3.0"
react-native-ratings@8.0.4: react-native-ratings@8.0.4:
version "8.0.4" version "8.0.4"
resolved "https://registry.yarnpkg.com/react-native-ratings/-/react-native-ratings-8.0.4.tgz#efd5ebad8acc08bf98d34d39b18fb7a6813ef991" resolved "https://registry.yarnpkg.com/react-native-ratings/-/react-native-ratings-8.0.4.tgz#efd5ebad8acc08bf98d34d39b18fb7a6813ef991"