検索ボックス候補機能を暫定作成

This commit is contained in:
harukin-expo-dev-env
2025-09-23 14:45:51 +00:00
parent 8ddf3a3e8d
commit d36195df69
3 changed files with 325 additions and 128 deletions

View File

@@ -135,11 +135,11 @@ export const StationDeteilView = (props) => {
onExit={onExit}
/>
)}
{updatePermission &&<StationDiagramButton
navigate={navigate}
onExit={onExit}
currentStation={currentStation}
/>}
<StationDiagramButton
navigate={navigate}
onExit={onExit}
currentStation={currentStation}
/>
{!currentStation[0].StationTimeTable || (
<StationTimeTableButton
info={info}

View File

@@ -0,0 +1,164 @@
import lineColorList from "@/assets/originData/lineColorList";
import { useStationList } from "@/stateBox/useStationList";
import { FC, useEffect, useState } from "react";
import {
View,
Text,
ScrollView,
TouchableOpacity,
LayoutAnimation,
} from "react-native";
type hoge = {
trainNumber: string;
array: string;
name: string;
timeType: string;
time: string;
}[];
export const SearchInputSuggestBox: FC<{
input: string;
setInput: (f: string) => void;
currentStationDiagram: hoge;
}> = ({ input, setInput, currentStationDiagram }) => {
const { getStationDataFromName } = useStationList();
const [stationList, setStationList] = useState<
{
stationName: string;
number: string[];
}[]
>([]);
const [listFiltered, setListFiltered] = useState<string>("");
const [filteredStationLine, setFilteredStationLine] = useState<string[]>([]);
useEffect(() => {
const x: { stationName: string; number: string[] }[] = [];
currentStationDiagram.forEach((d) => {
d.array.split("#").forEach((s) => {
if (s == "") return;
const [stationName, type, time] = s.split(",");
if (!x.find((item) => item.stationName === stationName)) {
if (!type?.includes("通")) {
const stationData = getStationDataFromName(stationName);
if (listFiltered === "その他") {
if (stationData.length === 0) {
x.push({
stationName,
number: stationData.map((item) => item.StationNumber),
});
return;
}
}
const filter = stationData.filter((s) => {
if (listFiltered === "") return true;
if (listFiltered === "その他") {
return !(
s.StationNumber ? s.StationNumber.slice(0, 1) : ""
).match(/[A-Z]/);
}
return (
s.StationNumber ? s.StationNumber.slice(0, 1) : ""
).includes(listFiltered);
});
if (filter.length === 0) return;
x.push({
stationName,
number: stationData.map((item) => item.StationNumber),
});
}
}
});
});
setStationList(x);
}, [currentStationDiagram, listFiltered]);
useEffect(() => {
const filtered = stationList
.map((s) => s.number?.map((r) => (r ? r.slice(0, 1) : "")))
.flat();
const arrayB = Array.from(new Set(filtered));
setFilteredStationLine(arrayB.map((r) => (r !== "" ? r : "その他")));
}, [stationList]);
return (
<View
style={{
maxHeight: 200,
width: "100%",
backgroundColor: "#0099CC",
zIndex: 100,
}}
>
<Text>{input}</Text>
<ScrollView keyboardShouldPersistTaps="handled">
<View style={{ flexDirection: "row", flexWrap: "wrap" }}>
{stationList.map(({ stationName, number }) => (
<TouchableOpacity
style={{
margin: 5,
padding: 5,
backgroundColor: "#eee",
borderRadius: 20,
}}
key={stationName + number.join(",")}
onPress={() => setInput(stationName)}
>
<Text>{stationName}</Text>
</TouchableOpacity>
))}
</View>
</ScrollView>
<View
style={{
flexDirection: "row",
flexWrap: "wrap",
borderTopColor: "#ccc",
borderTopWidth: 0.5,
paddingTop: 0,
marginTop: 10,
}}
>
<TouchableOpacity
style={{
margin: 5,
padding: 5,
backgroundColor: "#eee",
borderRadius: 5,
}}
key={"empty"}
onPress={() => {
LayoutAnimation.configureNext({
duration: 400,
update: { type: "easeInEaseOut", springDamping: 0.6 },
});
setListFiltered("");
}}
>
<Text></Text>
</TouchableOpacity>
{filteredStationLine.map((line) => (
<TouchableOpacity
style={{
margin: 5,
padding: 5,
backgroundColor: lineColorList[line]
? `${lineColorList[line]}`
: "#eee",
borderRadius: 5,
}}
key={line}
onPress={() => {
LayoutAnimation.configureNext({
duration: 400,
update: { type: "easeInEaseOut", springDamping: 0.6 },
});
setListFiltered(line);
}}
>
<Text style={{ color: lineColorList[line] ? `white` : "black" }}>
{line}
</Text>
</TouchableOpacity>
))}
</View>
</View>
);
};

View File

@@ -20,6 +20,7 @@ import { Switch } from "react-native-elements";
import { customTrainDataDetector } from "../custom-train-data";
import { getTrainType } from "@/lib/getTrainType";
import { trainTypeID } from "@/lib/CommonTypes";
import { SearchInputSuggestBox } from "./SearchBox/SearchInputSuggestBox";
type props = {
route: {
@@ -129,8 +130,10 @@ export const StationDiagramView: FC<props> = ({ route }) => {
// //条件によってフィルタリング
if (!threw && timeType && timeType.includes("通")) return;
if (!showLastStop && timeType && timeType.includes("着")) return;
if(selectedTypeList.findIndex((item) => item === "SPCL") === -1){
if(d.match(/9\d\d\d[D,M,S]/)) return;
if (
selectedTypeList.findIndex((item) => item === "SPCL") === -1
) {
if (d.match(/9\d\d\d[D,M,S]/)) return;
}
if (
selectedTypeList.length > 0 &&
@@ -174,9 +177,17 @@ export const StationDiagramView: FC<props> = ({ route }) => {
useEffect(() => {
const showSubscription = Keyboard.addListener("keyboardDidShow", () => {
LayoutAnimation.configureNext({
duration: 600,
update: { type: "spring", springDamping: 0.6 },
});
setKeyBoardVisible(true);
});
const hideSubscription = Keyboard.addListener("keyboardDidHide", () => {
LayoutAnimation.configureNext({
duration: 600,
update: { type: "spring", springDamping: 0.6 },
});
setKeyBoardVisible(false);
});
@@ -217,100 +228,142 @@ export const StationDiagramView: FC<props> = ({ route }) => {
keyboardVerticalOffset={80}
enabled={Platform.OS === "ios"}
>
<ScrollView horizontal style={{ height: 35, flexDirection: "row" }}>
<TouchableOpacity
{!keyBoardVisible ? (
<ScrollView
horizontal
style={{
alignItems: "center",
marginHorizontal: 5,
backgroundColor: threw ? "white" : "#ffffff00",
alignSelf: "center",
borderColor: "white",
borderWidth: 1,
borderRadius: 100,
}}
onPress={() => {
setIsThrew(!threw);
height: 35,
flexDirection: "row",
display: "flex",
}}
>
<Text
<TouchableOpacity
style={{
color: threw ? "#0099CC" : "white",
fontSize: 14,
margin: 5,
alignItems: "center",
marginHorizontal: 5,
backgroundColor: threw ? "white" : "#ffffff00",
alignSelf: "center",
borderColor: "white",
borderWidth: 1,
borderRadius: 100,
}}
onPress={() => {
setIsThrew(!threw);
}}
>
</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
alignItems: "center",
marginHorizontal: 5,
backgroundColor: showLastStop ? "white" : "#ffffff00",
alignSelf: "center",
borderColor: "white",
borderWidth: 1,
borderRadius: 100,
}}
onPress={() => {
setShowLastStop(!showLastStop);
}}
>
<Text
<Text
style={{
color: threw ? "#0099CC" : "white",
fontSize: 14,
margin: 5,
}}
>
</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
color: showLastStop ? "#0099CC" : "white",
fontSize: 14,
margin: 5,
alignItems: "center",
marginHorizontal: 5,
backgroundColor: showLastStop ? "white" : "#ffffff00",
alignSelf: "center",
borderColor: "white",
borderWidth: 1,
borderRadius: 100,
}}
onPress={() => {
setShowLastStop(!showLastStop);
}}
>
</Text>
</TouchableOpacity>
<View
style={{
height: "auto",
borderLeftWidth: 1,
margin: 5,
borderColor: "white",
}}
/>
{showTypeFiltering ? (
<>
<TypeSelectorBox
selectedTypeList={selectedTypeList}
setSelectedTypeList={setSelectedTypeList}
typeID="Normal"
relativeID={["OneMan"]}
/>
<TypeSelectorBox
selectedTypeList={selectedTypeList}
setSelectedTypeList={setSelectedTypeList}
typeID="Rapid"
relativeID={["OneManRapid"]}
/>
<TypeSelectorBox
selectedTypeList={selectedTypeList}
setSelectedTypeList={setSelectedTypeList}
typeID="LTDEXP"
relativeID={["NightLTDEXP"]}
/>
<TypeSelectorBox
selectedTypeList={selectedTypeList}
setSelectedTypeList={setSelectedTypeList}
typeID="SPCL"
relativeID={["SPCL_Normal", "SPCL_Rapid", "SPCL_EXP", "Party"]}
/>
<TypeSelectorBox
selectedTypeList={selectedTypeList}
setSelectedTypeList={setSelectedTypeList}
typeID="Freight"
/>
<TypeSelectorBox
selectedTypeList={selectedTypeList}
setSelectedTypeList={setSelectedTypeList}
typeID="Forwarding"
relativeID={["FreightForwarding"]}
/>
<Text
style={{
color: showLastStop ? "#0099CC" : "white",
fontSize: 14,
margin: 5,
}}
>
</Text>
</TouchableOpacity>
<View
style={{
height: "auto",
borderLeftWidth: 1,
margin: 5,
borderColor: "white",
}}
/>
{showTypeFiltering ? (
<>
<TypeSelectorBox
selectedTypeList={selectedTypeList}
setSelectedTypeList={setSelectedTypeList}
typeID="Normal"
relativeID={["OneMan"]}
/>
<TypeSelectorBox
selectedTypeList={selectedTypeList}
setSelectedTypeList={setSelectedTypeList}
typeID="Rapid"
relativeID={["OneManRapid"]}
/>
<TypeSelectorBox
selectedTypeList={selectedTypeList}
setSelectedTypeList={setSelectedTypeList}
typeID="LTDEXP"
relativeID={["NightLTDEXP"]}
/>
<TypeSelectorBox
selectedTypeList={selectedTypeList}
setSelectedTypeList={setSelectedTypeList}
typeID="SPCL"
relativeID={[
"SPCL_Normal",
"SPCL_Rapid",
"SPCL_EXP",
"Party",
]}
/>
<TypeSelectorBox
selectedTypeList={selectedTypeList}
setSelectedTypeList={setSelectedTypeList}
typeID="Freight"
/>
<TypeSelectorBox
selectedTypeList={selectedTypeList}
setSelectedTypeList={setSelectedTypeList}
typeID="Forwarding"
relativeID={["FreightForwarding"]}
/>
<TouchableOpacity
style={{
alignItems: "center",
marginHorizontal: 5,
backgroundColor: "#ffffff00",
alignSelf: "center",
borderColor: "white",
borderWidth: 1,
borderRadius: 100,
}}
onPress={() => {
LayoutAnimation.configureNext(
LayoutAnimation.Presets.easeInEaseOut
);
setShowTypeFiltering(false);
}}
>
<Text
style={{
color: "white",
fontSize: 14,
margin: 5,
}}
>
</Text>
</TouchableOpacity>
</>
) : (
<TouchableOpacity
style={{
alignItems: "center",
@@ -325,7 +378,7 @@ export const StationDiagramView: FC<props> = ({ route }) => {
LayoutAnimation.configureNext(
LayoutAnimation.Presets.easeInEaseOut
);
setShowTypeFiltering(false);
setShowTypeFiltering(true);
}}
>
<Text
@@ -335,11 +388,11 @@ export const StationDiagramView: FC<props> = ({ route }) => {
margin: 5,
}}
>
</Text>
</TouchableOpacity>
</>
) : (
)}
<TouchableOpacity
style={{
alignItems: "center",
@@ -351,10 +404,7 @@ export const StationDiagramView: FC<props> = ({ route }) => {
borderRadius: 100,
}}
onPress={() => {
LayoutAnimation.configureNext(
LayoutAnimation.Presets.easeInEaseOut
);
setShowTypeFiltering(true);
setDisplayMode(displayMode === "list" ? "grid" : "list");
}}
>
<Text
@@ -364,36 +414,19 @@ export const StationDiagramView: FC<props> = ({ route }) => {
margin: 5,
}}
>
{displayMode === "list" ? "横並びモード" : "リストモード"}
</Text>
</TouchableOpacity>
)}
<TouchableOpacity
style={{
alignItems: "center",
marginHorizontal: 5,
backgroundColor: "#ffffff00",
alignSelf: "center",
borderColor: "white",
borderWidth: 1,
borderRadius: 100,
}}
onPress={() => {
setDisplayMode(displayMode === "list" ? "grid" : "list");
}}
>
<Text
style={{
color: "white",
fontSize: 14,
margin: 5,
}}
>
{displayMode === "list" ? "横並びモード" : "リストモード"}
</Text>
</TouchableOpacity>
</ScrollView>
</ScrollView>
) : (
<View style={{ position: "relative", display: "flex" }}>
<SearchInputSuggestBox
input={input}
setInput={setInput}
currentStationDiagram={currentStationDiagram}
/>
</View>
)}
<View
style={{
height: 35,