basic implementation on notifications fetching with useQuery

This commit is contained in:
Nouman Tahir 2022-09-22 15:35:47 +05:00
parent b8ea6db4e5
commit efb620540c
7 changed files with 123 additions and 51 deletions

View File

@ -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={
<RefreshControl
refreshing={isNotificationRefreshing}
onRefresh={() => getActivities(selectedFilter)}
onRefresh={() => getActivities()}
progressBackgroundColor="#357CE6"
tintColor={!isDarkTheme ? '#357ce6' : '#96c0ff'}
titleColor="#fff"

View File

@ -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);

View File

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

View File

@ -22,3 +22,7 @@ export const initQueryClient = () => {
persistOptions: { persister: asyncStoragePersister },
} as PersistQueryClientProviderProps;
};
export * from "./notificationQueries";

View File

@ -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);
// }
});
}

View File

@ -5,6 +5,9 @@ const QUERIES = {
SCHEDULES: {
GET: 'QUERY_GET_SCHEDULES',
},
NOTIFICATIONS:{
GET: 'QERUY_GET_NOTIFICATIONS'
}
};
export default QUERIES;

View File

@ -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>(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 (
<NotificationScreen
<NotificationScreen
getActivities={_getActivities}
notifications={_notifications}
navigateToNotificationRoute={_navigateToNotificationRoute}