Skip to content

Commit

Permalink
feat: improve home refresh logic (#202)
Browse files Browse the repository at this point in the history
## Description

Closes: #XXXX



This PR improves the home refresh logic using a global flag that tells if the home should reload the data.
This is a temporary workaround untill we have a proper application wide cache.

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

- [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] provided a link to the relevant issue or specification
- [x] reviewed "Files changed" and left comments if necessary
- [x] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed all author checklist items have been addressed
  • Loading branch information
manu0466 authored Jun 22, 2023
1 parent 86a3540 commit 55de58f
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 17 deletions.
5 changes: 4 additions & 1 deletion src/hooks/useOnScreenDetached.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import useOnBackAction from './useOnBackAction';
const useOnScreenDetached = (onDetach: () => any, deps: DependencyList) => {
const backActionStateRef = useRef(false);
const isFocused = useIsFocused();
const memoizedDetachCallback = useCallback(onDetach, [...deps, onDetach]);
// Safe to ignore the onDetach value since we want to memoize the provided
// onDetach function using the provided deps list.
// eslint-disable-next-line react-hooks/exhaustive-deps
const memoizedDetachCallback = useCallback(onDetach, [...deps]);

useOnBackAction(() => {
backActionStateRef.current = true;
Expand Down
23 changes: 23 additions & 0 deletions src/recoil/home.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { atom, useRecoilValue, useSetRecoilState } from 'recoil';

/**
* Recoil that holds a boolean flag that tells if the home should
* be refreshed.
* NOTE: This is a workaround to force the home to refresh until we have
* a proper cache in place that can be updated after an operation that
* affect the data displayed in the Home screen.
*/
const homeShouldReloadData = atom<boolean>({
key: 'homeShouldReloadData',
default: false,
});

/**
* Hook that tels if the home should refresh the displayed data.
*/
export const useHomeShouldReloadData = () => useRecoilValue(homeShouldReloadData);

/**
* Hook that provides a function to update the value of the refresh home flag.
*/
export const useSetHomeShouldReloadData = () => useSetRecoilState(homeShouldReloadData);
15 changes: 13 additions & 2 deletions src/screens/BroadcastTx/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { DPMImages } from 'types/images';
import { DeliverTxResponse } from '@desmoslabs/desmjs';
import useOnScreenDetached from 'hooks/useOnScreenDetached';
import { ImageSourcePropType } from 'react-native';
import { useSetHomeShouldReloadData } from '@recoil/home';
import useStyles from './useStyles';

enum BroadcastStatus {
Expand Down Expand Up @@ -77,6 +78,7 @@ const BroadcastTx: React.FC<NavProps> = (props) => {
const [broadcastTxStatus, setBroadcastTxStatus] = useState<BroadcastTxStatus>({
status: BroadcastStatus.Cancel,
});
const setHomeShouldReloadData = useSetHomeShouldReloadData();

useEffect(() => {
estimateFees(messages, memo);
Expand Down Expand Up @@ -110,7 +112,7 @@ const BroadcastTx: React.FC<NavProps> = (props) => {
}
break;
}
}, [broadcastTxStatus, onCancel, onError, onSuccess]);
}, [broadcastTxStatus, onCancel, onError, onSuccess, setHomeShouldReloadData]);

const showSuccessModal = React.useCallback(() => {
showModal(SingleButtonModal, {
Expand Down Expand Up @@ -143,6 +145,7 @@ const BroadcastTx: React.FC<NavProps> = (props) => {
const deliveredTx = broadcastResult.value;
if (deliveredTx !== undefined) {
setBroadcastTxStatus({ status: BroadcastStatus.Success, deliveredTx });
setHomeShouldReloadData(true);
showSuccessModal();
} else {
setBroadcastTxStatus({ status: BroadcastStatus.Cancel });
Expand All @@ -154,7 +157,15 @@ const BroadcastTx: React.FC<NavProps> = (props) => {
}
setBroadcastingTx(false);
}
}, [broadcastTx, estimatedFee, memo, messages, showErrorModal, showSuccessModal]);
}, [
broadcastTx,
estimatedFee,
memo,
messages,
setHomeShouldReloadData,
showErrorModal,
showSuccessModal,
]);

return (
<StyledSafeAreaView topBar={<TopBar stackProps={props} title={t('tx details')} />}>
Expand Down
13 changes: 9 additions & 4 deletions src/screens/Home/components/TransactionsListItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,18 @@ import useMessagesAmount from 'hooks/messages/useGetMessageAmount';
import useStyles from './useStyles';

export interface TransactionsListItemProps {
/**
* The transaction whose information will be displayed.
*/
readonly transaction: Transaction;
}

const TransactionsListItem = (props: TransactionsListItemProps) => {
/**
* Components that shows the information of a transaction.
*/
const TransactionsListItem: React.FC<TransactionsListItemProps> = ({ transaction }) => {
const navigation = useNavigation<StackNavigationProp<RootNavigatorParamList>>();
const { t } = useTranslation('transaction');
const { transaction } = props;
const styles = useStyles();

// -------- VARIABLES --------
Expand All @@ -35,14 +40,14 @@ const TransactionsListItem = (props: TransactionsListItemProps) => {

// -------- CALLBACKS --------

const onPress = useCallback(() => {
const onItemPress = useCallback(() => {
navigation.navigate(ROUTES.TRANSACTION_DETAILS, {
transaction,
});
}, [navigation, transaction]);

return (
<TouchableOpacity onPress={onPress}>
<TouchableOpacity onPress={onItemPress}>
<View style={styles.root}>
{/* Header */}
<View style={styles.header}>
Expand Down
18 changes: 10 additions & 8 deletions src/screens/Home/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
import { useLazyQuery } from '@apollo/client';
import GetTransactionsByAddress from 'services/graphql/queries/GetTransactionsByAddress';
import { useActiveAccountAddress } from '@recoil/activeAccount';
import React from 'react';
import { FetchDataFunction, usePaginatedData } from 'hooks/usePaginatedData';
import { GQLGetTransactionsByAddress, Transaction } from 'types/transactions';
import { convertGqlMessageToTransaction } from 'lib/GraphQLUtils/transaction';
import { useApolloClient } from '@apollo/client';

/**
* Hook that provides a {@link FetchDataFunction} for the {@link usePaginatedData}
* hook to fetch the list of {@link Transaction} performed from the current active user.
*/
const useFetchCurrentUserTransactions = () => {
const useFetchCurrentUserTransactions = (): FetchDataFunction<Transaction, undefined> => {
// Here we use useApolloClient instead of useLazyQuery
// to force the returned callback to change when the client instance changes
// so that the usePaginatedData hook can properly update the data.
const client = useApolloClient();
const activeAccountAddress = useActiveAccountAddress();

const [fetchTransactions] = useLazyQuery<GQLGetTransactionsByAddress>(GetTransactionsByAddress, {
fetchPolicy: 'network-only',
});

return React.useCallback<FetchDataFunction<Transaction, undefined>>(
async (offset, limit) => {
const { data, error } = await fetchTransactions({
const { data, error } = await client.query<GQLGetTransactionsByAddress>({
query: GetTransactionsByAddress,
fetchPolicy: 'network-only',
variables: {
addresses: `{${activeAccountAddress}}`,
offset,
Expand All @@ -39,7 +41,7 @@ const useFetchCurrentUserTransactions = () => {
endReached: convertedData.length < limit,
};
},
[activeAccountAddress, fetchTransactions],
[activeAccountAddress, client],
);
};

Expand Down
13 changes: 12 additions & 1 deletion src/screens/Home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { ListRenderItem } from '@shopify/flash-list/src/FlashListProps';
import { Transaction } from 'types/transactions';
import TransactionsListItem from 'screens/Home/components/TransactionsListItem';
import Spacer from 'components/Spacer';
import { useHomeShouldReloadData, useSetHomeShouldReloadData } from '@recoil/home';
import { useActiveAccountTransactions } from './hooks';
import useStyles from './useStyles';

Expand Down Expand Up @@ -54,6 +55,9 @@ const Home: React.FC<NavProps> = (props) => {
fetchMore: fetchMoreTransactions,
} = useActiveAccountTransactions();

const homeShouldReloadData = useHomeShouldReloadData();
const setHomeShouldReloadData = useSetHomeShouldReloadData();

// -------- REFS ---------

const accountBalanceRef = useRef<AccountBalanceRef>();
Expand Down Expand Up @@ -82,7 +86,14 @@ const Home: React.FC<NavProps> = (props) => {

// ------- EFFECTS --------

useFocusEffect(refreshData);
useFocusEffect(
React.useCallback(() => {
if (homeShouldReloadData) {
refreshData();
setHomeShouldReloadData(false);
}
}, [homeShouldReloadData, refreshData, setHomeShouldReloadData]),
);

return (
<StyledSafeAreaView padding={0} noIosPadding>
Expand Down
5 changes: 4 additions & 1 deletion src/screens/SettingsSwitchChain/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Typography from 'components/Typography';
import Spacer from 'components/Spacer';
import { RootNavigatorParamList } from 'navigation/RootNavigator';
import ROUTES from 'navigation/routes';
import { useSetHomeShouldReloadData } from '@recoil/home';
import useStyles from './useStyles';

type NavProps = StackScreenProps<RootNavigatorParamList, ROUTES.SETTINGS_SWITCH_CHAIN>;
Expand All @@ -20,12 +21,14 @@ const SettingsSwitchChain = (props: NavProps) => {

const chainName = useSetting('chainName');
const setChainName = useSetSetting('chainName');
const setHomeShouldReloadData = useSetHomeShouldReloadData();

const changeChain = React.useCallback(
(newChainName: string) => {
setHomeShouldReloadData(true);
setChainName(newChainName);
},
[setChainName],
[setChainName, setHomeShouldReloadData],
);

const values: RadioValue[] = React.useMemo(
Expand Down

0 comments on commit 55de58f

Please sign in to comment.