Files
fltr-app/app/(tabs)/index.tsx
2025-10-15 13:57:06 +02:00

200 lines
6.0 KiB
TypeScript

import styles from "@/app/tabStyles/indexStyles";
import ShowCard from "@/components/ui/ShowCard";
import { useShowContext } from "@/contexts/ShowContext";
import { useStreamingServiceContext } from "@/contexts/StreamingServiceContext";
import { router } from "expo-router";
import React from "react";
import {
ActivityIndicator,
Image,
Text,
TouchableOpacity,
View,
} from "react-native";
import {
GestureHandlerRootView,
ScrollView,
} from "react-native-gesture-handler";
export default function HomeScreen() {
const { shows, error, loading } = useShowContext();
const { streamingServices } = useStreamingServiceContext();
const [filteredShows, setFilteredShows] = React.useState(shows);
const [activeFilter, setActiveFilter] = React.useState<string>("all");
React.useEffect(() => {
setFilteredShows(shows);
}, [shows]);
const handleFilter = (type: string) => {
setActiveFilter(type);
if (type === "all") {
setFilteredShows(shows);
return;
}
if (type === "live") {
const filtered = shows.filter((show) => show.running);
setFilteredShows(filtered);
return;
}
const filtered = shows.filter((show) => show.streamingService === type);
setFilteredShows(filtered);
};
const uniqueStreamingServices = React.useMemo(() => {
const uniqueServices = new Set(shows.map((show) => show.streamingService));
return Array.from(uniqueServices);
}, [shows]);
if (loading) {
return (
<View
style={[
styles.mainContainer,
{ justifyContent: "center", alignItems: "center" },
]}
>
<ActivityIndicator size="large" color="#ffffff" />
</View>
);
}
if (error) {
return (
<View
style={[
styles.mainContainer,
{ justifyContent: "center", alignItems: "center" },
]}
>
<Text>Error: {error}</Text>
</View>
);
}
return (
<GestureHandlerRootView>
<View style={styles.mainContainer}>
<View style={styles.header}>
<Text style={styles.title}>FLTR</Text>
</View>
<ScrollView contentContainerStyle={{ paddingBottom: 30 }}>
<View style={styles.filterSection}>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={{
alignItems: "center",
paddingHorizontal: 10,
gap: 10,
marginLeft: 10,
}}
>
{activeFilter !== "all" && (
<TouchableOpacity
style={{
padding: 2,
height: 50,
width: 50,
alignItems: "center",
justifyContent: "center",
backgroundColor: "hsl(221, 39%, 80%)",
borderRadius: 50,
}}
onPress={() => handleFilter("all")}
>
<Text>ALLE</Text>
</TouchableOpacity>
)}
{activeFilter !== "live" && (
<TouchableOpacity
style={{
padding: 2,
height: 50,
width: 50,
alignItems: "center",
justifyContent: "center",
backgroundColor: "hsl(221, 39%, 80%)",
borderRadius: 50,
}}
onPress={() => handleFilter("live")}
>
<Text>LIVE</Text>
</TouchableOpacity>
)}
{uniqueStreamingServices.map((serviceName) => {
const streamingService =
streamingServices[
`assets.images.streamingServices.${serviceName.toLowerCase()}`
];
return (
<TouchableOpacity
key={serviceName}
style={{
padding: 2,
backgroundColor: "hsl(221, 39%, 80%)",
borderRadius: 50,
}}
onPress={() => handleFilter(serviceName)}
>
<Image
source={{ uri: streamingService }}
style={{
width: 50,
height: 50,
borderRadius: 30,
resizeMode: "contain",
}}
/>
</TouchableOpacity>
);
})}
</ScrollView>
</View>
{filteredShows.map((show) => {
const showLiveBadge = show.running;
const streamingService =
streamingServices[
`assets.images.streamingServices.${show.streamingService.toLowerCase()}`
];
return (
<ShowCard
key={show.id}
title={show.title}
onPress={() =>
router.push({
pathname: "/showDetails",
params: {
id: String(show.id),
title: show.title,
bannerUri: show.bannerUri,
description: show.description,
concept: show.concept,
genres: show.genres,
streamingService: show.streamingService,
logoUri: show.logoUri,
},
})
}
imageUri={show.bannerUri}
streamingServiceUri={streamingService}
genres={show.genres}
{...(showLiveBadge
? {
liveBadgeText: "LIVE",
liveBadgeContainerStyle: styles.liveBadgeContainer,
}
: {})}
/>
);
})}
</ScrollView>
</View>
</GestureHandlerRootView>
);
}