From 21cd6c32410d7341d0d6767dd2de19609bf099cf Mon Sep 17 00:00:00 2001 From: DevOFVictory <49123418+mafeth@users.noreply.github.com> Date: Tue, 28 Oct 2025 22:42:19 +0100 Subject: [PATCH] filter, haptik, background --- app/(tabs)/index.tsx | 133 ++++++++++++++++---------- app/participant.tsx | 5 +- app/showDetails.tsx | 47 ++++++--- app/stackStyles/participantStyles.tsx | 4 +- components/ParticipantDeatails.tsx | 6 +- components/ui/ShowCard.tsx | 28 +++--- components/ui/StackHeader.tsx | 4 +- package.json | 2 + 8 files changed, 145 insertions(+), 84 deletions(-) diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 930c750..615fe23 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -2,6 +2,7 @@ import styles from "@/app/tabStyles/indexStyles"; import ShowCard from "@/components/ui/ShowCard"; import { useShowContext } from "@/contexts/ShowContext"; import { useStreamingServiceContext } from "@/contexts/StreamingServiceContext"; +import * as Haptics from 'expo-haptics'; import { router } from "expo-router"; import React from "react"; import { @@ -22,12 +23,19 @@ export default function HomeScreen() { const [filteredShows, setFilteredShows] = React.useState(shows); const [activeFilter, setActiveFilter] = React.useState("all"); + const haptikFeedback = () => { + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); + } + React.useEffect(() => { setFilteredShows(shows); }, [shows]); const handleFilter = (type: string) => { + haptikFeedback(); setActiveFilter(type); + + if (type === "all") { setFilteredShows(shows); return; @@ -39,12 +47,26 @@ export default function HomeScreen() { return; } - const filtered = shows.filter((show) => show.streamingService === type); + if (type === activeFilter) { + setFilteredShows(shows); + setActiveFilter('all'); + return; + } + + + + const filtered = shows.filter((show) => + show.streamingService.split(',').map(s => s.trim()).includes(type) + ); setFilteredShows(filtered); }; const uniqueStreamingServices = React.useMemo(() => { - const uniqueServices = new Set(shows.map((show) => show.streamingService)); + const uniqueServices = new Set(); + shows.forEach((show) => { + const services = show.streamingService.split(', ').map(s => s.trim()); + services.forEach(service => uniqueServices.add(service)); + }); return Array.from(uniqueServices); }, [shows]); @@ -95,48 +117,61 @@ export default function HomeScreen() { {activeFilter !== "all" && ( handleFilter("all")} > - ALLE + ALLE )} {activeFilter !== "live" && ( handleFilter("live")} > - LIVE + + LIVE + )} + + {uniqueStreamingServices.map((serviceName) => { const streamingService = streamingServices[ - `assets.images.streamingServices.${serviceName.toLowerCase()}` + `assets.images.streamingServices.${serviceName.toLowerCase()}` ]; return ( handleFilter(serviceName)} > @@ -154,45 +189,43 @@ export default function HomeScreen() { })} - {filteredShows.map((show) => { - const showLiveBadge = show.running; - const streamingService = - streamingServices[ - `assets.images.streamingServices.${show.streamingService.toLowerCase()}` - ]; + + {filteredShows.map((show) => { + const showLiveBadge = show.running; - return ( - - 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.logoUrl, - running: String(show.running), - }, - }) - } - imageUri={show.bannerUri} - streamingServiceUri={streamingService} - genres={show.genres} - {...(showLiveBadge - ? { + return ( + + 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.logoUrl, + running: String(show.running), + }, + }) + } + imageUri={show.bannerUri} + streamingServicesUris={show.streamingService.split(', ').map(s => streamingServices[`assets.images.streamingServices.${s.toLowerCase()}`])} + genres={show.genres} + {...(showLiveBadge + ? { liveBadgeText: "LIVE", liveBadgeContainerStyle: styles.liveBadgeContainer, } - : {})} - /> - ); - })} + : {})} + /> + ); + })} + diff --git a/app/participant.tsx b/app/participant.tsx index b799d0d..004bad2 100644 --- a/app/participant.tsx +++ b/app/participant.tsx @@ -179,7 +179,8 @@ export default function ParticipantScreen() { {name} - {appearances.map(({ show, seasons }) => { + {appearances.toReversed().map(({ show, seasons }) => { const partners = Array.from( new Map( seasons diff --git a/app/showDetails.tsx b/app/showDetails.tsx index ded2a5c..9fb7bda 100644 --- a/app/showDetails.tsx +++ b/app/showDetails.tsx @@ -1,9 +1,11 @@ +import { getShowById, Show } from "@/apis/showApi"; import ParticipantDetails from "@/components/ParticipantDeatails"; import ShowInfo from "@/components/ui/ShowInfo"; import StackHeader from "@/components/ui/StackHeader"; import { useSeasonContext } from "@/contexts/SeasonContext"; +import * as Haptics from 'expo-haptics'; import { router, useLocalSearchParams } from "expo-router"; -import React from "react"; +import React, { useState } from "react"; import { Dimensions, Image, @@ -16,14 +18,18 @@ import styles from "./stackStyles/showDetailStyles"; export default function ShowDetails() { const { - bannerUri, - description, - concept, - genres, - streamingService, + // bannerUri, + // description, + // concept, + // genres, + // streamingService, id, - endDate, + // endDate, } = useLocalSearchParams(); + + const [show, setShow] = useState(null); + const [loading, setLoading] = useState(true); + const [selectedParticipants, setSelectedParticipants] = React.useState(true); const [selectedSeason, setSelectedSeason] = React.useState(1); @@ -48,6 +54,18 @@ export default function ShowDetails() { React.useEffect(() => { if (!showId) return; + + const fetchShow = async () => { + try { + const data = await getShowById(showId); + setShow(data); + } finally { + setLoading(false); + } + }; + + fetchShow(); + let active = true; (async () => { const count = await fetchSeasonCount(showId); @@ -128,15 +146,15 @@ export default function ShowDetails() { { setSelectedSeason(season); + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); }} > {season} @@ -241,10 +260,10 @@ export default function ShowDetails() { ) : ( )} diff --git a/app/stackStyles/participantStyles.tsx b/app/stackStyles/participantStyles.tsx index 578301a..a4ade8d 100644 --- a/app/stackStyles/participantStyles.tsx +++ b/app/stackStyles/participantStyles.tsx @@ -50,7 +50,7 @@ const styles = StyleSheet.create({ performedShowsSection: { width: "100%", height: "100%", - backgroundColor: "hsl(221, 39%, 0%)", + backgroundColor: 'hsl(221, 39%, 16%)', marginTop: 20, }, performedShowsTitle: { @@ -175,7 +175,7 @@ const styles = StyleSheet.create({ width: 50, height: 50, borderRadius: 20, - backgroundColor: "hsl(221, 39%, 18%)", + backgroundColor: "hsl(221, 39%, 12%)", marginLeft: 15, marginTop: 15, marginBottom: 5, diff --git a/components/ParticipantDeatails.tsx b/components/ParticipantDeatails.tsx index fde5314..2b4c8f7 100644 --- a/components/ParticipantDeatails.tsx +++ b/components/ParticipantDeatails.tsx @@ -1,9 +1,9 @@ -import { View, Text, StyleSheet } from "react-native"; +import { StyleSheet, Text, View } from "react-native"; type ParticipantDetailsProps = { description: string; concept: string; - genres: string; + genres: string[]; streamingService: string; }; @@ -20,7 +20,7 @@ const ParticipantDetails = ({ Konzept: {concept} Genres: - {genres} + {genres.join(', ')} Produktion: {streamingService} diff --git a/components/ui/ShowCard.tsx b/components/ui/ShowCard.tsx index ae49032..3147720 100644 --- a/components/ui/ShowCard.tsx +++ b/components/ui/ShowCard.tsx @@ -3,7 +3,7 @@ import { Image, StyleSheet, Text, TouchableOpacity, View } from "react-native"; type ShowCardProps = { imageUri: string; - streamingServiceUri: string; + streamingServicesUris: string[]; liveBadgeText?: string; liveBadgeContainerStyle?: object; genres: string[]; @@ -13,7 +13,7 @@ type ShowCardProps = { const ShowCard = ({ imageUri, - streamingServiceUri, + streamingServicesUris, liveBadgeText, liveBadgeContainerStyle, genres, @@ -32,14 +32,20 @@ const ShowCard = ({ }} style={[StyleSheet.absoluteFillObject, { borderRadius: 35 }]} /> - - + + + {streamingServicesUris.length > 0 && streamingServicesUris.map((service) => ( + + + ))} + {liveBadgeText && ( {liveBadgeText} @@ -70,8 +76,8 @@ const ShowCard = ({ const styles = StyleSheet.create({ showContainer: { - width: "90%", - height: 200, + width: "100%", + height: 220, backgroundColor: "transparent", alignSelf: "center", borderRadius: 35, diff --git a/components/ui/StackHeader.tsx b/components/ui/StackHeader.tsx index aeecce7..224db45 100644 --- a/components/ui/StackHeader.tsx +++ b/components/ui/StackHeader.tsx @@ -20,9 +20,9 @@ export default function StackHeader() { - + {/* - + */} ); } diff --git a/package.json b/package.json index b66288d..51b33be 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,8 @@ "name": "fltr-app", "main": "expo-router/entry", "version": "1.0.0", + "displayName": "FLTR", + "description": "Reality TV", "scripts": { "start": "expo start", "reset-project": "node ./scripts/reset-project.js",