Skip to content

Commit

Permalink
fix(payments): update ui and verbiage for payment bubbles (#813)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jekrimo authored Nov 11, 2024
1 parent 8b7bd3b commit fc1e578
Show file tree
Hide file tree
Showing 8 changed files with 254 additions and 39 deletions.
16 changes: 14 additions & 2 deletions src/lib/components/messaging/ChatPreview.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import TimeAgo from "javascript-time-ago"
import { Appearance, ChatType, Route, Shape, Size, Status } from "$lib/enums"
import { Appearance, ChatType, PaymentRequestsEnum, Route, Shape, Size, Status } from "$lib/enums"
import type { Chat } from "$lib/types"
import { Text, Loader, Button, Icon } from "$lib/elements"
import { ProfilePicture } from "$lib/components"
Expand Down Expand Up @@ -48,7 +48,7 @@
return $_("message_previews.attachment")
}
if (chat.last_message_preview.startsWith("/request")) {
if (chat.last_message_preview.startsWith(PaymentRequestsEnum.Request)) {
try {
const sendingUserId = ConversationStore.getMessage(chat.id, chat.last_message_id)?.details.origin
const sendingUserDetails = get(Store.getUser(sendingUserId!))
Expand All @@ -60,6 +60,18 @@
} catch (error) {
return "Invalid message format"
}
} else 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!))
if (get(Store.getUser(sendingUserId!)).key !== ownId.key) {
return $_("message_previews.coin_declined", { values: { username: sendingUserDetails.name } })
} else {
return $_("message_previews.coin_canceled")
}
} catch (error) {
return "Invalid message format"
}
}
return chat.last_message_preview
Expand Down
5 changes: 5 additions & 0 deletions src/lib/enums/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ export enum Color {
RESET = "&r",
}

export enum PaymentRequestsEnum {
Reject = "/reject",
Request = "/request",
}

export enum Format {
BOLD = "&l",
STRIKETHROUGH = "&m",
Expand Down
12 changes: 11 additions & 1 deletion src/lib/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@
"none": "No messages sent yet.",
"attachment": "New attachment",
"coin_requested": "{username} has requested {amount}",
"coin_declined": "{username} has declined payment",
"coin_canceled": "You canceled coin request",
"request_sent": "You sent a request for {amount}"
},
"friends": {
Expand Down Expand Up @@ -203,14 +205,22 @@
"send": "Send",
"receive": "Receive",
"receiving_to": "Receiving to",
"send_coin": "Send Coin",
"sendCoin": "Send Coin",
"amount": "Amount",
"from": "From",
"to": "To",
"note": "Note",
"date": "Date",
"decline": "Decline",
"create": "Create Payment Request",
"declinePayment": "Decline Payment",
"sentRequest": "Request has been sent",
"cancel_request": "Cancel Request",
"canceledRequest": "Canceled Request",
"network": "Network",
"paymentDeclined": "Payment Canceled",
"youCanceledRequest": "You Canceled Payment Request",
"declinedPayment": "{user} Canceled Payment",
"assetType": "Asset type",
"assetName": "Asset name",
"assetId": "Asset Id",
Expand Down
1 change: 1 addition & 0 deletions src/lib/state/Store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class GlobalStore {
openFolders: createPersistentState<Record<string, boolean>>("uplink.openFolders", {}),
toasts: writable({}),
userCache: writable({}),
paymentTracker: createPersistentState("uplink.paymentTracker", []),
pageState: writable(""),
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/lib/state/initial.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Call, Chat, FileInfo, FriendRequest, User } from "$lib/types"
import type { Call, Chat, FileInfo, FriendRequest, PaymentTracker, User } from "$lib/types"
import type { Writable } from "svelte/store"
import type { ToastMessage } from "./ui/toast"
import type { VoiceRTCUser } from "$lib/media/Voice"
Expand Down Expand Up @@ -34,5 +34,6 @@ export interface IState {
// A cache of all fetched user data
// We use a Writable<User> to also allow easy subscription to changes if only that user interests us
userCache: Writable<{ [key: string]: Writable<User> }>
paymentTracker: Writable<PaymentTracker[]>
pageState: Writable<string>
}
6 changes: 6 additions & 0 deletions src/lib/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,12 @@ export type Transaction = {
note: string
}

export type PaymentTracker = {
messageId: string
senderId: string
rejectedPayment: boolean
}

export type Keybind = {
action: KeybindAction
key: string
Expand Down
45 changes: 39 additions & 6 deletions src/lib/utils/Wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -460,12 +460,14 @@ export class Transfer {
amount: bigint
toAddress: string
amountPreview: string
id: string

constructor() {
this.asset = { kind: AssetType.None, id: "" }
this.amount = BigInt(0)
this.toAddress = ""
this.amountPreview = ""
this.id = ""
}

isValid(): boolean {
Expand All @@ -489,6 +491,11 @@ export class Transfer {
return `/request ${transfer}`
}

toRejectString(id: string) {
let transfer = JSON.stringify(this, (k, v) => (k === "amount" && typeof v === "bigint" ? v.toString() : v))
return `/reject ${id}`
}

toDisplayString(): string {
let id = this.asset.id === "n/a" ? "" : this.asset.id
return `Send ${this.amountPreview} to ${shortenAddr(this.toAddress, 6)}`
Expand All @@ -501,24 +508,50 @@ export class Transfer {
}
}

export function getValidPaymentRequest(msg: string): Transfer | undefined {
let cmd = "/request "
if (msg.startsWith(cmd)) {
let json = msg.substring(cmd.length, msg.length)
export function getValidPaymentRequest(msg: string, msgId?: string): Transfer | undefined {
let requestCmd = "/request"
let rejectCmd = "/reject"

if (msg.startsWith(requestCmd)) {
let json = msg.substring(requestCmd.length, msg.length).trim()
let transfer = new Transfer()
try {
let parsed = JSON.parse(json, (k, v) => (k === "amount" && typeof v === "string" ? BigInt(v) : v))
transfer.asset = parsed.asset
transfer.amount = parsed.amount
transfer.toAddress = parsed.toAddress
transfer.amountPreview = parsed.amountPreview
} catch {
// if it wasn't valid json, do nothing.
} catch (err) {
console.log("Parse Failed", err)
}
if (transfer.asset.kind !== AssetType.None && transfer.isValid()) {
return transfer
}
} else if (msg.startsWith(rejectCmd)) {
let json = msg.substring(rejectCmd.length, msg.length).trim()
let transfer = new Transfer()

if (json.startsWith("{")) {
try {
let parsed = JSON.parse(json, (k, v) => (k === "amount" && typeof v === "string" ? BigInt(v) : v))
transfer.asset = parsed.asset
transfer.amount = parsed.amount
transfer.toAddress = parsed.toAddress
transfer.amountPreview = parsed.amountPreview
} catch (err) {
console.log("Parse Failed", err)
}
} else {
console.log("Reject message is not JSON, possibly an ID or UUID:", json)
return undefined
}

if (transfer.asset.kind !== AssetType.None && transfer.isValid()) {
return transfer
}
}

return undefined
}

export function shortenAddr(str: string, numChars: number): string {
Expand Down
Loading

0 comments on commit fc1e578

Please sign in to comment.