-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
885 additions
and
98 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { atom, useAtomValue, useStore } from 'jotai' | ||
import { useMemo } from 'react' | ||
import { AssetLookupResult, AssetResult } from '@algorandfoundation/algokit-utils/types/indexer' | ||
import { atomEffect } from 'jotai-effect' | ||
import { loadable } from 'jotai/utils' | ||
import { indexer } from '../common/data' | ||
|
||
// TODO: Size should be capped at some limit, so memory usage doesn't grow indefinitely | ||
export const assetsAtom = atom<AssetResult[]>([]) | ||
|
||
export const useAssetAtom = (assetIndex: number) => { | ||
const store = useStore() | ||
|
||
return useMemo(() => { | ||
const syncEffect = atomEffect((get, set) => { | ||
;(async () => { | ||
try { | ||
const asset = await get(assetAtom) | ||
set(assetsAtom, (prev) => { | ||
return prev.concat(asset) | ||
}) | ||
} catch (e) { | ||
// Ignore any errors as there is nothing to sync | ||
} | ||
})() | ||
}) | ||
const assetAtom = atom((get) => { | ||
// store.get prevents the atom from being subscribed to changes in assetsAtom | ||
const assets = store.get(assetsAtom) | ||
const asset = assets.find((a) => a.index === assetIndex) | ||
if (asset) { | ||
return asset | ||
} | ||
|
||
get(syncEffect) | ||
|
||
return indexer | ||
.lookupAssetByID(assetIndex) | ||
.do() | ||
.then((result) => { | ||
return (result as AssetLookupResult).asset | ||
}) | ||
}) | ||
return assetAtom | ||
}, [store, assetIndex]) | ||
} | ||
|
||
export const useLoadableAsset = (assetId: number) => { | ||
return useAtomValue( | ||
// Unfortunately we can't leverage Suspense here, as react doesn't support async useMemo inside the Suspense component | ||
// https://github.com/facebook/react/issues/20877 | ||
loadable(useAssetAtom(assetId)) | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { AssetResult } from '@algorandfoundation/algokit-utils/types/indexer' | ||
import { AssetModel } from '../models' | ||
|
||
export const asAsset = (assetResult: AssetResult): AssetModel => { | ||
return { | ||
id: assetResult.index, | ||
name: assetResult.params.name, | ||
total: assetResult.params.total, | ||
decimals: assetResult.params.decimals, | ||
unitName: assetResult.params['unit-name'], | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export type AssetModel = { | ||
id: number | ||
name?: string | ||
total: number | bigint | ||
decimals: number | bigint | ||
unitName?: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { AssetModel } from '@/features/assets/models' | ||
import Decimal from 'decimal.js' | ||
|
||
type Props = { | ||
amount: number | bigint | ||
asset: AssetModel | ||
} | ||
|
||
export const DisplayAssetAmount = ({ amount, asset }: Props) => { | ||
// asset decimals value must be from 0 to 19 so it is safe to use .toString() here | ||
const decimals = asset.decimals.toString() | ||
// the amount is uint64, should be safe to be .toString() | ||
const amountAsString = amount.toString() | ||
|
||
return ( | ||
<div> | ||
{new Decimal(amountAsString).div(new Decimal(10).pow(decimals)).toString()} {asset.unitName ?? ''} | ||
</div> | ||
) | ||
} |
155 changes: 155 additions & 0 deletions
155
...ts__/asset-transfer-view-visual.JBDSQEI37W5KWPQICT2IGCG2FWMUGJEUYYK3KFKNSYRNAXU2ARUA.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
<div> | ||
<div | ||
class="relative grid" | ||
style="grid-template-columns: minmax(128px, 128px) repeat(3, 128px); grid-template-rows: repeat(2, 40px);" | ||
> | ||
<div /> | ||
<div | ||
class="p-2 flex justify-center" | ||
> | ||
<h1 | ||
class="text-l font-semibold" | ||
> | ||
6MO6...HSJM | ||
</h1> | ||
</div> | ||
<div | ||
class="p-2 flex justify-center" | ||
> | ||
<h1 | ||
class="text-l font-semibold" | ||
> | ||
OCD5...4IFA | ||
</h1> | ||
</div> | ||
<div /> | ||
<div | ||
class="absolute right-0 -z-10" | ||
style="top: 40px;" | ||
> | ||
<div> | ||
<div | ||
class="p-0" | ||
/> | ||
<div | ||
class="p-0" | ||
style="height: 40px; width: 256px;" | ||
> | ||
<div | ||
class="grid h-full" | ||
style="grid-template-columns: repeat(2, minmax(0, 1fr)); height: 40px;" | ||
> | ||
<div | ||
class="flex justify-center" | ||
> | ||
<div | ||
class="border-muted h-full border-dashed" | ||
style="border-left-width: 2px;" | ||
/> | ||
</div> | ||
<div | ||
class="flex justify-center" | ||
> | ||
<div | ||
class="border-muted h-full border-dashed" | ||
style="border-left-width: 2px;" | ||
/> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
<div | ||
class="p-0 relative pr-8" | ||
> | ||
<div | ||
class="relative h-full p-0 flex items-center px-0" | ||
style="margin-left: 0px;" | ||
> | ||
<div | ||
class="inline" | ||
style="margin-left: 16px;" | ||
> | ||
JBDSQEI... | ||
</div> | ||
</div> | ||
</div> | ||
<div | ||
class="flex items-center justify-center" | ||
data-state="closed" | ||
style="grid-column-start: 2; grid-column-end: 4; color: rgb(126 200 191);" | ||
> | ||
<svg | ||
height="20" | ||
viewBox="0 0 21 21" | ||
width="20" | ||
xmlns="http://www.w3.org/2000/svg" | ||
xmlns:xlink="http://www.w3.org/1999/xlink" | ||
> | ||
<g | ||
transform="matrix(1 0 0 1 -153 -143 )" | ||
> | ||
<path | ||
d="M 163.5 143 C 169.38 143 174 147.62 174 153.5 C 174 159.38 169.38 164 163.5 164 C 157.62 164 153 159.38 153 153.5 C 153 147.62 157.62 143 163.5 143 Z " | ||
fill="currentColor" | ||
fill-rule="nonzero" | ||
stroke="none" | ||
/> | ||
</g> | ||
</svg> | ||
<div | ||
class="relative" | ||
style="width: calc(50.00% - 20px); height: 20px;" | ||
> | ||
<div | ||
class="h-1/2" | ||
style="border-bottom-width: 2px;" | ||
/> | ||
<svg | ||
class="absolute top-0 right-0" | ||
height="19px" | ||
preserveAspectRatio="xMinYMid meet" | ||
viewBox="340 139 1 13" | ||
width="11px" | ||
xmlns="http://www.w3.org/2000/svg" | ||
xmlns:xlink="http://www.w3.org/1999/xlink" | ||
> | ||
<path | ||
d="M 340.3 151.3 L 347 145.3 L 340.3 139.3 L 342.6 145.3 L 340.3 151.3 Z" | ||
fill="currentColor" | ||
fill-rule="nonzero" | ||
stroke="none" | ||
/> | ||
</svg> | ||
</div> | ||
<div | ||
class="absolute z-20 bg-card p-2 text-foreground w-20 text-xs" | ||
> | ||
Transfer | ||
<div> | ||
0.3 | ||
|
||
AKTA | ||
</div> | ||
</div> | ||
<svg | ||
height="20" | ||
viewBox="0 0 21 21" | ||
width="20" | ||
xmlns="http://www.w3.org/2000/svg" | ||
xmlns:xlink="http://www.w3.org/1999/xlink" | ||
> | ||
<g | ||
transform="matrix(1 0 0 1 -153 -143 )" | ||
> | ||
<path | ||
d="M 163.5 143 C 169.38 143 174 147.62 174 153.5 C 174 159.38 169.38 164 163.5 164 C 157.62 164 153 159.38 153 153.5 C 153 147.62 157.62 143 163.5 143 Z " | ||
fill="currentColor" | ||
fill-rule="nonzero" | ||
stroke="none" | ||
/> | ||
</g> | ||
</svg> | ||
</div> | ||
</div> | ||
</div> |
File renamed without changes.
File renamed without changes.
75 changes: 75 additions & 0 deletions
75
src/features/transactions/components/asset-transfer-transaction-info.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { cn } from '@/features/common/utils' | ||
import { useMemo } from 'react' | ||
import { AssetTransferTransactionModel } from '../models' | ||
import { DescriptionList } from '@/features/common/components/description-list' | ||
import { transactionSenderLabel, transactionReceiverLabel, transactionAmountLabel } from './transaction-view-table' | ||
import { DisplayAssetAmount } from '@/features/common/components/display-asset-amount' | ||
|
||
type Props = { | ||
transaction: AssetTransferTransactionModel | ||
} | ||
|
||
export const assetLabel = 'Asset' | ||
export const transactionCloseRemainderToLabel = 'Close Remainder To' | ||
export const transactionCloseRemainderAmountLabel = 'Close Remainder Amount' | ||
|
||
export function AssetTransferTransactionInfo({ transaction }: Props) { | ||
const items = useMemo( | ||
() => [ | ||
{ | ||
dt: transactionSenderLabel, | ||
dd: ( | ||
<a href="#" className={cn('text-primary underline')}> | ||
{transaction.sender} | ||
</a> | ||
), | ||
}, | ||
{ | ||
dt: transactionReceiverLabel, | ||
dd: ( | ||
<a href="#" className={cn('text-primary underline')}> | ||
{transaction.receiver} | ||
</a> | ||
), | ||
}, | ||
{ | ||
dt: assetLabel, | ||
dd: ( | ||
<a href="#" className={cn('text-primary underline')}> | ||
{transaction.asset.id} {`${transaction.asset.name ? `(${transaction.asset.name})` : ''}`} | ||
</a> | ||
), | ||
}, | ||
{ | ||
dt: transactionAmountLabel, | ||
dd: <DisplayAssetAmount amount={transaction.amount} asset={transaction.asset} />, | ||
}, | ||
...(transaction.closeRemainder | ||
? [ | ||
{ | ||
dt: transactionCloseRemainderToLabel, | ||
dd: ( | ||
<a href="#" className={cn('text-primary underline')}> | ||
{transaction.closeRemainder.to} | ||
</a> | ||
), | ||
}, | ||
{ | ||
dt: transactionCloseRemainderAmountLabel, | ||
dd: <DisplayAssetAmount amount={transaction.closeRemainder.amount} asset={transaction.asset} />, | ||
}, | ||
] | ||
: []), | ||
], | ||
[transaction.sender, transaction.receiver, transaction.asset, transaction.amount, transaction.closeRemainder] | ||
) | ||
|
||
return ( | ||
<div className={cn('space-y-2')}> | ||
<div className={cn('flex items-center justify-between')}> | ||
<h1 className={cn('text-2xl text-primary font-bold')}>Asset Transfer</h1> | ||
</div> | ||
<DescriptionList items={items} /> | ||
</div> | ||
) | ||
} |
Oops, something went wrong.