import React, { useEffect, useMemo } from 'react' import { useAsync } from 'react-async-hook' import { useTranslation } from 'react-i18next' import { FlatList, ListRenderItemInfo, StyleSheet, Text, View } from 'react-native' import AppAnalytics from 'src/analytics/AppAnalytics' import { CeloNewsEvents } from 'src/analytics/Events' import { celoNewsConfigSelector } from 'src/app/selectors' import CeloNewsFeedItem from 'src/celoNews/CeloNewsFeedItem' import { CeloNewsArticle, CeloNewsArticles } from 'src/celoNews/types' import Button, { BtnSizes, BtnTypes } from 'src/components/Button' import EmptyView from 'src/components/EmptyView' import { navigate } from 'src/navigator/NavigationService' import { Screens } from 'src/navigator/Screens' import { useSelector } from 'src/redux/hooks' import colors from 'src/styles/colors' import { typeScale } from 'src/styles/fonts' import { Spacing } from 'src/styles/styles' import Logger from 'src/utils/Logger' import { fetchWithTimeout } from 'src/utils/fetchWithTimeout' import networkConfig from 'src/web3/networkConfig' const TAG = 'exchange/CeloNewsFeed' const LOADING_SKELETON_DATA = Array.from({ length: 5 }).map( // This bypasses the type check, but it's fine because we're just using it for the skeleton (_, i) => ({ id: i }) as CeloNewsArticle ) function renderItem({ item: article }: ListRenderItemInfo) { return } function keyExtractor(item: CeloNewsArticle) { return item.id.toString() } function ItemSeparator() { return } export function useFetchArticles() { return useAsync(async () => { Logger.info(TAG, 'Fetching articles...') try { const response = await fetchWithTimeout(networkConfig.getCeloNewsFeedUrl) Logger.info(TAG, `Articles fetched (statusCode=${response.status})`) // status in the range 200-299 if (!response.ok) { throw new Error(`Failed to fetch articles: ${response.status} ${response.statusText}`) } const data = await response.json() return data as CeloNewsArticles } catch (error) { Logger.error(TAG, 'Failed to fetch articles', error) throw error } }, []) } export default function CeloNewsFeed() { const { t } = useTranslation() const asyncArticles = useFetchArticles() const { readMoreUrl } = useSelector(celoNewsConfigSelector) const isLoading = asyncArticles.status === 'loading' useEffect(() => { AppAnalytics.track(CeloNewsEvents.celo_news_screen_open) }, []) function onPressReadMore() { const url = readMoreUrl if (!url) { // This shouldn't happen since the button is only visible if the URL is set return } AppAnalytics.track(CeloNewsEvents.celo_news_bottom_read_more_tap, { url }) navigate(Screens.WebViewScreen, { uri: url }) } function onPressRetry() { AppAnalytics.track(CeloNewsEvents.celo_news_retry_tap) void asyncArticles.execute() } const footer = useMemo(() => { switch (asyncArticles.status) { case 'success': if (!readMoreUrl) { return null } return ( <>