Skip to content

Commit

Permalink
Grant modal UI fixes for mobile (#57)
Browse files Browse the repository at this point in the history
* Added changeset

* Added logs and mobile fix

* Trying in tab strategy

* Added polling

* Polished polling

* Update dashboard url

* Testing fetch fix

* Cleanup, isolated types

* Updated connection

* Added connecting modal, simplified flow

* Added close button to connected modal

* Removed old prop

* Fixed destructuring error

* Added new changeset

---------

Co-authored-by: justin <[email protected]>
  • Loading branch information
BurntNerve and justinbarry authored Feb 5, 2024
1 parent e7a8b2b commit 5e0d06f
Show file tree
Hide file tree
Showing 14 changed files with 208 additions and 78 deletions.
7 changes: 7 additions & 0 deletions .changeset/calm-coats-approve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@burnt-labs/abstraxion": major
"abstraxion-dashboard": minor
"demo-app": minor
---

Moved display logic to internal "useModal" hook. Consumers will need to change their strategy from a custom piece of state within their app to utilizing this new hook. The login flow will now be a single tab experience.
6 changes: 6 additions & 0 deletions .changeset/odd-planets-hammer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"abstraxion-dashboard": minor
"@burnt-labs/ui": minor
---

Added font files and small ui tweaks
22 changes: 21 additions & 1 deletion apps/abstraxion-dashboard/components/AbstraxionGrant/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"use client";
import { useState } from "react";
import { useState, useEffect } from "react";
import Image from "next/image";
import { Button, Spinner } from "@burnt-labs/ui";
import { MsgGrant } from "cosmjs-types/cosmos/authz/v1beta1/tx";
Expand All @@ -11,6 +11,7 @@ import { useAbstraxionAccount, useAbstraxionSigningClient } from "@/hooks";
import burntAvatar from "@/public/burntAvatarCircle.png";
import { CheckIcon } from "../Icons";
import { EncodeObject } from "@cosmjs/proto-signing";
import { redirect, useSearchParams } from "next/navigation";

interface AbstraxionGrantProps {
contracts: string[];
Expand All @@ -23,10 +24,29 @@ export const AbstraxionGrant = ({
}: AbstraxionGrantProps) => {
const { client } = useAbstraxionSigningClient();
const { data: account } = useAbstraxionAccount();
const searchParams = useSearchParams();

const [inProgress, setInProgress] = useState(false);
const [showSuccess, setShowSuccess] = useState(false);

useEffect(function redirectToDapp() {
if (showSuccess && searchParams.get("redirect_uri")) {
let redirectUri = new URLSearchParams(window.location.search).get(
"redirect_uri",
);
let url: URL | null = null;
if (redirectUri) {
url = new URL(redirectUri);
let params = new URLSearchParams(url.search);

params.append("granted", "true");
url.search = params.toString();
redirectUri = url.toString();
window.location.href = redirectUri;
}
}
});

const generateContractGrant = (granter: string) => {
const timestampThreeMonthsFromNow = Math.floor(
new Date(new Date().setMonth(new Date().getMonth() + 3)).getTime() / 1000,
Expand Down
16 changes: 10 additions & 6 deletions apps/demo-app/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Abstraxion,
useAbstraxionAccount,
useAbstraxionSigningClient,
useModal,
} from "@burnt-labs/abstraxion";
import { Button } from "@burnt-labs/ui";
import "@burnt-labs/ui/styles.css";
Expand All @@ -13,19 +14,23 @@ import { seatContractAddress } from "./layout";

type ExecuteResultOrUndefined = ExecuteResult | undefined;
export default function Page(): JSX.Element {
// console.log("hello");
// Abstraxion hooks
const { data: account } = useAbstraxionAccount();
const { client } = useAbstraxionSigningClient();

// General state hooks
const [isOpen, setIsOpen] = useState(false);
const [, setShowModal]: [
boolean,
React.Dispatch<React.SetStateAction<boolean>>,
] = useModal();
const [loading, setLoading] = useState(false);
const [executeResult, setExecuteResult] =
useState<ExecuteResultOrUndefined>(undefined);

const blockExplorerUrl = `https://explorer.burnt.com/xion-testnet-1/tx/${executeResult?.transactionHash}`;

function getTimestampInSeconds(date: Date | null) {
function getTimestampInSeconds(date: Date | null): number {
if (!date) return 0;
const d = new Date(date);
return Math.floor(d.getTime() / 1000);
Expand All @@ -36,7 +41,7 @@ export default function Page(): JSX.Element {
const oneYearFromNow = new Date();
oneYearFromNow.setFullYear(oneYearFromNow.getFullYear() + 1);

async function claimSeat() {
async function claimSeat(): Promise<void> {
setLoading(true);
const msg = {
sales: {
Expand Down Expand Up @@ -79,7 +84,7 @@ export default function Page(): JSX.Element {
<Button
fullWidth
onClick={() => {
setIsOpen(true);
setShowModal(true);
}}
structure="base"
>
Expand All @@ -102,9 +107,8 @@ export default function Page(): JSX.Element {
</Button>
) : null}
<Abstraxion
isOpen={isOpen}
onClose={() => {
setIsOpen(false);
setShowModal(false);
}}
/>
{executeResult ? (
Expand Down
1 change: 1 addition & 0 deletions packages/abstraxion/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ module.exports = {
rules: {
"no-nested-ternary": "off",
"no-unnecessary-condition": "off",
"@typescript-eslint/no-floating-promises": "off",
},
};
36 changes: 36 additions & 0 deletions packages/abstraxion/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export interface GrantsResponse {
grants: Grant[];
pagination: Pagination;
}

export interface Grant {
granter: string;
grantee: string;
authorization: Authorization;
expiration: string;
}

export interface Authorization {
"@type": string;
grants: GrantAuthorization[];
}

export interface GrantAuthorization {
contract: string;
limit: Limit;
filter: Filter;
}

export interface Limit {
"@type": string;
remaining: string;
}

export interface Filter {
"@type": string;
}

export interface Pagination {
next_key: null | string;
total: string;
}
28 changes: 17 additions & 11 deletions packages/abstraxion/src/components/Abstraxion/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,43 @@ import {
AbstraxionContext,
AbstraxionContextProvider,
} from "../AbstraxionContext";
import { AbstraxionSignin } from "../AbstraxionSignin";
import { Loading } from "../Loading";
import { ErrorDisplay } from "../ErrorDisplay";
import { Connected } from "../Connected/Connected";
import { AbstraxionSignin } from "../AbstraxionSignin";

export interface ModalProps {
onClose: VoidFunction;
isOpen: boolean;
}

export function Abstraxion({
isOpen,
onClose,
}: ModalProps): JSX.Element | null {
const { abstraxionError, isConnecting, isConnected } =
useContext(AbstraxionContext);
export function Abstraxion({ onClose }: ModalProps): JSX.Element | null {
const {
abstraxionError,
isConnecting,
isConnected,
showModal,
setShowModal,
} = useContext(AbstraxionContext);

useEffect(() => {
const closeOnEscKey = (e: KeyboardEventInit): void => {
e.key === "Escape" ? onClose() : null;
e.key === "Escape"
? () => {
onClose();
setShowModal(false);
}
: null;
};
document.addEventListener("keydown", closeOnEscKey);
return () => {
document.removeEventListener("keydown", closeOnEscKey);
};
}, [onClose]);

if (!isOpen) return null;
if (!showModal) return null;

return (
<Dialog open={isOpen} onOpenChange={onClose}>
<Dialog onOpenChange={onClose} open={showModal}>
<DialogContent>
{abstraxionError ? (
<ErrorDisplay />
Expand Down
29 changes: 21 additions & 8 deletions packages/abstraxion/src/components/AbstraxionContext/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ReactNode, createContext, useState } from "react";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import type { ReactNode } from "react";
import { useEffect, createContext, useState } from "react";
import type { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";

export interface AbstraxionContextProps {
isConnected: boolean;
Expand All @@ -11,7 +12,9 @@ export interface AbstraxionContextProps {
abstraxionAccount: DirectSecp256k1HdWallet | undefined;
setAbstraxionAccount: React.Dispatch<DirectSecp256k1HdWallet | undefined>;
granterAddress: string;
setgranterAddress: React.Dispatch<React.SetStateAction<string>>;
showModal: boolean;
setShowModal: React.Dispatch<React.SetStateAction<boolean>>;
setGranterAddress: React.Dispatch<React.SetStateAction<string>>;
contracts?: string[];
dashboardUrl?: string;
}
Expand All @@ -20,22 +23,30 @@ export const AbstraxionContext = createContext<AbstraxionContextProps>(
{} as AbstraxionContextProps,
);

export const AbstraxionContextProvider = ({
export function AbstraxionContextProvider({
children,
contracts,
dashboardUrl = "https://dashboard.burnt.com",
}: {
children: ReactNode;
contracts?: string[];
dashboardUrl?: string;
}) => {
}): JSX.Element {
const [abstraxionError, setAbstraxionError] = useState("");
const [isConnected, setIsConnected] = useState(false);
const [isConnecting, setIsConnecting] = useState(false);
const [showModal, setShowModal] = useState(false);
const [abstraxionAccount, setAbstraxionAccount] = useState<
DirectSecp256k1HdWallet | undefined
>(undefined);
const [granterAddress, setgranterAddress] = useState("");
const [granterAddress, setGranterAddress] = useState("");

useEffect(() => {
const searchParams = new URLSearchParams(window.location.search);
if (searchParams.get("granted") === "true") {
setShowModal(true);
}
}, []);

return (
<AbstraxionContext.Provider
Expand All @@ -49,12 +60,14 @@ export const AbstraxionContextProvider = ({
abstraxionAccount,
setAbstraxionAccount,
granterAddress,
setgranterAddress,
showModal,
setShowModal,
setGranterAddress,
contracts,
dashboardUrl,
}}
>
{children}
</AbstraxionContext.Provider>
);
};
}
Loading

0 comments on commit 5e0d06f

Please sign in to comment.