お気に入り駅のドット表示機能を追加
This commit is contained in:
166
components/Menu/StationPagination.tsx
Normal file
166
components/Menu/StationPagination.tsx
Normal file
@@ -0,0 +1,166 @@
|
||||
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";
|
||||
|
||||
type StationProps = {
|
||||
DispNum: string;
|
||||
JrHpUrl: string;
|
||||
MyStation: string;
|
||||
StationMap: string;
|
||||
StationNumber: string | null;
|
||||
StationTimeTable: string;
|
||||
Station_EN: string;
|
||||
Station_JP: string;
|
||||
jslodApi: string;
|
||||
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)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
type StationNumberProps = {
|
||||
currentStation: StationProps[];
|
||||
active: boolean;
|
||||
onPress: () => void;
|
||||
};
|
||||
export const StationNumber: FC<StationNumberProps> = (props) => {
|
||||
const { currentStation, active, onPress } = props;
|
||||
const [animation, setAnimation] = useState(0);
|
||||
const data = currentStation.filter((d) => (d.StationNumber ? true : false));
|
||||
useInterval(() => {
|
||||
if (!data) return;
|
||||
setAnimation(animation + 1 < data.length ? animation + 1 : 0);
|
||||
}, 2000);
|
||||
|
||||
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 (
|
||||
<>
|
||||
{active && (
|
||||
<View style={{ position: "relative", width: 0, height: 0 }}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
position: "absolute",
|
||||
width: 28,
|
||||
height: 28,
|
||||
marginLeft: 1,
|
||||
marginRight: 1,
|
||||
borderRadius: 22,
|
||||
borderColor: "black",
|
||||
borderWidth: 2,
|
||||
left: 0,
|
||||
top: -14,
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
<TouchableOpacity
|
||||
onPress={onPress}
|
||||
style={{
|
||||
alignContent: "center",
|
||||
alignItems: "center",
|
||||
width: size,
|
||||
height: size,
|
||||
marginLeft: margin,
|
||||
marginRight: margin,
|
||||
borderColor: lineColorList[lineID],
|
||||
backgroundColor: "white",
|
||||
borderWidth: border,
|
||||
borderRadius: 22,
|
||||
}}
|
||||
key={currentStation[0].StationNumber + lineID}
|
||||
>
|
||||
<View style={{ flex: 1 }} />
|
||||
<Text
|
||||
style={{
|
||||
fontSize: active ? 8 : 6,
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
textAlign: "center",
|
||||
color: "black",
|
||||
fontWeight: active ? "bold" : "normal",
|
||||
textAlignVertical: "center",
|
||||
}}
|
||||
>
|
||||
{lineID + "\n" + lineName}
|
||||
</Text>
|
||||
<View style={{ flex: 1 }} />
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
);
|
||||
};
|
Reference in New Issue
Block a user