Skip to content

Commit

Permalink
[embed] Add OperationModalContext
Browse files Browse the repository at this point in the history
  • Loading branch information
asiia-trilitech committed Aug 22, 2024
1 parent e5e3489 commit c7803ad
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 53 deletions.
48 changes: 7 additions & 41 deletions apps/embed-iframe/src/OperationModalContent.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { type PartialTezosOperation, TezosOperationType } from "@airgap/beacon-types";
import {
Accordion,
AccordionButton,
Expand All @@ -13,65 +12,32 @@ import {
VStack,
} from "@chakra-ui/react";
import * as Auth from "@umami/social-auth";
import { useEffect, useState } from "react";

import { TezosLogoIcon } from "./assets/icons/TezosLogo";
import { UmamiLogoIcon } from "./assets/icons/UmamiLogo";
import { JsValueWrap } from "./imported/JsValueWrap";

import { getErrorContext } from "./imported/utils/getErrorContext";
import { withTimeout } from "./imported/utils/withTimeout";
import { sendOperationErrorResponse, sendResponse, toSocialAccount, toTezosNetwork } from "./utils";
import { sendOperationErrorResponse, sendResponse, toTezosNetwork } from "./utils";
import { makeToolkit, prettyTezAmount } from "@umami/tezos";
import { useEmbedApp } from "./EmbedAppContext";
import { useColor } from "./imported/style/useColor";
import {
estimate,
EstimatedAccountOperations,
executeOperations,
toAccountOperations,
totalFee,
} from "@umami/core";
import { LoginButtonComponent } from "./LoginButtonComponent";
import { useOperationModalContext } from "./OperationModalContext";

const SIGN_TIMEOUT = 5 * 60 * 1000; // 5 minutes

export const OperationModalContent = ({
operations,
closeModal,
}: {
operations: PartialTezosOperation[];
closeModal: () => void;
}) => {
const [isLoading, setIsLoading] = useState(true);
export const OperationModalContent = () => {
const { onClose, isLoading, setIsLoading, estimatedOperations } = useOperationModalContext();
const { getNetwork, getUserData } = useEmbedApp();
const [estimatedOperations, setEstimatedOperations] = useState<EstimatedAccountOperations | null>(
null
);

const color = useColor();

useEffect(() => {
const fetchEstimatedOperations = async () => {
try {
const accountOperations = toAccountOperations(operations, toSocialAccount(getUserData()!));
const estimatedOperations = await estimate(
accountOperations,
toTezosNetwork(getNetwork()!)
);
setEstimatedOperations(estimatedOperations);
} catch (error) {
// TODO: display error to the user instead?
sendOperationErrorResponse(getErrorContext(error).description);
closeModal();
} finally {
setIsLoading(false);
}
};

fetchEstimatedOperations();
}, [operations, getUserData, getNetwork, closeModal]);

const onClick = async () => {
setIsLoading(true);
try {
Expand All @@ -94,7 +60,7 @@ export const OperationModalContent = ({
sendOperationErrorResponse(getErrorContext(error).description);
} finally {
setIsLoading(false);
closeModal();
onClose();
}
};

Expand Down Expand Up @@ -126,7 +92,7 @@ export const OperationModalContent = ({
<AccordionIcon />
</AccordionButton>
<AccordionPanel>
<JsValueWrap overflowY="auto" maxHeight="200px" value={operations} />
<JsValueWrap overflowY="auto" maxHeight="200px" value={estimatedOperations!.operations} />
</AccordionPanel>
</AccordionItem>
</Accordion>
Expand All @@ -137,7 +103,7 @@ export const OperationModalContent = ({
Count:
</Text>
<Text color={color("900")} data-testid="transaction-length" size="sm">
{operations.length}
{estimatedOperations!.operations.length}
</Text>
</Flex>

Expand Down
39 changes: 39 additions & 0 deletions apps/embed-iframe/src/OperationModalContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useDisclosure } from "@chakra-ui/react";
import { EstimatedAccountOperations } from "@umami/core";
import { createContext, PropsWithChildren, useContext, useState } from "react";

interface OperationModalContextState {
isOpen: boolean;
onOpen: () => void;
onClose: () => void;
isLoading: boolean;
setIsLoading: (isLoading: boolean) => void;
estimatedOperations: EstimatedAccountOperations | null;
setEstimatedOperations: (estimatedOperations: EstimatedAccountOperations | null) => void;
}

const OperationModalContext = createContext<OperationModalContextState | undefined>(undefined);

export const OperationModalProvider = ({ children }: PropsWithChildren) => {
const { isOpen, onOpen, onClose } = useDisclosure();
const [isLoading, setIsLoading] = useState(false);
const [estimatedOperations, setEstimatedOperations] = useState<EstimatedAccountOperations | null>(
null
);

return (
<OperationModalContext.Provider
value={{ isOpen, onOpen, onClose, isLoading, setIsLoading, estimatedOperations, setEstimatedOperations }}
>
{children}
</OperationModalContext.Provider>
);
};

export const useOperationModalContext = (): OperationModalContextState => {
const context = useContext(OperationModalContext);
if (context === undefined) {
throw new Error("useOperationModal must be used within a OperationModalProvider");
}
return context;
};
9 changes: 6 additions & 3 deletions apps/embed-iframe/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import theme from "./imported/style/theme";
import { EmbedAppProvider } from "./EmbedAppContext";
import "./main.scss";
import { LoginModalProvider } from "./LoginModalContext";
import { OperationModalProvider } from "./OperationModalContext";

import { Analytics } from "@vercel/analytics/react";

Expand All @@ -16,9 +17,11 @@ ReactDOM.createRoot(rootElement!).render(
<ChakraProvider theme={theme}>
<EmbedAppProvider>
<LoginModalProvider>
<ColorModeScript initialColorMode={theme.config.initialColorMode} />
<EmbeddedComponent />
<Analytics />
<OperationModalProvider>
<ColorModeScript initialColorMode={theme.config.initialColorMode} />
<EmbeddedComponent />
<Analytics />
</OperationModalProvider>
</LoginModalProvider>
</EmbedAppProvider>
</ChakraProvider>
Expand Down
33 changes: 24 additions & 9 deletions apps/embed-iframe/src/operationModalHooks.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import type { PartialTezosOperation } from "@airgap/beacon-types";
import { Center, Modal, ModalCloseButton, ModalContent, useDisclosure } from "@chakra-ui/react";
import { useState } from "react";
import { Center, Modal, ModalCloseButton, ModalContent } from "@chakra-ui/react";

import { OperationModalContent } from "./OperationModalContent";
import { sendOperationErrorResponse } from "./utils";
import { sendOperationErrorResponse, toSocialAccount, toTezosNetwork } from "./utils";
import { useOperationModalContext } from "./OperationModalContext";
import { ModalLoadingOverlay } from "./ModalLoadingOverlay";
import { estimate, getErrorContext, toAccountOperations } from "@umami/core";
import { useEmbedApp } from "./EmbedAppContext";

export const useOperationModal = () => {
const { isOpen, onOpen, onClose } = useDisclosure();
const [operations, setOperations] = useState<PartialTezosOperation[]>([]);
const { isOpen, onOpen, onClose, isLoading, setEstimatedOperations } = useOperationModalContext();
const { getNetwork, getUserData } = useEmbedApp();

const onModalCLose = () => {
sendOperationErrorResponse("User closed the modal");
Expand All @@ -26,14 +29,26 @@ export const useOperationModal = () => {
>
<ModalContent>
<ModalCloseButton onClick={onModalCLose} />
<OperationModalContent closeModal={onClose} operations={operations} />
<OperationModalContent />
{isLoading && <ModalLoadingOverlay />}
</ModalContent>
</Modal>
</Center>
),
onOpen: (operations: PartialTezosOperation[]) => {
setOperations(operations);
onOpen();
onOpen: async (operations: PartialTezosOperation[]) => {
try {
const accountOperations = toAccountOperations(operations, toSocialAccount(getUserData()!));
const estimatedOperations = await estimate(
accountOperations,
toTezosNetwork(getNetwork()!)
);

setEstimatedOperations(estimatedOperations);
onOpen();
} catch (error) {
sendOperationErrorResponse(getErrorContext(error).description);
onClose();
}
},
};
};

0 comments on commit c7803ad

Please sign in to comment.