Skip to content

Commit

Permalink
fix: fix claiming for timelocked activity (#5849)
Browse files Browse the repository at this point in the history
* fix: fix claiming for timelocked activity

* refactor: remove code duplication

* fix: fix icon on async footer

* fix: fix when timelock content is displayed

* enhancement: dont show icon if date is succeeded

* enhancement: dont show claim on timelock activities without SDRUC

* fix: fix activities with timelock and expiration date

* chore: improve readability for conditions

---------

Co-authored-by: Nicole O'Brien <nicole.obrien@iota.org>
  • Loading branch information
MarkNerdi996 and nicole-obrien committed Feb 23, 2023
1 parent b7d9dcf commit cbd8515
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 71 deletions.
7 changes: 5 additions & 2 deletions packages/shared/components/atoms/tiles/ActivityTile.svelte
Expand Up @@ -21,6 +21,7 @@
NftActivityTileContent,
GovernanceActivityTileContent,
} from 'shared/components'
import { time } from '@core/app'
export let activity: Activity
Expand All @@ -30,6 +31,8 @@
activity.type === ActivityType.Basic || activity.type === ActivityType.Foundry
? getAssetFromPersistedAssets(activity.assetId)
: undefined)
$: isTimelocked = activity?.asyncData?.timelockDate > $time
$: shouldShowAsyncFooter = activity.asyncData && activity.asyncData.asyncStatus !== ActivityAsyncStatus.Claimed
function handleTransactionClick(): void {
if (asset?.verification?.status === NotVerifiedStatus.New) {
Expand Down Expand Up @@ -70,9 +73,9 @@
<FoundryActivityTileContent {activity} />
{/if}
</tile-content>
{#if activity.asyncData?.asyncStatus === ActivityAsyncStatus.Timelocked}
{#if isTimelocked}
<TimelockActivityTileFooter {activity} />
{:else if activity.asyncData}
{:else if shouldShowAsyncFooter}
<AsyncActivityTileFooter {activity} />
{/if}
</activity-tile>
Expand Down
Expand Up @@ -30,9 +30,9 @@
(activity.direction === ActivityDirection.Incoming ||
activity.direction === ActivityDirection.SelfTransaction) &&
activity.asyncData?.asyncStatus === ActivityAsyncStatus.Unclaimed
$: shouldShowAsyncFooter = activity.asyncData?.asyncStatus !== ActivityAsyncStatus.Claimed
$: timeDiff = getTimeDiff(activity)
$: hasExpirationTime = !!activity.asyncData?.expirationDate
function handleRejectClick(): void {
openPopup({
Expand Down Expand Up @@ -68,45 +68,49 @@
return getTimeDifference(expirationDate, $time)
}
}
return localize('general.none')
return undefined
}
</script>

{#if shouldShowAsyncFooter}
<TileFooter>
<svelte:fragment slot="left">
<TileFooter>
<svelte:fragment slot="left">
{#if timeDiff}
<TooltipIcon
icon={IconEnum.ExpirationTime}
icon={hasExpirationTime ? IconEnum.ExpirationTime : IconEnum.Timelock}
iconClasses="text-gray-600 dark:text-gray-200"
title={localize('general.expirationTime')}
text={localize(`tooltips.transactionDetails.${activity.direction}.expirationTime`)}
title={localize(`general.${hasExpirationTime ? 'expirationTime' : 'timelockDate'}`)}
text={localize(
`tooltips.transactionDetails.${activity.direction}.${
hasExpirationTime ? 'expirationTime' : 'timelockDate'
}`
)}
position={Position.Top}
/>
<Text fontSize="13" color="gray-600" fontWeight={FontWeight.semibold}>{timeDiff}</Text>
</svelte:fragment>
<svelte:fragment slot="right">
{#if shouldShowActions}
<Button
onClick={handleRejectClick}
disabled={activity.asyncData?.isClaiming || activity.asyncData?.isRejected}
inlineStyle="min-width: 4rem;"
size={ButtonSize.Small}
outline
>
{localize('actions.reject')}
</Button>
<Button
onClick={handleClaimClick}
disabled={activity.asyncData?.isClaiming}
isBusy={activity.asyncData?.isClaiming}
inlineStyle="min-width: 4rem;"
size={ButtonSize.Small}
>
{localize('actions.claim')}
</Button>
{:else}
<ActivityAsyncStatusPill asyncStatus={activity.asyncData?.asyncStatus} />
{/if}
</svelte:fragment>
</TileFooter>
{/if}
{/if}
</svelte:fragment>
<svelte:fragment slot="right">
{#if shouldShowActions}
<Button
onClick={handleRejectClick}
disabled={activity.asyncData?.isClaiming || activity.asyncData?.isRejected}
inlineStyle="min-width: 4rem;"
size={ButtonSize.Small}
outline
>
{localize('actions.reject')}
</Button>
<Button
onClick={handleClaimClick}
disabled={activity.asyncData?.isClaiming}
isBusy={activity.asyncData?.isClaiming}
inlineStyle="min-width: 4rem;"
size={ButtonSize.Small}
>
{localize('actions.claim')}
</Button>
{:else}
<ActivityAsyncStatusPill asyncStatus={activity.asyncData?.asyncStatus} />
{/if}
</svelte:fragment>
</TileFooter>
@@ -1,9 +1,9 @@
import { syncBalance } from '@core/account/actions/syncBalance'
import { Activity } from '@core/wallet/types'
import { updateNftInAllAccountNfts } from '@core/nfts'
import { ActivityAsyncStatus, ActivityDirection, ActivityType } from '@core/wallet/enums'
import { allAccountActivities } from '../../stores'
import { refreshAccountAssetsForActiveProfile } from '../refreshAccountAssetsForActiveProfile'
import { getAsyncStatus } from '@core/wallet/utils/generateActivity/helper'

export function setAsyncStatusOfAccountActivities(time: Date): void {
const balancesToUpdate: number[] = []
Expand All @@ -14,8 +14,13 @@ export function setAsyncStatusOfAccountActivities(time: Date): void {
if (oldAsyncStatus === ActivityAsyncStatus.Claimed || oldAsyncStatus === ActivityAsyncStatus.Expired) {
continue
}
activity.asyncData.asyncStatus = getAsyncStatus(activity, time)

activity.asyncData.asyncStatus = getAsyncStatus(
false,
activity.asyncData.expirationDate,
activity.asyncData.timelockDate,
!!activity.storageDeposit,
time.getTime()
)
if (oldAsyncStatus !== null && oldAsyncStatus !== activity.asyncData.asyncStatus) {
if (!balancesToUpdate.includes(accountIndex)) {
balancesToUpdate.push(accountIndex)
Expand All @@ -40,19 +45,3 @@ export function setAsyncStatusOfAccountActivities(time: Date): void {
void refreshAccountAssetsForActiveProfile()
}
}

function getAsyncStatus(activity: Activity, time: Date): ActivityAsyncStatus {
if (activity.asyncData?.timelockDate) {
if (activity.asyncData.timelockDate.getTime() > time.getTime()) {
return ActivityAsyncStatus.Timelocked
}
} else if (activity.asyncData) {
if (activity.asyncData.asyncStatus !== ActivityAsyncStatus.Claimed) {
if (time > activity.asyncData.expirationDate) {
return ActivityAsyncStatus.Expired
} else {
return ActivityAsyncStatus.Unclaimed
}
}
}
}
Expand Up @@ -6,4 +6,8 @@ export const UNLOCK_CONDITION_STATE_CONTROLLER_ADDRESS = 4
export const UNLOCK_CONDITION_GOVERNOR_ADDRESS = 5
export const UNLOCK_CONDITION_IMMUTABLE_ALIAS = 6

export const ASYNC_UNLOCK_CONDITION_TYPES = [UNLOCK_CONDITION_STORAGE_DEPOSIT_RETURN, UNLOCK_CONDITION_EXPIRATION]
export const ASYNC_UNLOCK_CONDITION_TYPES = [
UNLOCK_CONDITION_STORAGE_DEPOSIT_RETURN,
UNLOCK_CONDITION_EXPIRATION,
UNLOCK_CONDITION_TIMELOCK,
]
@@ -1,8 +1,10 @@
import { IAccountState } from '@core/account'
import { isActivityHiddenForAccountIndex, ActivityAsyncStatus, IClaimData, Output, AsyncData } from '@core/wallet'
import { isActivityHiddenForAccountIndex, IClaimData, Output, AsyncData } from '@core/wallet'
import { getExpirationDateFromOutput } from '../../outputs/getExpirationDateFromOutput'
import { getTimelockDateFromOutput } from './getTimelockDateFromOutput'
import { isOutputAsync } from '../../outputs/isOutputAsync'
import { getAsyncStatus } from './getAsyncStatus'
import { getStorageDepositFromOutput } from './getStorageDepositFromOutput'

export function getAsyncDataFromOutput(
output: Output,
Expand All @@ -19,19 +21,15 @@ export function getAsyncDataFromOutput(

const expirationDate = getExpirationDateFromOutput(output)
const timelockDate = getTimelockDateFromOutput(output)
const { storageDeposit } = getStorageDepositFromOutput(output)

let asyncStatus
if (claimingData) {
asyncStatus = ActivityAsyncStatus.Claimed
} else if (timelockDate) {
if (timelockDate.getTime() > Date.now()) {
asyncStatus = ActivityAsyncStatus.Timelocked
}
} else if (expirationDate && expirationDate.getTime() < Date.now()) {
asyncStatus = ActivityAsyncStatus.Expired
} else {
asyncStatus = ActivityAsyncStatus.Unclaimed
}
const asyncStatus = getAsyncStatus(
!!claimingTransactionId,
expirationDate,
timelockDate,
!!storageDeposit,
Date.now()
)

return {
asyncStatus,
Expand Down
@@ -0,0 +1,23 @@
import { ActivityAsyncStatus } from '@core/wallet/enums'

export function getAsyncStatus(
isClaimed: boolean,
expirationDate: Date,
timelockDate: Date,
hasStorageDeposit: boolean,
currentTimeStamp: number
): ActivityAsyncStatus {
if (isClaimed) {
return ActivityAsyncStatus.Claimed
} else if (timelockDate && timelockDate.getTime() > currentTimeStamp) {
return ActivityAsyncStatus.Timelocked
} else if (expirationDate && expirationDate.getTime() < currentTimeStamp) {
return ActivityAsyncStatus.Expired
} else if (hasStorageDeposit || expirationDate) {
return ActivityAsyncStatus.Unclaimed
} else if (timelockDate) {
return ActivityAsyncStatus.Claimed
} else {
return ActivityAsyncStatus.Unclaimed
}
}
@@ -1,5 +1,6 @@
export * from './getActivityTypeFromOutput'
export * from './getAsyncDataFromOutput'
export * from './getAsyncStatus'
export * from './getAmountFromOutput'
export * from './getSendingInformation'
export * from './getGovernanceInfo'
Expand Down
Expand Up @@ -22,6 +22,6 @@ export function getTimeDifference(lateDate: Date, earlyDate: Date): string {
} else if (seconds > 0) {
return '<1min'
} else {
return '-'
return undefined
}
}

0 comments on commit cbd8515

Please sign in to comment.