Skip to content

Commit

Permalink
Show Reconnect button if the installed snap is a local snap (MetaMask#10
Browse files Browse the repository at this point in the history
)

* Show Connect button if the installed snap is a local snap

* show a reconnect button instead of the regular connect button

* apply requested changes

* fix fullwidth logic
  • Loading branch information
GuillaumeRx authored Sep 29, 2022
1 parent 3bfcb8a commit 67c0ff3
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 39 deletions.
19 changes: 17 additions & 2 deletions packages/site/src/components/Buttons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ComponentProps } from 'react';
import styled from 'styled-components';
import { MetamaskState } from '../hooks';
import { ReactComponent as FlaskFox } from '../assets/flask_fox.svg';
import { shouldDisplayReconnectButton } from '../utils';

const Link = styled.a`
display: flex;
Expand Down Expand Up @@ -36,6 +37,7 @@ const Button = styled.button`
align-self: flex-start;
align-items: center;
justify-content: center;
margin-top: auto;
${({ theme }) => theme.mediaQueries.small} {
width: 100%;
}
Expand Down Expand Up @@ -83,6 +85,15 @@ export const ConnectButton = (props: ComponentProps<typeof Button>) => {
);
};

export const ReconnectButton = (props: ComponentProps<typeof Button>) => {
return (
<Button {...props}>
<FlaskFox />
<ButtonText>Reconnect</ButtonText>
</Button>
);
};

export const SendHelloButton = (props: ComponentProps<typeof Button>) => {
return <Button {...props}>Send message</Button>;
};
Expand All @@ -94,14 +105,18 @@ export const HeaderButtons = ({
state: MetamaskState;
onConnectClick(): unknown;
}) => {
if (!state.isFlask && !state.isSnapInstalled) {
if (!state.isFlask && !state.installedSnap) {
return <InstallFlaskButton />;
}

if (!state.isSnapInstalled) {
if (!state.installedSnap) {
return <ConnectButton onClick={onConnectClick} />;
}

if (shouldDisplayReconnectButton(state.installedSnap)) {
return <ReconnectButton onClick={onConnectClick} />;
}

return (
<ConnectedContainer>
<ConnectedIndicator />
Expand Down
6 changes: 3 additions & 3 deletions packages/site/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useContext } from 'react';
import styled, { useTheme } from 'styled-components';
import { MetamaskActions, MetaMaskContext } from '../hooks';
import { connectSnap, getThemePreference, isSnapInstalled } from '../utils';
import { connectSnap, getThemePreference, getSnap } from '../utils';
import { HeaderButtons } from './Buttons';
import { SnapLogo } from './SnapLogo';
import { Toggle } from './Toggle';
Expand Down Expand Up @@ -48,11 +48,11 @@ export const Header = ({
const handleConnectClick = async () => {
try {
await connectSnap();
const snapInstalled = await isSnapInstalled();
const installedSnap = await getSnap();

dispatch({
type: MetamaskActions.SetInstalled,
payload: snapInstalled,
payload: installedSnap,
});
} catch (e) {
console.error(e);
Expand Down
46 changes: 38 additions & 8 deletions packages/site/src/components/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { useContext } from 'react';
import styled from 'styled-components';
import { MetamaskActions, MetaMaskContext } from '../hooks';
import { connectSnap, isSnapInstalled, sendHello } from '../utils';
import { ConnectButton, InstallFlaskButton, SendHelloButton } from './Buttons';
import {
connectSnap,
getSnap,
sendHello,
shouldDisplayReconnectButton,
} from '../utils';
import {
ConnectButton,
InstallFlaskButton,
ReconnectButton,
SendHelloButton,
} from './Buttons';
import { Card } from './Card';

const Container = styled.div`
Expand Down Expand Up @@ -95,11 +105,11 @@ export const Home = () => {
const handleConnectClick = async () => {
try {
await connectSnap();
const snapInstalled = await isSnapInstalled();
const installedSnap = await getSnap();

dispatch({
type: MetamaskActions.SetInstalled,
payload: snapInstalled,
payload: installedSnap,
});
} catch (e) {
console.error(e);
Expand Down Expand Up @@ -141,7 +151,7 @@ export const Home = () => {
fullWidth
/>
)}
{!state.isSnapInstalled && (
{!state.installedSnap && (
<Card
content={{
title: 'Connect',
Expand All @@ -157,6 +167,22 @@ export const Home = () => {
disabled={!state.isFlask}
/>
)}
{shouldDisplayReconnectButton(state.installedSnap) && (
<Card
content={{
title: 'Reconnect',
description:
'While connected to a local running snap this button will always be displayed in order to update the snap if a change is made.',
button: (
<ReconnectButton
onClick={handleConnectClick}
disabled={!state.installedSnap}
/>
),
}}
disabled={!state.installedSnap}
/>
)}
<Card
content={{
title: 'Send Hello message',
Expand All @@ -165,12 +191,16 @@ export const Home = () => {
button: (
<SendHelloButton
onClick={handleSendHelloClick}
disabled={!state.isSnapInstalled}
disabled={!state.installedSnap}
/>
),
}}
disabled={!state.isSnapInstalled}
fullWidth={state.isFlask && state.isSnapInstalled}
disabled={!state.installedSnap}
fullWidth={
state.isFlask &&
Boolean(state.installedSnap) &&
!shouldDisplayReconnectButton(state.installedSnap)
}
/>
<Notice>
<p>
Expand Down
12 changes: 6 additions & 6 deletions packages/site/src/hooks/MetamaskContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import {
useEffect,
useReducer,
} from 'react';
import { isFlask, isSnapInstalled } from '../utils';
import { Snap } from '../types';
import { isFlask, getSnap } from '../utils';

export type MetamaskState = {
isSnapInstalled: boolean;
isFlask: boolean;
installedSnap?: Snap;
error?: Error;
};

const initialState: MetamaskState = {
isSnapInstalled: false,
isFlask: false,
error: undefined,
};
Expand All @@ -42,7 +42,7 @@ const reducer: Reducer<MetamaskState, MetamaskDispatch> = (state, action) => {
case MetamaskActions.SetInstalled:
return {
...state,
isSnapInstalled: action.payload,
installedSnap: action.payload,
};

case MetamaskActions.SetFlaskDetected:
Expand Down Expand Up @@ -83,10 +83,10 @@ export const MetaMaskProvider = ({ children }: { children: ReactNode }) => {
}

async function detectSnapInstalled() {
const snapInstalled = await isSnapInstalled();
const installedSnap = await getSnap();
dispatch({
type: MetamaskActions.SetInstalled,
payload: snapInstalled,
payload: installedSnap,
});
}

Expand Down
2 changes: 1 addition & 1 deletion packages/site/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { type GetSnapsResponse } from './snap';
export { type GetSnapsResponse, type Snap } from './snap';
14 changes: 7 additions & 7 deletions packages/site/src/types/snap.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export type GetSnapsResponse = {
[k: string]: {
permissionName?: string;
id?: string;
version?: string;
initialPermissions?: { [k: string]: unknown };
};
export type GetSnapsResponse = Record<string, Snap>;

export type Snap = {
permissionName: string;
id: string;
version: string;
initialPermissions: Record<string, unknown>;
};
5 changes: 5 additions & 0 deletions packages/site/src/utils/button.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Snap } from '../types';
import { isLocalSnap } from './snap';

export const shouldDisplayReconnectButton = (installedSnap?: Snap) =>
installedSnap && isLocalSnap(installedSnap?.id);
1 change: 1 addition & 0 deletions packages/site/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './metamask';
export * from './snap';
export * from './theme';
export * from './localStorage';
export * from './button';
23 changes: 11 additions & 12 deletions packages/site/src/utils/snap.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { defaultSnapOrigin } from '../config';
import { GetSnapsResponse } from '../types';
import { GetSnapsResponse, Snap } from '../types';

/**
* Get the installed snaps in MetaMask.
Expand Down Expand Up @@ -37,25 +37,22 @@ export const connectSnap = async (
};

/**
* Check if a snap is already installed in MetaMask.
* Get the snap from MetaMask.
*
* @param version - The version of the snap to install (optional).
* @returns A boolean representing if the snap is installed in MetaMask.
* @returns The snap object returned by the extension.
*/
export const isSnapInstalled = async (version?: string): Promise<boolean> => {
export const getSnap = async (version?: string): Promise<Snap | undefined> => {
try {
const snaps = await getSnaps();

return Boolean(
Object.values(snaps).find(
(snap) =>
snap.id === defaultSnapOrigin &&
(!version || snap.version === version),
),
return Object.values(snaps).find(
(snap) =>
snap.id === defaultSnapOrigin && (!version || snap.version === version),
);
} catch (e) {
console.log('Failed to obtain installed snaps', e);
return false;
console.log('Failed to obtain installed snap', e);
return undefined;
}
};

Expand All @@ -74,3 +71,5 @@ export const sendHello = async () => {
],
});
};

export const isLocalSnap = (snapId: string) => snapId.startsWith('local:');

0 comments on commit 67c0ff3

Please sign in to comment.