updated app

This commit is contained in:
Juthatip McDevitt 2024-07-20 13:48:56 -05:00
parent d7286377f1
commit 1eee5aa334
10 changed files with 219 additions and 38 deletions

View file

@ -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 (
<View style={{borderWidth: 2, borderColor: "#EEEDEB"}}>
<FlatList data={category} horizontal renderItem={({item}) => (
<Pressable onPress={() => onCategoryClick(item.id)}>
<Pressable onPress={() => {onCategoryClick(item.id); selectCategory(item.name)}}>
<View style={{backgroundColor: "#F5F7F8",borderWidth: 1 ,borderColor: "white"}}>
<Text style={item.id == active? styles.selectTopic : styles.notSelectTopic}>{item.name}</Text>
</View>
@ -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'
}
})

View file

@ -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 (
<View>
<FlatList data={newsList} renderItem={({item}) => (
<>
<Pressable onPress={() => navigation.navigate('news', {news:item})} style={{padding: 5, display: "flex", flexDirection: "row"}}>
<Image source={{uri:item.urlToImage}} style={{height: 120, width: 120}}/>
<View style={{marginLeft: 5, marginRight: 130}}>
<Text numberOfLines={3} style={{marginTop: 5, fontSize: 16, fontFamily: 'playFairBold'}}>{item.title}</Text>
<Text style={{marginTop: 5,color: "gray"}}>{item?.source?.name}</Text>
</View>
</Pressable>
<View style={{height:1, backgroundColor: "gray", marginHorizontal: 5}}></View>
</>
)}/>
</View>
)
}
export default HomeHeadlineList

View file

@ -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 (
<View>
<FlatList data={newsList} horizontal showsHorizontalScrollIndicator={false} renderItem={({item}) => (
<Pressable style={{width:Dimensions.get('screen').width*0.95, marginRight: 10, marginTop: 5, marginBottom: 20}}>
<Image source={{uri:item.urlToImage}} style={{height: 350}}/>
<Pressable onPress={() => navigation.navigate('news', {news:item})} style={{width:Dimensions.get('screen').width*0.95, marginRight: 10, marginTop: 5, marginBottom: 5}}>
<Image source={{uri:item.urlToImage}} style={{height: 300}}/>
<View style={{backgroundColor: "#F5F7F8", padding: 10}}>
<Text style={{marginTop: 5, fontSize: 20, fontFamily: 'playFairBold'}}>{item.title}</Text>
<Text numberOfLines={2} style={{marginTop: 5, fontSize: 22, fontFamily: 'playFairBold'}}>{item.title}</Text>
<Text style={{marginTop: 5, color: "gray"}}>{item?.source?.name}</Text>
</View>
</Pressable>

View file

@ -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 (
<Stack.Navigator screenOptions={{headerShown: false}}>
<Stack.Screen name='home' component={Home} />
<Stack.Screen name='news' component={News} />
</Stack.Navigator>
)
}
export default HomeNavigator

View file

@ -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 (
<View>
<Text style={{fontSize: 32, fontFamily: 'playFairBold', color: "#000000", textAlign: "center", marginBottom: 20}}>The Quick News</Text>
<HomeCategory/>
<HomeTopHeadline/>
</View>
<ScrollView style={{backgroundColor: "white"}}>
{loading? < ActivityIndicator size={'large'} style={{color: "gray"}}/> :
<View>
<Text style={{marginTop: 10, fontSize: 32, fontFamily: 'playFairBold', color: "#000000", textAlign: "center", marginBottom: 20}}>The Quick News</Text>
<HomeCategory selectCategory={(category) => getByCategory(category)}/>
<HomeTopHeadline newsList={newsList}/>
<HomeHeadlineList newsList={newsList}/>
</View>
}
</ScrollView>
)
}

View file

@ -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 (
<ScrollView style={{backgroundColor: "white", height: "100%"}}>
<View style={{display: "flex", flexDirection: "row", justifyContent: "space-between", marginHorizontal: 10, marginVertical: 10}}>
<Pressable onPress={() => navigation.goBack()} style={{display: "flex", flexDirection: "row", alignItems: 'center', gap: 5}}>
<Ionicons name="arrow-back-outline" size={24} color="black" />
<Text>Back</Text>
</Pressable>
<Pressable onPress={() => shareLink()}>
<Fontisto name="share" size={20} color="black" />
</Pressable>
</View>
<View style={{height:1, backgroundColor: "gray", marginHorizontal: 5}}></View>
<View style={{marginHorizontal: 10, marginVertical: 20}}>
<Text style={{fontSize: 24, fontFamily: 'playFairBold'}}>{news.title}</Text>
<Text style={{marginTop: 20, color: "gray"}}><Text style={{fontWeight: "bold", color: "black"}}>{news.source.name} </Text>{news.author}</Text>
<Text style={{marginTop: 5, color: "gray"}}>{newInputDate}</Text>
</View>
<Image source={{uri:news.urlToImage}} style={{height: 300, marginHorizontal: 10,}}/>
<Text style={{marginHorizontal: 10, marginTop: 40, marginBottom: 20,fontSize: 18}}>{news.description}</Text>
<Text numberOfLines={4} style={{marginHorizontal: 10,fontSize: 18}}>{news.content}</Text>
<Pressable onPress={() => Linking.openURL(url)} >
<Text style={{marginTop: 20, marginHorizontal: 10,fontSize: 18, color: "gray"}}>Read More</Text>
</Pressable>
</ScrollView>
)
}
export default News

View file

@ -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
}

View file

@ -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 (
<SafeAreaView>
<View>
<Home/>
</View>
</SafeAreaView>
<NavigationContainer independent={true}>
<KeyboardAvoidingView>
<View style={{height: '100%', width: '100%'}}>
<HomeNavigator/>
</View>
</KeyboardAvoidingView>
</NavigationContainer>
);
}

View file

@ -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",

View file

@ -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",