Skip to content

Commit

Permalink
feat: optimistic disconnect behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
magiziz committed Mar 19, 2024
1 parent 30691f0 commit de8e6ec
Show file tree
Hide file tree
Showing 12 changed files with 186 additions and 75 deletions.
2 changes: 1 addition & 1 deletion .changeset/wild-hounds-talk.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"@rainbow-me/rainbowkit": patch
---

Disable disconnect buttons when wallet is disconnecting.
Added optimistic disconnect behavior for the account modal and chain modal. Additionally, a new prop `disconnecting` was introduced to `<ConnectButton.Custom>` to enable rendering of UI based on the optimistic behavior.
5 changes: 3 additions & 2 deletions examples/with-next-custom-button/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const Home: NextPage = () => {
<ConnectButton.Custom>
{({
account,
disconnecting,
chain,
openAccountModal,
openChainModal,
Expand All @@ -32,9 +33,9 @@ const Home: NextPage = () => {
})}
>
{(() => {
if (!mounted || !account || !chain) {
if (!mounted || !account || !chain || disconnecting) {
return (
<button onClick={openConnectModal} type="button">
<button disabled={disconnecting} onClick={openConnectModal} type="button">
Connect Wallet
</button>
);
Expand Down
8 changes: 7 additions & 1 deletion packages/example/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ const Example = ({ authEnabled }: AppContextProps) => {
authenticationStatus,
chain,
mounted,
disconnecting,
openAccountModal,
openChainModal,
openConnectModal,
Expand All @@ -137,6 +138,7 @@ const Example = ({ authEnabled }: AppContextProps) => {
const connected =
ready &&
account &&
!disconnecting &&
chain &&
(!authenticationStatus ||
authenticationStatus === 'authenticated');
Expand All @@ -155,7 +157,11 @@ const Example = ({ authEnabled }: AppContextProps) => {
{(() => {
if (!connected) {
return (
<button onClick={openConnectModal} type="button">
<button
disabled={disconnecting}
onClick={openConnectModal}
type="button"
>
Connect Wallet
</button>
);
Expand Down
16 changes: 14 additions & 2 deletions packages/rainbowkit/src/components/AccountModal/AccountModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useMainnetEnsName } from '../../hooks/useMainnetEnsName';
import { Dialog } from '../Dialog/Dialog';
import { DialogContent } from '../Dialog/DialogContent';
import { ProfileDetails } from '../ProfileDetails/ProfileDetails';
import { useRainbowKitWagmiState } from '../RainbowKitProvider/RainbowKitWagmiStateProvider';

export interface AccountModalProps {
open: boolean;
Expand All @@ -15,7 +16,14 @@ export function AccountModal({ onClose, open }: AccountModalProps) {
const { address } = useAccount();
const ensName = useMainnetEnsName(address);
const ensAvatar = useMainnetEnsAvatar(ensName);
const { disconnect } = useDisconnect();
const { setIsDisconnecting } = useRainbowKitWagmiState();

const { disconnect } = useDisconnect({
mutation: {
onSuccess: () => setIsDisconnecting(false),
onError: () => setIsDisconnecting(false),
},
});

if (!address) {
return null;
Expand All @@ -33,7 +41,11 @@ export function AccountModal({ onClose, open }: AccountModalProps) {
ensAvatar={ensAvatar}
ensName={ensName}
onClose={onClose}
onDisconnect={disconnect}
onDisconnect={() => {
onClose();
setIsDisconnecting(true);
disconnect();
}}
/>
</DialogContent>
</Dialog>
Expand Down
16 changes: 14 additions & 2 deletions packages/rainbowkit/src/components/ChainModal/ChainModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { DisconnectSqIcon } from '../Icons/DisconnectSq';
import { MenuButton } from '../MenuButton/MenuButton';
import { I18nContext } from '../RainbowKitProvider/I18nContext';
import { useRainbowKitChains } from '../RainbowKitProvider/RainbowKitChainContext';
import { useRainbowKitWagmiState } from '../RainbowKitProvider/RainbowKitWagmiStateProvider';
import { Text } from '../Text/Text';
import Chain from './Chain';
import {
Expand Down Expand Up @@ -45,7 +46,14 @@ export function ChainModal({ onClose, open }: ChainModalProps) {

const { i18n } = useContext(I18nContext);

const { disconnect } = useDisconnect();
const { disconnect } = useDisconnect({
mutation: {
onSuccess: () => setIsDisconnecting(false),
onError: () => setIsDisconnecting(false),
},
});

const { setIsDisconnecting } = useRainbowKitWagmiState();
const titleId = 'rk_chain_modal_title';
const mobile = isMobile();
const isCurrentChainSupported = chains.some((chain) => chain.id === chainId);
Expand Down Expand Up @@ -116,7 +124,11 @@ export function ChainModal({ onClose, open }: ChainModalProps) {
<>
<Box background="generalBorderDim" height="1" marginX="8" />
<MenuButton
onClick={() => disconnect()}
onClick={() => {
onClose();
setIsDisconnecting(true);
disconnect();
}}
testId="chain-option-disconnect"
>
<Box
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { style } from '@vanilla-extract/css';

export const button = style({
':disabled': {
opacity: 0.75,
pointerEvents: 'none',
},
});
19 changes: 14 additions & 5 deletions packages/rainbowkit/src/components/ConnectButton/ConnectButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { DropdownIcon } from '../Icons/Dropdown';
import { I18nContext } from '../RainbowKitProvider/I18nContext';
import { useRainbowKitChains } from '../RainbowKitProvider/RainbowKitChainContext';
import { useShowBalance } from '../RainbowKitProvider/ShowBalanceContext';
import * as styles from './ConnectButton.css';
import { ConnectButtonRenderer } from './ConnectButtonRenderer';

type AccountStatus = 'full' | 'avatar' | 'address';
Expand Down Expand Up @@ -58,6 +59,7 @@ export function ConnectButton({
account,
chain,
mounted,
disconnecting,
openAccountModal,
openChainModal,
openConnectModal,
Expand All @@ -78,7 +80,10 @@ export function ConnectButton({
},
})}
>
{ready && account && connectionStatus === 'connected' ? (
{ready &&
account &&
!disconnecting &&
connectionStatus === 'connected' ? (
<>
{chain && (chains.length > 1 || unsupportedChain) && (
<Box
Expand Down Expand Up @@ -266,15 +271,19 @@ export function ConnectButton({
background="accentColor"
borderRadius="connectButton"
boxShadow="connectButton"
className={touchableStyles({
active: 'shrink',
hover: 'grow',
})}
className={[
styles.button,
touchableStyles({
active: 'shrink',
hover: 'grow',
}),
]}
color="accentColorForeground"
fontFamily="body"
fontWeight="bold"
height="40"
key="connect"
disabled={disconnecting}
onClick={openConnectModal}
paddingX="14"
testId="connect-button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
useModalState,
} from '../RainbowKitProvider/ModalContext';
import { useRainbowKitChainsById } from '../RainbowKitProvider/RainbowKitChainContext';
import { useRainbowKitWagmiState } from '../RainbowKitProvider/RainbowKitWagmiStateProvider';
import { useShowBalance } from '../RainbowKitProvider/ShowBalanceContext';
import { ShowRecentTransactionsContext } from '../RainbowKitProvider/ShowRecentTransactionsContext';
import { abbreviateETHBalance } from './abbreviateETHBalance';
Expand Down Expand Up @@ -48,6 +49,7 @@ export interface ConnectButtonRendererProps {
unsupported?: boolean;
};
mounted: boolean;
disconnecting: boolean;
authenticationStatus?: AuthenticationStatus;
openAccountModal: () => void;
openChainModal: () => void;
Expand All @@ -65,7 +67,6 @@ export function ConnectButtonRenderer({
const { address } = useAccount();
const ensName = useMainnetEnsName(address);
const ensAvatar = useMainnetEnsAvatar(ensName);

const { chainId } = useAccount();
const { chains: wagmiChains } = useConfig();
const isCurrentChainSupported = wagmiChains.some(
Expand Down Expand Up @@ -115,6 +116,7 @@ export function ConnectButtonRenderer({
const { openConnectModal } = useConnectModal();
const { openChainModal } = useChainModal();
const { openAccountModal } = useAccountModal();
const { isDisconnecting: disconnecting } = useRainbowKitWagmiState();
const { accountModalOpen, chainModalOpen, connectModalOpen } =
useModalState();

Expand Down Expand Up @@ -151,6 +153,7 @@ export function ConnectButtonRenderer({
chainModalOpen,
connectModalOpen,
mounted: isMounted(),
disconnecting,
openAccountModal: openAccountModal ?? noop,
openChainModal: openChainModal ?? noop,
openConnectModal: openConnectModal ?? noop,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { AccountModal } from '../AccountModal/AccountModal';
import { ChainModal } from '../ChainModal/ChainModal';
import { ConnectModal } from '../ConnectModal/ConnectModal';
import { useAuthenticationStatus } from './AuthenticationContext';
import { useRainbowKitWagmiState } from './RainbowKitWagmiStateProvider';

function useModalStateValue() {
const [isModalOpen, setModalOpen] = useState(false);
Expand Down Expand Up @@ -66,6 +67,8 @@ export function ModalProvider({ children }: ModalProviderProps) {
openModal: openChainModal,
} = useModalStateValue();

const { isDisconnecting } = useRainbowKitWagmiState();

const [isWalletConnectModalOpen, setIsWalletConnectModalOpen] =
useState(false);

Expand Down Expand Up @@ -113,19 +116,25 @@ export function ModalProvider({ children }: ModalProviderProps) {
connectModalOpen,
isWalletConnectModalOpen,
openAccountModal:
isCurrentChainSupported && connectionStatus === 'connected'
!isDisconnecting &&
isCurrentChainSupported &&
connectionStatus === 'connected'
? openAccountModal
: undefined,
openChainModal:
connectionStatus === 'connected' ? openChainModal : undefined,
!isDisconnecting && connectionStatus === 'connected'
? openChainModal
: undefined,
openConnectModal:
connectionStatus === 'disconnected' ||
connectionStatus === 'unauthenticated'
(connectionStatus === 'disconnected' ||
connectionStatus === 'unauthenticated') &&
!isDisconnecting
? openConnectModal
: undefined,
setIsWalletConnectModalOpen,
}),
[
isDisconnecting,
connectionStatus,
accountModalOpen,
chainModalOpen,
Expand Down
Loading

0 comments on commit de8e6ec

Please sign in to comment.