地図の路線フィルタリング機能の強化

This commit is contained in:
harukin-expo-dev-env 2024-05-27 16:39:15 +00:00
parent 43b911c23f
commit c05824c3d0
6 changed files with 267 additions and 53 deletions

9
App.js
View File

@ -19,6 +19,7 @@ import "./components/ActionSheetComponents/sheets.js";
import { TrainDelayDataProvider } from "./stateBox/useTrainDelayData.js"; import { TrainDelayDataProvider } from "./stateBox/useTrainDelayData.js";
import { SafeAreaProvider } from "react-native-safe-area-context"; import { SafeAreaProvider } from "react-native-safe-area-context";
import { DeviceOrientationChangeProvider } from "./stateBox/useDeviceOrientationChange.js"; import { DeviceOrientationChangeProvider } from "./stateBox/useDeviceOrientationChange.js";
import { TrainMenuProvider } from "./stateBox/useTrainMenu.js";
LogBox.ignoreLogs([ LogBox.ignoreLogs([
"ViewPropTypes will be removed", "ViewPropTypes will be removed",
"ColorPropType will be removed", "ColorPropType will be removed",
@ -42,9 +43,11 @@ export default function App() {
<AreaInfoProvider> <AreaInfoProvider>
<AllTrainDiagramProvider> <AllTrainDiagramProvider>
<BusAndTrainDataProvider> <BusAndTrainDataProvider>
<SheetProvider> <TrainMenuProvider>
<AppContainer /> <SheetProvider>
</SheetProvider> <AppContainer />
</SheetProvider>
</TrainMenuProvider>
</BusAndTrainDataProvider> </BusAndTrainDataProvider>
</AllTrainDiagramProvider> </AllTrainDiagramProvider>
</AreaInfoProvider> </AreaInfoProvider>

3
Top.js
View File

@ -14,6 +14,7 @@ import { optionData } from "./lib/stackOption.js";
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
import { useCurrentTrain } from "./stateBox/useCurrentTrain.js"; import { useCurrentTrain } from "./stateBox/useCurrentTrain.js";
import { AS } from "./storageControl.js"; import { AS } from "./storageControl.js";
import { useTrainMenu } from "./stateBox/useTrainMenu";
const Stack = createStackNavigator(); const Stack = createStackNavigator();
export const Top = ({ navigationRef }) => { export const Top = ({ navigationRef }) => {
const { webview, getCurrentTrain } = useCurrentTrain(); const { webview, getCurrentTrain } = useCurrentTrain();
@ -21,7 +22,7 @@ export const Top = ({ navigationRef }) => {
const { navigate, addListener } = navigation; const { navigate, addListener } = navigation;
//地図用 //地図用
const [mapsStationData, setMapsStationData] = useState(undefined); const { mapsStationData, setMapsStationData } = useTrainMenu();
useEffect(() => { useEffect(() => {
getStationList2().then(setMapsStationData); getStationList2().then(setMapsStationData);

View File

@ -0,0 +1,147 @@
import React, { useEffect, useRef } from "react";
import {
View,
LayoutAnimation,
ScrollView,
Linking,
Text,
TouchableOpacity,
Platform,
BackHandler,
} from "react-native";
import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons";
import ActionSheet, {
SheetManager,
useScrollHandlers,
} from "react-native-actions-sheet";
import LottieView from "lottie-react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import ViewShot from "react-native-view-shot";
import * as Sharing from "expo-sharing";
import { useTrainDelayData } from "../../stateBox/useTrainDelayData";
import { useTrainMenu } from "../../stateBox/useTrainMenu";
import lineColorList from "../../assets/originData/lineColorList";
import { stationIDPair } from "../../lib/getStationList2";
import { lineListPair } from "../../lib/getStationList";
export const TrainMenuLineSelector = () => {
const { getTime, delayData, loadingDelayData, setLoadingDelayData } =
useTrainDelayData();
const {
selectedLine,
setSelectedLine,
mapsStationData: stationData,
setMapsStationData,
} = useTrainMenu();
const actionSheetRef = useRef(null);
const scrollHandlers = useScrollHandlers("scrollview-1", actionSheetRef);
const insets = useSafeAreaInsets();
const viewShot = useRef(null);
const platformIs = Platform.OS == "android";
return (
<ActionSheet
gestureEnabled
CustomHeaderComponent={<></>}
ref={actionSheetRef}
isModal={Platform.OS == "ios"}
containerStyle={platformIs ? { paddingBottom: insets.bottom } : {}}
useBottomSafeAreaPadding={platformIs}
>
<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>
</View>
{Object.keys(stationData).map((d) => (
<TouchableOpacity
style={{
flexDirection: "row",
backgroundColor: selectedLine == d ? "#0099CC33" : "white",
}}
onPress={() => {
SheetManager.hide("TrainMenuLineSelector");
setSelectedLine(selectedLine == d ? undefined : d);
}}
>
<View
style={{
width: 35,
position: "relative",
marginHorizontal: 15,
flexDirection: "row",
height: "101%",
}}
>
<View
style={{
backgroundColor: lineColorList[stationIDPair[d]],
flex: 1,
}}
>
<View style={{ flex: 1 }} />
<Text
style={{
color: "white",
textAlign: "center",
fontSize: 12,
fontWeight: "bold",
}}
>
{stationIDPair[d]}
</Text>
<View style={{ flex: 1 }} />
</View>
</View>
<View
style={{
padding: 8,
flexDirection: "row",
borderBottomWidth: 1,
borderBottomColor: "#f0f0f0",
flex: 1,
alignContent: "center",
alignItems: "center",
}}
>
<Text style={{ fontSize: 20 }}>
{lineListPair[stationIDPair[d]]}
</Text>
<View style={{ flex: 1 }} />
</View>
</TouchableOpacity>
))}
</ActionSheet>
);
};
const Handler = () => {
useEffect(() => {
const backAction = () => {
SheetManager.hide("TrainMenuLineSelector");
return true;
};
const backHandler = BackHandler.addEventListener(
"hardwareBackPress",
backAction
);
return () => backHandler.remove();
}, []);
return <></>;
};

View File

@ -2,9 +2,11 @@ import { registerSheet } from "react-native-actions-sheet";
import { EachTrainInfo } from "./EachTrainInfo"; import { EachTrainInfo } from "./EachTrainInfo";
import { JRSTraInfo } from "./JRSTraInfo"; import { JRSTraInfo } from "./JRSTraInfo";
import { StationDeteilView } from "./StationDeteilView"; import { StationDeteilView } from "./StationDeteilView";
import { TrainMenuLineSelector } from "./TrainMenuLineSelector";
registerSheet("EachTrainInfo", EachTrainInfo); registerSheet("EachTrainInfo", EachTrainInfo);
registerSheet("JRSTraInfo", JRSTraInfo); registerSheet("JRSTraInfo", JRSTraInfo);
registerSheet("StationDetailView", StationDeteilView); registerSheet("StationDetailView", StationDeteilView);
registerSheet("TrainMenuLineSelector", TrainMenuLineSelector);
export {}; export {};

View File

@ -1,18 +1,21 @@
import React, { useRef, useState, useEffect } from "react"; import React, { useRef, useState, useEffect } from "react";
import { View, Text, TouchableOpacity, Linking } from "react-native"; import { View, Text, TouchableOpacity, Linking, Platform } from "react-native";
import MapView, { Marker } from "react-native-maps"; import MapView, { Marker } from "react-native-maps";
import { MaterialCommunityIcons } from "@expo/vector-icons"; import Constants from "expo-constants";
import { MaterialCommunityIcons, Ionicons } from "@expo/vector-icons";
import { useCurrentTrain } from "../stateBox/useCurrentTrain"; import { useCurrentTrain } from "../stateBox/useCurrentTrain";
import { useNavigation } from "@react-navigation/native"; import { useNavigation } from "@react-navigation/native";
import lineColorList from "../assets/originData/lineColorList"; import lineColorList from "../assets/originData/lineColorList";
import { stationIDPair } from "../lib/getStationList2"; import { stationIDPair } from "../lib/getStationList2";
import { lineListPair } from "../lib/getStationList"; import { lineListPair } from "../lib/getStationList";
import { SheetManager } from "react-native-actions-sheet";
import { useTrainMenu } from "../stateBox/useTrainMenu";
export default function TrainMenu({ stationData, style }) { export default function TrainMenu({ stationData, style }) {
const { webview } = useCurrentTrain(); const { webview } = useCurrentTrain();
const mapRef = useRef(); const mapRef = useRef();
const { navigate } = useNavigation(); const { navigate } = useNavigation();
const [stationPin, setStationPin] = useState([]); const [stationPin, setStationPin] = useState([]);
const [selectedLine, setSelectedLine] = useState(undefined); const { selectedLine, setSelectedLine } = useTrainMenu();
useEffect(() => { useEffect(() => {
const stationPinData = []; const stationPinData = [];
Object.keys(stationData).map((d, indexBase) => Object.keys(stationData).map((d, indexBase) =>
@ -40,32 +43,6 @@ export default function TrainMenu({ stationData, style }) {
}, [stationPin]); }, [stationPin]);
return ( return (
<View style={{ height: "100%", backgroundColor: "#0099CC", ...style }}> <View style={{ height: "100%", backgroundColor: "#0099CC", ...style }}>
{selectedLine && (
<View
style={{
position: "absolute",
top: 0,
left: 0,
right: 0,
backgroundColor: lineColorList[stationIDPair[selectedLine]],
padding: 10,
zIndex: 100,
alignItems: "center",
}}
>
<Text
style={{
color: "white",
fontWeight: "bold",
fontSize: 20,
textAlign: "center",
}}
>
{selectedLine ? lineListPair[stationIDPair[selectedLine]] : "全線"}
</Text>
</View>
)}
<MapView <MapView
style={{ flex: 1, width: "100%", height: "100%" }} style={{ flex: 1, width: "100%", height: "100%" }}
showsUserLocation={true} showsUserLocation={true}
@ -105,6 +82,34 @@ export default function TrainMenu({ stationData, style }) {
flex: 1, 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: 20,
textAlign: "center",
}}
>
{selectedLine
? lineListPair[stationIDPair[selectedLine]]
: "ここを押して路線をフィルタリングできます  ▲"}
</Text>
</TouchableOpacity>
<Text style={{ position: "absolute", bottom: 40 }}> <Text style={{ position: "absolute", bottom: 40 }}>
路線記号からフィルタリング 路線記号からフィルタリング
</Text> </Text>
@ -116,8 +121,12 @@ export default function TrainMenu({ stationData, style }) {
padding: 5, padding: 5,
margin: 2, margin: 2,
borderRadius: 10, borderRadius: 10,
borderColor: "white",
borderWidth: 1,
borderStyle: "solid",
alignItems: "center", alignItems: "center",
opacity: selectedLine == d ? 1 : !selectedLine ? 1 : 0.5, opacity: selectedLine == d ? 1 : !selectedLine ? 1 : 0.5,
zIndex: 10,
}} }}
onPress={() => setSelectedLine(selectedLine == d ? undefined : d)} onPress={() => setSelectedLine(selectedLine == d ? undefined : d)}
> >
@ -166,26 +175,11 @@ export default function TrainMenu({ stationData, style }) {
</UsefulBox> </UsefulBox>
</View> </View>
)} )}
{navigate && ( <MapsButton
<TouchableOpacity onPress={() => navigate("Apps")}
style={{ top={Platform.OS == "ios" ? Constants.statusBarHeight : 0}
padding: 10, mapSwitch={"flex"}
flexDirection: "row", />
borderColor: "white",
borderWidth: 1,
margin: 10,
borderRadius: 5,
alignItems: "center",
}}
onPress={() => navigate("Apps")}
>
<View style={{ flex: 1 }} />
<Text style={{ fontSize: 25, fontWeight: "bold", color: "white" }}>
閉じる
</Text>
<View style={{ flex: 1 }} />
</TouchableOpacity>
)}
</View> </View>
); );
} }
@ -228,3 +222,39 @@ const MapPin = ({ index, indexBase, latlng, D, d, navigate, webview }) => {
></Marker> ></Marker>
); );
}; };
const MapsButton = ({ onPress, top, mapSwitch }) => {
const styles = {
touch: {
position: "absolute",
top,
left: 10,
width: 50,
height: 50,
backgroundColor: "#0099CC",
borderColor: "white",
borderStyle: "solid",
borderWidth: 1,
borderRadius: 50,
alignContent: "center",
alignSelf: "center",
alignItems: "center",
display: mapSwitch,
},
text: {
textAlign: "center",
width: "auto",
height: "auto",
textAlignVertical: "center",
fontWeight: "bold",
color: "white",
},
};
return (
<TouchableOpacity onPress={onPress} style={styles.touch}>
<View style={{ flex: 1 }} />
<Ionicons name="close" color="white" size={30} />
<View style={{ flex: 1 }} />
</TouchableOpacity>
);
};

31
stateBox/useTrainMenu.js Normal file
View File

@ -0,0 +1,31 @@
import React, { createContext, useContext, useState } from "react";
const initialState = {
selectedLine: undefined,
setSelectedLine: () => {},
mapsStationData: undefined,
setMapsStationData: () => {},
};
const TrainMenuContext = createContext(initialState);
export const useTrainMenu = () => {
return useContext(TrainMenuContext);
};
export const TrainMenuProvider = ({ children }) => {
const [selectedLine, setSelectedLine] = useState(undefined);
const [mapsStationData, setMapsStationData] = useState(undefined);
return (
<TrainMenuContext.Provider
value={{
selectedLine,
setSelectedLine,
mapsStationData,
setMapsStationData,
}}
>
{children}
</TrainMenuContext.Provider>
);
};