Skip to content

Commit

Permalink
refactor: update ui
Browse files Browse the repository at this point in the history
  • Loading branch information
janniks committed Nov 15, 2023
1 parent ecea19b commit 7f24fa5
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 134 deletions.
2 changes: 0 additions & 2 deletions packages/connect-ui/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export namespace Components {
"callback": Function;
"defaultProviders": StxProvider[];
"registeredProviders": StxProvider[];
"selectedProvider": StxProvider | undefined;
}
}
declare global {
Expand All @@ -30,7 +29,6 @@ declare namespace LocalJSX {
"callback"?: Function;
"defaultProviders"?: StxProvider[];
"registeredProviders"?: StxProvider[];
"selectedProvider"?: StxProvider | undefined;
}
interface IntrinsicElements {
"connect-modal": ConnectModal;
Expand Down
52 changes: 0 additions & 52 deletions packages/connect-ui/src/components/modal/modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -52,65 +52,13 @@
.modal-header {
display: flex;
flex-direction: column;

@include mobile {
flex-direction: row-reverse;
align-items: flex-start;
}
}

.close-modal {
display: flex;
align-items: flex-end;
justify-content: flex-end;
}

.close-icon {
cursor: pointer;
}

.modal-content {
display: flex;
flex-direction: column;
}

.modal-title {
color: #242629;
font-family: 'Open Sauce One', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial,
sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
font-weight: 500;
font-size: 32px;
line-height: 32px;
margin-bottom: 18px;
padding-right: 48px;
margin-top: 18px;

@include mobile {
font-size: 24px;
line-height: 24px;
margin-bottom: 8px;
margin-top: 0px;
padding-right: 0px;
}
}

.modal-subtitle {
font-size: 16px;
font-weight: 400;
line-height: 24px;
color: #74777d;

@include mobile {
font-size: 13px;
}
}

.download-app-container {
display: flex;
flex-direction: column;
margin-top: 20px;
}

.button {
width: 100%;
max-width: 139px;
Expand Down
146 changes: 92 additions & 54 deletions packages/connect-ui/src/components/modal/modal.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
import { Component, Element, Prop, State, h } from '@stencil/core';
import { Component, Element, Prop, h } from '@stencil/core';
import { StxProvider } from '../../providers';
import CloseIcon from './assets/close-icon.svg';
import { setSelectedProvider } from '../../session';

const CHROME_STORE_URL =
'https://chrome.google.com/webstore/detail/hiro-wallet/ldinpeekobnhjjdofggfgjlcehhmanlj/';
const FIREFOX_STORE_URL = 'https://addons.mozilla.org/en-US/firefox/addon/hiro-wallet/';
const XVERSE_APP_STORE_URL = 'https://apps.apple.com/app/id1552272513';
const XVERSE_PLAY_STORE_URL =
'https://play.google.com/store/apps/details?id=com.secretkeylabs.xverse';
const XVERSE_CHROME_STORE_URL =
'https://chrome.google.com/webstore/detail/xverse-wallet/idnnbdplmphpflfnlkomgpfbpcgelopg';
import CloseIcon from './assets/close-icon.svg';
import { getBrowser, getPlatform } from './utils';

@Component({
tag: 'connect-modal',
Expand All @@ -21,18 +13,14 @@ const XVERSE_CHROME_STORE_URL =
export class Modal {
@Prop() defaultProviders: StxProvider[];
@Prop() registeredProviders: StxProvider[];
@Prop() selectedProvider: StxProvider | undefined;

@Prop() callback: Function;

@State() hasOpenedInstall: boolean;

@State() hasOpenedInstallXverse: boolean;

@Element() modalEl: HTMLConnectModalElement;

handleSelectProvider(providerId: string) {
setSelectedProvider(providerId);
this.modalEl.remove();
this.callback();
}

Expand All @@ -41,73 +29,109 @@ export class Modal {
// todo: throw Error that website can catch and handle (e.g. ConnectCancelError)
}

handleDownloadPath(browser: string) {
// todo: nice to have:
// getComment(provider: StxProvider, browser: string, isMobile?: string) {
// if (!provider.urls) return null;

// const hasExtension = this.getBrowserUrl(provider);
// const hasMobile = this.getMobileUrl(provider);

// if (isMobile && hasExtension && !hasMobile) return 'Extension Only';
// if (!isMobile && !hasExtension && hasMobile) return 'Mobile Only';

// if (!isMobile && !browser) return 'Current browser not supported';

// return null;
// }

getBrowserUrl(provider: StxProvider) {
return provider.urls?.chromeWebStore ?? provider.urls?.mozillaWebStore;
}

getMobileUrl(provider: StxProvider) {
return provider.urls?.iOSAppStore ?? provider.urls?.androidAppStore;
}

getInstallUrl(provider: StxProvider, browser: string) {
if (browser === 'Chrome') {
window.open(CHROME_STORE_URL, '_blank');
return provider.urls?.chromeWebStore ?? this.getMobileUrl(provider) ?? provider.urls?.about;
} else if (browser === 'Firefox') {
window.open(FIREFOX_STORE_URL, '_blank');
return provider.urls?.mozillaWebStore ?? this.getMobileUrl(provider) ?? provider.urls?.about;
} else if (browser === 'IOS') {
window.open(XVERSE_APP_STORE_URL, '_blank');
this.hasOpenedInstallXverse = true;
return;
return provider.urls?.iOSAppStore ?? this.getBrowserUrl(provider) ?? provider.urls?.about;
} else if (browser === 'Android') {
window.open(XVERSE_PLAY_STORE_URL, '_blank');
this.hasOpenedInstallXverse = true;
return;
} else if (browser === 'Xverse-Chrome') {
window.open(XVERSE_CHROME_STORE_URL, '_blank');
this.hasOpenedInstallXverse = true;
return;
return provider.urls?.androidAppStore ?? this.getBrowserUrl(provider) ?? provider.urls?.about;
} else {
window.open('https://www.hiro.so/wallet/install-web', '_blank');
return this.getBrowserUrl(provider) ?? provider.urls?.about ?? this.getMobileUrl(provider);
}
this.hasOpenedInstall = true;
}

render() {
// const browser = getBrowser();
// const isMobile = getPlatform();

// IF INCOMPATIBLE BROWSER
// todo:
const browser = getBrowser();
const mobile = getPlatform();

return (
<div class="modal-container">
<div class="modal-body leading-snug space-y-5">
<div class="modal-body leading-snug space-y-5 cursor-default">
{/* INTRO */}
<div class="modal-header space-y-2">
<div class="close-modal flex items-center">
<p class="font-bold text-lg flex-1">Select wallet</p>
<img class="close-icon" src={CloseIcon} onClick={() => this.handleCloseModal()} />
<div class="font-semibold text-lg flex-1">Select wallet</div>
<button
class="p-1 bg-transparent rounded-full hover:bg-gray-100 active:scale-95"
onClick={() => this.handleCloseModal()}
>
<span class="sr-only">Close popup</span>
<img src={CloseIcon} />
</button>
</div>
{this.registeredProviders.length === 0 ? (
<div class="space-y-3">
<p>No installed wallets detected. You can install one from the list below.</p>
<div class="text-center">
<a
class="rounded-xl text-sm font-semibold bg-gray-200 text-gray-500 px-3 py-1.5 hover:bg-gray-300"
href=""
// href="" todo: link to docs
rel="noopener noreferrer"
target="_blank"
>
What's a wallet?
🔐 What's a wallet?
</a>
</div>
</div>
) : (
<div>Choose the wallet you want to continue with or install a new one.</div>
)}
{!mobile && !browser && (
<p class="text-yellow-500 py-4">⚠️ Unfortunately, your browser isn't supported</p>
)}
</div>

{/* INSTALLED SECTION */}
{this.registeredProviders.length > 0 && (
<div class="space-y-2">
<p class="text-xs font-semibold text-gray-400">INSTALLED</p>
{this.registeredProviders.map((provider: StxProvider) => (
<div class="flex gap-2 items-center">
<div class="flex gap-3 items-center">
<div class="basis-12 aspect-square">
<img src={provider.icon} alt={`${provider.name} Icon`} class="w-full h-full" />
</div>
<div class="flex-1 text-xl font-bold">{provider.name}</div>
<button class="text-sm px-5 py-1.5 min-w-[72px] text-white bg-green-500 rounded-full hover:bg-green-400">
<div class="flex-1">
<div class="text-xl font-bold">{provider.name}</div>
{provider.urls?.about && (
<a
href={provider.urls.about}
class="text-gray-400 text-sm"
rel="noopener noreferrer"
>
About →
</a>
)}
</div>
<button
class="text-sm px-5 py-1.5 min-w-[72px] text-white bg-green-500 rounded-full hover:bg-green-400 active:scale-95"
onClick={() => this.handleSelectProvider(provider.id)}
>
SELECT
</button>
</div>
Expand All @@ -120,19 +144,33 @@ export class Modal {
<div class="space-y-2">
<p class="text-xs font-semibold text-gray-400">POPULAR</p>
{this.defaultProviders.map((provider: StxProvider) => (
<div class="flex gap-4 items-center">
<div class="flex gap-3 items-center">
<div class="basis-12 aspect-square">
<img src={provider.icon} alt={`${provider.name} Icon`} class="w-full h-full" />
</div>
<div class="flex-1 text-xl font-bold">{provider.name}</div>
<a
class="text-sm px-5 py-1.5 min-w-[72px] text-white bg-blue-500 rounded-full hover:bg-blue-400"
href={provider.urls.website}
rel="noopener noreferrer"
target="_blank"
>
INSTALL
</a>
<div class="flex-1">
<div class="text-xl font-bold">{provider.name}</div>
{provider.urls?.about && (
<a
href={provider.urls.about}
class="text-gray-400 text-sm"
rel="noopener noreferrer"
target="_blank"
>
About →
</a>
)}
</div>
{this.getInstallUrl(provider, browser) && (
<a
class="relative text-sm px-5 py-1.5 min-w-[72px] text-white bg-blue-500 rounded-full hover:bg-blue-400 active:scale-95 cursor-pointer"
href={this.getInstallUrl(provider, browser)}
rel="noopener noreferrer"
target="_blank"
>
INSTALL
</a>
)}
</div>
))}
</div>
Expand Down
1 change: 0 additions & 1 deletion packages/connect-ui/src/components/modal/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
| `callback` | -- | | `Function` | `undefined` |
| `defaultProviders` | -- | | `StxProvider[]` | `undefined` |
| `registeredProviders` | -- | | `StxProvider[]` | `undefined` |
| `selectedProvider` | -- | | `StxProvider` | `undefined` |


----------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion packages/connect-ui/src/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export interface StxProvider {
icon?: string;
/** Different web URLs of the provider */
urls?: {
website?: string;
about?: string;
chromeWebStore?: string;
mozillaWebStore?: string;
androidAppStore?: string;
Expand Down
51 changes: 35 additions & 16 deletions packages/connect/src/stories/Connect.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,49 @@
import { DEFAULT_PROVIDERS } from '@stacks/connect';
import { ConnectPage } from './ConnectPage';
import { clearSelectedProvider } from '@stacks/connect-ui';

const meta = {
export default {
component: ConnectPage,
};

export default meta;

export const WithoutInstalledWallets = {
// 1. No mocking
export const NoMocking = {
render: () => <ConnectPage />,
};

const ConnectWithInstalledWallet = () => {
// 2. Mocking
const ConnectWithMockedRegister = () => {
window.webbtc_stx_providers = [DEFAULT_PROVIDERS[0]]; // simulate installed wallet
return <ConnectPage />;
};
export const WithMockedRegister = {
render: () => <ConnectWithMockedRegister />,
};

// 3. Mocking
declare global {
interface Window {
MockedProvider: any;
}
}
const ConnectWithMockedWallet = () => {
window.webbtc_stx_providers = [
{
id: 'LeatherProvider',
name: 'Leather Wallet',
icon: 'data:image/png;base64,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',
urls: {
website: 'https://leather.io',
iOSAppStore: 'https://apps.apple.com/us/app/blockstack-wallet/id1440635868',
},
id: 'MockedProvider',
name: 'Mocked Wallet',
},
];

return <ConnectPage />;
window.MockedProvider = {
authenticationRequest: () => {
alert('MockedProvider.authenticationRequest()');
},
};
return (
<ConnectPage>
<button onClick={() => clearSelectedProvider()}>Disconnect</button>
</ConnectPage>
);
};
export const WithInstalledWallet = {
render: () => <ConnectWithInstalledWallet />,
export const WithMockedWallet = {
render: () => <ConnectWithMockedWallet />,
};
Loading

0 comments on commit 7f24fa5

Please sign in to comment.