diff --git a/App.js b/App.js
index 38e843f..44d2de1 100644
--- a/App.js
+++ b/App.js
@@ -1,17 +1,12 @@
import React, { useEffect } from "react";
-import { NavigationContainer } from "@react-navigation/native";
-import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { Platform, UIManager } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
+import { AppContainer } from "./Apps.js";
import { UpdateAsync } from "./UpdateAsync.js";
-import TNDView from "./ndView";
import { LogBox } from "react-native";
-import { initIcon } from "./lib/initIcon";
import { FavoriteStationProvider } from "./stateBox/useFavoriteStation";
-import { Top } from "./Top.js";
-import { MenuPage } from "./MenuPage.js";
import { CurrentTrainProvider } from "./stateBox/useCurrentTrain.js";
-import { useAreaInfo, AreaInfoProvider } from "./stateBox/useAreaInfo.js";
+import { AreaInfoProvider } from "./stateBox/useAreaInfo.js";
import { BusAndTrainDataProvider } from "./stateBox/useBusAndTrainData.js";
import { AllTrainDiagramProvider } from "./stateBox/useAllTrainDiagram.js";
import { SheetProvider } from "react-native-actions-sheet";
@@ -20,11 +15,13 @@ import { TrainDelayDataProvider } from "./stateBox/useTrainDelayData.js";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { DeviceOrientationChangeProvider } from "./stateBox/useDeviceOrientationChange.js";
import { TrainMenuProvider } from "./stateBox/useTrainMenu.js";
+import { buildProvidersTree } from "./lib/providerTreeProvider.js";
+
LogBox.ignoreLogs([
"ViewPropTypes will be removed",
"ColorPropType will be removed",
]);
-const Tab = createBottomTabNavigator();
+
if (Platform.OS === "android") {
if (UIManager.setLayoutAnimationEnabledExperimental) {
UIManager.setLayoutAnimationEnabledExperimental(true);
@@ -33,77 +30,25 @@ if (Platform.OS === "android") {
export default function App() {
useEffect(() => UpdateAsync(), []);
+
+ const ProviderTree = buildProvidersTree([
+ FavoriteStationProvider,
+ TrainDelayDataProvider,
+ CurrentTrainProvider,
+ AreaInfoProvider,
+ AllTrainDiagramProvider,
+ BusAndTrainDataProvider,
+ TrainMenuProvider,
+ SheetProvider,
+ AppContainer,
+ ]);
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
);
}
-export function AppContainer() {
- const { areaInfo, areaIconBadgeText } = useAreaInfo();
- const navigationRef = React.useRef();
- return (
-
-
-
- {(props) => }
-
-
-
-
- {(props) => }
-
-
-
- );
-}
diff --git a/Apps.js b/Apps.js
new file mode 100644
index 0000000..9f4a261
--- /dev/null
+++ b/Apps.js
@@ -0,0 +1,55 @@
+import React from "react";
+import { NavigationContainer } from "@react-navigation/native";
+import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
+import { Platform } from "react-native";
+import TNDView from "./ndView";
+import { initIcon } from "./lib/initIcon";
+import { Top } from "./Top.js";
+import { MenuPage } from "./MenuPage.js";
+import { useAreaInfo } from "./stateBox/useAreaInfo.js";
+import "./components/ActionSheetComponents/sheets.js";
+
+export function AppContainer() {
+ const Tab = createBottomTabNavigator();
+ const { areaInfo, areaIconBadgeText } = useAreaInfo();
+ const navigationRef = React.useRef();
+ const getTabProps = (name, label, icon, iconFamily, tabBarBadge) => ({
+ name,
+ options: {
+ tabBarLabel: label,
+ headerTransparent: true,
+ gestureEnabled: true,
+ tabBarIcon: initIcon(icon, iconFamily),
+ tabBarBadge,
+ },
+ });
+ return (
+
+
+ }
+ />
+
+
+ }
+ />
+
+
+ );
+}
diff --git a/Top.js b/Top.js
index bb9aa87..b2bd3bf 100644
--- a/Top.js
+++ b/Top.js
@@ -13,13 +13,12 @@ import FavoriteList from "./components/FavoriteList.js";
import { optionData } from "./lib/stackOption.js";
import { useNavigation } from "@react-navigation/native";
import { useCurrentTrain } from "./stateBox/useCurrentTrain.js";
-import { AS } from "./storageControl.js";
+import { ASCore } from "./storageControl.js";
import { useTrainMenu } from "./stateBox/useTrainMenu";
const Stack = createStackNavigator();
export const Top = ({ navigationRef }) => {
const { webview } = useCurrentTrain();
- const navigation = useNavigation();
- const { navigate, addListener } = navigation;
+ const { navigate, addListener } = useNavigation();
//地図用
const { setMapsStationData, injectJavaScript, setInjectJavaScript } =
@@ -29,42 +28,43 @@ export const Top = ({ navigationRef }) => {
getStationList2().then(setMapsStationData);
}, []);
const [mapSwitch, setMapSwitch] = React.useState("false");
- const ASCore = ({ k, s, d }) =>
- AS.getItem(k)
- .then((d) => (d ? s(d) : AS.setItem(k, d)))
- .catch(() => AS.setItem(k, d));
useEffect(() => {
//地図スイッチ
ASCore({ k: "mapSwitch", s: setMapSwitch, d: "false" });
}, []);
+
+ const goToFavoriteList = () => navigate("favoriteList");
+
useEffect(() => {
- const unsubscribe = addListener("tabLongPress", () =>
- navigate("favoriteList")
- );
+ const unsubscribe = addListener("tabLongPress", goToFavoriteList);
return unsubscribe;
- }, [navigation]);
- useEffect(() => {
- const unsubscribe = navigation.addListener("tabPress", () => {
- if (navigationRef.current?.getCurrentRoute().name == "Apps") {
- if (mapSwitch == "true") {
- navigation.navigate("trainMenu");
- setInjectJavaScript("");
- } else {
- webview.current?.injectJavaScript(`AccordionClassEvent()`);
- }
+ }, [{ navigate, addListener }]);
+
+
+ const goToTrainMenu = () => {
+ if (navigationRef.current?.getCurrentRoute().name == "Apps") {
+ if (mapSwitch == "true") {
+ navigate("trainMenu");
+ setInjectJavaScript("");
} else {
- if (mapSwitch == "true") {
- if (injectJavaScript) {
- webview.current?.injectJavaScript(injectJavaScript);
- setInjectJavaScript("");
- }
- }
- navigation.navigate("Apps");
+ webview.current?.injectJavaScript(`AccordionClassEvent()`);
}
- });
+ } else {
+ if (mapSwitch == "true") {
+ if (injectJavaScript) {
+ webview.current?.injectJavaScript(injectJavaScript);
+ setInjectJavaScript("");
+ }
+ }
+ navigate("Apps");
+ }
+ };
+
+ useEffect(() => {
+ const unsubscribe = addListener("tabPress", goToTrainMenu);
return unsubscribe;
- }, [navigation, mapSwitch, injectJavaScript]);
+ }, [{ navigate, addListener }, mapSwitch, injectJavaScript]);
return (
diff --git a/components/Apps.js b/components/Apps.js
index 38a188b..1b33f12 100644
--- a/components/Apps.js
+++ b/components/Apps.js
@@ -11,7 +11,7 @@ import Constants from "expo-constants";
import { Ionicons } from "@expo/vector-icons";
import * as Updates from "expo-updates";
-import { AS } from "../storageControl";
+import { AS, ASCore } from "../storageControl";
import { news } from "../config/newsUpdate";
import { getStationList, lineList } from "../lib/getStationList";
import { injectJavascriptData } from "../lib/webViewInjectjavascript";
@@ -36,7 +36,7 @@ export default function Apps() {
const { navigate } = useNavigation();
const { isLandscape } = useDeviceOrientationChange();
const handleLayout = () => {};
- const { setInjectJavaScript, mapsStationData: stationData } = useTrainMenu();
+ const { setInjectJavaScript, mapsStationData } = useTrainMenu();
//画面表示関連
const [iconSetting, setIconSetting] = useState(undefined);
@@ -63,10 +63,6 @@ export default function Apps() {
stationMenu,
trainMenu
);
- const ASCore = ({ k, s, d }) =>
- AS.getItem(k)
- .then((d) => (d ? s(d) : AS.setItem(k, d).then(Updates.reloadAsync)))
- .catch(() => AS.setItem(k, d).then(Updates.reloadAsync));
useEffect(() => {
//ニュース表示
@@ -79,13 +75,13 @@ export default function Apps() {
useEffect(() => {
//列車アイコンスイッチ
- ASCore({ k: "iconSwitch", s: setIconSetting, d: "true" });
+ ASCore({ k: "iconSwitch", s: setIconSetting, d: "true", u: true });
//地図スイッチ
- ASCore({ k: "mapSwitch", s: setMapSwitch, d: "false" });
+ ASCore({ k: "mapSwitch", s: setMapSwitch, d: "false", u: true });
//駅メニュースイッチ
- ASCore({ k: "stationSwitch", s: setStationMenu, d: "true" });
+ ASCore({ k: "stationSwitch", s: setStationMenu, d: "true", u: true });
//列車メニュースイッチ
- ASCore({ k: "trainSwitch", s: setTrainMenu, d: "true" });
+ ASCore({ k: "trainSwitch", s: setTrainMenu, d: "true", u: true });
}, []);
const openStationACFromEachTrainInfo = async (stationName) => {
@@ -127,7 +123,7 @@ export default function Apps() {
{!trainInfo.trainNum && isLandscape ? (
) : (
-
+
)}
);
}
-const NewMenu = ({ webview, LoadError }) => {
+const NewMenu = ({ LoadError }) => {
+ const { webview } = useCurrentTrain();
const { width } = useWindowDimensions();
return (
{
+ // 基本ケース:ContextProviderが1つしか残っていない場合、それを返して終了する
+ if (providers.length === 1) {
+ return providers[0];
+ }
+
+ // 配列から最初の2つのContextProviderを取り出す
+ const FirstProvider = providers.shift();
+ const SecondProvider = providers.shift();
+
+ // 十分な数のContextProviderがあるかどうかを確認
+ if (FirstProvider === undefined || SecondProvider === undefined) {
+ throw new Error("ContextProviderが不足しています");
+ }
+
+ // 最初の2つのContextProviderをネストした新しいContextProviderを作成し、再帰する
+ return buildProvidersTree([
+ ({ children }) => (
+
+ {children}
+
+ ),
+ ...providers,
+ ]);
+};
diff --git a/storageControl.js b/storageControl.js
index 939a943..31feacb 100644
--- a/storageControl.js
+++ b/storageControl.js
@@ -1,4 +1,5 @@
import storage from "./storageConfig.js";
+import * as Updates from "expo-updates";
export const AS = {
getItem: (key) => storage.load({ key }),
@@ -13,3 +14,9 @@ export const AS = {
}),
removeItem: (key) => storage.remove({ key }),
};
+export const ASCore = ({ k, s, d, u }) =>
+ AS.getItem(k)
+ .then((d) =>
+ d ? s(d) : AS.setItem(k, d).then(() => u && Updates.reloadAsync())
+ )
+ .catch(() => AS.setItem(k, d).then(() => u && Updates.reloadAsync()));