mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-09 19:40:44 +00:00
changed default hero to carousal
This commit is contained in:
parent
56b4e60ecb
commit
9fcb6a34b7
4 changed files with 111 additions and 56 deletions
6
app.json
6
app.json
|
|
@ -2,7 +2,7 @@
|
||||||
"expo": {
|
"expo": {
|
||||||
"name": "Nuvio",
|
"name": "Nuvio",
|
||||||
"slug": "nuvio",
|
"slug": "nuvio",
|
||||||
"version": "0.6.0-beta.6",
|
"version": "0.6.0-beta.7",
|
||||||
"orientation": "default",
|
"orientation": "default",
|
||||||
"icon": "./assets/ios/AppIcon.appiconset/Icon-App-60x60@3x.png",
|
"icon": "./assets/ios/AppIcon.appiconset/Icon-App-60x60@3x.png",
|
||||||
"userInterfaceStyle": "dark",
|
"userInterfaceStyle": "dark",
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
"ios": {
|
"ios": {
|
||||||
"supportsTablet": true,
|
"supportsTablet": true,
|
||||||
"icon": "./assets/ios/AppIcon.appiconset/Icon-App-60x60@3x.png",
|
"icon": "./assets/ios/AppIcon.appiconset/Icon-App-60x60@3x.png",
|
||||||
"buildNumber": "6",
|
"buildNumber": "7",
|
||||||
"infoPlist": {
|
"infoPlist": {
|
||||||
"NSAppTransportSecurity": {
|
"NSAppTransportSecurity": {
|
||||||
"NSAllowsArbitraryLoads": true
|
"NSAllowsArbitraryLoads": true
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
"WAKE_LOCK"
|
"WAKE_LOCK"
|
||||||
],
|
],
|
||||||
"package": "com.nuvio.app",
|
"package": "com.nuvio.app",
|
||||||
"versionCode": 6,
|
"versionCode": 7,
|
||||||
"architectures": [
|
"architectures": [
|
||||||
"arm64-v8a",
|
"arm64-v8a",
|
||||||
"armeabi-v7a",
|
"armeabi-v7a",
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ interface HeroCarouselProps {
|
||||||
const { width } = Dimensions.get('window');
|
const { width } = Dimensions.get('window');
|
||||||
|
|
||||||
const CARD_WIDTH = Math.min(width * 0.8, 480);
|
const CARD_WIDTH = Math.min(width * 0.8, 480);
|
||||||
const CARD_HEIGHT = Math.round(CARD_WIDTH * 9 / 16) + 270; // further increased space for text/actions
|
const CARD_HEIGHT = Math.round(CARD_WIDTH * 9 / 16) + 290; // slight increase for text/actions
|
||||||
|
|
||||||
const HeroCarousel: React.FC<HeroCarouselProps> = ({ items, loading = false }) => {
|
const HeroCarousel: React.FC<HeroCarouselProps> = ({ items, loading = false }) => {
|
||||||
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
|
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ export const DEFAULT_SETTINGS: AppSettings = {
|
||||||
preferredPlayer: 'internal',
|
preferredPlayer: 'internal',
|
||||||
showHeroSection: true,
|
showHeroSection: true,
|
||||||
featuredContentSource: 'catalogs',
|
featuredContentSource: 'catalogs',
|
||||||
heroStyle: 'legacy',
|
heroStyle: 'carousel',
|
||||||
selectedHeroCatalogs: [], // Empty array means all catalogs are selected
|
selectedHeroCatalogs: [], // Empty array means all catalogs are selected
|
||||||
logoSourcePreference: 'metahub', // Default to Metahub as first source
|
logoSourcePreference: 'metahub', // Default to Metahub as first source
|
||||||
tmdbLanguagePreference: 'en', // Default to English
|
tmdbLanguagePreference: 'en', // Default to English
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,44 @@ const HomeScreenSettings: React.FC = () => {
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Compact segmented control for nicer toggles
|
||||||
|
const SegmentedControl = ({
|
||||||
|
options,
|
||||||
|
value,
|
||||||
|
onChange
|
||||||
|
}: {
|
||||||
|
options: { label: string; value: string }[];
|
||||||
|
value: string;
|
||||||
|
onChange: (val: string) => void;
|
||||||
|
}) => (
|
||||||
|
<View style={[styles.segmentContainer, { backgroundColor: isDarkMode ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)' }]}>
|
||||||
|
{options.map((opt, idx) => {
|
||||||
|
const selected = value === opt.value;
|
||||||
|
return (
|
||||||
|
<TouchableOpacity
|
||||||
|
key={opt.value}
|
||||||
|
onPress={() => onChange(opt.value)}
|
||||||
|
activeOpacity={0.85}
|
||||||
|
style={[
|
||||||
|
styles.segment,
|
||||||
|
idx === 0 && styles.segmentFirst,
|
||||||
|
idx === options.length - 1 && styles.segmentLast,
|
||||||
|
selected && { backgroundColor: colors.primary },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Text style={{
|
||||||
|
color: selected ? colors.white : (isDarkMode ? colors.highEmphasis : colors.textDark),
|
||||||
|
fontWeight: '700',
|
||||||
|
fontSize: 13,
|
||||||
|
}}>
|
||||||
|
{opt.label}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
// Format selected catalogs text
|
// Format selected catalogs text
|
||||||
const getSelectedCatalogsText = useCallback(() => {
|
const getSelectedCatalogsText = useCallback(() => {
|
||||||
if (!settings.selectedHeroCatalogs || settings.selectedHeroCatalogs.length === 0) {
|
if (!settings.selectedHeroCatalogs || settings.selectedHeroCatalogs.length === 0) {
|
||||||
|
|
@ -274,61 +312,33 @@ const HomeScreenSettings: React.FC = () => {
|
||||||
|
|
||||||
{settings.showHeroSection && (
|
{settings.showHeroSection && (
|
||||||
<>
|
<>
|
||||||
<View style={styles.radioCardContainer}>
|
<View style={styles.segmentCard}>
|
||||||
<RadioOption
|
<Text style={[styles.segmentTitle, { color: isDarkMode ? colors.mediumEmphasis : colors.textMutedDark }]}>Hero Layout</Text>
|
||||||
selected={settings.heroStyle === 'legacy'}
|
<SegmentedControl
|
||||||
onPress={() => handleUpdateSetting('heroStyle', 'legacy')}
|
options={[{ label: 'Legacy', value: 'legacy' }, { label: 'Carousel', value: 'carousel' }]}
|
||||||
label="Legacy Hero (banner)"
|
value={settings.heroStyle}
|
||||||
|
onChange={(val) => handleUpdateSetting('heroStyle', val as any)}
|
||||||
/>
|
/>
|
||||||
<View style={styles.radioDescription}>
|
<Text style={[styles.segmentHint, { color: isDarkMode ? colors.mediumEmphasis : colors.textMutedDark }]}>Full-width banner or swipeable cards</Text>
|
||||||
<Text style={[styles.radioDescriptionText, { color: isDarkMode ? colors.mediumEmphasis : colors.textMutedDark }]}>
|
|
||||||
Original full-width banner with overlayed info and actions.
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.radioCardContainer}>
|
<View style={styles.segmentCard}>
|
||||||
<RadioOption
|
<Text style={[styles.segmentTitle, { color: isDarkMode ? colors.mediumEmphasis : colors.textMutedDark }]}>Featured Source</Text>
|
||||||
selected={settings.heroStyle === 'carousel'}
|
<SegmentedControl
|
||||||
onPress={() => handleUpdateSetting('heroStyle', 'carousel')}
|
options={[{ label: 'TMDB', value: 'tmdb' }, { label: 'Catalogs', value: 'catalogs' }]}
|
||||||
label="New Card Carousel"
|
value={settings.featuredContentSource}
|
||||||
|
onChange={(val) => handleUpdateSetting('featuredContentSource', val as any)}
|
||||||
/>
|
/>
|
||||||
<View style={styles.radioDescription}>
|
{settings.featuredContentSource === 'catalogs' && (
|
||||||
<Text style={[styles.radioDescriptionText, { color: isDarkMode ? colors.mediumEmphasis : colors.textMutedDark }]}>
|
<TouchableOpacity
|
||||||
A beautiful, swipeable carousel of featured cards with smooth animations.
|
onPress={() => navigation.navigate('HeroCatalogs')}
|
||||||
</Text>
|
style={[styles.manageLink, { backgroundColor: isDarkMode ? colors.elevation1 : 'rgba(0,0,0,0.04)' }]}
|
||||||
</View>
|
activeOpacity={0.8}
|
||||||
</View>
|
>
|
||||||
<View style={styles.radioCardContainer}>
|
<Text style={{ color: isDarkMode ? colors.highEmphasis : colors.textDark, fontWeight: '600' }}>Manage selected catalogs</Text>
|
||||||
<RadioOption
|
<MaterialIcons name="chevron-right" size={20} color={isDarkMode ? colors.mediumEmphasis : colors.textMutedDark} />
|
||||||
selected={settings.featuredContentSource === 'tmdb'}
|
</TouchableOpacity>
|
||||||
onPress={() => {
|
)}
|
||||||
console.log('Selected TMDB source');
|
|
||||||
handleUpdateSetting('featuredContentSource', 'tmdb');
|
|
||||||
}}
|
|
||||||
label="TMDB Trending Movies"
|
|
||||||
/>
|
|
||||||
<View style={styles.radioDescription}>
|
|
||||||
<Text style={[styles.radioDescriptionText, { color: isDarkMode ? colors.mediumEmphasis : colors.textMutedDark }]}>
|
|
||||||
Featured content will be sourced from TMDB's trending movies API. This provides a variety of popular and recent content, even if not available in your catalogs.
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View style={styles.radioCardContainer}>
|
|
||||||
<RadioOption
|
|
||||||
selected={settings.featuredContentSource === 'catalogs'}
|
|
||||||
onPress={() => {
|
|
||||||
console.log('Selected Catalogs source');
|
|
||||||
handleUpdateSetting('featuredContentSource', 'catalogs');
|
|
||||||
}}
|
|
||||||
label="Installed Catalogs"
|
|
||||||
/>
|
|
||||||
<View style={styles.radioDescription}>
|
|
||||||
<Text style={[styles.radioDescriptionText, { color: isDarkMode ? colors.mediumEmphasis : colors.textMutedDark }]}>
|
|
||||||
Featured content will be sourced from your enabled catalogs. This ensures that featured content is available to stream from your installed add-ons.
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
@ -481,6 +491,51 @@ const styles = StyleSheet.create({
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
lineHeight: 20,
|
lineHeight: 20,
|
||||||
},
|
},
|
||||||
|
segmentContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
borderRadius: 10,
|
||||||
|
padding: 4,
|
||||||
|
gap: 6,
|
||||||
|
marginTop: 8,
|
||||||
|
},
|
||||||
|
segment: {
|
||||||
|
flex: 1,
|
||||||
|
borderRadius: 8,
|
||||||
|
paddingVertical: 10,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
segmentFirst: {
|
||||||
|
},
|
||||||
|
segmentLast: {
|
||||||
|
},
|
||||||
|
segmentCard: {
|
||||||
|
marginHorizontal: 16,
|
||||||
|
marginTop: 12,
|
||||||
|
padding: 16,
|
||||||
|
borderRadius: 12,
|
||||||
|
backgroundColor: 'rgba(255,255,255,0.05)'
|
||||||
|
},
|
||||||
|
segmentTitle: {
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: '700',
|
||||||
|
letterSpacing: 0.6,
|
||||||
|
opacity: 0.9,
|
||||||
|
},
|
||||||
|
segmentHint: {
|
||||||
|
marginTop: 8,
|
||||||
|
fontSize: 12,
|
||||||
|
opacity: 0.7,
|
||||||
|
},
|
||||||
|
manageLink: {
|
||||||
|
marginTop: 10,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
paddingVertical: 10,
|
||||||
|
borderRadius: 10,
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
},
|
||||||
savedIndicator: {
|
savedIndicator: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: Platform.OS === 'android' ? (StatusBar.currentHeight || 0) + 60 : 90,
|
top: Platform.OS === 'android' ? (StatusBar.currentHeight || 0) + 60 : 90,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue