Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into ezeth
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] committed Nov 6, 2024
2 parents 1267e3f + 0a7891a commit 2461873
Show file tree
Hide file tree
Showing 15 changed files with 280 additions and 82 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
"@emotion/react": "^11.13.0",
"@emotion/styled": "^11.13.0",
"@headlessui/react": "^1.7.14",
"@hyperlane-xyz/registry": "4.8.1",
"@hyperlane-xyz/sdk": "5.5.0",
"@hyperlane-xyz/utils": "5.5.0",
"@hyperlane-xyz/widgets": "5.5.0",
"@hyperlane-xyz/registry": "5.0.0",
"@hyperlane-xyz/sdk": "5.6.2",
"@hyperlane-xyz/utils": "5.6.2",
"@hyperlane-xyz/widgets": "5.6.2",
"@interchain-ui/react": "^1.23.28",
"@metamask/jazzicon": "https://github.com/jmrossy/jazzicon#7a8df28974b4e81129bfbe3cab76308b889032a6",
"@metamask/post-message-stream": "6.1.2",
Expand Down
30 changes: 30 additions & 0 deletions src/components/icons/Docs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { memo } from 'react';

import { Color } from '../../styles/Color';
import { IconProps } from './types';

function _DocsIcon({
width = 24,
height = 24,
className,
color = Color.black,
...props
}: IconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
viewBox="0 -960 960 960"
className={className}
{...props}
>
<path
fill={color}
d="M320-440h320v-80H320v80Zm0 120h320v-80H320v80Zm0 120h200v-80H320v80ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"
/>
</svg>
);
}

export const DocsIcon = memo(_DocsIcon);
30 changes: 30 additions & 0 deletions src/components/icons/History.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { memo } from 'react';

import { Color } from '../../styles/Color';
import { IconProps } from './types';

function _HistoryIcon({
width = 24,
height = 24,
className,
color = Color.black,
...props
}: IconProps) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
viewBox="0 -960 960 960"
className={className}
{...props}
>
<path
fill={color}
d="M480-120q-138 0-240.5-91.5T122-440h82q14 104 92.5 172T480-200q117 0 198.5-81.5T760-480q0-117-81.5-198.5T480-760q-69 0-129 32t-101 88h110v80H120v-240h80v94q51-64 124.5-99T480-840q75 0 140.5 28.5t114 77q48.5 48.5 77 114T840-480q0 75-28.5 140.5t-77 114q-48.5 48.5-114 77T480-120Zm112-192L440-464v-216h80v184l128 128-56 56Z"
/>
</svg>
);
}

export const HistoryIcon = memo(_HistoryIcon);
30 changes: 30 additions & 0 deletions src/components/icons/Wallet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { memo } from 'react';

import { Color } from '../../styles/Color';
import { IconProps } from './types';

function _WalletIcon({
width = 17,
height = 14,
className,
color = Color.black,
...props
}: IconProps) {
return (
<svg
width={width}
height={height}
viewBox="0 0 17 14"
xmlns="http://www.w3.org/2000/svg"
className={className}
{...props}
>
<path
d="M3.33333 13.4737C2.41667 13.4737 1.63194 13.1439 0.979167 12.4842C0.326389 11.8246 0 11.0316 0 10.1053V3.36842C0 2.44211 0.326389 1.64912 0.979167 0.989474C1.63194 0.329825 2.41667 0 3.33333 0H13.3333C14.25 0 15.0347 0.329825 15.6875 0.989474C16.3403 1.64912 16.6667 2.44211 16.6667 3.36842V10.1053C16.6667 11.0316 16.3403 11.8246 15.6875 12.4842C15.0347 13.1439 14.25 13.4737 13.3333 13.4737H3.33333ZM3.33333 3.57895H13.3333C13.7361 3.57895 14.1146 3.64211 14.4687 3.76842C14.8229 3.89474 15.1389 4.07719 15.4167 4.31579V3.36842C15.4167 2.77895 15.2153 2.2807 14.8125 1.87368C14.4097 1.46667 13.9167 1.26316 13.3333 1.26316H3.33333C2.75 1.26316 2.25694 1.46667 1.85417 1.87368C1.45139 2.2807 1.25 2.77895 1.25 3.36842V4.31579C1.52778 4.07719 1.84375 3.89474 2.19792 3.76842C2.55208 3.64211 2.93056 3.57895 3.33333 3.57895ZM1.3125 6.4421L11.25 8.86316C11.3472 8.89123 11.4479 8.89474 11.5521 8.87368C11.6562 8.85263 11.7431 8.80702 11.8125 8.73684L15.1458 5.91579C14.9653 5.59298 14.7153 5.33333 14.3958 5.13684C14.0764 4.94035 13.7222 4.84211 13.3333 4.84211H3.33333C2.84722 4.84211 2.41667 4.99298 2.04167 5.29474C1.66667 5.59649 1.42361 5.97895 1.3125 6.4421Z"
fill={color}
/>
</svg>
);
}

export const WalletIcon = memo(_WalletIcon);
6 changes: 6 additions & 0 deletions src/components/icons/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { SVGProps } from 'react';

// TODO: Replace with DefaultIconProps in widgets lib
export type IconProps = SVGProps<SVGSVGElement> & {
color?: string;
};
28 changes: 28 additions & 0 deletions src/components/layout/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,26 @@ import Head from 'next/head';
import { PropsWithChildren } from 'react';

import { APP_NAME, BACKGROUND_COLOR, BACKGROUND_IMAGE } from '../../consts/app';
import { useStore } from '../../features/store';
import { SideBarMenu } from '../../features/wallet/SideBarMenu';
import { WalletEnvSelectionModal } from '../../features/wallet/WalletEnvSelectionModal';
import { useAccounts } from '../../features/wallet/hooks/multiProtocol';
import { Footer } from '../nav/Footer';
import { Header } from '../nav/Header';

export function AppLayout({ children }: PropsWithChildren) {
const { readyAccounts } = useAccounts();
const numReady = readyAccounts.length;

const { showEnvSelectModal, setShowEnvSelectModal, isSideBarOpen, setIsSideBarOpen } = useStore(
(s) => ({
showEnvSelectModal: s.showEnvSelectModal,
setShowEnvSelectModal: s.setShowEnvSelectModal,
isSideBarOpen: s.isSideBarOpen,
setIsSideBarOpen: s.setIsSideBarOpen,
}),
);

return (
<>
<Head>
Expand All @@ -24,6 +40,18 @@ export function AppLayout({ children }: PropsWithChildren) {
</div>
<Footer />
</div>

<WalletEnvSelectionModal
isOpen={showEnvSelectModal}
close={() => setShowEnvSelectModal(false)}
/>
{numReady > 0 && (
<SideBarMenu
onClose={() => setIsSideBarOpen(false)}
isOpen={isSideBarOpen}
onConnectWallet={() => setShowEnvSelectModal(true)}
/>
)}
</>
);
}
Expand Down
39 changes: 17 additions & 22 deletions src/components/nav/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
import Image from 'next/image';
import Link from 'next/link';
import { ReactNode } from 'react';

import { links } from '../../consts/links';
import { Discord } from '../icons/Discord';
import { Github } from '../icons/Github';
import { Twitter } from '../icons/Twitter';

const footerLinks1 = [
{ title: 'Docs', url: links.docs, external: true },
{ title: 'Homepage', url: links.home, external: true },
{ title: 'Explorer', url: links.explorer, external: true },
];
type FooterLink = {
title: string;
url: string;
external: boolean;
icon?: ReactNode;
};

const footerLinks3 = [
const footerLinks: FooterLink[] = [
{ title: 'Docs', url: links.docs, external: true },
{ title: 'Terms', url: links.tos, external: true },
{ title: 'Twitter', url: links.twitter, external: true, icon: <Twitter fill="#fff" /> },
{ title: 'Homepage', url: links.home, external: true },
{ title: 'Privacy', url: links.privacyPolicy, external: true },
{ title: 'Discord', url: links.discord, external: true, icon: <Discord fill="#fff" /> },
{ title: 'Explorer', url: links.explorer, external: true },
{ title: 'Bounty', url: links.bounty, external: true },
{ title: 'Github', url: links.github, external: true, icon: <Github fill="#fff" /> },
];

Expand Down Expand Up @@ -46,21 +54,8 @@ function FooterLogo() {
function FooterNav() {
return (
<nav className="flex text-md font-medium">
<ul className={`${styles.linkCol} mr-14`}>
{footerLinks1.map((item) => (
<li className="" key={item.title}>
<Link
className={styles.linkItem}
target={item.external ? '_blank' : '_self'}
href={item.url}
>
<div className="">{item.title}</div>
</Link>
</li>
))}
</ul>
<ul className={`${styles.linkCol}`}>
{footerLinks3.map((item) => (
<ul className={`${styles.linkGrid}`}>
{footerLinks.map((item) => (
<li key={item.title}>
<Link
className={styles.linkItem}
Expand All @@ -78,6 +73,6 @@ function FooterNav() {
}

const styles = {
linkCol: 'flex flex-col gap-1.5',
linkGrid: 'grid grid-cols-3 gap-x-6 gap-y-1.5',
linkItem: 'flex items-center capitalize text-decoration-none hover:underline underline-offset-2',
};
5 changes: 5 additions & 0 deletions src/consts/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ export const links = {
discord: 'https://discord.gg/VK9ZUy3aTV',
github: 'https://github.com/hyperlane-xyz/hyperlane-warp-ui-template',
docs: 'https://docs.hyperlane.xyz',
warpDocs: 'https://docs.hyperlane.xyz/docs/reference/applications/warp-routes',
gasDocs: 'https://docs.hyperlane.xyz/docs/reference/hooks/interchain-gas',
chains: 'https://docs.hyperlane.xyz/docs/resources/domains',
twitter: 'https://twitter.com/hyperlane',
blog: 'https://medium.com/hyperlane',
tos: 'https://hyperlane.xyz/terms-of-service',
privacyPolicy: 'https://hyperlane.xyz/privacy-policy',
bounty:
'https://github.com/search?q=org:hyperlane-xyz+label:bounty+is:open+is:issue&type=issues&s=&o=desc',
};
12 changes: 12 additions & 0 deletions src/features/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export interface AppState {
failUnconfirmedTransfers: () => void;
transferLoading: boolean;
setTransferLoading: (isLoading: boolean) => void;
isSideBarOpen: boolean;
setIsSideBarOpen: (isOpen: boolean) => void;
showEnvSelectModal: boolean;
setShowEnvSelectModal: (show: boolean) => void;
}

export const useStore = create<AppState>()(
Expand Down Expand Up @@ -55,6 +59,14 @@ export const useStore = create<AppState>()(
setTransferLoading: (isLoading) => {
set(() => ({ transferLoading: isLoading }));
},
isSideBarOpen: false,
setIsSideBarOpen: (isSideBarOpen) => {
set(() => ({ isSideBarOpen }));
},
showEnvSelectModal: false,
setShowEnvSelectModal: (showEnvSelectModal) => {
set(() => ({ showEnvSelectModal }));
},
}),
{
name: 'app-state',
Expand Down
27 changes: 9 additions & 18 deletions src/features/wallet/WalletControlBar.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import Image from 'next/image';
import { useState } from 'react';

import { ProtocolType, shortenAddress } from '@hyperlane-xyz/utils';
import { ChevronIcon } from '@hyperlane-xyz/widgets';

import { SolidButton } from '../../components/buttons/SolidButton';
import { WalletLogo } from '../../components/icons/WalletLogo';
import Wallet from '../../images/icons/wallet.svg';
import { useIsSsr } from '../../utils/ssr';
import { useStore } from '../store';

import { SideBarMenu } from './SideBarMenu';
import { WalletEnvSelectionModal } from './WalletEnvSelectionModal';
import { useAccounts, useWalletDetails } from './hooks/multiProtocol';

export function WalletControlBar() {
const isSsr = useIsSsr();

const [showEnvSelectModal, setShowEnvSelectModal] = useState(false);
const [isSideBarOpen, setIsSideBarOpen] = useState(false);
const { setShowEnvSelectModal, setIsSideBarOpen } = useStore((s) => ({
setShowEnvSelectModal: s.setShowEnvSelectModal,
setIsSideBarOpen: s.setIsSideBarOpen,
}));

const { readyAccounts } = useAccounts();
const walletDetails = useWalletDetails();
Expand Down Expand Up @@ -47,7 +48,7 @@ export function WalletControlBar() {

{numReady === 1 && (
<SolidButton onClick={() => setIsSideBarOpen(true)} classes="px-2.5 py-1" color="white">
<div className="flex items-center justify-center">
<div className="flex w-36 items-center justify-center xs:w-auto">
<WalletLogo walletDetails={firstWallet} size={26} />
<div className="mx-3 flex flex-col items-start">
<div className="text-xs text-gray-500">{firstWallet.name || 'Wallet'}</div>
Expand All @@ -57,6 +58,7 @@ export function WalletControlBar() {
: 'Unknown'}
</div>
</div>
<ChevronIcon direction="s" width={10} height={6} />
</div>
</SolidButton>
)}
Expand All @@ -74,22 +76,11 @@ export function WalletControlBar() {
<div className="text-xs text-gray-500">Wallets</div>
<div className="text-xs">{`${numReady} Connected`}</div>
</div>
<ChevronIcon direction="s" width={10} height={6} />
</div>
</SolidButton>
)}
</div>

<WalletEnvSelectionModal
isOpen={showEnvSelectModal}
close={() => setShowEnvSelectModal(false)}
/>
{numReady > 0 && (
<SideBarMenu
onClose={() => setIsSideBarOpen(false)}
isOpen={isSideBarOpen}
onConnectWallet={() => setShowEnvSelectModal(true)}
/>
)}
</div>
);
}
57 changes: 57 additions & 0 deletions src/features/wallet/WalletFloatingButtons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import Link from 'next/link';

import { IconButton } from '../../components/buttons/IconButton';
import { DocsIcon } from '../../components/icons/Docs';
import { WalletIcon } from '../../components/icons/Wallet';
import { links } from '../../consts/links';
import { Color } from '../../styles/Color';
import { useStore } from '../store';

import { HistoryIcon } from '../../components/icons/History';
import { useAccounts } from './hooks/multiProtocol';

export function WalletFloatingButtons() {
const { readyAccounts } = useAccounts();
const { setShowEnvSelectModal, setIsSideBarOpen, isSideBarOpen } = useStore((s) => ({
setShowEnvSelectModal: s.setShowEnvSelectModal,
setIsSideBarOpen: s.setIsSideBarOpen,
isSideBarOpen: s.isSideBarOpen,
}));

const numReady = readyAccounts.length;

return (
<div className="absolute -right-8 top-2 hidden flex-col items-center justify-end gap-4 sm:flex">
{numReady === 0 && (
<IconButton
classes={`p-1 ${styles.roundedCircle} `}
title="Connect Wallet"
onClick={() => setShowEnvSelectModal(true)}
>
<WalletIcon color={Color.primary} height={16} width={16} />
</IconButton>
)}
{numReady >= 1 && (
<IconButton
classes={`p-0.5 ${styles.roundedCircle} `}
title="History"
onClick={() => setIsSideBarOpen(!isSideBarOpen)}
>
<HistoryIcon color={Color.primary} height={20} width={20} />
</IconButton>
)}
<Link
href={links.warpDocs}
target="_blank"
className={`p-0.5 ${styles.roundedCircle} ${styles.link}`}
>
<DocsIcon color={Color.primary} height={20} width={20} />
</Link>
</div>
);
}

const styles = {
link: 'hover:opacity-70 active:opacity-60',
roundedCircle: 'rounded-full bg-white',
};
Loading

0 comments on commit 2461873

Please sign in to comment.