:api added explore auto-complete feature
This commit is contained in:
@@ -1,11 +1,118 @@
|
||||
import styles from "@/app/tabStyles/indexStyles";
|
||||
import React from "react";
|
||||
import { Text, View } from "react-native";
|
||||
import {
|
||||
Text,
|
||||
View,
|
||||
TextInput,
|
||||
FlatList,
|
||||
TouchableOpacity,
|
||||
Keyboard,
|
||||
TouchableWithoutFeedback,
|
||||
} from "react-native";
|
||||
import Feather from "@expo/vector-icons/Feather";
|
||||
import { useDiscoveryContext } from "@/contexts/DiscoveryContext";
|
||||
import { useShowContext } from "@/contexts/ShowContext";
|
||||
|
||||
export default function TabTwoScreen() {
|
||||
const { query, setQuery, suggestions, loading, error, clear } =
|
||||
useDiscoveryContext();
|
||||
|
||||
const { shows } = useShowContext();
|
||||
|
||||
const personSuggestions = React.useMemo(
|
||||
() => suggestions.filter((s) => s.type === "PERSON"),
|
||||
[suggestions]
|
||||
);
|
||||
|
||||
const showSuggestions = React.useMemo(
|
||||
() => suggestions.filter((s) => s.type === "SHOW"),
|
||||
[suggestions]
|
||||
);
|
||||
|
||||
const [tag, setTag] = React.useState<string | null>(null);
|
||||
return (
|
||||
<View style={styles.mainContainer}>
|
||||
<Text>Explore Screen</Text>
|
||||
</View>
|
||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||||
<View style={styles.mainContainer}>
|
||||
<View style={styles.header}>
|
||||
<Text style={[styles.title, { fontSize: 28 }]}>Durchsuchen</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.searchContainer}>
|
||||
<TextInput
|
||||
value={query}
|
||||
onChangeText={setQuery}
|
||||
placeholder="Wonach suchst du?"
|
||||
placeholderTextColor=""
|
||||
style={{
|
||||
fontSize: 18,
|
||||
fontWeight: "500",
|
||||
color: "hsl(221, 39%, 80%)",
|
||||
}}
|
||||
returnKeyType="search"
|
||||
onSubmitEditing={() => {
|
||||
console.log("Search:", query);
|
||||
}}
|
||||
autoCapitalize="none"
|
||||
/>
|
||||
|
||||
{query.length === 0 ? (
|
||||
<Feather name="search" size={24} color="hsl(221, 39%, 80%)" />
|
||||
) : (
|
||||
<Feather
|
||||
name="x"
|
||||
size={24}
|
||||
color="hsl(221, 39%, 80%)"
|
||||
onPress={() => setQuery("")}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
|
||||
{tag && (
|
||||
<View style={styles.tagContainer}>
|
||||
<Text style={styles.tagLabel}>{tag}</Text>
|
||||
<Feather
|
||||
name="x"
|
||||
size={18}
|
||||
color="hsl(221, 39%, 80%)"
|
||||
onPress={() => setTag(null)}
|
||||
style={{ marginLeft: "auto", marginRight: 10 }}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{query.length > 0 && (
|
||||
<>
|
||||
<View style={styles.suggestionsSection}>
|
||||
<Text style={styles.suggestionTitle}>Suchvorschläge</Text>
|
||||
|
||||
{showSuggestions.map((suggestion, idx) => (
|
||||
<TouchableOpacity
|
||||
key={suggestion.text + "_" + idx}
|
||||
style={styles.suggestionContainer}
|
||||
onPress={() => {
|
||||
setTag(suggestion.text);
|
||||
}}
|
||||
>
|
||||
<View style={styles.imageContainer}></View>
|
||||
<Text style={styles.suggestionLabel}>{suggestion.text}</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
{personSuggestions.map((suggestion, idx) => (
|
||||
<TouchableOpacity
|
||||
key={suggestion.text + "_" + idx}
|
||||
style={styles.suggestionContainer}
|
||||
onPress={() => {
|
||||
setTag(suggestion.text);
|
||||
}}
|
||||
>
|
||||
<View style={styles.imageContainer}></View>
|
||||
<Text style={styles.suggestionLabel}>{suggestion.text}</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ export default function HomeScreen() {
|
||||
alignItems: "center",
|
||||
paddingHorizontal: 10,
|
||||
gap: 10,
|
||||
marginLeft: 10,
|
||||
}}
|
||||
>
|
||||
{uniqueStreamingServices.map((serviceName) => {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { ShowProvider } from "@/contexts/ShowContext";
|
||||
import { SeasonProvider } from "@/contexts/SeasonContext";
|
||||
import { StreamingServiceProvider } from "@/contexts/StreamingServiceContext";
|
||||
import { PersonProvider } from "@/contexts/PersonContext";
|
||||
import { DiscoveryProvider } from "@/contexts/DiscoveryContext";
|
||||
import { Stack } from "expo-router";
|
||||
import "react-native-reanimated";
|
||||
|
||||
@@ -11,22 +12,24 @@ export default function RootLayout() {
|
||||
<SeasonProvider>
|
||||
<StreamingServiceProvider>
|
||||
<PersonProvider>
|
||||
<Stack>
|
||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||
<Stack.Screen
|
||||
name="showDetails"
|
||||
options={{
|
||||
headerShown: false,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="participant"
|
||||
options={{
|
||||
presentation: "fullScreenModal",
|
||||
headerShown: false,
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
<DiscoveryProvider>
|
||||
<Stack>
|
||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||
<Stack.Screen
|
||||
name="showDetails"
|
||||
options={{
|
||||
headerShown: false,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="participant"
|
||||
options={{
|
||||
presentation: "fullScreenModal",
|
||||
headerShown: false,
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
</DiscoveryProvider>
|
||||
</PersonProvider>
|
||||
</StreamingServiceProvider>
|
||||
</SeasonProvider>
|
||||
|
||||
@@ -40,7 +40,105 @@ export default StyleSheet.create({
|
||||
filterSection: {
|
||||
width: "100%",
|
||||
height: 70,
|
||||
backgroundColor: "hsl(221, 39%, 5%)",
|
||||
marginTop: 20,
|
||||
},
|
||||
searchContainer: {
|
||||
width: "90%",
|
||||
height: 60,
|
||||
marginHorizontal: "auto",
|
||||
backgroundColor: "hsl(221, 39%, 8%)",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
borderRadius: 20,
|
||||
paddingHorizontal: 20,
|
||||
|
||||
marginTop: 15,
|
||||
borderWidth: 1.5,
|
||||
borderColor: "hsl(221, 39%, 15%)",
|
||||
shadowColor: "#000",
|
||||
shadowOffset: {
|
||||
width: 0,
|
||||
height: 2,
|
||||
},
|
||||
shadowOpacity: 0.25,
|
||||
shadowRadius: 3.84,
|
||||
elevation: 5,
|
||||
},
|
||||
searchLabel: {
|
||||
color: "hsl(221, 39%, 80%)",
|
||||
fontSize: 18,
|
||||
fontWeight: "500",
|
||||
},
|
||||
suggestionsSection: {
|
||||
width: "90%",
|
||||
height: "auto",
|
||||
paddingBottom: 15,
|
||||
borderRadius: 20,
|
||||
backgroundColor: "hsl(221, 39%, 8%)",
|
||||
borderWidth: 1.5,
|
||||
borderColor: "hsl(221, 39%, 15%)",
|
||||
marginHorizontal: "auto",
|
||||
alignSelf: "center",
|
||||
marginTop: 15,
|
||||
shadowColor: "#000",
|
||||
shadowOffset: {
|
||||
width: 0,
|
||||
height: 2,
|
||||
},
|
||||
shadowOpacity: 0.25,
|
||||
shadowRadius: 3.84,
|
||||
elevation: 5,
|
||||
},
|
||||
suggestionTitle: {
|
||||
color: "hsl(0, 0%, 60%)",
|
||||
fontSize: 14,
|
||||
marginLeft: 15,
|
||||
marginTop: 15,
|
||||
fontWeight: "500",
|
||||
},
|
||||
suggestionContainer: {
|
||||
marginTop: 15,
|
||||
width: "100%",
|
||||
height: 30,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
paddingHorizontal: 10,
|
||||
},
|
||||
imageContainer: {
|
||||
width: 20,
|
||||
height: 20,
|
||||
borderRadius: 10,
|
||||
borderWidth: 1.5,
|
||||
borderColor: "hsl(0, 0%, 90%)",
|
||||
},
|
||||
suggestionLabel: {
|
||||
color: "white",
|
||||
fontSize: 12,
|
||||
fontWeight: "500",
|
||||
marginLeft: 10,
|
||||
},
|
||||
tagContainer: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
backgroundColor: "hsl(221, 39%, 8%)",
|
||||
borderWidth: 1.5,
|
||||
borderColor: "hsl(221, 39%, 15%)",
|
||||
height: "auto",
|
||||
width: "auto",
|
||||
paddingVertical: 10,
|
||||
borderRadius: 50,
|
||||
marginTop: 15,
|
||||
marginLeft: 20,
|
||||
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
tagLabel: {
|
||||
color: "hsl(0, 0%, 90%)",
|
||||
fontSize: 14,
|
||||
fontWeight: "500",
|
||||
marginLeft: 15,
|
||||
textAlign: "center",
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user