Skip to content

Commit

Permalink
Performance boost (#50)
Browse files Browse the repository at this point in the history
Co-authored-by: Nate Sawant <natesawant@gmail.com>
Co-authored-by: mai <thisismainguyen@gmail.com>
Co-authored-by: ZainabImadulla <zainab.imadulla@icloud.com>
  • Loading branch information
4 people authored Dec 4, 2024
1 parent eac1fb2 commit 5974e72
Show file tree
Hide file tree
Showing 20 changed files with 186 additions and 60 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,5 @@ coverage-final.json
build/

# MongoDB data directory
/data/
/data/
.vercel
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ MONGO_PASSWORD="dbUserPassword"
SUPABASE_PASSWORD="p4JeQ2sCH3OXC1jP"
SUPABASE_URL="https://npyvbmfnusakklalqxcz.supabase.co"
SUPABASE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im5weXZibWZudXNha2tsYWxxeGN6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MjkyODg2MTgsImV4cCI6MjA0NDg2NDYxOH0.P_gUi5uPuALkeXtHeWKYrPDVaIyESW5BQS_NvdvRkNs"
IMAGE_KIT_ID=https://ik.imagekit.io/bfd79mqcsx/tr:w-300,h-300/
```

### 4. Running the Application
Expand Down
4 changes: 4 additions & 0 deletions backend/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const AWS_PUBLIC_KEY = process.env.PUBLIC_KEY_AWS || '';
const AWS_PRIVATE_KEY = process.env.SECRET_KEY_AWS || '';
const AWS_BUCKET_NAME = process.env.S3BUCKETNAME || '';
const AWS_BUCKET_REGION = process.env.S3BUCKETREGION || '';
const IMAGE_KIT = process.env.IMAGE_KIT_ID || '';

const SERVER_PORT = process.env.SERVER_PORT
? Number(process.env.SERVER_PORT)
Expand Down Expand Up @@ -38,4 +39,7 @@ export const config = {
name: AWS_BUCKET_NAME,
region: AWS_BUCKET_REGION,
},
imagekit : {
key : IMAGE_KIT
}
};
53 changes: 53 additions & 0 deletions backend/src/controllers/species/get.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import express from 'express';
import { Species } from '../../models/species';
import { DEFAULT_LIMIT, DEFAULT_PAGE } from '../../consts/pagination';

export const getById = async (req: express.Request, res: express.Response) => {
const id = req.params.id;
Expand Down Expand Up @@ -38,3 +39,55 @@ export const searchSpecies = async (
return res.status(500).json({ message: 'Internal server error' });
}
};

export const searchAndPaginatedSpecies = async (
req: express.Request,
res: express.Response,
) => {
try {
const { text = '', page = DEFAULT_PAGE, limit = DEFAULT_LIMIT } = req.query;
const pageSize = parseInt(page as string);
const limitSize = parseInt(limit as string);

if (pageSize < 1 || limitSize < 1) {
return res.status(400).json({
error:
'Invalid pagination parameters. Page and limit must be positive numbers.',
});
}

const skip = (pageSize - 1) * limitSize;

const query = [
{
$search: {
index: 'commonNames',
autocomplete: {
query: text,
path: 'commonNames',
fuzzy: {
maxEdits: 2,
prefixLength: 0,
maxExpansions: 50,
},
},
},
},
{ $skip: skip },
{ $limit: limitSize },
];

const results = await Species.aggregate(query);

return res.status(200).json({
page: pageSize,
limit: limitSize,
results,
});
} catch (error) {
console.error(error);
return res.status(500).json({
error: 'An error occurred while fetching users.',
});
}
};
2 changes: 2 additions & 0 deletions backend/src/routes/species.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import express from 'express';
import {
getById,
getByScientificName,
searchAndPaginatedSpecies,
searchSpecies,
} from '../controllers/species/get';
import { isAuthenticated } from '../middlewares/authMiddleware';
Expand Down Expand Up @@ -53,4 +54,5 @@ export default (router: express.Router) => {
getByScientificName,
);
router.get('/species/search/:searchRequest', isAuthenticated, searchSpecies);
router.get('/species/paginated', isAuthenticated, searchAndPaginatedSpecies);
};
2 changes: 1 addition & 1 deletion backend/src/services/s3Service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class S3ServiceImpl implements S3Service {
try {
await this.client.send(command);
const url = encodeURI(
`https://${this.name}.s3.${this.region}.amazonaws.com/${fileKey}`,
config.imagekit.key + fileKey
);
return url;
} catch (error) {
Expand Down
2 changes: 1 addition & 1 deletion backend/src/services/userService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,9 +331,9 @@ export class UserServiceImpl implements UserService {
],
},
},
{ $sort: { date: -1 } },
{ $skip: (page - 1) * limit },
{ $limit: limit },
{ $sort: { date: -1 } },
{
$lookup: {
from: 'users',
Expand Down
1 change: 0 additions & 1 deletion frontend/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.generate.snapper",
"googleMapsApiKey": "process.env.GOOGLE_MAPS_API_KEY",
"infoPlist": {
"NSUserNotificationUsageDescription": "Snapper would like to send you notifications."
}
Expand Down
13 changes: 6 additions & 7 deletions frontend/app/(app)/(tabs)/explore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ export default function Explore() {
);
const [coordinate, setCoordinate] = useState<number[]>([200, 200]);
const [mapSearch, setMapSearch] = useState('');
const changeText = (input: string) => {
setSearch(input);
};

const changeMapText = () => {
const delimeter = ' ';
Expand Down Expand Up @@ -62,6 +59,8 @@ export default function Explore() {
}
};

//These should be hooks but oh well.

/**
* On Query, will pattern match against the toggle options which will
* trigger different endpoints
Expand All @@ -72,7 +71,7 @@ export default function Explore() {
let endpoint;
switch (toggle) {
case 'Fish':
endpoint = `/species/search/${search}`;
endpoint = `/species/paginated?text=${search}`;
break;
case 'Posts':
endpoint = `/divelogs/search?text=${search}`;
Expand All @@ -85,7 +84,7 @@ export default function Explore() {
};

const { isPending, error, data } = useQuery({
queryKey: ['search', search],
queryKey: ['search', search, toggle],
queryFn: () => onQueryFunction(),
enabled: search.length > 0,
});
Expand Down Expand Up @@ -170,7 +169,7 @@ export default function Explore() {
const renderSearchPage = () => {
return (
<View className="w-full h-full">
<View className="mb-2">{renderCustomInput(changeText, search)}</View>
<View className="mb-2">{renderCustomInput(setSearch, search)}</View>
<View className="mb-2">
<ToggleButtons />
</View>
Expand Down Expand Up @@ -217,7 +216,7 @@ export default function Explore() {
};

return (
<SafeAreaView className="h-screen w-screen">
<SafeAreaView className="h-screen w-screen bg-white">
{selectedCategory === 'Map' && renderMapPage()}
<View className="w-full px-[5%] z-10">
<View className="mb-2 bg-[#FFFFFF] rounded-full">
Expand Down
63 changes: 46 additions & 17 deletions frontend/app/(app)/(tabs)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { useAuthStore } from '../../../auth/authStore';
import HomeMenu from '../../../components/home/menu-bar';
import { Category, Filter } from '../../../consts/home-menu';
import { useCallback, useEffect, useState } from 'react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useUserFollowingPosts } from '../../../hooks/user';
import BigDiveLog from '../../../components/divelog/divelog';
import NearbyDiveLog from '../../../components/home/nearby-divelog';
Expand All @@ -19,10 +19,8 @@ import { DEFAULT_SHERM_LOCATION } from '../../../consts/location';
import { PROFILE_PHOTO } from '../../../consts/profile';
import { useNearbyDiveLogs } from '../../../hooks/divelog';
import FilterMenu from '../../../components/home/filter';
import usePulsingAnimation from '../../../utils/skeleton';
import { useInfoPopup } from '../../../contexts/info-popup-context';
import InfoPopup from '../../../components/info-popup';
import { useQueryClient } from '@tanstack/react-query';
import { useFocusEffect } from 'expo-router';

const Home = () => {
Expand All @@ -38,7 +36,45 @@ const Home = () => {
const [selectedFilters, setSelectedFilters] = useState<Filter[]>([
Filter.ALL,
]);
const opacity = usePulsingAnimation();

const memoizeUserFollowingPosts = () => {
const queryResult = useUserFollowingPosts(mongoDBId!, selectedFilters);

return useMemo(
() => ({
data: queryResult.data,
isLoading: queryResult.isLoading,
fetchNextPage: queryResult.fetchNextPage,
hasNextPage: queryResult.hasNextPage,
isFetchingNextPage: queryResult.isFetchingNextPage,
refetch: queryResult.refetch,
isRefetching: queryResult.isRefetching,
error: queryResult.error,
}),
[queryResult.data],
);
};

const memoizeNearbyDiveLogs = () => {
const queryResult = useNearbyDiveLogs(
currentLocation.latitude,
currentLocation.longitude,
selectedFilters,
);

return useMemo(
() => ({
data: queryResult.data,
isLoading: queryResult.isLoading,
fetchNextPage: queryResult.fetchNextPage,
hasNextPage: queryResult.hasNextPage,
refetch: queryResult.refetch,
isFetching: queryResult.isFetching,
error: queryResult.error,
}),
[queryResult.data],
);
};

// hooks call for following posts
const {
Expand All @@ -50,7 +86,7 @@ const Home = () => {
refetch: refetchFollowingPosts,
isRefetching: isRefetchingFollowingPosts,
error: errorFollowingPosts,
} = useUserFollowingPosts(mongoDBId!, selectedFilters);
} = memoizeUserFollowingPosts();

// hooks call for nearby posts
const {
Expand All @@ -61,11 +97,7 @@ const Home = () => {
refetch: refetchNearByPosts,
isFetching: isFetchingNearbyPosts,
error: errorNearbyPosts,
} = useNearbyDiveLogs(
currentLocation.latitude,
currentLocation.longitude,
selectedFilters,
);
} = memoizeNearbyDiveLogs();

// fetch the current location of user
useEffect(() => {
Expand Down Expand Up @@ -197,16 +229,14 @@ const Home = () => {
renderItem={renderFollowingPost}
key="following-divelogs"
showsVerticalScrollIndicator={false}
onEndReached={() =>
loadMorePosts(fetchNextPageFollowing, hasNextPageFollowing)
onEndReached={() => {
loadMorePosts(fetchNextPageFollowing, hasNextPageFollowing)}
}
onEndReachedThreshold={0.3}
ListFooterComponent={
isFetchingNextPageFollowing ? (
<View className="mt-10">
<View className="mt-10">
<DiveLogSkeleton />
</View>
) : null
}
contentContainerStyle={{ paddingBottom: 150 }}
ItemSeparatorComponent={() => <View className="h-12" />}
Expand Down Expand Up @@ -242,8 +272,8 @@ const Home = () => {

return (
<ScrollView
className = "mb-20"
showsVerticalScrollIndicator={false}
/*
onScroll={(e) => {
const contentHeight = e.nativeEvent.contentSize.height;
const layoutHeight = e.nativeEvent.layoutMeasurement.height;
Expand All @@ -253,7 +283,6 @@ const Home = () => {
} else {
}
}}
*/
>
<View className="flex flex-row">
<View className="w-[48%] mr-[2%]">
Expand Down
8 changes: 6 additions & 2 deletions frontend/app/(app)/(tabs)/notification.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useFocusEffect } from 'expo-router';
import React, { useCallback, useEffect, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { FlatList, SafeAreaView, SectionList, Text, View } from 'react-native';
import { useAuthStore } from '../../../auth/authStore';
import NotificationEntry from '../../../components/notification/notification';
Expand All @@ -17,12 +17,16 @@ const Notification = () => {
data,
isLoading,
error,
refetch,
refetch: originalRefetch,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
} = useUserNotification(mongoDBId || '');

const refetch = useCallback(() => {
originalRefetch();
}, [originalRefetch]);

useFocusEffect(
useCallback(() => {
refetch();
Expand Down
20 changes: 18 additions & 2 deletions frontend/app/(app)/user/[id].tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
import React from 'react';
import { useLocalSearchParams } from 'expo-router';
import { router, Stack, useLocalSearchParams } from 'expo-router';
import User from './components/user-profile';
import Arrow from '../../../components/arrow';

const Profile = () => {
const { id } = useLocalSearchParams<{ id: string }>();
return <User id={id} />;

return (
<>
<Stack.Screen
options={{
headerTitle: '',
headerTransparent: true,
headerShown: true,
headerLeft: () => (
<Arrow direction="left" onPress={() => router.back()} />
),
}}
/>
<User id={id} />
</>
);
};

export default Profile;
Loading

0 comments on commit 5974e72

Please sign in to comment.