This commit is contained in:
Cron1cle
2025-10-09 17:20:40 +02:00
parent c116352310
commit aedd87416f
10 changed files with 141 additions and 50 deletions

View File

@@ -99,7 +99,7 @@ export default function HomeScreen() {
<TouchableOpacity
key={serviceName}
style={{
padding: 3,
padding: 2,
backgroundColor: "hsl(221, 39%, 80%)",
borderRadius: 50,
}}

View File

@@ -4,12 +4,12 @@ import Ionicons from "@expo/vector-icons/Ionicons";
import React, { useEffect, useMemo, useState } from "react";
import { router, useLocalSearchParams } from "expo-router";
import { usePersonContext } from "@/contexts/PersonContext";
import * as WebBrowser from "expo-web-browser";
import {
ScrollView,
GestureHandlerRootView,
} from "react-native-gesture-handler";
import { useShowContext } from "@/contexts/ShowContext";
import { getPersonHistory } from "@/apis/personApi";
export default function ParticipantScreen() {
const { getPersonAppearances, isLoading, getError } = usePersonContext();
@@ -34,8 +34,9 @@ export default function ParticipantScreen() {
const grouped = data.showIds.map((id) => ({
showId: id,
seasons: data.byShow[id],
partners: data.partnersByShow[id] || [],
}));
setAppearances(grouped);
setAppearances(grouped as any);
})();
return () => {
active = false;
@@ -44,14 +45,30 @@ export default function ParticipantScreen() {
const resolved = useMemo(
() =>
appearances
(appearances as any[])
.map((a) => {
const show = shows.find((s) => s.id === a.showId);
if (!show) return null;
return { show, seasons: a.seasons };
return {
show,
seasons: a.seasons as number[],
partners: a.partners as {
seasonNumber: number;
partner?: { id: number; name: string; imageUrl?: string | null };
}[],
};
})
.filter(
(v): v is { show: (typeof shows)[number]; seasons: number[] } => !!v
(
v
): v is {
show: (typeof shows)[number];
seasons: number[];
partners: {
seasonNumber: number;
partner?: { id: number; name: string; imageUrl?: string | null };
}[];
} => !!v
),
[appearances, shows]
);
@@ -75,12 +92,6 @@ export default function ParticipantScreen() {
<View style={styles.dot} />
<Text style={styles.participantInfo}>Köln</Text>
</View>
<Image
source={{
uri: "https://www.fernseh-puls.com/wp-content/uploads/are-you-the-one-calvin-o-im-steckbrief-wir-stellen-euch-den-kandidaten-vor.jpg",
}}
style={styles.participantImage}
/>
<View style={styles.performedShowsSection}>
<Text style={styles.performedShowsTitle}>Auftritte:</Text>
@@ -107,23 +118,31 @@ export default function ParticipantScreen() {
marginTop: 15,
}}
>
{resolved.map(({ show, seasons }) => (
<TouchableOpacity key={show.id} style={styles.showContainer}>
<Image
source={{ uri: show.thumbnailUri }}
style={styles.showImage}
/>
<Text style={styles.showTitle} numberOfLines={2}>
{show.title}
</Text>
<Text style={styles.showSeason} numberOfLines={1}>
Staffel
{seasons.length === 1
? ` ${seasons[0]}`
: `n ${seasons.join(", ")}`}
</Text>
</TouchableOpacity>
))}
{resolved.map(({ show, seasons, partners }) => {
const seasonPartnerLines = partners.map((p) => {
const label = `Staffel ${p.seasonNumber}`;
if (!p.partner) return label;
return `${label} • Partner: ${p.partner.name}`;
});
return (
<TouchableOpacity key={show.id} style={styles.showContainer}>
<Image
source={{ uri: show.thumbnailUri }}
style={styles.showImage}
/>
<Text style={styles.showTitle} numberOfLines={2}>
{show.title}
</Text>
<Text
style={styles.showSeason}
numberOfLines={seasonPartnerLines.length}
>
{seasonPartnerLines.join("\n")}
</Text>
</TouchableOpacity>
);
})}
</ScrollView>
</View>
</ScrollView>

View File

@@ -4,6 +4,7 @@ import ShowInfo from "@/components/ui/ShowInfo";
import ParticipantDetails from "@/components/ParticipantDeatails";
import React from "react";
import { useSeasonContext } from "@/contexts/SeasonContext";
import { getShowColors } from "@/constants/colors";
import {
Dimensions,
Image,
@@ -12,7 +13,6 @@ import {
TouchableOpacity,
View,
} from "react-native";
import * as WebBrowser from "expo-web-browser";
import styles from "./stackStyles/showDetailStyles";
export default function ShowDetails() {
@@ -23,6 +23,8 @@ export default function ShowDetails() {
genres,
streamingService,
id,
startDate,
endDate,
logoUri,
} = useLocalSearchParams();
const [selectedParticipants, setSelectedParticipants] =
@@ -37,6 +39,8 @@ export default function ShowDetails() {
const [pLoading, setPLoading] = React.useState(false);
const [pError, setPError] = React.useState<string | null>(null);
const { tabColor, seasonColor } = getShowColors(Number(id));
React.useEffect(() => {
if (!showId) return;
let active = true;
@@ -85,6 +89,8 @@ export default function ShowDetails() {
seasons={seasonCount}
participants={participants.length}
streamingService={streamingService as string}
startDate={startDate as string}
endDate={endDate as string | null}
/>
<View style={styles.showBannerLogoContainer}>
@@ -103,7 +109,7 @@ export default function ShowDetails() {
styles.infoLabel,
{
fontWeight: selectedParticipants ? "bold" : "normal",
color: selectedParticipants ? "#199edb" : "hsl(0, 0%, 65%)",
color: selectedParticipants ? tabColor : "hsl(0, 0%, 65%)",
},
]}
>
@@ -142,7 +148,7 @@ export default function ShowDetails() {
{
backgroundColor:
selectedSeason === season
? "#199edb"
? seasonColor
: "hsl(0, 0%, 20%)",
},
]}
@@ -172,7 +178,10 @@ export default function ShowDetails() {
{participants.map((p) => (
<TouchableOpacity
key={p.id}
style={styles.participantContainer}
style={[
styles.participantContainer,
{ backgroundColor: tabColor },
]}
onPress={() =>
router.push({
pathname: "/participant",
@@ -190,6 +199,8 @@ export default function ShowDetails() {
height: "100%",
borderRadius: 10,
}}
resizeMode="cover"
blurRadius={p.imageUri.includes("pravatar") ? 16 : 0}
/>
<Text style={styles.participantLabel} numberOfLines={2}>
{p.name}

View File

@@ -50,7 +50,7 @@ const styles = StyleSheet.create({
},
performedShowsSection: {
width: "100%",
height: 375,
height: "100%",
paddingLeft: 15,
paddingBottom: 20,
backgroundColor: "hsl(221, 39%, 0%)",