Skip to content

Commit

Permalink
Merge pull request #928 from tablelandnetwork/datadanne/refactor-tabl…
Browse files Browse the repository at this point in the history
…eland-wait-logic

Garage: refactor tableland wait logic
  • Loading branch information
datadanne authored Oct 17, 2023
2 parents 58db149 + 49b777c commit 3e92ae0
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 125 deletions.
28 changes: 2 additions & 26 deletions garage/src/components/SubmitMissionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import {
} from "wagmi";
import { as0xString } from "../utils/types";
import { Mission } from "../types";
import { useTablelandConnection } from "../hooks/useTablelandConnection";
import { TransactionStateAlert } from "./TransactionStateAlert";
import { secondaryChain, deployment } from "../env";
import { abi } from "../abis/MissionsManager";
import { useWaitForTablelandTxn } from "../hooks/useWaitForTablelandTxn";

const { missionContractAddress } = deployment;

Expand All @@ -48,8 +48,6 @@ export const SubmitMissionModal = ({
onTransactionCompleted,
refresh,
}: ModalProps) => {
const { validator } = useTablelandConnection();

const initialState = {
deliverables: mission.deliverables.map(({ key }) => ({ key, value: "" })),
};
Expand Down Expand Up @@ -90,29 +88,7 @@ export const SubmitMissionModal = ({
onTransactionCompleted(isSuccess);
}, [onTransactionCompleted, isTxLoading, isSuccess, data]);

useEffect(() => {
if (validator && data?.hash) {
const controller = new AbortController();
const signal = controller.signal;

validator
.pollForReceiptByTransactionHash(
{
chainId: secondaryChain.id,
transactionHash: data?.hash,
},
{ interval: 2000, signal }
)
.then((_) => {
refresh();
})
.catch((_) => {});

return () => {
controller.abort();
};
}
}, [validator, data, refresh]);
useWaitForTablelandTxn(secondaryChain.id, data?.hash, refresh, refresh);

const onInputChanged = useCallback(
(e: React.ChangeEvent<HTMLInputElement>, atIndex: number) => {
Expand Down
45 changes: 45 additions & 0 deletions garage/src/hooks/useWaitForTablelandTxn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useEffect, useState } from "react";
import { useTablelandConnection } from "./useTablelandConnection";

export const useWaitForTablelandTxn = (
chainId: number,
transactionHash: string | undefined,
onComplete: () => void,
onCancelled: () => void
) => {
const { validator } = useTablelandConnection();
const [isLoading, setIsLoading] = useState(false);

useEffect(() => {
if (validator && transactionHash) {
const controller = new AbortController();
const signal = controller.signal;

setIsLoading(true);

validator
.pollForReceiptByTransactionHash(
{
chainId,
transactionHash,
},
{ interval: 2000, signal }
)
.then((_) => {
setIsLoading(false);
onComplete();
})
.catch((_) => {
setIsLoading(false);
onCancelled();
});

return () => {
setIsLoading(false);
controller.abort();
};
}
}, [chainId, transactionHash, onComplete, onCancelled]);

return { isLoading };
};
45 changes: 10 additions & 35 deletions garage/src/pages/Dashboard/modules/RigsInventory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { CheckIcon, QuestionIcon } from "@chakra-ui/icons";
import { useBlockNumber } from "wagmi";
import { useAccount } from "../../../hooks/useAccount";
import { useOwnedRigs } from "../../../hooks/useOwnedRigs";
import { useTablelandConnection } from "../../../hooks/useTablelandConnection";
import { NFT } from "../../../hooks/useNFTs";
import { useNFTsCached } from "../../../components/NFTsContext";
import { Rig, RigWithPilots, Pilot } from "../../../types";
Expand All @@ -35,6 +34,7 @@ import { sleep } from "../../../utils/async";
import { prettyNumber } from "../../../utils/fmt";
import { firstSetValue, copySet, toggleInSet } from "../../../utils/set";
import { mainChain } from "../../../env";
import { useWaitForTablelandTxn } from "../../../hooks/useWaitForTablelandTxn";

interface RigListItemProps {
rig: RigWithPilots;
Expand Down Expand Up @@ -141,9 +141,8 @@ const isSelectable = (rig: Rig, selectable: Selectable): boolean => {
};

export const RigsInventory = (props: React.ComponentProps<typeof Box>) => {
const { address, actingAsAddress, delegations } = useAccount();
const { actingAsAddress } = useAccount();
const { rigs, refresh } = useOwnedRigs(actingAsAddress);
const { validator } = useTablelandConnection();
const { data: currentBlockNumber } = useBlockNumber();
const pilots = useMemo(() => {
if (!rigs) return;
Expand Down Expand Up @@ -191,39 +190,15 @@ export const RigsInventory = (props: React.ComponentProps<typeof Box>) => {
if (!pendingTx) setSelectedRigs(new Set());
}, [pendingTx]);

// Effect that waits until a tableland receipt is available for a tx hash
// and then refreshes the rig data
useEffect(() => {
if (validator && pendingTx) {
const controller = new AbortController();
const signal = controller.signal;

validator
.pollForReceiptByTransactionHash(
{
chainId: mainChain.id,
transactionHash: pendingTx,
},
{ interval: 2000, signal }
)
.then((_) => {
refreshRigsAndClearPendingTx();
})
.catch((_) => {
clearPendingTx();
});

return () => {
controller.abort();
};
}
}, [pendingTx, refreshRigsAndClearPendingTx, validator, clearPendingTx]);
useWaitForTablelandTxn(
mainChain.id,
pendingTx,
refreshRigsAndClearPendingTx,
clearPendingTx
);

const {
trainRigsModal,
pilotRigsModal,
parkRigsModal,
} = useGlobalFlyParkModals();
const { trainRigsModal, pilotRigsModal, parkRigsModal } =
useGlobalFlyParkModals();

const openTrainModal = useCallback(() => {
if (rigs?.length && selectedRigs.size) {
Expand Down
54 changes: 24 additions & 30 deletions garage/src/pages/Proposal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ import {
proposalStatus,
} from "../../components/ProposalStatusBadge";
import { useProposal, Result, Vote } from "../../hooks/useProposal";
import { useTablelandConnection } from "../../hooks/useTablelandConnection";
import { useAddressVotingPower } from "../../hooks/useAddressVotingPower";
import { TOPBAR_HEIGHT } from "../../Topbar";
import { prettyNumber, truncateWalletAddress } from "../../utils/fmt";
import { as0xString } from "../../utils/types";
import { ProposalWithOptions, ProposalStatus } from "../../types";
import { deployment, secondaryChain } from "../../env";
import { abi } from "../../abis/VotingRegistry";
import { useWaitForTablelandTxn } from "../../hooks/useWaitForTablelandTxn";

const ipfsGatewayBaseUrl = "https://nftstorage.link";

Expand Down Expand Up @@ -87,7 +87,6 @@ const CastVote = ({
(v) => v.address.toLowerCase() === address?.toLowerCase()
);

const { validator } = useTablelandConnection();
const { votingPower } = useAddressVotingPower(address, proposal.id);

const { data: blockNumber } = useBlockNumber();
Expand Down Expand Up @@ -155,34 +154,29 @@ const CastVote = ({
hash: data?.hash,
});

useEffect(() => {
if (validator && data?.hash) {
const controller = new AbortController();
const signal = controller.signal;

validator
.pollForReceiptByTransactionHash(
{
chainId: secondaryChain.id,
transactionHash: data?.hash,
},
{ interval: 2000, signal }
)
.then((_) => {
toast({
title: "Vote successful",
status: "success",
duration: 5_000,
});
refresh();
})
.catch((_) => {});

return () => {
controller.abort();
};
}
}, [validator, data, refresh, toast]);
const onTxnCompleted = useCallback(() => {
toast({
title: "Vote successful",
status: "success",
duration: 5_000,
});
refresh();
}, [toast, refresh]);

const onTxnFailed = useCallback(() => {
toast({
title: "Not able to fetch tableland receipt, please refresh the page.",
status: "warning",
duration: 5_000,
});
}, [toast, refresh]);

useWaitForTablelandTxn(
secondaryChain.id,
data?.hash,
onTxnCompleted,
onTxnFailed
);

const isMobile = useBreakpointValue(
{ base: true, lg: false },
Expand Down
43 changes: 9 additions & 34 deletions garage/src/pages/RigDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ import { RigDisplay } from "../../components/RigDisplay";
import { FlightLog } from "./modules/FlightLog";
import { Pilots } from "./modules/Pilots";
import { RigAttributes } from "./modules/RigAttributes";
import { useTablelandConnection } from "../../hooks/useTablelandConnection";
import { useRig } from "../../hooks/useRig";
import { findNFT } from "../../utils/nfts";
import { prettyNumber, truncateWalletAddress } from "../../utils/fmt";
Expand All @@ -52,6 +51,7 @@ import { abi } from "../../abis/TablelandRigs";
import { ReactComponent as OpenseaMark } from "../../assets/opensea-mark.svg";
import { ReactComponent as TablelandMark } from "../../assets/tableland.svg";
import { ReactComponent as FilecoinMark } from "../../assets/filecoin-mark.svg";
import { useWaitForTablelandTxn } from "../../hooks/useWaitForTablelandTxn";

const { contractAddress } = deployment;

Expand Down Expand Up @@ -267,7 +267,6 @@ export const RigDetails = () => {
const { actingAsAddress } = useAccount();
const { data: currentBlockNumber } = useBlockNumber();
const { rig, refresh: refreshRig } = useRig(id || "");
const { validator } = useTablelandConnection();

const { data: contractData, refetch } = useContractReads({
allowFailure: false,
Expand Down Expand Up @@ -325,42 +324,18 @@ export const RigDetails = () => {
sleep(500).then((_) => setPendingTx(undefined));
}, [refresh, setPendingTx]);

// Effect that waits until a tableland receipt is available for a tx hash
// and then refreshes the rig data
useEffect(() => {
if (validator && pendingTx) {
const controller = new AbortController();
const signal = controller.signal;

validator
.pollForReceiptByTransactionHash(
{
chainId: mainChain.id,
transactionHash: pendingTx,
},
{ interval: 2000, signal }
)
.then((_) => {
refreshRigAndClearPendingTx();
})
.catch((_) => {
clearPendingTx();
});

return () => {
controller.abort();
};
}
}, [pendingTx, refreshRigAndClearPendingTx, validator, clearPendingTx]);
useWaitForTablelandTxn(
mainChain.id,
pendingTx,
refreshRigAndClearPendingTx,
clearPendingTx
);

const currentNFT =
rig?.currentPilot && nfts && findNFT(rig.currentPilot, nfts);

const {
trainRigsModal,
pilotRigsModal,
parkRigsModal,
} = useGlobalFlyParkModals();
const { trainRigsModal, pilotRigsModal, parkRigsModal } =
useGlobalFlyParkModals();

const onOpenTrainModal = useCallback(() => {
if (rig) trainRigsModal.openModal([rig], setPendingTx);
Expand Down

0 comments on commit 3e92ae0

Please sign in to comment.