|
7 | 7 | import { feeRatePercentilesStore } from '$btc/stores/fee-rate-percentiles.store'; |
8 | 8 | import { OCP_PAY_WITH_BTC_ENABLED } from '$env/open-crypto-pay.env'; |
9 | 9 | import IconChain from '$lib/components/icons/IconChain.svelte'; |
| 10 | + import IconHelpCircle from '$lib/components/icons/IconHelpCircle.svelte'; |
10 | 11 | import QrCodeScanner from '$lib/components/qr/QrCodeScanner.svelte'; |
11 | 12 | import ScannerCodeInput from '$lib/components/scanner/ScannerCodeInput.svelte'; |
12 | 13 | import BottomSheet from '$lib/components/ui/BottomSheet.svelte'; |
13 | 14 | import Button from '$lib/components/ui/Button.svelte'; |
14 | | - import ButtonGroup from '$lib/components/ui/ButtonGroup.svelte'; |
15 | | - import ContentWithToolbar from '$lib/components/ui/ContentWithToolbar.svelte'; |
16 | 15 | import Responsive from '$lib/components/ui/Responsive.svelte'; |
17 | 16 | import { OPEN_CRYPTO_PAY_ENTER_MANUALLY_BUTTON } from '$lib/constants/test-ids.constants'; |
18 | 17 | import { btcAddressMainnet } from '$lib/derived/address.derived'; |
|
27 | 26 | import { PAY_CONTEXT_KEY, type PayContext } from '$lib/stores/open-crypto-pay.store'; |
28 | 27 | import type { QrStatus } from '$lib/types/qr-code'; |
29 | 28 | import { ScannerResults } from '$lib/types/scanner'; |
| 29 | + import { replaceOisyPlaceholders } from '$lib/utils/i18n.utils'; |
30 | 30 | import { prepareBasePayableTokens } from '$lib/utils/open-crypto-pay.utils'; |
31 | 31 | import { waitReady } from '$lib/utils/timeout.utils'; |
32 | 32 |
|
33 | 33 | interface Props { |
34 | | - onNext: (results: ScannerResults) => void; |
| 34 | + onNext: (params: { results: ScannerResults; code?: string }) => void; |
| 35 | + onOpenInfo?: () => void; |
35 | 36 | } |
36 | 37 |
|
37 | | - let { onNext }: Props = $props(); |
| 38 | + let { onNext, onOpenInfo }: Props = $props(); |
| 39 | +
|
| 40 | + const WALLET_CONNECT_URI_PREFIX = 'wc:'; |
38 | 41 |
|
39 | 42 | let openBottomSheet = $state(false); |
40 | 43 | let uri = $state(''); |
|
44 | 47 | const { setData, setAvailableTokens } = getContext<PayContext>(PAY_CONTEXT_KEY); |
45 | 48 |
|
46 | 49 | const processCode = async (code: string) => { |
| 50 | + if (code.startsWith(WALLET_CONNECT_URI_PREFIX)) { |
| 51 | + onNext({ results: ScannerResults.WALLET_CONNECT, code }); |
| 52 | + return; |
| 53 | + } |
| 54 | +
|
47 | 55 | busy.start(); |
48 | 56 |
|
49 | 57 | error = ''; |
|
74 | 82 |
|
75 | 83 | setAvailableTokens(tokensWithFees); |
76 | 84 |
|
77 | | - onNext(ScannerResults.PAY); |
| 85 | + onNext({ results: ScannerResults.PAY }); |
78 | 86 | } catch (_: unknown) { |
79 | 87 | error = $i18n.scanner.error.code_link_is_not_valid; |
80 | 88 | } finally { |
|
101 | 109 | }); |
102 | 110 | </script> |
103 | 111 |
|
104 | | -<ContentWithToolbar styleClass="flex flex-col gap-3 md:gap-4 w-full"> |
105 | | - <QrCodeScanner onScan={handleScan} /> |
| 112 | +<div class="relative flex w-full flex-col bg-tertiary"> |
| 113 | + <QrCodeScanner expandedLayout onScan={handleScan} /> |
106 | 114 |
|
107 | 115 | <Responsive up="md"> |
108 | 116 | <ScannerCodeInput |
109 | 117 | name="uri" |
110 | 118 | {error} |
111 | 119 | label={$i18n.scanner.text.url_or_code} |
112 | 120 | placeholder={$i18n.scanner.text.enter_or_paste_code} |
| 121 | + styleClass="absolute right-0 bottom-[90px] left-0 mx-auto w-[90%] rounded-lg bg-surface" |
113 | 122 | bind:value={uri} |
114 | | - /> |
| 123 | + > |
| 124 | + <Button disabled={isEmptyUri} fullWidth onclick={handleManualConnect} paddingSmall> |
| 125 | + {$i18n.core.text.continue} |
| 126 | + </Button> |
| 127 | + </ScannerCodeInput> |
115 | 128 | </Responsive> |
116 | 129 |
|
117 | 130 | <Responsive down="sm"> |
118 | 131 | <BottomSheet contentClass="min-h-[10vh]" bind:visible={openBottomSheet}> |
119 | 132 | {#snippet content()} |
120 | | - <div class="mb-4"> |
121 | | - <ScannerCodeInput |
122 | | - name="uri" |
123 | | - {error} |
124 | | - label={$i18n.scanner.text.url_or_code} |
125 | | - placeholder={$i18n.scanner.text.enter_or_paste_code} |
126 | | - bind:value={uri} |
127 | | - /> |
128 | | - </div> |
129 | | - {/snippet} |
130 | | - |
131 | | - {#snippet footer()} |
132 | | - <Button disabled={isEmptyUri} fullWidth onclick={handleManualConnect}> |
133 | | - {$i18n.core.text.continue} |
134 | | - </Button> |
| 133 | + <ScannerCodeInput |
| 134 | + name="uri" |
| 135 | + {error} |
| 136 | + label={$i18n.scanner.text.url_or_code} |
| 137 | + placeholder={$i18n.scanner.text.enter_or_paste_code} |
| 138 | + bind:value={uri} |
| 139 | + > |
| 140 | + <Button disabled={isEmptyUri} fullWidth onclick={handleManualConnect} paddingSmall> |
| 141 | + {$i18n.core.text.continue} |
| 142 | + </Button> |
| 143 | + </ScannerCodeInput> |
135 | 144 | {/snippet} |
136 | 145 | </BottomSheet> |
| 146 | + |
| 147 | + <div class="absolute right-0 bottom-[90px] left-0 mx-auto flex w-[200px] justify-center"> |
| 148 | + <Button |
| 149 | + colorStyle="tertiary" |
| 150 | + innerStyleClass="flex items-center justify-center" |
| 151 | + onclick={() => { |
| 152 | + uri = ''; |
| 153 | + error = ''; |
| 154 | + openBottomSheet = true; |
| 155 | + }} |
| 156 | + testId={OPEN_CRYPTO_PAY_ENTER_MANUALLY_BUTTON} |
| 157 | + > |
| 158 | + {$i18n.scanner.text.enter_manually} |
| 159 | + |
| 160 | + <IconChain /> |
| 161 | + </Button> |
| 162 | + </div> |
137 | 163 | </Responsive> |
138 | 164 |
|
139 | | - {#snippet toolbar()} |
140 | | - <Responsive up="md"> |
141 | | - <ButtonGroup> |
142 | | - <Button disabled={isEmptyUri} onclick={handleManualConnect}> |
143 | | - {$i18n.core.text.continue} |
144 | | - </Button> |
145 | | - </ButtonGroup> |
146 | | - </Responsive> |
147 | | - |
148 | | - <Responsive down="sm"> |
149 | | - <div class="mb-4 flex flex-0"> |
150 | | - <Button |
151 | | - colorStyle="primary" |
152 | | - innerStyleClass="flex items-center justify-center" |
153 | | - link |
154 | | - onclick={() => { |
155 | | - uri = ''; |
156 | | - error = ''; |
157 | | - openBottomSheet = true; |
158 | | - }} |
159 | | - testId={OPEN_CRYPTO_PAY_ENTER_MANUALLY_BUTTON} |
160 | | - > |
161 | | - {$i18n.scanner.text.enter_manually} |
162 | | - <IconChain /> |
163 | | - </Button> |
164 | | - </div> |
165 | | - </Responsive> |
166 | | - {/snippet} |
167 | | -</ContentWithToolbar> |
| 165 | + <Button |
| 166 | + fullWidth |
| 167 | + link |
| 168 | + onclick={onOpenInfo} |
| 169 | + styleClass="text-secondary bg-surface py-4 rounded-none" |
| 170 | + > |
| 171 | + <span>{replaceOisyPlaceholders($i18n.scanner.text.what_is_scan)}</span> |
| 172 | + |
| 173 | + <IconHelpCircle /> |
| 174 | + </Button> |
| 175 | +</div> |
0 commit comments