/
SendFormPopup.svelte
156 lines (142 loc) · 5.15 KB
/
SendFormPopup.svelte
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<script lang="typescript">
import { localize } from '@core/i18n'
import { Button, Text, FontWeight, TextType, Tabs } from 'shared/components'
import { closePopup, openPopup } from '@auxiliary/popup'
import {
IAsset,
NewTransactionDetails,
newTransactionDetails,
NewTransactionType,
setNewTransactionDetails,
} from '@core/wallet'
import { RecipientInput, AssetAmountInput, OptionalInput, NetworkInput, NftInput } from 'shared/components'
import { DestinationNetwork } from '@core/network'
import { getByteLengthOfString } from '@core/utils'
import { get } from 'svelte/store'
import { selectedAccount } from '@core/account'
enum SendForm {
SendToken = 'general.sendToken',
SendNft = 'general.sendNft',
}
let assetAmountInput: AssetAmountInput
let recipientInput: RecipientInput
let metadataInput: OptionalInput
let tagInput: OptionalInput
let network: DestinationNetwork
let nftId: string
let rawAmount: string
let asset: IAsset
let unit: string
const transactionDetails = get(newTransactionDetails)
let { metadata, recipient, tag } = transactionDetails
if (transactionDetails.type === NewTransactionType.TokenTransfer) {
rawAmount = transactionDetails.rawAmount
asset = transactionDetails.asset
unit = transactionDetails.unit
} else {
nftId = transactionDetails.nftId
}
const tabs: SendForm[] = [SendForm.SendToken, SendForm.SendNft]
let activeTab: SendForm =
transactionDetails.type === NewTransactionType.TokenTransfer ? SendForm.SendToken : SendForm.SendNft
$: ownsNfts = $selectedAccount.balances.nfts.length > 0
function getTransactionDetails(): NewTransactionDetails {
if (activeTab === SendForm.SendToken) {
return {
type: NewTransactionType.TokenTransfer,
asset,
rawAmount,
unit,
recipient,
metadata,
tag,
}
} else {
return {
type: NewTransactionType.NftTransfer,
nftId,
recipient,
metadata,
tag,
}
}
}
async function validate(): Promise<boolean> {
try {
if (activeTab === SendForm.SendToken) {
await assetAmountInput?.validate()
} else if (!nftId) {
return false
}
await Promise.all([
recipientInput?.validate(),
metadataInput?.validate(validateOptionalInput(metadata, 8192, localize('error.send.metadataTooLong'))),
tagInput?.validate(validateOptionalInput(tag, 64, localize('error.send.tagTooLong'))),
])
return true
} catch (error) {
console.error('Error: ', error)
return false
}
}
function validateOptionalInput(value: string, byteLimit: number, errorMessage: string): Promise<void> {
return new Promise((resolve, reject) => {
if (getByteLengthOfString(value) > byteLimit) {
reject(errorMessage)
}
resolve()
})
}
async function onContinue(): Promise<void> {
const valid = await validate()
if (valid) {
setNewTransactionDetails(getTransactionDetails())
openPopup({
type: 'sendConfirmation',
overflow: true,
})
}
}
function onCancel(): void {
closePopup()
}
</script>
<send-form-popup class="w-full h-full space-y-6 flex flex-auto flex-col flex-shrink-0">
<Text type={TextType.h3} fontWeight={FontWeight.semibold} classes="text-left">
{localize('popups.transaction.title')}
</Text>
{#if ownsNfts}
<Tabs bind:activeTab {tabs} />
{/if}
<send-form-inputs class="flex flex-col space-y-4">
{#if activeTab === SendForm.SendToken}
<AssetAmountInput bind:this={assetAmountInput} bind:asset bind:rawAmount bind:unit />
{:else}
<NftInput bind:nftId />
{/if}
<NetworkInput bind:network />
<RecipientInput bind:this={recipientInput} bind:recipient />
<optional-inputs class="flex flex-row flex-wrap gap-4">
<OptionalInput
bind:this={metadataInput}
bind:value={metadata}
label={localize('general.metadata')}
description={localize('tooltips.optionalInput')}
/>
<OptionalInput
bind:this={tagInput}
bind:value={tag}
label={localize('general.tag')}
description={localize('tooltips.optionalInput')}
/>
</optional-inputs>
</send-form-inputs>
<popup-buttons class="flex flex-row flex-nowrap w-full space-x-4">
<Button classes="w-full" outline onClick={onCancel}>
{localize('actions.cancel')}
</Button>
<Button classes="w-full" onClick={onContinue}>
{localize('actions.send')}
</Button>
</popup-buttons>
</send-form-popup>