Skip to content

Commit

Permalink
Merge branch 'develop' into 2000-highlight-checkbox-in-connectionrequ…
Browse files Browse the repository at this point in the history
…estdrawer
  • Loading branch information
Tuditi authored Feb 28, 2024
2 parents 3136d21 + 70a7506 commit 9cc1848
Show file tree
Hide file tree
Showing 36 changed files with 387 additions and 205 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
import { Icon, IconName, Text, TooltipIcon } from '@bloomwalletio/ui'
import { ABSTAIN_VOTE_VALUE } from '@contexts/governance/constants'
import { getPercentagesFromAnswerStatuses, IProposalAnswerPercentages } from '@contexts/governance'
import {
getPercentagesFromAnswerStatuses,
getProjectedPercentages,
IProposalAnswerPercentages,
} from '@contexts/governance'
import { selectedProposal } from '@contexts/governance/stores'
export let onQuestionClick: (questionIndex: number) => void
Expand All @@ -18,12 +22,15 @@
export let selectedAnswerValue: number = undefined
export let votedAnswerValue: number = undefined
export let isLoading: boolean = false
export let projected: boolean = false
let percentages: IProposalAnswerPercentages = {}
let winnerAnswerIndex: number
$: answers = [...(question?.answers ?? []), { value: 0, text: 'Abstain', additionalInfo: '' }]
$: percentages = getPercentagesFromAnswerStatuses(answerStatuses)
$: percentages = projected
? getProjectedPercentages(answerStatuses)
: getPercentagesFromAnswerStatuses(answerStatuses)
$: disabled =
$selectedProposal?.status === EventStatus.Upcoming ||
$selectedProposal?.status === EventStatus.Ended ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
VotingEventPayload,
TrackedParticipationOverview,
} from '@iota/sdk/out/types'
import { Alert, Button } from '@bloomwalletio/ui'
import { Alert, Button, Text, Toggle, TooltipIcon } from '@bloomwalletio/ui'
import { getVotingEvent } from '@contexts/governance/actions'
import { ABSTAIN_VOTE_VALUE } from '@contexts/governance/constants'
import {
Expand Down Expand Up @@ -37,6 +37,7 @@
let openedQuestionIndex: number = -1
let isUpdatingVotedAnswerValues: boolean = false
let lastAction: 'vote' | 'stopVote'
let projected: boolean = false
$: selectedProposalOverview = $participationOverviewForSelectedAccount?.participations?.[$selectedProposal?.id]
$: trackedParticipations = Object.values(selectedProposalOverview ?? {})
Expand Down Expand Up @@ -179,7 +180,15 @@
})
</script>

<Pane classes="w-3/5 h-full p-6 pr-3 flex flex-col justify-between">
<Pane classes="w-3/5 h-full p-6 pr-3 flex flex-col justify-between gap-4">
{@const isVotable = [EventStatus.Commencing, EventStatus.Holding].includes($selectedProposal?.status)}
{#if isVotable}
<div class="flex justify-end items-center gap-2 px-5">
<TooltipIcon tooltip={localize('views.governance.details.projection.tooltip')} />
<Text>{localize('views.governance.details.projection.label')}</Text>
<Toggle label="" bind:checked={projected} />
</div>
{/if}
<proposal-questions
class="relative flex flex-1 flex-col space-y-5 overflow-y-scroll pr-3"
bind:this={proposalQuestions}
Expand All @@ -196,13 +205,14 @@
answerStatuses={$selectedParticipationEventStatus?.questions[questionIndex]?.answers}
{onQuestionClick}
{onAnswerClick}
{projected}
/>
{/each}
{/if}
</proposal-questions>
{#if $selectedProposal?.status === EventStatus.Upcoming}
<Alert variant="info" text={alertText} />
{:else if [EventStatus.Commencing, EventStatus.Holding].includes($selectedProposal?.status)}
{:else if isVotable}
{@const isLoaded = questions && overviewLoaded && statusLoaded}
{@const isStoppingVote = lastAction === 'stopVote' && hasGovernanceTransactionInProgress}
{@const isStopVotingDisabled = !isLoaded || !isVotingForProposal || isUpdatingVotedAnswerValues}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
}
function getFormattedMarketPrice(_activity: Activity): string | undefined {
if ((_activity.type === ActivityType.Basic || _activity.type === ActivityType.Foundry) && token) {
if ([ActivityType.Basic, ActivityType.Governance, ActivityType.Foundry].includes(_activity.type) && token) {
const amount = _activity.tokenTransfer?.rawAmount ?? _activity.baseTokenTransfer.rawAmount
const marketPrice = getFiatValueFromTokenAmount(amount, token)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
<script lang="ts">
import { ITokenWithBalance } from '@core/token'
import { ExpiredActivityPill, TimelockActivityPill, NftAvatar, TokenAvatar, UnclaimedActivityPill } from '@ui'
import {
ExpiredActivityPill,
TimelockActivityPill,
NftAvatar,
TokenAvatar,
UnclaimedActivityPill,
GovernanceAvatar,
} from '@ui'
import {
ActivityType,
getActivityActionColor,
getActivityActionTextColor,
getActivityActionPill,
getActivityTileAction,
getActivityTileAsset,
Expand Down Expand Up @@ -33,35 +40,37 @@
? getNftByIdFromAllAccountNfts($selectedAccountIndex, activity.nftId)
: undefined)
$: color = getActivityActionColor(activity, $darkMode)
$: color = getActivityActionTextColor(activity)
$: pill = getActivityActionPill(activity, $time)
</script>

<div class="flex flex-row gap-4 items-center overflow-hidden">
<div class="py-1">
{#if token}
{#if activity.type === ActivityType.Governance}
<GovernanceAvatar governanceAction={activity.governanceAction} size="lg" />
{:else if token}
<TokenAvatar {token} hideNetworkBadge size="lg" />
{:else if activity.type === ActivityType.Nft}
<NftAvatar {nft} size="lg" shape="square" />
{:else if activity.type === ActivityType.SmartContract}
<Avatar
icon={IconName.FileCode}
size="lg"
textColor="brand"
textColor="primary"
backgroundColor={$darkMode ? 'surface-2-dark' : 'surface-2'}
/>
{:else if activity.type === ActivityType.Alias}
<Avatar
icon={IconName.Alias}
size="lg"
textColor="brand"
textColor="primary"
backgroundColor={$darkMode ? 'surface-2-dark' : 'surface-2'}
/>
{/if}
</div>
<div class="flex flex-col items-start justify-between overflow-hidden">
<div class="w-full flex flex-row gap-1 overflow-hidden">
<Text customColor={color} class="shrink-0">{localize(getActivityTileAction(activity))}</Text>
<Text textColor={color} class="shrink-0">{localize(getActivityTileAction(activity))}</Text>
<Text truncate>{getActivityTileAsset(activity, $selectedAccountIndex)}</Text>
</div>
<div class="flex gap-2">
Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion packages/shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"author": "Bloom Labs Ltd <[email protected]>",
"license": "Apache-2.0",
"dependencies": {
"@bloomwalletio/ui": "0.20.6",
"@bloomwalletio/ui": "0.20.8",
"@ethereumjs/rlp": "4.0.1",
"@ethereumjs/tx": "5.2.1",
"@ethereumjs/util": "9.0.2",
Expand Down
24 changes: 24 additions & 0 deletions packages/shared/src/components/avatars/GovernanceAvatar.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts">
import { Avatar, IconName } from '@bloomwalletio/ui'
import { GovernanceAction } from '@core/activity'
import { darkMode } from '@core/app/stores'
export let governanceAction: GovernanceAction
export let size: 'xxs' | 'xs' | 'sm' | 'base' | 'md' | 'lg' = 'md'
const ICONS_FOR_ACTION = {
[GovernanceAction.StartVoting]: IconName.Package,
[GovernanceAction.StopVoting]: IconName.Package,
[GovernanceAction.ChangedVote]: IconName.PackageCheck,
[GovernanceAction.Revote]: IconName.PackageCheck,
[GovernanceAction.IncreaseVotingPower]: IconName.PackagePlus,
[GovernanceAction.DecreaseVotingPower]: IconName.PackageMinus,
}
</script>

<Avatar
icon={ICONS_FOR_ACTION[governanceAction]}
{size}
textColor="primary"
backgroundColor={$darkMode ? 'surface-2-dark' : 'surface-2'}
/>
1 change: 1 addition & 0 deletions packages/shared/src/components/avatars/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default as ContactAvatar } from './ContactAvatar.svelte'
export { default as GovernanceAvatar } from './GovernanceAvatar.svelte'
export { default as NftAvatar } from './NftAvatar.svelte'
export { default as NetworkAvatar } from './NetworkAvatar.svelte'
export { default as ProfileAvatar } from './ProfileAvatar.svelte'
Expand Down
84 changes: 84 additions & 0 deletions packages/shared/src/lib/auxiliary/blockscout/api/blockscout.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { NftStandard } from '@core/nfts/enums'
import { TokenStandard } from '@core/token/enums'
import { QueryParameters } from '@core/utils'
import { BaseApi } from '@core/utils/api'
import { DEFAULT_EXPLORER_URLS } from '@core/network/constants'
import { SupportedNetworkId } from '@core/network/enums'
import { IBlockscoutApi, IBlockscoutAsset, IBlockscoutAssetMetadata, IBlockscoutTransaction } from '../interfaces'
import { NetworkId } from '@core/network/types'

interface INextPageParams {
block_number: number
index: number
items_count: number
}

interface IPaginationResponse<T> {
items: T[]
next_page_params: INextPageParams | null
}

export class BlockscoutApi extends BaseApi implements IBlockscoutApi {
constructor(networkId: NetworkId) {
const explorerUrl = DEFAULT_EXPLORER_URLS[networkId as SupportedNetworkId]
super(`${explorerUrl}/api/v2`)
}

private async makePaginatedGetRequest<T>(
path: string,
queryParameters?: QueryParameters,
items: T[] = [],
nextPageParameters?: INextPageParams | null
): Promise<T[]> {
if (nextPageParameters === null) {
return Promise.resolve(items)
}
return this.get<IPaginationResponse<T>>(path, { ...queryParameters, ...nextPageParameters }).then(
(response) => {
if (!response) {
return Promise.resolve(items)
}
return this.makePaginatedGetRequest(
path,
queryParameters,
items.concat(response.items),
response.next_page_params
)
}
)
}

async getAssetMetadata(assetAddress: string): Promise<IBlockscoutAssetMetadata | undefined> {
const response = await this.get<IBlockscoutAssetMetadata>(`tokens/${assetAddress}`)
if (response) {
response.type = response.type.replace('-', '') as TokenStandard.Erc20 | NftStandard.Erc721
return response
}
}

async getAssetsForAddress(
address: string,
standard: TokenStandard.Erc20 | NftStandard.Erc721 = TokenStandard.Erc20
): Promise<IBlockscoutAsset[]> {
const tokenType = standard.replace('ERC', 'ERC-')
const path = `addresses/${address}/tokens`
const response = await this.get<IPaginationResponse<IBlockscoutAsset>>(path, { type: tokenType })
if (response) {
return (response?.items ?? []).map((asset) => ({
...asset,
token: {
...asset.token,
type: asset.token.type.replace('-', ''),
},
}))
} else {
return []
}
}

async getTransactionsForAddress(address: string): Promise<IBlockscoutTransaction[]> {
const path = `addresses/${address}/transactions`
const items = await this.makePaginatedGetRequest<IBlockscoutTransaction>(path)
return items
}
}
1 change: 1 addition & 0 deletions packages/shared/src/lib/auxiliary/blockscout/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './blockscout.api'
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { NftStandard } from '@core/nfts/enums'
import { TokenStandard } from '@core/token/enums'
import { IBlockscoutAsset } from './blockscout-asset.interface'
import { IBlockscoutAssetMetadata } from './blockscout-asset-metadata.interface'
import { IBlockscoutTransaction } from './blockscout-transaction.interface'

export interface IBlockscoutApi {
getAssetMetadata(assetAddress: string): Promise<IBlockscoutAssetMetadata | undefined>
getAssetsForAddress(
address: string,
tokenStandard?: TokenStandard.Erc20 | NftStandard.Erc721
): Promise<IBlockscoutAsset[]>
getTransactionsForAddress(address: string): Promise<IBlockscoutTransaction[]>
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// snake_case returned by the API
export interface IExplorerAssetMetadata {
export interface IBlockscoutAssetMetadata {
address: string
circulating_market_cap: string
decimals: number
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { IBlockscoutAssetMetadata } from './blockscout-asset-metadata.interface'

// snake_case returned by the API
export interface IBlockscoutAsset {
token: IBlockscoutAssetMetadata
token_id: string
token_instance: unknown
value: string
}
Loading

0 comments on commit 9cc1848

Please sign in to comment.