Skip to content

Commit

Permalink
feat: add wc loader (#128)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidecarpini authored Dec 1, 2023
1 parent 4a0a2c3 commit 30deb72
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 53 deletions.
2 changes: 1 addition & 1 deletion packages/dapp-kit-ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</head>
<body>
<vwk-vechain-dapp-connect-kit
mode="DARK"
mode="LIGHT"
></vwk-vechain-dapp-connect-kit>
</body>
</html>
15 changes: 14 additions & 1 deletion packages/dapp-kit-ui/src/components/connect-modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
LightChevronLeftSvg,
LightCloseSvg,
} from '../assets';
import { subscribeToCustomEvent } from '../utils';
import { isMobile, subscribeToCustomEvent } from '../utils';
import { DAppKitUI } from '../client';
import type { Theme, ThemeMode } from '../constants/theme';
import type { DappKitContext } from './provider';
Expand Down Expand Up @@ -62,6 +62,8 @@ export class ConnectModal extends LitElement {

@property({ type: Boolean })
open = false;
@property({ type: Boolean })
openingVeWorld = false;
@property()
mode: ThemeMode = 'LIGHT';
@property()
Expand All @@ -73,13 +75,23 @@ export class ConnectModal extends LitElement {
super();

subscribeToCustomEvent('vwk-open-wc-modal', (options: OpenOptions) => {
if (isMobile()) {
this.openingVeWorld = true;
window.open(
`veworld://app.veworld?uri=${encodeURIComponent(
options.uri,
)}`,
'_self',
);
}
this.open = true;
this.walletConnectQRcode = options.uri;
});

subscribeToCustomEvent('vwk-close-wc-modal', () => {
this.open = false;
this.walletConnectQRcode = undefined;
this.openingVeWorld = false;
});

subscribeToCustomEvent('vwk-open-wallet-modal', () => {
Expand Down Expand Up @@ -155,6 +167,7 @@ export class ConnectModal extends LitElement {
${
this.walletConnectQRcode
? html` <vwk-wallet-connect-qrcode
.openingVeWorld=${this.openingVeWorld}
.mode=${this.mode}
.theme=${this.theme}
.walletConnectQRcode=${this
Expand Down
162 changes: 133 additions & 29 deletions packages/dapp-kit-ui/src/components/wallet-connect-qr-code.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import type { TemplateResult } from 'lit';
import { css, html, LitElement, nothing, svg } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { Colors } from '../constants';
import { ANDROID_STORE_URL, Colors, IOS_STORE_URL } from '../constants';
import {
buttonStyle,
CheckSvg,
DarkCopySvg,
LightCopySvg,
VeWorldLogo,
WalletConnectLogo,
} from '../assets';
import { QrCodeUtil } from '../utils';
import { isAndroid, QrCodeUtil } from '../utils';
import type { Theme, ThemeMode } from '../constants/theme';

const qrCodeSize = 280;
@customElement('vwk-wallet-connect-qrcode')
export class WalletConnectQrCode extends LitElement {
static override styles = [
Expand All @@ -25,7 +27,8 @@ export class WalletConnectQrCode extends LitElement {
}
.qrcode-container {
margin: 20px auto 20px auto;
position: relative;
margin: 20px auto 0 auto;
background-color: ${Colors.White};
width: 280px;
padding: 10px;
Expand All @@ -36,7 +39,7 @@ export class WalletConnectQrCode extends LitElement {
align-items: center;
}
img {
img.wc-icon {
position: absolute;
width: 65px;
height: 65px;
Expand All @@ -46,7 +49,7 @@ export class WalletConnectQrCode extends LitElement {
.separator {
display: flex;
align-items: center;
padding-bottom: 20px;
padding: 20px 0px;
}
.line {
Expand Down Expand Up @@ -81,6 +84,41 @@ export class WalletConnectQrCode extends LitElement {
width: 20px;
height: 20px;
}
.veworld-icon {
width: 20px;
height: 20px;
border-radius: 5px;
}
@keyframes loading {
to {
stroke-dashoffset: 0px;
}
}
use {
stroke: #3496ff;
animation: loading 1s linear infinite;
}
svg.loader {
position: absolute;
fill: none;
stroke: transparent;
stroke-linecap: round;
stroke-width: 1px;
top: 10;
left: 10;
}
.openingVeWorldText {
text-align: center;
font-family: 'Inter', sans-serif;
font-size: 14px;
padding: 20px 0;
color: #3496ff;
}
`,
];

Expand All @@ -92,34 +130,50 @@ export class WalletConnectQrCode extends LitElement {
walletConnectQRcode?: string = undefined;
@property()
showCopiedIcon = false;
@property()
openingVeWorld = false;

override render(): TemplateResult | typeof nothing {
let copyIcon = this.mode === 'LIGHT' ? LightCopySvg : DarkCopySvg;
if (this.showCopiedIcon) {
copyIcon = CheckSvg;
}
return this.walletConnectQRcode
? html`
<div class="qrcode-body">
<div class="qrcode-container">
${this.svgWCQrCode(this.walletConnectQRcode)}
<img src=${WalletConnectLogo} />
</div>
<div class="separator">
<div class="line ${this.mode} ${this.theme}"></div>
<div class="or ${this.mode} ${this.theme}">or</div>
<div class="line ${this.mode} ${this.theme}"></div>
</div>
<button

return html`
<div class="qrcode-body">
<div class="qrcode-container">
${this.openingVeWorld ? this.svgLoaderTemplate() : nothing}
${this.svgWCQrCode(this.walletConnectQRcode)}
<img class="wc-icon" src=${WalletConnectLogo} />
</div>
${this.openingVeWorld
? html`<div class="openingVeWorldText">
Opening VeWorld...
</div>`
: nothing}
${this.openingVeWorld
? html`<button
class="${this.mode} ${this.theme}"
@click=${this.onCopy}
@click=${this.getVeWorld}
>
<div class="icon">${copyIcon}</div>
Copy to Clipboard
</button>
</div>
`
: nothing;
<img class="veworld-icon" src=${VeWorldLogo} />
Get VeWorld
</button>`
: nothing}
<div class="separator">
<div class="line ${this.mode} ${this.theme}"></div>
<div class="or ${this.mode} ${this.theme}">or</div>
<div class="line ${this.mode} ${this.theme}"></div>
</div>
<button
class="${this.mode} ${this.theme}"
@click=${this.onCopy}
>
<div class="icon">${copyIcon}</div>
Copy to Clipboard
</button>
</div>
`;
}

private onCopy = async (): Promise<void> => {
Expand All @@ -130,12 +184,62 @@ export class WalletConnectQrCode extends LitElement {
}, 1000);
};

private svgWCQrCode(uri: string): TemplateResult {
const size = 280;
private getVeWorld = (): void => {
if (isAndroid()) {
window.open(ANDROID_STORE_URL, '_self');
} else {
window.open(IOS_STORE_URL, '_self');
}
};

private svgLoaderTemplate(): TemplateResult {
const ICON_SIZE = 88;
const DH_ARRAY = 317;
const DH_OFFSET = 425;
const radius = '8';
let numRadius = 0;

if (radius.includes('%')) {
numRadius = (ICON_SIZE / 100) * parseInt(radius, 10);
} else {
numRadius = parseInt(radius, 10);
}

numRadius *= 1.17;
const dashArray = DH_ARRAY - numRadius * 1.57;
const dashOffset = DH_OFFSET - numRadius * 1.8;

return html`
<svg
class="loader"
viewBox="0 0 110 110"
width=${qrCodeSize + 50}
height=${qrCodeSize + 50}
>
<rect
id="wcm-loader"
x="2"
y="2"
width="106"
height="106"
rx=${numRadius}
></rect>
<use
xlink:href="#wcm-loader"
stroke-dasharray="106 ${dashArray}"
stroke-dashoffset=${dashOffset}
></use>
</svg>
`;
}

private svgWCQrCode(uri?: string): TemplateResult | typeof nothing {
if (!uri) {
return nothing;
}
return svg`
<svg height=${size} width=${size}>
${QrCodeUtil.generate(uri, size, size / 4)}
<svg height=${qrCodeSize} width=${qrCodeSize}>
${QrCodeUtil.generate(uri, qrCodeSize, qrCodeSize / 4)}
</svg>
`;
}
Expand Down
23 changes: 1 addition & 22 deletions packages/dapp-kit-ui/src/modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type {
} from '@vechainfoundation/dapp-kit';
import { DAppKitLogger } from '@vechainfoundation/dapp-kit';
import { subscribeKey } from 'valtio/utils';
import { dispatchCustomEvent, isMobile, subscribeToCustomEvent } from './utils';
import { dispatchCustomEvent, subscribeToCustomEvent } from './utils';

const MODAL_STATE_EVENT = 'vwk-modal-state-change';

Expand Down Expand Up @@ -40,27 +40,6 @@ class CustomWalletConnectModal implements WCModal {
*/
openModal(options: OpenOptions): Promise<void> {
DAppKitLogger.debug('CustomWalletConnectModal', 'opening the modal');

if (isMobile()) {
window.open(
`veworld://app.veworld?uri=${encodeURIComponent(options.uri)}`,
'_self',
);
// TODO: commented out for now, as it's not working as expected, maybe a modal item is better
// const linkingTime = new Date().getTime();
// const TIMEOUT = 5000;
// setTimeout(() => {
// const now = new Date().getTime();
// // avoid redirecting to the store if coming back from the app
// if (now - linkingTime < TIMEOUT + 250) {
// if (isAndroid()) {
// window.open(ANDROID_STORE_URL, '_self');
// } else {
// window.open(IOS_STORE_URL, '_self');
// }
// }
// }, TIMEOUT);
}
dispatchCustomEvent('vwk-open-wc-modal', options);
return Promise.resolve();
}
Expand Down

0 comments on commit 30deb72

Please sign in to comment.