Compare commits
58 Commits
8ec53d6e06
...
2fb7d97d33
Author | SHA1 | Date | |
---|---|---|---|
|
2fb7d97d33 | ||
|
31618aab49 | ||
|
343bf25139 | ||
|
e58e24ba71 | ||
|
c0478bf9ae | ||
|
0838414540 | ||
|
a9488b98bc | ||
|
76ebf8055b | ||
|
26cf84705a | ||
|
55f4a79eef | ||
|
7b572cd657 | ||
|
046a8dbfb2 | ||
|
fa882223d4 | ||
|
bb7b474006 | ||
|
61fa0f8484 | ||
|
ede2884c4a | ||
|
935aaf2610 | ||
|
098cae5053 | ||
|
7cddc657fd | ||
|
adee63b549 | ||
|
5dd60027a0 | ||
|
558d37c3c6 | ||
|
74ff188d84 | ||
|
974b12667f | ||
|
9a157d711b | ||
|
6ff4aba050 | ||
|
a4eda11b2d | ||
|
45e14274cb | ||
|
499e895165 | ||
|
a6b676fe9d | ||
|
a785508b45 | ||
|
aa0ff60e37 | ||
|
5204231ccb | ||
|
ea4fa46fe0 | ||
|
8e0f04c5b2 | ||
|
e7cecd38c1 | ||
|
3976552e43 | ||
|
79ba9748a6 | ||
|
8967baf121 | ||
|
0d4dcee4b6 | ||
|
f4dca5cd87 | ||
|
9df1fc1ed2 | ||
|
8818addecd | ||
|
1a1e9c417b | ||
|
e04cfb9a8b | ||
|
ceffd2da7e | ||
|
ef16d9ed6b | ||
|
cbeba9f269 | ||
|
77328bf97a | ||
|
a979fee6ec | ||
|
2176b5511a | ||
|
837bd6eb4f | ||
|
f9e3b1d658 | ||
|
892d567991 | ||
|
294b95967f | ||
|
a5efb13506 | ||
|
00b17bfbc1 | ||
|
72c4bd10aa |
4
.gitignore
vendored
@ -5,4 +5,6 @@ npm-debug.*
|
||||
*.p12
|
||||
*.key
|
||||
*.mobileprovision
|
||||
dist/
|
||||
dist/
|
||||
# Local Netlify folder
|
||||
.netlify
|
||||
|
41
Apps.js
@ -14,50 +14,51 @@ export function AppContainer() {
|
||||
const Tab = createBottomTabNavigator();
|
||||
const { areaInfo, areaIconBadgeText, isInfo } = useAreaInfo();
|
||||
const navigationRef = React.useRef();
|
||||
const getTabProps = (name, label, icon, iconFamily, tabBarBadge, style) => ({
|
||||
const getTabProps = (name, label, icon, iconFamily, tabBarBadge, isInfo) => ({
|
||||
name,
|
||||
options: {
|
||||
tabBarLabel: label,
|
||||
headerTransparent: true,
|
||||
headerShown: false,
|
||||
gestureEnabled: true,
|
||||
tabBarIcon: initIcon(icon, iconFamily),
|
||||
tabBarBadge,
|
||||
tabBarBadgeStyle: style,
|
||||
tabBarIcon: initIcon(icon, iconFamily,tabBarBadge,isInfo),
|
||||
|
||||
},
|
||||
});
|
||||
const [fontLoaded, error] = useFonts({
|
||||
"JR-Nishi": require("./assets/fonts/jr-nishi.otf"),
|
||||
"Zou": require("./assets/fonts/DelaGothicOne-Regular.ttf"),
|
||||
});
|
||||
const [fontLoaded, error] = useFonts({
|
||||
"JR-Nishi": require("./assets/fonts/jr-nishi.otf"),
|
||||
Zou: require("./assets/fonts/DelaGothicOne-Regular.ttf"),
|
||||
});
|
||||
return (
|
||||
<NavigationContainer name="Root" style={{ flex: 1 }} ref={navigationRef}>
|
||||
<NavigationContainer ref={navigationRef}>
|
||||
<Tab.Navigator
|
||||
tabBarOptions={{ keyboardHidesTabBar: Platform.OS === "android" }}
|
||||
initialRouteName="menuPage"
|
||||
initialRouteName="topMenu"
|
||||
screenOptions={{
|
||||
lazy: false,
|
||||
animation: "shift",
|
||||
}}
|
||||
detachInactiveScreens={false}
|
||||
lazy={false}
|
||||
>
|
||||
<Tab.Screen
|
||||
{...getTabProps("login", "位置情報", "barchart", "AntDesign")}
|
||||
children={(props) => <Top {...props} navigationRef={navigationRef} />}
|
||||
{...getTabProps("positions", "走行位置", "barchart", "AntDesign")}
|
||||
component={Top}
|
||||
/>
|
||||
<Tab.Screen
|
||||
{...getTabProps("menuPage", "リンク", "radio", "Ionicons")}
|
||||
{...getTabProps("topMenu", "トップメニュー", "radio", "Ionicons")}
|
||||
component={MenuPage}
|
||||
/>
|
||||
|
||||
<Tab.Screen
|
||||
{...getTabProps(
|
||||
"home",
|
||||
"information",
|
||||
"運行情報",
|
||||
"train",
|
||||
"Ionicons",
|
||||
areaInfo ? areaIconBadgeText : undefined,
|
||||
isInfo && {
|
||||
backgroundColor: "#00b8ff",
|
||||
color: "white",
|
||||
}
|
||||
isInfo
|
||||
)}
|
||||
children={(props) => <TNDView {...props} />}
|
||||
children={TNDView}
|
||||
/>
|
||||
</Tab.Navigator>
|
||||
</NavigationContainer>
|
||||
|
35
MenuPage.js
@ -1,19 +1,18 @@
|
||||
import React, { useEffect } from "react";
|
||||
import {
|
||||
createStackNavigator,
|
||||
TransitionPresets,
|
||||
} from "@react-navigation/stack";
|
||||
import { createStackNavigator } from "@react-navigation/stack";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import { AS } from "./storageControl";
|
||||
import TrainBase from "./components/trainbaseview";
|
||||
import HowTo from "./howto";
|
||||
import Menu from "./menu";
|
||||
import News from "./components/news";
|
||||
import Setting from "./components/Settings/settings";
|
||||
import { useFavoriteStation } from "./stateBox/useFavoriteStation";
|
||||
import { optionData } from "./lib/stackOption";
|
||||
import CurrentTrainListView from "./components/CurrentTrainListView";
|
||||
import AllTrainDiagramView from "./components/AllTrainDiagramView";
|
||||
import { useCurrentTrain } from "./stateBox/useCurrentTrain";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { news } from "./config/newsUpdate";
|
||||
const Stack = createStackNavigator();
|
||||
|
||||
export function MenuPage() {
|
||||
@ -24,12 +23,24 @@ export function MenuPage() {
|
||||
useEffect(() => {
|
||||
AS.getItem("startPage")
|
||||
.then((res) => {
|
||||
if (res == "true") navigation.navigate("login");
|
||||
if (res == "true") navigation.navigate("positions");
|
||||
})
|
||||
.catch((e) => {
|
||||
//6.0以降false
|
||||
AS.setItem("startPage", "true");
|
||||
AS.setItem("startPage", "false");
|
||||
});
|
||||
|
||||
//ニュース表示
|
||||
AS.getItem("status")
|
||||
.then((d) => {
|
||||
if (d != news) navigation.navigate("topMenu", { screen: "news" });
|
||||
})
|
||||
.catch(() => navigation.navigate("topMenu", { screen: "news" }));
|
||||
AS.getItem("isSetIcon")
|
||||
.then((isSetIcon) => {
|
||||
if (isSetIcon == "true") SheetManager.show("TrainIconUpdate");
|
||||
})
|
||||
.catch((error) => console.error("Error fetching icon setting:", error));
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
const unsubscribe = addListener("tabPress", (e) => {
|
||||
@ -56,6 +67,7 @@ export function MenuPage() {
|
||||
}}
|
||||
children={() => <Menu getCurrentTrain={getCurrentTrain} />}
|
||||
/>
|
||||
<Stack.Screen name="news" options={optionData} component={News} />
|
||||
<Stack.Screen
|
||||
name="setting"
|
||||
options={{
|
||||
@ -67,13 +79,8 @@ export function MenuPage() {
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="trainbase"
|
||||
options={{ ...optionData, gestureResponseDistance: { vertical: 300 } }}
|
||||
children={(props) => <TrainBase {...props} />}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="currentTrainIDList"
|
||||
options={{ ...optionData, gestureResponseDistance: { vertical: 300 } }}
|
||||
component={CurrentTrainListView}
|
||||
options={{ ...optionData }}
|
||||
component={TrainBase}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="AllTrainIDList"
|
||||
|
79
Top.js
@ -1,8 +1,6 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
createStackNavigator,
|
||||
TransitionPresets,
|
||||
} from "@react-navigation/stack";
|
||||
import React, { useEffect } from "react";
|
||||
import { createStackNavigator } from "@react-navigation/stack";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import Apps from "./components/Apps";
|
||||
import TrainBase from "./components/trainbaseview";
|
||||
import HowTo from "./howto";
|
||||
@ -10,91 +8,76 @@ import News from "./components/news";
|
||||
import TrainMenu from "./components/trainMenu";
|
||||
import FavoriteList from "./components/FavoriteList";
|
||||
import { optionData } from "./lib/stackOption";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { useCurrentTrain } from "./stateBox/useCurrentTrain";
|
||||
import { useTrainMenu } from "./stateBox/useTrainMenu";
|
||||
import { AS } from "./storageControl";
|
||||
import { news } from "./config/newsUpdate";
|
||||
import { Linking, Platform } from "react-native";
|
||||
const Stack = createStackNavigator();
|
||||
export const Top = ({ navigationRef }) => {
|
||||
export const Top = () => {
|
||||
const { webview } = useCurrentTrain();
|
||||
const { navigate, addListener } = useNavigation();
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
//ニュース表示
|
||||
AS.getItem("status")
|
||||
.then((d) => {
|
||||
if (d != news) navigate("news");
|
||||
})
|
||||
.catch(() => navigate("news"));
|
||||
}, []);
|
||||
|
||||
|
||||
const { navigate, addListener, isFocused } = useNavigation();
|
||||
|
||||
//地図用
|
||||
const { injectJavaScript, setInjectJavaScript, mapSwitch } = useTrainMenu();
|
||||
const { injectJavaScript, mapSwitch } = useTrainMenu();
|
||||
|
||||
const goToFavoriteList = () => navigate("favoriteList");
|
||||
const goToFavoriteList = () =>
|
||||
navigate("positions", { screen: "favoriteList" });
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = addListener("tabLongPress", goToFavoriteList);
|
||||
return unsubscribe;
|
||||
}, [{ navigate, addListener }]);
|
||||
}, []);
|
||||
|
||||
const goToTrainMenu = () => {
|
||||
if (navigationRef.current?.getCurrentRoute().name == "Apps") {
|
||||
if (mapSwitch == "true") {
|
||||
navigate("trainMenu");
|
||||
setInjectJavaScript("");
|
||||
} else {
|
||||
webview.current?.injectJavaScript(`AccordionClassEvent()`);
|
||||
}
|
||||
} else {
|
||||
if (mapSwitch == "true") {
|
||||
if (injectJavaScript) {
|
||||
webview.current?.injectJavaScript(injectJavaScript);
|
||||
setInjectJavaScript("");
|
||||
}
|
||||
}
|
||||
navigate("Apps");
|
||||
if (Platform.OS === "web") {
|
||||
Linking.openURL("https://train.jr-shikoku.co.jp/");
|
||||
setTimeout(() => {
|
||||
navigate("topMenu", { screen: "menu" });
|
||||
}, 100);
|
||||
|
||||
return;
|
||||
}
|
||||
if (!isFocused()) {
|
||||
navigate("positions", { screen: "Apps" });
|
||||
}
|
||||
if (mapSwitch == "true") {
|
||||
navigate("positions", { screen: "trainMenu" });
|
||||
} else {
|
||||
webview.current?.injectJavaScript(`AccordionClassEvent()`);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = addListener("tabPress", goToTrainMenu);
|
||||
return unsubscribe;
|
||||
}, [{ navigate, addListener }, mapSwitch, injectJavaScript]);
|
||||
}, [addListener, mapSwitch, injectJavaScript]);
|
||||
|
||||
return (
|
||||
<Stack.Navigator>
|
||||
<Stack.Navigator detachInactiveScreens={false}>
|
||||
<Stack.Screen
|
||||
name="Apps"
|
||||
options={{
|
||||
headerShown: false,
|
||||
gestureEnabled: true,
|
||||
headerTransparent: true,
|
||||
detachPreviousScreen: false,
|
||||
}}
|
||||
component={Apps}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="trainbase"
|
||||
options={{
|
||||
title: "トレインビジョン",
|
||||
gestureEnabled: true,
|
||||
...TransitionPresets.SlideFromRightIOS,
|
||||
}}
|
||||
options={{ ...optionData }}
|
||||
component={TrainBase}
|
||||
/>
|
||||
|
||||
<Stack.Screen name="howto" options={optionData} component={HowTo} />
|
||||
<Stack.Screen name="news" options={optionData} component={News} />
|
||||
|
||||
<Stack.Screen
|
||||
name="trainMenu"
|
||||
options={optionData}
|
||||
component={TrainMenu}
|
||||
/>
|
||||
|
||||
<Stack.Screen
|
||||
name="favoriteList"
|
||||
options={{ ...optionData, gestureEnabled: false }}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { ToastAndroid } from "react-native";
|
||||
import { Platform, ToastAndroid } from "react-native";
|
||||
import * as Updates from "expo-updates";
|
||||
|
||||
export const UpdateAsync = () => {
|
||||
Updates.checkForUpdateAsync()
|
||||
.then((update) => {
|
||||
if (!update.isAvailable) return;
|
||||
if (Platform.OS == "ios") {
|
||||
if (Platform.OS !== "android") {
|
||||
alert("アプリのデータを更新しています。");
|
||||
} else {
|
||||
ToastAndroid.showWithGravityAndOffset(
|
||||
@ -20,7 +20,7 @@ export const UpdateAsync = () => {
|
||||
return;
|
||||
})
|
||||
.catch((e) => {
|
||||
Platform.OS == "ios"
|
||||
Platform.OS != "android"
|
||||
? alert(e.toString())
|
||||
: ToastAndroid.showWithGravityAndOffset(
|
||||
e.toString(),
|
456
app.json
@ -1,56 +1,28 @@
|
||||
{
|
||||
"expo": {
|
||||
"name": "JR四国運行状況",
|
||||
"name": "JR四国非公式",
|
||||
"slug": "jrshikoku",
|
||||
"privacy": "public",
|
||||
"platforms": ["ios", "android"],
|
||||
"plugins": [
|
||||
[
|
||||
"react-native-android-widget",
|
||||
{
|
||||
"widgets": [
|
||||
{
|
||||
"name": "JR_shikoku_train_info",
|
||||
"label": "JR四国列車遅延速報EX",
|
||||
"minWidth": "70dp",
|
||||
"minHeight": "50dp",
|
||||
"description": "JR四国列車遅延速報EXのウィジェットです。30分ごとに自動更新します。タッチすると強制更新します。",
|
||||
"previewImage": "./assets/icon.png",
|
||||
"updatePeriodMillis": 1800000,
|
||||
"resizeMode": "horizontal|vertical"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expo-font",
|
||||
[
|
||||
"expo-screen-orientation",
|
||||
{
|
||||
"initialOrientation": "DEFAULT"
|
||||
}
|
||||
],
|
||||
[
|
||||
"expo-location",
|
||||
{
|
||||
"locationWhenInUsePermission": "この位置情報は、リンク画面で現在地側近の駅情報を取得するのに使用されます。"
|
||||
}
|
||||
]
|
||||
"platforms": [
|
||||
"ios",
|
||||
"android",
|
||||
"web"
|
||||
],
|
||||
"version": "5.0",
|
||||
"version": "6.0",
|
||||
"orientation": "default",
|
||||
"icon": "./assets/icon.png",
|
||||
"icon": "./assets/icons/s8600.png",
|
||||
"splash": {
|
||||
"image": "./assets/splash.png",
|
||||
"resizeMode": "contain",
|
||||
"backgroundColor": "#00b8ff"
|
||||
},
|
||||
"updates": {
|
||||
"fallbackToCacheTimeout": 0,
|
||||
"url": "https://u.expo.dev/398abf60-57a7-11e9-970c-8f04356d08bf"
|
||||
},
|
||||
"assetBundlePatterns": ["**/*"],
|
||||
"assetBundlePatterns": [
|
||||
"**/*"
|
||||
],
|
||||
"ios": {
|
||||
"buildNumber": "39",
|
||||
"buildNumber": "46",
|
||||
"supportsTablet": false,
|
||||
"bundleIdentifier": "jrshikokuinfo.xprocess.hrkn",
|
||||
"config": {
|
||||
@ -61,16 +33,24 @@
|
||||
"com.apple.developer.nfc.readersession.felica.systemcodes": [
|
||||
"0003",
|
||||
"FE00"
|
||||
]
|
||||
],
|
||||
"ITSAppUsesNonExemptEncryption": false
|
||||
},
|
||||
"entitlements": {
|
||||
"com.apple.developer.nfc.readersession.formats": ["TAG"]
|
||||
"com.apple.developer.nfc.readersession.formats": [
|
||||
"TAG"
|
||||
]
|
||||
}
|
||||
},
|
||||
"android": {
|
||||
"package": "jrshikokuinfo.xprocess.hrkn",
|
||||
"versionCode": 22,
|
||||
"permissions": ["ACCESS_FINE_LOCATION", "NFC"],
|
||||
"versionCode": 27,
|
||||
"permissions": [
|
||||
"ACCESS_FINE_LOCATION",
|
||||
"NFC",
|
||||
"android.permission.ACCESS_COARSE_LOCATION",
|
||||
"android.permission.ACCESS_FINE_LOCATION"
|
||||
],
|
||||
"googleServicesFile": "./google-services.json",
|
||||
"config": {
|
||||
"googleMaps": {
|
||||
@ -85,6 +65,394 @@
|
||||
},
|
||||
"runtimeVersion": {
|
||||
"policy": "sdkVersion"
|
||||
}
|
||||
},
|
||||
"plugins": [
|
||||
"expo-font",
|
||||
"expo-localization",
|
||||
[
|
||||
"expo-screen-orientation",
|
||||
{
|
||||
"initialOrientation": "DEFAULT"
|
||||
}
|
||||
],
|
||||
[
|
||||
"expo-location",
|
||||
{
|
||||
"locationWhenInUsePermission": "この位置情報は、リンク画面で現在地側近の駅情報を取得するのに使用されます。"
|
||||
}
|
||||
],
|
||||
[
|
||||
"react-native-android-widget",
|
||||
{
|
||||
"widgets": [
|
||||
{
|
||||
"name": "JR_shikoku_train_info",
|
||||
"label": "列車遅延速報EX",
|
||||
"minWidth": "70dp",
|
||||
"minHeight": "50dp",
|
||||
"description": "JR四国列車遅延速報EXのウィジェットです。30分ごとに自動更新します。タッチすると強制更新します。",
|
||||
"previewImage": "./assets/icon.png",
|
||||
"updatePeriodMillis": 1800000,
|
||||
"resizeMode": "horizontal|vertical"
|
||||
},
|
||||
{
|
||||
"name": "JR_shikoku_train_strange",
|
||||
"label": "怪レい列車",
|
||||
"minWidth": "70dp",
|
||||
"minHeight": "50dp",
|
||||
"description": "JR四国怪レい列車BOTのウィジェットです。30分ごとに自動更新します。タッチすると強制更新します。",
|
||||
"previewImage": "./assets/icon.png",
|
||||
"updatePeriodMillis": 1800000,
|
||||
"resizeMode": "horizontal|vertical"
|
||||
},
|
||||
{
|
||||
"name": "JR_shikoku_info",
|
||||
"label": "運行情報",
|
||||
"minWidth": "70dp",
|
||||
"minHeight": "50dp",
|
||||
"description": "JR四国運行情報のウィジェットです。30分ごとに自動更新します。タッチすると強制更新します。",
|
||||
"previewImage": "./assets/icon.png",
|
||||
"updatePeriodMillis": 1800000,
|
||||
"resizeMode": "horizontal|vertical"
|
||||
},
|
||||
{
|
||||
"name": "JR_shikoku_apps_shortcut",
|
||||
"label": "クイックアクセス",
|
||||
"minWidth": "70dp",
|
||||
"minHeight": "50dp",
|
||||
"description": "JR四国非公式アプリの各種リンクを表示するウィジェットです。",
|
||||
"previewImage": "./assets/icon.png",
|
||||
"updatePeriodMillis": 1800000,
|
||||
"resizeMode": "horizontal|vertical"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
[
|
||||
"expo-alternate-app-icons",
|
||||
[
|
||||
{
|
||||
"name": "32",
|
||||
"ios": "./assets/icons/32.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/32.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "32kpuuy",
|
||||
"ios": "./assets/icons/32kpuuy.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/32kpuuy.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "32tht",
|
||||
"ios": "./assets/icons/32tht.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/32tht.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "32at",
|
||||
"ios": "./assets/icons/32at.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/32at.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "54",
|
||||
"ios": "./assets/icons/54.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/54.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "54st",
|
||||
"ios": "./assets/icons/54st.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/54st.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "40",
|
||||
"ios": "./assets/icons/40.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/40.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "185mrt",
|
||||
"ios": "./assets/icons/s185_mrt.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s185_mrt.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "185tu",
|
||||
"ios": "./assets/icons/s185tu.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s185tu.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "185iyor",
|
||||
"ios": "./assets/icons/s185iyor.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s185iyor.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "185iyoy",
|
||||
"ios": "./assets/icons/s185iyoy.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s185iyoy.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "185toai",
|
||||
"ios": "./assets/icons/s185to_ai.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s185to_ai.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "185mm1",
|
||||
"ios": "./assets/icons/s185mm1.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s185mm1.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "185ym1",
|
||||
"ios": "./assets/icons/s185ym1.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s185ym1.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "1000",
|
||||
"ios": "./assets/icons/s1000.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s1000.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "1200n",
|
||||
"ios": "./assets/icons/s1200n.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s1200n.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "1500",
|
||||
"ios": "./assets/icons/s1500.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s1500.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "5001",
|
||||
"ios": "./assets/icons/s5001.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s5001.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "5001k",
|
||||
"ios": "./assets/icons/s5001k.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s5001k.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "6000p",
|
||||
"ios": "./assets/icons/s6000p.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s6000p.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "7000",
|
||||
"ios": "./assets/icons/s7000.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s7000.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "s7200",
|
||||
"ios": "./assets/icons/s7200.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s7200.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "2000asi",
|
||||
"ios": "./assets/icons/s2000_asi.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s2000_asi.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "N2000",
|
||||
"ios": "./assets/icons/s2000n.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s2000n.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "2002a",
|
||||
"ios": "./assets/icons/s2002a.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s2002a.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "2600",
|
||||
"ios": "./assets/icons/s2600.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s2600.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "2700",
|
||||
"ios": "./assets/icons/s2700.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s2700.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "2700apy",
|
||||
"ios": "./assets/icons/s2700apy.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s2700apy.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "2700apr",
|
||||
"ios": "./assets/icons/s2700apr.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s2700apr.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "8000no",
|
||||
"ios": "./assets/icons/s8000no.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s8000no.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "8000nr",
|
||||
"ios": "./assets/icons/s8000nr.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s8000nr.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "8000ap",
|
||||
"ios": "./assets/icons/s8000ap.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s8000ap.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "8000nn",
|
||||
"ios": "./assets/icons/s8000nn.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s8000nn.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "8600",
|
||||
"ios": "./assets/icons/s8600.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/s8600.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "9640",
|
||||
"ios": "./assets/icons/tosa9640.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/tosa9640.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "9640jgr",
|
||||
"ios": "./assets/icons/tosa9640jgr.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/tosa9640jgr.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "285",
|
||||
"ios": "./assets/icons/w285.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/w285.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "213w",
|
||||
"ios": "./assets/icons/w213w.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/w213w.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "EF65",
|
||||
"ios": "./assets/icons/ef65.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/ef65.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "EF210",
|
||||
"ios": "./assets/icons/ef210.png",
|
||||
"android": {
|
||||
"foregroundImage": "./assets/icons/ef210.png",
|
||||
"backgroundColor": "#001413"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
BIN
assets/icons/32.png
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
assets/icons/32at.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
assets/icons/32kpuuy.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
assets/icons/32tht.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
assets/icons/40.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
assets/icons/54.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/icons/54st.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
BIN
assets/icons/ef210.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
BIN
assets/icons/ef65.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
45
assets/icons/icons.ts
Normal file
@ -0,0 +1,45 @@
|
||||
export default () =>{
|
||||
return [
|
||||
{ "id": "32", "name": "キハ32形", "icon": require("./32.png") },
|
||||
{ "id": "32kpuuy", "name": "キハ32形かっぱうようよ号", "icon": require("./32kpuuy.png") },
|
||||
{ "id": "32tht", "name": "キハ32形新幹線ホビートレイン", "icon": require("./32tht.png") },
|
||||
{ "id": "32at", "name": "キクハ32形アンパンマントロッコ", "icon": require("./32at.png") },
|
||||
{ "id": "54", "name": "キハ54形", "icon": require("./54.png") },
|
||||
{ "id": "54st", "name": "キハ54形しまんトロッコ", "icon": require("./54st.png") },
|
||||
{ "id": "40", "name": "キハ40", "icon": require("./40.png") },
|
||||
{ "id": "185mrt", "name": "キハ185系四国色", "icon": require("./s185_mrt.png") },
|
||||
{ "id": "185tu", "name": "キハ185系剣山色", "icon": require("./s185tu.png") },
|
||||
{ "id": "185iyor", "name": "キハ185系伊予灘ものがたり(赤)", "icon": require("./s185iyor.png") },
|
||||
{ "id": "185iyoy", "name": "キハ185系伊予灘ものがたり(黄)", "icon": require("./s185iyoy.png") },
|
||||
{ "id": "185toai", "name": "キハ185系藍よしのがわトロッコ", "icon": require("./s185to_ai.png") },
|
||||
{ "id": "185mm1", "name": "キハ185系四国まんなか千年ものがたり(緑)", "icon": require("./s185mm1.png") },
|
||||
{ "id": "185ym1", "name": "キハ185系時代の夜明けのものがたり(茶)", "icon": require("./s185ym1.png") },
|
||||
{ "id": "1000", "name": "1000形", "icon": require("./s1000.png") },
|
||||
{ "id": "1200n", "name": "1200形", "icon": require("./s1200n.png") },
|
||||
{ "id": "1500", "name": "1500形", "icon": require("./s1500.png") },
|
||||
{ "id": "5001", "name": "5000系(二階建て)", "icon": require("./s5001.png") },
|
||||
{ "id": "5001k", "name": "5000系(平屋側)", "icon": require("./s5001k.png") },
|
||||
{ "id": "6000p", "name": "6000系", "icon": require("./s6000p.png") },
|
||||
{ "id": "7000", "name": "7000系", "icon": require("./s7000.png") },
|
||||
{ "id": "7200", "name": "7200系", "icon": require("./s7200.png") },
|
||||
{ "id": "2000asi", "name": "2000系", "icon": require("./s2000_asi.png") },
|
||||
{ "id": "N2000", "name": "N2000系", "icon": require("./s2000n.png") },
|
||||
{ "id": "2002a", "name": "2000系アンパンマン", "icon": require("./s2002a.png") },
|
||||
{ "id": "2600", "name": "2600系" , "icon": require("./s2600.png")},
|
||||
{ "id": "2700", "name": "2700系", "icon": require("./s2700.png") },
|
||||
{ "id": "2700apy", "name": "2700系アンパンマン(黄)", "icon": require("./s2700apy.png") },
|
||||
{ "id": "2700apr", "name": "2700系アンパンマン(赤)", "icon": require("./s2700apr.png") },
|
||||
{ "id": "8000no", "name": "8000系(オレンジ)", "icon": require("./s8000no.png") },
|
||||
{ "id": "8000nr", "name": "8000系(赤)", "icon": require("./s8000nr.png") },
|
||||
{ "id": "8000ap", "name": "8000系アンパンマン", "icon": require("./s8000ap.png") },
|
||||
{ "id": "8000nn", "name": "8000系リニューアル改", "icon": require("./s8000nn.png") },
|
||||
{ "id": "8600", "name": "8600系", "icon": require("./s8600.png") },
|
||||
{ "id": "9640", "name": "9640形(白)", "icon": require("./tosa9640.png") },
|
||||
{ "id": "9640jgr", "name": "9640形オープンデッキ(緑)", "icon": require("./tosa9640jgr.png") },
|
||||
{ "id": "285", "name": "285系サンライズ瀬戸", "icon": require("./w285.png") },
|
||||
{ "id": "213w", "name": "ラ・マル・ド・ボァ", "icon": require("./w213w.png") },
|
||||
{ "id": "EF65", "name": "EF65", "icon": require("./ef65.png") },
|
||||
{ "id": "EF210", "name": "EF210", "icon": require("./ef210.png") },
|
||||
]
|
||||
|
||||
}
|
BIN
assets/icons/s1000.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
assets/icons/s1200n.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/icons/s1500.png
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
assets/icons/s185_mrt.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
assets/icons/s185iyor.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/icons/s185iyoy.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/icons/s185mm1.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
assets/icons/s185to_ai.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/icons/s185tu.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/icons/s185ym1.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
assets/icons/s2000_asi.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/icons/s2000n.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
assets/icons/s2002a.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/icons/s2600.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/icons/s2700.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/icons/s2700apr.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/icons/s2700apy.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/icons/s5001.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/icons/s5001k.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/icons/s6000p.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
BIN
assets/icons/s7000.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
assets/icons/s7200.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
assets/icons/s8000ap.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
assets/icons/s8000nn.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/icons/s8000no.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/icons/s8000nr.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/icons/s8600.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
assets/icons/tosa9640.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
assets/icons/tosa9640jgr.png
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
assets/icons/w213w.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
assets/icons/w285.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
@ -8,7 +8,6 @@ export const EachTrainInfo = ({ payload }) => {
|
||||
return (
|
||||
<ActionSheet
|
||||
gestureEnabled={true}
|
||||
//gestureEnabled={!actionSheetHorizonalScroll}
|
||||
CustomHeaderComponent={<></>}
|
||||
ref={actionSheetRef}
|
||||
drawUnderStatusBar={false}
|
||||
|
@ -9,9 +9,6 @@ import { trainPosition } from "../../../lib/trainPositionTextArray";
|
||||
import { TrainPositionDataPush } from "../../発車時刻表/LED_inside_Component/TrainPositionDataPush";
|
||||
import { getStationID } from "../../../lib/eachTrainInfoCoreLib/getStationData";
|
||||
import { useStationList } from "../../../stateBox/useStationList";
|
||||
import { lineList } from "../../../lib/getStationList";
|
||||
|
||||
|
||||
|
||||
export const TrainDataView = ({
|
||||
currentTrainData,
|
||||
@ -21,7 +18,6 @@ export const TrainDataView = ({
|
||||
mode = 0,
|
||||
navigate,
|
||||
}) => {
|
||||
|
||||
const { stationList } = useStationList();
|
||||
|
||||
const { width, height } = useWindowDimensions();
|
||||
@ -57,13 +53,14 @@ export const TrainDataView = ({
|
||||
return `${Pos}${platformNumber ? ` ${platformNumber}番線` : ""}`;
|
||||
};
|
||||
const [dialog, setDialog] = useState(false);
|
||||
const [deleteDialog, setDeleteDialog] = useState(false);
|
||||
const [deleteDialog, setDeleteDialog] = useState(false);
|
||||
const [posInput, setPosInput] = useState("");
|
||||
const [descInput, setDescInput] = useState("");
|
||||
const [stationInput, setStationInput] = useState("");
|
||||
const [stationNumberInput, setStationNumberInput] = useState("");
|
||||
return (<>
|
||||
<TrainPositionDataPush
|
||||
return (
|
||||
<>
|
||||
<TrainPositionDataPush
|
||||
dialog={dialog}
|
||||
setDialog={setDialog}
|
||||
currentTrainData={currentTrainData}
|
||||
@ -73,111 +70,118 @@ export const TrainDataView = ({
|
||||
descInput={descInput}
|
||||
setPosInput={setPosInput}
|
||||
setDescInput={setDescInput}
|
||||
station={{Station_JP:trainPositionText(currentTrainData),StationNumber:currentPosition[0]}} />
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
//minHeight: 200,
|
||||
//height: heightPercentageToDP("20%"),
|
||||
width: isLandscape ? (width / 100) * 40 : width,
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<TouchableOpacity
|
||||
style={{ flex: 1, flexDirection: "row" }}
|
||||
//disabled={!onLine}
|
||||
onLongPress={() => {
|
||||
const { isBetween, Pos } = trainPosition(currentTrainData);
|
||||
if (isBetween === true) {
|
||||
if (platformNumber == undefined && platformDescription == undefined)
|
||||
return;
|
||||
setStationInput(`${Pos.from}→${Pos.to}間`);
|
||||
setStationNumberInput(
|
||||
getStationID(currentTrainData?.Pos, stationList)
|
||||
);
|
||||
setPosInput(platformNumber?.toString() || "");
|
||||
setDeleteDialog(true);
|
||||
} else {
|
||||
setStationInput(Pos.Pos);
|
||||
setStationNumberInput(
|
||||
getStationID(currentTrainData?.Pos, stationList)
|
||||
);
|
||||
setDescInput(platformDescription || "");
|
||||
setPosInput(platformNumber?.toString() || "");
|
||||
setDialog(true);
|
||||
}
|
||||
station={{
|
||||
Station_JP: trainPositionText(currentTrainData),
|
||||
StationNumber: currentPosition[0],
|
||||
}}
|
||||
onPress={() => {
|
||||
if(!onLine) return;
|
||||
const test = [];
|
||||
Object.keys(mapsStationData).forEach((d) => {
|
||||
mapsStationData[d].forEach((x) => {
|
||||
if (x.StationNumber == currentPosition[0])
|
||||
test.push({ line: d, station: x });
|
||||
});
|
||||
if (currentPosition[0] == "M12") {
|
||||
test.push({
|
||||
line: "seto",
|
||||
station: { Station_JP: "児島", MyStation: "0" },
|
||||
});
|
||||
}
|
||||
});
|
||||
if (!test.length) return;
|
||||
navigate("Apps");
|
||||
inject(
|
||||
`MoveDisplayStation('${test[0].line}_${test[0].station.MyStation}_${test[0].station.Station_JP}');document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`
|
||||
);
|
||||
SheetManager.hide("EachTrainInfo");
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
//minHeight: 200,
|
||||
//height: heightPercentageToDP("20%"),
|
||||
width: isLandscape ? (width / 100) * 40 : width,
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<StateBox
|
||||
mode={mode}
|
||||
title={`現在地 ${currentPosition?.toString()}${onLine ? "▶️" : ""}`}
|
||||
text={trainPositionText(currentTrainData)}
|
||||
endText={platformDescription ? `${platformDescription}` : ""}
|
||||
style={
|
||||
onLine
|
||||
? { borderWidth: 1, borderColor: "red", borderStyle: "solid" }
|
||||
: {}
|
||||
}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={{ flex: 1, flexDirection: mode == 2 ? "row" : "column" }}>
|
||||
<View style={{ flex: 1, flexDirection: "row" }}>
|
||||
<StateBox
|
||||
mode={mode}
|
||||
title={isNaN(currentTrainData?.delay) ? "状態" : "遅延時分"}
|
||||
text={`${currentTrainData?.delay}${
|
||||
isNaN(currentTrainData?.delay) ? "" : "分"
|
||||
}`}
|
||||
/>
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
style={{ flex: 1, flexDirection: "row" }}
|
||||
disabled={nearTrainIDList.length == 0}
|
||||
//disabled={!onLine}
|
||||
onLongPress={() => {
|
||||
const { isBetween, Pos } = trainPosition(currentTrainData);
|
||||
if (isBetween === true) {
|
||||
if (
|
||||
platformNumber == undefined &&
|
||||
platformDescription == undefined
|
||||
)
|
||||
return;
|
||||
setStationInput(`${Pos.from}→${Pos.to}間`);
|
||||
setStationNumberInput(
|
||||
getStationID(currentTrainData?.Pos, stationList)
|
||||
);
|
||||
setPosInput(platformNumber?.toString() || "");
|
||||
setDeleteDialog(true);
|
||||
} else {
|
||||
setStationInput(Pos.Pos);
|
||||
setStationNumberInput(
|
||||
getStationID(currentTrainData?.Pos, stationList)
|
||||
);
|
||||
setDescInput(platformDescription || "");
|
||||
setPosInput(platformNumber?.toString() || "");
|
||||
setDialog(true);
|
||||
}
|
||||
}}
|
||||
onPress={() => {
|
||||
if (nearTrainIDList.length == 0) return;
|
||||
openTrainInfo(nearTrainIDList[0]);
|
||||
if (!onLine) return;
|
||||
const test = [];
|
||||
Object.keys(mapsStationData).forEach((d) => {
|
||||
mapsStationData[d].forEach((x) => {
|
||||
if (x.StationNumber == currentPosition[0])
|
||||
test.push({ line: d, station: x });
|
||||
});
|
||||
if (currentPosition[0] == "M12") {
|
||||
test.push({
|
||||
line: "seto",
|
||||
station: { Station_JP: "児島", MyStation: "0" },
|
||||
});
|
||||
}
|
||||
});
|
||||
if (!test.length) return;
|
||||
navigate("positions", { screen: "Apps" });
|
||||
inject(
|
||||
`MoveDisplayStation('${test[0].line}_${test[0].station.MyStation}_${test[0].station.Station_JP}');document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`
|
||||
);
|
||||
SheetManager.hide("EachTrainInfo");
|
||||
}}
|
||||
>
|
||||
{nearTrainIDList.length == 0 ? (
|
||||
<StateBox mode={mode} title="列番" text={currentTrainData?.num} />
|
||||
) : (
|
||||
<StateBox
|
||||
mode={mode}
|
||||
title={`現在地 ${currentPosition?.toString()}${onLine ? "▶️" : ""}`}
|
||||
text={trainPositionText(currentTrainData)}
|
||||
endText={platformDescription ? `${platformDescription}` : ""}
|
||||
style={
|
||||
onLine
|
||||
? { borderWidth: 1, borderColor: "red", borderStyle: "solid" }
|
||||
: {}
|
||||
}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={{ flex: 1, flexDirection: mode == 2 ? "row" : "column" }}>
|
||||
<View style={{ flex: 1, flexDirection: "row" }}>
|
||||
<StateBox
|
||||
mode={mode}
|
||||
title="増解結相手を表示▶️"
|
||||
text={`${nearTrainIDList}`}
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
borderColor: "red",
|
||||
borderStyle: "solid",
|
||||
}}
|
||||
title={isNaN(currentTrainData?.delay) ? "状態" : "遅延時分"}
|
||||
text={`${currentTrainData?.delay}${
|
||||
isNaN(currentTrainData?.delay) ? "" : "分"
|
||||
}`}
|
||||
/>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
style={{ flex: 1, flexDirection: "row" }}
|
||||
disabled={nearTrainIDList.length == 0}
|
||||
onPress={() => {
|
||||
if (nearTrainIDList.length == 0) return;
|
||||
openTrainInfo(nearTrainIDList[0]);
|
||||
}}
|
||||
>
|
||||
{nearTrainIDList.length == 0 ? (
|
||||
<StateBox mode={mode} title="列番" text={currentTrainData?.num} />
|
||||
) : (
|
||||
<StateBox
|
||||
mode={mode}
|
||||
title="増解結相手を表示▶️"
|
||||
text={`${nearTrainIDList}`}
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
borderColor: "red",
|
||||
borderStyle: "solid",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
LayoutAnimation,
|
||||
} from "react-native";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import { useScrollHandlers } from "react-native-actions-sheet";
|
||||
import { AS } from "../../storageControl";
|
||||
import trainList from "../../assets/originData/trainList";
|
||||
import { lineListPair } from "../../lib/getStationList";
|
||||
@ -188,7 +189,7 @@ export const EachTrainInfoCore = ({
|
||||
const count = position * 44 - 50;
|
||||
// 0.5秒待機してからスクロール
|
||||
setTimeout(
|
||||
() => ScrollViewRef.current?.scrollTo({ y: count, animated: true }),
|
||||
() => scrollHandlers.ref.current?.scrollTo({ y: count, animated: true }),
|
||||
400
|
||||
);
|
||||
}
|
||||
@ -219,8 +220,9 @@ export const EachTrainInfoCore = ({
|
||||
|
||||
const { height } = useWindowDimensions();
|
||||
const { isLandscape } = useDeviceOrientationChange();
|
||||
const ScrollViewRef = useRef();
|
||||
|
||||
const scrollHandlers = actionSheetRef
|
||||
? useScrollHandlers("scrollview-1", actionSheetRef)
|
||||
: null;
|
||||
const [trueTrainID, setTrueTrainID] = useState();
|
||||
useEffect(() => {
|
||||
if (!data.trainNum) return;
|
||||
@ -289,6 +291,18 @@ export const EachTrainInfoCore = ({
|
||||
} else if (pos[1] == "児島" && pos[0] == "宇多津") {
|
||||
setCurrentPosition(["Y09", "M12"]);
|
||||
return;
|
||||
}else if (pos[0] == "伊予若宮" && pos[1] == "伊予白滝") {
|
||||
setCurrentPosition(["S18", "S14"]);
|
||||
return;
|
||||
} else if (pos[0] == "伊予白滝" && pos[1] == "伊予若宮") {
|
||||
setCurrentPosition(["S14", "S18"]);
|
||||
return;
|
||||
} else if (pos[0] == "伊予大洲" && pos[1] == "伊予若宮") {
|
||||
setCurrentPosition(["U14", "U14"]);
|
||||
return;
|
||||
} else if (pos[0] == "伊予若宮" && pos[1] == "伊予大洲") {
|
||||
setCurrentPosition(["U14", "U14"]);
|
||||
return;
|
||||
}
|
||||
const currentPosID = Object.keys(originalStationList).map((key) => {
|
||||
let firstStation = false;
|
||||
@ -335,8 +349,7 @@ export const EachTrainInfoCore = ({
|
||||
.then((d) => {
|
||||
if (d) setTrainPositionSwitch(d);
|
||||
})
|
||||
//6.0で変更
|
||||
.catch(() => AS.setItem("trainPositionSwitch", "false"));
|
||||
.catch(() => AS.setItem("trainPositionSwitch", "true"));
|
||||
}, []);
|
||||
|
||||
const openTrainInfo = (d) => {
|
||||
@ -362,7 +375,7 @@ export const EachTrainInfoCore = ({
|
||||
} else {
|
||||
SheetManager.hide("EachTrainInfo").then(() => {
|
||||
//0.1秒待機してから開く
|
||||
setTimeout(() => SheetManager.show("EachTrainInfo", { payload }), 2);
|
||||
setTimeout(() => SheetManager.show("EachTrainInfo", { payload }), 200);
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -412,7 +425,7 @@ export const EachTrainInfoCore = ({
|
||||
from={from}
|
||||
styles={styles}
|
||||
actionSheetRef={actionSheetRef}
|
||||
ScrollViewRef={ScrollViewRef}
|
||||
scrollHandlers={scrollHandlers}
|
||||
containerProps={{
|
||||
style: {
|
||||
maxHeight: isLandscape ? height - 94 : (height / 100) * 70,
|
||||
|
@ -13,7 +13,7 @@ export const TrainViewIcon: FC<Props> = ({ data, navigate, from }) => {
|
||||
const [isTrainView, setIsTrainView] = useState(false);
|
||||
//トレインビュー表示対象(特急、マリン)かを判定
|
||||
useEffect(() => {
|
||||
if (!data.limited) return;
|
||||
if (!data.limited) return () => {};
|
||||
setIsTrainView(
|
||||
getType(data.limited.split(":")[0]) &&
|
||||
!data.limited.split(":")[1].match("サンポート")
|
||||
|
179
components/ActionSheetComponents/TrainIconUpdate.tsx
Normal file
@ -0,0 +1,179 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
Platform,
|
||||
Image,
|
||||
BackHandler,
|
||||
} from "react-native";
|
||||
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
||||
import ActionSheet, { SheetManager } from "react-native-actions-sheet";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import ViewShot from "react-native-view-shot";
|
||||
import * as Sharing from "expo-sharing";
|
||||
import icons from "../../assets/icons/icons";
|
||||
|
||||
import { getAppIconName } from "expo-alternate-app-icons";
|
||||
import { AS } from "@/storageControl";
|
||||
export const TrainIconUpdate = () => {
|
||||
const [iconList] = useState(icons());
|
||||
const [currentIcon] = useState(getAppIconName());
|
||||
const actionSheetRef = useRef(null);
|
||||
const insets = useSafeAreaInsets();
|
||||
const viewShot = useRef(null);
|
||||
|
||||
const onCapture = async () => {
|
||||
const url = await viewShot.current.capture();
|
||||
|
||||
const ok = await Sharing.isAvailableAsync();
|
||||
if (ok) {
|
||||
await Sharing.shareAsync(
|
||||
"file://" + url,
|
||||
(options = { mimeType: "image/jpeg", dialogTitle: "Share this image" })
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ActionSheet
|
||||
gestureEnabled
|
||||
CustomHeaderComponent={<></>}
|
||||
onClose={() => {
|
||||
AS.setItem("isSetIcon", "false");
|
||||
}}
|
||||
ref={actionSheetRef}
|
||||
isModal={Platform.OS == "ios"}
|
||||
containerStyle={
|
||||
Platform.OS == "android"
|
||||
? {
|
||||
paddingBottom: insets.bottom,
|
||||
}
|
||||
: {}
|
||||
}
|
||||
useBottomSafeAreaPadding={Platform.OS == "android"}
|
||||
>
|
||||
<Handler />
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "#0099CC",
|
||||
borderTopRadius: 5,
|
||||
borderColor: "dark",
|
||||
borderWidth: 1,
|
||||
}}
|
||||
>
|
||||
<View style={{ height: 26, width: "100%", backgroundColor: "#0099CC" }}>
|
||||
<View
|
||||
style={{
|
||||
height: 6,
|
||||
width: 45,
|
||||
borderRadius: 100,
|
||||
backgroundColor: "#f0f0f0",
|
||||
marginVertical: 10,
|
||||
alignSelf: "center",
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<ViewShot ref={viewShot} options={{ format: "jpg" }}>
|
||||
<View
|
||||
style={{
|
||||
padding: 10,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
backgroundColor: "#0099CC",
|
||||
}}
|
||||
>
|
||||
<Text style={{ fontSize: 30, fontWeight: "bold", color: "white" }}>
|
||||
アイコンを変更しました!
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
</View>
|
||||
{currentIcon ? (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
backgroundColor: "#FFFFFFEE",
|
||||
padding: 10,
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
source={iconList.filter(({ id }) => id == currentIcon)[0].icon}
|
||||
style={{
|
||||
width: 50,
|
||||
height: 50,
|
||||
padding: 30,
|
||||
borderWidth: 1,
|
||||
borderRadius: 10,
|
||||
borderColor: "white",
|
||||
margin: 10,
|
||||
backgroundColor: "white",
|
||||
}}
|
||||
/>
|
||||
<Text>JR四国非公式アプリ</Text>
|
||||
</View>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<View
|
||||
style={{
|
||||
padding: 10,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
backgroundColor: "#0099CC",
|
||||
}}
|
||||
>
|
||||
<Text style={{ fontSize: 15, fontWeight: "bold", color: "white" }}>
|
||||
JR四国非公式アプリを更新して好きなアイコンに変更してみよう!
|
||||
</Text>
|
||||
</View>
|
||||
</ViewShot>
|
||||
<View
|
||||
style={{
|
||||
padding: 10,
|
||||
backgroundColor: "#0099CC",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
padding: 10,
|
||||
flexDirection: "row",
|
||||
borderColor: "white",
|
||||
borderWidth: 1,
|
||||
margin: 10,
|
||||
borderRadius: 5,
|
||||
alignItems: "center",
|
||||
backgroundColor: "#0099CC",
|
||||
flex: 1,
|
||||
}}
|
||||
onPress={onCapture}
|
||||
>
|
||||
<MaterialCommunityIcons name="share" color="white" size={30} />
|
||||
<View style={{ flex: 1 }} />
|
||||
<Text style={{ fontSize: 25, fontWeight: "bold", color: "white" }}>
|
||||
推しアイコンをシェア
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</ActionSheet>
|
||||
);
|
||||
};
|
||||
const Handler = () => {
|
||||
useEffect(() => {
|
||||
const backAction = () => {
|
||||
SheetManager.hide("JRSTraInfo");
|
||||
return true;
|
||||
};
|
||||
const backHandler = BackHandler.addEventListener(
|
||||
"hardwareBackPress",
|
||||
backAction
|
||||
);
|
||||
return () => backHandler.remove();
|
||||
}, []);
|
||||
return <></>;
|
||||
};
|
@ -9,6 +9,7 @@ import {
|
||||
import ActionSheet, { SheetManager } from "react-native-actions-sheet";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import { useTrainMenu } from "../../stateBox/useTrainMenu";
|
||||
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
|
||||
import lineColorList from "../../assets/originData/lineColorList";
|
||||
import { stationIDPair } from "../../lib/getStationList2";
|
||||
import { lineListPair } from "../../lib/getStationList";
|
||||
@ -19,6 +20,7 @@ export const TrainMenuLineSelector = () => {
|
||||
setSelectedLine,
|
||||
mapsStationData: stationData,
|
||||
} = useTrainMenu();
|
||||
const { webview } = useCurrentTrain();
|
||||
const actionSheetRef = useRef(null);
|
||||
const insets = useSafeAreaInsets();
|
||||
const platformIs = Platform.OS == "android";
|
||||
@ -52,7 +54,25 @@ export const TrainMenuLineSelector = () => {
|
||||
}}
|
||||
onPress={() => {
|
||||
SheetManager.hide("TrainMenuLineSelector");
|
||||
setSelectedLine(selectedLine == d ? undefined : d);
|
||||
const s = selectedLine == d ? undefined : d;
|
||||
if(!s) return;
|
||||
setSelectedLine(s);
|
||||
Object.keys(stationData).forEach((data, indexBase) => {
|
||||
stationData[data].forEach((D, index) => {
|
||||
if (!D.StationMap) return null;
|
||||
if (s && s != data) return;
|
||||
const latlng = D.StationMap.replace(
|
||||
"https://www.google.co.jp/maps/place/",
|
||||
""
|
||||
).split(",");
|
||||
if (latlng.length == 0) return null;
|
||||
if (index == 0 ) {
|
||||
webview.current
|
||||
?.injectJavaScript(`MoveDisplayStation('${data}_${D.MyStation}_${D.Station_JP}');
|
||||
document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`);
|
||||
}
|
||||
});
|
||||
});
|
||||
}}
|
||||
>
|
||||
<View
|
||||
|
@ -3,10 +3,12 @@ import { EachTrainInfo } from "./EachTrainInfo";
|
||||
import { JRSTraInfo } from "./JRSTraInfo";
|
||||
import { StationDeteilView } from "./StationDeteilView";
|
||||
import { TrainMenuLineSelector } from "./TrainMenuLineSelector";
|
||||
import { TrainIconUpdate } from "./TrainIconUpdate";
|
||||
|
||||
registerSheet("EachTrainInfo", EachTrainInfo);
|
||||
registerSheet("JRSTraInfo", JRSTraInfo);
|
||||
registerSheet("StationDetailView", StationDeteilView);
|
||||
registerSheet("TrainMenuLineSelector", TrainMenuLineSelector);
|
||||
registerSheet("TrainIconUpdate", TrainIconUpdate);
|
||||
|
||||
export {};
|
||||
|
@ -20,7 +20,7 @@ import { useNavigation } from "@react-navigation/native";
|
||||
import { BigButton } from "./atom/BigButton";
|
||||
import { Switch } from "react-native-elements";
|
||||
export default function AllTrainDiagramView() {
|
||||
const { navigate } = useNavigation();
|
||||
const { goBack, navigate } = useNavigation();
|
||||
const { keyList, allTrainDiagram } = useAllTrainDiagram();
|
||||
const [input, setInput] = useState(""); // 文字入力
|
||||
const [keyBoardVisible, setKeyBoardVisible] = useState(false);
|
||||
@ -206,7 +206,7 @@ export default function AllTrainDiagramView() {
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
<BigButton
|
||||
onPress={() => navigate("menu")}
|
||||
onPress={goBack}
|
||||
string="閉じる"
|
||||
style={{
|
||||
display:
|
||||
|
@ -20,7 +20,7 @@ export const getInfoString = async () => {
|
||||
}
|
||||
return null;
|
||||
});
|
||||
ToastAndroid.show(`${text}`, ToastAndroid.SHORT);
|
||||
//ToastAndroid.show(`${text}`, ToastAndroid.SHORT);
|
||||
return { time, text };
|
||||
};
|
||||
|
||||
|
@ -20,7 +20,7 @@ export const getDelayData = async () => {
|
||||
}
|
||||
return null;
|
||||
});
|
||||
ToastAndroid.show(`${delayString}`, ToastAndroid.SHORT);
|
||||
//ToastAndroid.show(`${delayString}`, ToastAndroid.SHORT);
|
||||
return { time, delayString };
|
||||
};
|
||||
export function TraInfoEXWidget({ time, delayString }) {
|
||||
|
@ -20,11 +20,11 @@ export async function widgetTaskHandler(props) {
|
||||
const WidgetName = await AS.getItem(
|
||||
`widgetType/${widgetInfo.widgetId}`
|
||||
).catch((e) => "JR_shikoku_train_info");
|
||||
ToastAndroid.show(
|
||||
`Widget Action: ${JSON.stringify(widgetInfo.widgetId)}`,
|
||||
ToastAndroid.SHORT
|
||||
);
|
||||
ToastAndroid.show(`Widget Name: ${WidgetName}`, ToastAndroid.SHORT);
|
||||
// ToastAndroid.show(
|
||||
// `Widget Action: ${JSON.stringify(widgetInfo.widgetId)}`,
|
||||
// ToastAndroid.SHORT
|
||||
// );
|
||||
//ToastAndroid.show(`Widget Name: ${WidgetName}`, ToastAndroid.SHORT);
|
||||
switch (widgetAction) {
|
||||
case "WIDGET_ADDED":
|
||||
case "WIDGET_UPDATE":
|
||||
|
@ -60,7 +60,7 @@ export default function Apps() {
|
||||
useShow: () => SheetManager.show("StationDetailView", { payload }),
|
||||
onExit: () => SheetManager.hide("StationDetailView"),
|
||||
};
|
||||
SheetManager.show("StationDetailView", { payload });
|
||||
setTimeout(()=>SheetManager.show("StationDetailView", { payload }),50);
|
||||
} else {
|
||||
SheetManager.hide("StationDetailView");
|
||||
}
|
||||
|
@ -4,12 +4,12 @@ import { useCurrentTrain } from "../stateBox/useCurrentTrain";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { BigButton } from "./atom/BigButton";
|
||||
export default function CurrentTrainListView() {
|
||||
const { navigate } = useNavigation();
|
||||
const { goBack } = useNavigation();
|
||||
const { currentTrain } = useCurrentTrain();
|
||||
return (
|
||||
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
||||
{currentTrain && currentTrain.map((d) => <Text>{d.num}</Text>)}
|
||||
<BigButton onPress={() => navigate("menu")} string="閉じる" />
|
||||
<BigButton onPress={goBack} string="閉じる" />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ScrollView, View, Animated, LayoutAnimation } from "react-native";
|
||||
import React, { useEffect, useMemo, useState, useLayoutEffect } from "react";
|
||||
import { useScrollHandlers } from "react-native-actions-sheet";
|
||||
import { NativeViewGestureHandler } from "react-native-gesture-handler";
|
||||
import { AS } from "../storageControl";
|
||||
|
||||
export const DynamicHeaderScrollView = (props) => {
|
||||
@ -13,7 +13,7 @@ export const DynamicHeaderScrollView = (props) => {
|
||||
topStickyContent,
|
||||
styles,
|
||||
from,
|
||||
ScrollViewRef,
|
||||
scrollHandlers,
|
||||
} = props;
|
||||
const [headerSize, setHeaderSize] = useState("default");
|
||||
useLayoutEffect(() => {
|
||||
@ -53,9 +53,7 @@ export const DynamicHeaderScrollView = (props) => {
|
||||
|
||||
const Scroll_Distance = Max_Header_Height - Min_Header_Height;
|
||||
|
||||
const scrollHandlers = actionSheetRef
|
||||
? useScrollHandlers("scrollview-1", actionSheetRef)
|
||||
: null;
|
||||
|
||||
|
||||
const shotHeaderStyle = {
|
||||
on: {
|
||||
@ -110,6 +108,7 @@ export const DynamicHeaderScrollView = (props) => {
|
||||
const [headerVisible, setHeaderVisible] = useState(false);
|
||||
|
||||
const onScroll = (event) => {
|
||||
scrollHandlers.onScroll(event);
|
||||
switch (headerSize) {
|
||||
case "big":
|
||||
setHeaderVisible(false);
|
||||
@ -153,26 +152,31 @@ export const DynamicHeaderScrollView = (props) => {
|
||||
{topStickyContent}
|
||||
</Animated.View>
|
||||
</View>
|
||||
<ScrollView
|
||||
{...scrollHandlers}
|
||||
style={{ backgroundColor: "white", zIndex: 0 }}
|
||||
stickyHeaderIndices={[1]}
|
||||
scrollEventThrottle={16}
|
||||
onScroll={onScroll}
|
||||
ref={ScrollViewRef}
|
||||
<NativeViewGestureHandler
|
||||
simultaneousHandlers={scrollHandlers.simultaneousHandlers}
|
||||
>
|
||||
<View style={{ height: Scroll_Distance, flexDirection: "column" }} />
|
||||
{topStickyContent && (
|
||||
<View
|
||||
style={{
|
||||
paddingTop: Min_Header_Height + 40,
|
||||
flexDirection: "column",
|
||||
}}
|
||||
index={1}
|
||||
/>
|
||||
)}
|
||||
{children}
|
||||
</ScrollView>
|
||||
<ScrollView
|
||||
nestedScrollEnabled
|
||||
ref={scrollHandlers.ref}
|
||||
onLayout={scrollHandlers.onLayout}
|
||||
scrollEventThrottle={scrollHandlers.scrollEventThrottle}
|
||||
style={{ backgroundColor: "white", zIndex: 0 }}
|
||||
stickyHeaderIndices={[1]}
|
||||
onScroll={onScroll}
|
||||
>
|
||||
<View style={{ height: Scroll_Distance, flexDirection: "column" }} />
|
||||
{topStickyContent && (
|
||||
<View
|
||||
style={{
|
||||
paddingTop: Min_Header_Height + 40,
|
||||
flexDirection: "column",
|
||||
}}
|
||||
index={1}
|
||||
/>
|
||||
)}
|
||||
{children}
|
||||
</ScrollView>
|
||||
</NativeViewGestureHandler>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { View, Text, TouchableOpacity, ScrollView } from "react-native";
|
||||
import React, { useEffect } from "react";
|
||||
import { View, Text, ScrollView } from "react-native";
|
||||
|
||||
import Icon from "react-native-vector-icons/Entypo";
|
||||
import { useFavoriteStation } from "../stateBox/useFavoriteStation";
|
||||
@ -11,9 +11,18 @@ import { BigButton } from "./atom/BigButton";
|
||||
export default function FavoriteList() {
|
||||
const { favoriteStation } = useFavoriteStation();
|
||||
const { webview } = useCurrentTrain();
|
||||
const { navigate, goBack } = useNavigation();
|
||||
const { navigate, addListener, goBack, canGoBack } = useNavigation();
|
||||
const { mapsStationData: stationData } = useTrainMenu();
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = addListener("tabPress", goToTrainMenu);
|
||||
return unsubscribe;
|
||||
}, [{ navigate, addListener }]);
|
||||
|
||||
const goToTrainMenu = (e) => {
|
||||
e.preventDefault();
|
||||
goBack();
|
||||
};
|
||||
return (
|
||||
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
||||
<Text
|
||||
@ -50,7 +59,8 @@ export default function FavoriteList() {
|
||||
`MoveDisplayStation('${lineName}_${currentStation[0].MyStation}_${currentStation[0].Station_JP}');
|
||||
document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`
|
||||
);
|
||||
navigate("Apps");
|
||||
goBack();
|
||||
if (canGoBack()) goBack();
|
||||
}}
|
||||
>
|
||||
<View
|
||||
|
@ -5,10 +5,11 @@ import {
|
||||
Ionicons,
|
||||
MaterialCommunityIcons,
|
||||
} from "@expo/vector-icons";
|
||||
import { ListItem } from "@rneui/themed";
|
||||
import TouchableScale from 'react-native-touchable-scale';
|
||||
import Icon from "react-native-vector-icons/Entypo";
|
||||
import { TextBox } from "../atom/TextBox";
|
||||
import { TicketBox } from "../atom/TicketBox";
|
||||
import { ListItem } from "native-base";
|
||||
|
||||
export const FixedContentBottom = (props) => {
|
||||
return (
|
||||
@ -249,10 +250,16 @@ export const FixedContentBottom = (props) => {
|
||||
name: "しこくたぬきのぽんちゃん 【四国家サポーターズクラブ】",
|
||||
},
|
||||
].map((d) => (
|
||||
<ListItem onPress={() => Linking.openURL(d.url)}>
|
||||
<Text>{d.name}</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Icon name="chevron-right" size={20} />
|
||||
<ListItem bottomDivider onPress={() => Linking.openURL(d.url)}
|
||||
key={d.url}friction={90} //
|
||||
tension={100} // These props are passed to the parent component (here TouchableScale)
|
||||
activeScale={0.95} //
|
||||
Component={TouchableScale}
|
||||
>
|
||||
<ListItem.Content>
|
||||
<ListItem.Title>{d.name}</ListItem.Title>
|
||||
</ListItem.Content>
|
||||
<ListItem.Chevron />
|
||||
</ListItem>
|
||||
))}
|
||||
</View>
|
||||
|
27
components/Menu/SimpleDot.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import React, { FC } from "react";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { TouchableOpacity } from "react-native";
|
||||
type SimpleDotProps = {
|
||||
active: boolean;
|
||||
onPress: () => void;
|
||||
};
|
||||
export const SimpleDot: FC<SimpleDotProps> = (props) => {
|
||||
const { active, onPress } = props;
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
width: 20,
|
||||
marginHorizontal: 2,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
onPress={onPress}
|
||||
>
|
||||
<Ionicons
|
||||
name="ellipse"
|
||||
size={active ? 20 : 14}
|
||||
color={active ? "#00b8ff" : "#00b8ff55"}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
@ -1,6 +1,5 @@
|
||||
import React, { FC, useState } from "react";
|
||||
import { View, Text, TouchableOpacity } from "react-native";
|
||||
import { Pagination } from "react-native-snap-carousel";
|
||||
import { useInterval } from "../../lib/useInterval";
|
||||
|
||||
import lineColorList from "../../assets/originData/lineColorList";
|
||||
@ -18,78 +17,6 @@ type StationProps = {
|
||||
lat: number;
|
||||
lng: number;
|
||||
};
|
||||
type StationPaginationProps = {
|
||||
entries: StationProps[][];
|
||||
activeSlide: number;
|
||||
carouselRef: any;
|
||||
setSelectedCurrentStation: React.Dispatch<React.SetStateAction<number>>;
|
||||
dotButton: boolean;
|
||||
};
|
||||
|
||||
export const Paginations: FC<StationPaginationProps> = (props) => {
|
||||
const {
|
||||
entries,
|
||||
activeSlide,
|
||||
carouselRef,
|
||||
setSelectedCurrentStation,
|
||||
dotButton,
|
||||
} = props;
|
||||
return (
|
||||
<Pagination
|
||||
dotsLength={entries.length}
|
||||
activeDotIndex={activeSlide}
|
||||
carouselRef={carouselRef}
|
||||
containerStyle={{ paddingVertical: 0 }}
|
||||
dotStyle={{
|
||||
width: 12,
|
||||
height: 12,
|
||||
borderRadius: 6,
|
||||
backgroundColor: "#0099CC",
|
||||
}}
|
||||
inactiveDotStyle={
|
||||
{
|
||||
// Define styles for inactive dots here
|
||||
}
|
||||
}
|
||||
tappableDots={true}
|
||||
inactiveDotOpacity={0.4}
|
||||
inactiveDotScale={0.8}
|
||||
inactiveDotElement={
|
||||
dotButton && (
|
||||
<StationNumberMaker
|
||||
currentStations={entries}
|
||||
setSelectedCurrentStation={setSelectedCurrentStation}
|
||||
/>
|
||||
)
|
||||
}
|
||||
dotElement={
|
||||
dotButton && (
|
||||
<StationNumberMaker
|
||||
currentStations={entries}
|
||||
setSelectedCurrentStation={setSelectedCurrentStation}
|
||||
/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
type StationNumberMakerProps = {
|
||||
currentStations: StationProps[][];
|
||||
setSelectedCurrentStation: React.Dispatch<React.SetStateAction<number>>;
|
||||
active?: boolean;
|
||||
index?: number;
|
||||
};
|
||||
export const StationNumberMaker: FC<StationNumberMakerProps> = (props) => {
|
||||
const { currentStations, active, index, setSelectedCurrentStation } = props;
|
||||
return (
|
||||
<StationNumber
|
||||
currentStation={currentStations[index]}
|
||||
active={active}
|
||||
onPress={() => setSelectedCurrentStation(index)}
|
||||
key={currentStations[index][0].StationNumber}
|
||||
/>
|
||||
);
|
||||
};
|
||||
type StationNumberProps = {
|
||||
currentStation: StationProps[];
|
||||
active: boolean;
|
||||
@ -107,41 +34,42 @@ export const StationNumber: FC<StationNumberProps> = (props) => {
|
||||
const lineID = data[animation].StationNumber.slice(0, 1);
|
||||
const lineName = data[animation].StationNumber.slice(1);
|
||||
const size = active ? 24 : 18;
|
||||
const margin = active ? 3 : 6;
|
||||
const border = active ? 2 : 1;
|
||||
return (
|
||||
<>
|
||||
<TouchableOpacity
|
||||
onPress={onPress} style={{
|
||||
width: 28,
|
||||
height:24,
|
||||
alignContent:"center",
|
||||
alignItems:"center",
|
||||
justifyContent:"center",
|
||||
position:"relative",
|
||||
}}>
|
||||
{active && (
|
||||
<View style={{ position: "relative", width: 0, height: 0 }}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
position: "absolute",
|
||||
width: 28,
|
||||
height: 28,
|
||||
marginLeft: 1,
|
||||
marginRight: 1,
|
||||
marginHorizontal:1,
|
||||
borderRadius: 22,
|
||||
borderColor: "black",
|
||||
borderWidth: 2,
|
||||
left: 0,
|
||||
top: -14,
|
||||
left: -1,
|
||||
top: -2,
|
||||
zIndex:10
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
<TouchableOpacity
|
||||
onPress={onPress}
|
||||
<View
|
||||
style={{
|
||||
alignContent: "center",
|
||||
alignItems: "center",
|
||||
width: size,
|
||||
height: size,
|
||||
marginLeft: margin,
|
||||
marginRight: margin,
|
||||
borderColor: lineColorList[lineID],
|
||||
backgroundColor: "white",
|
||||
borderWidth: border,
|
||||
borderWidth: active ? 2 : 1,
|
||||
borderRadius: 22,
|
||||
}}
|
||||
key={currentStation[0].StationNumber + lineID}
|
||||
@ -161,7 +89,7 @@ export const StationNumber: FC<StationNumberProps> = (props) => {
|
||||
{lineID + "\n" + lineName}
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
@ -1,17 +1,19 @@
|
||||
import React from "react";
|
||||
import { View, Text, TouchableOpacity, ScrollView } from "react-native";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { useFavoriteStation } from "../../stateBox/useFavoriteStation";
|
||||
import { CheckBox } from "react-native-elements";
|
||||
import { FavoriteSettingsItem } from "./FavoliteSettings/FavoiliteSettingsItem";
|
||||
|
||||
export const FavoriteSettings = ({ navigate }) => {
|
||||
export const FavoriteSettings = () => {
|
||||
const { favoriteStation, setFavoriteStation } = useFavoriteStation();
|
||||
const { goBack } = useNavigation();
|
||||
return (
|
||||
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
||||
<View style={{ backgroundColor: "#0099CC", flexDirection: "row" }}>
|
||||
<View style={{ flex: 1 }}>
|
||||
<TouchableOpacity
|
||||
onPress={() => navigate("settingTopPage")}
|
||||
onPress={goBack}
|
||||
style={{
|
||||
flexDirection: "column",
|
||||
flex: 1,
|
||||
|
154
components/Settings/LauncherIconSettings.js
Normal file
@ -0,0 +1,154 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
ScrollView,
|
||||
Image,
|
||||
ToastAndroid,
|
||||
Platform,
|
||||
} from "react-native";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import * as Updates from "expo-updates";
|
||||
import { AS } from "../../storageControl";
|
||||
import icons from "../../assets/icons/icons";
|
||||
import { setAlternateAppIcon, getAppIconName } from "expo-alternate-app-icons";
|
||||
import { widthPercentageToDP } from "react-native-responsive-screen";
|
||||
|
||||
export const LauncherIconSettings = ({ navigate }) => {
|
||||
const { goBack } = useNavigation();
|
||||
const [iconList] = useState(icons());
|
||||
const [currentIcon] = useState(getAppIconName());
|
||||
return (
|
||||
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
||||
<View style={{ backgroundColor: "#0099CC", flexDirection: "row" }}>
|
||||
<View style={{ flex: 1 }}>
|
||||
<TouchableOpacity
|
||||
onPress={goBack}
|
||||
style={{
|
||||
flexDirection: "column",
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
fontWeight: "bold",
|
||||
textAlign: "left",
|
||||
textAlignVertical: "center",
|
||||
color: "white",
|
||||
padding: 10,
|
||||
}}
|
||||
>
|
||||
< 設定
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
fontWeight: "bold",
|
||||
textAlign: "center",
|
||||
color: "white",
|
||||
padding: 10,
|
||||
}}
|
||||
>
|
||||
アイコン設定
|
||||
</Text>
|
||||
<View style={{ flex: 1 }}></View>
|
||||
</View>
|
||||
<ScrollView style={{ flex: 1, backgroundColor: "white" }}>
|
||||
{currentIcon ? (
|
||||
<>
|
||||
<Text
|
||||
style={{
|
||||
backgroundColor: "#DDDDDD",
|
||||
}}
|
||||
>
|
||||
現在のアイコン:
|
||||
{iconList.filter(({ id }) => id == currentIcon)[0].id}
|
||||
</Text>
|
||||
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "cokumn",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
backgroundColor: "#DDDDDD",
|
||||
padding: 10,
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
source={iconList.filter(({ id }) => id == currentIcon)[0].icon}
|
||||
style={{
|
||||
width: 50,
|
||||
height: 50,
|
||||
padding: 30,
|
||||
borderWidth: 1,
|
||||
borderRadius: 10,
|
||||
borderColor: "white",
|
||||
margin: 10,
|
||||
backgroundColor: "white",
|
||||
}}
|
||||
/>
|
||||
<Text>JR四国非公式アプリ</Text>
|
||||
</View>
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap",
|
||||
alignContent: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
{iconList.map(({ name, icon, id }) => {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
key={id}
|
||||
style={{
|
||||
margin: 10,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
width: widthPercentageToDP("30%"),
|
||||
maxWidth: 60,
|
||||
height: 100,
|
||||
|
||||
borderColor: "#999999",
|
||||
borderWidth: id == currentIcon ? 2 : 0,
|
||||
borderRadius: 10,
|
||||
}}
|
||||
onPress={() => {
|
||||
setAlternateAppIcon(id)
|
||||
.then((res) => {
|
||||
AS.setItem("isSetIcon", "true");
|
||||
if (Platform.OS === "android") {
|
||||
ToastAndroid.show(
|
||||
"アイコンを変更しました。アプリを再起動します。",
|
||||
ToastAndroid.SHORT
|
||||
);
|
||||
} else if (Platform.OS === "ios") {
|
||||
Updates.reloadAsync();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
alert(err);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Image source={icon} style={{ width: 50, height: 50 }} />
|
||||
<Text>{id}</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
};
|
@ -1,5 +1,6 @@
|
||||
import React from "react";
|
||||
import { View, Text, TouchableOpacity, ScrollView } from "react-native";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { SwitchArea } from "../atom/SwitchArea";
|
||||
import { CheckBox } from "react-native-elements";
|
||||
import { TripleSwitchArea } from "../atom/TripleSwitchArea";
|
||||
@ -21,12 +22,13 @@ export const LayoutSettings = ({
|
||||
headerSize,
|
||||
setHeaderSize,
|
||||
}) => {
|
||||
const { goBack } = useNavigation();
|
||||
return (
|
||||
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
||||
<View style={{ backgroundColor: "#0099CC", flexDirection: "row" }}>
|
||||
<View style={{ flex: 1 }}>
|
||||
<TouchableOpacity
|
||||
onPress={() => navigate("settingTopPage")}
|
||||
onPress={goBack}
|
||||
style={{
|
||||
flexDirection: "column",
|
||||
flex: 1,
|
||||
|
@ -1,12 +1,15 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { View, Text, TouchableOpacity, ScrollView,Clipboard } from "react-native";
|
||||
import { View, Text, TouchableOpacity, ScrollView } from "react-native";
|
||||
import * as Clipboard from 'expo-clipboard';
|
||||
|
||||
import { CheckBox } from "react-native-elements";
|
||||
import { AS } from "../../storageControl";
|
||||
import { useNotification } from "../../stateBox/useNotifications";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
|
||||
export const NotificationSettings = ({ navigate }) => {
|
||||
export const NotificationSettings = () => {
|
||||
const { expoPushToken } = useNotification();
|
||||
const { goBack } = useNavigation();
|
||||
const [traInfoEX, setTraInfoEX] = useState(false);
|
||||
const [informations, setInformations] = useState(false);
|
||||
const [strangeTrain, setStrangeTrain] = useState(false);
|
||||
@ -21,9 +24,7 @@ export const NotificationSettings = ({ navigate }) => {
|
||||
<View style={{ backgroundColor: "#0099CC", flexDirection: "row" }}>
|
||||
<View style={{ flex: 1 }}>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
navigate("settingTopPage");
|
||||
}}
|
||||
onPress={goBack}
|
||||
style={{
|
||||
flexDirection: "column",
|
||||
flex: 1,
|
||||
@ -40,7 +41,7 @@ export const NotificationSettings = ({ navigate }) => {
|
||||
padding: 10,
|
||||
}}
|
||||
>
|
||||
< 設定/送信
|
||||
< 設定
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
</TouchableOpacity>
|
||||
@ -79,7 +80,7 @@ export const NotificationSettings = ({ navigate }) => {
|
||||
AS.setItem("traInfoEX", traInfoEX.toString()),
|
||||
AS.setItem("informations", informations.toString()),
|
||||
AS.setItem("strangeTrain", strangeTrain.toString()),
|
||||
]).then(()=>alert("通知の設定を保存、登録しました"));
|
||||
]).then(() => alert("通知の設定を保存、登録しました"));
|
||||
});
|
||||
}}
|
||||
style={{
|
||||
@ -120,9 +121,10 @@ export const NotificationSettings = ({ navigate }) => {
|
||||
setBool={setStrangeTrain}
|
||||
str="怪レい列車"
|
||||
/>
|
||||
<Text style={{fontWeight: "bold", padding: 10 }} onPress={()=>{
|
||||
Clipboard.setString(expoPushToken);
|
||||
}}>
|
||||
<Text
|
||||
style={{ fontWeight: "bold", padding: 10 }}
|
||||
onPress={() => Clipboard.setStringAsync(expoPushToken)}
|
||||
>
|
||||
通知を受け取りたい項目を選択してください。チェックボックスを選び、右上の「登録実行」を押すと設定が反映され、通知が届くようになります。
|
||||
</Text>
|
||||
</ScrollView>
|
||||
|
@ -10,14 +10,15 @@ import {
|
||||
} from "react-native";
|
||||
import * as Updates from "expo-updates";
|
||||
import { useWindowDimensions } from "react-native";
|
||||
import { ListItem } from "native-base";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { ListItem } from "@rneui/themed";
|
||||
import TouchableScale from "react-native-touchable-scale";
|
||||
import { SwitchArea } from "../atom/SwitchArea";
|
||||
import { useNotification } from "../../stateBox/useNotifications";
|
||||
|
||||
const versionCode = "5.6.0.2";
|
||||
const versionCode = "6.0";
|
||||
|
||||
export const SettingTopPage = ({
|
||||
navigate,
|
||||
testNFC,
|
||||
startPage,
|
||||
setStartPage,
|
||||
@ -25,12 +26,13 @@ export const SettingTopPage = ({
|
||||
}) => {
|
||||
const { width } = useWindowDimensions();
|
||||
const { expoPushToken } = useNotification();
|
||||
const navigation = useNavigation();
|
||||
return (
|
||||
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
||||
<View style={{ backgroundColor: "#0099CC", flexDirection: "row" }}>
|
||||
<View style={{ flex: 1 }}>
|
||||
<TouchableOpacity
|
||||
onPress={() => navigate("menu")}
|
||||
onPress={() => navigation.goBack()}
|
||||
style={{
|
||||
flexDirection: "column",
|
||||
flex: 1,
|
||||
@ -118,179 +120,63 @@ export const SettingTopPage = ({
|
||||
falseText={"リンクメニュー"}
|
||||
trueText={"列車位置情報"}
|
||||
/>
|
||||
<ListItem
|
||||
style={{ flexDirection: "row" }}
|
||||
onPress={() => navigate("FavoriteSettings")}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
alignItems: "center",
|
||||
alignContent: "center",
|
||||
textAlign: "center",
|
||||
textAlignVertical: "center",
|
||||
}}
|
||||
>
|
||||
お気に入り登録の並び替え
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
alignItems: "center",
|
||||
alignContent: "center",
|
||||
textAlign: "center",
|
||||
textAlignVertical: "center",
|
||||
}}
|
||||
>
|
||||
{">"}
|
||||
</Text>
|
||||
</ListItem>
|
||||
<ListItem
|
||||
style={{ flexDirection: "row" }}
|
||||
onPress={() => navigate("NotificationSettings")}
|
||||
<SettingList
|
||||
string="お気に入り登録の並び替え"
|
||||
onPress={() =>
|
||||
navigation.navigate("setting", { screen: "FavoriteSettings" })
|
||||
}
|
||||
/>
|
||||
<SettingList
|
||||
string={`通知設定${
|
||||
expoPushToken == "" ? "(通知設定をオンにしてください)" : "(β)"
|
||||
}`}
|
||||
onPress={() =>
|
||||
navigation.navigate("setting", { screen: "NotificationSettings" })
|
||||
}
|
||||
disabled={expoPushToken == ""}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
alignItems: "center",
|
||||
alignContent: "center",
|
||||
textAlign: "center",
|
||||
textAlignVertical: "center",
|
||||
}}
|
||||
>
|
||||
通知設定{expoPushToken == "" ? "(通知設定をオンにしてください)" : "(β)"}
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
alignItems: "center",
|
||||
alignContent: "center",
|
||||
textAlign: "center",
|
||||
textAlignVertical: "center",
|
||||
}}
|
||||
>
|
||||
{">"}
|
||||
</Text>
|
||||
</ListItem>
|
||||
<ListItem
|
||||
style={{ flexDirection: "row" }}
|
||||
onPress={() => navigate("LayoutSettings")}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
alignItems: "center",
|
||||
alignContent: "center",
|
||||
textAlign: "center",
|
||||
textAlignVertical: "center",
|
||||
}}
|
||||
>
|
||||
レイアウト設定
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
alignItems: "center",
|
||||
alignContent: "center",
|
||||
textAlign: "center",
|
||||
textAlignVertical: "center",
|
||||
}}
|
||||
>
|
||||
{">"}
|
||||
</Text>
|
||||
</ListItem>
|
||||
/>
|
||||
|
||||
<SettingList
|
||||
string="レイアウト設定"
|
||||
onPress={() =>
|
||||
navigation.navigate("setting", { screen: "LayoutSettings" })
|
||||
}
|
||||
/>
|
||||
{Platform.OS === "android" ? (
|
||||
<ListItem
|
||||
style={{ flexDirection: "row" }}
|
||||
onPress={() => navigate("WidgetSettings")}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
alignItems: "center",
|
||||
alignContent: "center",
|
||||
textAlign: "center",
|
||||
textAlignVertical: "center",
|
||||
}}
|
||||
>
|
||||
ウィジェット設定
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
alignItems: "center",
|
||||
alignContent: "center",
|
||||
textAlign: "center",
|
||||
textAlignVertical: "center",
|
||||
}}
|
||||
>
|
||||
{">"}
|
||||
</Text>
|
||||
</ListItem>
|
||||
<SettingList
|
||||
string="ウィジェット設定"
|
||||
onPress={() =>
|
||||
navigation.navigate("setting", { screen: "WidgetSettings" })
|
||||
}
|
||||
/>
|
||||
) : null}
|
||||
<ListItem
|
||||
style={{ flexDirection: "row" }}
|
||||
<SettingList
|
||||
string="アイコン設定"
|
||||
onPress={() =>
|
||||
navigation.navigate("setting", { screen: "LauncherIconSettings" })
|
||||
}
|
||||
/>
|
||||
<SettingList
|
||||
string="プライバシーポリシー"
|
||||
onPress={() =>
|
||||
Linking.openURL(
|
||||
"https://nexcloud.haruk.in/sites/press-harukin/JRShikokuApps/policy"
|
||||
)
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
alignItems: "center",
|
||||
alignContent: "center",
|
||||
textAlign: "center",
|
||||
textAlignVertical: "center",
|
||||
}}
|
||||
>
|
||||
プライバシーポリシー
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
</ListItem>
|
||||
<ListItem
|
||||
style={{ flexDirection: "row" }}
|
||||
/>
|
||||
|
||||
<SettingList
|
||||
string="開発情報"
|
||||
onPress={() =>
|
||||
Linking.openURL("https://nexcloud.haruk.in/s/2WFEN5oLPGtrRqT")
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
alignItems: "center",
|
||||
alignContent: "center",
|
||||
textAlign: "center",
|
||||
textAlignVertical: "center",
|
||||
}}
|
||||
>
|
||||
開発情報
|
||||
</Text>
|
||||
/>
|
||||
|
||||
<View style={{ flex: 1 }} />
|
||||
</ListItem>
|
||||
<ListItem
|
||||
style={{ flexDirection: "row" }}
|
||||
<SettingList
|
||||
string="運営Twitter"
|
||||
onPress={() => Linking.openURL("https://twitter.com/Xprocess_main")}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 20,
|
||||
alignItems: "center",
|
||||
alignContent: "center",
|
||||
textAlign: "center",
|
||||
textAlignVertical: "center",
|
||||
}}
|
||||
>
|
||||
運営Twitter
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
</ListItem>
|
||||
/>
|
||||
|
||||
{/* <ListItem style={{ flexDirection: "row" }} onPress={() => testNFC()}>
|
||||
<Text
|
||||
style={{
|
||||
@ -328,3 +214,20 @@ export const SettingTopPage = ({
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const SettingList = ({ string, onPress, disabled }) => {
|
||||
return (
|
||||
<ListItem
|
||||
activeScale={0.95}
|
||||
Component={TouchableScale}
|
||||
bottomDivider
|
||||
onPress={onPress}
|
||||
disabled={disabled}
|
||||
>
|
||||
<ListItem.Content>
|
||||
<ListItem.Title>{string}</ListItem.Title>
|
||||
</ListItem.Content>
|
||||
<ListItem.Chevron />
|
||||
</ListItem>
|
||||
);
|
||||
};
|
||||
|
@ -1,8 +1,7 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { View, Text, TouchableOpacity, ScrollView } from "react-native";
|
||||
import { SwitchArea } from "../atom/SwitchArea";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { CheckBox } from "react-native-elements";
|
||||
import { TripleSwitchArea } from "../atom/TripleSwitchArea";
|
||||
import { getWidgetInfo, WidgetPreview } from "react-native-android-widget";
|
||||
import { getDelayData } from "../AndroidWidget/TraInfoEXWidget";
|
||||
import { getInfoString } from "../AndroidWidget/InfoWidget";
|
||||
@ -12,6 +11,7 @@ import { ListItem } from "native-base";
|
||||
|
||||
export const WidgetSettings = ({ navigate }) => {
|
||||
const { JR_shikoku_train_info, Info_Widget } = nameToWidget;
|
||||
const { goBack } = useNavigation();
|
||||
const [time, setTime] = useState();
|
||||
const [delayString, setDelayString] = useState();
|
||||
const [trainInfo, setTrainInfo] = useState();
|
||||
@ -25,7 +25,9 @@ export const WidgetSettings = ({ navigate }) => {
|
||||
setWidgetList(d);
|
||||
};
|
||||
|
||||
useEffect(reload, []);
|
||||
useEffect(() => {
|
||||
reload();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
getDelayData().then(({ time, delayString }) => {
|
||||
@ -42,7 +44,7 @@ export const WidgetSettings = ({ navigate }) => {
|
||||
<View style={{ backgroundColor: "#0099CC", flexDirection: "row" }}>
|
||||
<View style={{ flex: 1 }}>
|
||||
<TouchableOpacity
|
||||
onPress={() => navigate("settingTopPage")}
|
||||
onPress={goBack}
|
||||
style={{
|
||||
flexDirection: "column",
|
||||
flex: 1,
|
||||
|
@ -8,10 +8,11 @@ import {
|
||||
Image,
|
||||
useWindowDimensions,
|
||||
ToastAndroid,
|
||||
Platform
|
||||
} from "react-native";
|
||||
import { createStackNavigator } from "@react-navigation/stack";
|
||||
import { TransitionPresets } from "@react-navigation/stack";
|
||||
import * as ExpoFelicaReader from "../../modules/expo-felica-reader/src";
|
||||
//import * as ExpoFelicaReader from "../../modules/expo-felica-reader/src";
|
||||
import * as Updates from "expo-updates";
|
||||
import StatusbarDetect from "../../StatusbarDetect";
|
||||
import { AS } from "../../storageControl";
|
||||
@ -23,6 +24,7 @@ import { LayoutSettings } from "./LayoutSettings";
|
||||
import { FavoriteSettings } from "./FavoriteSettings";
|
||||
import { WidgetSettings } from "./WidgetSettings";
|
||||
import { NotificationSettings } from "./NotificationSettings";
|
||||
import { LauncherIconSettings } from "./LauncherIconSettings";
|
||||
|
||||
const Stack = createStackNavigator();
|
||||
export default function Setting(props) {
|
||||
@ -48,8 +50,8 @@ export default function Setting(props) {
|
||||
AS.getItem("startPage").then(setStartPage);
|
||||
}, []);
|
||||
const testNFC = async () => {
|
||||
const result = await ExpoFelicaReader.scan();
|
||||
alert(result);
|
||||
//const result = await ExpoFelicaReader.scan();
|
||||
//alert(result);
|
||||
};
|
||||
const updateAndReload = () => {
|
||||
Promise.all([
|
||||
@ -136,7 +138,7 @@ export default function Setting(props) {
|
||||
/>
|
||||
)}
|
||||
</Stack.Screen>
|
||||
<Stack.Screen
|
||||
{Platform.OS === 'android' && <Stack.Screen
|
||||
name="WidgetSettings"
|
||||
options={{
|
||||
gestureEnabled: true,
|
||||
@ -147,6 +149,18 @@ export default function Setting(props) {
|
||||
}}
|
||||
>
|
||||
{(props) => <WidgetSettings {...props} navigate={navigate} />}
|
||||
</Stack.Screen>}
|
||||
<Stack.Screen
|
||||
name="LauncherIconSettings"
|
||||
options={{
|
||||
gestureEnabled: true,
|
||||
...TransitionPresets.SlideFromRightIOS,
|
||||
cardOverlayEnabled: true,
|
||||
headerTransparent: true,
|
||||
headerShown: false,
|
||||
}}
|
||||
>
|
||||
{(props) => <LauncherIconSettings {...props} navigate={navigate} />}
|
||||
</Stack.Screen>
|
||||
<Stack.Screen
|
||||
name="FavoriteSettings"
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React, { FC } from "react";
|
||||
import { Marker } from "react-native-maps";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
type Props = {
|
||||
index: number;
|
||||
indexBase: number;
|
||||
@ -12,6 +13,7 @@ type Props = {
|
||||
|
||||
export const MapPin: FC<Props> = (props) => {
|
||||
const { index, indexBase, latlng, D, d, navigate, webview } = props;
|
||||
const {goBack} = useNavigation();
|
||||
return (
|
||||
<Marker
|
||||
key={index + indexBase}
|
||||
@ -24,7 +26,7 @@ export const MapPin: FC<Props> = (props) => {
|
||||
`MoveDisplayStation('${d}_${D.MyStation}_${D.Station_JP}');
|
||||
document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`
|
||||
);
|
||||
if (navigate) navigate("Apps");
|
||||
if (navigate) goBack();
|
||||
}}
|
||||
image={require("../../assets/reccha-small.png")}
|
||||
></Marker>
|
||||
|
@ -6,7 +6,7 @@ import { news } from "../config/newsUpdate";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { BigButton } from "./atom/BigButton";
|
||||
const News: FC = () => {
|
||||
const { navigate } = useNavigation();
|
||||
const { goBack } = useNavigation();
|
||||
return (
|
||||
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
|
||||
<WebView
|
||||
@ -20,7 +20,7 @@ const News: FC = () => {
|
||||
<BigButton
|
||||
onPress={() => {
|
||||
AS.setItem("status", news);
|
||||
navigate("Apps");
|
||||
goBack();
|
||||
}}
|
||||
string="更新情報を閉じる"
|
||||
/>
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React, { useRef, useState, useEffect, useLayoutEffect } from "react";
|
||||
import { View, Text, TouchableOpacity, Linking } from "react-native";
|
||||
import MapView, { Marker } from "react-native-maps";
|
||||
import { MaterialCommunityIcons, Ionicons } from "@expo/vector-icons";
|
||||
import MapView from "react-native-maps";
|
||||
import { useCurrentTrain } from "../stateBox/useCurrentTrain";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import lineColorList from "../assets/originData/lineColorList";
|
||||
@ -15,7 +14,7 @@ import { MapsButton } from "./TrainMenu/MapsButton";
|
||||
export default function TrainMenu({ style }) {
|
||||
const { webview } = useCurrentTrain();
|
||||
const mapRef = useRef();
|
||||
const { navigate } = useNavigation();
|
||||
const { navigate, goBack } = useNavigation();
|
||||
const [stationPin, setStationPin] = useState([]);
|
||||
const {
|
||||
selectedLine,
|
||||
@ -35,12 +34,6 @@ export default function TrainMenu({ style }) {
|
||||
""
|
||||
).split(",");
|
||||
if (latlng.length == 0) return null;
|
||||
if (index == 0 && stationPin.length > 0) {
|
||||
setInjectJavaScript(
|
||||
`MoveDisplayStation('${d}_${D.MyStation}_${D.Station_JP}');
|
||||
document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`
|
||||
);
|
||||
}
|
||||
stationPinData.push({ D, d, latlng, indexBase: 0, index });
|
||||
});
|
||||
});
|
||||
@ -82,7 +75,7 @@ export default function TrainMenu({ style }) {
|
||||
d={d}
|
||||
navigate={navigate}
|
||||
webview={webview}
|
||||
key={D.StationNumber+d}
|
||||
key={D.StationNumber + d}
|
||||
/>
|
||||
))}
|
||||
</MapView>
|
||||
@ -152,7 +145,27 @@ export default function TrainMenu({ style }) {
|
||||
opacity: selectedLine == d ? 1 : !selectedLine ? 1 : 0.5,
|
||||
zIndex: 10,
|
||||
}}
|
||||
onPress={() => setSelectedLine(selectedLine == d ? undefined : d)}
|
||||
onPress={() => {
|
||||
const s = selectedLine == d ? undefined : d;
|
||||
if(!s) return;
|
||||
setSelectedLine(s);
|
||||
Object.keys(stationData).forEach((data, indexBase) => {
|
||||
stationData[data].forEach((D, index) => {
|
||||
if (!D.StationMap) return null;
|
||||
if (s && s != data) return;
|
||||
const latlng = D.StationMap.replace(
|
||||
"https://www.google.co.jp/maps/place/",
|
||||
""
|
||||
).split(",");
|
||||
if (latlng.length == 0) return null;
|
||||
if (index == 0 && stationPin.length > 0) {
|
||||
webview.current
|
||||
?.injectJavaScript(`MoveDisplayStation('${data}_${D.MyStation}_${D.Station_JP}');
|
||||
document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`);
|
||||
}
|
||||
});
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{ color: "white", fontWeight: "bold", fontSize: 20 }}
|
||||
@ -201,7 +214,7 @@ export default function TrainMenu({ style }) {
|
||||
)}
|
||||
<MapsButton
|
||||
onPress={() => {
|
||||
navigate("Apps");
|
||||
goBack();
|
||||
webview.current?.injectJavaScript(injectJavaScript);
|
||||
}}
|
||||
top={0}
|
||||
@ -209,4 +222,4 @@ export default function TrainMenu({ style }) {
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
226
components/trainMenu.web.js
Normal file
@ -0,0 +1,226 @@
|
||||
import React, { useRef, useState, useEffect, useLayoutEffect } from "react";
|
||||
import { View, Text, TouchableOpacity, Linking } from "react-native";
|
||||
//import MapView from "react-native-maps";
|
||||
import { useCurrentTrain } from "../stateBox/useCurrentTrain";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import lineColorList from "../assets/originData/lineColorList";
|
||||
import { stationIDPair } from "../lib/getStationList2";
|
||||
import { lineListPair } from "../lib/getStationList";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import { useTrainMenu } from "../stateBox/useTrainMenu";
|
||||
//import { MapPin } from "./TrainMenu/MapPin";
|
||||
import { UsefulBox } from "./TrainMenu/UsefulBox";
|
||||
import { MapsButton } from "./TrainMenu/MapsButton";
|
||||
export default function TrainMenu({ style }) {
|
||||
return null;
|
||||
const { webview } = useCurrentTrain();
|
||||
const mapRef = useRef();
|
||||
const { navigate, goBack } = useNavigation();
|
||||
const [stationPin, setStationPin] = useState([]);
|
||||
const {
|
||||
selectedLine,
|
||||
setSelectedLine,
|
||||
injectJavaScript,
|
||||
setInjectJavaScript,
|
||||
mapsStationData: stationData,
|
||||
} = useTrainMenu();
|
||||
useEffect(() => {
|
||||
const stationPinData = [];
|
||||
Object.keys(stationData).forEach((d, indexBase) => {
|
||||
stationData[d].forEach((D, index) => {
|
||||
if (!D.StationMap) return null;
|
||||
if (selectedLine && selectedLine != d) return;
|
||||
const latlng = D.StationMap.replace(
|
||||
"https://www.google.co.jp/maps/place/",
|
||||
""
|
||||
).split(",");
|
||||
if (latlng.length == 0) return null;
|
||||
stationPinData.push({ D, d, latlng, indexBase: 0, index });
|
||||
});
|
||||
});
|
||||
setStationPin(stationPinData);
|
||||
}, [stationData, selectedLine]);
|
||||
useLayoutEffect(() => {
|
||||
mapRef.current.fitToCoordinates(
|
||||
stationPin.map(({ latlng }) => ({
|
||||
latitude: parseFloat(latlng[0]),
|
||||
longitude: parseFloat(latlng[1]),
|
||||
})),
|
||||
{ edgePadding: { top: 80, bottom: 120, left: 50, right: 50 } } // Add margin values here
|
||||
);
|
||||
}, [stationPin]);
|
||||
return (
|
||||
<View style={{ height: "100%", backgroundColor: "#0099CC", ...style }}>
|
||||
<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,
|
||||
}}
|
||||
>
|
||||
{stationPin.map(({ D, d, latlng, indexBase, index }) => (
|
||||
<MapPin
|
||||
index={index}
|
||||
indexBase={indexBase}
|
||||
latlng={latlng}
|
||||
D={D}
|
||||
d={d}
|
||||
navigate={navigate}
|
||||
webview={webview}
|
||||
key={D.StationNumber + d}
|
||||
/>
|
||||
))}
|
||||
</MapView>
|
||||
<View style={{ position: "relative" }}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
position: "absolute",
|
||||
width: "100vw",
|
||||
bottom: 0,
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
backgroundColor: selectedLine
|
||||
? lineColorList[stationIDPair[selectedLine]]
|
||||
: "#0099CC",
|
||||
padding: 10,
|
||||
zIndex: 1,
|
||||
alignItems: "center",
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
width: "100%",
|
||||
paddingBottom: 50,
|
||||
}}
|
||||
onPress={() => SheetManager.show("TrainMenuLineSelector")}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: "white",
|
||||
fontWeight: "bold",
|
||||
fontSize: 10,
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
▲ ここを押して路線をフィルタリングできます ▲
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
color: "white",
|
||||
fontWeight: "bold",
|
||||
fontSize: 20,
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
{selectedLine
|
||||
? lineListPair[stationIDPair[selectedLine]]
|
||||
: "JR四国 対象全駅"}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<Text style={{ position: "absolute", bottom: 40 }}>
|
||||
路線記号からフィルタリング
|
||||
</Text>
|
||||
{Object.keys(stationData).map((d) => (
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: lineColorList[stationIDPair[d]],
|
||||
padding: 5,
|
||||
margin: 2,
|
||||
borderRadius: 10,
|
||||
borderColor: "white",
|
||||
borderWidth: 1,
|
||||
borderStyle: "solid",
|
||||
alignItems: "center",
|
||||
opacity: selectedLine == d ? 1 : !selectedLine ? 1 : 0.5,
|
||||
zIndex: 10,
|
||||
}}
|
||||
onPress={() => {
|
||||
const s = selectedLine == d ? undefined : d;
|
||||
if(!s) return;
|
||||
setSelectedLine(s);
|
||||
Object.keys(stationData).forEach((data, indexBase) => {
|
||||
stationData[data].forEach((D, index) => {
|
||||
if (!D.StationMap) return null;
|
||||
if (s && s != data) return;
|
||||
const latlng = D.StationMap.replace(
|
||||
"https://www.google.co.jp/maps/place/",
|
||||
""
|
||||
).split(",");
|
||||
if (latlng.length == 0) return null;
|
||||
if (index == 0 && stationPin.length > 0) {
|
||||
webview.current
|
||||
?.injectJavaScript(`MoveDisplayStation('${data}_${D.MyStation}_${D.Station_JP}');
|
||||
document.getElementById("disp").insertAdjacentHTML("afterbegin", "<div />");`);
|
||||
}
|
||||
});
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{ color: "white", fontWeight: "bold", fontSize: 20 }}
|
||||
>
|
||||
{stationIDPair[d]}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
{navigate && (
|
||||
<View style={{ flexDirection: "row" }}>
|
||||
<UsefulBox
|
||||
backgroundColor={"#F89038"}
|
||||
icon="train-car"
|
||||
flex={1}
|
||||
onPressButton={() =>
|
||||
navigate("howto", {
|
||||
info: "https://train.jr-shikoku.co.jp/usage.htm",
|
||||
})
|
||||
}
|
||||
>
|
||||
使い方
|
||||
</UsefulBox>
|
||||
<UsefulBox
|
||||
backgroundColor={"#EA4752"}
|
||||
icon="star"
|
||||
flex={1}
|
||||
onPressButton={() => navigate("favoriteList")}
|
||||
>
|
||||
お気に入り
|
||||
</UsefulBox>
|
||||
<UsefulBox
|
||||
backgroundColor={"#91C31F"}
|
||||
icon="clipboard-list-outline"
|
||||
flex={1}
|
||||
onPressButton={() =>
|
||||
Linking.openURL(
|
||||
"https://nexcloud.haruk.in/apps/forms/ZRHjWFF7znr5Xjr2"
|
||||
)
|
||||
}
|
||||
>
|
||||
フィードバック
|
||||
</UsefulBox>
|
||||
</View>
|
||||
)}
|
||||
<MapsButton
|
||||
onPress={() => {
|
||||
goBack();
|
||||
webview.current?.injectJavaScript(injectJavaScript);
|
||||
}}
|
||||
top={0}
|
||||
mapSwitch={"flex"}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import React, { useRef } from "react";
|
||||
import React from "react";
|
||||
import { StatusBar, Platform, View } from "react-native";
|
||||
import { WebView } from "react-native-webview";
|
||||
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
||||
@ -6,44 +6,43 @@ import { useNavigation } from "@react-navigation/native";
|
||||
import { BigButton } from "./atom/BigButton";
|
||||
|
||||
export default function TrainBase({ route }) {
|
||||
const { info, from } = route.params;
|
||||
const { navigate } = useNavigation();
|
||||
const webview = useRef();
|
||||
const jss = `document.getElementById('Footer').style.display = 'none';
|
||||
if (!route.params) {
|
||||
return null;
|
||||
}
|
||||
const { info } = route.params;
|
||||
const { goBack } = useNavigation();
|
||||
const jss = `
|
||||
document.getElementById('Footer').style.display = 'none';
|
||||
${
|
||||
Platform.OS == "ios" &&
|
||||
`document.getElementsByTagName("html")[0].style['font-size'] = '11px';`
|
||||
}`;
|
||||
//const jss = `alert("ほげ")`;
|
||||
Platform.OS == "ios"
|
||||
? `document.getElementsByTagName("html")[0].style['font-size'] = '11px';`
|
||||
: ""
|
||||
}
|
||||
true;`;
|
||||
return (
|
||||
<View style={{ height: "100%" }}>
|
||||
{Platform.OS == "ios" && <StatusBar barStyle="dark-content" />}
|
||||
<WebView
|
||||
//useWebKit={true}
|
||||
ref={webview}
|
||||
useWebKit
|
||||
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) => {}}
|
||||
mixedContentMode={"compatibility"}
|
||||
javaScriptEnabled
|
||||
injectedJavaScript={jss}
|
||||
setSupportMultipleWindows
|
||||
/>
|
||||
{(from == "LED" || from == "LED2" || from == "AllTrainIDList") && (
|
||||
<BigButton
|
||||
style={{ borderColor: "black" }}
|
||||
tS={{ color: "black" }}
|
||||
string="閉じる"
|
||||
onPress={() =>
|
||||
navigate(from == "AllTrainIDList" ? "AllTrainIDList" : "menu")
|
||||
}
|
||||
>
|
||||
<MaterialCommunityIcons name="close" color="black" size={30} />
|
||||
</BigButton>
|
||||
)}
|
||||
<BigButton
|
||||
style={{ borderColor: "black" }}
|
||||
tS={{ color: "black" }}
|
||||
string="閉じる"
|
||||
onPress={goBack}
|
||||
>
|
||||
<MaterialCommunityIcons name="close" color="black" size={30} />
|
||||
</BigButton>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
export const news = "2025-01-09";
|
||||
export const news = "2025-03-06";
|
||||
|
6
eas.json
@ -35,6 +35,12 @@
|
||||
},
|
||||
"production5.0": {
|
||||
"channel": "dmm"
|
||||
},
|
||||
"beta6.0": {
|
||||
"channel": "ebookjapan"
|
||||
},
|
||||
"production6.0": {
|
||||
"channel": "ebay"
|
||||
}
|
||||
},
|
||||
"submit": {
|
||||
|
10
howto.js
@ -4,15 +4,17 @@ import { WebView } from "react-native-webview";
|
||||
import { BigButton } from "./components/atom/BigButton";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
export default ({ navigation: { navigate }, route }) => {
|
||||
if (!route.params) {
|
||||
return null
|
||||
}
|
||||
const { info, goTo, useShow } = route.params;
|
||||
const { goBack } = useNavigation();
|
||||
const onExit = () => {
|
||||
if(goTo != "NearTrainDiagramView") {
|
||||
navigate(goTo || "Apps");
|
||||
if (goTo != "NearTrainDiagramView") {
|
||||
//navigate(goTo || "Apps");
|
||||
useShow && useShow();
|
||||
} else {
|
||||
goBack();
|
||||
}
|
||||
goBack();
|
||||
};
|
||||
return (
|
||||
<View style={styles}>
|
||||
|
6
index.js
@ -1,5 +1,7 @@
|
||||
import 'babel-polyfill';
|
||||
import { registerRootComponent } from "expo";
|
||||
import { registerWidgetTaskHandler } from "react-native-android-widget";
|
||||
import { Platform } from "react-native";
|
||||
|
||||
import App from "./App";
|
||||
import { widgetTaskHandler } from "./components/AndroidWidget/widget-task-handler";
|
||||
@ -8,4 +10,6 @@ import { widgetTaskHandler } from "./components/AndroidWidget/widget-task-handle
|
||||
// It also ensures that whether you load the app in Expo Go or in a native build,
|
||||
// the environment is set up appropriately
|
||||
registerRootComponent(App);
|
||||
registerWidgetTaskHandler(widgetTaskHandler);
|
||||
if (Platform.OS === "android") {
|
||||
registerWidgetTaskHandler(widgetTaskHandler);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 種別判定
|
||||
export const getType = (string) => {
|
||||
export const getType = (string:string) => {
|
||||
switch (string) {
|
||||
case "express":
|
||||
return "特急";
|
@ -1,6 +1,6 @@
|
||||
// Description: 電車名の変換を行う。
|
||||
// マリンライナーやマリン表記をマリンライナーに変換する。
|
||||
export const migrateTrainName = (string) => {
|
||||
export const migrateTrainName = (string:string) => {
|
||||
return string
|
||||
.replace("マリン", "マリンライナー")
|
||||
.replace("ライナーライナー", "ライナー");
|
@ -1,7 +1,7 @@
|
||||
// S列番の列車からDやMの列車を検索する
|
||||
export const searchSpecialTrain = (trainNum, trainList) => {
|
||||
export const searchSpecialTrain = (trainNum: string, trainList: any[]) => {
|
||||
const searchBase = trainNum.replace("S", "").replace("X", "");
|
||||
const search = (text) => {
|
||||
const search = (text: string) => {
|
||||
const TD = trainList[searchBase + text];
|
||||
if (TD) {
|
||||
return true;
|
@ -1,6 +1,6 @@
|
||||
import { Platform } from "react-native";
|
||||
|
||||
export const getPDFViewURL = (url) => {
|
||||
export const getPDFViewURL = (url:string) => {
|
||||
if (Platform.OS == "ios") return url;
|
||||
else
|
||||
return `https://mozilla.github.io/pdf.js/web/viewer.html?file=${encodeURI(url)}`;
|
@ -41,7 +41,7 @@ export const lineListPair = {
|
||||
M: "瀬戸大橋線(児島-宇多津間)[M]",
|
||||
};
|
||||
|
||||
export const getStationList = async (props) => {
|
||||
export const getStationList = async () => {
|
||||
if (status) return status;
|
||||
//駅リストイニシャライズ
|
||||
return await Promise.all([
|
||||
@ -68,8 +68,8 @@ export const getStationList = async (props) => {
|
||||
stationList["徳島線(徳島-阿波池田間)[B]"],
|
||||
stationList["鳴門線(池谷-鳴門間)[N]"],
|
||||
stationList["瀬戸大橋線(児島-宇多津間)[M]"],
|
||||
stationList.駅間リスト,
|
||||
stationList.日英対応表,
|
||||
stationList["駅間リスト"],
|
||||
stationList["日英対応表"],
|
||||
] = values;
|
||||
const concatBetweenStations = (eachRouteData) => {
|
||||
let additional = [];
|
||||
@ -82,7 +82,7 @@ export const getStationList = async (props) => {
|
||||
eachRouteData[routeIndex + 1].StationNumber.replace(/[A-Z]/g, "")
|
||||
);
|
||||
if (nextStationID - currentStationID != 1) {
|
||||
stationList.駅間リスト.forEach((betweenList) => {
|
||||
stationList["駅間リスト"].forEach((betweenList) => {
|
||||
if (
|
||||
betweenList.BetweenStation ==
|
||||
routeData.Station_JP +
|
||||
@ -125,12 +125,12 @@ export const getStationList = async (props) => {
|
||||
stationList["予讃線(高松-松山間)[Y]"] = addStationPosition(
|
||||
concatBetweenStations(stationList["予讃線(高松-松山間)[Y]"]),
|
||||
予讃線,
|
||||
stationList.日英対応表
|
||||
stationList["日英対応表"]
|
||||
);
|
||||
stationList["予讃線(松山-宇和島間)[U]"] = addStationPosition(
|
||||
concatBetweenStations(stationList["予讃線(松山-宇和島間)[U]"]),
|
||||
予讃線,
|
||||
stationList.日英対応表
|
||||
stationList["日英対応表"]
|
||||
);
|
||||
stationList["予讃線/愛ある伊予灘線(向井原-伊予大洲間)[S]"] =
|
||||
addStationPosition(
|
||||
@ -138,32 +138,32 @@ export const getStationList = async (props) => {
|
||||
stationList["予讃線/愛ある伊予灘線(向井原-伊予大洲間)[S]"]
|
||||
),
|
||||
予讃線,
|
||||
stationList.日英対応表
|
||||
stationList["日英対応表"]
|
||||
);
|
||||
stationList["土讃線(多度津-高知間)[D]"] = addStationPosition(
|
||||
concatBetweenStations(stationList["土讃線(多度津-高知間)[D]"]),
|
||||
土讃線,
|
||||
stationList.日英対応表
|
||||
stationList["日英対応表"]
|
||||
);
|
||||
stationList["土讃線(高知-窪川間)[K]"] = addStationPosition(
|
||||
concatBetweenStations(stationList["土讃線(高知-窪川間)[K]"]),
|
||||
土讃線,
|
||||
stationList.日英対応表
|
||||
stationList["日英対応表"]
|
||||
);
|
||||
stationList["高徳線(高松-徳島間)[T]"] = addStationPosition(
|
||||
concatBetweenStations(stationList["高徳線(高松-徳島間)[T]"]),
|
||||
高徳線,
|
||||
stationList.日英対応表
|
||||
stationList["日英対応表"]
|
||||
);
|
||||
stationList["鳴門線(池谷-鳴門間)[N]"] = addStationPosition(
|
||||
concatBetweenStations(stationList["鳴門線(池谷-鳴門間)[N]"]),
|
||||
鳴門線,
|
||||
stationList.日英対応表
|
||||
stationList["日英対応表"]
|
||||
);
|
||||
const tokushimaCurrent = addStationPosition(
|
||||
concatBetweenStations(stationList["徳島線(徳島-阿波池田間)[B]"]),
|
||||
徳島線,
|
||||
stationList.日英対応表
|
||||
stationList["日英対応表"]
|
||||
);
|
||||
stationList["徳島線(徳島-阿波池田間)[B]"] = [
|
||||
tokushimaCurrent[tokushimaCurrent.length - 1],
|
@ -1,20 +1,72 @@
|
||||
import React from "react";
|
||||
import React, { FC } from "react";
|
||||
import { Ionicons, AntDesign } from "@expo/vector-icons";
|
||||
import { Text, View } from "react-native";
|
||||
type name = keyof typeof Ionicons.glyphMap & keyof typeof AntDesign.glyphMap;
|
||||
type type = "Ionicons" | "AntDesign";
|
||||
export const initIcon = (name: name, type:type) => {
|
||||
export const initIcon = (
|
||||
name: name,
|
||||
type: type,
|
||||
tabBarBadge: string,
|
||||
isInfo: boolean
|
||||
) => {
|
||||
switch (type) {
|
||||
case "Ionicons":
|
||||
return ({ focused, color, size }) => (
|
||||
<Ionicons name={name} size={32} color={focused ? "#0099CC" : "black"} />
|
||||
<>
|
||||
{!!tabBarBadge && <Badge tabBarBadge={tabBarBadge} isInfo={isInfo} />}
|
||||
<Ionicons
|
||||
name={name}
|
||||
size={30}
|
||||
color={focused ? "#0099CC" : "black"}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
case "AntDesign":
|
||||
return ({ focused, color, size }) => (
|
||||
<AntDesign
|
||||
name={name}
|
||||
size={32}
|
||||
color={focused ? "#0099CC" : "black"}
|
||||
/>
|
||||
<>
|
||||
{!!tabBarBadge && <Badge tabBarBadge={tabBarBadge} isInfo={isInfo} />}
|
||||
<AntDesign
|
||||
name={name}
|
||||
size={30}
|
||||
color={focused ? "#0099CC" : "black"}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
type BadgeProps = { tabBarBadge: string; isInfo: boolean };
|
||||
|
||||
export const Badge: FC<BadgeProps> = ({ tabBarBadge, isInfo }) => {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
position: "relative",
|
||||
top: -5,
|
||||
right: 0,
|
||||
zIndex: 100,
|
||||
padding: 1,
|
||||
width: 0,
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
backgroundColor: isInfo ? "#00b8ff" : "red",
|
||||
borderRadius: 10,
|
||||
padding: 2,
|
||||
shadowColor: "#000",
|
||||
shadowOffset: { width: 0, height: 0 },
|
||||
shadowOpacity: 0.5,
|
||||
shadowRadius: 4,
|
||||
elevation: 2
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: "white", paddingHorizontal: 4 }}>
|
||||
{tabBarBadge}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
@ -1,4 +1,5 @@
|
||||
export const buildProvidersTree = (providers) => {
|
||||
import React, { FC } from "react";
|
||||
export const buildProvidersTree:FC<any> = (providers) => {
|
||||
// 基本ケース:ContextProviderが1つしか残っていない場合、それを返して終了する
|
||||
if (providers.length === 1) {
|
||||
return providers[0];
|
102
menu.js
@ -1,5 +1,5 @@
|
||||
import React, { useRef, useState, useEffect } from "react";
|
||||
import Carousel, { Pagination } from "react-native-snap-carousel";
|
||||
import Carousel from "react-native-reanimated-carousel";
|
||||
import {
|
||||
Platform,
|
||||
View,
|
||||
@ -8,6 +8,7 @@ import {
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
LayoutAnimation,
|
||||
Dimensions,
|
||||
} from "react-native";
|
||||
import Constants from "expo-constants";
|
||||
import * as Location from "expo-location";
|
||||
@ -32,9 +33,10 @@ import { SheetManager } from "react-native-actions-sheet";
|
||||
import { useTrainDelayData } from "./stateBox/useTrainDelayData";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { useStationList } from "./stateBox/useStationList";
|
||||
import { Paginations } from "./components/Menu/StationPagination";
|
||||
import { StationNumber } from "./components/Menu/StationPagination";
|
||||
import lineColorList from "./assets/originData/lineColorList";
|
||||
import { AS } from "./storageControl";
|
||||
import { SimpleDot } from "./components/Menu/SimpleDot";
|
||||
|
||||
export default function Menu({ getCurrentTrain }) {
|
||||
const { navigate } = useNavigation();
|
||||
@ -44,6 +46,7 @@ export default function Menu({ getCurrentTrain }) {
|
||||
//位置情報
|
||||
const [locationStatus, setLocationStatus] = useState(null);
|
||||
useEffect(() => {
|
||||
if (Platform.OS == "web") return;
|
||||
Location.requestForegroundPermissionsAsync().then((data) => {
|
||||
setLocationStatus(
|
||||
Platform.OS == "ios"
|
||||
@ -118,13 +121,13 @@ export default function Menu({ getCurrentTrain }) {
|
||||
const count = selectedCurrentStation - 1;
|
||||
setSelectedCurrentStation(count);
|
||||
}
|
||||
}, [selectedCurrentStation, currentStation, favoriteStation]);
|
||||
}, [selectedCurrentStation, currentStation, allStationData]);
|
||||
useEffect(() => {
|
||||
if (!carouselRef.current) return;
|
||||
if (carouselRef.current?._itemToSnapTo != selectedCurrentStation) {
|
||||
carouselRef.current.snapToItem(0);
|
||||
carouselRef.current.snapToItem(selectedCurrentStation);
|
||||
}
|
||||
carouselRef?.current.scrollTo({
|
||||
count: selectedCurrentStation - carouselRef.current.getCurrentIndex(),
|
||||
animated: true,
|
||||
});
|
||||
}, [selectedCurrentStation]);
|
||||
|
||||
//全列車ダイヤリストを作成するuseEffect
|
||||
@ -162,10 +165,11 @@ export default function Menu({ getCurrentTrain }) {
|
||||
});
|
||||
AS.setItem(
|
||||
"CarouselSettings/activeDotSettings",
|
||||
!dotButton ? "true": "false"
|
||||
!dotButton ? "true" : "false"
|
||||
);
|
||||
setDotButton(!dotButton);
|
||||
}
|
||||
};
|
||||
const width = Dimensions.get("window").width;
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
@ -179,41 +183,80 @@ export default function Menu({ getCurrentTrain }) {
|
||||
<ScrollView>
|
||||
<TopMenuButton />
|
||||
{originalStationList.length != 0 && allStationData.length != 0 && (
|
||||
<>
|
||||
<View style={{ flex: 1, paddingTop: 10 }}>
|
||||
<Carousel
|
||||
ref={carouselRef}
|
||||
layout={"default"}
|
||||
data={originalStationList && allStationData}
|
||||
sliderWidth={wp("100%")}
|
||||
itemWidth={wp("80%")}
|
||||
enableMomentum
|
||||
callbackOffsetMargin={1000}
|
||||
activeAnimationOptions={0.3}
|
||||
height={(wp("80%") / 20) * 9 + 10}
|
||||
pagingEnabled={true}
|
||||
snapEnabled={true}
|
||||
loop={false}
|
||||
width={width}
|
||||
style={{ width: width, alignContent: "center" }}
|
||||
mode="parallax"
|
||||
modeConfig={{
|
||||
parallaxScrollingScale: 1,
|
||||
parallaxScrollingOffset: 100,
|
||||
parallaxAdjacentItemScale: 0.8,
|
||||
}}
|
||||
onSnapToItem={setSelectedCurrentStation}
|
||||
renderItem={({ item }) => {
|
||||
renderItem={({ item, index }) => {
|
||||
return (
|
||||
<View
|
||||
style={{ marginVertical: 10 }}
|
||||
style={{
|
||||
backgroundColor: "#0000",
|
||||
width: width,
|
||||
flexDirection: "row",
|
||||
marginLeft: 0,
|
||||
marginRight: 0,
|
||||
}}
|
||||
key={item[0].StationNumber}
|
||||
>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Sign
|
||||
currentStation={item}
|
||||
isCurrentStation={item == currentStation}
|
||||
oP={oPSign}
|
||||
oLP={oLPSign}
|
||||
/>
|
||||
<View style={{ flex: 1 }} />
|
||||
</View>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Paginations
|
||||
entries={allStationData}
|
||||
activeSlide={selectedCurrentStation}
|
||||
carouselRef={carouselRef}
|
||||
setSelectedCurrentStation={setSelectedCurrentStation}
|
||||
dotButton={dotButton}
|
||||
/>
|
||||
</>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
justifyContent: "center",
|
||||
alignContent: "center",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
{originalStationList &&
|
||||
allStationData.map((d, index) => {
|
||||
const active = index == selectedCurrentStation;
|
||||
const numberIndex = d[0].StationNumber;
|
||||
if (dotButton) {
|
||||
return (
|
||||
<StationNumber
|
||||
onPress={() => setSelectedCurrentStation(index)}
|
||||
currentStation={d}
|
||||
active={active}
|
||||
index={numberIndex}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<SimpleDot
|
||||
onPress={() => setSelectedCurrentStation(index)}
|
||||
active={active}
|
||||
index={numberIndex}
|
||||
/>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
{allStationData.length != 0 &&
|
||||
originalStationList.length != 0 &&
|
||||
@ -350,10 +393,13 @@ const JRSTraInfoBox = () => {
|
||||
/>
|
||||
</View>
|
||||
) : delayData ? (
|
||||
delayData.map((d,index,array) => {
|
||||
delayData.map((d, index, array) => {
|
||||
let data = d.split(" ");
|
||||
return (
|
||||
<View style={{ flexDirection: "row" }} key={data[1] + "key"+index}>
|
||||
<View
|
||||
style={{ flexDirection: "row" }}
|
||||
key={data[1] + "key" + index}
|
||||
>
|
||||
<Text style={{ flex: 15, fontSize: 18 }}>
|
||||
{data[0].replace("\n", "")}
|
||||
</Text>
|
||||
|
63
ndView.js
@ -1,63 +0,0 @@
|
||||
import React, { useRef, useState } from "react";
|
||||
import { View, Platform, TouchableOpacity } from "react-native";
|
||||
import { WebView } from "react-native-webview";
|
||||
import Constants from "expo-constants";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
export default function tndView() {
|
||||
const webview = useRef();
|
||||
const jsa = `
|
||||
document.querySelector('.sitettl').style.display = 'none';
|
||||
document.querySelector('.attention').style.display = 'none';
|
||||
`;
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "#309AC3",
|
||||
height: "100%",
|
||||
paddingTop: Platform.OS == "ios" ? Constants.statusBarHeight : 0,
|
||||
}}
|
||||
>
|
||||
<WebView
|
||||
useWebKit={true}
|
||||
ref={webview}
|
||||
source={{ uri: "https://www.jr-shikoku.co.jp/info/" }}
|
||||
originWhitelist={["https://www.jr-shikoku.co.jp"]}
|
||||
mixedContentMode={"compatibility"}
|
||||
javaScriptEnabled={true}
|
||||
injectedJavaScript={jsa}
|
||||
pullToRefreshEnabled
|
||||
onError={() => this.webView?.reload()}
|
||||
/>
|
||||
<ReloadButton
|
||||
onPress={() => webview.current?.reload()}
|
||||
top={Platform.OS == "ios" ? Constants.statusBarHeight : 0}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const ReloadButton = ({ onPress, top, mapSwitch, LoadError = false }) => {
|
||||
const styles = {
|
||||
position: "absolute",
|
||||
top,
|
||||
right: 10,
|
||||
width: 50,
|
||||
height: 50,
|
||||
backgroundColor: LoadError ? "red" : "#0099CC",
|
||||
borderColor: "white",
|
||||
borderStyle: "solid",
|
||||
borderWidth: 1,
|
||||
borderRadius: 50,
|
||||
alignContent: "center",
|
||||
alignSelf: "center",
|
||||
alignItems: "center",
|
||||
display: mapSwitch,
|
||||
};
|
||||
return (
|
||||
<TouchableOpacity onPress={onPress} style={styles}>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Ionicons name="reload" color="white" size={30} />
|
||||
<View style={{ flex: 1 }} />
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
156
ndView.tsx
Normal file
@ -0,0 +1,156 @@
|
||||
import React, { Ref, useRef, useState,useEffect } from "react";
|
||||
import { View, Platform, TouchableOpacity, StyleProp, ViewStyle,Linking } from "react-native";
|
||||
import { WebView } from "react-native-webview";
|
||||
import Constants from "expo-constants";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
export default function tndView() {
|
||||
const webview = useRef<WebView>(null);
|
||||
const { navigate, addListener, isFocused } = useNavigation();
|
||||
const jsa = `
|
||||
document.querySelector('.sitettl').style.display = 'none';
|
||||
document.querySelector('.attention').style.display = 'none';
|
||||
document.querySelector('.mapheader').style.display = 'none';
|
||||
document.querySelector('.map').style.width = '100vw';
|
||||
document.querySelector('.map').style.display = 'block';
|
||||
document.querySelector('.map').style.marginLeft = '-5px';
|
||||
document.querySelector('.map').style.marginTop = '0px';
|
||||
|
||||
|
||||
document.querySelector('.mapbase > img').style.width = '100vw';
|
||||
document.querySelector('.ml_station > img').style.width = '100vw';
|
||||
|
||||
document.querySelector('.ml_seto >img').removeAttribute('width');
|
||||
document.querySelector('.ml_seto >img').removeAttribute('height');
|
||||
document.querySelector('.ml_seto >img').style.width = '14.5vw';
|
||||
document.querySelector('.ml_seto').style.top = '0.2vw';
|
||||
document.querySelector('.ml_seto').style.right = '25.8vw';
|
||||
|
||||
document.querySelector('.ml_yosan1 >img').removeAttribute('width');
|
||||
document.querySelector('.ml_yosan1 >img').removeAttribute('height');
|
||||
document.querySelector('.ml_yosan1 >img').style.width = '42.6vw';
|
||||
document.querySelector('.ml_yosan1').style.top = '5.1vw';
|
||||
document.querySelector('.ml_yosan1').style.left = '18.7vw';
|
||||
|
||||
document.querySelector('.ml_yosan2 >img').removeAttribute('width');
|
||||
document.querySelector('.ml_yosan2 >img').removeAttribute('height');
|
||||
document.querySelector('.ml_yosan2 >img').style.width = '12.2vw';
|
||||
document.querySelector('.ml_yosan2').style.top = '8.6vw';
|
||||
document.querySelector('.ml_yosan2').style.left = '8.0vw';
|
||||
|
||||
document.querySelector('.ml_dosan1 >img').removeAttribute('width');
|
||||
document.querySelector('.ml_dosan1 >img').removeAttribute('height');
|
||||
document.querySelector('.ml_dosan1 >img').style.width = '13.5vw';
|
||||
document.querySelector('.ml_dosan1').style.top = '6.6vw';
|
||||
document.querySelector('.ml_dosan1').style.left = '47.8vw';
|
||||
|
||||
document.querySelector('.ml_dosan2 >img').removeAttribute('width');
|
||||
document.querySelector('.ml_dosan2 >img').removeAttribute('height');
|
||||
document.querySelector('.ml_dosan2 >img').style.width = '22.5vw';
|
||||
document.querySelector('.ml_dosan2').style.top = '32vw';
|
||||
document.querySelector('.ml_dosan2').style.left = '26.5vw';
|
||||
|
||||
document.querySelector('.ml_kotoku >img').removeAttribute('width');
|
||||
document.querySelector('.ml_kotoku >img').removeAttribute('height');
|
||||
document.querySelector('.ml_kotoku >img').style.width = '17vw';
|
||||
document.querySelector('.ml_kotoku').style.top = '6.5vw';
|
||||
document.querySelector('.ml_kotoku').style.left = '72.9vw';
|
||||
|
||||
document.querySelector('.ml_mugi >img').removeAttribute('width');
|
||||
document.querySelector('.ml_mugi >img').removeAttribute('height');
|
||||
document.querySelector('.ml_mugi >img').style.width = '11.6vw';
|
||||
document.querySelector('.ml_mugi').style.top = '23.6vw';
|
||||
document.querySelector('.ml_mugi').style.left = '78.3vw';
|
||||
|
||||
document.querySelector('.ml_tokushima >img').removeAttribute('width');
|
||||
document.querySelector('.ml_tokushima >img').removeAttribute('height');
|
||||
document.querySelector('.ml_tokushima >img').style.width = '27.8vw';
|
||||
document.querySelector('.ml_tokushima').style.top = '17vw';
|
||||
document.querySelector('.ml_tokushima').style.left = '61.3vw';
|
||||
|
||||
document.querySelector('.ml_naruto >img').removeAttribute('width');
|
||||
document.querySelector('.ml_naruto >img').removeAttribute('height');
|
||||
document.querySelector('.ml_naruto >img').style.width = '5.5vw';
|
||||
document.querySelector('.ml_naruto').style.top = '17.1vw';
|
||||
document.querySelector('.ml_naruto').style.left = '88.5vw';
|
||||
|
||||
document.querySelector('.ml_yodo >img').removeAttribute('width');
|
||||
document.querySelector('.ml_yodo >img').removeAttribute('height');
|
||||
document.querySelector('.ml_yodo >img').style.width = '18.3vw';
|
||||
document.querySelector('.ml_yodo').style.top = '30.2vw';
|
||||
document.querySelector('.ml_yodo').style.left = '9.6vw';
|
||||
|
||||
setInterval(() => {
|
||||
document.querySelectorAll('.ml_seto, .ml_yosan1, .ml_yosan2, .ml_dosan1, .ml_dosan2, .ml_kotoku, .ml_mugi, .ml_tokushima, .ml_naruto, .ml_yodo').forEach(el => {
|
||||
el.style.visibility = el.style.visibility === 'hidden' ? 'visible' : 'hidden';
|
||||
});
|
||||
}, 1000);
|
||||
`;
|
||||
const goToTrainMenu = () =>{
|
||||
if (Platform.OS === "web") {
|
||||
Linking.openURL("https://www.jr-shikoku.co.jp/info/");
|
||||
setTimeout(() => {
|
||||
// @ts-ignore
|
||||
navigate("topMenu", { screen: "menu" });
|
||||
}, 100);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
// @ts-ignore
|
||||
const unsubscribe = addListener("tabPress", goToTrainMenu);
|
||||
return unsubscribe;
|
||||
}, [addListener]);
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "#309AC3",
|
||||
height: "100%",
|
||||
paddingTop: Platform.OS == "ios" ? Constants.statusBarHeight : 0,
|
||||
}}
|
||||
>
|
||||
<WebView
|
||||
ref={webview}
|
||||
source={{ uri: "https://www.jr-shikoku.co.jp/info/" }}
|
||||
originWhitelist={["https://www.jr-shikoku.co.jp"]}
|
||||
mixedContentMode={"compatibility"}
|
||||
javaScriptEnabled={true}
|
||||
injectedJavaScript={jsa}
|
||||
pullToRefreshEnabled
|
||||
onError={() => this.webView?.reload()}
|
||||
onMessage={()=>{}}
|
||||
/>
|
||||
<ReloadButton
|
||||
onPress={() => webview.current.reload()}
|
||||
top={Platform.OS == "ios" ? Constants.statusBarHeight : 0}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const ReloadButton = ({ onPress, top, LoadError = false }) => {
|
||||
const styles:StyleProp<ViewStyle> = {
|
||||
position: "absolute",
|
||||
top,
|
||||
right: 10,
|
||||
width: 50,
|
||||
height: 50,
|
||||
backgroundColor: LoadError ? "red" : "#0099CC",
|
||||
borderColor: "white",
|
||||
borderStyle: "solid",
|
||||
borderWidth: 1,
|
||||
borderRadius: 50,
|
||||
alignContent: "center",
|
||||
alignSelf: "center",
|
||||
alignItems: "center",
|
||||
};
|
||||
return (
|
||||
<TouchableOpacity onPress={onPress} style={styles}>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Ionicons name="reload" color="white" size={30} />
|
||||
<View style={{ flex: 1 }} />
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
85
package.json
@ -7,55 +7,74 @@
|
||||
"eject": "expo eject"
|
||||
},
|
||||
"dependencies": {
|
||||
"@expo/metro-runtime": "~4.0.1",
|
||||
"@expo/ngrok": "^4.1.0",
|
||||
"@expo/vector-icons": "^14.0.0",
|
||||
"@react-native-async-storage/async-storage": "1.21.0",
|
||||
"@react-native-community/masked-view": "0.1.10",
|
||||
"@react-navigation/bottom-tabs": "^5.11.11",
|
||||
"@react-navigation/native": "^5.9.4",
|
||||
"@react-navigation/stack": "^5.14.5",
|
||||
"@expo/vector-icons": "^14.0.2",
|
||||
"@gorhom/bottom-sheet": "^5",
|
||||
"@lottiefiles/dotlottie-react": "^0.13.0",
|
||||
"@react-native-async-storage/async-storage": "1.23.1",
|
||||
"@react-native-masked-view/masked-view": "0.3.2",
|
||||
"@react-navigation/bottom-tabs": "^7.2.0",
|
||||
"@react-navigation/native": "^7.0.14",
|
||||
"@react-navigation/stack": "^7.1.1",
|
||||
"@rneui/base": "^0.0.0-edge.2",
|
||||
"@rneui/themed": "^0.0.0-edge.2",
|
||||
"dayjs": "^1.11.9",
|
||||
"eas-cli": "^5.9.1",
|
||||
"expo": "^50.0.11",
|
||||
"expo-dev-client": "~3.3.9",
|
||||
"expo-device": "~5.9.3",
|
||||
"expo-font": "~11.10.3",
|
||||
"expo-location": "~16.5.5",
|
||||
"expo-notifications": "~0.27.6",
|
||||
"expo-screen-orientation": "~6.4.1",
|
||||
"expo-sharing": "~11.10.0",
|
||||
"expo-updates": "~0.24.11",
|
||||
"expo-web-browser": "~12.8.2",
|
||||
"expo": "^52.0.0",
|
||||
"expo-alternate-app-icons": "^1.3.0",
|
||||
"expo-clipboard": "~7.0.1",
|
||||
"expo-constants": "~17.0.4",
|
||||
"expo-dev-client": "~5.0.9",
|
||||
"expo-device": "~7.0.2",
|
||||
"expo-font": "~13.0.3",
|
||||
"expo-haptics": "~14.0.1",
|
||||
"expo-intent-launcher": "~12.0.2",
|
||||
"expo-linear-gradient": "~14.0.2",
|
||||
"expo-linking": "~7.0.4",
|
||||
"expo-localization": "~16.0.1",
|
||||
"expo-location": "~18.0.5",
|
||||
"expo-notifications": "~0.29.12",
|
||||
"expo-screen-orientation": "~8.0.4",
|
||||
"expo-sharing": "~13.0.1",
|
||||
"expo-status-bar": "~2.0.1",
|
||||
"expo-updates": "~0.26.12",
|
||||
"expo-video": "~2.0.5",
|
||||
"expo-web-browser": "~14.0.2",
|
||||
"firebase": "8.2.3",
|
||||
"lottie-react-native": "6.5.1",
|
||||
"lottie-react-native": "7.1.0",
|
||||
"native-base": "^2.15.2",
|
||||
"npm": "^7.18.1",
|
||||
"pushy-react-native": "^1.0.18",
|
||||
"react": "18.2.0",
|
||||
"react-native": "0.73.4",
|
||||
"react-native-actions-sheet": "0.8.21",
|
||||
"react-native-android-widget": "^0.11.2",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"react-native": "0.76.6",
|
||||
"react-native-actions-sheet": "^0.9.7",
|
||||
"react-native-android-widget": "^0.15.1",
|
||||
"react-native-auto-height-image": "^3.2.4",
|
||||
"react-native-elements": "^3.4.2",
|
||||
"react-native-gesture-handler": "~2.14.0",
|
||||
"react-native-maps": "1.10.0",
|
||||
"react-native-reanimated": "~3.6.2",
|
||||
"react-native-gesture-handler": "~2.20.2",
|
||||
"react-native-maps": "1.18.0",
|
||||
"react-native-reanimated": "~3.16.1",
|
||||
"react-native-reanimated-carousel": "^3.5.1",
|
||||
"react-native-remote-svg": "^2.0.6",
|
||||
"react-native-responsive-screen": "^1.4.2",
|
||||
"react-native-router-flux": "^4.3.1",
|
||||
"react-native-safe-area-context": "4.8.2",
|
||||
"react-native-screens": "~3.29.0",
|
||||
"react-native-safe-area-context": "4.12.0",
|
||||
"react-native-screens": "~4.4.0",
|
||||
"react-native-snap-carousel": "^3.9.1",
|
||||
"react-native-sortables": "^1.1.0",
|
||||
"react-native-storage": "^1.0.1",
|
||||
"react-native-svg": "14.1.0",
|
||||
"react-native-svg": "15.8.0",
|
||||
"react-native-svg-uri": "^1.2.3",
|
||||
"react-native-vector-icons": "^8.1.0",
|
||||
"react-native-view-shot": "3.8.0",
|
||||
"react-native-webview": "13.6.4",
|
||||
"react-native-touchable-scale": "^2.2.0",
|
||||
"react-native-vector-icons": "^10.2.0",
|
||||
"react-native-view-shot": "~4.0.3",
|
||||
"react-native-walkthrough-tooltip": "^1.6.0",
|
||||
"react-native-web": "~0.19.13",
|
||||
"react-native-webview": "13.12.5",
|
||||
"typescript": "^5.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-preset-expo": "^10.0.0"
|
||||
"babel-preset-expo": "~12.0.0"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
|
1
public/_redirects
Normal file
@ -0,0 +1 @@
|
||||
/* /index.html 200
|
@ -4,6 +4,7 @@ import React, {
|
||||
useState,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
FC,
|
||||
} from "react";
|
||||
import { AS } from "../storageControl";
|
||||
import { useStationList } from "./useStationList";
|
||||
@ -13,13 +14,20 @@ const initialState = {
|
||||
lodAddMigration: () => {},
|
||||
};
|
||||
|
||||
const FavoriteStationContext = createContext(initialState);
|
||||
type initialStateType = {
|
||||
favoriteStation: any[];
|
||||
setFavoriteStation: (d:any)=>void;
|
||||
lodAddMigration: ()=>void;
|
||||
};
|
||||
const FavoriteStationContext = createContext<initialStateType>(initialState);
|
||||
|
||||
export const useFavoriteStation = () => {
|
||||
return useContext(FavoriteStationContext);
|
||||
};
|
||||
|
||||
export const FavoriteStationProvider = ({ children }) => {
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
export const FavoriteStationProvider:FC<Props> = ({ children }) => {
|
||||
const [favoriteStation, setFavoriteStation] = useState([]);
|
||||
const { getStationData } = useStationList();
|
||||
const lodAddMigration = () => {
|
@ -6,9 +6,7 @@ import React, {
|
||||
FC,
|
||||
useRef,
|
||||
} from "react";
|
||||
// 6.0でライブラリ変更
|
||||
import { Platform, Clipboard } from "react-native";
|
||||
// 6.0でライブラリ更新、tsの型定義が変わった
|
||||
import { Platform } from "react-native";
|
||||
import * as Notifications from "expo-notifications";
|
||||
import * as Device from "expo-device";
|
||||
import Constants from "expo-constants";
|
||||
|
@ -42,7 +42,9 @@ export const TrainMenuProvider = ({ children }) => {
|
||||
const [mapsStationData, setMapsStationData] = useState(undefined);
|
||||
const [injectJavaScript, setInjectJavaScript] = useState();
|
||||
|
||||
useEffect(() => getStationList2().then(setMapsStationData), []);
|
||||
useEffect(() => {
|
||||
getStationList2().then(setMapsStationData);
|
||||
}, []);
|
||||
|
||||
//画面表示関連
|
||||
const [iconSetting, setIconSetting] = useState(undefined);
|
||||
@ -72,7 +74,6 @@ export const TrainMenuProvider = ({ children }) => {
|
||||
//列車アイコンスイッチ
|
||||
ASCore({ k: "iconSwitch", s: setIconSetting, d: "true", u: true });
|
||||
//地図スイッチ
|
||||
//6.0.0以降true
|
||||
ASCore({ k: "mapSwitch", s: setMapSwitch, d: "false", u: true });
|
||||
//駅メニュースイッチ
|
||||
ASCore({ k: "stationSwitch", s: setStationMenu, d: "true", u: true });
|
||||
|
@ -1,4 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {},
|
||||
"compilerOptions": {
|
||||
"plugins": [
|
||||
{
|
||||
"@/*": ["./*"] //追加
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": ["./*"] //修正
|
||||
}
|
||||
},
|
||||
"extends": "expo/tsconfig.base"
|
||||
}
|
||||
|