mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-10-16 06:25:42 -04:00
feat: refactor platforms to support multiple TMDB provider IDs per platform
- Replace `tmdbProviderId` (single int) with a many-to-many `platformTmdbProviders` join table so one platform entry can map to multiple TMDB provider IDs (e.g. a single "Max" platform covers several regional TMDB IDs) - Add `isSubscription` flag to platforms to distinguish subscription services from transactional ones, replacing the old `displayOrder` field in API responses - Add `getPlatformTmdbIds` / `getPlatformTmdbIdMap` helpers in `@sofa/core/platforms` and thread them through discover, explore, and platform list procedures - Replace `providerId: number` with `platformId: string` (UUID) in discover input schema so the client never needs to resolve TMDB IDs - Add `scripts/sync-tmdb-providers.ts` script to pull live provider data from TMDB and update `platforms.json` - Split native title detail availability into separate "Stream" and "Buy or Rent" sections matching the web pattern - Add two new DB migrations for the join table and platform schema changes
This commit is contained in:
58 files changed
+8291
-907
No files matched your search
@@ -471,30 +471,76 @@ export default function TitleDetailScreen() {
|
||||
iconColor={titleAccent}
|
||||
/>
|
||||
</View>
|
||||
<ScrollView
|
||||
horizontal
|
||||
showsHorizontalScrollIndicator={false}
|
||||
contentContainerStyle={titleAvailabilityContentStyle}
|
||||
>
|
||||
{availability.map((offer) => (
|
||||
<View key={`${offer.platformId}-${offer.offerType}`} className="items-center">
|
||||
{offer.logoPath && (
|
||||
<Image
|
||||
source={{ uri: offer.logoPath }}
|
||||
style={titleDetailStyles.providerLogo}
|
||||
contentFit="cover"
|
||||
/>
|
||||
{(() => {
|
||||
const stream = availability.filter((o) => o.offerType === "stream");
|
||||
const purchase = availability.filter((o) => o.offerType === "purchase");
|
||||
return (
|
||||
<View className="gap-3">
|
||||
{stream.length > 0 && (
|
||||
<View>
|
||||
<Text className="text-muted-foreground/60 mb-1.5 px-4 text-[10px] font-medium tracking-wider uppercase">
|
||||
{t`Stream`}
|
||||
</Text>
|
||||
<ScrollView
|
||||
horizontal
|
||||
showsHorizontalScrollIndicator={false}
|
||||
contentContainerStyle={titleAvailabilityContentStyle}
|
||||
>
|
||||
{stream.map((offer) => (
|
||||
<View key={offer.platformId} className="items-center">
|
||||
{offer.logoPath && (
|
||||
<Image
|
||||
source={{ uri: offer.logoPath }}
|
||||
style={titleDetailStyles.providerLogo}
|
||||
contentFit="cover"
|
||||
/>
|
||||
)}
|
||||
<Text
|
||||
maxFontSizeMultiplier={1.0}
|
||||
className="text-muted-foreground mt-1 max-w-[60px] text-center text-xs"
|
||||
numberOfLines={1}
|
||||
>
|
||||
{offer.providerName}
|
||||
</Text>
|
||||
</View>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
)}
|
||||
{purchase.length > 0 && (
|
||||
<View>
|
||||
<Text className="text-muted-foreground/60 mb-1.5 px-4 text-[10px] font-medium tracking-wider uppercase">
|
||||
{t`Buy or Rent`}
|
||||
</Text>
|
||||
<ScrollView
|
||||
horizontal
|
||||
showsHorizontalScrollIndicator={false}
|
||||
contentContainerStyle={titleAvailabilityContentStyle}
|
||||
>
|
||||
{purchase.map((offer) => (
|
||||
<View key={offer.platformId} className="items-center">
|
||||
{offer.logoPath && (
|
||||
<Image
|
||||
source={{ uri: offer.logoPath }}
|
||||
style={titleDetailStyles.providerLogo}
|
||||
contentFit="cover"
|
||||
/>
|
||||
)}
|
||||
<Text
|
||||
maxFontSizeMultiplier={1.0}
|
||||
className="text-muted-foreground mt-1 max-w-[60px] text-center text-xs"
|
||||
numberOfLines={1}
|
||||
>
|
||||
{offer.providerName}
|
||||
</Text>
|
||||
</View>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
)}
|
||||
<Text
|
||||
maxFontSizeMultiplier={1.0}
|
||||
className="text-muted-foreground mt-1 max-w-[60px] text-center text-xs"
|
||||
numberOfLines={1}
|
||||
>
|
||||
{offer.providerName}
|
||||
</Text>
|
||||
</View>
|
||||
))}
|
||||
</ScrollView>
|
||||
);
|
||||
})()}
|
||||
</Animated.View>
|
||||
)}
|
||||
|
||||
|
||||
Reference in new issue
Block a user