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

fix(ui): Chatbar payment UI update #871

Open
wants to merge 86 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
ad4a207
basic
Jekrimo Oct 24, 2024
91c538f
add decline tacker
Jekrimo Oct 24, 2024
9a3e407
fixed
Jekrimo Oct 28, 2024
3928b99
better
Jekrimo Oct 28, 2024
8382c4b
moar
Jekrimo Oct 28, 2024
8e583e5
one more
Jekrimo Oct 31, 2024
5a490c0
yay
Jekrimo Oct 31, 2024
52816a9
gotit
Jekrimo Oct 31, 2024
c36609c
clean
Jekrimo Nov 1, 2024
c3b8c04
translations
Jekrimo Nov 1, 2024
7651be3
fix oops
Jekrimo Nov 1, 2024
136db60
miss
Jekrimo Nov 4, 2024
e818809
cln
Jekrimo Nov 4, 2024
e192682
wt
Jekrimo Nov 4, 2024
eca590d
start
Jekrimo Nov 4, 2024
4410944
wip
Jekrimo Nov 5, 2024
60c6e5d
Merge branch 'dev' into chatbar-payment-ui-update
Jekrimo Nov 11, 2024
0a7c9b1
merfge and fix
Jekrimo Nov 11, 2024
c6c4be4
bad merge
Jekrimo Nov 11, 2024
978d327
smol
Jekrimo Nov 11, 2024
13d51d1
sm
Jekrimo Nov 11, 2024
d862962
almost
Jekrimo Nov 11, 2024
cdd36bb
close
Jekrimo Nov 12, 2024
2d752a6
qu wip
Jekrimo Nov 12, 2024
3ec9948
got it
Jekrimo Nov 14, 2024
17b3ef6
test
Jekrimo Nov 14, 2024
17a362f
wip
Jekrimo Nov 19, 2024
fdd3e9b
yus and clean
Jekrimo Nov 20, 2024
cdf817e
clean
Jekrimo Nov 20, 2024
12ada6d
YUS
Jekrimo Nov 20, 2024
3f0f3c7
cln
Jekrimo Nov 20, 2024
fd4c825
fix
Jekrimo Nov 21, 2024
dc102c0
fix and clean
Jekrimo Nov 21, 2024
844e1e6
Merge branch 'dev' into chatbar-payment-ui-update
Jekrimo Nov 21, 2024
8eddfaf
clean spell
Jekrimo Nov 21, 2024
dd149f5
Merge branch 'chatbar-payment-ui-update' of https://github.com/Satell…
Jekrimo Nov 21, 2024
ff94f9b
unused classes
Jekrimo Nov 21, 2024
608cb27
Merge branch 'dev' into chatbar-payment-ui-update
Jekrimo Nov 22, 2024
8c91c07
Merge branch 'dev' into chatbar-payment-ui-update
Jekrimo Nov 25, 2024
2ac50c8
fix preview
Jekrimo Nov 25, 2024
c531a74
wierd but works!
Jekrimo Nov 25, 2024
7172a67
Merge branch 'dev' into chatbar-payment-ui-update
Jekrimo Nov 26, 2024
c9ab460
Merge branch 'dev' into chatbar-payment-ui-update
Jekrimo Dec 2, 2024
1817f1e
wip
Jekrimo Dec 2, 2024
f3acad4
Merge branch 'dev' into chatbar-payment-ui-update
stavares843 Dec 2, 2024
894a777
Merge branch 'dev' into chatbar-payment-ui-update
stavares843 Dec 2, 2024
330acf6
Merge branch 'dev' into chatbar-payment-ui-update
phillsatellite Dec 3, 2024
3351bc6
Merge branch 'dev' into chatbar-payment-ui-update
luisecm Dec 3, 2024
6e1e550
Merge branch 'dev' into chatbar-payment-ui-update
phillsatellite Dec 4, 2024
992deb4
so close
Jekrimo Dec 4, 2024
9abc894
Merge branch 'chatbar-payment-ui-update' of https://github.com/Satell…
Jekrimo Dec 4, 2024
4c3edd5
HUZZAH
Jekrimo Dec 4, 2024
023b8e5
clean
Jekrimo Dec 5, 2024
cb0648c
last one
Jekrimo Dec 5, 2024
5693c7c
Merge branch 'dev' into chatbar-payment-ui-update
phillsatellite Dec 5, 2024
229d9a1
Merge branch 'dev' into chatbar-payment-ui-update
stavares843 Dec 5, 2024
262f6d1
Merge branch 'dev' into chatbar-payment-ui-update
phillsatellite Dec 6, 2024
c7ad670
Merge branch 'dev' into chatbar-payment-ui-update
Jekrimo Dec 9, 2024
1e1dd0a
wooooof
Jekrimo Dec 9, 2024
bec7d4a
Merge branch 'chatbar-payment-ui-update' of https://github.com/Satell…
Jekrimo Dec 9, 2024
126115d
Merge branch 'dev' into chatbar-payment-ui-update
phillsatellite Dec 9, 2024
6e19f52
Merge branch 'dev' into chatbar-payment-ui-update
Jekrimo Dec 10, 2024
cd9735a
wip
Jekrimo Dec 11, 2024
3144133
Merge branch 'chatbar-payment-ui-update' of https://github.com/Satell…
Jekrimo Dec 11, 2024
173fd0e
fix busted btc messages
Jekrimo Dec 12, 2024
1fb8246
fix cancel message
Jekrimo Dec 12, 2024
fd34dfd
update(files): attempt to fix ci bugs
luisecm Dec 12, 2024
55e98ee
update(src): remove my changes since does nothing
luisecm Dec 12, 2024
df7ffd5
test
Jekrimo Dec 12, 2024
3b2a038
Merge branch 'chatbar-payment-ui-update' of https://github.com/Satell…
Jekrimo Dec 12, 2024
bf82386
Merge branch 'dev' into chatbar-payment-ui-update
luisecm Dec 12, 2024
4464bc0
Merge branch 'dev' into chatbar-payment-ui-update
luisecm Dec 13, 2024
ca429c8
Merge branch 'dev' into chatbar-payment-ui-update
tooshel Dec 15, 2024
555c63f
btc and eth error handles
Jekrimo Dec 17, 2024
b0e082a
Merge branch 'chatbar-payment-ui-update' of https://github.com/Satell…
Jekrimo Dec 17, 2024
72f2908
missing needed return
Jekrimo Dec 17, 2024
4d2fba2
sending user details got changed from wallet response updated the var…
Jekrimo Dec 17, 2024
4ff9819
Merge branch 'dev' into chatbar-payment-ui-update
stavares843 Dec 17, 2024
43a165c
Merge branch 'dev' into chatbar-payment-ui-update
luisecm Dec 18, 2024
09607c1
Merge branch 'dev' into chatbar-payment-ui-update
luisecm Dec 20, 2024
29fb6f8
up
Jekrimo Dec 26, 2024
43004f3
Merge branch 'chatbar-payment-ui-update' of https://github.com/Satell…
Jekrimo Dec 26, 2024
2ae534a
Merge branch 'dev' into chatbar-payment-ui-update
luisecm Dec 30, 2024
aa63bf6
Merge branch 'dev' into chatbar-payment-ui-update
luisecm Dec 30, 2024
0ede6ba
Merge branch 'dev' into chatbar-payment-ui-update
Jekrimo Jan 2, 2025
8cbe1d1
Merge branch 'dev' into chatbar-payment-ui-update
dariusc93 Jan 3, 2025
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
34 changes: 32 additions & 2 deletions src/lib/components/messaging/ChatPreview.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
$: user = chat.typing_indicator.users().map(u => {
return $lookupUsers[u]
})
$: self = get(Store.state.user)
let timeago = getTimeAgo(chat.last_message_at)
const dispatch = createEventDispatcher()
let ownId = get(Store.state.user)
Expand All @@ -57,9 +56,11 @@
? $_("message_previews.coin_requested", { values: { username: sendingUserDetails.name, amount: amountPreview } })
: $_("message_previews.request_sent", { values: { amount: amountPreview } })
} catch (error) {
console.log(chat.last_message_preview)
return "Invalid message format"
}
} else if (chat.last_message_preview.startsWith(PaymentRequestsEnum.Reject)) {
}
if (chat.last_message_preview.startsWith(PaymentRequestsEnum.Reject)) {
try {
const sendingUserId = ConversationStore.getMessage(chat.id, chat.last_message_id)?.details.origin
const sendingUserDetails = get(Store.getUser(sendingUserId!))
Expand All @@ -69,6 +70,35 @@
return $_("message_previews.coin_canceled")
}
} catch (error) {
console.log(chat.last_message_preview)
return "Invalid message format"
}
}
if (chat.last_message_preview.startsWith(PaymentRequestsEnum.Send)) {
try {
const sendingUserId = ConversationStore.getMessage(chat.id, chat.last_message_id)?.details.origin
const sendingUserDetails = get(Store.getUser(sendingUserId!))
const jsonStartIndex = chat.last_message_preview.indexOf("{")
if (jsonStartIndex === -1) {
console.error("No JSON found in last_message_preview:", chat.last_message_preview)
return "Invalid message format"
}
const jsonPart = chat.last_message_preview.slice(jsonStartIndex)
let parsedMessage
try {
parsedMessage = JSON.parse(jsonPart)
} catch (error) {
console.error("Error parsing JSON:", error, chat.last_message_preview)
return "Invalid message format"
}
const amountWei = parsedMessage.details.amount
if (sendingUserDetails.key !== ownId.key) {
return `${sendingUserDetails.name} sent you ${amountWei}`
} else {
return `You sent ${amountWei} to ${sendingUserDetails.name}`
}
} catch (error) {
console.error("Error in PaymentRequestsEnum.Send condition:", error)
return "Invalid message format"
}
}
Expand Down
260 changes: 220 additions & 40 deletions src/lib/components/wallet/CreateTransaction.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,107 @@
import Button from "$lib/elements/Button.svelte"
import { ConversationStore } from "$lib/state/conversation"
import { Store } from "$lib/state/Store"
import { AssetType, shortenAddr, Transfer, wallet, type Asset } from "$lib/utils/Wallet"
import { AssetType, getValidPaymentRequest, shortenAddr, Transfer, wallet, type Asset } from "$lib/utils/Wallet"
import { RaygunStoreInstance } from "$lib/wasm/RaygunStore"
import { get } from "svelte/store"
import { _ } from "svelte-i18n"
import { Select } from "$lib/elements"
import { Icon, Input, Label, Select, Text } from "$lib/elements"
import { Appearance, PaymentRequestsEnum, Shape, Size } from "$lib/enums"

export let onClose

enum ViewMode {
None = "",
Send = "send",
Receive = "receive",
QRScanner = "send",
SendFunds = "SendFunds",
}
let transfer = new Transfer()

let sendCoin = ViewMode.None
let initialSelect = "Select an asset"
async function sendMessage(text: string) {
let chat = get(Store.state.activeChat)
let txt = text.split("\n")
let result = await RaygunStoreInstance.send(chat.id, txt, [])
result.onSuccess(res => {
ConversationStore.addPendingMessages(chat.id, res.message, txt)
})
if (sendCoin === ViewMode.Send) {
let chat = get(Store.state.activeChat)
let txt = text.split("\n")
let whatReturned = await getValidPaymentRequest(txt[0])?.execute()
if (whatReturned !== undefined) {
let result = await RaygunStoreInstance.send(chat.id, txt, [])
result.onSuccess(res => {
ConversationStore.addPendingMessages(chat.id, res.message, txt)
})
}
}
if (sendCoin === ViewMode.Receive) {
let chat = get(Store.state.activeChat)
let txt = text.split("\n")
let result = await RaygunStoreInstance.send(chat.id, txt, [])
result.onSuccess(res => {
console.log(txt)
ConversationStore.addPendingMessages(chat.id, res.message, txt)
})
}
}

let inputAmount = ""

function onInputAmount() {
//remove any input that is not a number or a dot
isAmountTouched = true
console.log(transfer.asset.kind)
inputAmount = inputAmount.replace(/[^0-9.]/g, "")
//if there is more than 1 dot, only keep the first one
if (inputAmount.split(".").length > 2) {
let i = inputAmount.indexOf(".")
inputAmount = inputAmount.substring(0, i + 1) + inputAmount.substring(i + 1, inputAmount.length).replace(".", "")
const i = inputAmount.indexOf(".")
inputAmount = inputAmount.substring(0, i + 1) + inputAmount.substring(i + 1).replace(".", "")
}

//convert string amount to bigint
wallet.toBigIntAmount(transfer.asset, inputAmount).then(amount => {
transfer.amount = amount
wallet.toAmountPreviewString(transfer.asset, transfer.amount).then(amountPreview => {
transfer.amountPreview = amountPreview
const decimalPlaces = 18 // Max decimals for the asset type
const parts = inputAmount.split(".")
if (parts[1] && parts[1].length > decimalPlaces) {
inputAmount = parts[0] + "." + parts[1].substring(0, decimalPlaces)
}

isValidAmount = /^[0-9]+(\.[0-9]+)?$/.test(inputAmount)

if (isValidAmount) {
wallet.toBigIntAmount(transfer.asset, inputAmount).then(amount => {
transfer.amount = amount
wallet.toAmountPreviewString(transfer.asset, transfer.amount).then(amountPreview => {
transfer.amountPreview = amountPreview
})
})
})
}
}

let addressInput = ""
let isValidAddress = false
let isAddressTouched = false
let isValidAmount = false
let isAmountTouched = false
function onAddressInput() {
isAddressTouched = true

const bitcoinRegex = /^(1|3|bc1|tb1)[a-zA-HJ-NP-Z0-9]{25,62}$/
const ethereumRegex = /^0x[a-fA-F0-9]{40}$/

isValidAddress = bitcoinRegex.test(addressInput) || ethereumRegex.test(addressInput)

if (isValidAddress) {
transfer.toAddress = addressInput
}
}

onInputAmount()
function onChangeAssetKind() {
transfer.asset.id = ""
transfer.amount = BigInt(0)
onInputAmount()
wallet.myAddress(transfer.asset).then(address => {
transfer.toAddress = address
})
if (sendCoin !== ViewMode.Send) {
wallet.myAddress(transfer.asset).then(address => {
transfer.toAddress = address
})
} else {
wallet.myAddress(transfer.asset).then(address => {
transfer.toAddress = addressInput
})
}
}
onChangeAssetKind()

Expand All @@ -56,21 +111,146 @@
}
</script>

<div>
<div>{$_("payments.assetType") + ":"}<Select bind:selected={transfer.asset.kind} options={Object.values(AssetType).map(value => ({ value: value, text: value }))} on:change={onChangeAssetKind} /></div>
{#if needsAssetId()}
<div>{$_("payments.assetId") + ":"}<input bind:value={transfer.asset.id} on:change={onInputAmount} /></div>
{/if}
<div>{transfer.amountPreview}</div>
<div>{$_("payments.amount") + ":"} <input bind:value={inputAmount} type="text" on:input={onInputAmount} /></div>
{#if transfer.toAddress !== ""}
<div>{$_("payments.receiving_to")}: {shortenAddr(transfer.toAddress, 6)}</div>
{/if}
<div class="payment_modal">
<div class="title">
<Text size={Size.Large} color="#00B894" centered hook="chat-topbar-username" class="min-text" singleLine>Transfer Funds</Text>
</div>
<div class="transfer_type">
<Button
appearance={Appearance.Alt}
on:click={async () => {
sendCoin = ViewMode.Send
}}><Icon icon={Shape.DollarOut}></Icon>{$_("payments.send")}</Button>
<Button
appearance={Appearance.Alt}
on:click={async () => {
sendCoin = ViewMode.Receive
}}><Icon icon={Shape.DollarIn}></Icon>{$_("payments.request")}</Button>
</div>
{#if sendCoin === ViewMode.Send}
<div class="asset_selector">
<Label text={$_("payments.type") + ":"}></Label>
<Select bind:selected={transfer.asset.kind} options={Object.values(AssetType).map(value => ({ value: value, text: value }))} on:change={onChangeAssetKind} />
</div>

{#if transfer.asset.kind !== initialSelect}
<div class="address">
<Label text={$_("payments.address")} />
<div class="address_QR">
<Input bind:value={addressInput} on:input={onAddressInput} />
{#if isAddressTouched && !isValidAddress}
<span class="error">Invalid wallet address.</span>
{/if}
</div>
</div>
{/if}

<Button
disabled={!transfer.isValid()}
on:click={async () => {
await sendMessage(transfer.toCmdString())
onClose()
}}>{$_("payments.request")}</Button>
{#if isValidAddress && addressInput !== ""}
<div class="amount">
<Label text={$_("payments.amount")} />
<Input bind:value={inputAmount} on:input={onInputAmount} />
{#if isAmountTouched && !isValidAmount && inputAmount.length > 1}
<span class="error">Invalid amount format.</span>
{/if}
</div>
{/if}

{#if needsAssetId()}
<div class="payment_amount">
{$_("payments.assetId") + ":"}
<Input bind:value={transfer.asset.id} on:change={onInputAmount} />
</div>
{/if}

{#if isValidAddress && isValidAmount}
<div class="send_button">
<Button
disabled={!transfer.isValid()}
on:click={async () => {
await sendMessage(transfer.toDisplayString(transfer.asset.kind, inputAmount, transfer.toAddress))
onClose()
}}>{$_("payments.create_transaction")}</Button>
</div>
{/if}
{:else if sendCoin === ViewMode.Receive}
<div class="asset_selector">
<Label text={$_("payments.type") + ":"}></Label><Select bind:selected={transfer.asset.kind} options={Object.values(AssetType).map(value => ({ value: value, text: value }))} on:change={onChangeAssetKind} />
</div>
{#if transfer.toAddress !== ""}
<div class="address">
<Label text={$_("payments.address")} />
<div class="address_QR">
<Input value={transfer.toAddress} />
</div>
</div>
<div class="amount">
<Label text={$_("payments.amount")} />
<Input bind:value={inputAmount} on:input={onInputAmount} />
</div>
{/if}

{#if needsAssetId()}
<div class="payment_amount">{$_("payments.assetId") + ":"}<Input bind:value={transfer.asset.id} on:change={onInputAmount} /></div>
{/if}
<div class="send_button">
<Button
disabled={!transfer.isValid()}
on:click={async () => {
await sendMessage(transfer.toCmdString())
onClose()
}}>{$_("payments.create_transaction")}</Button>
</div>
{/if}
</div>

<style lang="scss">
.payment_modal {
padding: var(--gap-less);
max-width: 300px;
}
.title {
gap: var(--gap-less);
display: flex;
width: 100%;
align-items: center;
justify-content: center;
}
.address {
padding: var(--gap-less);
display: block;
width: 100%;
align-items: center;
justify-content: center;
}
.transfer_type {
display: flex;
width: 100%;
justify-content: space-between;
align-items: center;
padding: 0 5%;
}
.amount {
display: block;
width: 100%;
align-items: center;
justify-content: center;
padding: var(--gap-less);
}
.payment_amount {
display: inline-flex;
gap: var(--gap-less);
}
.send_button {
display: flex;
padding: var(--gap-less);
:global(button) {
width: 100%;
}
}
.asset_selector {
display: block;
justify-content: space-between;
align-items: center;
padding: var(--gap-less);
}
</style>
Loading
Loading