diff --git a/news_app/app/Components/HomeCategory.js b/news_app/app/Components/HomeCategory.js index 167550d..f82f16e 100644 --- a/news_app/app/Components/HomeCategory.js +++ b/news_app/app/Components/HomeCategory.js @@ -1,11 +1,19 @@ import { View, Text, FlatList, Pressable, StyleSheet} from 'react-native' import React, { useState } from 'react' +import { useFonts } from 'expo-font'; + +const HomeCategory = ({selectCategory}) => { + useFonts({ + 'playFairBold': require('../../assets/fonts/PlayfairDisplay-Bold.ttf'), + 'playFair': require('../../assets/fonts/PlayfairDisplay-Regular.ttf') + }) -const HomeCategory = () => { const [active, setActive] = useState(1); const onCategoryClick = (id) => { setActive(id); } + //category + const category = [ { id: 1, @@ -40,10 +48,12 @@ const HomeCategory = () => { name: 'Sports' }, ] + + return ( ( - onCategoryClick(item.id)}> + {onCategoryClick(item.id); selectCategory(item.name)}}> {item.name} @@ -58,14 +68,16 @@ const styles= StyleSheet.create({ marginRight: 10, fontSize: 18, padding: 10, - color: "#45474B" + color: "#45474B", + fontFamily: 'playFair' }, selectTopic:{ marginRight: 10, fontSize: 20, fontWeight: '700', padding: 10, - color: "black" + color: "black", + fontFamily: 'playFairBold' } }) diff --git a/news_app/app/Components/HomeHeadlineList.js b/news_app/app/Components/HomeHeadlineList.js new file mode 100644 index 0000000..afacf5f --- /dev/null +++ b/news_app/app/Components/HomeHeadlineList.js @@ -0,0 +1,33 @@ +import { View, Text, FlatList, Pressable, Image } from 'react-native' +import React, { useEffect, useState } from 'react' +import { useFonts } from 'expo-font'; +import globalAPI from '../Service/globalAPI'; +import { useNavigation } from 'expo-router'; + +const HomeHeadlineList = ({newsList}) => { + const navigation = useNavigation(); + + useFonts({ + 'playFairBold': require('../../assets/fonts/PlayfairDisplay-Bold.ttf'), + 'playFair': require('../../assets/fonts/PlayfairDisplay-Regular.ttf') + }) + + return ( + + ( + <> + navigation.navigate('news', {news:item})} style={{padding: 5, display: "flex", flexDirection: "row"}}> + + + {item.title} + {item?.source?.name} + + + + + )}/> + + ) +} + +export default HomeHeadlineList \ No newline at end of file diff --git a/news_app/app/Components/HomeTopHeadline.js b/news_app/app/Components/HomeTopHeadline.js index 15b2ee8..00fcdcb 100644 --- a/news_app/app/Components/HomeTopHeadline.js +++ b/news_app/app/Components/HomeTopHeadline.js @@ -2,28 +2,33 @@ import { View, Text, FlatList, Pressable, Image, Dimensions } from 'react-native import React, { useEffect, useState } from 'react' import GlobalAPI from '../Service/globalAPI' import { useFonts } from 'expo-font' +import { useNavigation } from '@react-navigation/native' const HomeTopHeadline = () => { - useFonts({ - 'playFairBold': require('../../assets/fonts/PlayfairDisplay-Bold.ttf') - }) - const [newsList, setNewsList] = useState([]); - useEffect(() => { - getTopHeadline(); - }, []) + const navigation = useNavigation(); + + useFonts({ + 'playFairBold': require('../../assets/fonts/PlayfairDisplay-Bold.ttf'), + 'playFair': require('../../assets/fonts/PlayfairDisplay-Regular.ttf') + }) - const getTopHeadline = async() => { - const result = (await GlobalAPI.getTopHeadline).data; - setNewsList(result.articles) - } + const [newsList, setNewsList] = useState([]); + useEffect(() => { + getTopHeadline(); + }, []) + + const getTopHeadline = async() => { + const result = (await GlobalAPI.getTopHeadline).data; + setNewsList(result.articles) + } return ( ( - - + navigation.navigate('news', {news:item})} style={{width:Dimensions.get('screen').width*0.95, marginRight: 10, marginTop: 5, marginBottom: 5}}> + - {item.title} + {item.title} {item?.source?.name} diff --git a/news_app/app/Navigation/HomeNavigator.js b/news_app/app/Navigation/HomeNavigator.js new file mode 100644 index 0000000..4c923b9 --- /dev/null +++ b/news_app/app/Navigation/HomeNavigator.js @@ -0,0 +1,17 @@ +import { createStackNavigator } from '@react-navigation/stack'; +import Home from '../Screen/Home' +import News from '../Screen/News' + + +const Stack = createStackNavigator(); + +const HomeNavigator = () => { + return ( + + + + + ) +} + +export default HomeNavigator \ No newline at end of file diff --git a/news_app/app/Screen/Home.js b/news_app/app/Screen/Home.js index afd465b..f0c5f6c 100644 --- a/news_app/app/Screen/Home.js +++ b/news_app/app/Screen/Home.js @@ -1,19 +1,46 @@ -import { View, Text, SafeAreaView } from 'react-native'; -import React from 'react'; +import { View, Text, ScrollView, ActivityIndicator} from 'react-native'; +import React, { useEffect, useState } from 'react'; import HomeCategory from "../Components/HomeCategory"; import HomeTopHeadline from "../Components/HomeTopHeadline"; +import HomeHeadlineList from "../Components/HomeHeadlineList"; import {useFonts} from 'expo-font' +import globalAPI from '../Service/globalAPI'; const Home = () => { - useFonts({ - 'playFairBold': require('../../assets/fonts/PlayfairDisplay-Bold.ttf') - }) + useFonts({ + 'playFairBold': require('../../assets/fonts/PlayfairDisplay-Bold.ttf') + }) + + const [newsList, setNewsList] = useState([]); + const [loading, setLoading] = useState(true) + useEffect(() => { + getTopHeadline(); + getByCategory('latest'); + }, []) + //get all + const getTopHeadline = async() => { + const result = (await globalAPI.getTopHeadline).data; + setNewsList(result.articles) + } + //get by category + const getByCategory = async(category) => { + setLoading(true); + const result = (await globalAPI.getByCategory(category)).data; + setNewsList(result.articles) + setLoading(false); + } + return ( - - The Quick News - - - + + {loading? < ActivityIndicator size={'large'} style={{color: "gray"}}/> : + + The Quick News + getByCategory(category)}/> + + + + } + ) } diff --git a/news_app/app/Screen/News.js b/news_app/app/Screen/News.js new file mode 100644 index 0000000..59c058e --- /dev/null +++ b/news_app/app/Screen/News.js @@ -0,0 +1,55 @@ +import { View, Text, Image, Pressable, Linking, Share } from 'react-native' +import React, { useEffect } from 'react' +import { useRoute } from '@react-navigation/native' +import { useFonts } from 'expo-font' +import { Ionicons, Fontisto } from '@expo/vector-icons'; +import { useNavigation } from 'expo-router'; +import { ScrollView } from 'react-native-gesture-handler'; + +const News = () => { + useFonts({ + 'playFairBold': require('../../assets/fonts/PlayfairDisplay-Bold.ttf') + }) + const news = useRoute().params.news; + const navigation=useNavigation(); + //share news + const shareLink = () => { + Share.share({url: news.url}) + } + useEffect(() => { + console.log(news) + },[]) + //Time + const publishedDate = news.publishedAt; + const newInputDate = publishedDate.replace("T", " ").replace("Z", " "); + //url + const url = news.url + + return ( + + + navigation.goBack()} style={{display: "flex", flexDirection: "row", alignItems: 'center', gap: 5}}> + + Back + + shareLink()}> + + + + + + {news.title} + {news.source.name} {news.author} + {newInputDate} + + + {news.description} + {news.content} + Linking.openURL(url)} > + Read More + + + ) +} + +export default News \ No newline at end of file diff --git a/news_app/app/Service/globalAPI.js b/news_app/app/Service/globalAPI.js index 5640119..7554844 100644 --- a/news_app/app/Service/globalAPI.js +++ b/news_app/app/Service/globalAPI.js @@ -5,7 +5,12 @@ const api = create({ }) const APIKey = process.env.EXPO_PUBLIC_API_KEY; +const API_KEY_ALL = process.env.EXPO_PUBLIC_API_KEY_ALL; + const getTopHeadline = api.get('/top-headlines'+APIKey); +const getByCategory = (category)=>api.get('/everything?q='+category+API_KEY_ALL); + export default{ - getTopHeadline + getTopHeadline, + getByCategory } diff --git a/news_app/app/index.js b/news_app/app/index.js index 7dc4656..36a1a6a 100644 --- a/news_app/app/index.js +++ b/news_app/app/index.js @@ -1,12 +1,19 @@ -import { SafeAreaView, Text, View } from "react-native"; -import Home from "./Screen/Home" +import { KeyboardAvoidingView, SafeAreaView, View} from "react-native"; +import { NavigationContainer } from '@react-navigation/native'; +import HomeNavigator from './Navigation/HomeNavigator' + export default function Index() { + return ( - - - - - + + + + + + + + + ); } diff --git a/news_app/package-lock.json b/news_app/package-lock.json index ad485c8..b33e0e7 100644 --- a/news_app/package-lock.json +++ b/news_app/package-lock.json @@ -9,7 +9,8 @@ "version": "1.0.0", "dependencies": { "@expo/vector-icons": "^14.0.2", - "@react-navigation/native": "^6.0.2", + "@react-navigation/native": "^6.1.18", + "@react-navigation/stack": "^6.4.1", "apisauce": "^3.0.1", "expo": "~51.0.21", "expo-constants": "~16.0.2", @@ -6311,6 +6312,24 @@ "nanoid": "^3.1.23" } }, + "node_modules/@react-navigation/stack": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.4.1.tgz", + "integrity": "sha512-upMEHOKMtuMu4c9gmoPlO/JqI6mDlSqwXg1aXKOTQLXAF8H5koOLRfrmi7AkdiE9A7lDXWUAZoGuD9O88cYvDQ==", + "dependencies": { + "@react-navigation/elements": "^1.3.31", + "color": "^4.2.3", + "warn-once": "^0.1.0" + }, + "peerDependencies": { + "@react-navigation/native": "^6.0.0", + "react": "*", + "react-native": "*", + "react-native-gesture-handler": ">= 1.0.0", + "react-native-safe-area-context": ">= 3.0.0", + "react-native-screens": ">= 3.0.0" + } + }, "node_modules/@remix-run/node": { "version": "2.10.3", "resolved": "https://registry.npmjs.org/@remix-run/node/-/node-2.10.3.tgz", diff --git a/news_app/package.json b/news_app/package.json index 28dd95c..2f99d47 100644 --- a/news_app/package.json +++ b/news_app/package.json @@ -16,7 +16,8 @@ }, "dependencies": { "@expo/vector-icons": "^14.0.2", - "@react-navigation/native": "^6.0.2", + "@react-navigation/native": "^6.1.18", + "@react-navigation/stack": "^6.4.1", "apisauce": "^3.0.1", "expo": "~51.0.21", "expo-constants": "~16.0.2",