├── .eslintignore
├── amplify
├── backend
│ ├── storage
│ │ └── youtubeclonemedia
│ │ │ ├── storage-params.json
│ │ │ ├── parameters.json
│ │ │ └── s3-cloudformation-template.json
│ ├── tags.json
│ ├── api
│ │ └── YoutubeClone
│ │ │ ├── transform.conf.json
│ │ │ ├── parameters.json
│ │ │ ├── resolvers
│ │ │ └── README.md
│ │ │ ├── schema.graphql
│ │ │ └── stacks
│ │ │ └── CustomResources.json
│ ├── analytics
│ │ └── youtubeclone
│ │ │ ├── parameters.json
│ │ │ └── pinpoint-cloudformation-template.json
│ ├── backend-config.json
│ └── auth
│ │ └── YoutubeClone
│ │ ├── parameters.json
│ │ └── YoutubeClone-cloudformation-template.yml
├── .config
│ └── project-config.json
├── team-provider-info.json
└── cli.json
├── screens
├── VideoScreen
│ ├── index.ts
│ ├── styles.ts
│ └── VideoScreen.tsx
├── HomeScreen.tsx
├── TabOneScreen.tsx
├── NotFoundScreen.tsx
├── TabTwoScreen.tsx
└── VideoUploadScreen.tsx
├── assets
├── images
│ ├── icon.png
│ ├── logo.png
│ ├── splash.png
│ ├── favicon.png
│ └── adaptive-icon.png
├── fonts
│ └── SpaceMono-Regular.ttf
└── data
│ ├── video.json
│ ├── videos.json
│ └── comments.json
├── components
├── VideoListItem
│ ├── index.tsx
│ ├── styles.ts
│ └── VideoListItem.tsx
├── StyledText.tsx
├── __tests__
│ └── StyledText-test.js
├── VideoPlayer
│ └── index.tsx
├── VideoComment
│ └── index.tsx
├── Themed.tsx
├── VideoComments
│ └── index.tsx
└── EditScreenInfo.tsx
├── src
└── models
│ ├── schema.d.ts
│ ├── index.js
│ ├── index.d.ts
│ └── schema.js
├── tsconfig.json
├── babel.config.js
├── constants
├── Layout.ts
└── Colors.ts
├── .expo-shared
└── assets.json
├── .vscode
└── settings.json
├── hooks
├── useColorScheme.ts
└── useCachedResources.ts
├── types.tsx
├── .gitignore
├── navigation
├── LinkingConfiguration.ts
├── index.tsx
├── HomeStack.tsx
└── BottomTabNavigator.tsx
├── app.json
├── LICENSE
├── App.tsx
└── package.json
/.eslintignore:
--------------------------------------------------------------------------------
1 | src/models
--------------------------------------------------------------------------------
/amplify/backend/storage/youtubeclonemedia/storage-params.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/screens/VideoScreen/index.ts:
--------------------------------------------------------------------------------
1 | import VideoScreen from './VideoScreen';
2 | export default VideoScreen;
--------------------------------------------------------------------------------
/assets/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VadimNotJustDev/YoutubeClone/HEAD/assets/images/icon.png
--------------------------------------------------------------------------------
/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VadimNotJustDev/YoutubeClone/HEAD/assets/images/logo.png
--------------------------------------------------------------------------------
/assets/images/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VadimNotJustDev/YoutubeClone/HEAD/assets/images/splash.png
--------------------------------------------------------------------------------
/components/VideoListItem/index.tsx:
--------------------------------------------------------------------------------
1 | import VideoListItem from './VideoListItem';
2 | export default VideoListItem;
--------------------------------------------------------------------------------
/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VadimNotJustDev/YoutubeClone/HEAD/assets/images/favicon.png
--------------------------------------------------------------------------------
/src/models/schema.d.ts:
--------------------------------------------------------------------------------
1 | import { Schema } from '@aws-amplify/datastore';
2 |
3 | export declare const schema: Schema;
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "expo/tsconfig.base",
3 | "compilerOptions": {
4 | "strict": true
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/assets/images/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VadimNotJustDev/YoutubeClone/HEAD/assets/images/adaptive-icon.png
--------------------------------------------------------------------------------
/assets/fonts/SpaceMono-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VadimNotJustDev/YoutubeClone/HEAD/assets/fonts/SpaceMono-Regular.ttf
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function(api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo'],
5 | plugins: ['react-native-reanimated/plugin'],
6 | };
7 | };
8 |
--------------------------------------------------------------------------------
/amplify/backend/tags.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "Key": "user:Stack",
4 | "Value": "{project-env}"
5 | },
6 | {
7 | "Key": "user:Application",
8 | "Value": "{project-name}"
9 | }
10 | ]
--------------------------------------------------------------------------------
/components/StyledText.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import { Text, TextProps } from './Themed';
4 |
5 | export function MonoText(props: TextProps) {
6 | return ;
7 | }
8 |
--------------------------------------------------------------------------------
/src/models/index.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | import { initSchema } from '@aws-amplify/datastore';
3 | import { schema } from './schema';
4 |
5 |
6 |
7 | const { Comment, User, Video } = initSchema(schema);
8 |
9 | export {
10 | Comment,
11 | User,
12 | Video
13 | };
--------------------------------------------------------------------------------
/amplify/backend/api/YoutubeClone/transform.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 5,
3 | "ElasticsearchWarning": true,
4 | "ResolverConfig": {
5 | "project": {
6 | "ConflictHandler": "AUTOMERGE",
7 | "ConflictDetection": "VERSION"
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/constants/Layout.ts:
--------------------------------------------------------------------------------
1 | import { Dimensions } from 'react-native';
2 |
3 | const width = Dimensions.get('window').width;
4 | const height = Dimensions.get('window').height;
5 |
6 | export default {
7 | window: {
8 | width,
9 | height,
10 | },
11 | isSmallDevice: width < 375,
12 | };
13 |
--------------------------------------------------------------------------------
/amplify/backend/api/YoutubeClone/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "AppSyncApiName": "YoutubeClone",
3 | "DynamoDBBillingMode": "PAY_PER_REQUEST",
4 | "DynamoDBEnableServerSideEncryption": false,
5 | "AuthCognitoUserPoolId": {
6 | "Fn::GetAtt": [
7 | "authYoutubeClone",
8 | "Outputs.UserPoolId"
9 | ]
10 | }
11 | }
--------------------------------------------------------------------------------
/.expo-shared/assets.json:
--------------------------------------------------------------------------------
1 | {
2 | "e997a5256149a4b76e6bfd6cbf519c5e5a0f1d278a3d8fa1253022b03c90473b": true,
3 | "af683c96e0ffd2cf81287651c9433fa44debc1220ca7cb431fe482747f34a505": true,
4 | "12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true,
5 | "40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true
6 | }
7 |
--------------------------------------------------------------------------------
/amplify/backend/api/YoutubeClone/resolvers/README.md:
--------------------------------------------------------------------------------
1 | Any resolvers that you add in this directory will override the ones automatically generated by Amplify CLI and will be directly copied to the cloud.
2 | For more information, visit [https://docs.amplify.aws/cli/graphql-transformer/resolvers](https://docs.amplify.aws/cli/graphql-transformer/resolvers)
--------------------------------------------------------------------------------
/components/__tests__/StyledText-test.js:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import renderer from 'react-test-renderer';
3 |
4 | import { MonoText } from '../StyledText';
5 |
6 | it(`renders correctly`, () => {
7 | const tree = renderer.create(Snapshot test!).toJSON();
8 |
9 | expect(tree).toMatchSnapshot();
10 | });
11 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.exclude": {
3 | "amplify/.config": true,
4 | "amplify/**/*-parameters.json": true,
5 | "amplify/**/amplify.state": true,
6 | "amplify/**/transform.conf.json": true,
7 | "amplify/#current-cloud-backend": true,
8 | "amplify/backend/amplify-meta.json": true,
9 | "amplify/backend/awscloudformation": true
10 | }
11 | }
--------------------------------------------------------------------------------
/amplify/.config/project-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "providers": [
3 | "awscloudformation"
4 | ],
5 | "projectName": "YoutubeClone",
6 | "version": "3.1",
7 | "frontend": "javascript",
8 | "javascript": {
9 | "framework": "react-native",
10 | "config": {
11 | "SourceDir": "src",
12 | "DistributionDir": "/",
13 | "BuildCommand": "npm run-script build",
14 | "StartCommand": "npm run-script start"
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/hooks/useColorScheme.ts:
--------------------------------------------------------------------------------
1 | import { ColorSchemeName, useColorScheme as _useColorScheme } from 'react-native';
2 |
3 | // The useColorScheme value is always either light or dark, but the built-in
4 | // type suggests that it can be null. This will not happen in practice, so this
5 | // makes it a bit easier to work with.
6 | export default function useColorScheme(): NonNullable {
7 | return _useColorScheme() as NonNullable;
8 | }
9 |
--------------------------------------------------------------------------------
/constants/Colors.ts:
--------------------------------------------------------------------------------
1 | const tintColorLight = '#2f95dc';
2 | const tintColorDark = '#fff';
3 |
4 | export default {
5 | light: {
6 | text: '#000',
7 | background: '#fff',
8 | tint: tintColorLight,
9 | tabIconDefault: '#ccc',
10 | tabIconSelected: tintColorLight,
11 | },
12 | dark: {
13 | text: '#fff',
14 | background: '#000',
15 | tint: tintColorDark,
16 | tabIconDefault: '#ccc',
17 | tabIconSelected: tintColorDark,
18 | },
19 | };
20 |
--------------------------------------------------------------------------------
/types.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Learn more about using TypeScript with React Navigation:
3 | * https://reactnavigation.org/docs/typescript/
4 | */
5 |
6 | export type RootStackParamList = {
7 | Root: undefined;
8 | VideoScreen: undefined;
9 | NotFound: undefined;
10 | };
11 |
12 | export type BottomTabParamList = {
13 | Home: undefined;
14 | Explore: undefined;
15 | New: undefined;
16 | Subscriptions: undefined;
17 | Library: undefined;
18 | };
19 |
20 | export type TabOneParamList = {
21 | TabOneScreen: undefined;
22 | };
23 |
24 | export type TabTwoParamList = {
25 | TabTwoScreen: undefined;
26 | };
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .expo/
3 | npm-debug.*
4 | *.jks
5 | *.p8
6 | *.p12
7 | *.key
8 | *.mobileprovision
9 | *.orig.*
10 | web-build/
11 |
12 | # macOS
13 | .DS_Store
14 |
15 | #amplify
16 | amplify/\#current-cloud-backend
17 | amplify/.config/local-*
18 | amplify/logs
19 | amplify/mock-data
20 | amplify/backend/amplify-meta.json
21 | amplify/backend/awscloudformation
22 | amplify/backend/.temp
23 | build/
24 | dist/
25 | node_modules/
26 | aws-exports.js
27 | awsconfiguration.json
28 | amplifyconfiguration.json
29 | amplifyconfiguration.dart
30 | amplify-build-config.json
31 | amplify-gradle-config.json
32 | amplifytools.xcconfig
33 | .secret-*
--------------------------------------------------------------------------------
/assets/data/video.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "1",
3 | "createdAt": "5 months ago",
4 | "title": "Build a Realtime Chat App in React Native (tutorial for beginners) 🔴 ",
5 | "thumbnail": "https://notjustdev-dummy.s3.us-east-2.amazonaws.com/thumbnails/thumbnail1.jpeg",
6 | "videoUrl": "http://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4",
7 | "duration": 384,
8 | "user": {
9 | "name": "Vadim Savin",
10 | "image": "https://notjustdev-dummy.s3.us-east-2.amazonaws.com/avatars/vadim.jpg",
11 | "subscribers": 100000
12 | },
13 | "views": 357000,
14 | "tags": "#VadimSavin #notjust #notJustDeveloper",
15 | "likes": 3759,
16 | "dislikes": 53
17 | }
--------------------------------------------------------------------------------
/amplify/backend/analytics/youtubeclone/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "appName": "youtubeclone",
3 | "roleName": "pinpointLambdaRole4b90add6",
4 | "cloudformationPolicyName": "cloudformationPolicy4b90add6",
5 | "cloudWatchPolicyName": "cloudWatchPolicy4b90add6",
6 | "pinpointPolicyName": "pinpointPolicy4b90add6",
7 | "authPolicyName": "pinpoint_amplify_4b90add6",
8 | "unauthPolicyName": "pinpoint_amplify_4b90add6",
9 | "authRoleName": {
10 | "Ref": "AuthRoleName"
11 | },
12 | "unauthRoleName": {
13 | "Ref": "UnauthRoleName"
14 | },
15 | "authRoleArn": {
16 | "Fn::GetAtt": [
17 | "AuthRole",
18 | "Arn"
19 | ]
20 | }
21 | }
--------------------------------------------------------------------------------
/navigation/LinkingConfiguration.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Learn more about deep linking with React Navigation
3 | * https://reactnavigation.org/docs/deep-linking
4 | * https://reactnavigation.org/docs/configuring-links
5 | */
6 |
7 | import * as Linking from 'expo-linking';
8 |
9 | export default {
10 | prefixes: [Linking.makeUrl('/')],
11 | config: {
12 | screens: {
13 | Root: {
14 | screens: {
15 | TabOne: {
16 | screens: {
17 | TabOneScreen: 'one',
18 | },
19 | },
20 | TabTwo: {
21 | screens: {
22 | TabTwoScreen: 'two',
23 | },
24 | },
25 | },
26 | },
27 | NotFound: '*',
28 | },
29 | },
30 | };
31 |
--------------------------------------------------------------------------------
/screens/HomeScreen.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import { View, StyleSheet, FlatList } from "react-native";
3 |
4 | import { DataStore } from "aws-amplify";
5 | import { Video } from "../src/models";
6 |
7 | import VideoListItem from "../components/VideoListItem";
8 |
9 | const HomeScreen = () => {
10 | const [videos, setVideos] = useState