Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add wc loader #128

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading