as

Settings
Sign out
Notifications
Alexa
Amazon Appstore
AWS
Documentation
Support
Contact Us
My Cases
Get Started
Design and Develop
Publish
Reference
Support

Part 1: Final Code

Here is the final code for part one.

Folder Structure

src/
├── components/
│   ├── Header.tsx
│   └── VideoCard.tsx
├── screens
│   ├── LandingScreen.tsx
└── App.tsx

Components

Header.tsx

VideoCard.tsx

Copied to clipboard.


import React, {useState} from 'react';
import {StyleSheet, Text, TouchableOpacity, Image, View} from 'react-native';

interface IProps {
  title: string;
  imgURL: string;
  description: string;
  pressFunction: Function;
}

const VideoCard = ({title, imgURL, description, pressFunction}: IProps) => {
  const [focused, setFocused] = useState(false);

  return (
    <TouchableOpacity
      style={[
        styles.videoCardContainer,
        focused ? styles.focused : styles.unfocused,
      ]}
      onPress={() => pressFunction()}
      onFocus={() => setFocused(true)}
      onBlur={() => setFocused(false)}>
      <Image style={styles.videoImage} source={{uri: imgURL}} />
      <View style={styles.videoTextContainer}>
        <Text style={styles.videoTitle}>{title}</Text>
        <Text style={styles.videoDescription}>{description}</Text>
      </View>
    </TouchableOpacity>
  );
};

const styles = StyleSheet.create({
  videoCardContainer: {
    height: 400,
    width: 550,
    margin: 10,
    borderRadius: 5,
  },
  unfocused: {
    borderWidth: 1,
    borderColor: 'white',
  },
  focused: {
    borderWidth: 5,
    borderColor: 'yellow',
  },
  videoTextContainer: {
    height: '25%',
    display: 'flex',
    justifyContent: 'space-around',
    padding: 10,
  },
  videoImage: {
    height: '75%',
  },
  videoTitle: {
    fontSize: 20,
    fontWeight: 'bold',
    color: 'white',
  },
  videoDescription: {
    color: 'white',
  },
});

export default VideoCard;

Screens

LandingScreen.tsx

Copied to clipboard.


import React, {useState, useEffect} from 'react';
import {FlatList, StyleSheet, View, Text} from 'react-native';
import Header from '../components/Header';
import VideoCard from '../components/VideoCard';
import {TVFocusGuideView} from '@amazon-devices/react-native-kepler';

interface IVideo {
  id: string;
  title: string;
  description: string;
  duration: number;
  thumbURL: string;
  imgURL: string;
  videoURL: string;
  categories: Array<string>;
  channel_id: number;
}

const LandingScreen = () => {
  const [islandVideos, setIslandVideos] = useState<IVideo[]>([]);
  const [underwaterVideos, setUnderwaterVideos] = useState<IVideo[]>([]);

  const url = 'https://d2ob7xfxpe6plv.cloudfront.net/TestData.json';

  const getAllVideos = () => {
    fetch(url)
      .then((response) => response.json())
      .then((data) => {
        // Filter videos for each category
        const islands = data.testData.filter(
          (video: IVideo) =>
            video.categories && video.categories.includes('Costa Rica Islands'),
        );

        const underwater = data.testData.filter(
          (video: IVideo) =>
            video.categories &&
            video.categories.includes('Costa Rica Underwater'),
        );

        setIslandVideos(islands);
        setUnderwaterVideos(underwater);
      })
      .catch((error) => {
        console.log(error);
      });
  };

  useEffect(() => {
    getAllVideos();
  }, []);

  return (
    <>
      <Header />
      <TVFocusGuideView autoFocus={true}>
        <Text style={styles.categoryTitle}>Costa Rica Islands</Text>
        <FlatList
          style={styles.flatList}
          horizontal
          data={islandVideos}
          renderItem={({item}) => (
            <View style={styles.itemContainer}>
              <VideoCard
                title={item.title}
                description={
                  item.description.split(' ').slice(0, 20).join(' ') + '...'
                }
                imgURL={item.imgURL}
                pressFunction={() => {}}
              />
            </View>
          )}
        />
      </TVFocusGuideView>
      <TVFocusGuideView autoFocus={true}>
        <Text style={styles.categoryTitle}>Costa Rica Underwater</Text>
        <FlatList
          style={styles.flatList}
          horizontal
          data={underwaterVideos}
          renderItem={({item}) => (
            <View style={styles.itemContainer}>
              <VideoCard
                title={item.title}
                description={
                  item.description.split(' ').slice(0, 20).join(' ') + '...'
                }
                imgURL={item.imgURL}
                pressFunction={() => {}}
              />
            </View>
          )}
        />
      </TVFocusGuideView>
    </>
  );
};

const styles = StyleSheet.create({
  flatList: {
    padding: 10,
  },
  itemContainer: {
    margin: 10,
  },
  categoryTitle: {
    fontSize: 24,
    fontWeight: 'bold',
    color: 'white',
    marginLeft: 30,
  },
});

export default LandingScreen;

App.tsx

Copied to clipboard.


import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import LandingScreen from './screens/LandingScreen';

export const App = () => {
  return (
    <View style={styles.container}>
      <LandingScreen />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#232F3E',
  },
});