Skip to content

Commit

Permalink
ditch reactquery in favor of custom handler hook
Browse files Browse the repository at this point in the history
  • Loading branch information
gkasdorf committed Oct 13, 2023
1 parent 4b3801c commit 3b9567e
Show file tree
Hide file tree
Showing 11 changed files with 147 additions and 77 deletions.
19 changes: 3 additions & 16 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,10 @@ import { enableFreeze, enableScreens } from 'react-native-screens';
import { useFonts } from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';
import { enableMapSet } from 'immer';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { Infinity } from '@tamagui/lucide-icons';
import ImageViewerProvider from '@components/Common/ImageViewer/ImageViewerProvider';
import { LogBox } from 'react-native';
import { StatusBar } from 'expo-status-bar';

const queryClient = new QueryClient({
defaultOptions: {
queries: {
// @ts-expect-error - This is a valid option
staleTime: Infinity,
},
},
});

enableMapSet();
enableScreens();

Expand Down Expand Up @@ -50,11 +39,9 @@ export default function App(): React.JSX.Element | null {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<TamaguiProvider config={tguiConfig}>
<QueryClientProvider client={queryClient}>
<Theme name="lightTheme">
<PartTwo />
</Theme>
</QueryClientProvider>
<Theme name="lightTheme">
<PartTwo />
</Theme>
</TamaguiProvider>
</GestureHandlerRootView>
);
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"@tamagui/config": "^1.74.12",
"@tamagui/lucide-icons": "^1.74.12",
"@tamagui/theme-builder": "^1.74.13",
"@tanstack/react-query": "^4.36.1",
"@types/markdown-it": "^13.0.2",
"@types/react": "~18.2.14",
"axios": "^1.5.1",
Expand Down
12 changes: 4 additions & 8 deletions src/api/common/ApiInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,14 @@ class ApiInstance {

const siteRes = await this.instance.getSite();

console.log(siteRes.version);

if (siteRes.version.includes('.19')) {
this.isUpdate = true;
}

console.log(this.isUpdate);

// Save the site info
useSiteStore.getState().setSite(siteRes);

if (options.authToken != null) {
console.log(options.authToken);

this.initialized = true;
this.authToken = options.authToken;

Expand Down Expand Up @@ -437,11 +431,15 @@ class ApiInstance {
state.feeds.set(feedId, {
feedId,
postIds,
nextPage: options.page! + 1,
});
} else {
feed.postIds = [...feed.postIds, ...postIds];
feed.nextPage = options.page! + 1;
}
});

return undefined;
}

return res;
Expand Down Expand Up @@ -486,8 +484,6 @@ class ApiInstance {
return res;
}

console.log(res.comments.length);

const builtComments = buildCommentChains(res.comments);

addCommentsToPost(postId, builtComments.commentInfo);
Expand Down
25 changes: 14 additions & 11 deletions src/components/Account/AddAccountModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ interface IProps {
route: any;
}

export default function AddAccountModal({ navigation, route }: IProps): React.JSX.Element {
export default function AddAccountModal({
navigation,
route,
}: IProps): React.JSX.Element {
const [form, setForm] = useState({
instance: '',
username: '',
Expand All @@ -25,8 +28,6 @@ export default function AddAccountModal({ navigation, route }: IProps): React.JS
const login = useLogin();

const onLoginPress = (): void => {
console.log('Trying login...');

void login.doLogin({
username: form.username,
password: form.password,
Expand All @@ -42,18 +43,16 @@ export default function AddAccountModal({ navigation, route }: IProps): React.JS
};

return (
<VStack
space="$1"
marginHorizontal="$3"
marginVertical="$2"
>
<VStack space="$1" marginHorizontal="$3" marginVertical="$2">
<LoadingOverlay visible={login.status.loading} />
<InputWrapper>
<Label icon={<Globe size={12} />}>Instance</Label>
<TextInput
size="$3"
placeholder="Instance"
onChangeText={(v) => { onFormChange('instance', v); }}
onChangeText={(v) => {
onFormChange('instance', v);
}}
autoCorrect={false}
autoCapitalize="none"
inputMode="url"
Expand All @@ -63,7 +62,9 @@ export default function AddAccountModal({ navigation, route }: IProps): React.JS
<Label icon={<User size={12} />}>Username</Label>
<TextInput
placeholder="Username"
onChangeText={(v) => { onFormChange('username', v); }}
onChangeText={(v) => {
onFormChange('username', v);
}}
autoCorrect={false}
autoCapitalize="none"
autoComplete="username"
Expand All @@ -73,7 +74,9 @@ export default function AddAccountModal({ navigation, route }: IProps): React.JS
<Label icon={<Key size={12} />}>Password</Label>
<TextInput
placeholder="Password"
onChangeText={(v) => { onFormChange('password', v); }}
onChangeText={(v) => {
onFormChange('password', v);
}}
autoCorrect={false}
secureTextEntry
autoComplete="current-password"
Expand Down
21 changes: 16 additions & 5 deletions src/components/Feed/components/MainFeed.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from 'react';
import { useQuery } from '@tanstack/react-query';
import React, { useCallback } from 'react';
import instance from '@api/Instance';
import VStack from '@components/Common/Stack/VStack';
import { useRoute } from '@react-navigation/core';
import { useFeedPostIds } from '@src/state/feed/feedStore';
import { useFeedNextPage, useFeedPostIds } from '@src/state/feed/feedStore';
import { ListRenderItemInfo } from '@shopify/flash-list';
import FeedItem from '@components/Feed/components/Feed/FeedItem';
import { FlatList } from 'react-native';
import { useLoadData } from '@hooks/useLoadData';

const renderItem = ({
item,
Expand All @@ -20,11 +20,20 @@ export default function MainFeed(): React.JSX.Element {
// Get the feed ID
const { key } = useRoute();
const postIds = useFeedPostIds(key);
const nextPage = useFeedNextPage(key);

const { isLoading } = useQuery(['feed', key], async () => {
await instance.getPosts(key);
const { isLoading, append } = useLoadData(async () => {
await instance.getPosts(key, {}, true);
});

const onEndReached = useCallback(() => {
append(async () => {
await instance.getPosts(key, {
page: nextPage,
});
});
}, [nextPage]);

return (
<VStack flex={1}>
<FlatList
Expand All @@ -35,6 +44,8 @@ export default function MainFeed(): React.JSX.Element {
maxToRenderPerBatch={5}
updateCellsBatchingPeriod={100}
windowSize={5}
onEndReachedThreshold={0.5}
onEndReached={onEndReached}
/>
</VStack>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from 'react';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useQuery } from '@tanstack/react-query';
import LoadingOverlay from '@components/Common/Loading/LoadingOverlay';
import { Alert, FlatList } from 'react-native';
import { FlatList } from 'react-native';
import { GetSiteResponse } from 'lemmy-js-client';
import OnboardingInstanceListItem from '@components/Onboarding/OnboardingInstanceList/components/OnboardingInstanceListItem';
import VStack from '@components/Common/Stack/VStack';
import OnboardingInstanceListHeader from '@components/Onboarding/OnboardingInstanceList/components/OnboardingInstanceListHeader';
import getInstanceList from '@api/instanceList/getInstanceList';
import { useLoadData } from '@hooks/useLoadData';

const keyExtractor = (item: GetSiteResponse): string => {
return item.site_view.site.name;
Expand All @@ -17,18 +17,19 @@ interface IProps {
navigation: NativeStackNavigationProp<any>;
}

const renderItem = ({ item }) => {
interface RenderItem {
item: GetSiteResponse;
}

const renderItem = ({ item }: RenderItem): React.JSX.Element => {
return <OnboardingInstanceListItem item={item} />;
};

export default function OnboardingInstanceListScreen({
navigation,
}: IProps): React.JSX.Element {
const { isLoading, data } = useQuery(['onboardingInstanceList'], async () => {
return await getInstanceList().catch((err): GetSiteResponse[] => {
Alert.alert('Error', err.message);
return [];
});
const { isLoading, data } = useLoadData<GetSiteResponse[]>(async () => {
return await getInstanceList();
});

return (
Expand Down
13 changes: 8 additions & 5 deletions src/components/Post/screens/PostScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,23 @@ import {
import LoadingScreen from '@components/Common/Loading/LoadingScreen';
import VStack from '@components/Common/Stack/VStack';
import Post from '@components/Post/components/Post';
import { useQuery } from '@tanstack/react-query';
import instance from '@api/Instance';
import { ICommentInfo } from '@src/types';
import { Spinner } from 'tamagui';
import CommentChain from '@components/Common/Comment/CommentChain';
import { FlatList } from 'react-native';
import { useLoadData } from '@hooks/useLoadData';

interface IProps {
navigation: NativeStackNavigationProp<any>;
route: any;
}

// @ts-expect-error - this is correct
const renderItem = ({ item }): React.JSX.Element => {
interface RenderItem {
item: ICommentInfo;
}

const renderItem = ({ item }: RenderItem): React.JSX.Element => {
return <CommentChain commentInfo={item} />;
};

Expand All @@ -37,8 +40,8 @@ export default function PostScreen({
const postTitle = usePostTitle(postId);
const postCommentsInfo = usePostCommentsInfo(postId);

const { isLoading } = useQuery(['post', postId], async () => {
return await instance.getComments(postId);
const { isLoading } = useLoadData(async () => {
return await instance.getPost(postId);
});

useEffect(() => {
Expand Down
8 changes: 0 additions & 8 deletions src/hooks/useImageDimensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,6 @@ export const useImageDimensions = (): UseImageDimensions => {
}, [imageViewer.dimensions]);

const update = (): void => {
console.log(
getRatio(
imageViewer.dimensions.height,
imageViewer.dimensions.width,
0.9,
),
);

setDimensions({
scaled: getRatio(
imageViewer.dimensions.height,
Expand Down
88 changes: 88 additions & 0 deletions src/hooks/useLoadData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { useCallback, useEffect, useState } from 'react';

interface UseLoadData<DataType = undefined> {
refresh: (refreshFunc?: () => Promise<DataType>) => void;
append: (appendFunc: () => Promise<DataType>) => void;
isLoading: boolean;
isError: boolean;
error?: string;
data?: DataType;
}

interface Status<DataType = undefined> {
isLoading: boolean;
isError: boolean;
error?: string;
data?: DataType;
}

export const useLoadData = <ReturnType>(
func: () => Promise<ReturnType>,
): UseLoadData<ReturnType> => {
const [status, setStatus] = useState<Status<ReturnType>>({
isLoading: true,
isError: false,
error: undefined,
data: undefined,
});

useEffect(() => {
run(func);
}, []);

const run = useCallback((func: () => Promise<ReturnType>, append = false) => {
if (!status.isLoading) {
setStatus({
...status,
isLoading: true,
isError: false,
error: undefined,
});
}

void func()
.then((data) => {
if (append) {
setStatus({
isLoading: false,
isError: false,
error: undefined,
data: {
...status.data,
...data,
},
});
} else {
setStatus({
isLoading: false,
isError: false,
error: undefined,
data,
});
}
})
.catch((e) => {
setStatus({
isLoading: false,
isError: true,
error: e.message,
});
});
}, []);

const refresh = useCallback((refreshFunc?: () => Promise<ReturnType>) => {
if (refreshFunc == null) refreshFunc = func;

run(refreshFunc);
}, []);

const append = useCallback((appendFunc: () => Promise<ReturnType>) => {
run(appendFunc, true);
}, []);

return {
...status,
refresh,
append,
};
};
Loading

0 comments on commit 3b9567e

Please sign in to comment.