├── .expo-shared └── assets.json ├── .gitignore ├── App.js ├── README.md ├── app.json ├── assets ├── adaptive-icon.png ├── favicon.png ├── icon.png └── splash.png ├── babel.config.js ├── components └── shared │ └── Post.js ├── data └── posts.js ├── home.png ├── icons.js ├── package.json ├── screens ├── home │ ├── components │ │ ├── Header.js │ │ └── Stories.js │ └── index.js ├── profile │ └── index.js ├── reel │ └── index.js ├── search │ └── index.js └── shop │ └── index.js ├── utils.js └── yarn.lock /.expo-shared/assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true, 3 | "40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .expo/ 3 | dist/ 4 | npm-debug.* 5 | *.jks 6 | *.p8 7 | *.p12 8 | *.key 9 | *.mobileprovision 10 | *.orig.* 11 | web-build/ 12 | 13 | # macOS 14 | .DS_Store 15 | .idea 16 | -------------------------------------------------------------------------------- /App.js: -------------------------------------------------------------------------------- 1 | import {StatusBar} from 'expo-status-bar'; 2 | import {NavigationContainer} from '@react-navigation/native'; 3 | import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; 4 | import {Image, StyleSheet, SafeAreaView} from "react-native"; 5 | 6 | const Tab = createBottomTabNavigator(); 7 | 8 | // Icons 9 | import {HomeFilled, Home, Search, SearchFilled, Reel, ReelFilled, Shop, ShopFilled} from "./icons"; 10 | 11 | // screens 12 | import HomeScreen from "./screens/home"; 13 | import SearchScreen from "./screens/search"; 14 | import ReelScreen from "./screens/reel"; 15 | import ShopScreen from "./screens/shop"; 16 | import ProfileScreen from "./screens/profile"; 17 | 18 | export default function App() { 19 | return ( 20 | 21 | 22 | 23 | 39 | { 44 | if (focused) 45 | return 46 | return 47 | } 48 | }} 49 | /> 50 | { 55 | if (focused) 56 | return 57 | return 58 | } 59 | }} 60 | /> 61 | { 66 | if (focused) 67 | return 68 | return 69 | } 70 | }} 71 | /> 72 | { 77 | if (focused) 78 | return 79 | return 80 | } 81 | }} 82 | /> 83 | { 88 | return 97 | } 98 | }} 99 | /> 100 | 101 | 102 | 103 | ); 104 | } 105 | 106 | const styles = StyleSheet.create({ 107 | avatar: { 108 | width: 24, 109 | height: 24, 110 | borderRadius: 24, 111 | borderColor: '#000' 112 | } 113 | }) 114 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## React Native Instagram UI Clone 2 | 3 | Kendimi geliştirmek için boş vakitlerimde popüler uygulamaların UI clonelarını çıkarmaya çalışacağım. 4 | 5 | Bu süreçte çok şey öğreneceğime eminim :) Şimdilik sadece anasayfayı tasarladım, yavaş yavaş diğer sayfaları ve getirdiği challengeları yapmayı deneyeceğim. 6 | 7 | #### Anasayfa Demo 8 | 9 | ![](home.png) 10 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "instagram-app", 4 | "slug": "instagram-app", 5 | "version": "1.0.0", 6 | "orientation": "portrait", 7 | "icon": "./assets/icon.png", 8 | "splash": { 9 | "image": "./assets/splash.png", 10 | "resizeMode": "contain", 11 | "backgroundColor": "#ffffff" 12 | }, 13 | "updates": { 14 | "fallbackToCacheTimeout": 0 15 | }, 16 | "assetBundlePatterns": [ 17 | "**/*" 18 | ], 19 | "ios": { 20 | "supportsTablet": true 21 | }, 22 | "android": { 23 | "adaptiveIcon": { 24 | "foregroundImage": "./assets/adaptive-icon.png", 25 | "backgroundColor": "#FFFFFF" 26 | } 27 | }, 28 | "web": { 29 | "favicon": "./assets/favicon.png" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tayfunerbilen/react-native-instagram-ui-clone/1cdb93c1e3757efb8fa34099015aaa7c5ac90ecc/assets/adaptive-icon.png -------------------------------------------------------------------------------- /assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tayfunerbilen/react-native-instagram-ui-clone/1cdb93c1e3757efb8fa34099015aaa7c5ac90ecc/assets/favicon.png -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tayfunerbilen/react-native-instagram-ui-clone/1cdb93c1e3757efb8fa34099015aaa7c5ac90ecc/assets/icon.png -------------------------------------------------------------------------------- /assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tayfunerbilen/react-native-instagram-ui-clone/1cdb93c1e3757efb8fa34099015aaa7c5ac90ecc/assets/splash.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /components/shared/Post.js: -------------------------------------------------------------------------------- 1 | import {View, Text, Image, Dimensions, StyleSheet} from "react-native"; 2 | import {useState} from "react"; 3 | import {Heart, Comment, Message, More, Bookmark} from "../../icons"; 4 | import SeeMore from 'react-native-see-more-inline'; 5 | import { dayjs } from "../../utils" 6 | 7 | function Post({post}) { 8 | 9 | const [width, setWidth] = useState(0) 10 | const [height, setHeight] = useState(0) 11 | 12 | Image.getSize(post.image, (w, h) => { 13 | const screenWidth = Dimensions.get('window').width 14 | const scaleFactor = w / screenWidth 15 | const imageHeight = h / scaleFactor 16 | setWidth(screenWidth) 17 | setHeight(imageHeight) 18 | }) 19 | 20 | return ( 21 | 22 | 23 | 24 | 30 | {post.user.name} 31 | 32 | 33 | 34 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | {post.likes} likes 55 | 56 | 57 | {post.user.name} 58 | {' '} 59 | 60 | {post.description.split(' ').map(str => { 61 | if (str.includes('#')) { 62 | return {str} {' '} 63 | } 64 | return str + ' ' 65 | })} 66 | 67 | 68 | 69 | View all {post.comments} comments 70 | 71 | 72 | 73 | {dayjs(post.date).fromNow()} 74 | 75 | See Translation 76 | 77 | 78 | 79 | ) 80 | } 81 | 82 | export default Post 83 | 84 | const styles = StyleSheet.create({ 85 | header: { 86 | flexDirection: 'row', 87 | alignItems: 'center', 88 | justifyContent: 'space-between', 89 | paddingVertical: 15, 90 | paddingHorizontal: 10 91 | }, 92 | user: { 93 | flexDirection: 'row', 94 | alignItems: 'center' 95 | }, 96 | avatar: { 97 | width: 30, 98 | height: 30, 99 | borderRadius: 30, 100 | marginRight: 10 101 | }, 102 | image: {}, 103 | username: { 104 | fontSize: 14, 105 | fontWeight: '500' 106 | }, 107 | actions: { 108 | flexDirection: 'row', 109 | justifyContent: 'space-between', 110 | alignItems: 'center', 111 | paddingVertical: 10 112 | }, 113 | inner: { 114 | paddingHorizontal: 15 115 | }, 116 | likes: { 117 | fontWeight: '600', 118 | fontSize: 14 119 | }, 120 | postUser: { 121 | fontWeight: '600', 122 | fontSize: 14 123 | }, 124 | leftActions: { 125 | flexDirection: 'row', 126 | alignItems: 'center' 127 | }, 128 | icon: { 129 | marginRight: 15 130 | }, 131 | description: { 132 | fontSize: 14, 133 | fontWeight: 'normal' 134 | }, 135 | post: { 136 | marginBottom: 20 137 | }, 138 | comments: { 139 | opacity: 0.5 140 | }, 141 | time: { 142 | fontSize: 12, 143 | opacity: 0.5 144 | }, 145 | translation: { 146 | fontSize: 12, 147 | fontWeight: '600', 148 | paddingLeft: 10 149 | }, 150 | hashtag: { 151 | color: '#00376b' 152 | } 153 | }) 154 | -------------------------------------------------------------------------------- /data/posts.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | id: 1, 4 | description: `Saniye değerinizi "saat:dakika:saniye" formatına kolayca formatlamanız için bir ipucu, dilerseniz "11, 8" yerine "14, 5" yazarak sadece "dakika:saniye" formatını da döndürebilirsiniz. 5 | 6 | Video ya da müzik oynatıcısı yazarken mutlaka ihtiyaç duyarsınız, o zamanlarda bu postu hatırlayın :) 7 | 8 | #javascript #time`, 9 | image: 'https://instagram.fada1-15.fna.fbcdn.net/v/t51.2885-15/fr/e15/s1080x1080/269049551_1381361122320329_5806265218763602481_n.jpg?_nc_ht=instagram.fada1-15.fna.fbcdn.net&_nc_cat=105&_nc_ohc=K9Xcvc_ujhwAX90WrVJ&tn=kHwNFBbr5Fks2f5B&edm=AP_V10EBAAAA&ccb=7-4&oh=00_AT9gHKsOp_3GwPy5C1C4VbCXSUXRXRBTlp7yhVrW-_1SFg&oe=61CB69BB&_nc_sid=4f375e', 10 | likes: 309, 11 | comments: 4, 12 | date: '2021-12-24 00:10:14', 13 | user: { 14 | name: 'tayfunerbilen', 15 | avatar: 'https://pbs.twimg.com/profile_images/1469715048436277258/141ZXcHO_400x400.jpg' 16 | }, 17 | }, 18 | { 19 | id: 2, 20 | description: `hiçbir şey göründüğü gibi değil :)`, 21 | image: 'https://instagram.fada1-13.fna.fbcdn.net/v/t51.2885-15/e15/s640x640/259056325_1839402789571919_2029569847025834861_n.jpg?_nc_ht=instagram.fada1-13.fna.fbcdn.net&_nc_cat=111&_nc_ohc=qQYX4DBndSAAX-OpeUF&edm=AIQHJ4wBAAAA&ccb=7-4&ig_cache_key=MjcxMTc3NTQ2MTcxMzUzOTQwOQ%3D%3D.2-ccb7-4&oh=00_AT94zom2qS4GHVm4ECHyindZl3RXExCfSY-BB3gs4gIXpw&oe=61CB26E2&_nc_sid=7b02f1', 22 | likes: 101, 23 | comments: 23, 24 | date: '2021-12-23 14:22:13', 25 | user: { 26 | name: 'prototurk.official', 27 | avatar: 'https://instagram.fada1-12.fna.fbcdn.net/v/t51.2885-19/s150x150/84282248_2585093868401217_3175104158965432320_n.jpg?_nc_ht=instagram.fada1-12.fna.fbcdn.net&_nc_cat=109&_nc_ohc=DkmPVqQp7ngAX-kkJdi&edm=AP_V10EBAAAA&ccb=7-4&oh=00_AT8wncZepFvRhXXDF9_yBMxmumOxgBP5wbkc7qPs_AxZIA&oe=61CB01E1&_nc_sid=4f375e' 28 | }, 29 | }, 30 | { 31 | id: 3, 32 | description: `Görsellerin üzerinde transparan bir renk ekleyip onları biraz daha açık ya da koyu yapmak istediğinizde ::before ile eklemek yerine 2. bir renk olarak tanımlayıp kullanabilirsiniz. 33 | 34 | 1. resim -> orijinal 35 | 2. resim -> siyahın %60 transparan hali 36 | 3. resim -> beyazın %80 transparan hali`, 37 | image: 'https://instagram.fada1-15.fna.fbcdn.net/v/t51.2885-15/sh0.08/e35/s750x750/245365485_577611403439334_2523063214361865428_n.jpg?_nc_ht=instagram.fada1-15.fna.fbcdn.net&_nc_cat=106&_nc_ohc=UqEaPb0UX64AX-EhF04&edm=AP_V10EBAAAA&ccb=7-4&oh=00_AT_-2uXHoAFvfR4p-tRHxvJju6MnkYiM8N8E4h3XXNkumg&oe=61CB4E59&_nc_sid=4f375e', 38 | likes: 101, 39 | comments: 23, 40 | date: '2021-12-21 14:22:13', 41 | user: { 42 | name: 'prototurk.official', 43 | avatar: 'https://instagram.fada1-12.fna.fbcdn.net/v/t51.2885-19/s150x150/84282248_2585093868401217_3175104158965432320_n.jpg?_nc_ht=instagram.fada1-12.fna.fbcdn.net&_nc_cat=109&_nc_ohc=DkmPVqQp7ngAX-kkJdi&edm=AP_V10EBAAAA&ccb=7-4&oh=00_AT8wncZepFvRhXXDF9_yBMxmumOxgBP5wbkc7qPs_AxZIA&oe=61CB01E1&_nc_sid=4f375e' 44 | }, 45 | } 46 | ] 47 | -------------------------------------------------------------------------------- /home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tayfunerbilen/react-native-instagram-ui-clone/1cdb93c1e3757efb8fa34099015aaa7c5ac90ecc/home.png -------------------------------------------------------------------------------- /icons.js: -------------------------------------------------------------------------------- 1 | import Svg, {Path, Circle, Line, Rect, Polygon, Mask} from 'react-native-svg'; 2 | 3 | function Logo({size = 24, fill, ...props}) { 4 | return ( 5 | 6 | 10 | 11 | ) 12 | } 13 | 14 | function Home({size = 24, fill, ...props}) { 15 | return ( 16 | 17 | 24 | 25 | ) 26 | } 27 | 28 | function HomeFilled({size = 24, ...props}) { 29 | return ( 30 | 31 | 34 | 35 | ) 36 | } 37 | 38 | function Search({size = 24, fill, ...props}) { 39 | return ( 40 | 41 | 43 | 45 | 46 | ) 47 | } 48 | 49 | function SearchFilled({size = 24, ...props}) { 50 | return ( 51 | 52 | 54 | 55 | ) 56 | } 57 | 58 | function Reel({size = 24, fill, ...props}) { 59 | return ( 60 | 61 | 62 | 65 | 68 | 69 | ) 70 | } 71 | 72 | function ReelFilled({size = 24, fill, ...props}) { 73 | return ( 74 | 75 | 76 | 78 | 79 | 82 | 85 | 86 | ) 87 | } 88 | 89 | function Shop({size = 24, fill, ...props}) { 90 | return ( 91 | 92 | 95 | 98 | 101 | 102 | ) 103 | } 104 | 105 | function ShopFilled({size = 24, fill, ...props}) { 106 | return ( 107 | 108 | 111 | 114 | 115 | ) 116 | } 117 | 118 | function Plus({size = 24, fill, ...props}) { 119 | return ( 120 | 121 | 124 | 126 | 128 | 129 | ) 130 | } 131 | 132 | function Heart({size = 24, ...props}) { 133 | return ( 134 | 135 | 137 | 138 | ) 139 | } 140 | 141 | function Chat({size = 24, fill, ...props}) { 142 | return ( 143 | 144 | 146 | 149 | 150 | ) 151 | } 152 | 153 | function PlusOutline({size = 16, ...props}) { 154 | return ( 155 | 156 | 158 | 159 | ) 160 | } 161 | 162 | function Comment({size = 24, fill, ...props}) { 163 | return ( 164 | 165 | 167 | 168 | ) 169 | } 170 | 171 | function Message({size = 24, fill, ...props}) { 172 | return ( 173 | 174 | 176 | 178 | 179 | ) 180 | } 181 | 182 | function Bookmark({size = 24, fill, ...props}) { 183 | return ( 184 | 185 | 187 | 188 | ) 189 | } 190 | 191 | function More({size = 24, ...props}) { 192 | return ( 193 | 194 | 195 | 196 | 197 | 198 | ) 199 | } 200 | 201 | export { 202 | Home, 203 | HomeFilled, 204 | Search, 205 | SearchFilled, 206 | Reel, 207 | ReelFilled, 208 | Shop, 209 | ShopFilled, 210 | Logo, 211 | Plus, 212 | Heart, 213 | Chat, 214 | PlusOutline, 215 | Comment, 216 | Message, 217 | Bookmark, 218 | More 219 | } 220 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "web": "expo start --web", 8 | "eject": "expo eject" 9 | }, 10 | "dependencies": { 11 | "@react-navigation/bottom-tabs": "^6.0.9", 12 | "@react-navigation/native": "^6.0.6", 13 | "dayjs": "^1.10.7", 14 | "expo": "~44.0.0", 15 | "expo-linear-gradient": "~11.0.0", 16 | "expo-status-bar": "~1.2.0", 17 | "react": "17.0.1", 18 | "react-dom": "17.0.1", 19 | "react-native": "0.64.3", 20 | "react-native-safe-area-context": "3.3.2", 21 | "react-native-screens": "~3.10.1", 22 | "react-native-see-more-inline": "^1.3.0", 23 | "react-native-svg": "12.1.1", 24 | "react-native-text-size": "^4.0.0-rc.1", 25 | "react-native-web": "0.17.1" 26 | }, 27 | "devDependencies": { 28 | "@babel/core": "^7.12.9" 29 | }, 30 | "private": true 31 | } 32 | -------------------------------------------------------------------------------- /screens/home/components/Header.js: -------------------------------------------------------------------------------- 1 | import {Chat, Heart, Logo, Plus} from "../../../icons"; 2 | import {StyleSheet, View} from "react-native"; 3 | 4 | function Header() { 5 | return ( 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ) 24 | } 25 | 26 | export default Header 27 | 28 | const styles = StyleSheet.create({ 29 | header: { 30 | flexDirection: 'row', 31 | backgroundColor: '#fff', 32 | justifyContent: 'space-between', 33 | alignItems: 'center', 34 | paddingHorizontal: 20, 35 | paddingVertical: 10 36 | }, 37 | actions: { 38 | flexDirection: 'row' 39 | }, 40 | icon: { 41 | marginLeft: 20, 42 | position: 'relative' 43 | }, 44 | notification: { 45 | width: 8, 46 | height: 8, 47 | backgroundColor: '#FF3450', 48 | borderRadius: 100 49 | }, 50 | notificationContent: { 51 | position: 'absolute', 52 | top: -2, 53 | right: -2, 54 | backgroundColor: '#fff', 55 | padding: 1.5 56 | } 57 | }) 58 | -------------------------------------------------------------------------------- /screens/home/components/Stories.js: -------------------------------------------------------------------------------- 1 | import {StyleSheet, View, ScrollView, Text, Image} from "react-native"; 2 | import {LinearGradient} from 'expo-linear-gradient'; 3 | import { PlusOutline } from "../../../icons"; 4 | 5 | function Stories() { 6 | 7 | const user = { 8 | name: 'Tayfun Erbilen', 9 | avatar: 'https://pbs.twimg.com/profile_images/1469715048436277258/141ZXcHO_400x400.jpg', 10 | hasStory: false 11 | } 12 | 13 | const items = [ 14 | { 15 | id: 2, 16 | avatar: 'https://pbs.twimg.com/profile_images/1455707950341890051/flRfKMOq_400x400.jpg', 17 | user: 'Nacho Iacovino' 18 | }, 19 | { 20 | id: 3, 21 | avatar: 'https://pbs.twimg.com/profile_images/557940120184041473/bFyXy8Pu_400x400.jpeg', 22 | user: 'Rich Harris' 23 | }, 24 | { 25 | id: 4, 26 | avatar: 'https://pbs.twimg.com/profile_images/1439602105107443714/Vpb3Ra1K_400x400.jpg', 27 | user: 'Taylor Otwell' 28 | }, 29 | { 30 | id: 5, 31 | avatar: 'https://pbs.twimg.com/profile_images/1262107495037796359/N_HoUfGz_400x400.jpg', 32 | user: 'Galen Gidman' 33 | }, 34 | { 35 | id: 6, 36 | avatar: 'https://pbs.twimg.com/profile_images/1458081709291868178/7bFb7AbF_400x400.jpg', 37 | user: 'Scott Jehl' 38 | }, 39 | { 40 | id: 7, 41 | avatar: 'https://pbs.twimg.com/profile_images/1266007237874647044/-JqTQ_14_400x400.jpg', 42 | user: 'Ildiko Gaspar' 43 | }, 44 | { 45 | id: 8, 46 | avatar: 'https://pbs.twimg.com/profile_images/1323356199945859072/oJM0cDPb_400x400.png', 47 | user: 'Joel Thoms' 48 | }, 49 | { 50 | id: 9, 51 | avatar: 'https://pbs.twimg.com/profile_images/1386085325647265801/-w1nECc4_400x400.jpg', 52 | user: 'Emir Karşıyakalı' 53 | }, 54 | { 55 | id: 10, 56 | avatar: 'https://pbs.twimg.com/profile_images/958997253892419586/Jb6NPqEa_400x400.jpg', 57 | user: 'Selman Kaya' 58 | } 59 | ] 60 | 61 | return ( 62 | 63 | 67 | 71 | 75 | 81 | 82 | {!user.hasStory && } 83 | Your Story 84 | 85 | {items.map((item, key) => ( 86 | 87 | 91 | 97 | 98 | {item.user} 99 | 100 | ))} 101 | 102 | 103 | ) 104 | } 105 | 106 | export default Stories 107 | 108 | const styles = StyleSheet.create({ 109 | container: { 110 | paddingLeft: 0, 111 | paddingRight: 0, 112 | borderBottomWidth: 0.5, 113 | borderBottomColor: '#DBDBDB', 114 | paddingBottom: 10 115 | }, 116 | story: { 117 | width: 68, 118 | marginRight: 15, 119 | position: 'relative' 120 | }, 121 | avatarParent: { 122 | width: 68, 123 | height: 68, 124 | borderRadius: 34, 125 | padding: 2, 126 | }, 127 | plus: { 128 | position: 'absolute', 129 | bottom: 20, 130 | right: 0, 131 | padding: 3, 132 | borderRadius: 25, 133 | backgroundColor: '#fff' 134 | }, 135 | avatar: { 136 | width: 64, 137 | height: 64, 138 | borderWidth: 2, 139 | borderColor: '#fff', 140 | borderRadius: 64 141 | }, 142 | title: { 143 | fontSize: 13, 144 | marginTop: 3, 145 | textAlign: 'center' 146 | } 147 | }) 148 | -------------------------------------------------------------------------------- /screens/home/index.js: -------------------------------------------------------------------------------- 1 | import {View, Text, RefreshControl, ScrollView, StyleSheet} from "react-native"; 2 | import Header from "./components/Header"; 3 | import Stories from "./components/Stories"; 4 | import Post from "../../components/shared/Post"; 5 | import posts from "../../data/posts"; 6 | import {useCallback, useState} from "react"; 7 | 8 | const wait = (timeout) => { 9 | return new Promise(resolve => setTimeout(resolve, timeout)); 10 | } 11 | 12 | function Home() { 13 | 14 | const [refreshing, setRefreshing] = useState(false); 15 | 16 | const onRefresh = useCallback(() => { 17 | setRefreshing(true); 18 | wait(2000).then(() => setRefreshing(false)); 19 | }, []); 20 | 21 | return ( 22 | 23 |
24 | 30 | } 31 | > 32 | 33 | {posts && posts.map(post => ( 34 | 35 | ))} 36 | 37 | 38 | ) 39 | } 40 | 41 | export default Home 42 | 43 | const styles = StyleSheet.create({ 44 | container: { 45 | flex: 1, 46 | backgroundColor: '#fff' 47 | } 48 | }) 49 | -------------------------------------------------------------------------------- /screens/profile/index.js: -------------------------------------------------------------------------------- 1 | import {View, Text, StyleSheet} from "react-native"; 2 | 3 | function Search() { 4 | return ( 5 | 6 | Profile 7 | 8 | ) 9 | } 10 | 11 | export default Search 12 | 13 | const styles = StyleSheet.create({ 14 | container: { 15 | flex: 1, 16 | backgroundColor: '#fff' 17 | } 18 | }) 19 | -------------------------------------------------------------------------------- /screens/reel/index.js: -------------------------------------------------------------------------------- 1 | import {View, Text, StyleSheet} from "react-native"; 2 | 3 | function Search() { 4 | return ( 5 | 6 | Reel 7 | 8 | ) 9 | } 10 | 11 | export default Search 12 | 13 | const styles = StyleSheet.create({ 14 | container: { 15 | flex: 1, 16 | backgroundColor: '#fff' 17 | } 18 | }) 19 | -------------------------------------------------------------------------------- /screens/search/index.js: -------------------------------------------------------------------------------- 1 | import {View, Text, StyleSheet} from "react-native"; 2 | 3 | function Search() { 4 | return ( 5 | 6 | Search 7 | 8 | ) 9 | } 10 | 11 | export default Search 12 | 13 | const styles = StyleSheet.create({ 14 | container: { 15 | flex: 1, 16 | backgroundColor: '#fff' 17 | } 18 | }) 19 | -------------------------------------------------------------------------------- /screens/shop/index.js: -------------------------------------------------------------------------------- 1 | import {View, Text, StyleSheet} from "react-native"; 2 | 3 | function Search() { 4 | return ( 5 | 6 | Shop 7 | 8 | ) 9 | } 10 | 11 | export default Search 12 | 13 | const styles = StyleSheet.create({ 14 | container: { 15 | flex: 1, 16 | backgroundColor: '#fff' 17 | } 18 | }) 19 | -------------------------------------------------------------------------------- /utils.js: -------------------------------------------------------------------------------- 1 | import dayjs from "dayjs"; 2 | import relativeTime from "dayjs/plugin/relativeTime" 3 | dayjs.extend(relativeTime) 4 | 5 | export { 6 | dayjs 7 | } 8 | --------------------------------------------------------------------------------