diff --git a/src/components/notification/view/notificationView.tsx b/src/components/notification/view/notificationView.tsx index 2c2738710..1c99a4d51 100644 --- a/src/components/notification/view/notificationView.tsx +++ b/src/components/notification/view/notificationView.tsx @@ -47,14 +47,13 @@ class NotificationView extends PureComponent { // Component Functions _handleOnDropdownSelect = async (index) => { - const { getActivities, changeSelectedFilter, } = this.props; + const { changeSelectedFilter, } = this.props; const { filters, contentOffset } = this.state; const _selectedFilter = filters[index].key; this.setState({ selectedFilter: _selectedFilter, selectedIndex: index, contentOffset }); await changeSelectedFilter(_selectedFilter, index); - getActivities(_selectedFilter, false); this.listRef.current?.scrollToOffset({ x: 0, y: 0, animated: false }); }; @@ -228,7 +227,7 @@ class NotificationView extends PureComponent { ref={this.listRef} data={_notifications} keyExtractor={(item, index) => `${item.id}-${index}`} - onEndReached={() => getActivities(selectedFilter, true)} + onEndReached={() => getActivities(true)} onEndReachedThreshold={0.3} ListFooterComponent={this._renderFooterLoading} ListEmptyComponent={ @@ -242,7 +241,7 @@ class NotificationView extends PureComponent { refreshControl={ getActivities(selectedFilter)} + onRefresh={() => getActivities()} progressBackgroundColor="#357CE6" tintColor={!isDarkTheme ? '#357ce6' : '#96c0ff'} titleColor="#fff" diff --git a/src/providers/ecency/ecency.ts b/src/providers/ecency/ecency.ts index b9c3a33fc..feb22420f 100644 --- a/src/providers/ecency/ecency.ts +++ b/src/providers/ecency/ecency.ts @@ -7,7 +7,7 @@ import serverList from '../../config/serverListApi'; import { SERVER_LIST } from '../../constants/options/api'; import { parsePost } from '../../utils/postParser'; import { convertCommentHistory, convertLatestQuotes, convertReferral, convertReferralStat } from './converters'; -import { CommentHistoryItem, LatestMarketPrices, ReceivedVestingShare, Referral, ReferralStat } from './ecency.types'; +import { CommentHistoryItem, LatestMarketPrices, NotificationFilters, ReceivedVestingShare, Referral, ReferralStat } from './ecency.types'; @@ -424,8 +424,9 @@ export const getLeaderboard = async (duration: 'day' | 'week' | 'month') => { * @returns array of notifications */ export const getNotifications = async (data: { - filter?: "rvotes" | "mentions" | "follows" | "replies" | "reblogs" | "transfers" | "delegations", - since?: string + filter?: NotificationFilters, + since?: string, + limit?: number, }) => { try { const response = await ecencyApi.post(`/private-api/notifications`, data); diff --git a/src/providers/ecency/ecency.types.ts b/src/providers/ecency/ecency.types.ts index 571cfe098..c41636891 100644 --- a/src/providers/ecency/ecency.types.ts +++ b/src/providers/ecency/ecency.types.ts @@ -56,4 +56,15 @@ export enum ScheduledPostStatus { POSTPONED = 2, PUBLISHED = 3, ERROR = 4, +} + +export enum NotificationFilters { + ACTIVITIES = "activities", + RVOTES = "rvotes", + MENTIONS = "mentions", + FOLLOWS = "follows", + REPLIES = "replies", + REBLOGS = "reblogs", + TRANFERS = "transfers", + DELEGATIONS = "delegations" } \ No newline at end of file diff --git a/src/providers/queries/index.ts b/src/providers/queries/index.ts index 9a9705790..15c4e4553 100644 --- a/src/providers/queries/index.ts +++ b/src/providers/queries/index.ts @@ -22,3 +22,7 @@ export const initQueryClient = () => { persistOptions: { persister: asyncStoragePersister }, } as PersistQueryClientProviderProps; }; + + +export * from "./notificationQueries"; + diff --git a/src/providers/queries/notificationQueries.ts b/src/providers/queries/notificationQueries.ts new file mode 100644 index 000000000..8c1320c58 --- /dev/null +++ b/src/providers/queries/notificationQueries.ts @@ -0,0 +1,32 @@ +import { useQuery } from "@tanstack/react-query"; +import { getNotifications } from "../ecency/ecency"; +import { NotificationFilters } from "../ecency/ecency.types"; +import QUERIES from "./queryKeys"; + + +export const useNotificationsQuery = ( filter : NotificationFilters) => { + return useQuery([QUERIES.NOTIFICATIONS.GET, filter], async () => { + const resonse = getNotifications({ filter, since: undefined, limit: 20 }) + return resonse || [] + // const lastId = res.length > 0 ? [...res].pop().id : null; + + // if (loadMore && (lastId === lastNotificationId || res.length === 0)) { + // setEndOfNotification(true); + // setIsRefershing(false); + // setIsLoading(false); + // } else { + // console.log(''); + // const stateNotifications = notificationsMap.get(type) || []; + // const _notifications = loadMore + // ? unionBy(stateNotifications, res, 'id') + // : loadUnread + // ? unionBy(res, stateNotifications, 'id') + // : res; + // notificationsMap.set(type, _notifications); + // setNotificationsMap(notificationsMap); + // setLastNotificationId(lastId); + // setIsRefershing(false); + // setIsLoading(false); + // } + }); +} diff --git a/src/providers/queries/queryKeys.ts b/src/providers/queries/queryKeys.ts index f0195924d..598e2f5c0 100644 --- a/src/providers/queries/queryKeys.ts +++ b/src/providers/queries/queryKeys.ts @@ -5,6 +5,9 @@ const QUERIES = { SCHEDULES: { GET: 'QUERY_GET_SCHEDULES', }, + NOTIFICATIONS:{ + GET: 'QERUY_GET_NOTIFICATIONS' + } }; export default QUERIES; diff --git a/src/screens/notification/container/notificationContainer.tsx b/src/screens/notification/container/notificationContainer.tsx index 67d0df1ef..3ede3502a 100644 --- a/src/screens/notification/container/notificationContainer.tsx +++ b/src/screens/notification/container/notificationContainer.tsx @@ -1,6 +1,6 @@ /* eslint-disable react/no-unused-state */ import React, { useRef, useState } from 'react'; -import { Alert } from 'react-native'; +import { Alert, Button } from 'react-native'; import { useDispatch } from 'react-redux'; import get from 'lodash/get'; import { useIntl } from 'react-intl'; @@ -20,10 +20,16 @@ import { showProfileModal } from '../../../redux/actions/uiAction'; import { markHiveNotifications } from '../../../providers/hive/dhive'; import bugsnapInstance from '../../../config/bugsnag'; import { useAppSelector } from '../../../hooks'; +import { useNotificationsQuery } from '../../../providers/queries'; +import { NotificationFilters } from '../../../providers/ecency/ecency.types'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; +import QUERIES from '../../../providers/queries/queryKeys'; +import { SafeAreaView } from 'react-native-safe-area-context'; const NotificationContainer = ({ navigation }) => { const intl = useIntl(); const dispatch = useDispatch(); + const queryClient = useQueryClient(); const isLoggedIn = useAppSelector((state) => state.application.isLoggedIn); const isConnected = useAppSelector((state) => state.application.isConnected); @@ -37,65 +43,81 @@ const NotificationContainer = ({ navigation }) => { const [lastNotificationId, setLastNotificationId] = useState(null); const [isRefreshing, setIsRefershing] = useState(false); const [isLoading, setIsLoading] = useState(false); - const [selectedFilter, setSelectedFilter] = useState('activities'); + const [selectedFilter, setSelectedFilter] = useState(NotificationFilters.ACTIVITIES); const [endOfNotification, setEndOfNotification] = useState(false); + const notificationsQuery = useNotificationsQuery(selectedFilter) + useEffect(() => { setEndOfNotification(false); setNotificationsMap(new Map()); - _getActivities(selectedFilter); + // _getActivities(selectedFilter); + notificationsQuery.refetch(); + //TODO: later invalidate all queries on logout or account switch using query client }, [currentAccount.username]); useEffect(() => { if (currentAccount.unread_activity_count > unreadCountRef.current) { - notificationsMap.forEach((value, key) => { - console.log('fetching new activities for ', key); - _getActivities(key, false, true); - }); + queryClient.refetchQueries([QUERIES.NOTIFICATIONS.GET]); //refetches all cahced quries starting with given ke + //TODO: handle new notification received, either invalidate filters or add data above } unreadCountRef.current = currentAccount.unread_activity_count; }, [currentAccount.unread_activity_count]); - const _getActivities = (type = 'activities', loadMore = false, loadUnread = false) => { - const since = loadMore ? lastNotificationId : null; - if (isLoading) { - return; - } - if (!endOfNotification || !loadMore || loadUnread) { - setIsLoading(true); - setIsRefershing(!loadMore); - getNotifications({ filter: type, since: since, limit: 20 }) - .then((res) => { - const lastId = res.length > 0 ? [...res].pop().id : null; - if (loadMore && (lastId === lastNotificationId || res.length === 0)) { - setEndOfNotification(true); - setIsRefershing(false); - setIsLoading(false); - } else { - console.log(''); - const stateNotifications = notificationsMap.get(type) || []; - const _notifications = loadMore - ? unionBy(stateNotifications, res, 'id') - : loadUnread - ? unionBy(res, stateNotifications, 'id') - : res; - notificationsMap.set(type, _notifications); - setNotificationsMap(notificationsMap); - setLastNotificationId(lastId); - setIsRefershing(false); - setIsLoading(false); - } - }) - .catch(() => { - setIsRefershing(false); - setIsLoading(false); - }); - } + const _getActivities = (loadMore = false, loadUnread = false) => { + + + if(loadMore){ + console.log("load more notifications") + } else { + notificationsQuery.refetch(); + } + + // const since = loadMore ? lastNotificationId : null; + + // if (isLoading) { + // return; + // } + + // if (!endOfNotification || !loadMore || loadUnread) { + // setIsLoading(true); + // setIsRefershing(!loadMore); + // getNotifications({ filter: type, since: since, limit: 20 }) + // .then((res) => { + // const lastId = res.length > 0 ? [...res].pop().id : null; + + // if (loadMore && (lastId === lastNotificationId || res.length === 0)) { + // setEndOfNotification(true); + // setIsRefershing(false); + // setIsLoading(false); + // } else { + // console.log(''); + // const stateNotifications = notificationsMap.get(type) || []; + // const _notifications = loadMore + // ? unionBy(stateNotifications, res, 'id') + // : loadUnread + // ? unionBy(res, stateNotifications, 'id') + // : res; + // notificationsMap.set(type, _notifications); + // setNotificationsMap(notificationsMap); + // setLastNotificationId(lastId); + // setIsRefershing(false); + // setIsLoading(false); + // } + // }) + // .catch(() => { + // setIsRefershing(false); + // setIsLoading(false); + // }); + // } }; + + + const _navigateToNotificationRoute = (data) => { const type = get(data, 'type'); const permlink = get(data, 'permlink'); @@ -189,9 +211,9 @@ const NotificationContainer = ({ navigation }) => { setEndOfNotification(false); }; - const _notifications = notificationsMap.get(selectedFilter) || []; + const _notifications = notificationsQuery.data || []; return ( -