お気に入り一覧のドラッグ並び替え機能を実装

This commit is contained in:
harukin-expo-dev-env 2025-06-10 16:19:43 +00:00
parent c43778c3c5
commit 6ad46c0e63
2 changed files with 69 additions and 78 deletions

View File

@ -2,14 +2,10 @@ import React, { useEffect, useState } from "react";
import Icon from "react-native-vector-icons/Entypo";
import { View, Text, TouchableOpacity, LayoutAnimation } from "react-native";
import lineColorList from "../../../assets/originData/lineColorList";
import Ionicons from "react-native-vector-icons/Ionicons";
import { AS } from "../../../storageControl";
export const FavoriteSettingsItem = ({
currentStation,
setFavoriteStation,
index,
array,
}) => {
export const FavoriteSettingsItem = ({ currentStation }) => {
const lineIDs = [];
const EachIDs = [];
console.log(currentStation);
@ -19,27 +15,6 @@ export const FavoriteSettingsItem = ({
lineIDs.push(textArray.filter((s) => "A" < s && s < "Z").join(""));
EachIDs.push(textArray.filter((s) => "0" <= s && s <= "9").join(""));
});
const [head, setHead] = useState(false);
const [tail, setTail] = useState(false);
useEffect(() => {
switch (true) {
case array.length == 1:
setHead(true);
setTail(true);
break;
case index == 0:
setHead(true);
setTail(false);
break;
case index == array.length - 1:
setHead(false);
setTail(true);
break;
default:
setHead(false);
setTail(false);
}
}, [array]);
return (
<View style={{ flexDirection: "row", backgroundColor: "white" }}>
@ -47,7 +22,7 @@ export const FavoriteSettingsItem = ({
style={{
width: 35,
position: "relative",
marginHorizontal: 15,
marginHorizontal: 10,
flexDirection: "row",
height: "101%",
}}
@ -91,43 +66,15 @@ export const FavoriteSettingsItem = ({
>
<Text style={{ fontSize: 20 }}>{currentStation[0].Station_JP}</Text>
<View style={{ flex: 1 }} />
<TouchableOpacity
style={{ marginHorizontal: 10, marginVertical: 4, width: 30 }}
onPress={() => {
console.log("up");
LayoutAnimation.configureNext(
LayoutAnimation.Presets.easeInEaseOut
);
const removedStation = [...array].filter((d, i) => {
if (i == index) return false;
return true;
});
removedStation.splice(index - 1, 0, currentStation);
setFavoriteStation(removedStation);
AS.setItem("favoriteStation", JSON.stringify(removedStation));
}}
>
{head ? null : <Icon name="chevron-up" size={26} />}
</TouchableOpacity>
<TouchableOpacity
style={{ marginHorizontal: 10, marginVertical: 4, width: 30 }}
onPress={() => {
console.log("down");
LayoutAnimation.configureNext(
LayoutAnimation.Presets.easeInEaseOut
);
const removedStation = [...array].filter((d, i) => {
if (i == index) return false;
return true;
});
removedStation.splice(index + 1, 0, currentStation);
setFavoriteStation(removedStation);
AS.setItem("favoriteStation", JSON.stringify(removedStation));
}}
>
{tail ? null : <Icon name="chevron-down" size={26} />}
</TouchableOpacity>
</View>
<View
style={{
alignContent: "center",
alignItems: "center",
alignSelf: "center",
}}
>
<Ionicons name={"reorder-two"} size={20} style={{ marginHorizontal: 10 }} />
</View>
</View>
);

View File

@ -1,30 +1,57 @@
import React from "react";
import { View, Text, TouchableOpacity, ScrollView } from "react-native";
import React, { useCallback } from "react";
import { View, Text, StyleSheet } from "react-native";
import Animated, { useAnimatedRef } from "react-native-reanimated";
import { useNavigation } from "@react-navigation/native";
import Sortable from "react-native-sortables";
import { useFavoriteStation } from "../../stateBox/useFavoriteStation";
import { FavoriteSettingsItem } from "./FavoliteSettings/FavoiliteSettingsItem";
import { SheetHeaderItem } from "@/components/atom/SheetHeaderItem";
export const FavoriteSettings = () => {
const { favoriteStation, setFavoriteStation } = useFavoriteStation();
const scrollableRef = useAnimatedRef();
const { goBack } = useNavigation();
const renderItem = useCallback((props) => {
const { item, index } = props;
return (
<FavoriteSettingsItem
currentStation={item}
key={item[0].StationNumber}
/>
);
}, []);
return (
<View style={{ height: "100%", backgroundColor: "#0099CC" }}>
<SheetHeaderItem
title="お気に入り設定"
LeftItem={{ title: " 設定", onPress: goBack }}
/>
<ScrollView style={{ flex: 1, backgroundColor: "white" }}>
{favoriteStation.map((currentStation, index, array) => (
<FavoriteSettingsItem
currentStation={currentStation}
setFavoriteStation={setFavoriteStation}
index={index}
array={array}
key={currentStation[0].StationNumber}
/>
))}
</ScrollView>
<Animated.ScrollView
style={{ flex: 1, backgroundColor: "white" }}
contentContainerStyle={styles.contentContainer}
ref={scrollableRef}
>
<Sortable.Grid
columnGap={0}
columns={1}
data={favoriteStation}
renderItem={renderItem}
rowGap={0}
scrollableRef={scrollableRef} // required for auto scroll
snapOffsetY={0}
onDragEnd={(newOrder) => {
const newFavoriteStation = newOrder.indexToKey.map((item,index,array)=>{
let returnData = [];
favoriteStation.forEach((station) => {
if (station[0].StationNumber === item) returnData = station;
});
return returnData;
});
setFavoriteStation(newFavoriteStation);
}}
keyExtractor={(item) => item[0].StationNumber}
/>
</Animated.ScrollView>
<Text
style={{
backgroundColor: "white",
@ -37,3 +64,20 @@ export const FavoriteSettings = () => {
</View>
);
};
const styles = StyleSheet.create({
card: {
alignItems: "center",
backgroundColor: "#36877F",
borderRadius: 10,
height: 100,
justifyContent: "center",
},
contentContainer: {
padding: 10,
},
text: {
color: "white",
fontWeight: "bold",
},
});