diff --git a/src/Components/ErrorBoundary/ErrorBoundary.tsx b/src/Components/ErrorBoundary/ErrorBoundary.tsx index 8c41157..3a17e1f 100644 --- a/src/Components/ErrorBoundary/ErrorBoundary.tsx +++ b/src/Components/ErrorBoundary/ErrorBoundary.tsx @@ -1,4 +1,5 @@ import React, { Component, ErrorInfo, ReactNode } from "react"; +import ErrorMessage from "../ErrorMessage/ErrorMessage"; interface Props { place?: string @@ -25,7 +26,14 @@ class ErrorBoundary extends Component { public render() { if (this.state.hasError) { - return

Sorry.. there was an error

; + return + Sorry, something went wrong...😵 +
+ Try refreshing the page. +

+ + } type="unknown">
; } return this.props.children; diff --git a/src/Components/ErrorMessage/ErrorMessage.tsx b/src/Components/ErrorMessage/ErrorMessage.tsx index 69ce4dd..b6cd8fc 100644 --- a/src/Components/ErrorMessage/ErrorMessage.tsx +++ b/src/Components/ErrorMessage/ErrorMessage.tsx @@ -1,7 +1,7 @@ import { Link } from "react-router-dom" interface Props { - message?: string, + message?: string | JSX.Element, type?: 'unknown' | 'fetching' } @@ -22,9 +22,9 @@ export default function ErrorMessage({ return (
-

+

{messageToShow} -

+
Back to home page
) diff --git a/src/Components/Modals/NoWeblnModal/NoWeblnModal.tsx b/src/Components/Modals/NoWeblnModal/NoWeblnModal.tsx new file mode 100644 index 0000000..c044161 --- /dev/null +++ b/src/Components/Modals/NoWeblnModal/NoWeblnModal.tsx @@ -0,0 +1,69 @@ +import { motion } from 'framer-motion' +import { useAppSelector } from 'src/utils/hooks'; +import { ModalCard, modalCardVariants } from 'src/Components/Modals/ModalsContainer/ModalsContainer' +import Button from 'src/Components/Button/Button' +import { IoClose } from 'react-icons/io5'; +import NutImg from './nut.png' +import AlbyImg from './alby.png' + +export default function NoWeblnModal({ onClose, direction, ...props }: ModalCard) { + + const isMobile = useAppSelector(s => s.ui.isMobileScreen); + + + let content: JSX.Element; + + if (isMobile) + content = <> +
+ Nut images +
+

+ Oops! Looks like you’re browsing on mobile. +

+

+ In order to use BOLT🔩FUN’s voting button, you need to use a lightning browser wallet like Alby. You can download the extension on your desktop and try again. +

+ + else + content = <> +
+ Nut images +
+

+ Oops! Looks like you don’t have Alby installed +

+

+ In order to use BOLT🔩FUN’s voting button, you’ll need to use a lightning browser wallet like Alby. Download it to continue. +

+ + + + + return ( + + +

No WebLB Detected

+ {content} +
+ ) +} diff --git a/src/Components/Modals/NoWeblnModal/alby.png b/src/Components/Modals/NoWeblnModal/alby.png new file mode 100644 index 0000000..eca9dfc Binary files /dev/null and b/src/Components/Modals/NoWeblnModal/alby.png differ diff --git a/src/Components/Modals/NoWeblnModal/index.ts b/src/Components/Modals/NoWeblnModal/index.ts new file mode 100644 index 0000000..4dd1808 --- /dev/null +++ b/src/Components/Modals/NoWeblnModal/index.ts @@ -0,0 +1,4 @@ + +import { lazyModal } from 'src/utils/helperFunctions'; + +export const { LazyComponent: NoWeblnModal } = lazyModal(() => import('./NoWeblnModal')) \ No newline at end of file diff --git a/src/Components/Modals/NoWeblnModal/nut.png b/src/Components/Modals/NoWeblnModal/nut.png new file mode 100644 index 0000000..0313442 Binary files /dev/null and b/src/Components/Modals/NoWeblnModal/nut.png differ diff --git a/src/features/Donations/components/DonateCard/useDonate.tsx b/src/features/Donations/components/DonateCard/useDonate.tsx index c69dfd7..5598619 100644 --- a/src/features/Donations/components/DonateCard/useDonate.tsx +++ b/src/features/Donations/components/DonateCard/useDonate.tsx @@ -17,56 +17,65 @@ export const useDonate = () => { onError: (error: any) => void, onSetteled: () => void }>) => { - setPaymentStatus(PaymentStatus.FETCHING_PAYMENT_DETAILS) - donateMutation({ - variables: { - amountInSat: amount - }, - onCompleted: async (donationData) => { - try { - setPaymentStatus(PaymentStatus.AWAITING_PAYMENT); - const webln = await Wallet_Service.getWebln() - const paymentResponse = await webln.sendPayment(donationData.donate.payment_request); - setPaymentStatus(PaymentStatus.PAID); - - //Confirm Voting payment - confirmDonation({ - variables: { - paymentRequest: donationData.donate.payment_request, - preimage: paymentResponse.preimage - }, - onCompleted: () => { - setPaymentStatus(PaymentStatus.PAYMENT_CONFIRMED); - config?.onSuccess?.(); - config?.onSetteled?.() - }, - onError: (error) => { - console.log(error) - setPaymentStatus(PaymentStatus.NETWORK_ERROR); - config?.onError?.(error); - config?.onSetteled?.(); - alert("A network error happened while confirming the payment...") - }, - refetchQueries: [ - 'DonationsStats' - ] - }) - } catch (error) { - setPaymentStatus(PaymentStatus.CANCELED); - config?.onError?.(error); - config?.onSetteled?.(); - alert("Payment rejected by user") + Wallet_Service.getWebln() + .then(webln => { + if (!webln) { + config?.onError?.(new Error('No WebLN Detetcted')) + config?.onSetteled?.() + return } - }, - onError: (error) => { - console.log(error); - setPaymentStatus(PaymentStatus.NETWORK_ERROR); - config?.onError?.(error); - config?.onSetteled?.(); - alert("A network error happened...") - } - }) + setPaymentStatus(PaymentStatus.FETCHING_PAYMENT_DETAILS) + donateMutation({ + variables: { + amountInSat: amount + }, + onCompleted: async (donationData) => { + try { + setPaymentStatus(PaymentStatus.AWAITING_PAYMENT); + const paymentResponse = await webln.sendPayment(donationData.donate.payment_request); + setPaymentStatus(PaymentStatus.PAID); + + //Confirm Voting payment + confirmDonation({ + variables: { + paymentRequest: donationData.donate.payment_request, + preimage: paymentResponse.preimage + }, + onCompleted: () => { + setPaymentStatus(PaymentStatus.PAYMENT_CONFIRMED); + config?.onSuccess?.(); + config?.onSetteled?.() + }, + onError: (error) => { + console.log(error) + setPaymentStatus(PaymentStatus.NETWORK_ERROR); + config?.onError?.(error); + config?.onSetteled?.(); + alert("A network error happened while confirming the payment...") + }, + refetchQueries: [ + 'DonationsStats' + ] + }) + } catch (error) { + setPaymentStatus(PaymentStatus.CANCELED); + config?.onError?.(error); + config?.onSetteled?.(); + alert("Payment rejected by user") + } + + }, + onError: (error) => { + console.log(error); + setPaymentStatus(PaymentStatus.NETWORK_ERROR); + config?.onError?.(error); + config?.onSetteled?.(); + alert("A network error happened...") + } + }) + }) + }, [confirmDonation, donateMutation]); const isLoading = paymentStatus !== PaymentStatus.DEFAULT && paymentStatus !== PaymentStatus.PAYMENT_CONFIRMED && paymentStatus !== PaymentStatus.NOT_PAID && paymentStatus !== PaymentStatus.NETWORK_ERROR && paymentStatus !== PaymentStatus.CANCELED diff --git a/src/redux/features/modals.slice.ts b/src/redux/features/modals.slice.ts index 6e05b12..c6c3a27 100644 --- a/src/redux/features/modals.slice.ts +++ b/src/redux/features/modals.slice.ts @@ -12,6 +12,7 @@ import { LinkingAccountModal } from "src/features/Profiles/pages/EditProfilePage import { ComponentProps } from "react"; import { generateId } from "src/utils/helperFunctions"; +import { NoWeblnModal } from "src/Components/Modals/NoWeblnModal"; export enum Direction { START, @@ -34,6 +35,7 @@ export const ALL_MODALS = { Claim_SubmittedCard, Claim_FundWithdrawCard, ConfirmModal, + NoWeblnModal, LinkingAccountModal, // Text Editor Modals diff --git a/src/services/wallet.service.ts b/src/services/wallet.service.ts index 8510599..a9f6d27 100644 --- a/src/services/wallet.service.ts +++ b/src/services/wallet.service.ts @@ -1,6 +1,7 @@ import { requestProvider, MissingProviderError, WebLNProvider } from 'webln'; import { store } from '../redux/store' import { connectWallet as connectWalletStore } from '../redux/features/wallet.slice' +import { openModal } from 'src/redux/features/modals.slice'; class _Wallet_Service { @@ -10,20 +11,19 @@ class _Wallet_Service { async getWebln() { if (!this.isConnected) await this.connectWallet(); - return this.webln as WebLNProvider; + return this.webln; } init() { - const connectedPreviously = localStorage.getItem('wallet-connected') - if (connectedPreviously) - this.connectWallet(); + // const connectedPreviously = localStorage.getItem('wallet-connected') + // if (connectedPreviously) + // this.connectWallet(); } async connectWallet() { try { const webln = await requestProvider(); store.dispatch(connectWalletStore()) - localStorage.setItem('wallet-connected', 'yes') this.webln = webln; this.isConnected = false; } @@ -35,11 +35,13 @@ class _Wallet_Service { message = "Check out https://getalby.com to get a web enabled lightning wallet"; } + console.log(message); - localStorage.removeItem('wallet-connected') // Show the error (though you should probably use something better than alert!) - alert(message); + store.dispatch(openModal({ + Modal: "NoWeblnModal" + })) } } diff --git a/src/utils/hooks/useVote/useVote.tsx b/src/utils/hooks/useVote/useVote.tsx index e0009d2..37a6fdc 100644 --- a/src/utils/hooks/useVote/useVote.tsx +++ b/src/utils/hooks/useVote/useVote.tsx @@ -41,81 +41,93 @@ export const useVote = (params: Params) => { if (!itemId || !itemType) return; - setPaymentStatus(PaymentStatus.FETCHING_PAYMENT_DETAILS) - voteMutaion({ - variables: { - itemId, - itemType, - amountInSat: amount - }, - onCompleted: async (votingData) => { - try { - setPaymentStatus(PaymentStatus.AWAITING_PAYMENT); - const webln = await Wallet_Service.getWebln() - const paymentResponse = await webln.sendPayment(votingData.vote.payment_request); - setPaymentStatus(PaymentStatus.PAID); - //Confirm Voting payment - confirmVote({ - variables: { - paymentRequest: votingData.vote.payment_request, - preimage: paymentResponse.preimage - }, - onCompleted: () => { - setPaymentStatus(PaymentStatus.PAYMENT_CONFIRMED); - onSuccess?.(votingData.vote.amount_in_sat); - onSetteled?.() - }, - update(cache, { data }) { - try { - const { item_id, item_type, amount_in_sat } = data!.confirmVote; - const { votes_count } = cache.readFragment({ - id: `${item_type}:${item_id}`, - fragment: gql` - fragment My${item_type} on ${item_type} { - votes_count - }` - }) ?? {}; - cache.writeFragment({ - id: `${item_type}:${item_id}`, - fragment: gql` - fragment My${item_type} on ${item_type} { - votes_count - } - `, - data: { - votes_count: votes_count + amount_in_sat - }, - }) - } catch (error) { - onError?.(error) - } - }, - - onError: (error) => { - setPaymentStatus(PaymentStatus.NETWORK_ERROR); - onError?.(error); - onSetteled?.(); - alert("A network error happened while confirming the payment...") - } - }) - } catch (error) { - setPaymentStatus(PaymentStatus.CANCELED); - onError?.(error); - onSetteled?.(); - alert("Payment rejected by user") + Wallet_Service.getWebln() + .then(webln => { + if (!webln) { + onError?.(new Error('No WebLN Detetcted')) + onSetteled?.() + return } - }, - onError: (error) => { - console.log(error); - setPaymentStatus(PaymentStatus.NETWORK_ERROR); - onError?.(error); - onSetteled?.(); - alert("A network error happened...") - } - }) + setPaymentStatus(PaymentStatus.FETCHING_PAYMENT_DETAILS) + voteMutaion({ + variables: { + itemId, + itemType, + amountInSat: amount + }, + onCompleted: async (votingData) => { + try { + setPaymentStatus(PaymentStatus.AWAITING_PAYMENT); + const paymentResponse = await webln.sendPayment(votingData.vote.payment_request); + setPaymentStatus(PaymentStatus.PAID); + + //Confirm Voting payment + confirmVote({ + variables: { + paymentRequest: votingData.vote.payment_request, + preimage: paymentResponse.preimage + }, + onCompleted: () => { + setPaymentStatus(PaymentStatus.PAYMENT_CONFIRMED); + onSuccess?.(votingData.vote.amount_in_sat); + onSetteled?.() + }, + update(cache, { data }) { + try { + const { item_id, item_type, amount_in_sat } = data!.confirmVote; + const { votes_count } = cache.readFragment({ + id: `${item_type}:${item_id}`, + fragment: gql` + fragment My${item_type} on ${item_type} { + votes_count + }` + }) ?? {}; + cache.writeFragment({ + id: `${item_type}:${item_id}`, + fragment: gql` + fragment My${item_type} on ${item_type} { + votes_count + } + `, + data: { + votes_count: votes_count + amount_in_sat + }, + }) + } catch (error) { + onError?.(error) + } + }, + + onError: (error) => { + setPaymentStatus(PaymentStatus.NETWORK_ERROR); + onError?.(error); + onSetteled?.(); + alert("A network error happened while confirming the payment...") + } + }) + } catch (error) { + setPaymentStatus(PaymentStatus.CANCELED); + onError?.(error); + onSetteled?.(); + alert("Payment rejected by user") + + } + + }, + onError: (error) => { + console.log(error); + setPaymentStatus(PaymentStatus.NETWORK_ERROR); + onError?.(error); + onSetteled?.(); + alert("A network error happened...") + } + }) + }) + + }, [confirmVote, voteMutaion, params.itemId, params.itemType, params.onError, params.onSetteled, params.onSuccess]);