Skip to content

Commit

Permalink
perf: notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
LuisCusihuaman committed Dec 6, 2023
1 parent 59d449b commit fda060e
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 102 deletions.
8 changes: 7 additions & 1 deletion src/api/snaps/use-snaps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
import type { AxiosError } from 'axios';
import { createQuery } from 'react-query-kit';

import type { Notification } from '@/screens/notifications/types';

import { client } from '../common';
import type { Snap } from './types';

Expand Down Expand Up @@ -186,7 +188,11 @@ export const useMentions = createQuery<Response, Variables, Error>({
},
});

export const useNotifications = createQuery<Response, Variables, AxiosError>({
export const useNotifications = createQuery<
Notification[],
Variables,
AxiosError
>({
primaryKey: '/api/notification',
queryFn: async ({ queryKey: [primaryKey, variables] }) => {
try {
Expand Down
56 changes: 10 additions & 46 deletions src/screens/notifications/mentions-view.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useNavigation } from '@react-navigation/native';
import { useCallback, useEffect, useState } from 'react';
import React from 'react';
import { FlatList, RefreshControl } from 'react-native';

Expand All @@ -10,79 +9,44 @@ import { EmptyList, FocusAwareStatusBar, Text, View } from '@/ui';

import { Card } from '../feed/card';

const INCREMENT_RENDER = 10;
const INITIAL_RENDER = 20;

const MentionScreen = () => {
const currentUser = getUserState();

const { data, isLoading, isError, refetch } = useMentions({
variables: { user_id: currentUser?.id },
});

const [mentionSnaps, setMentionSnaps] = useState<Snap[]>([]);

useEffect(() => {
setMentionSnaps(data ? data : []);
}, [data]);

const { navigate } = useNavigation();

// State to track the number of items to render
const [renderCount, setRenderCount] = useState(INITIAL_RENDER);
const [refresh, setRefresh] = useState(false);

// The useCallback hook
const onRefresh = useCallback(() => {
setRefresh(true);
refetch().then(() => setRefresh(false));
}, [refetch]);
const onRefresh = () => {
refetch();
};

// Early return in case of error
if (isError) {
return (
<View>
<Text> Error Loading data </Text>
<Text>Error Loading data</Text>
</View>
);
}

// Corrected renderItem function
const renderItem = ({ item, index }: { item: Snap; index: number }) => {
if (index < renderCount) {
return (
<Card snap={item} onPress={() => navigate('Snap', { snap: item })} />
);
}
return null;
};

const handleEndReached = () => {
console.log(`handleEndReached before: ${renderCount}`);

// Load more items when the user reaches the end
if (renderCount < (data ? data.length : 0)) {
setRenderCount(renderCount + INCREMENT_RENDER);
}

// console.log(`handleEndReached after: ${renderCount}`);
};
const renderItem = ({ item }: { item: Snap }) => (
<Card snap={item} onPress={() => navigate('Snap', { snap: item })} />
);

return (
<View>
<FocusAwareStatusBar />

<FlatList
data={mentionSnaps}
data={data}
renderItem={renderItem}
keyExtractor={(_, index) => `item-${index}`}
ListEmptyComponent={<EmptyList isLoading={isLoading} />}
onEndReached={handleEndReached}
onEndReachedThreshold={0.1}
refreshControl={
<RefreshControl refreshing={refresh} onRefresh={onRefresh} />
<RefreshControl refreshing={isLoading} onRefresh={onRefresh} />
}
getItemLayout={(_data, index) => ({
getItemLayout={(_, index) => ({
length: 100,
offset: 100 * index,
index,
Expand Down
39 changes: 29 additions & 10 deletions src/screens/notifications/notification-screen.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,42 @@
import React from 'react';
import React, { useState } from 'react';

import { FocusAwareStatusBar, Text, View } from '@/ui';
import { FocusAwareStatusBar, View } from '@/ui';

import Tab from '../profile/components/tab'; // Import the Tab component
import MentionScreen from './mentions-view';
import NotificationView from './notification-view';

const NotionficationScreen = () => {
const [selectedTab, setSelectedTab] = useState('Notifications'); // Initial tab

const handleTabChange = (tabName: string) => {
setSelectedTab(tabName);
};

return (
<>
<View>
<FocusAwareStatusBar />
<Text className="text-center text-2xl font-bold">Notifications</Text>

<NotificationView />
<View>
<View className="flex flex-row items-center justify-between px-4 py-2">
<Tab
title="Notifications"
selected={selectedTab === 'Notifications'}
onPress={() => handleTabChange('Notifications')}
/>
<Tab
title="Mentions"
selected={selectedTab === 'Mentions'}
onPress={() => handleTabChange('Mentions')}
/>
</View>
</View>

<View className="mt-1 border-t border-slate-200 py-3 text-center">
<Text className="text-center text-2xl font-bold">Mentions</Text>
{selectedTab === 'Notifications' ? (
<NotificationView />
) : (
<MentionScreen />
</View>
</>
)}
</View>
);
};

Expand Down
54 changes: 9 additions & 45 deletions src/screens/notifications/notification-view.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useState } from 'react';
import React, { useEffect } from 'react';
import { FlatList, RefreshControl, Text, View } from 'react-native';

import { useNotifications } from '@/api';
Expand All @@ -8,74 +8,38 @@ import { EmptyList, FocusAwareStatusBar } from '@/ui';
import NotificationCard from './notification-card';
import type { Notification } from './types';

const INCREMENT_RENDER = 10;
const INITIAL_RENDER = 20;

export default function NotificationView() {
const currentUser = getUserState();

const { data, isLoading, isError, refetch } = useNotifications({
variables: { user_id: currentUser?.id },
});

const [notifications, setNotifications] = useState<any>([]);

useEffect(() => {
setNotifications(data ? data : []);
}, [data]);

const [renderCount, setRenderCount] = useState(INITIAL_RENDER);
const [refresh, setRefresh] = useState(false);

// The useCallback hook
const onRefresh = useCallback(() => {
setRefresh(true);
refetch().then(() => setRefresh(false));
refetch();
}, [refetch]);

// Early return in case of error
if (isError) {
return (
<View>
<Text> Error Loading data </Text>
<Text>Error Loading data</Text>
</View>
);
}

const renderItem = ({
item,
index,
}: {
item: Notification;
index: number;
}) => {
if (index < renderCount) {
return <NotificationCard notification={item} />;
}
return null;
};

const handleEndReached = () => {
if (renderCount < (data ? data.length : 0)) {
setRenderCount(renderCount + INCREMENT_RENDER);
}
};

return (
<View>
<FocusAwareStatusBar />

<FlatList
data={notifications}
renderItem={renderItem}
data={data}
renderItem={({ item }: { item: Notification }) => (
<NotificationCard notification={item} />
)}
keyExtractor={(_, index) => `item-${index}`}
ListEmptyComponent={<EmptyList isLoading={isLoading} />}
onEndReached={handleEndReached}
onEndReachedThreshold={0.1}
refreshControl={
<RefreshControl refreshing={refresh} onRefresh={onRefresh} />
<RefreshControl refreshing={isLoading} onRefresh={() => refetch()} />
}
getItemLayout={(_data, index) => ({
getItemLayout={(_, index) => ({
length: 100,
offset: 100 * index,
index,
Expand Down

0 comments on commit fda060e

Please sign in to comment.