jrshikoku/components/Menu/Carousel/CarouselBox.tsx
2025-07-15 02:56:29 +00:00

187 lines
5.6 KiB
TypeScript

import Sign from "@/components/駅名表/Sign";
import React, { useEffect, useRef, useState } from "react";
import { AS } from "@/storageControl";
import {
useWindowDimensions,
View,
LayoutAnimation,
TouchableOpacity,
Text,
ScrollView,
} from "react-native";
import Carousel, { ICarouselInstance } from "react-native-reanimated-carousel";
import { SheetManager } from "react-native-actions-sheet";
import { StationNumber } from "../StationPagination";
import { SimpleDot } from "../SimpleDot";
export const CarouselBox = ({
originalStationList,
listUpStation,
nearPositionStation,
setListIndex,
listIndex,
navigate,
stationListMode,
isSearchMode
}) => {
const carouselRef = useRef<ICarouselInstance>(null);
const { height, width } = useWindowDimensions();
const [dotButton, setDotButton] = useState(false);
const carouselBadgeScrollViewRef = useRef<ScrollView>(null);
useEffect(() => {
if (!carouselBadgeScrollViewRef.current) return;
const dotSize = dotButton ? 28 : 24;
const scrollToIndex = dotSize * listIndex - width / 2 + dotSize - 5;
carouselBadgeScrollViewRef.current.scrollTo({
x: scrollToIndex,
animated: true,
});
}, [listIndex, dotButton, width, carouselBadgeScrollViewRef]);
const oPSign = () => {
const payload = {
currentStation: listUpStation[listIndex],
navigate,
goTo: "menu",
//@ts-ignore
useShow: () => SheetManager.show("StationDetailView", { payload }),
onExit: () => SheetManager.hide("StationDetailView"),
};
//@ts-ignore
SheetManager.show("StationDetailView", { payload });
};
const oLPSign = () => {
LayoutAnimation.configureNext({
duration: 600,
update: { type: "spring", springDamping: 0.5 },
});
AS.setItem(
"CarouselSettings/activeDotSettings",
!dotButton ? "true" : "false"
);
setDotButton(!dotButton);
};
useEffect(() => {
AS.getItem("CarouselSettings/activeDotSettings").then((data) => {
setDotButton(data === "true");
});
}, []);
const RenderItem = ({ item, index }) => {
return (
<View
style={{
backgroundColor: "#0000",
width,
flexDirection: "row",
marginLeft: 0,
marginRight: 0,
}}
key={item[0].StationNumber}
>
<View style={{ flex: 1 }} />
{item[0].StationNumber != "null" ? (
<Sign
stationID={item[0].StationNumber}
isCurrentStation={item == nearPositionStation}
oP={oPSign}
oLP={oLPSign}
/>
) : (
<TouchableOpacity
style={{
width: width * 0.8,
height: ((width * 0.8) / 20) * 9,
borderColor: "#0099CC",
borderWidth: 1,
backgroundColor: "white",
}}
>
<View
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
<Text style={{ color: "#0099CC", fontSize: 20 }}>
{!!isSearchMode ? "路線検索モードです。入力欄に駅名やナンバリングを入力したり、上に並んでいる路線を選んでみましょう!" :stationListMode == "position"
? "現在地の近くに駅がありません。"
: "お気に入りリストがありません。お気に入りの駅を追加しよう!"}
</Text>
</View>
</TouchableOpacity>
)}
<View style={{ flex: 1 }} />
</View>
);
};
return (
<View style={{ flex: 1, paddingTop: 10 }}>
<Carousel
ref={carouselRef}
data={
listUpStation.length > 0
? listUpStation
: [[{ StationNumber: "null" }]]
}
height={(((width / 100) * 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,
}}
scrollAnimationDuration={600}
onSnapToItem={setListIndex}
renderItem={RenderItem}
overscrollEnabled={false}
defaultIndex={listIndex >= listUpStation.length ? 0 : listIndex}
/>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={{
flexDirection: "row",
justifyContent: "center",
alignContent: "center",
alignItems: "center",
paddingVertical: 2,
paddingHorizontal: 10,
minWidth: width,
}}
ref={(scrollViewRef) => {
// ScrollViewのrefを保存
if (scrollViewRef) {
carouselBadgeScrollViewRef.current = scrollViewRef;
}
}}
>
{originalStationList &&
listUpStation.map((d, index) => {
const active = index == listIndex;
const numberKey = d[0].StationNumber + index;
return dotButton ? (
<StationNumber
onPress={() => setListIndex(index)}
currentStation={d}
active={active}
key={numberKey}
/>
) : (
<SimpleDot
onPress={() => setListIndex(index)}
active={active}
key={numberKey}
/>
);
})}
</ScrollView>
</View>
);
};