From 5289732bfd161b8788f58d58ea47b61715e5c3c6 Mon Sep 17 00:00:00 2001 From: Ionut Anin Date: Mon, 6 Nov 2023 00:47:45 +0200 Subject: [PATCH] add start / stop button, show loading state --- src/background/grantFlow.ts | 26 ++++++++++++++++-- src/background/index.ts | 23 +++++++++++----- src/content/monetization.tsx | 1 + src/popup/Popup.scss | 53 ++++++++++++++++++++++++++++++++++-- src/popup/Popup.tsx | 34 +++++++++++++++++------ src/types/message.d.ts | 1 + 6 files changed, 118 insertions(+), 20 deletions(-) diff --git a/src/background/grantFlow.ts b/src/background/grantFlow.ts index faaecbeb..ff43e43a 100644 --- a/src/background/grantFlow.ts +++ b/src/background/grantFlow.ts @@ -24,6 +24,8 @@ export class PaymentFlowService { interactRef: string walletAddressId: string + manageUrl: string + amount: string | number sendingWalletAddress: any @@ -229,6 +231,7 @@ export class PaymentFlowService { throw new Error('No continuation request') } + this.manageUrl = continuationRequest.data.access_token.manage this.continuationRequestToken = continuationRequest.data.access_token.value } @@ -280,9 +283,28 @@ export class PaymentFlowService { }) } + async rotateToken() { + const response = await this.axiosInstance.post( + this.manageUrl, + undefined, + this.getHeaders(this.continuationRequestToken), + ) + + if (!response.data.access_token.value) { + throw new Error('No continuation request') + } + + this.manageUrl = response.data.access_token.manage + this.continuationRequestToken = response.data.access_token.value + } + async sendPayment() { - await this.createQuote() - await this.runPayment() + await this.createQuote().catch(async () => { + await this.rotateToken() + }) + await this.runPayment().catch(async () => { + await this.rotateToken() + }) } async getCurrentActiveTabId() { diff --git a/src/background/index.ts b/src/background/index.ts index ef39e73c..69f25814 100755 --- a/src/background/index.ts +++ b/src/background/index.ts @@ -82,13 +82,22 @@ class Background { amount, } = message.data - this.grantFlow = new PaymentFlowService( - sendingPaymentPointerUrl, - receivingPaymentPointerUrl, - amount, - ) + if (this.grantFlow?.sendingPaymentPointerUrl === sendingPaymentPointerUrl) { + if (!this.paymentStarted) { + this.paymentStarted = true + const currentTabId = await this.grantFlow?.getCurrentActiveTabId() + await tabs.sendMessage(currentTabId ?? 0, { type: 'START_PAYMENTS' }) + } + } else { + this.grantFlow = new PaymentFlowService( + sendingPaymentPointerUrl, + receivingPaymentPointerUrl, + amount, + ) + + this.grantFlow.initPaymentFlow() + } - this.grantFlow.initPaymentFlow() break } @@ -119,7 +128,7 @@ class Background { break } - case 'STOP_PAYMENTS': { + case 'PAUSE_PAYMENTS': { this.paymentStarted = false break } diff --git a/src/content/monetization.tsx b/src/content/monetization.tsx index 0f82900b..c7043939 100644 --- a/src/content/monetization.tsx +++ b/src/content/monetization.tsx @@ -15,6 +15,7 @@ export class PaymentSender { } stop() { + sendMessage({ type: 'PAUSE_PAYMENTS' }) clearInterval(this.sender) } diff --git a/src/popup/Popup.scss b/src/popup/Popup.scss index c426f553..ee1425d9 100644 --- a/src/popup/Popup.scss +++ b/src/popup/Popup.scss @@ -61,6 +61,19 @@ body { position: relative; padding-right: 60px; + &.active { + &::before { + content: ''; + position: absolute; + background: rgb(255 255 255 / 70%); + width: 100%; + height: 100%; + top: 0; + left: 0; + z-index: 1; + } + } + .input-wrapper { position: relative; border-bottom: 1px solid #e0e0e0; @@ -160,22 +173,47 @@ body { right: 0; top: 0; bottom: 0; + z-index: 2; display: grid; grid-gap: 2px; grid-auto-flow: row; + grid-auto-rows: 1fr; padding: 4px 4px 4px 16px; button { width: 44px; + padding: 0; &.submit-btn { border-radius: 0 6px 6px 0; + position: relative; + + &.loading { + img { + display: none; + } + + &::before { + content: ''; + width: 20px; + height: 20px; + border: 3px solid white; + border-top-color: rgb(255 255 255 / 20%); + border-left-color: rgb(255 255 255 / 20%); + animation: spin 500ms linear infinite; + border-radius: 50%; + } + } } &.stop-btn { - background-color: #ff65a3; - color: #999; - border-radius: 0 0 6px 0; + background-color: black; + border-radius: 0 6px 6px 0; + + img { + height: 32px; + width: 32px; + } } &.edit-btn { @@ -190,3 +228,12 @@ body { } } } + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/src/popup/Popup.tsx b/src/popup/Popup.tsx index af5bdf53..d6fd7c8f 100644 --- a/src/popup/Popup.tsx +++ b/src/popup/Popup.tsx @@ -14,6 +14,7 @@ const DollarIcon = runtime.getURL('assets/images/dollar.svg') const CloseIcon = runtime.getURL('assets/images/close.svg') const Popup = () => { + const [loading, setLoading] = useState(false) const [paymentStarted, setPaymentStarted] = useState(false) const [spent, setSpent] = useState(0) const [sendingPaymentPointer, setSendingPaymentPointer] = useState('') @@ -44,6 +45,7 @@ const Popup = () => { const handleSubmit = async (event: React.FormEvent) => { event.preventDefault() + setLoading(true) const data = { amount: formData.amount, paymentPointer: formData.paymentPointer, @@ -51,13 +53,11 @@ const Popup = () => { } await sendMessage({ type: 'SET_INCOMING_POINTER', data }) - window.close() } const getSendingPaymentPointer = async () => { const response = await sendMessage({ type: 'GET_SENDING_PAYMENT_POINTER' }) setSendingPaymentPointer(response.data.sendingPaymentPointerUrl) - setPaymentStarted(response.data.paymentStarted) const { sendingPaymentPointerUrl: paymentPointer, amount } = response.data if (paymentPointer && amount) { @@ -70,11 +70,14 @@ const Popup = () => { const listenForIncomingPayment = async () => { const listener = (message: any) => { - console.log('message', message) if (message.type === 'SPENT_AMOUNT') { setSpent(message.data.spentAmount) setPaymentStarted(true) } + + if (loading) { + setLoading(false) + } } runtime.onMessage.addListener(listener) @@ -86,7 +89,12 @@ const Popup = () => { const stopPayments = async (e: React.MouseEvent) => { e.preventDefault() setPaymentStarted(false) - await sendMessage({ type: 'STOP_PAYMENTS' }) + setTimeout(() => { + if (loading) { + setLoading(false) + } + }, 1000) + await sendMessageToActiveTab({ type: 'STOP_PAYMENTS' }) } return ( @@ -102,7 +110,9 @@ const Popup = () => { <> Success -
+
@@ -111,6 +121,7 @@ const Popup = () => { name="paymentPointer" value={formData.paymentPointer} onInput={handleChange} + disabled={paymentStarted} placeholder="https://ilp.rafiki.money/alice" />
@@ -125,15 +136,22 @@ const Popup = () => { name="amount" value={formData.amount} onInput={handleChange} + disabled={paymentStarted} placeholder="0.05" />
- + {paymentStarted ? ( + + ) : ( + + )}
diff --git a/src/types/message.d.ts b/src/types/message.d.ts index c61c64d2..8dc5b546 100644 --- a/src/types/message.d.ts +++ b/src/types/message.d.ts @@ -9,6 +9,7 @@ declare type EXTMessageType = | 'START_PAYMENTS' | 'STOP_PAYMENTS' | 'PAYMENT_SUCCESS' + | 'PAUSE_PAYMENTS' declare type EXTMessage = { type: EXTMessageType