Merge commit '1fb471205c30dc71e59506f01afc002ee81bcef4' into develop

This commit is contained in:
harukin-OneMix4 2024-02-11 21:26:52 +09:00
commit acecd1a88b
9 changed files with 599 additions and 445 deletions

View File

@ -2,32 +2,28 @@ import React, { useEffect, useState, useRef } from "react";
import {
View,
LayoutAnimation,
ScrollView,
Linking,
Text,
TouchableOpacity,
TouchableWithoutFeedback,
Platform,
StyleSheet,
} from "react-native";
import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons";
import ActionSheet, {
SheetManager,
useScrollHandlers,
} from "react-native-actions-sheet";
import { Ionicons } from "@expo/vector-icons";
import ActionSheet, { SheetManager } from "react-native-actions-sheet";
import { AS } from "../../storageControl";
import trainList from "../../assets/originData/trainList";
import { lineList } from "../../lib/getStationList";
import {
heightPercentageToDP,
widthPercentageToDP,
} from "react-native-responsive-screen";
import lineColorList from "../../assets/originData/lineColorList";
import { heightPercentageToDP } from "react-native-responsive-screen";
import { useCurrentTrain } from "../../stateBox/useCurrentTrain";
import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData";
import dayjs from "dayjs";
import { getTrainType } from "../../lib/getTrainType";
import { customTrainDataDetector } from "../custom-train-data";
import { useBusAndTrainData } from "../../stateBox/useBusAndTrainData";
import { EachStopList } from "./EachTrainInfo/EachStopList";
import { DataFromButton } from "./EachTrainInfo/DataFromButton";
import { DynamicHeaderScrollView } from "../DynamicHeaderScrollView";
import { LongHeader } from "./EachTrainInfo/LongHeader";
import { ShortHeader } from "./EachTrainInfo/ShortHeader";
import { ScrollStickyContent } from "./EachTrainInfo/ScrollStickyContent";
export const EachTrainInfo = (props) => {
if (!props.payload) return <></>;
@ -67,9 +63,6 @@ export const EachTrainInfo = (props) => {
showNearTrain.forEach((d) => {
const [station, se, time] = d.split(",");
console.log(trainData); //trainDataは現在の列車の停車駅リスト
console.log(station); //showNearTrainは裏列車の停車駅リスト
console.log(trainData[0]);
if (station == trainData[0].split(",")[0])
setHeadStation(trainData[0].split(",")[0]);
if (station == trainData[trainData.length - 1].split(",")[0])
@ -383,7 +376,6 @@ export const EachTrainInfo = (props) => {
.replace("ライナーライナー", "ライナー");
};
const actionSheetRef = useRef(null);
const scrollHandlers = useScrollHandlers("scrollview-1", actionSheetRef);
return (
<ActionSheet
gestureEnabled={true}
@ -453,168 +445,38 @@ export const EachTrainInfo = (props) => {
/>
)}
</View>
{from == "AllTrainDiagramView" || (
<ScrollView
//onTouchStart={() => setActionSheetHorizonalScroll(true)}
//onScrollEndDrag={() => setActionSheetHorizonalScroll(false)}
//onScrollBeginDrag={() => console.log("onScrollBeginDrag")}
style={{
flexDirection: "row",
//width: widthPercentageToDP("200%"),
minHeight: 200,
height: heightPercentageToDP("20%"),
}}
horizontal
pagingEnabled
>
<TrainDataView
currentTrainData={currentTrainData}
currentPosition={currentPosition}
nearTrainIDList={nearTrainIDList}
openTrainInfo={openTrainInfo}
/>
{/* <View
style={{
flexDirection: "column",
height: heightPercentageToDP("20%"),
flex: 1,
width: widthPercentageToDP("100%"),
}}
>
<View style={{ flex: 1, flexDirection: "row" }}>
<View
style={{
flex: 1,
backgroundColor: "white",
borderRadius: 10,
padding: 10,
margin: 10,
}}
>
<Text style={{ fontSize: 15, color: "#0099CC" }}>行先</Text>
<View style={{ flex: 1 }} />
<Text
style={{
fontSize: 20,
color: "#0099CC",
textAlign: "right",
}}
>
岡山
</Text>
</View>
<View
style={{
flex: 3,
backgroundColor: "white",
borderRadius: 10,
padding: 10,
margin: 10,
}}
>
<Text style={{ fontSize: 15, color: "#0099CC" }}>
車両案内
</Text>
<View style={{ flex: 1 }} />
<Text
style={{
fontSize: 20,
color: "#0099CC",
textAlign: "right",
}}
>
宇多津でうずしお号と連結
</Text>
</View>
</View>
<View style={{ flex: 1, flexDirection: "row" }}>
<View
style={{
flex: 1,
backgroundColor: "white",
borderRadius: 10,
padding: 10,
margin: 10,
}}
>
<Text style={{ fontSize: 15, color: "#0099CC" }}>
編成(使用車両2700)
</Text>
<View style={{ flex: 1 }} />
<Text
style={{
fontSize: 20,
color: "#0099CC",
textAlign: "left",
}}
>
{"[<自][自>][アン自|指>][アン指|G>]"}
</Text>
</View>
</View>
</View> */}
</ScrollView>
)}
<View
style={{
alignItems: "center",
backgroundColor: "white",
flexDirection: "row",
}}
>
<View
style={{
padding: 8,
flexDirection: "row",
borderBottomWidth: 1,
borderBottomColor: "#f0f0f0",
flex: 1,
}}
>
<Text style={{ fontSize: 20 }}>停車駅</Text>
<View style={{ flex: 1 }} />
<View style={{ flexDirection: "row" }}>
{!isNaN(currentTrainData?.delay) &&
currentTrainData?.delay != 0 && (
<Text
style={{
fontSize: 15,
color: "black",
position: "absolute",
right: 110,
textAlign: "right",
textDecorationLine: "line-through",
}}
>
(定刻)
</Text>
)}
<Text
style={{
fontSize: 20,
color: isNaN(currentTrainData?.delay)
? "black"
: currentTrainData?.delay == 0
? "black"
: "red",
width: 60,
}}
>
見込
</Text>
<Text style={{ fontSize: 20, width: 50 }}></Text>
</View>
</View>
</View>
<ScrollView
{...scrollHandlers}
style={{
maxHeight: heightPercentageToDP(
from == "AllTrainDiagramView" ? "70%" : "50%"
),
backgroundColor: "white",
}}
<DynamicHeaderScrollView
styles={styles}
containerProps={{ style: { maxHeight: heightPercentageToDP("70%") } }}
Max_Header_Height={from == "AllTrainDiagramView" ? 0 : 200}
Min_Header_Height={from == "AllTrainDiagramView" ? 0 : 80}
shortHeader={
from == "AllTrainDiagramView" ? (
<></>
) : (
<ShortHeader
currentTrainData={currentTrainData}
currentPosition={currentPosition}
nearTrainIDList={nearTrainIDList}
openTrainInfo={openTrainInfo}
/>
)
}
longHeader={
from == "AllTrainDiagramView" ? (
<></>
) : (
<LongHeader
currentTrainData={currentTrainData}
currentPosition={currentPosition}
nearTrainIDList={nearTrainIDList}
openTrainInfo={openTrainInfo}
/>
)
}
topStickyContent={
<ScrollStickyContent currentTrainData={currentTrainData} />
}
>
{headStation && !isConcatNear && (
<TouchableOpacity
@ -648,7 +510,7 @@ export const EachTrainInfo = (props) => {
i.split(",")[1] == "提" ? (
<DataFromButton i={i} />
) : (
<StationButton
<EachStopList
i={i}
index={index}
stationList={stationList}
@ -693,271 +555,26 @@ export const EachTrainInfo = (props) => {
<View style={{ flex: 1 }} />
</View>
</View>
</ScrollView>
</DynamicHeaderScrollView>
</View>
</ActionSheet>
);
};
const DataFromButton = ({ i }) => {
const [station, se, time] = i.split(",");
return (
<TouchableWithoutFeedback
onPress={() => Linking.openURL(time)}
key={station}
>
<View style={{ flexDirection: "row" }}>
<View
style={{
padding: 8,
flexDirection: "row",
borderBottomWidth: 1,
borderBottomColor: "#f0f0f0",
flex: 1,
}}
>
<Text style={{ fontSize: 20 }}>{station}</Text>
<View style={{ flex: 1 }} />
<Text style={{ fontSize: 18 }}>
提供元
<MaterialCommunityIcons
name={"open-in-new"}
color="black"
size={20}
/>
</Text>
</View>
</View>
</TouchableWithoutFeedback>
);
};
const StationButton = ({
i,
index,
stationList,
points,
currentTrainData,
openStationACFromEachTrainInfo,
}) => {
const [station, se, time] = i.split(","); // 阿波池田,発,6:21
const Stations = stationList
.map((a) => a.filter((d) => d.StationName == station))
.reduce((newArray, e) => newArray.concat(e), []);
/*Array [
Object {
"StationName": "佐古",
"StationNumber": "T01",
},
Object {
"StationName": "佐古",
"StationNumber": "B01",
},
] */
const StationNumbers =
Stations &&
Stations.filter((d) => d.StationNumber).map((d) => d.StationNumber);
// Array [ "T01", "B01",]
const lineIDs = [];
const EachIDs = [];
StationNumbers.forEach((d) => {
const textArray = d.split("");
lineIDs.push(textArray.filter((s) => "A" < s && s < "Z").join(""));
EachIDs.push(textArray.filter((s) => "0" <= s && s <= "9").join(""));
});
// Array [ "T", "B",]
// Array [ "01", "01",]
const dates = dayjs()
.set("hour", parseInt(time.split(":")[0]))
.set("minute", parseInt(time.split(":")[1]))
.add(isNaN(currentTrainData?.delay) ? 0 : currentTrainData.delay, "minute");
const timeString = dates.format("HH:mm").split(":");
return (
<TouchableWithoutFeedback
onPress={() => openStationACFromEachTrainInfo(station)}
key={station}
>
<View style={{ flexDirection: "row", backgroundColor: "white" }}>
<View
style={{
width: 35,
position: "relative",
marginHorizontal: 15,
flexDirection: "row",
height: "101%",
}}
>
{lineIDs.map((lineID, index) => (
<View
style={{
backgroundColor: lineColorList[lineID],
flex: 1,
}}
key={lineID}
>
<View style={{ flex: 1 }} />
<Text
style={{
color: "white",
textAlign: "center",
fontSize: 10,
fontWeight: "bold",
}}
>
{lineIDs[index]}
{"\n"}
{EachIDs[index]}
</Text>
<View style={{ flex: 1 }} />
</View>
))}
</View>
<View
style={{
padding: 8,
flexDirection: "row",
borderBottomWidth: 1,
borderBottomColor: "#f0f0f0",
flex: 1,
}}
>
<Text style={{ fontSize: 20 }}>{station}</Text>
<View style={{ flex: 1 }} />
{points && points.findIndex((d) => d == index) >= 0 ? (
<Text style={{ fontSize: 20, marginRight: 70 }}>🚊</Text>
) : null}
{!isNaN(currentTrainData?.delay) && currentTrainData?.delay != 0 && (
<Text
style={{
fontSize: 15,
color: "black",
width: 60,
position: "absolute",
right: 120,
textAlign: "right",
textDecorationLine: "line-through",
}}
>
{time}
</Text>
)}
<Text
style={{
fontSize: 20,
color: isNaN(currentTrainData?.delay)
? "black"
: currentTrainData?.delay == 0
? "black"
: "red",
width: 60,
}}
>
{timeString[0]}:{timeString[1]}
</Text>
<Text style={{ fontSize: 18, width: 50 }}>
{se?.replace("発", "出発").replace("着", "到着")}
</Text>
</View>
</View>
</TouchableWithoutFeedback>
);
};
const TrainDataView = ({
currentTrainData,
currentPosition,
nearTrainIDList,
openTrainInfo,
}) => {
return (
<View
style={{
flexDirection: "row",
minHeight: 200,
height: heightPercentageToDP("20%"),
width: widthPercentageToDP("100%"),
}}
>
<StateBox
title={`現在地 ${currentPosition.toString()}`}
text={
currentTrainData?.Pos.match("")
? `${
currentTrainData?.Pos.replace("(下り)", "")
.replace("(上り)", "")
.split("")[0]
}${
currentTrainData?.Pos.replace("(下り)", "")
.replace("(上り)", "")
.split("")[1]
}`
: currentTrainData?.Pos
}
/>
<View style={{ flex: 1, flexDirection: "column" }}>
<View style={{ flex: 1, flexDirection: "row" }}>
<StateBox
title={isNaN(currentTrainData?.delay) ? "状態" : "遅延時分"}
text={`${currentTrainData?.delay}${
isNaN(currentTrainData?.delay) ? "" : "分"
}`}
/>
</View>
<TouchableOpacity
style={{ flex: 1, flexDirection: "row" }}
disabled={nearTrainIDList.length == 0}
onPress={() => {
if (nearTrainIDList.length == 0) return;
openTrainInfo(nearTrainIDList[0]);
}}
>
{nearTrainIDList.length == 0 ? (
<StateBox title="列番" text={currentTrainData?.num} />
) : (
<StateBox
title="増解結相手を表示▶️"
text={`${nearTrainIDList}`}
style={{
borderWidth: 1,
borderColor: "red",
borderStyle: "solid",
}}
/>
)}
</TouchableOpacity>
</View>
</View>
);
};
const StateBox = ({ text, title, style }) => (
<View style={{ ...boxStyle, ...style }}>
<Text style={{ fontSize: 12, color: "#0099CC" }}>{title}</Text>
<View style={{ flex: 1 }} />
<View style={{ fontSize: 25, color: "#0099CC", textAlign: "right" }}>
{text?.match("") ? (
<>
<Text style={boxTextStyle}>{text.split("")[0]}</Text>
<Text style={{ color: "#0099CC", textAlign: "right" }}></Text>
<Text style={boxTextStyle}>{text.split("")[1]}</Text>
</>
) : (
<Text style={boxTextStyle}>{text}</Text>
)}
</View>
</View>
);
const boxStyle = {
flex: 1,
backgroundColor: "white",
borderRadius: 10,
padding: 10,
margin: 10,
};
const boxTextStyle = {
fontSize: 25,
color: "#0099CC",
textAlign: "right",
};
const styles = StyleSheet.create({
header: {
justifyContent: "center",
alignItems: "center",
left: 0,
right: 0,
//paddingTop: 10,
position: "absolute",
zIndex: 1,
backgroundColor: "f0f0f0",
},
headerText: {
color: "#fff",
fontSize: 25,
fontWeight: "bold",
textAlign: "center",
},
});

View File

@ -0,0 +1,36 @@
import React from "react";
import { View, Text, TouchableWithoutFeedback } from "react-native";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import { Linking } from "react-native";
export const DataFromButton = ({ i }) => {
const [station, se, time] = i.split(",");
return (
<TouchableWithoutFeedback
onPress={() => Linking.openURL(time)}
key={station}
>
<View style={{ flexDirection: "row" }}>
<View
style={{
padding: 8,
flexDirection: "row",
borderBottomWidth: 1,
borderBottomColor: "#f0f0f0",
flex: 1,
}}
>
<Text style={{ fontSize: 20 }}>{station}</Text>
<View style={{ flex: 1 }} />
<Text style={{ fontSize: 18 }}>
提供元
<MaterialCommunityIcons
name={"open-in-new"}
color="black"
size={20}
/>
</Text>
</View>
</View>
</TouchableWithoutFeedback>
);
};

View File

@ -0,0 +1,137 @@
import React from "react";
import { View, Text, TouchableWithoutFeedback } from "react-native";
import dayjs from "dayjs";
import lineColorList from "../../../assets/originData/lineColorList";
export const EachStopList = ({
i,
index,
stationList,
points,
currentTrainData,
openStationACFromEachTrainInfo,
}) => {
const [station, se, time] = i.split(","); // 阿波池田,発,6:21
const Stations = stationList
.map((a) => a.filter((d) => d.StationName == station))
.reduce((newArray, e) => newArray.concat(e), []);
/*Array [
Object {
"StationName": "佐古",
"StationNumber": "T01",
},
Object {
"StationName": "佐古",
"StationNumber": "B01",
},
] */
const StationNumbers =
Stations &&
Stations.filter((d) => d.StationNumber).map((d) => d.StationNumber);
// Array [ "T01", "B01",]
const lineIDs = [];
const EachIDs = [];
StationNumbers.forEach((d) => {
const textArray = d.split("");
lineIDs.push(textArray.filter((s) => "A" < s && s < "Z").join(""));
EachIDs.push(textArray.filter((s) => "0" <= s && s <= "9").join(""));
});
// Array [ "T", "B",]
// Array [ "01", "01",]
const dates = dayjs()
.set("hour", parseInt(time.split(":")[0]))
.set("minute", parseInt(time.split(":")[1]))
.add(isNaN(currentTrainData?.delay) ? 0 : currentTrainData.delay, "minute");
const timeString = dates.format("HH:mm").split(":");
return (
<TouchableWithoutFeedback
onPress={() => openStationACFromEachTrainInfo(station)}
key={station}
>
<View style={{ flexDirection: "row", backgroundColor: "white" }}>
<View
style={{
width: 35,
position: "relative",
marginHorizontal: 15,
flexDirection: "row",
height: "101%",
}}
>
{lineIDs.map((lineID, index) => (
<View
style={{
backgroundColor: lineColorList[lineID],
flex: 1,
}}
key={lineID}
>
<View style={{ flex: 1 }} />
<Text
style={{
color: "white",
textAlign: "center",
fontSize: 10,
fontWeight: "bold",
}}
>
{lineIDs[index]}
{"\n"}
{EachIDs[index]}
</Text>
<View style={{ flex: 1 }} />
</View>
))}
</View>
<View
style={{
padding: 8,
flexDirection: "row",
borderBottomWidth: 1,
borderBottomColor: "#f0f0f0",
flex: 1,
}}
>
<Text style={{ fontSize: 20 }}>{station}</Text>
<View style={{ flex: 1 }} />
{points && points.findIndex((d) => d == index) >= 0 ? (
<Text style={{ fontSize: 20, marginRight: 70 }}>🚊</Text>
) : null}
{!isNaN(currentTrainData?.delay) && currentTrainData?.delay != 0 && (
<Text
style={{
fontSize: 15,
color: "black",
width: 60,
position: "absolute",
right: 120,
textAlign: "right",
textDecorationLine: "line-through",
}}
>
{time}
</Text>
)}
<Text
style={{
fontSize: 20,
color: isNaN(currentTrainData?.delay)
? "black"
: currentTrainData?.delay == 0
? "black"
: "red",
width: 60,
}}
>
{timeString[0]}:{timeString[1]}
</Text>
<Text style={{ fontSize: 18, width: 50 }}>
{se?.replace("発", "出発").replace("着", "到着")}
</Text>
</View>
</View>
</TouchableWithoutFeedback>
);
};

View File

@ -0,0 +1,33 @@
import React from "react";
import { ScrollView } from "react-native";
import { TrainDataView } from "./TrainDataView";
export const LongHeader = ({
currentTrainData,
currentPosition,
nearTrainIDList,
openTrainInfo,
}) => {
return (
<ScrollView
//onTouchStart={() => setActionSheetHorizonalScroll(true)}
//onScrollEndDrag={() => setActionSheetHorizonalScroll(false)}
//onScrollBeginDrag={() => console.log("onScrollBeginDrag")}
style={{
flexDirection: "row",
//width: widthPercentageToDP("200%"),
// minHeight: 200,
//height: heightPercentageToDP("20%"),
}}
horizontal
pagingEnabled
>
<TrainDataView
currentTrainData={currentTrainData}
currentPosition={currentPosition}
nearTrainIDList={nearTrainIDList}
openTrainInfo={openTrainInfo}
/>
</ScrollView>
);
};

View File

@ -0,0 +1,57 @@
import React from "react";
import { View, Text } from "react-native";
export const ScrollStickyContent = ({ currentTrainData }) => {
return (
<View
style={{
alignItems: "center",
backgroundColor: "white",
flexDirection: "row",
}}
>
<View
style={{
padding: 8,
flexDirection: "row",
borderBottomWidth: 1,
borderBottomColor: "#f0f0f0",
flex: 1,
}}
>
<Text style={{ fontSize: 20 }}>停車駅</Text>
<View style={{ flex: 1 }} />
<View style={{ flexDirection: "row" }}>
{!isNaN(currentTrainData?.delay) && currentTrainData?.delay != 0 && (
<Text
style={{
fontSize: 15,
color: "black",
position: "absolute",
right: 110,
textAlign: "right",
textDecorationLine: "line-through",
}}
>
(定刻)
</Text>
)}
<Text
style={{
fontSize: 20,
color: isNaN(currentTrainData?.delay)
? "black"
: currentTrainData?.delay == 0
? "black"
: "red",
width: 60,
}}
>
見込
</Text>
<Text style={{ fontSize: 20, width: 50 }}></Text>
</View>
</View>
</View>
);
};

View File

@ -0,0 +1,35 @@
import React from "react";
import { ScrollView } from "react-native";
import { TrainDataView } from "./TrainDataView";
export const ShortHeader = ({
currentTrainData,
currentPosition,
nearTrainIDList,
openTrainInfo,
}) => {
return (
<ScrollView
//onTouchStart={() => setActionSheetHorizonalScroll(true)}
//onScrollEndDrag={() => setActionSheetHorizonalScroll(false)}
//onScrollBeginDrag={() => console.log("onScrollBeginDrag")}
style={{
flexDirection: "row",
flex: 1,
//width: widthPercentageToDP("200%"),
// minHeight: 200,
//height: heightPercentageToDP("20%"),
}}
horizontal
pagingEnabled
>
<TrainDataView
mode={2}
currentTrainData={currentTrainData}
currentPosition={currentPosition}
nearTrainIDList={nearTrainIDList}
openTrainInfo={openTrainInfo}
/>
</ScrollView>
);
};

View File

@ -0,0 +1,55 @@
import React from "react";
import { View, Text } from "react-native";
export const StateBox = ({ text, title, style, mode }) => (
<View style={{ ...(mode == 2 ? boxStyle2 : boxStyle), ...style }}>
<Text style={{ fontSize: 12, color: "#0099CC" }}>{title}</Text>
<View style={{ flex: 1 }} />
<View
style={{
color: "#0099CC",
textAlign: "right",
flexDirection: mode == 2 ? "row" : "column",
}}
>
{text?.match("") ? (
<>
<Text style={mode == 2 ? boxTextStyle2 : boxTextStyle}>
{text.split("")[0]}
</Text>
<Text style={{ color: "#0099CC", textAlign: "right" }}></Text>
<Text style={mode == 2 ? boxTextStyle2 : boxTextStyle}>
{text.split("")[1]}
</Text>
</>
) : (
<Text style={mode == 2 ? boxTextStyle2 : boxTextStyle}>{text}</Text>
)}
</View>
</View>
);
const boxStyle = {
flex: 1,
backgroundColor: "white",
borderRadius: 10,
padding: 10,
margin: 10,
};
const boxStyle2 = {
flex: 1,
backgroundColor: "white",
borderRadius: 10,
padding: 5,
margin: 5,
};
const boxTextStyle2 = {
fontSize: 18,
color: "#0099CC",
textAlign: "right",
};
const boxTextStyle = {
fontSize: 25,
color: "#0099CC",
textAlign: "right",
};

View File

@ -0,0 +1,79 @@
import React from "react";
import { View, Text, TouchableOpacity } from "react-native";
import { StateBox } from "./StateBox";
import {
heightPercentageToDP,
widthPercentageToDP,
} from "react-native-responsive-screen";
export const TrainDataView = ({
currentTrainData,
currentPosition,
nearTrainIDList,
openTrainInfo,
mode = 0,
}) => {
return (
<View
style={{
flexDirection: "row",
//minHeight: 200,
//height: heightPercentageToDP("20%"),
width: widthPercentageToDP("100%"),
flex: 1,
}}
>
<StateBox
mode={mode}
title={`現在地 ${currentPosition.toString()}`}
text={
currentTrainData?.Pos.match("")
? `${
currentTrainData?.Pos.replace("(下り)", "")
.replace("(上り)", "")
.split("")[0]
}${
currentTrainData?.Pos.replace("(下り)", "")
.replace("(上り)", "")
.split("")[1]
}`
: currentTrainData?.Pos
}
/>
<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}
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 File

@ -0,0 +1,105 @@
import { ScrollView, View, Animated } from "react-native";
import React, { useRef } from "react";
export const DynamicHeaderScrollView = (props) => {
const {
Max_Header_Height = 200,
Min_Header_Height = 80,
children,
scrollViewProps = {},
containerProps = {},
shortHeader = <></>,
longHeader = <></>,
topStickyContent,
styles,
} = props;
const scrollOffsetY = useRef(new Animated.Value(0)).current;
const Scroll_Distance = Max_Header_Height - Min_Header_Height;
const animatedHeaderHeight = scrollOffsetY.interpolate({
inputRange: [Scroll_Distance, Scroll_Distance + 10],
outputRange: [Max_Header_Height, 0],
extrapolate: "clamp",
});
const animatedHeaderHeight2 = scrollOffsetY.interpolate({
inputRange: [0, Scroll_Distance],
outputRange: [Max_Header_Height, Min_Header_Height],
extrapolate: "clamp",
});
const animatedHeaderVisible = scrollOffsetY.interpolate({
inputRange: [Min_Header_Height, Scroll_Distance],
outputRange: [1, 0],
extrapolate: "clamp",
});
const animatedHeaderVisible2 = scrollOffsetY.interpolate({
inputRange: [Min_Header_Height, Scroll_Distance],
outputRange: [0, 1],
extrapolate: "clamp",
});
return (
<View {...containerProps}>
<View style={{ position: "relative" }}>
<Animated.View
style={[
styles.header,
{
height: animatedHeaderHeight2,
backgroundColor: "#0099CC",
margin: 0,
top: 0,
opacity: animatedHeaderVisible2,
},
]}
>
{shortHeader}
</Animated.View>
<Animated.View
style={[
styles.header,
{
height: animatedHeaderHeight,
backgroundColor: "#0099CC",
opacity: animatedHeaderVisible,
top: 0,
},
]}
>
{longHeader}
</Animated.View>
</View>
<ScrollView
{...scrollViewProps}
style={{
backgroundColor: "white",
}}
stickyHeaderIndices={[1]}
scrollEventThrottle={16}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: scrollOffsetY } } }],
{ useNativeDriver: false }
)}
>
<View
style={{
height: Scroll_Distance,
flexDirection: "column",
}}
/>
{topStickyContent && (
<View
style={{
paddingTop: Min_Header_Height,
flexDirection: "column",
}}
index={1}
>
{topStickyContent}
</View>
)}
{children}
</ScrollView>
</View>
);
};