From ad2a252311ff8bf6bd9dcdbbbf46b5e0a06b807e Mon Sep 17 00:00:00 2001 From: herkoss Date: Mon, 17 Jul 2023 18:59:58 +0300 Subject: [PATCH 01/43] TW-786 Refactored transaction history for send, receive and delegate --- .../activity-group-amount-change.styles.ts | 12 +- .../activity-group-amount-change.tsx | 17 ++- ...ivity-group-dollar-amount-change.styles.ts | 3 +- .../activity-group-dollar-amount-change.tsx | 13 +- .../activity-group-item.styles.ts | 54 +++++--- .../activity-group-item.tsx | 118 ++++++++++++------ .../activity-group-type.styles.ts | 14 --- .../activity-group-type.tsx | 27 ---- .../use-activity-group-info.hook.ts | 80 ++++++++---- .../activity-groups-list.tsx | 82 ++++++------ src/interfaces/activity.interface.mock.ts | 19 +++ src/interfaces/activity.interface.ts | 2 + src/utils/operation.utils.ts | 6 + src/utils/transfer.utils.ts | 3 +- 14 files changed, 266 insertions(+), 184 deletions(-) delete mode 100644 src/components/activity-groups-list/activity-group-item/activity-group-type/activity-group-type.styles.ts delete mode 100644 src/components/activity-groups-list/activity-group-item/activity-group-type/activity-group-type.tsx diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.styles.ts b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.styles.ts index fd2d2819a..97f741f73 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.styles.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.styles.ts @@ -4,8 +4,16 @@ export const useActivityGroupAmountChangeStyles = createUseStyles(({ colors, typ container: { alignItems: 'flex-end' }, - amountText: { - ...typography.numbersRegular17, + amountWeight: { + fontWeight: '400' + }, + amountText15: { + ...typography.numbersRegular15 + }, + amountText13: { + ...typography.numbersRegular13 + }, + destructiveAmountText: { color: colors.destructive }, positiveAmountText: { diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx index 4961504f5..dfc3aaea2 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx @@ -6,17 +6,30 @@ import { conditionalStyle } from '../../../../utils/conditional-style'; import { formatAssetAmount } from '../../../../utils/number.util'; import { useActivityGroupAmountChangeStyles } from './activity-group-amount-change.styles'; +export enum TextSize { + Small = 'Small', + Regular = 'Regular' +} interface Props { + textSize?: TextSize; nonZeroAmounts: NonZeroAmounts; } -export const ActivityGroupAmountChange: FC = ({ nonZeroAmounts }) => { +export const ActivityGroupAmountChange: FC = ({ nonZeroAmounts, textSize = TextSize.Regular }) => { const styles = useActivityGroupAmountChangeStyles(); return ( {nonZeroAmounts.amounts.map(({ parsedAmount, isPositive, symbol }, index) => ( - + {isPositive && '+'} {formatAssetAmount(parsedAmount)} {symbol} diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.styles.ts b/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.styles.ts index 43ad312c7..6e49d2bc6 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.styles.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.styles.ts @@ -12,6 +12,7 @@ export const useActivityGroupDollarAmountChangeStyles = createUseStyles(({ color color: colors.destructive }, valueText: { - ...typography.numbersRegular11 + ...typography.numbersRegular11, + color: colors.gray1 } })); diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.tsx index 5791302a1..efef8e4ae 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.tsx @@ -2,7 +2,6 @@ import React, { FC } from 'react'; import { View } from 'react-native'; import { NonZeroAmounts } from '../../../../interfaces/non-zero-amounts.interface'; -import { conditionalStyle } from '../../../../utils/conditional-style'; import { FormattedAmount } from '../../../formatted-amount'; import { useActivityGroupDollarAmountChangeStyles } from './activity-group-dollar-amount-change.styles'; @@ -16,17 +15,7 @@ export const ActivityGroupDollarAmountChange: FC = ({ nonZeroAmounts }) = return ( {nonZeroAmounts.dollarSums.map((amount, index) => ( - + ))} ); diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts index f063a6efb..f04b5f6ac 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts @@ -1,31 +1,45 @@ -import { createUseStyles } from '../../../styles/create-use-styles'; -import { formatSize } from '../../../styles/format-size'; +import { createUseStyles } from 'src/styles/create-use-styles'; +import { formatSize } from 'src/styles/format-size'; -export const useActivityGroupItemStyles = createUseStyles(({ colors }) => ({ - container: { - borderBottomColor: colors.lines, - borderBottomWidth: formatSize(0.5), +export const useActivityGroupItemStyles = createUseStyles(({ colors, typography }) => ({ + root: { + paddingVertical: formatSize(16), paddingRight: formatSize(16) }, - upperContainer: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center' + card: { + marginTop: formatSize(12), + paddingHorizontal: formatSize(12), + borderRadius: formatSize(8), + backgroundColor: colors.cardBG }, - exploreContainer: { - flexDirection: 'row', - alignItems: 'center' + oprationTitle: { + ...typography.body15Regular, + color: colors.black + }, + oprationSubtitle: { + ...typography.numbersRegular11, + color: colors.gray1 }, - lowerContainer: { + detailItem: { flexDirection: 'row', justifyContent: 'space-between', - alignItems: 'flex-end' + alignItems: 'center', + paddingVertical: formatSize(12) }, - statusContainer: { - flexDirection: 'row', - alignItems: 'center' + detailText: { + color: colors.gray1 + }, + detailItemBorder: { + borderBottomWidth: formatSize(1), + borderBottomColor: colors.lines + }, + row: { + flexDirection: 'row' + }, + justifyBetween: { + justifyContent: 'space-between' }, - accountPkh: { - height: formatSize(24) + itemsStart: { + alignItems: 'flex-start' } })); diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx index 7530af19f..ede2fb39d 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx @@ -1,19 +1,25 @@ -import React, { FC } from 'react'; -import { View } from 'react-native'; +import { isEmpty } from 'lodash-es'; +import React, { FC, useState } from 'react'; +import { View, Text, TouchableOpacity } from 'react-native'; -import { useNetworkInfo } from '../../../hooks/use-network-info.hook'; -import { useNonZeroAmounts } from '../../../hooks/use-non-zero-amounts.hook'; -import { ActivityGroup, emptyActivity } from '../../../interfaces/activity.interface'; -import { useSelectedRpcUrlSelector } from '../../../store/settings/settings-selectors'; -import { formatSize } from '../../../styles/format-size'; -import { tzktUrl } from '../../../utils/linking.util'; -import { Divider } from '../../divider/divider'; -import { ExternalLinkButton } from '../../icon/external-link-button/external-link-button'; -import { PublicKeyHashText } from '../../public-key-hash-text/public-key-hash-text'; -import { ActivityGroupAmountChange } from './activity-group-amount-change/activity-group-amount-change'; +import { Divider } from 'src/components/divider/divider'; +import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; +import { Icon } from 'src/components/icon/icon'; +import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; +import { RobotIcon } from 'src/components/robot-icon/robot-icon'; +import { WalletAddress } from 'src/components/wallet-address/wallet-address'; +import { isAndroid } from 'src/config/system'; +import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; +import { ActivityGroup } from 'src/interfaces/activity.interface'; +import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { formatSize } from 'src/styles/format-size'; +import { tzktUrl } from 'src/utils/linking.util'; + +import { ActivityGroupAmountChange, TextSize } from './activity-group-amount-change/activity-group-amount-change'; import { ActivityGroupDollarAmountChange } from './activity-group-dollar-amount-change/activity-group-dollar-amount-change'; import { useActivityGroupItemStyles } from './activity-group-item.styles'; -import { ActivityGroupType } from './activity-group-type/activity-group-type'; +import { useActivityGroupInfo } from './activity-group-type/use-activity-group-info.hook'; import { ActivityStatusBadge } from './activity-status-badge/activity-status-badge'; import { ActivityTime } from './activity-time/activity-time'; import { ActivityGroupItemSelectors } from './selectors'; @@ -25,45 +31,75 @@ interface Props { export const ActivityGroupItem: FC = ({ group }) => { const styles = useActivityGroupItemStyles(); + const { + transactionType, + transactionSubtype, + transactionHash, + destination: [label, value, address] + } = useActivityGroupInfo(group); const nonZeroAmounts = useNonZeroAmounts(group); const selectedRpcUrl = useSelectedRpcUrlSelector(); - const { isTezosNode } = useNetworkInfo(); - const firstActivity = group[0] ?? emptyActivity; + const [areDetailsVisible, setAreDetailsVisible] = useState(false); return ( - - - - - - - - - + + + + + + + {transactionType} + + {label} {value} + + + + + + - - - - - - + + + + - + - - {isTezosNode && } + setAreDetailsVisible(prevState => !prevState)}> + + - + {areDetailsVisible && ( + + {!isEmpty(nonZeroAmounts.amounts) && ( + + {transactionSubtype} + + + + + + )} + + {label} + + + + TxHash: + + + + + + + + )} ); }; diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-type/activity-group-type.styles.ts b/src/components/activity-groups-list/activity-group-item/activity-group-type/activity-group-type.styles.ts deleted file mode 100644 index c073f5beb..000000000 --- a/src/components/activity-groups-list/activity-group-item/activity-group-type/activity-group-type.styles.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createUseStyles } from '../../../../styles/create-use-styles'; - -export const useActivityGroupTypeStyles = createUseStyles(({ colors, typography }) => ({ - container: { - flexDirection: 'row', - alignItems: 'center', - flexShrink: 1 - }, - text: { - ...typography.caption13Regular, - color: colors.black, - flexShrink: 1 - } -})); diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-type/activity-group-type.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-type/activity-group-type.tsx deleted file mode 100644 index 5730472aa..000000000 --- a/src/components/activity-groups-list/activity-group-item/activity-group-type/activity-group-type.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { FC } from 'react'; -import { Text, View } from 'react-native'; - -import { ActivityGroup } from '../../../../interfaces/activity.interface'; -import { formatSize } from '../../../../styles/format-size'; -import { Divider } from '../../../divider/divider'; -import { Icon } from '../../../icon/icon'; -import { useActivityGroupTypeStyles } from './activity-group-type.styles'; -import { useActivityGroupInfo } from './use-activity-group-info.hook'; - -interface Props { - group: ActivityGroup; -} - -export const ActivityGroupType: FC = ({ group }) => { - const styles = useActivityGroupTypeStyles(); - - const [iconName, iconColor, typeText] = useActivityGroupInfo(group); - - return ( - - - - {typeText} - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts b/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts index e5b39353b..65e20b0ee 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts @@ -1,47 +1,75 @@ import { useMemo } from 'react'; -import { ActivityTypeEnum } from '../../../../enums/activity-type.enum'; -import { ActivityGroup, emptyActivity } from '../../../../interfaces/activity.interface'; -import { useSelectedAccountSelector } from '../../../../store/wallet/wallet-selectors'; -import { useColors } from '../../../../styles/use-colors'; -import { isString } from '../../../../utils/is-string'; -import { IconNameEnum } from '../../../icon/icon-name.enum'; +import { ActivityTypeEnum } from 'src/enums/activity-type.enum'; +import { ActivityGroup, emptyActivity } from 'src/interfaces/activity.interface'; +import { useSelectedAccountSelector } from 'src/store/wallet/wallet-selectors'; +import { useColors } from 'src/styles/use-colors'; +import { truncateLongAddress } from 'src/utils/exolix.util'; +import { isString } from 'src/utils/is-string'; + +interface ReturnType { + transactionType: string; + transactionSubtype: string; + transactionHash: string; + destination: [string, string, string]; +} export const useActivityGroupInfo = (group: ActivityGroup) => { const colors = useColors(); - const publicKeyHash = useSelectedAccountSelector().publicKeyHash; + const { publicKeyHash } = useSelectedAccountSelector(); + + return useMemo(() => { + const firstActivity = group[0] ?? emptyActivity; - return useMemo<[IconNameEnum, string, string]>(() => { if (group.length > 1) { - return [IconNameEnum.Clipboard, colors.gray1, 'Interaction']; + return { + transactionType: 'Interaction', + transactionSubtype: 'Sent', + transactionHash: firstActivity.hash, + destination: ['To:', truncateLongAddress(firstActivity.destination.address), firstActivity.destination.address] + }; } - const firstActivity = group[0] ?? emptyActivity; - switch (firstActivity.type) { case ActivityTypeEnum.Transaction: if (firstActivity.source.address !== publicKeyHash) { - return [IconNameEnum.ArrowDown, colors.adding, firstActivity.source.alias ?? 'Received']; + return { + transactionType: firstActivity.source.alias ?? 'Receive', + transactionSubtype: 'Received', + transactionHash: firstActivity.hash, + destination: ['From:', truncateLongAddress(firstActivity.source.address), firstActivity.source.address] + }; } - return [ - IconNameEnum.ArrowUp, - colors.destructive, - isString(firstActivity.entrypoint) - ? `Called ${firstActivity.entrypoint}` - : firstActivity.destination.alias ?? 'Sent' - ]; + return { + transactionType: isString(firstActivity.entrypoint) ? `Called ${firstActivity.entrypoint}` : 'Send', + transactionSubtype: 'Sent', + transactionHash: firstActivity.hash, + destination: ['To:', truncateLongAddress(firstActivity.reciever.address), firstActivity.reciever.address] + }; + case ActivityTypeEnum.Delegation: const alias = firstActivity.destination.alias; - const postfix = isString(alias) ? ` to ${alias}` : ''; + const postfix = isString(alias) ? alias : truncateLongAddress(firstActivity.destination.address); + + return { + transactionType: isString(firstActivity.destination.address) ? 'Delegation' : 'Undelegation', + transactionSubtype: 'Sent', + transactionHash: firstActivity.hash, + destination: ['To:', postfix, firstActivity.destination.address] + }; - return [ - IconNameEnum.Deal, - colors.gray1, - isString(firstActivity.destination.address) ? 'Delegated' + postfix : 'Undelegated' - ]; default: - return [IconNameEnum.Clipboard, colors.gray1, 'Undelegated']; + return { + transactionType: 'Undelegation', + transactionSubtype: 'Sent', + transactionHash: firstActivity.hash, + destination: [ + 'Received:', + truncateLongAddress(firstActivity.reciever.address), + firstActivity.reciever.address + ] + }; } }, [group, publicKeyHash, colors]); }; diff --git a/src/components/activity-groups-list/activity-groups-list.tsx b/src/components/activity-groups-list/activity-groups-list.tsx index a773f0d5e..47df63288 100644 --- a/src/components/activity-groups-list/activity-groups-list.tsx +++ b/src/components/activity-groups-list/activity-groups-list.tsx @@ -54,49 +54,55 @@ export const ActivityGroupsList: FC = ({ return result; }, [activityGroups]); + console.log('sections: ', sections[0]?.title, JSON.stringify(sections[0]?.data[0], null, 2)); + const isShowPlaceholder = useMemo(() => activityGroups.length === 0, [activityGroups]); - return isShowPlaceholder ? ( + return ( <> - {shouldShowPromotion && ( - - + {shouldShowPromotion && ( + + + + )} + + + ) : ( + <> + item[0].hash} + renderItem={({ item, index, section }) => ( + <> + + {index === 0 && section.title === sections[0].title && shouldShowPromotion && ( + + + + )} + + )} + renderSectionHeader={({ section: { title } }) => {title}} + refreshControl={} /> - + )} - - - ) : ( - <> - item[0].hash} - renderItem={({ item, index, section }) => ( - <> - - {index === 0 && section.title === sections[0].title && shouldShowPromotion && ( - - - - )} - - )} - renderSectionHeader={({ section: { title } }) => {title}} - refreshControl={} - /> ); }; diff --git a/src/interfaces/activity.interface.mock.ts b/src/interfaces/activity.interface.mock.ts index 00daf7305..abd46235b 100644 --- a/src/interfaces/activity.interface.mock.ts +++ b/src/interfaces/activity.interface.mock.ts @@ -21,6 +21,10 @@ const mockAppliedOperation: ActivityInterface = { destination: { address: 'address1', alias: 'alias1' + }, + reciever: { + address: 'address1', + alias: 'alias1' } }; @@ -36,6 +40,10 @@ const mockPendingOperation: ActivityInterface = { destination: { address: 'address3', alias: 'alias3' + }, + reciever: { + address: 'address3', + alias: 'alias3' } }; @@ -50,6 +58,10 @@ const mockAppliedDelegationOperation: ActivityInterface = { destination: { address: 'address3', alias: 'alias3' + }, + reciever: { + address: 'address3', + alias: 'alias3' } }; @@ -102,6 +114,10 @@ export const mockActivitiesWithoutMatchedAddress: Array = [ address: 'address0', alias: 'alias0' }, + reciever: { + address: 'address0', + alias: 'alias0' + }, entrypoint: 'transfer', hash: 'hash', source: { @@ -120,6 +136,7 @@ export const mockActivitiesWithMatchedAddress: Array = [ { amount: '-1', destination: { address: 'address4', alias: 'alias4' }, + reciever: { address: 'address4', alias: 'alias4' }, entrypoint: 'transfer', hash: 'hash', id: 0, @@ -132,6 +149,7 @@ export const mockActivitiesWithMatchedAddress: Array = [ { amount: '-0', destination: { address: 'address7', alias: 'alias7' }, + reciever: { address: 'address7', alias: 'alias7' }, entrypoint: 'transfer', hash: 'hash', id: 1, @@ -144,6 +162,7 @@ export const mockActivitiesWithMatchedAddress: Array = [ { amount: '-contractBalance', destination: { address: 'address0', alias: 'alias0' }, + reciever: { address: 'address0', alias: 'alias0' }, entrypoint: 'transfer', hash: 'hash', id: 2, diff --git a/src/interfaces/activity.interface.ts b/src/interfaces/activity.interface.ts index 522d2287c..42534f16f 100644 --- a/src/interfaces/activity.interface.ts +++ b/src/interfaces/activity.interface.ts @@ -14,6 +14,7 @@ export interface ActivityInterface { entrypoint?: string; source: MemberInterface; destination: MemberInterface; + reciever: MemberInterface; level?: number; } @@ -27,5 +28,6 @@ export const emptyActivity: ActivityInterface = { id: 0, timestamp: 0, source: emptyMember, + reciever: emptyMember, destination: emptyMember }; diff --git a/src/utils/operation.utils.ts b/src/utils/operation.utils.ts index 0c8735b43..77a6221ac 100644 --- a/src/utils/operation.utils.ts +++ b/src/utils/operation.utils.ts @@ -34,6 +34,7 @@ export const mapOperationsToActivities = (address: string, operations: Array { @@ -78,6 +80,7 @@ export const mapOperationsToActivities = (address: string, operations: Array Date: Tue, 18 Jul 2023 14:29:56 +0300 Subject: [PATCH 02/43] TW-786 Fixed tests --- .../activity-group-item.tsx | 31 ++++++++------ .../use-activity-group-info.hook.ts | 40 +++++++++++++------ .../activity-group-item/selectors.ts | 3 +- .../activity-groups-list.tsx | 2 - src/interfaces/activity.interface.mock.ts | 31 ++++---------- src/interfaces/activity.interface.ts | 3 +- src/utils/transfer.utils.ts | 3 +- 7 files changed, 59 insertions(+), 54 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx index ede2fb39d..b9b97ebda 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx @@ -1,6 +1,6 @@ import { isEmpty } from 'lodash-es'; -import React, { FC, useState } from 'react'; -import { View, Text, TouchableOpacity } from 'react-native'; +import React, { FC, useCallback, useState } from 'react'; +import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; @@ -8,12 +8,14 @@ import { Icon } from 'src/components/icon/icon'; import { IconNameEnum } from 'src/components/icon/icon-name.enum'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; import { RobotIcon } from 'src/components/robot-icon/robot-icon'; +import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics'; import { WalletAddress } from 'src/components/wallet-address/wallet-address'; import { isAndroid } from 'src/config/system'; import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; -import { ActivityGroup } from 'src/interfaces/activity.interface'; +import { ActivityGroup, emptyActivity } from 'src/interfaces/activity.interface'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; +import { isDefined } from 'src/utils/is-defined'; import { tzktUrl } from 'src/utils/linking.util'; import { ActivityGroupAmountChange, TextSize } from './activity-group-amount-change/activity-group-amount-change'; @@ -35,13 +37,16 @@ export const ActivityGroupItem: FC = ({ group }) => { transactionType, transactionSubtype, transactionHash, - destination: [label, value, address] + destination: { label, value, address } } = useActivityGroupInfo(group); const nonZeroAmounts = useNonZeroAmounts(group); const selectedRpcUrl = useSelectedRpcUrlSelector(); const [areDetailsVisible, setAreDetailsVisible] = useState(false); + const handleOpenActivityDetailsPress = useCallback(() => setAreDetailsVisible(prevState => !prevState), []); + + const firstActivity = group[0] ?? emptyActivity; return ( @@ -64,13 +69,13 @@ export const ActivityGroupItem: FC = ({ group }) => { - + - + - setAreDetailsVisible(prevState => !prevState)}> + - + {areDetailsVisible && ( @@ -83,10 +88,12 @@ export const ActivityGroupItem: FC = ({ group }) => { )} - - {label} - - + {isDefined(address) && ( + + {label} + + + )} TxHash: diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts b/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts index 65e20b0ee..b83727eaa 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts @@ -7,18 +7,22 @@ import { useColors } from 'src/styles/use-colors'; import { truncateLongAddress } from 'src/utils/exolix.util'; import { isString } from 'src/utils/is-string'; -interface ReturnType { +interface ActivityInfo { transactionType: string; transactionSubtype: string; transactionHash: string; - destination: [string, string, string]; + destination: { + label: string; + value: string; + address: string | undefined; + }; } export const useActivityGroupInfo = (group: ActivityGroup) => { const colors = useColors(); const { publicKeyHash } = useSelectedAccountSelector(); - return useMemo(() => { + return useMemo(() => { const firstActivity = group[0] ?? emptyActivity; if (group.length > 1) { @@ -26,7 +30,11 @@ export const useActivityGroupInfo = (group: ActivityGroup) => { transactionType: 'Interaction', transactionSubtype: 'Sent', transactionHash: firstActivity.hash, - destination: ['To:', truncateLongAddress(firstActivity.destination.address), firstActivity.destination.address] + destination: { + label: 'To:', + value: truncateLongAddress(firstActivity.destination.address), + address: firstActivity.destination.address + } }; } @@ -37,7 +45,11 @@ export const useActivityGroupInfo = (group: ActivityGroup) => { transactionType: firstActivity.source.alias ?? 'Receive', transactionSubtype: 'Received', transactionHash: firstActivity.hash, - destination: ['From:', truncateLongAddress(firstActivity.source.address), firstActivity.source.address] + destination: { + label: 'From:', + value: truncateLongAddress(firstActivity.source.address), + address: firstActivity.source.address + } }; } @@ -45,7 +57,11 @@ export const useActivityGroupInfo = (group: ActivityGroup) => { transactionType: isString(firstActivity.entrypoint) ? `Called ${firstActivity.entrypoint}` : 'Send', transactionSubtype: 'Sent', transactionHash: firstActivity.hash, - destination: ['To:', truncateLongAddress(firstActivity.reciever.address), firstActivity.reciever.address] + destination: { + label: 'To:', + value: truncateLongAddress(firstActivity.reciever?.address ?? ''), + address: firstActivity.reciever?.address + } }; case ActivityTypeEnum.Delegation: @@ -56,7 +72,7 @@ export const useActivityGroupInfo = (group: ActivityGroup) => { transactionType: isString(firstActivity.destination.address) ? 'Delegation' : 'Undelegation', transactionSubtype: 'Sent', transactionHash: firstActivity.hash, - destination: ['To:', postfix, firstActivity.destination.address] + destination: { label: 'To:', value: postfix, address: firstActivity.destination.address } }; default: @@ -64,11 +80,11 @@ export const useActivityGroupInfo = (group: ActivityGroup) => { transactionType: 'Undelegation', transactionSubtype: 'Sent', transactionHash: firstActivity.hash, - destination: [ - 'Received:', - truncateLongAddress(firstActivity.reciever.address), - firstActivity.reciever.address - ] + destination: { + label: 'Received:', + value: truncateLongAddress(firstActivity.reciever?.address ?? ''), + address: firstActivity.reciever?.address + } }; } }, [group, publicKeyHash, colors]); diff --git a/src/components/activity-groups-list/activity-group-item/selectors.ts b/src/components/activity-groups-list/activity-group-item/selectors.ts index e67d7a031..8746ac279 100644 --- a/src/components/activity-groups-list/activity-group-item/selectors.ts +++ b/src/components/activity-groups-list/activity-group-item/selectors.ts @@ -1,4 +1,5 @@ export enum ActivityGroupItemSelectors { operationHash = 'Activity group item/Operation hash', - externalLink = 'Activity group item/External link' + externalLink = 'Activity group item/External link', + details = 'Activity group item/Details' } diff --git a/src/components/activity-groups-list/activity-groups-list.tsx b/src/components/activity-groups-list/activity-groups-list.tsx index 47df63288..b3cbeaca3 100644 --- a/src/components/activity-groups-list/activity-groups-list.tsx +++ b/src/components/activity-groups-list/activity-groups-list.tsx @@ -54,8 +54,6 @@ export const ActivityGroupsList: FC = ({ return result; }, [activityGroups]); - console.log('sections: ', sections[0]?.title, JSON.stringify(sections[0]?.data[0], null, 2)); - const isShowPlaceholder = useMemo(() => activityGroups.length === 0, [activityGroups]); return ( diff --git a/src/interfaces/activity.interface.mock.ts b/src/interfaces/activity.interface.mock.ts index abd46235b..097633da0 100644 --- a/src/interfaces/activity.interface.mock.ts +++ b/src/interfaces/activity.interface.mock.ts @@ -21,10 +21,6 @@ const mockAppliedOperation: ActivityInterface = { destination: { address: 'address1', alias: 'alias1' - }, - reciever: { - address: 'address1', - alias: 'alias1' } }; @@ -40,10 +36,6 @@ const mockPendingOperation: ActivityInterface = { destination: { address: 'address3', alias: 'alias3' - }, - reciever: { - address: 'address3', - alias: 'alias3' } }; @@ -58,10 +50,6 @@ const mockAppliedDelegationOperation: ActivityInterface = { destination: { address: 'address3', alias: 'alias3' - }, - reciever: { - address: 'address3', - alias: 'alias3' } }; @@ -114,10 +102,6 @@ export const mockActivitiesWithoutMatchedAddress: Array = [ address: 'address0', alias: 'alias0' }, - reciever: { - address: 'address0', - alias: 'alias0' - }, entrypoint: 'transfer', hash: 'hash', source: { @@ -128,7 +112,8 @@ export const mockActivitiesWithoutMatchedAddress: Array = [ level: undefined, status: ActivityStatusEnum.Applied, timestamp: 1628380800000, - type: ActivityTypeEnum.Origination + type: ActivityTypeEnum.Origination, + reciever: { address: '' } } ]; @@ -136,7 +121,6 @@ export const mockActivitiesWithMatchedAddress: Array = [ { amount: '-1', destination: { address: 'address4', alias: 'alias4' }, - reciever: { address: 'address4', alias: 'alias4' }, entrypoint: 'transfer', hash: 'hash', id: 0, @@ -144,12 +128,12 @@ export const mockActivitiesWithMatchedAddress: Array = [ source: { address: 'address1', alias: 'alias1' }, status: ActivityStatusEnum.Applied, timestamp: 1628380800000, - type: ActivityTypeEnum.Transaction + type: ActivityTypeEnum.Transaction, + reciever: { address: 'address4' } }, { amount: '-0', destination: { address: 'address7', alias: 'alias7' }, - reciever: { address: 'address7', alias: 'alias7' }, entrypoint: 'transfer', hash: 'hash', id: 1, @@ -157,12 +141,12 @@ export const mockActivitiesWithMatchedAddress: Array = [ source: { address: 'address1', alias: 'alias1' }, status: ActivityStatusEnum.Applied, timestamp: 1628380800000, - type: ActivityTypeEnum.Delegation + type: ActivityTypeEnum.Delegation, + reciever: { address: '' } }, { amount: '-contractBalance', destination: { address: 'address0', alias: 'alias0' }, - reciever: { address: 'address0', alias: 'alias0' }, entrypoint: 'transfer', hash: 'hash', id: 2, @@ -170,6 +154,7 @@ export const mockActivitiesWithMatchedAddress: Array = [ source: { address: 'address1', alias: 'alias1' }, status: ActivityStatusEnum.Applied, timestamp: 1628380800000, - type: ActivityTypeEnum.Origination + type: ActivityTypeEnum.Origination, + reciever: { address: '' } } ]; diff --git a/src/interfaces/activity.interface.ts b/src/interfaces/activity.interface.ts index 42534f16f..9608121d8 100644 --- a/src/interfaces/activity.interface.ts +++ b/src/interfaces/activity.interface.ts @@ -14,7 +14,7 @@ export interface ActivityInterface { entrypoint?: string; source: MemberInterface; destination: MemberInterface; - reciever: MemberInterface; + reciever?: MemberInterface; level?: number; } @@ -28,6 +28,5 @@ export const emptyActivity: ActivityInterface = { id: 0, timestamp: 0, source: emptyMember, - reciever: emptyMember, destination: emptyMember }; diff --git a/src/utils/transfer.utils.ts b/src/utils/transfer.utils.ts index 72c2e9496..a8f90e732 100644 --- a/src/utils/transfer.utils.ts +++ b/src/utils/transfer.utils.ts @@ -27,8 +27,7 @@ export const mapTransfersToActivities = (address: string, transfers: TransferInt id: token_id ?? 0, type: ActivityTypeEnum.Transaction, amount: source.address === address ? `-${amount}` : amount, - timestamp: new Date(timestamp).getTime(), - reciever: { address: '' } + timestamp: new Date(timestamp).getTime() }); } From f3f107064353efe0d8a81cafa5cf69eb2e08c5cf Mon Sep 17 00:00:00 2001 From: herkoss Date: Thu, 27 Jul 2023 13:39:02 +0300 Subject: [PATCH 03/43] TW-786 Fixed qa issues --- ios/TempleWallet.xcodeproj/project.pbxproj | 15 +- .../activity-group-details.tsx | 129 ++++++++++++++++++ .../activity-group-item.styles.ts | 21 ++- .../activity-group-item.tsx | 91 +++--------- .../use-activity-group-info.hook.ts | 12 +- src/components/robot-icon/robot-icon.tsx | 7 +- src/hooks/use-non-zero-amounts.hook.ts | 25 +++- src/store/wallet/wallet-selectors.ts | 5 + 8 files changed, 214 insertions(+), 91 deletions(-) create mode 100644 src/components/activity-groups-list/activity-group-item/activity-group-details.tsx diff --git a/ios/TempleWallet.xcodeproj/project.pbxproj b/ios/TempleWallet.xcodeproj/project.pbxproj index 9e593d539..721ed9fa7 100644 --- a/ios/TempleWallet.xcodeproj/project.pbxproj +++ b/ios/TempleWallet.xcodeproj/project.pbxproj @@ -542,11 +542,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = TempleWallet/TempleWallet.entitlements; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 319; DEVELOPMENT_TEAM = D653UWS37K; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = D653UWS37K; ENABLE_BITCODE = NO; INFOPLIST_FILE = "TempleWallet/Debug-Info.plist"; LD_RUNPATH_SEARCH_PATHS = ( @@ -560,8 +559,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = "com.madfish.temple-wallet"; PRODUCT_NAME = TempleWallet; - PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.madfish.temple-wallet"; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.madfish.temple-wallet"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -577,11 +575,9 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = TempleWallet/TempleWallet.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 319; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = D653UWS37K; + DEVELOPMENT_TEAM = D653UWS37K; INFOPLIST_FILE = TempleWallet/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -595,7 +591,6 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.madfish.temple-wallet"; PRODUCT_NAME = TempleWallet; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.madfish.temple-wallet"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx new file mode 100644 index 000000000..d912f82a0 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx @@ -0,0 +1,129 @@ +import { isEmpty } from 'lodash-es'; +import React, { FC, useState, useCallback, useMemo } from 'react'; +import { View, Text } from 'react-native'; + +import { CollectibleIcon } from 'src/components/collectible-icon/collectible-icon'; +import { Divider } from 'src/components/divider/divider'; +import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; +import { Icon } from 'src/components/icon/icon'; +import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; +import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics'; +import { WalletAddress } from 'src/components/wallet-address/wallet-address'; +import { ActivityNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; +import { ActivityInterface } from 'src/interfaces/activity.interface'; +import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { useCollectibleBySlugSelector } from 'src/store/wallet/wallet-selectors'; +import { formatSize } from 'src/styles/format-size'; +import { isDefined } from 'src/utils/is-defined'; +import { tzktUrl } from 'src/utils/linking.util'; + +import { ActivityGroupAmountChange, TextSize } from './activity-group-amount-change/activity-group-amount-change'; +import { ActivityGroupDollarAmountChange } from './activity-group-dollar-amount-change/activity-group-dollar-amount-change'; +import { useActivityGroupItemStyles } from './activity-group-item.styles'; +import { BAKING_REWARDS_TEXT } from './activity-group-type/use-activity-group-info.hook'; +import { ActivityStatusBadge } from './activity-status-badge/activity-status-badge'; +import { ActivityTime } from './activity-time/activity-time'; +import { ActivityGroupItemSelectors } from './selectors'; + +interface ActivityDetailsProps { + activity: ActivityInterface; + nonZeroAmounts: ActivityNonZeroAmounts; + label: string; + address: string | undefined; + transactionHash: string; + transactionType: string; + transactionSubtype: string; +} + +export const ActivityDetails: FC = ({ + activity, + nonZeroAmounts, + label, + address, + transactionHash, + transactionType, + transactionSubtype +}) => { + const styles = useActivityGroupItemStyles(); + const selectedRpcUrl = useSelectedRpcUrlSelector(); + + const [areDetailsVisible, setAreDetailsVisible] = useState(false); + const handleOpenActivityDetailsPress = useCallback(() => setAreDetailsVisible(prevState => !prevState), []); + + const collectible = useCollectibleBySlugSelector(`${activity.address}_${activity.tokenId ?? 0}`); + const isCollectible = useMemo(() => isDefined(collectible), [collectible]); + + return ( + + + + + + + + + + + + {areDetailsVisible && ( + + {!isEmpty(nonZeroAmounts.amounts) && ( + + {transactionSubtype} + + + + {isCollectible ? ( + 0.00$ + ) : ( + + )} + + + {isDefined(collectible) && ( + <> + + + + )} + + + )} + {isDefined(address) && ( + + {label} + + + {transactionType === BAKING_REWARDS_TEXT && ( + <> + + + + )} + + + )} + + TxHash: + + + + + + + + )} + + ); +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts index f04b5f6ac..21c582133 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts @@ -6,6 +6,9 @@ export const useActivityGroupItemStyles = createUseStyles(({ colors, typography paddingVertical: formatSize(16), paddingRight: formatSize(16) }, + flex: { + flex: 1 + }, card: { marginTop: formatSize(12), paddingHorizontal: formatSize(12), @@ -13,7 +16,7 @@ export const useActivityGroupItemStyles = createUseStyles(({ colors, typography backgroundColor: colors.cardBG }, oprationTitle: { - ...typography.body15Regular, + ...typography.numbersRegular15, color: colors.black }, oprationSubtitle: { @@ -23,14 +26,13 @@ export const useActivityGroupItemStyles = createUseStyles(({ colors, typography detailItem: { flexDirection: 'row', justifyContent: 'space-between', - alignItems: 'center', paddingVertical: formatSize(12) }, detailText: { color: colors.gray1 }, detailItemBorder: { - borderBottomWidth: formatSize(1), + borderBottomWidth: formatSize(0.5), borderBottomColor: colors.lines }, row: { @@ -41,5 +43,18 @@ export const useActivityGroupItemStyles = createUseStyles(({ colors, typography }, itemsStart: { alignItems: 'flex-start' + }, + itemsEnd: { + alignItems: 'flex-end' + }, + itemsCenter: { + alignItems: 'center' + }, + robotBackground: { + backgroundColor: colors.navigation + }, + ntfPrice: { + ...typography.numbersRegular11, + color: colors.gray1 } })); diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx index b9b97ebda..d54dc2eec 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx @@ -1,30 +1,17 @@ -import { isEmpty } from 'lodash-es'; -import React, { FC, useCallback, useState } from 'react'; +import React, { FC } from 'react'; import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; -import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; -import { Icon } from 'src/components/icon/icon'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; -import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; import { RobotIcon } from 'src/components/robot-icon/robot-icon'; -import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics'; -import { WalletAddress } from 'src/components/wallet-address/wallet-address'; -import { isAndroid } from 'src/config/system'; import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; import { ActivityGroup, emptyActivity } from 'src/interfaces/activity.interface'; -import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; -import { isDefined } from 'src/utils/is-defined'; -import { tzktUrl } from 'src/utils/linking.util'; -import { ActivityGroupAmountChange, TextSize } from './activity-group-amount-change/activity-group-amount-change'; +import { ActivityGroupAmountChange } from './activity-group-amount-change/activity-group-amount-change'; +import { ActivityDetails } from './activity-group-details'; import { ActivityGroupDollarAmountChange } from './activity-group-dollar-amount-change/activity-group-dollar-amount-change'; import { useActivityGroupItemStyles } from './activity-group-item.styles'; import { useActivityGroupInfo } from './activity-group-type/use-activity-group-info.hook'; -import { ActivityStatusBadge } from './activity-status-badge/activity-status-badge'; -import { ActivityTime } from './activity-time/activity-time'; -import { ActivityGroupItemSelectors } from './selectors'; interface Props { group: ActivityGroup; @@ -41,72 +28,36 @@ export const ActivityGroupItem: FC = ({ group }) => { } = useActivityGroupInfo(group); const nonZeroAmounts = useNonZeroAmounts(group); - const selectedRpcUrl = useSelectedRpcUrlSelector(); - - const [areDetailsVisible, setAreDetailsVisible] = useState(false); - const handleOpenActivityDetailsPress = useCallback(() => setAreDetailsVisible(prevState => !prevState), []); - const firstActivity = group[0] ?? emptyActivity; return ( - - - - - + + + + + {transactionType} + + + {label} {value} + - - - - - - - - - - - - - - - {areDetailsVisible && ( - - {!isEmpty(nonZeroAmounts.amounts) && ( - - {transactionSubtype} - - - - - - )} - {isDefined(address) && ( - - {label} - - - )} - - TxHash: - - - - - - - - )} + ); }; diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts b/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts index b83727eaa..c910cb7bf 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts @@ -18,6 +18,16 @@ interface ActivityInfo { }; } +export const BAKING_REWARDS_TEXT = 'Baking rewards'; + +const getReceiveTransactionType = (alias: string | undefined): string => { + if (Boolean(alias?.toLowerCase().includes('payouts'))) { + return BAKING_REWARDS_TEXT; + } + + return 'Receive'; +}; + export const useActivityGroupInfo = (group: ActivityGroup) => { const colors = useColors(); const { publicKeyHash } = useSelectedAccountSelector(); @@ -42,7 +52,7 @@ export const useActivityGroupInfo = (group: ActivityGroup) => { case ActivityTypeEnum.Transaction: if (firstActivity.source.address !== publicKeyHash) { return { - transactionType: firstActivity.source.alias ?? 'Receive', + transactionType: getReceiveTransactionType(firstActivity.source.alias), transactionSubtype: 'Received', transactionHash: firstActivity.hash, destination: { diff --git a/src/components/robot-icon/robot-icon.tsx b/src/components/robot-icon/robot-icon.tsx index 78dc94f1d..029e23788 100644 --- a/src/components/robot-icon/robot-icon.tsx +++ b/src/components/robot-icon/robot-icon.tsx @@ -1,7 +1,7 @@ import { createAvatar } from '@dicebear/avatars'; import * as botttsSprites from '@dicebear/avatars-bottts-sprites'; import React, { FC, useMemo } from 'react'; -import { View } from 'react-native'; +import { StyleProp, View, ViewStyle } from 'react-native'; import { SvgXml } from 'react-native-svg'; import { formatSize } from '../../styles/format-size'; @@ -10,9 +10,10 @@ import { useRobotIconStyles } from './robot-icon.styles'; interface Props { seed: string; size?: number; + style?: StyleProp; } -export const RobotIcon: FC = ({ seed, size = formatSize(44) }) => { +export const RobotIcon: FC = ({ seed, size = formatSize(44), style }) => { const styles = useRobotIconStyles(); const xml = useMemo( @@ -27,7 +28,7 @@ export const RobotIcon: FC = ({ seed, size = formatSize(44) }) => { ); return ( - + ); diff --git a/src/hooks/use-non-zero-amounts.hook.ts b/src/hooks/use-non-zero-amounts.hook.ts index febf80ef7..bc57b9604 100644 --- a/src/hooks/use-non-zero-amounts.hook.ts +++ b/src/hooks/use-non-zero-amounts.hook.ts @@ -2,6 +2,8 @@ import { BigNumber } from 'bignumber.js'; import { useMemo } from 'react'; import { useDispatch } from 'react-redux'; +import { useFiatToUsdRateSelector } from 'src/store/settings/settings-selectors'; + import { ActivityGroup } from '../interfaces/activity.interface'; import { useUsdToTokenRates } from '../store/currency/currency-selectors'; import { loadTokenMetadataActions } from '../store/tokens-metadata/tokens-metadata-actions'; @@ -11,10 +13,25 @@ import { isString } from '../utils/is-string'; import { mutezToTz } from '../utils/tezos.util'; import { useTokenMetadataGetter } from './use-token-metadata-getter.hook'; -export const useNonZeroAmounts = (group: ActivityGroup) => { +interface ActivityAmount { + symbol: string; + isPositive: boolean; + exchangeRate: number; + parsedAmount: BigNumber; +} + +export interface ActivityNonZeroAmounts { + amounts: Array; + dollarSums: Array; +} + +const DEFAULT_EXCHANGE_RATE = 1; + +export const useNonZeroAmounts = (group: ActivityGroup): ActivityNonZeroAmounts => { const dispatch = useDispatch(); const getTokenMetadata = useTokenMetadataGetter(); const exchangeRates = useUsdToTokenRates(); + const fiatToUsdRate = useFiatToUsdRateSelector(); return useMemo(() => { const amounts = []; @@ -23,7 +40,7 @@ export const useNonZeroAmounts = (group: ActivityGroup) => { for (const { address, tokenId, amount } of group) { const slug = getTokenSlug({ address, id: tokenId }); - const { decimals, symbol, name } = getTokenMetadata(slug); + const { decimals, symbol, name, artifactUri } = getTokenMetadata(slug); const exchangeRate: number | undefined = exchangeRates[slug]; if (isString(address) && !isString(name)) { dispatch(loadTokenMetadataActions.submit({ address, id: Number(tokenId ?? '0') })); @@ -33,7 +50,7 @@ export const useNonZeroAmounts = (group: ActivityGroup) => { const isPositive = parsedAmount.isPositive(); if (isDefined(exchangeRate)) { - const summand = parsedAmount.multipliedBy(exchangeRate); + const summand = parsedAmount.multipliedBy(exchangeRate).multipliedBy(fiatToUsdRate ?? DEFAULT_EXCHANGE_RATE); if (isPositive) { positiveAmountSum = positiveAmountSum.plus(summand); } else { @@ -45,7 +62,7 @@ export const useNonZeroAmounts = (group: ActivityGroup) => { amounts.push({ parsedAmount, isPositive, - symbol, + symbol: isDefined(artifactUri) ? name : symbol, exchangeRate }); } diff --git a/src/store/wallet/wallet-selectors.ts b/src/store/wallet/wallet-selectors.ts index 6c4768701..bb38039f8 100644 --- a/src/store/wallet/wallet-selectors.ts +++ b/src/store/wallet/wallet-selectors.ts @@ -107,6 +107,11 @@ export const useCollectiblesListSelector = () => { return useMemo(() => assetsList.filter(asset => isCollectible(asset) && isNonZeroBalance(asset)), [assetsList]); }; +export const useCollectibleBySlugSelector = (slug: string): TokenInterface | undefined => { + const assetsList = useAssetsListSelector(); + + return useMemo(() => assetsList.find(asset => isCollectible(asset) && getTokenSlug(asset) === slug), [assetsList]); +}; export const useVisibleCollectiblesListSelector = () => { const collectiblesList = useCollectiblesListSelector(); From 800d7f2d36c274848c2c819243d7e23fcf80894a Mon Sep 17 00:00:00 2001 From: herkoss Date: Thu, 27 Jul 2023 13:53:42 +0300 Subject: [PATCH 04/43] TW-786 Fixed ios/TempleWallet.xcodeproj/project.pbxproj --- ios/TempleWallet.xcodeproj/project.pbxproj | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ios/TempleWallet.xcodeproj/project.pbxproj b/ios/TempleWallet.xcodeproj/project.pbxproj index 721ed9fa7..9e593d539 100644 --- a/ios/TempleWallet.xcodeproj/project.pbxproj +++ b/ios/TempleWallet.xcodeproj/project.pbxproj @@ -542,10 +542,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = TempleWallet/TempleWallet.entitlements; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 319; DEVELOPMENT_TEAM = D653UWS37K; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = D653UWS37K; ENABLE_BITCODE = NO; INFOPLIST_FILE = "TempleWallet/Debug-Info.plist"; LD_RUNPATH_SEARCH_PATHS = ( @@ -559,7 +560,8 @@ ); PRODUCT_BUNDLE_IDENTIFIER = "com.madfish.temple-wallet"; PRODUCT_NAME = TempleWallet; - PROVISIONING_PROFILE_SPECIFIER = ""; + PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.madfish.temple-wallet"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.madfish.temple-wallet"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -575,9 +577,11 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = TempleWallet/TempleWallet.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 319; - DEVELOPMENT_TEAM = D653UWS37K; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = D653UWS37K; INFOPLIST_FILE = TempleWallet/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -591,6 +595,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.madfish.temple-wallet"; PRODUCT_NAME = TempleWallet; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.madfish.temple-wallet"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; From bcc2e75e5b60aa61e321d1ecd8daa19c7005cd7a Mon Sep 17 00:00:00 2001 From: herkoss Date: Thu, 27 Jul 2023 14:13:53 +0300 Subject: [PATCH 05/43] TW-786 Fixed selected fiat currency symbol --- .../activity-group-item/activity-group-details.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx index d912f82a0..7e59ede3c 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx @@ -12,7 +12,10 @@ import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics' import { WalletAddress } from 'src/components/wallet-address/wallet-address'; import { ActivityNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; import { ActivityInterface } from 'src/interfaces/activity.interface'; -import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { + useCurrentFiatCurrencyMetadataSelector, + useSelectedRpcUrlSelector +} from 'src/store/settings/settings-selectors'; import { useCollectibleBySlugSelector } from 'src/store/wallet/wallet-selectors'; import { formatSize } from 'src/styles/format-size'; import { isDefined } from 'src/utils/is-defined'; @@ -47,6 +50,7 @@ export const ActivityDetails: FC = ({ }) => { const styles = useActivityGroupItemStyles(); const selectedRpcUrl = useSelectedRpcUrlSelector(); + const { symbol } = useCurrentFiatCurrencyMetadataSelector(); const [areDetailsVisible, setAreDetailsVisible] = useState(false); const handleOpenActivityDetailsPress = useCallback(() => setAreDetailsVisible(prevState => !prevState), []); @@ -75,7 +79,7 @@ export const ActivityDetails: FC = ({ {isCollectible ? ( - 0.00$ + 0.00{symbol} ) : ( )} From f58b5547eb571eb9a356c521c4bf49131efe848f Mon Sep 17 00:00:00 2001 From: herkoss Date: Mon, 31 Jul 2023 20:08:55 +0300 Subject: [PATCH 06/43] TW-786 Fixed QA issues --- .../activity-group-details.tsx | 39 ++++++++++++++++-- .../activity-group-item.styles.ts | 3 ++ .../activity-group-item.tsx | 11 ++++- .../use-activity-group-info.hook.ts | 41 +++++++++++++------ 4 files changed, 76 insertions(+), 18 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx index 7e59ede3c..295c122af 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx @@ -24,7 +24,11 @@ import { tzktUrl } from 'src/utils/linking.util'; import { ActivityGroupAmountChange, TextSize } from './activity-group-amount-change/activity-group-amount-change'; import { ActivityGroupDollarAmountChange } from './activity-group-dollar-amount-change/activity-group-dollar-amount-change'; import { useActivityGroupItemStyles } from './activity-group-item.styles'; -import { BAKING_REWARDS_TEXT } from './activity-group-type/use-activity-group-info.hook'; +import { + BAKING_REWARDS_TEXT, + DELEGATION_TEXT, + UNDELEGATION_TEXT +} from './activity-group-type/use-activity-group-info.hook'; import { ActivityStatusBadge } from './activity-status-badge/activity-status-badge'; import { ActivityTime } from './activity-time/activity-time'; import { ActivityGroupItemSelectors } from './selectors'; @@ -57,6 +61,29 @@ export const ActivityDetails: FC = ({ const collectible = useCollectibleBySlugSelector(`${activity.address}_${activity.tokenId ?? 0}`); const isCollectible = useMemo(() => isDefined(collectible), [collectible]); + const { shouldShowTzktLink, bakerAddress } = useMemo(() => { + if (transactionType === BAKING_REWARDS_TEXT) { + return { + shouldShowTzktLink: true, + bakerAddress: activity.source.address + }; + } else if (transactionType === DELEGATION_TEXT) { + return { + shouldShowTzktLink: true, + bakerAddress: activity.destination.address + }; + } else if (transactionType === UNDELEGATION_TEXT) { + return { + shouldShowTzktLink: true, + bakerAddress: activity.destination.address + }; + } + + return { + shouldShowTzktLink: false, + bakerAddress: '' + }; + }, [transactionType]); return ( @@ -66,7 +93,11 @@ export const ActivityDetails: FC = ({ - + @@ -99,11 +130,11 @@ export const ActivityDetails: FC = ({ {label} - {transactionType === BAKING_REWARDS_TEXT && ( + {shouldShowTzktLink && ( <> diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts index 21c582133..e34124dbb 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts @@ -56,5 +56,8 @@ export const useActivityGroupItemStyles = createUseStyles(({ colors, typography ntfPrice: { ...typography.numbersRegular11, color: colors.gray1 + }, + chevron: { + padding: formatSize(4) } })); diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx index d54dc2eec..3248c718a 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx @@ -1,11 +1,13 @@ import React, { FC } from 'react'; import { View, Text } from 'react-native'; +import { AvatarImage } from 'src/components/avatar-image/avatar-image'; import { Divider } from 'src/components/divider/divider'; import { RobotIcon } from 'src/components/robot-icon/robot-icon'; import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; import { ActivityGroup, emptyActivity } from 'src/interfaces/activity.interface'; import { formatSize } from 'src/styles/format-size'; +import { isDefined } from 'src/utils/is-defined'; import { ActivityGroupAmountChange } from './activity-group-amount-change/activity-group-amount-change'; import { ActivityDetails } from './activity-group-details'; @@ -21,10 +23,11 @@ export const ActivityGroupItem: FC = ({ group }) => { const styles = useActivityGroupItemStyles(); const { + seed, transactionType, transactionSubtype, transactionHash, - destination: { label, value, address } + destination: { label, value, address, bakerLogo } } = useActivityGroupInfo(group); const nonZeroAmounts = useNonZeroAmounts(group); @@ -33,7 +36,11 @@ export const ActivityGroupItem: FC = ({ group }) => { return ( - + {isDefined(bakerLogo) ? ( + + ) : ( + + )} diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts b/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts index c910cb7bf..8e2efd00c 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts @@ -2,6 +2,7 @@ import { useMemo } from 'react'; import { ActivityTypeEnum } from 'src/enums/activity-type.enum'; import { ActivityGroup, emptyActivity } from 'src/interfaces/activity.interface'; +import { useBakersListSelector } from 'src/store/baking/baking-selectors'; import { useSelectedAccountSelector } from 'src/store/wallet/wallet-selectors'; import { useColors } from 'src/styles/use-colors'; import { truncateLongAddress } from 'src/utils/exolix.util'; @@ -11,14 +12,18 @@ interface ActivityInfo { transactionType: string; transactionSubtype: string; transactionHash: string; + seed: string; destination: { label: string; value: string; address: string | undefined; + bakerLogo?: string; }; } export const BAKING_REWARDS_TEXT = 'Baking rewards'; +export const DELEGATION_TEXT = 'Delegation'; +export const UNDELEGATION_TEXT = 'Undelegation'; const getReceiveTransactionType = (alias: string | undefined): string => { if (Boolean(alias?.toLowerCase().includes('payouts'))) { @@ -30,6 +35,7 @@ const getReceiveTransactionType = (alias: string | undefined): string => { export const useActivityGroupInfo = (group: ActivityGroup) => { const colors = useColors(); + const bakers = useBakersListSelector(); const { publicKeyHash } = useSelectedAccountSelector(); return useMemo(() => { @@ -38,13 +44,14 @@ export const useActivityGroupInfo = (group: ActivityGroup) => { if (group.length > 1) { return { transactionType: 'Interaction', - transactionSubtype: 'Sent', + transactionSubtype: 'Sent:', transactionHash: firstActivity.hash, destination: { label: 'To:', value: truncateLongAddress(firstActivity.destination.address), address: firstActivity.destination.address - } + }, + seed: firstActivity.destination.address }; } @@ -53,25 +60,27 @@ export const useActivityGroupInfo = (group: ActivityGroup) => { if (firstActivity.source.address !== publicKeyHash) { return { transactionType: getReceiveTransactionType(firstActivity.source.alias), - transactionSubtype: 'Received', + transactionSubtype: 'Received:', transactionHash: firstActivity.hash, destination: { label: 'From:', value: truncateLongAddress(firstActivity.source.address), address: firstActivity.source.address - } + }, + seed: firstActivity.source.address }; } return { transactionType: isString(firstActivity.entrypoint) ? `Called ${firstActivity.entrypoint}` : 'Send', - transactionSubtype: 'Sent', + transactionSubtype: 'Sent:', transactionHash: firstActivity.hash, destination: { label: 'To:', value: truncateLongAddress(firstActivity.reciever?.address ?? ''), address: firstActivity.reciever?.address - } + }, + seed: firstActivity.reciever?.address ?? '' }; case ActivityTypeEnum.Delegation: @@ -79,22 +88,30 @@ export const useActivityGroupInfo = (group: ActivityGroup) => { const postfix = isString(alias) ? alias : truncateLongAddress(firstActivity.destination.address); return { - transactionType: isString(firstActivity.destination.address) ? 'Delegation' : 'Undelegation', - transactionSubtype: 'Sent', + transactionType: isString(firstActivity.destination.address) ? DELEGATION_TEXT : UNDELEGATION_TEXT, + transactionSubtype: 'Sent:', transactionHash: firstActivity.hash, - destination: { label: 'To:', value: postfix, address: firstActivity.destination.address } + destination: { + label: 'To:', + value: postfix, + address: firstActivity.destination.address, + bakerLogo: bakers.find(baker => baker.address === firstActivity.destination.address)?.logo + }, + seed: firstActivity.destination.address }; default: return { transactionType: 'Undelegation', - transactionSubtype: 'Sent', + transactionSubtype: 'Sent:', transactionHash: firstActivity.hash, destination: { label: 'Received:', value: truncateLongAddress(firstActivity.reciever?.address ?? ''), - address: firstActivity.reciever?.address - } + address: firstActivity.reciever?.address, + bakerLogo: bakers.find(baker => baker.address === firstActivity.destination.address)?.logo + }, + seed: firstActivity.reciever?.address ?? '' }; } }, [group, publicKeyHash, colors]); From 64295fdb83a9bc250a97a7802ec75d9e5c04f857 Mon Sep 17 00:00:00 2001 From: herkoss Date: Wed, 2 Aug 2023 16:08:27 +0300 Subject: [PATCH 07/43] TW-786 Added parser --- package.json | 3 ++- .../activity-group-item/activity-group-item.tsx | 14 ++++++++++++++ yarn.lock | 17 ++++++++++++----- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 478d869de..d46104905 100644 --- a/package.json +++ b/package.json @@ -55,9 +55,10 @@ "@taquito/tzip12": "17.0.0", "@taquito/tzip16": "17.0.0", "@taquito/utils": "17.0.0", + "@temple-wallet/transactions-parser": "^1.0.0", + "@temple-wallet/wallet-address-validator": "^0.4.2", "@tezos-domains/core": "1.26.0", "@tezos-domains/taquito-client": "1.26.0", - "@temple-wallet/wallet-address-validator": "^0.4.2", "@tradle/react-native-http": "^2.0.1", "asyncstorage-down": "^4.2.0", "axios": "^0.27.2", diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx index 3248c718a..ae1650d76 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx @@ -19,6 +19,20 @@ interface Props { group: ActivityGroup; } +interface GroupItem { + title: string; + subtitle: string; + sender: string; + receiver: string; + transactionHash: string; + status: string; + timestamp: string; + amounts: { + amountInTokens: Array; + amountInDollars: number; + }; +} + export const ActivityGroupItem: FC = ({ group }) => { const styles = useActivityGroupItemStyles(); diff --git a/yarn.lock b/yarn.lock index 2df0f51fa..43d6327ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3928,6 +3928,13 @@ elliptic "^6.5.4" typedarray-to-buffer "^4.0.0" +"@temple-wallet/transactions-parser@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@temple-wallet/transactions-parser/-/transactions-parser-1.0.0.tgz#2a78b25a9c5ff6b54c83ae0ed621260c5f28c062" + integrity sha512-Bwa3xB33zVaOd2xB5nRET1L2O9qElO6r3hkXNJmIVPD3skFkYlsU2yOegEn5/6ZsH0eZGQA1PMb3LMq3BWheDw== + dependencies: + bignumber.js "^9.1.0" + "@temple-wallet/wallet-address-validator@^0.4.2": version "0.4.2" resolved "https://registry.yarnpkg.com/@temple-wallet/wallet-address-validator/-/wallet-address-validator-0.4.2.tgz#1334a67aa71d0c397dd7c20a94245a612fd7feff" @@ -8000,6 +8007,11 @@ csstype@^3.0.2: resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz" integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== +csstype@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== + currency-codes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/currency-codes/-/currency-codes-2.1.0.tgz#6d84a1b7fec70ecb9ef64e57bf60f4271899044c" @@ -8008,11 +8020,6 @@ currency-codes@^2.1.0: first-match "~0.0.1" nub "~0.0.0" -csstype@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" - integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== - cycle@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz" From dd69343534b53e193c5eea61ab13b650f20126c6 Mon Sep 17 00:00:00 2001 From: herkoss Date: Thu, 3 Aug 2023 21:19:51 +0300 Subject: [PATCH 08/43] TW-786 Used Parser --- .../activity-group-details.tsx | 255 ++++++++++-------- .../activity-group-item.styles.ts | 40 ++- .../activity-group-item.tsx | 175 ++++++++---- .../activity-status-badge.tsx | 7 +- .../activity-time/activity-time.tsx | 2 +- .../activity-groups-list.tsx | 4 +- src/hooks/use-contract-activity.ts | 36 ++- src/hooks/use-non-zero-amounts.hook.ts | 2 +- src/interfaces/activity.interface.ts | 4 +- src/screens/activity/activity.tsx | 1 + src/utils/token-operations.util.ts | 39 ++- 11 files changed, 350 insertions(+), 215 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx index 295c122af..6eb8a77dc 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx @@ -1,8 +1,8 @@ -import { isEmpty } from 'lodash-es'; -import React, { FC, useState, useCallback, useMemo } from 'react'; +import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; +import { BigNumber } from 'bignumber.js'; +import React, { FC, useState, useCallback } from 'react'; import { View, Text } from 'react-native'; -import { CollectibleIcon } from 'src/components/collectible-icon/collectible-icon'; import { Divider } from 'src/components/divider/divider'; import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; import { Icon } from 'src/components/icon/icon'; @@ -10,91 +10,138 @@ import { IconNameEnum } from 'src/components/icon/icon-name.enum'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics'; import { WalletAddress } from 'src/components/wallet-address/wallet-address'; -import { ActivityNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; -import { ActivityInterface } from 'src/interfaces/activity.interface'; -import { - useCurrentFiatCurrencyMetadataSelector, - useSelectedRpcUrlSelector -} from 'src/store/settings/settings-selectors'; -import { useCollectibleBySlugSelector } from 'src/store/wallet/wallet-selectors'; +import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; -import { isDefined } from 'src/utils/is-defined'; import { tzktUrl } from 'src/utils/linking.util'; import { ActivityGroupAmountChange, TextSize } from './activity-group-amount-change/activity-group-amount-change'; import { ActivityGroupDollarAmountChange } from './activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityGroupItemStyles } from './activity-group-item.styles'; -import { - BAKING_REWARDS_TEXT, - DELEGATION_TEXT, - UNDELEGATION_TEXT -} from './activity-group-type/use-activity-group-info.hook'; +import { useActivityCommonStyles, useActivityDetailsStyles } from './activity-group-item.styles'; import { ActivityStatusBadge } from './activity-status-badge/activity-status-badge'; import { ActivityTime } from './activity-time/activity-time'; import { ActivityGroupItemSelectors } from './selectors'; -interface ActivityDetailsProps { - activity: ActivityInterface; - nonZeroAmounts: ActivityNonZeroAmounts; - label: string; - address: string | undefined; - transactionHash: string; - transactionType: string; - transactionSubtype: string; -} +const SendTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ + nonZeroAmounts, + address, + hash +}) => { + const selectedRpcUrl = useSelectedRpcUrlSelector(); + const styles = useActivityDetailsStyles(); -export const ActivityDetails: FC = ({ - activity, + const commonStyles = useActivityCommonStyles(); + + return ( + <> + + Sent: + + + + + + + To: + + + + TxHash: + + + + + + + + ); +}; +const ReceiveTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ nonZeroAmounts, - label, address, - transactionHash, - transactionType, - transactionSubtype + hash }) => { - const styles = useActivityGroupItemStyles(); const selectedRpcUrl = useSelectedRpcUrlSelector(); - const { symbol } = useCurrentFiatCurrencyMetadataSelector(); + const styles = useActivityDetailsStyles(); + const commonStyles = useActivityCommonStyles(); - const [areDetailsVisible, setAreDetailsVisible] = useState(false); - const handleOpenActivityDetailsPress = useCallback(() => setAreDetailsVisible(prevState => !prevState), []); + return ( + <> + + Received: + + + + + + + From: + + + + TxHash: + + + + + + + + ); +}; +const DelegateDetails: FC<{ address: string; hash: string }> = ({ address, hash }) => { + const selectedRpcUrl = useSelectedRpcUrlSelector(); + const styles = useActivityDetailsStyles(); + const commonStyles = useActivityCommonStyles(); - const collectible = useCollectibleBySlugSelector(`${activity.address}_${activity.tokenId ?? 0}`); - const isCollectible = useMemo(() => isDefined(collectible), [collectible]); - const { shouldShowTzktLink, bakerAddress } = useMemo(() => { - if (transactionType === BAKING_REWARDS_TEXT) { - return { - shouldShowTzktLink: true, - bakerAddress: activity.source.address - }; - } else if (transactionType === DELEGATION_TEXT) { - return { - shouldShowTzktLink: true, - bakerAddress: activity.destination.address - }; - } else if (transactionType === UNDELEGATION_TEXT) { - return { - shouldShowTzktLink: true, - bakerAddress: activity.destination.address - }; - } + return ( + <> + + To: + + + + + + + + TxHash: + + + + + + + + ); +}; + +interface ActivityDetailsProps { + activity: Activity; +} + +const nonZeroAmounts = { + amounts: [{ parsedAmount: new BigNumber(888), isPositive: true, exchangeRate: 1.2, symbol: 'XTZ' }], + dollarSums: [new BigNumber(888)] +}; - return { - shouldShowTzktLink: false, - bakerAddress: '' - }; - }, [transactionType]); +export const ActivityDetails: FC = ({ activity }) => { + const detailsStyles = useActivityDetailsStyles(); + const commonStyles = useActivityCommonStyles(); + + const [areDetailsVisible, setAreDetailsVisible] = useState(false); + const handleOpenActivityDetailsPress = useCallback(() => setAreDetailsVisible(prevState => !prevState), []); return ( - - + + @@ -102,61 +149,35 @@ export const ActivityDetails: FC = ({ {areDetailsVisible && ( - - {!isEmpty(nonZeroAmounts.amounts) && ( - - {transactionSubtype} - - - - {isCollectible ? ( - 0.00{symbol} - ) : ( - - )} - + + {(() => { + switch (activity.type) { + case ActivityType.Send: + return ( + + ); + + case ActivityType.Recieve: + case ActivityType.BakingRewards: + return ( + + ); + + case ActivityType.Delegation: + return ; - {isDefined(collectible) && ( - <> - - - - )} - - - )} - {isDefined(address) && ( - - {label} - - - {shouldShowTzktLink && ( - <> - - - - )} - - - )} - - TxHash: - - - - - - + default: + return null; + } + })()} )} diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts index e34124dbb..c1121af50 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts @@ -35,6 +35,36 @@ export const useActivityGroupItemStyles = createUseStyles(({ colors, typography borderBottomWidth: formatSize(0.5), borderBottomColor: colors.lines }, + robotBackground: { + backgroundColor: colors.navigation + } +})); + +export const useActivityDetailsStyles = createUseStyles(({ colors }) => ({ + card: { + marginTop: formatSize(12), + paddingHorizontal: formatSize(12), + borderRadius: formatSize(8), + backgroundColor: colors.cardBG + }, + itemWrapper: { + flexDirection: 'row', + justifyContent: 'space-between', + paddingVertical: formatSize(12) + }, + text: { + color: colors.gray1 + }, + border: { + borderBottomWidth: formatSize(0.5), + borderBottomColor: colors.lines + }, + chevron: { + padding: formatSize(4) + } +})); + +export const useActivityCommonStyles = createUseStyles(() => ({ row: { flexDirection: 'row' }, @@ -49,15 +79,5 @@ export const useActivityGroupItemStyles = createUseStyles(({ colors, typography }, itemsCenter: { alignItems: 'center' - }, - robotBackground: { - backgroundColor: colors.navigation - }, - ntfPrice: { - ...typography.numbersRegular11, - color: colors.gray1 - }, - chevron: { - padding: formatSize(4) } })); diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx index ae1650d76..a505fa324 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx @@ -1,84 +1,151 @@ +import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; +import { BigNumber } from 'bignumber.js'; import React, { FC } from 'react'; import { View, Text } from 'react-native'; +import { BakerInterface } from 'src/apis/baking-bad'; import { AvatarImage } from 'src/components/avatar-image/avatar-image'; import { Divider } from 'src/components/divider/divider'; import { RobotIcon } from 'src/components/robot-icon/robot-icon'; -import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; import { ActivityGroup, emptyActivity } from 'src/interfaces/activity.interface'; +import { useBakersListSelector } from 'src/store/baking/baking-selectors'; import { formatSize } from 'src/styles/format-size'; +import { truncateLongAddress } from 'src/utils/exolix.util'; import { isDefined } from 'src/utils/is-defined'; import { ActivityGroupAmountChange } from './activity-group-amount-change/activity-group-amount-change'; import { ActivityDetails } from './activity-group-details'; import { ActivityGroupDollarAmountChange } from './activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityGroupItemStyles } from './activity-group-item.styles'; -import { useActivityGroupInfo } from './activity-group-type/use-activity-group-info.hook'; +import { useActivityCommonStyles, useActivityGroupItemStyles } from './activity-group-item.styles'; interface Props { group: ActivityGroup; } -interface GroupItem { - title: string; - subtitle: string; - sender: string; - receiver: string; - transactionHash: string; - status: string; - timestamp: string; - amounts: { - amountInTokens: Array; - amountInDollars: number; - }; -} +const nonZeroAmounts = { + amounts: [{ parsedAmount: new BigNumber(888), isPositive: true, exchangeRate: 1.2, symbol: 'XTZ' }], + dollarSums: [new BigNumber(888)] +}; -export const ActivityGroupItem: FC = ({ group }) => { +const findBaker = (bakers: Array, candidate: string) => + bakers.find(baker => baker.address === candidate); + +const GetActivityItem: FC<{ activity: Activity }> = ({ activity }) => { const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + const bakers = useBakersListSelector(); + + switch (activity.type) { + case ActivityType.Recieve: + return ( + + + + + + Receive + + + + From: {truncateLongAddress(activity.from.address)} + + + + + ); + case ActivityType.Send: + return ( + + + + + + Send + + + + To: {truncateLongAddress(activity.to.address)} + + + + + ); + case ActivityType.BakingRewards: { + const baker = findBaker(bakers, activity.from.address); + + return ( + + {isDefined(baker) ? ( + + ) : ( + + )} + + + + Baking rewards + + + + + From: {baker?.name ?? truncateLongAddress(activity.from.address)} + + + + + + ); + } + case ActivityType.Delegation: { + const baker = findBaker(bakers, activity.to?.address ?? ''); + + return ( + + {isDefined(baker) ? ( + + ) : ( + + )} + + + + + Delegate + + + + + To: {baker?.name ?? truncateLongAddress(activity.to?.address ?? '')} + + + + + + ); + } - const { - seed, - transactionType, - transactionSubtype, - transactionHash, - destination: { label, value, address, bakerLogo } - } = useActivityGroupInfo(group); - const nonZeroAmounts = useNonZeroAmounts(group); + default: + return null; + } +}; +export const ActivityGroupItem: FC = ({ group }) => { + const styles = useActivityGroupItemStyles(); const firstActivity = group[0] ?? emptyActivity; return ( - - {isDefined(bakerLogo) ? ( - - ) : ( - - )} - - - - {transactionType} - - - - - {label} {value} - - - - - + - + ); }; diff --git a/src/components/activity-groups-list/activity-group-item/activity-status-badge/activity-status-badge.tsx b/src/components/activity-groups-list/activity-group-item/activity-status-badge/activity-status-badge.tsx index ed9f050a4..e2c2b160b 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-status-badge/activity-status-badge.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-status-badge/activity-status-badge.tsx @@ -1,3 +1,4 @@ +import { TzktOperationStatus } from '@temple-wallet/transactions-parser'; import React, { FC, useMemo } from 'react'; import { Text, View } from 'react-native'; @@ -6,7 +7,7 @@ import { useColors } from '../../../../styles/use-colors'; import { useActivityStatusBadgeStyles } from './activity-status-badge.styles'; interface Props { - status: ActivityStatusEnum; + status: ActivityStatusEnum | TzktOperationStatus; } export const ActivityStatusBadge: FC = ({ status }) => { @@ -16,8 +17,8 @@ export const ActivityStatusBadge: FC = ({ status }) => { const backgroundColor = useMemo(() => { let result = colors.destructive; - status === ActivityStatusEnum.Pending && (result = colors.gray2); - status === ActivityStatusEnum.Applied && (result = colors.adding); + (status === ActivityStatusEnum.Pending || status === TzktOperationStatus.Pending) && (result = colors.gray2); + (status === ActivityStatusEnum.Applied || status === TzktOperationStatus.Applied) && (result = colors.adding); return result; }, [status, colors]); diff --git a/src/components/activity-groups-list/activity-group-item/activity-time/activity-time.tsx b/src/components/activity-groups-list/activity-group-item/activity-time/activity-time.tsx index 6489c1279..09cf6d7ec 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-time/activity-time.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-time/activity-time.tsx @@ -4,7 +4,7 @@ import { Text } from 'react-native'; import { useActivityTimeStyles } from './activity-time.styles'; interface Props { - timestamp: number; + timestamp: string; } export const ActivityTime: FC = ({ timestamp }) => { diff --git a/src/components/activity-groups-list/activity-groups-list.tsx b/src/components/activity-groups-list/activity-groups-list.tsx index b3cbeaca3..a8739eed0 100644 --- a/src/components/activity-groups-list/activity-groups-list.tsx +++ b/src/components/activity-groups-list/activity-groups-list.tsx @@ -38,7 +38,7 @@ export const ActivityGroupsList: FC = ({ const date = new Date(firstActivity.timestamp); if (isTheSameDay(date, prevActivityDate)) { - result[result.length - 1].data.push(activityGroup); + result[result.length - 1]?.data.push(activityGroup); } else { let title = date.toLocaleString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' }).toUpperCase(); @@ -80,7 +80,7 @@ export const ActivityGroupsList: FC = ({ contentContainerStyle={styles.sectionListContentContainer} onEndReachedThreshold={0.01} onEndReached={handleUpdate} - keyExtractor={item => item[0].hash} + keyExtractor={(item, index) => item[0]?.hash ?? index} renderItem={({ item, index, section }) => ( <> diff --git a/src/hooks/use-contract-activity.ts b/src/hooks/use-contract-activity.ts index 97a3f0703..687e90ad9 100644 --- a/src/hooks/use-contract-activity.ts +++ b/src/hooks/use-contract-activity.ts @@ -1,7 +1,12 @@ +import { Activity, TzktMemberInterface } from '@temple-wallet/transactions-parser'; import { uniq } from 'lodash-es'; -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { useDispatch } from 'react-redux'; + +import { ActivityInterface } from 'src/interfaces/activity.interface'; +import { loadBakersListActions } from 'src/store/baking/baking-actions'; +import { useBakersListSelector } from 'src/store/baking/baking-selectors'; -import { ActivityGroup } from '../interfaces/activity.interface'; import { UseActivityInterface } from '../interfaces/use-activity.interface'; import { useSelectedRpcUrlSelector } from '../store/settings/settings-selectors'; import { useSelectedAccountSelector } from '../store/wallet/wallet-selectors'; @@ -9,17 +14,28 @@ import { isDefined } from '../utils/is-defined'; import { loadActivity } from '../utils/token-operations.util'; export const useContractActivity = (tokenSlug?: string): UseActivityInterface => { + const dispatch = useDispatch(); const selectedAccount = useSelectedAccountSelector(); const selectedRpcUrl = useSelectedRpcUrlSelector(); + const bakers = useBakersListSelector(); const lastActivityRef = useRef(''); const [isAllLoaded, setIsAllLoaded] = useState(false); - const [activities, setActivities] = useState>([]); + const [activities, setActivities] = useState>>([]); + + const knownBakers = useMemo>( + () => + bakers.map(baker => ({ + address: baker.address, + alias: baker.name + })), + [bakers] + ); const initialLoad = useCallback( async (refresh = false) => { - const activities = await loadActivity(selectedRpcUrl, selectedAccount, tokenSlug); + const activities = await loadActivity(selectedRpcUrl, selectedAccount, tokenSlug, knownBakers); if (activities.length === 0) { setIsAllLoaded(true); @@ -39,9 +55,11 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => setActivities(activities); } }, - [selectedRpcUrl, selectedAccount, tokenSlug] + [selectedRpcUrl, selectedAccount, tokenSlug, knownBakers] ); + useEffect(() => void dispatch(loadBakersListActions.submit()), []); + useEffect(() => { initialLoad(); }, [initialLoad]); @@ -61,7 +79,13 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => lastActivityRef.current = lastItem.hash; if (isDefined(lastItem)) { - const newActivity = await loadActivity(selectedRpcUrl, selectedAccount, tokenSlug, lastItem); + const newActivity = await loadActivity( + selectedRpcUrl, + selectedAccount, + tokenSlug, + knownBakers, + lastItem as unknown as ActivityInterface + ); if (newActivity.length === 0) { setIsAllLoaded(true); diff --git a/src/hooks/use-non-zero-amounts.hook.ts b/src/hooks/use-non-zero-amounts.hook.ts index bc57b9604..9357e0ecb 100644 --- a/src/hooks/use-non-zero-amounts.hook.ts +++ b/src/hooks/use-non-zero-amounts.hook.ts @@ -38,7 +38,7 @@ export const useNonZeroAmounts = (group: ActivityGroup): ActivityNonZeroAmounts let positiveAmountSum = new BigNumber(0); let negativeAmountSum = new BigNumber(0); - for (const { address, tokenId, amount } of group) { + for (const { tokensDeltas } of group) { const slug = getTokenSlug({ address, id: tokenId }); const { decimals, symbol, name, artifactUri } = getTokenMetadata(slug); const exchangeRate: number | undefined = exchangeRates[slug]; diff --git a/src/interfaces/activity.interface.ts b/src/interfaces/activity.interface.ts index 9608121d8..a1d44ca07 100644 --- a/src/interfaces/activity.interface.ts +++ b/src/interfaces/activity.interface.ts @@ -1,3 +1,5 @@ +import { Activity } from '@temple-wallet/transactions-parser'; + import { ActivityStatusEnum } from '../enums/activity-status.enum'; import { ActivityTypeEnum } from '../enums/activity-type.enum'; import { emptyMember, MemberInterface } from './member.interface'; @@ -18,7 +20,7 @@ export interface ActivityInterface { level?: number; } -export type ActivityGroup = ActivityInterface[]; +export type ActivityGroup = Array; export const emptyActivity: ActivityInterface = { type: ActivityTypeEnum.Transaction, diff --git a/src/screens/activity/activity.tsx b/src/screens/activity/activity.tsx index a5f41e8d6..741d3630f 100644 --- a/src/screens/activity/activity.tsx +++ b/src/screens/activity/activity.tsx @@ -7,6 +7,7 @@ import { usePageAnalytic } from '../../utils/analytics/use-analytics.hook'; export const Activity = () => { const { activities, handleUpdate } = useContractActivity(); + console.log('activities: ', activities); usePageAnalytic(ScreensEnum.Activity); diff --git a/src/utils/token-operations.util.ts b/src/utils/token-operations.util.ts index 3b5b37f73..c4090649e 100644 --- a/src/utils/token-operations.util.ts +++ b/src/utils/token-operations.util.ts @@ -1,3 +1,6 @@ +import { Activity, TzktMemberInterface, TzktOperation, parseTransactions } from '@temple-wallet/transactions-parser'; +import { LiquidityBakingMintOrBurnInterface } from '@temple-wallet/transactions-parser/dist/types/liquidity-baking'; +import { Fa12TransferInterface, Fa2TransferInterface } from '@temple-wallet/transactions-parser/dist/types/transfers'; import { uniq } from 'lodash-es'; import { getTzktApi } from '../api.service'; @@ -5,18 +8,11 @@ import { OPERATION_LIMIT } from '../config/general'; import { ActivityTypeEnum } from '../enums/activity-type.enum'; import { AccountInterface } from '../interfaces/account.interface'; import { ActivityInterface } from '../interfaces/activity.interface'; -import { - OperationFa12Interface, - OperationFa2Interface, - OperationInterface, - OperationLiquidityBakingInterface -} from '../interfaces/operation.interface'; import { TokenTypeEnum } from '../interfaces/token-type.enum'; import { LIQUIDITY_BAKING_DEX_ADDRESS } from '../token/data/token-slugs'; import { TEZ_TOKEN_SLUG } from '../token/data/tokens-metadata'; import { getTokenType } from '../token/utils/token.utils'; import { isDefined } from './is-defined'; -import { mapOperationsToActivities } from './operation.utils'; import { createReadOnlyTezosToolkit } from './rpc/tezos-toolkit.utils'; import { sleep } from './timeouts.util'; @@ -51,7 +47,7 @@ const getTokenFa2Operations = ( lastLevel?: number ) => getTzktApi(selectedRpcUrl) - .get>('operations/transactions', { + .get>('operations/transactions', { params: { limit: OPERATION_LIMIT, entrypoint: 'transfer', @@ -65,7 +61,7 @@ const getTokenFa2Operations = ( const getTokenFa12Operations = (selectedRpcUrl: string, account: string, contractAddress: string, lastLevel?: number) => getTzktApi(selectedRpcUrl) - .get>('operations/transactions', { + .get>('operations/transactions', { params: { limit: OPERATION_LIMIT, entrypoint: 'transfer', @@ -79,7 +75,7 @@ const getTokenFa12Operations = (selectedRpcUrl: string, account: string, contrac const getTezosOperations = (selectedRpcUrl: string, account: string, lastId?: number) => getTzktApi(selectedRpcUrl) - .get>(`accounts/${account}/operations`, { + .get>(`accounts/${account}/operations`, { params: { limit: OPERATION_LIMIT, type: ActivityTypeEnum.Transaction, @@ -92,7 +88,7 @@ const getTezosOperations = (selectedRpcUrl: string, account: string, lastId?: nu const getAccountOperations = (selectedRpcUrl: string, account: string, lastId?: number) => getTzktApi(selectedRpcUrl) - .get>(`accounts/${account}/operations`, { + .get>(`accounts/${account}/operations`, { params: { limit: OPERATION_LIMIT, type: `${ActivityTypeEnum.Delegation},${ActivityTypeEnum.Origination},${ActivityTypeEnum.Transaction}`, @@ -104,7 +100,7 @@ const getAccountOperations = (selectedRpcUrl: string, account: string, lastId?: const getFa12IncomingOperations = (selectedRpcUrl: string, account: string, lowerId: number, upperId?: number) => getTzktApi(selectedRpcUrl) - .get>('operations/transactions', { + .get>('operations/transactions', { params: { 'sender.ne': account, 'target.ne': account, @@ -119,7 +115,7 @@ const getFa12IncomingOperations = (selectedRpcUrl: string, account: string, lowe const getFa2IncomingOperations = (selectedRpcUrl: string, account: string, lowerId: number, upperId?: number) => getTzktApi(selectedRpcUrl) - .get>('operations/transactions', { + .get>('operations/transactions', { params: { 'sender.ne': account, 'target.ne': account, @@ -136,7 +132,7 @@ const getAllOperations = async ( selectedRpcUrl: string, publicKeyHash: string, upperId?: number -): Promise => { +): Promise => { const operations = await getAccountOperations(selectedRpcUrl, publicKeyHash, upperId); if (operations.length === 0) { return []; @@ -162,7 +158,7 @@ const loadOperations = async ( selectedAccount: AccountInterface, tokenSlug?: string, lastItem?: ActivityInterface -) => { +): Promise> => { const [contractAddress, tokenId] = (tokenSlug ?? '').split('_'); if (isDefined(tokenSlug)) { @@ -171,7 +167,7 @@ const loadOperations = async ( } if (tokenSlug === LIQUIDITY_BAKING_DEX_ADDRESS) { - return getContractOperations( + return getContractOperations( selectedRpcUrl, selectedAccount.publicKeyHash, contractAddress, @@ -205,19 +201,22 @@ export const loadActivity = async ( selectedRpcUrl: string, selectedAccount: AccountInterface, tokenSlug?: string, + knownBakers?: Array, lastItem?: ActivityInterface -) => { +): Promise>> => { const operationsHashes = await loadOperations(selectedRpcUrl, selectedAccount, tokenSlug, lastItem) .then(operations => operations.map(operation => operation.hash)) .then(newHashes => uniq(newHashes.filter(x => x !== lastItem?.hash))); - const operationGroups = []; + const operationGroups: Array> = []; for (const opHash of operationsHashes) { - const { data } = await getOperationGroupByHash(selectedRpcUrl, opHash); + const { data } = await getOperationGroupByHash(selectedRpcUrl, opHash); operationGroups.push(data); await sleep(100); } - return operationGroups.map(group => mapOperationsToActivities(selectedAccount.publicKeyHash, group)); + const result = operationGroups.map(group => parseTransactions(group, selectedAccount.publicKeyHash, knownBakers)); + + return result; }; From 41a26da7aca13c6cbddd93136a144c9b2d91843e Mon Sep 17 00:00:00 2001 From: herkoss Date: Sat, 5 Aug 2023 00:12:11 +0300 Subject: [PATCH 09/43] TW-786 Finished big refactoting --- src/apis/baking-bad/consts.ts | 6 + .../activity-details-card.tsx | 30 +++ .../delegate-details.tsx | 40 ++++ .../receive-tokens-details.tsx | 50 +++++ .../send-tokens-details.tsx | 51 +++++ .../activity-group-item/activity-details.tsx | 53 +++++ .../activity-group-details.tsx | 185 ------------------ .../activity-group-item.tsx | 138 +------------ .../use-activity-group-info.hook.ts | 118 ----------- .../activity-info/activity-info.tsx | 28 +++ .../activity-info/baking-rewards-info.tsx | 46 +++++ .../activity-info/delegation-info.tsx | 39 ++++ .../activity-info/receive-info.tsx | 34 ++++ .../activity-info/send-info.tsx | 34 ++++ src/hooks/use-contract-activity.ts | 30 +-- src/hooks/use-non-zero-amounts.hook.ts | 19 +- src/interfaces/account.interface.ts | 6 - src/interfaces/activity.interface.mock.ts | 160 --------------- src/interfaces/activity.interface.ts | 37 +--- src/interfaces/member.interface.ts | 7 +- src/interfaces/operation.interface.mock.ts | 85 -------- src/interfaces/operation.interface.ts | 67 ------- src/interfaces/transfer.interface.mock.ts | 17 -- src/interfaces/transfer.interface.ts | 11 -- src/interfaces/tzkt.interface.ts | 25 --- src/screens/activity/activity.tsx | 1 - src/store/baking/baking-selectors.ts | 26 +++ src/store/wallet/wallet-reducers.ts | 4 +- src/store/wallet/wallet-selectors.ts | 5 - src/utils/activity.spec.ts | 12 -- src/utils/activity.utils.ts | 52 ----- src/utils/operation.utils.ts | 153 --------------- src/utils/operations.utils.spec.ts | 20 -- .../string-to-activity-status-enum.util.ts | 18 -- src/utils/token-operations.util.ts | 52 ++--- src/utils/transfer.utils.spec.ts | 36 ---- src/utils/transfer.utils.ts | 35 ---- 37 files changed, 498 insertions(+), 1232 deletions(-) create mode 100644 src/components/activity-groups-list/activity-group-item/activity-details-card/activity-details-card.tsx create mode 100644 src/components/activity-groups-list/activity-group-item/activity-details-card/delegate-details.tsx create mode 100644 src/components/activity-groups-list/activity-group-item/activity-details-card/receive-tokens-details.tsx create mode 100644 src/components/activity-groups-list/activity-group-item/activity-details-card/send-tokens-details.tsx create mode 100644 src/components/activity-groups-list/activity-group-item/activity-details.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/activity-group-details.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts create mode 100644 src/components/activity-groups-list/activity-group-item/activity-info/activity-info.tsx create mode 100644 src/components/activity-groups-list/activity-group-item/activity-info/baking-rewards-info.tsx create mode 100644 src/components/activity-groups-list/activity-group-item/activity-info/delegation-info.tsx create mode 100644 src/components/activity-groups-list/activity-group-item/activity-info/receive-info.tsx create mode 100644 src/components/activity-groups-list/activity-group-item/activity-info/send-info.tsx delete mode 100644 src/interfaces/activity.interface.mock.ts delete mode 100644 src/interfaces/operation.interface.mock.ts delete mode 100644 src/interfaces/operation.interface.ts delete mode 100644 src/interfaces/transfer.interface.mock.ts delete mode 100644 src/interfaces/transfer.interface.ts delete mode 100644 src/utils/activity.spec.ts delete mode 100644 src/utils/activity.utils.ts delete mode 100644 src/utils/operation.utils.ts delete mode 100644 src/utils/operations.utils.spec.ts delete mode 100644 src/utils/string-to-activity-status-enum.util.ts delete mode 100644 src/utils/transfer.utils.spec.ts delete mode 100644 src/utils/transfer.utils.ts diff --git a/src/apis/baking-bad/consts.ts b/src/apis/baking-bad/consts.ts index e66ae2c0b..d00b4978e 100644 --- a/src/apis/baking-bad/consts.ts +++ b/src/apis/baking-bad/consts.ts @@ -45,3 +45,9 @@ export const mockBaker: BakerInterface = { audit: 'Mock Audit', insuranceCoverage: 44 }; + +export const EVERSTAKE_PAYOUTS_BAKER = { + address: 'tz1W1en9UpMCH4ZJL8wQCh8JDKCZARyVx2co', + logo: 'https://services.tzkt.io/v1/avatars/tz1aRoaRhSpRYvFdyvgWLL6TGyRoGF51wDjM', + name: 'Everstake' +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-details-card/activity-details-card.tsx b/src/components/activity-groups-list/activity-group-item/activity-details-card/activity-details-card.tsx new file mode 100644 index 000000000..633fc2177 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-details-card/activity-details-card.tsx @@ -0,0 +1,30 @@ +import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; +import React, { FC } from 'react'; + +import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; + +import { DelegateDetails } from './delegate-details'; +import { ReceiveTokensDetails } from './receive-tokens-details'; +import { SendTokensDetails } from './send-tokens-details'; + +export const ActivityDetailsCard: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = ({ + activity, + nonZeroAmounts +}) => { + switch (activity.type) { + case ActivityType.Send: + return ; + + case ActivityType.Recieve: + case ActivityType.BakingRewards: + return ( + + ); + + case ActivityType.Delegation: + return ; + + default: + return null; + } +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-details-card/delegate-details.tsx b/src/components/activity-groups-list/activity-group-item/activity-details-card/delegate-details.tsx new file mode 100644 index 000000000..fccf094e7 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-details-card/delegate-details.tsx @@ -0,0 +1,40 @@ +import React, { FC } from 'react'; +import { View, Text } from 'react-native'; + +import { Divider } from 'src/components/divider/divider'; +import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; +import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; +import { WalletAddress } from 'src/components/wallet-address/wallet-address'; +import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { formatSize } from 'src/styles/format-size'; +import { tzktUrl } from 'src/utils/linking.util'; + +import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; +import { ActivityGroupItemSelectors } from '../selectors'; + +export const DelegateDetails: FC<{ address: string | undefined; hash: string }> = ({ hash, address = '' }) => { + const selectedRpcUrl = useSelectedRpcUrlSelector(); + const styles = useActivityDetailsStyles(); + const commonStyles = useActivityCommonStyles(); + + return ( + <> + + To: + + + + + + + + TxHash: + + + + + + + + ); +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-details-card/receive-tokens-details.tsx b/src/components/activity-groups-list/activity-group-item/activity-details-card/receive-tokens-details.tsx new file mode 100644 index 000000000..f3f58e488 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-details-card/receive-tokens-details.tsx @@ -0,0 +1,50 @@ +import React, { FC } from 'react'; +import { View, Text } from 'react-native'; + +import { Divider } from 'src/components/divider/divider'; +import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; +import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; +import { WalletAddress } from 'src/components/wallet-address/wallet-address'; +import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { formatSize } from 'src/styles/format-size'; +import { tzktUrl } from 'src/utils/linking.util'; + +import { ActivityGroupAmountChange, TextSize } from '../activity-group-amount-change/activity-group-amount-change'; +import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; +import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; +import { ActivityGroupItemSelectors } from '../selectors'; + +export const ReceiveTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ + nonZeroAmounts, + address, + hash +}) => { + const selectedRpcUrl = useSelectedRpcUrlSelector(); + const styles = useActivityDetailsStyles(); + const commonStyles = useActivityCommonStyles(); + + return ( + <> + + Received: + + + + + + + From: + + + + TxHash: + + + + + + + + ); +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-details-card/send-tokens-details.tsx b/src/components/activity-groups-list/activity-group-item/activity-details-card/send-tokens-details.tsx new file mode 100644 index 000000000..8038aa326 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-details-card/send-tokens-details.tsx @@ -0,0 +1,51 @@ +import React, { FC } from 'react'; +import { View, Text } from 'react-native'; + +import { Divider } from 'src/components/divider/divider'; +import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; +import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; +import { WalletAddress } from 'src/components/wallet-address/wallet-address'; +import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { formatSize } from 'src/styles/format-size'; +import { tzktUrl } from 'src/utils/linking.util'; + +import { ActivityGroupAmountChange, TextSize } from '../activity-group-amount-change/activity-group-amount-change'; +import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; +import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; +import { ActivityGroupItemSelectors } from '../selectors'; + +export const SendTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ + nonZeroAmounts, + address, + hash +}) => { + const selectedRpcUrl = useSelectedRpcUrlSelector(); + const styles = useActivityDetailsStyles(); + + const commonStyles = useActivityCommonStyles(); + + return ( + <> + + Sent: + + + + + + + To: + + + + TxHash: + + + + + + + + ); +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-details.tsx b/src/components/activity-groups-list/activity-group-item/activity-details.tsx new file mode 100644 index 000000000..cb5b0f2d7 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-details.tsx @@ -0,0 +1,53 @@ +import { Activity } from '@temple-wallet/transactions-parser'; +import React, { FC, useState, useCallback } from 'react'; +import { View } from 'react-native'; + +import { Divider } from 'src/components/divider/divider'; +import { Icon } from 'src/components/icon/icon'; +import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics'; +import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { formatSize } from 'src/styles/format-size'; + +import { ActivityDetailsCard } from './activity-details-card/activity-details-card'; +import { useActivityCommonStyles, useActivityDetailsStyles } from './activity-group-item.styles'; +import { ActivityStatusBadge } from './activity-status-badge/activity-status-badge'; +import { ActivityTime } from './activity-time/activity-time'; +import { ActivityGroupItemSelectors } from './selectors'; + +interface Props { + activity: Activity; + nonZeroAmounts: NonZeroAmounts; +} + +export const ActivityDetails: FC = ({ activity, nonZeroAmounts }) => { + const detailsStyles = useActivityDetailsStyles(); + const commonStyles = useActivityCommonStyles(); + + const [areDetailsVisible, setAreDetailsVisible] = useState(false); + const handleOpenActivityDetailsPress = useCallback(() => setAreDetailsVisible(prevState => !prevState), []); + + return ( + + + + + + + + + + + + {areDetailsVisible && ( + + + + )} + + ); +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx deleted file mode 100644 index 6eb8a77dc..000000000 --- a/src/components/activity-groups-list/activity-group-item/activity-group-details.tsx +++ /dev/null @@ -1,185 +0,0 @@ -import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; -import { BigNumber } from 'bignumber.js'; -import React, { FC, useState, useCallback } from 'react'; -import { View, Text } from 'react-native'; - -import { Divider } from 'src/components/divider/divider'; -import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; -import { Icon } from 'src/components/icon/icon'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; -import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; -import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics'; -import { WalletAddress } from 'src/components/wallet-address/wallet-address'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; -import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; -import { formatSize } from 'src/styles/format-size'; -import { tzktUrl } from 'src/utils/linking.util'; - -import { ActivityGroupAmountChange, TextSize } from './activity-group-amount-change/activity-group-amount-change'; -import { ActivityGroupDollarAmountChange } from './activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityDetailsStyles } from './activity-group-item.styles'; -import { ActivityStatusBadge } from './activity-status-badge/activity-status-badge'; -import { ActivityTime } from './activity-time/activity-time'; -import { ActivityGroupItemSelectors } from './selectors'; - -const SendTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ - nonZeroAmounts, - address, - hash -}) => { - const selectedRpcUrl = useSelectedRpcUrlSelector(); - const styles = useActivityDetailsStyles(); - - const commonStyles = useActivityCommonStyles(); - - return ( - <> - - Sent: - - - - - - - To: - - - - TxHash: - - - - - - - - ); -}; -const ReceiveTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ - nonZeroAmounts, - address, - hash -}) => { - const selectedRpcUrl = useSelectedRpcUrlSelector(); - const styles = useActivityDetailsStyles(); - const commonStyles = useActivityCommonStyles(); - - return ( - <> - - Received: - - - - - - - From: - - - - TxHash: - - - - - - - - ); -}; -const DelegateDetails: FC<{ address: string; hash: string }> = ({ address, hash }) => { - const selectedRpcUrl = useSelectedRpcUrlSelector(); - const styles = useActivityDetailsStyles(); - const commonStyles = useActivityCommonStyles(); - - return ( - <> - - To: - - - - - - - - TxHash: - - - - - - - - ); -}; - -interface ActivityDetailsProps { - activity: Activity; -} - -const nonZeroAmounts = { - amounts: [{ parsedAmount: new BigNumber(888), isPositive: true, exchangeRate: 1.2, symbol: 'XTZ' }], - dollarSums: [new BigNumber(888)] -}; - -export const ActivityDetails: FC = ({ activity }) => { - const detailsStyles = useActivityDetailsStyles(); - const commonStyles = useActivityCommonStyles(); - - const [areDetailsVisible, setAreDetailsVisible] = useState(false); - const handleOpenActivityDetailsPress = useCallback(() => setAreDetailsVisible(prevState => !prevState), []); - - return ( - - - - - - - - - - - - {areDetailsVisible && ( - - {(() => { - switch (activity.type) { - case ActivityType.Send: - return ( - - ); - - case ActivityType.Recieve: - case ActivityType.BakingRewards: - return ( - - ); - - case ActivityType.Delegation: - return ; - - default: - return null; - } - })()} - - )} - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx index a505fa324..14fe3e602 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx @@ -1,151 +1,29 @@ -import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; -import { BigNumber } from 'bignumber.js'; import React, { FC } from 'react'; -import { View, Text } from 'react-native'; +import { View } from 'react-native'; -import { BakerInterface } from 'src/apis/baking-bad'; -import { AvatarImage } from 'src/components/avatar-image/avatar-image'; import { Divider } from 'src/components/divider/divider'; -import { RobotIcon } from 'src/components/robot-icon/robot-icon'; +import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; import { ActivityGroup, emptyActivity } from 'src/interfaces/activity.interface'; -import { useBakersListSelector } from 'src/store/baking/baking-selectors'; import { formatSize } from 'src/styles/format-size'; -import { truncateLongAddress } from 'src/utils/exolix.util'; -import { isDefined } from 'src/utils/is-defined'; -import { ActivityGroupAmountChange } from './activity-group-amount-change/activity-group-amount-change'; -import { ActivityDetails } from './activity-group-details'; -import { ActivityGroupDollarAmountChange } from './activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityGroupItemStyles } from './activity-group-item.styles'; +import { ActivityDetails } from './activity-details'; +import { useActivityGroupItemStyles } from './activity-group-item.styles'; +import { ActivityInfo } from './activity-info/activity-info'; interface Props { group: ActivityGroup; } -const nonZeroAmounts = { - amounts: [{ parsedAmount: new BigNumber(888), isPositive: true, exchangeRate: 1.2, symbol: 'XTZ' }], - dollarSums: [new BigNumber(888)] -}; - -const findBaker = (bakers: Array, candidate: string) => - bakers.find(baker => baker.address === candidate); - -const GetActivityItem: FC<{ activity: Activity }> = ({ activity }) => { - const styles = useActivityGroupItemStyles(); - const commonStyles = useActivityCommonStyles(); - const bakers = useBakersListSelector(); - - switch (activity.type) { - case ActivityType.Recieve: - return ( - - - - - - Receive - - - - From: {truncateLongAddress(activity.from.address)} - - - - - ); - case ActivityType.Send: - return ( - - - - - - Send - - - - To: {truncateLongAddress(activity.to.address)} - - - - - ); - case ActivityType.BakingRewards: { - const baker = findBaker(bakers, activity.from.address); - - return ( - - {isDefined(baker) ? ( - - ) : ( - - )} - - - - Baking rewards - - - - - From: {baker?.name ?? truncateLongAddress(activity.from.address)} - - - - - - ); - } - case ActivityType.Delegation: { - const baker = findBaker(bakers, activity.to?.address ?? ''); - - return ( - - {isDefined(baker) ? ( - - ) : ( - - )} - - - - - Delegate - - - - - To: {baker?.name ?? truncateLongAddress(activity.to?.address ?? '')} - - - - - - ); - } - - default: - return null; - } -}; - export const ActivityGroupItem: FC = ({ group }) => { const styles = useActivityGroupItemStyles(); const firstActivity = group[0] ?? emptyActivity; + const nonZeroAmounts = useNonZeroAmounts(firstActivity.tokensDeltas); return ( - + - + ); }; diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts b/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts deleted file mode 100644 index 8e2efd00c..000000000 --- a/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { useMemo } from 'react'; - -import { ActivityTypeEnum } from 'src/enums/activity-type.enum'; -import { ActivityGroup, emptyActivity } from 'src/interfaces/activity.interface'; -import { useBakersListSelector } from 'src/store/baking/baking-selectors'; -import { useSelectedAccountSelector } from 'src/store/wallet/wallet-selectors'; -import { useColors } from 'src/styles/use-colors'; -import { truncateLongAddress } from 'src/utils/exolix.util'; -import { isString } from 'src/utils/is-string'; - -interface ActivityInfo { - transactionType: string; - transactionSubtype: string; - transactionHash: string; - seed: string; - destination: { - label: string; - value: string; - address: string | undefined; - bakerLogo?: string; - }; -} - -export const BAKING_REWARDS_TEXT = 'Baking rewards'; -export const DELEGATION_TEXT = 'Delegation'; -export const UNDELEGATION_TEXT = 'Undelegation'; - -const getReceiveTransactionType = (alias: string | undefined): string => { - if (Boolean(alias?.toLowerCase().includes('payouts'))) { - return BAKING_REWARDS_TEXT; - } - - return 'Receive'; -}; - -export const useActivityGroupInfo = (group: ActivityGroup) => { - const colors = useColors(); - const bakers = useBakersListSelector(); - const { publicKeyHash } = useSelectedAccountSelector(); - - return useMemo(() => { - const firstActivity = group[0] ?? emptyActivity; - - if (group.length > 1) { - return { - transactionType: 'Interaction', - transactionSubtype: 'Sent:', - transactionHash: firstActivity.hash, - destination: { - label: 'To:', - value: truncateLongAddress(firstActivity.destination.address), - address: firstActivity.destination.address - }, - seed: firstActivity.destination.address - }; - } - - switch (firstActivity.type) { - case ActivityTypeEnum.Transaction: - if (firstActivity.source.address !== publicKeyHash) { - return { - transactionType: getReceiveTransactionType(firstActivity.source.alias), - transactionSubtype: 'Received:', - transactionHash: firstActivity.hash, - destination: { - label: 'From:', - value: truncateLongAddress(firstActivity.source.address), - address: firstActivity.source.address - }, - seed: firstActivity.source.address - }; - } - - return { - transactionType: isString(firstActivity.entrypoint) ? `Called ${firstActivity.entrypoint}` : 'Send', - transactionSubtype: 'Sent:', - transactionHash: firstActivity.hash, - destination: { - label: 'To:', - value: truncateLongAddress(firstActivity.reciever?.address ?? ''), - address: firstActivity.reciever?.address - }, - seed: firstActivity.reciever?.address ?? '' - }; - - case ActivityTypeEnum.Delegation: - const alias = firstActivity.destination.alias; - const postfix = isString(alias) ? alias : truncateLongAddress(firstActivity.destination.address); - - return { - transactionType: isString(firstActivity.destination.address) ? DELEGATION_TEXT : UNDELEGATION_TEXT, - transactionSubtype: 'Sent:', - transactionHash: firstActivity.hash, - destination: { - label: 'To:', - value: postfix, - address: firstActivity.destination.address, - bakerLogo: bakers.find(baker => baker.address === firstActivity.destination.address)?.logo - }, - seed: firstActivity.destination.address - }; - - default: - return { - transactionType: 'Undelegation', - transactionSubtype: 'Sent:', - transactionHash: firstActivity.hash, - destination: { - label: 'Received:', - value: truncateLongAddress(firstActivity.reciever?.address ?? ''), - address: firstActivity.reciever?.address, - bakerLogo: bakers.find(baker => baker.address === firstActivity.destination.address)?.logo - }, - seed: firstActivity.reciever?.address ?? '' - }; - } - }, [group, publicKeyHash, colors]); -}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-info/activity-info.tsx b/src/components/activity-groups-list/activity-group-item/activity-info/activity-info.tsx new file mode 100644 index 000000000..742fbaed8 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-info/activity-info.tsx @@ -0,0 +1,28 @@ +import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; +import React, { FC } from 'react'; + +import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; + +import { BakingRewardsInfo } from './baking-rewards-info'; +import { DelegationInfo } from './delegation-info'; +import { ReceiveInfo } from './receive-info'; +import { SendInfo } from './send-info'; + +export const ActivityInfo: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = ({ + activity, + nonZeroAmounts +}) => { + switch (activity.type) { + case ActivityType.Send: + return ; + case ActivityType.Recieve: + return ; + case ActivityType.BakingRewards: + return ; + case ActivityType.Delegation: + return ; + + default: + return null; + } +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-info/baking-rewards-info.tsx b/src/components/activity-groups-list/activity-group-item/activity-info/baking-rewards-info.tsx new file mode 100644 index 000000000..9c6de2de3 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-info/baking-rewards-info.tsx @@ -0,0 +1,46 @@ +import React, { FC } from 'react'; +import { View, Text } from 'react-native'; + +import { AvatarImage } from 'src/components/avatar-image/avatar-image'; +import { Divider } from 'src/components/divider/divider'; +import { RobotIcon } from 'src/components/robot-icon/robot-icon'; +import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { useBakerByAddressSelector } from 'src/store/baking/baking-selectors'; +import { formatSize } from 'src/styles/format-size'; +import { truncateLongAddress } from 'src/utils/exolix.util'; +import { isDefined } from 'src/utils/is-defined'; + +import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; +import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; +import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; + +export const BakingRewardsInfo: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ + address, + nonZeroAmounts +}) => { + const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + + const baker = useBakerByAddressSelector(address); + + return ( + + {isDefined(baker) ? ( + + ) : ( + + )} + + + + Baking rewards + + + + From: {baker?.name ?? truncateLongAddress(address)} + + + + + ); +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-info/delegation-info.tsx b/src/components/activity-groups-list/activity-group-item/activity-info/delegation-info.tsx new file mode 100644 index 000000000..9c1223d9d --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-info/delegation-info.tsx @@ -0,0 +1,39 @@ +import React, { FC } from 'react'; +import { View, Text } from 'react-native'; + +import { AvatarImage } from 'src/components/avatar-image/avatar-image'; +import { Divider } from 'src/components/divider/divider'; +import { RobotIcon } from 'src/components/robot-icon/robot-icon'; +import { useBakerByAddressSelector } from 'src/store/baking/baking-selectors'; +import { formatSize } from 'src/styles/format-size'; +import { truncateLongAddress } from 'src/utils/exolix.util'; +import { isDefined } from 'src/utils/is-defined'; + +import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; + +export const DelegationInfo: FC<{ address: string | undefined }> = ({ address = '' }) => { + const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + + const baker = useBakerByAddressSelector(address); + + return ( + + {isDefined(baker) ? ( + + ) : ( + + )} + + + + + Delegate + + + To: {baker?.name ?? truncateLongAddress(address)} + + + + ); +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-info/receive-info.tsx b/src/components/activity-groups-list/activity-group-item/activity-info/receive-info.tsx new file mode 100644 index 000000000..048a1a75f --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-info/receive-info.tsx @@ -0,0 +1,34 @@ +import React, { FC } from 'react'; +import { View, Text } from 'react-native'; + +import { Divider } from 'src/components/divider/divider'; +import { RobotIcon } from 'src/components/robot-icon/robot-icon'; +import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { formatSize } from 'src/styles/format-size'; +import { truncateLongAddress } from 'src/utils/exolix.util'; + +import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; +import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; +import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; + +export const ReceiveInfo: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ address, nonZeroAmounts }) => { + const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + + return ( + + + + + + Receive + + + + From: {truncateLongAddress(address)} + + + + + ); +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-info/send-info.tsx b/src/components/activity-groups-list/activity-group-item/activity-info/send-info.tsx new file mode 100644 index 000000000..c3f5eca50 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-info/send-info.tsx @@ -0,0 +1,34 @@ +import React, { FC } from 'react'; +import { View, Text } from 'react-native'; + +import { Divider } from 'src/components/divider/divider'; +import { RobotIcon } from 'src/components/robot-icon/robot-icon'; +import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { formatSize } from 'src/styles/format-size'; +import { truncateLongAddress } from 'src/utils/exolix.util'; + +import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; +import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; +import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; + +export const SendInfo: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ address, nonZeroAmounts }) => { + const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + + return ( + + + + + + Send + + + + To: {truncateLongAddress(address)} + + + + + ); +}; diff --git a/src/hooks/use-contract-activity.ts b/src/hooks/use-contract-activity.ts index 687e90ad9..1b25c31c3 100644 --- a/src/hooks/use-contract-activity.ts +++ b/src/hooks/use-contract-activity.ts @@ -1,9 +1,10 @@ -import { Activity, TzktMemberInterface } from '@temple-wallet/transactions-parser'; +import { TzktMemberInterface } from '@temple-wallet/transactions-parser'; import { uniq } from 'lodash-es'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; -import { ActivityInterface } from 'src/interfaces/activity.interface'; +import { EVERSTAKE_PAYOUTS_BAKER } from 'src/apis/baking-bad/consts'; +import { ActivityGroup } from 'src/interfaces/activity.interface'; import { loadBakersListActions } from 'src/store/baking/baking-actions'; import { useBakersListSelector } from 'src/store/baking/baking-selectors'; @@ -13,6 +14,10 @@ import { useSelectedAccountSelector } from '../store/wallet/wallet-selectors'; import { isDefined } from '../utils/is-defined'; import { loadActivity } from '../utils/token-operations.util'; +const KNOWN_BAKERS: Array = [ + { address: EVERSTAKE_PAYOUTS_BAKER.address, alias: 'Everstake payouts' } +]; + export const useContractActivity = (tokenSlug?: string): UseActivityInterface => { const dispatch = useDispatch(); const selectedAccount = useSelectedAccountSelector(); @@ -22,14 +27,17 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => const lastActivityRef = useRef(''); const [isAllLoaded, setIsAllLoaded] = useState(false); - const [activities, setActivities] = useState>>([]); + const [activities, setActivities] = useState>([]); const knownBakers = useMemo>( () => - bakers.map(baker => ({ - address: baker.address, - alias: baker.name - })), + [ + KNOWN_BAKERS, + bakers.map(({ address, name }) => ({ + address, + alias: name + })) + ].flat(), [bakers] ); @@ -79,13 +87,7 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => lastActivityRef.current = lastItem.hash; if (isDefined(lastItem)) { - const newActivity = await loadActivity( - selectedRpcUrl, - selectedAccount, - tokenSlug, - knownBakers, - lastItem as unknown as ActivityInterface - ); + const newActivity = await loadActivity(selectedRpcUrl, selectedAccount, tokenSlug, knownBakers, lastItem); if (newActivity.length === 0) { setIsAllLoaded(true); diff --git a/src/hooks/use-non-zero-amounts.hook.ts b/src/hooks/use-non-zero-amounts.hook.ts index 9357e0ecb..e53dcd575 100644 --- a/src/hooks/use-non-zero-amounts.hook.ts +++ b/src/hooks/use-non-zero-amounts.hook.ts @@ -1,13 +1,12 @@ +import { TokenDelta } from '@temple-wallet/transactions-parser'; import { BigNumber } from 'bignumber.js'; import { useMemo } from 'react'; import { useDispatch } from 'react-redux'; import { useFiatToUsdRateSelector } from 'src/store/settings/settings-selectors'; -import { ActivityGroup } from '../interfaces/activity.interface'; import { useUsdToTokenRates } from '../store/currency/currency-selectors'; import { loadTokenMetadataActions } from '../store/tokens-metadata/tokens-metadata-actions'; -import { getTokenSlug } from '../token/utils/token.utils'; import { isDefined } from '../utils/is-defined'; import { isString } from '../utils/is-string'; import { mutezToTz } from '../utils/tezos.util'; @@ -20,14 +19,14 @@ interface ActivityAmount { parsedAmount: BigNumber; } -export interface ActivityNonZeroAmounts { +interface ActivityNonZeroAmounts { amounts: Array; dollarSums: Array; } const DEFAULT_EXCHANGE_RATE = 1; -export const useNonZeroAmounts = (group: ActivityGroup): ActivityNonZeroAmounts => { +export const useNonZeroAmounts = (tokensDeltas: Array): ActivityNonZeroAmounts => { const dispatch = useDispatch(); const getTokenMetadata = useTokenMetadataGetter(); const exchangeRates = useUsdToTokenRates(); @@ -38,15 +37,15 @@ export const useNonZeroAmounts = (group: ActivityGroup): ActivityNonZeroAmounts let positiveAmountSum = new BigNumber(0); let negativeAmountSum = new BigNumber(0); - for (const { tokensDeltas } of group) { - const slug = getTokenSlug({ address, id: tokenId }); - const { decimals, symbol, name, artifactUri } = getTokenMetadata(slug); - const exchangeRate: number | undefined = exchangeRates[slug]; + for (const { atomicAmount, tokenSlug } of tokensDeltas) { + const { decimals, symbol, name, artifactUri } = getTokenMetadata(tokenSlug); + const [address, tokenId] = tokenSlug.split('_'); + const exchangeRate: number | undefined = exchangeRates[tokenSlug]; if (isString(address) && !isString(name)) { dispatch(loadTokenMetadataActions.submit({ address, id: Number(tokenId ?? '0') })); } - const parsedAmount = mutezToTz(new BigNumber(amount), decimals); + const parsedAmount = mutezToTz(atomicAmount, decimals); const isPositive = parsedAmount.isPositive(); if (isDefined(exchangeRate)) { @@ -69,5 +68,5 @@ export const useNonZeroAmounts = (group: ActivityGroup): ActivityNonZeroAmounts } return { amounts, dollarSums: [negativeAmountSum, positiveAmountSum].filter(sum => !sum.isZero()) }; - }, [group, getTokenMetadata, exchangeRates]); + }, [tokensDeltas, getTokenMetadata, exchangeRates]); }; diff --git a/src/interfaces/account.interface.ts b/src/interfaces/account.interface.ts index cd9735132..f119261ce 100644 --- a/src/interfaces/account.interface.ts +++ b/src/interfaces/account.interface.ts @@ -1,8 +1,6 @@ import { EMPTY_PUBLIC_KEY_HASH } from '../config/system'; import { AccountTypeEnum } from '../enums/account-type.enum'; -import { LoadableEntityState } from '../store/types'; import { AccountTokenInterface } from '../token/interfaces/account-token.interface'; -import { ActivityGroup } from './activity.interface'; export interface AccountBaseInterface { name: string; @@ -21,10 +19,6 @@ export interface AccountInterface extends AccountBaseInterface { tokensList?: AccountTokenInterface[]; /** @deprecated */ removedTokensList?: string[]; - /** @deprecated */ - activityGroups?: LoadableEntityState; - /** @deprecated */ - pendingActivities?: ActivityGroup[]; } export const initialAccount: AccountInterface = { diff --git a/src/interfaces/activity.interface.mock.ts b/src/interfaces/activity.interface.mock.ts deleted file mode 100644 index 097633da0..000000000 --- a/src/interfaces/activity.interface.mock.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { ActivityStatusEnum } from '../enums/activity-status.enum'; -import { ActivityTypeEnum } from '../enums/activity-type.enum'; -import { ActivityInterface } from './activity.interface'; -import { TzktTokenTransfer } from './tzkt.interface'; - -const mockMember = { - address: 'address2', - alias: 'alias2' -}; - -const mockAppliedOperation: ActivityInterface = { - id: 0, - type: ActivityTypeEnum.Transaction, - status: ActivityStatusEnum.Applied, - hash: 'hash1', - amount: '0', - address: 'address1', - timestamp: 1, - entrypoint: 'transfer', - source: mockMember, - destination: { - address: 'address1', - alias: 'alias1' - } -}; - -const mockPendingOperation: ActivityInterface = { - id: 1, - type: ActivityTypeEnum.Transaction, - status: ActivityStatusEnum.Pending, - hash: 'hash2', - amount: '1', - timestamp: 10, - entrypoint: '', - source: mockMember, - destination: { - address: 'address3', - alias: 'alias3' - } -}; - -const mockAppliedDelegationOperation: ActivityInterface = { - id: 2, - type: ActivityTypeEnum.Delegation, - status: ActivityStatusEnum.Applied, - hash: 'hash3', - amount: '0', - timestamp: 6, - source: mockMember, - destination: { - address: 'address3', - alias: 'alias3' - } -}; - -const mockPendingTransfer: TzktTokenTransfer = { - id: 221390075, - level: 2330482, - timestamp: '2022-05-02T11:46:59Z', - token: { - id: 85, - contract: { alias: 'kUSD', address: 'KT1K9gCRgaLRFKTErYt1wVxA3Frb9FjasjTV' }, - tokenId: '0', - standard: 'fa1.2', - metadata: { name: 'Kolibri USD', symbol: 'kUSD', decimals: '18' } - }, - from: { address: 'tz1VvDQcafAxpAcc2hFWDpSmRYqdEmEhrW1h' }, - to: { alias: 'QuipuSwap kUSD', address: 'KT1K4EwTpbvYN9agJdjpyJm4ZZdhpUNKB3F6' }, - amount: '434827741374364513', - transactionId: 221390021 -}; - -const mockAppliedTransfer: TzktTokenTransfer = { - id: 221390075, - level: 2330482, - timestamp: '2022-05-02T11:46:59Z', - token: { - id: 85, - contract: { alias: 'kUSD', address: 'KT1K9gCRgaLRFKTErYt1wVxA3Frb9FjasjTV' }, - tokenId: '0', - standard: 'fa1.2', - metadata: { name: 'Kolibri USD', symbol: 'kUSD', decimals: '18' } - }, - from: { address: 'tz1VvDQcafAxpAcc2hFWDpSmRYqdEmEhrW1h' }, - to: { alias: 'QuipuSwap kUSD', address: 'KT1K4EwTpbvYN9agJdjpyJm4ZZdhpUNKB3F6' }, - amount: '434827741374364513', - transactionId: 221390021 -}; - -export const mockOperations: Array = [ - mockAppliedOperation, - mockPendingOperation, - mockAppliedDelegationOperation -]; - -export const mockTransfers: Array = [mockPendingTransfer, mockAppliedTransfer]; - -export const mockActivitiesWithoutMatchedAddress: Array = [ - { - amount: 'contractBalance', - destination: { - address: 'address0', - alias: 'alias0' - }, - entrypoint: 'transfer', - hash: 'hash', - source: { - address: 'address1', - alias: 'alias1' - }, - id: 2, - level: undefined, - status: ActivityStatusEnum.Applied, - timestamp: 1628380800000, - type: ActivityTypeEnum.Origination, - reciever: { address: '' } - } -]; - -export const mockActivitiesWithMatchedAddress: Array = [ - { - amount: '-1', - destination: { address: 'address4', alias: 'alias4' }, - entrypoint: 'transfer', - hash: 'hash', - id: 0, - level: undefined, - source: { address: 'address1', alias: 'alias1' }, - status: ActivityStatusEnum.Applied, - timestamp: 1628380800000, - type: ActivityTypeEnum.Transaction, - reciever: { address: 'address4' } - }, - { - amount: '-0', - destination: { address: 'address7', alias: 'alias7' }, - entrypoint: 'transfer', - hash: 'hash', - id: 1, - level: undefined, - source: { address: 'address1', alias: 'alias1' }, - status: ActivityStatusEnum.Applied, - timestamp: 1628380800000, - type: ActivityTypeEnum.Delegation, - reciever: { address: '' } - }, - { - amount: '-contractBalance', - destination: { address: 'address0', alias: 'alias0' }, - entrypoint: 'transfer', - hash: 'hash', - id: 2, - level: undefined, - source: { address: 'address1', alias: 'alias1' }, - status: ActivityStatusEnum.Applied, - timestamp: 1628380800000, - type: ActivityTypeEnum.Origination, - reciever: { address: '' } - } -]; diff --git a/src/interfaces/activity.interface.ts b/src/interfaces/activity.interface.ts index a1d44ca07..f82a5e1d6 100644 --- a/src/interfaces/activity.interface.ts +++ b/src/interfaces/activity.interface.ts @@ -1,34 +1,17 @@ -import { Activity } from '@temple-wallet/transactions-parser'; +import { Activity, ActivityType, TzktOperationStatus } from '@temple-wallet/transactions-parser'; +import { BigNumber } from 'bignumber.js'; -import { ActivityStatusEnum } from '../enums/activity-status.enum'; -import { ActivityTypeEnum } from '../enums/activity-type.enum'; -import { emptyMember, MemberInterface } from './member.interface'; - -export interface ActivityInterface { - type: ActivityTypeEnum; - status: ActivityStatusEnum; - hash: string; - amount: string; - address?: string; - id: number; - tokenId?: string; - timestamp: number; - entrypoint?: string; - source: MemberInterface; - destination: MemberInterface; - reciever?: MemberInterface; - level?: number; -} +import { emptyMember } from './member.interface'; export type ActivityGroup = Array; -export const emptyActivity: ActivityInterface = { - type: ActivityTypeEnum.Transaction, - status: ActivityStatusEnum.Pending, +export const emptyActivity: Activity = { + type: ActivityType.Send, + status: TzktOperationStatus.Applied, hash: '', - amount: '', + tokensDeltas: [{ atomicAmount: new BigNumber(0), tokenSlug: 'tez' }], id: 0, - timestamp: 0, - source: emptyMember, - destination: emptyMember + timestamp: '', + from: emptyMember, + to: emptyMember }; diff --git a/src/interfaces/member.interface.ts b/src/interfaces/member.interface.ts index 2296cbc69..496be0364 100644 --- a/src/interfaces/member.interface.ts +++ b/src/interfaces/member.interface.ts @@ -1,8 +1,5 @@ -export interface MemberInterface { - address: string; - alias?: string; -} +import { TzktMemberInterface } from '@temple-wallet/transactions-parser'; -export const emptyMember: MemberInterface = { +export const emptyMember: TzktMemberInterface = { address: '' }; diff --git a/src/interfaces/operation.interface.mock.ts b/src/interfaces/operation.interface.mock.ts deleted file mode 100644 index d67406550..000000000 --- a/src/interfaces/operation.interface.mock.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { ActivityStatusEnum } from '../enums/activity-status.enum'; -import { ActivityTypeEnum } from '../enums/activity-type.enum'; -import { OperationInterface } from './operation.interface'; - -const mockMember = { - address: 'address1', - alias: 'alias1' -}; - -const mockTarget = { - address: 'address4', - alias: 'alias4' -}; - -export const mockOperations: Array = [ - { - id: 0, - entrypoint: 'transfer', - type: ActivityTypeEnum.Transaction, - status: ActivityStatusEnum.Applied, - hash: 'hash', - block: 'block', - amount: 1, - timestamp: new Date(2021, 7, 8, 0, 0, 0).toISOString(), - hasInternals: true, - contractBalance: 'contractBalance', - sender: mockMember, - target: mockTarget, - newDelegate: { - address: 'address5', - alias: 'alias5' - }, - originatedContract: { - address: 'address6', - alias: 'alias6' - } - }, - { - id: 1, - entrypoint: 'transfer', - type: ActivityTypeEnum.Delegation, - status: ActivityStatusEnum.Applied, - hash: 'hash', - block: 'block', - amount: 1, - timestamp: new Date(2021, 7, 8, 0, 0, 0).toISOString(), - hasInternals: true, - contractBalance: 'contractBalance', - sender: mockMember, - target: mockTarget, - newDelegate: { - address: 'address7', - alias: 'alias7' - }, - originatedContract: { - address: 'address8', - alias: 'alias8' - } - }, - { - id: 2, - entrypoint: 'transfer', - type: ActivityTypeEnum.Origination, - status: ActivityStatusEnum.Applied, - hash: 'hash', - block: 'block', - amount: 1, - timestamp: new Date(2021, 7, 8, 0, 0, 0).toISOString(), - hasInternals: true, - contractBalance: 'contractBalance', - sender: mockMember, - target: { - address: 'address4', - alias: 'alias4' - }, - newDelegate: { - address: 'address9', - alias: 'alias9' - }, - originatedContract: { - address: 'address0', - alias: 'alias0' - } - } -]; diff --git a/src/interfaces/operation.interface.ts b/src/interfaces/operation.interface.ts deleted file mode 100644 index 885bf8ebf..000000000 --- a/src/interfaces/operation.interface.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { ActivityStatusEnum } from '../enums/activity-status.enum'; -import { ActivityTypeEnum } from '../enums/activity-type.enum'; -import { MemberInterface } from './member.interface'; - -export interface OperationInterface { - id: number; - type: ActivityTypeEnum; - status: ActivityStatusEnum; - hash: string; - block: string; - amount: number; - level?: number; - timestamp: string; - entrypoint: string; - parameter?: unknown; - hasInternals?: boolean; - contractBalance?: string; - sender: MemberInterface; - target: MemberInterface; - newDelegate?: MemberInterface; - originatedContract?: MemberInterface; -} - -interface Fa2Transaction { - to_: string; - amount: string; - token_id: string; -} - -interface Fa2OpParams { - txs: Array; - from_: 'tz1h85hgb9hk4MmLuouLcWWna4wBLtqCq4Ta'; -} - -export type ParameterFa12 = { - entrypoint: string; - value: { - to: string; - from: string; - value: string; - }; -}; - -export type ParameterLiquidityBaking = { - entrypoint: string; - value: { - target: string; - quantity: string; // can be 'number' or '-number - }; -}; - -export interface OperationFa12Interface extends OperationInterface { - parameter: ParameterFa12; -} - -export interface OperationLiquidityBakingInterface extends OperationInterface { - parameter: ParameterLiquidityBaking | ParameterFa12; -} - -export type ParamterFa2 = { - entrypoint: string; - value: Array; -}; - -export interface OperationFa2Interface extends OperationInterface { - parameter: ParamterFa2; -} diff --git a/src/interfaces/transfer.interface.mock.ts b/src/interfaces/transfer.interface.mock.ts deleted file mode 100644 index 698c1b47b..000000000 --- a/src/interfaces/transfer.interface.mock.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { ActivityStatusEnum } from '../enums/activity-status.enum'; -import { TransferInterface } from './transfer.interface'; - -export const mockSenderAddress = 'mockSenderAddress'; -export const mockReceiverAddress = 'mockReceiverAddress'; - -export const mockAppliedTransfer: TransferInterface = { - contract: 'mockContractAddress', - token_id: 777, - status: ActivityStatusEnum.Applied, - amount: '100', - hash: 'mockTransferHash', - timestamp: 'mockTransferTimestamp', - from: mockSenderAddress, - to: mockReceiverAddress, - alias: 'mockAlias' -}; diff --git a/src/interfaces/transfer.interface.ts b/src/interfaces/transfer.interface.ts deleted file mode 100644 index 6d493a7bf..000000000 --- a/src/interfaces/transfer.interface.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface TransferInterface { - contract: string; - token_id?: number; - status: string; - amount: string; - hash: string; - timestamp: string; - from: string; - to: string; - alias: string; -} diff --git a/src/interfaces/tzkt.interface.ts b/src/interfaces/tzkt.interface.ts index 4ea360cec..e769321f2 100644 --- a/src/interfaces/tzkt.interface.ts +++ b/src/interfaces/tzkt.interface.ts @@ -3,31 +3,6 @@ interface TzktAlias { address: string; } -export interface TzktTokenTransfer { - amount: string; - from?: TzktAlias; - id: number; - level: number; - timestamp: string; - to: TzktAlias; - token: { - contract: TzktAlias; - id: number; - metadata: { - name: string; - symbol: string; - decimals: string; - thumbnailUri?: string; - eth_name?: string; - eth_symbol?: string; - eth_contract?: string; - }; - standard: string; - tokenId: string; - }; - transactionId: number; -} - export interface TzktAccountTokenBalance { account: TzktAlias; balance: string; diff --git a/src/screens/activity/activity.tsx b/src/screens/activity/activity.tsx index 741d3630f..a5f41e8d6 100644 --- a/src/screens/activity/activity.tsx +++ b/src/screens/activity/activity.tsx @@ -7,7 +7,6 @@ import { usePageAnalytic } from '../../utils/analytics/use-analytics.hook'; export const Activity = () => { const { activities, handleUpdate } = useContractActivity(); - console.log('activities: ', activities); usePageAnalytic(ScreensEnum.Activity); diff --git a/src/store/baking/baking-selectors.ts b/src/store/baking/baking-selectors.ts index ed248a61c..89963eaaa 100644 --- a/src/store/baking/baking-selectors.ts +++ b/src/store/baking/baking-selectors.ts @@ -1,4 +1,8 @@ +import { useMemo } from 'react'; + import { BakerInterface, emptyBaker } from 'src/apis/baking-bad'; +import { EVERSTAKE_PAYOUTS_BAKER } from 'src/apis/baking-bad/consts'; +import { isDefined } from 'src/utils/is-defined'; import { useSelector } from '../selector'; @@ -11,4 +15,26 @@ export const useSelectedBakerSelector = (): [BakerInterface, boolean] => { export const useBakersListSelector = () => useSelector(state => state.baking.bakersList.data); +export const useBakerByAddressSelector = ( + address: string +): Pick | undefined => { + const bakers = useSelector(state => state.baking.bakersList.data); + + return useMemo(() => { + if (address === EVERSTAKE_PAYOUTS_BAKER.address) { + return EVERSTAKE_PAYOUTS_BAKER; + } + + const baker = bakers.find(baker => baker.address === address); + + if (isDefined(baker)) { + return { + address: baker.address, + name: baker.name, + logo: baker.logo + }; + } + }, [bakers]); +}; + export const useBakerRewardsListSelector = () => useSelector(state => state.baking.bakerRewardsList.data); diff --git a/src/store/wallet/wallet-reducers.ts b/src/store/wallet/wallet-reducers.ts index a6657af5c..c6d17a8d2 100644 --- a/src/store/wallet/wallet-reducers.ts +++ b/src/store/wallet/wallet-reducers.ts @@ -192,9 +192,7 @@ export const walletReducers = createReducer(walletInitialState, bui isVisible: undefined, tezosBalance: undefined, tokensList: undefined, - removedTokensList: undefined, - activityGroups: undefined, - pendingActivities: undefined + removedTokensList: undefined }); } diff --git a/src/store/wallet/wallet-selectors.ts b/src/store/wallet/wallet-selectors.ts index bb38039f8..6c4768701 100644 --- a/src/store/wallet/wallet-selectors.ts +++ b/src/store/wallet/wallet-selectors.ts @@ -107,11 +107,6 @@ export const useCollectiblesListSelector = () => { return useMemo(() => assetsList.filter(asset => isCollectible(asset) && isNonZeroBalance(asset)), [assetsList]); }; -export const useCollectibleBySlugSelector = (slug: string): TokenInterface | undefined => { - const assetsList = useAssetsListSelector(); - - return useMemo(() => assetsList.find(asset => isCollectible(asset) && getTokenSlug(asset) === slug), [assetsList]); -}; export const useVisibleCollectiblesListSelector = () => { const collectiblesList = useCollectiblesListSelector(); diff --git a/src/utils/activity.spec.ts b/src/utils/activity.spec.ts deleted file mode 100644 index d60ef7977..000000000 --- a/src/utils/activity.spec.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { mockOperations, mockTransfers } from '../interfaces/activity.interface.mock'; -import { groupActivitiesByHash } from './activity.utils'; - -describe('groupActivitiesByHash', () => { - it('should sort operations and transfers by timestamp in descending order', () => { - expect(groupActivitiesByHash(mockOperations, [], [], mockTransfers.slice(1))).toMatchSnapshot(); - }); - - it('should push operations and transfers with the same hash into one group and not mutate activities', () => { - expect(groupActivitiesByHash(mockOperations, [], [], mockTransfers)).toMatchSnapshot(); - }); -}); diff --git a/src/utils/activity.utils.ts b/src/utils/activity.utils.ts deleted file mode 100644 index e48e3f1d3..000000000 --- a/src/utils/activity.utils.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ActivityTypeEnum } from '../enums/activity-type.enum'; -import { ActivityGroup, ActivityInterface, emptyActivity } from '../interfaces/activity.interface'; -import { TzktTokenTransfer } from '../interfaces/tzkt.interface'; -import { isDefined } from './is-defined'; - -export const groupActivitiesByHash = ( - operations: Array, - fa12Operations: Array, - fa2Operations: Array, - transfers: Array -) => { - const allOperations = [...fa12Operations, ...fa2Operations, ...operations].sort( - (b, a) => a.level ?? 0 - (b.level ?? 0) - ); - - const enrichedOperations: Array = allOperations.map(operation => { - if (operation.type === ActivityTypeEnum.Transaction) { - const foundTransfer = transfers.find(transfer => transfer.transactionId === operation.id); - if (isDefined(foundTransfer)) { - return { - ...operation, - address: foundTransfer.token.contract.address, - id: Number(foundTransfer.token.tokenId) ?? 0, - amount: foundTransfer.amount - }; - } - } - - return operation; - }); - - return transformActivityInterfaceToActivityGroups(enrichedOperations); -}; - -const transformActivityInterfaceToActivityGroups = (activites: ActivityInterface[]) => { - const result: ActivityGroup[] = []; - - const activities = activites.sort((a, b) => b.timestamp - a.timestamp); - let prevActivity: ActivityInterface = emptyActivity; - - for (const activity of activities) { - if (activity.hash === prevActivity.hash) { - result[result.length - 1].push(activity); - } else { - result.push([activity]); - } - - prevActivity = activity; - } - - return result; -}; diff --git a/src/utils/operation.utils.ts b/src/utils/operation.utils.ts deleted file mode 100644 index 77a6221ac..000000000 --- a/src/utils/operation.utils.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { BigNumber } from 'bignumber.js'; - -import { ActivityTypeEnum } from '../enums/activity-type.enum'; -import { ActivityInterface } from '../interfaces/activity.interface'; -import { MemberInterface } from '../interfaces/member.interface'; -import { - OperationInterface, - ParameterFa12, - ParameterLiquidityBaking, - ParamterFa2 -} from '../interfaces/operation.interface'; -import { isDefined } from './is-defined'; -import { stringToActivityStatusEnum } from './string-to-activity-status-enum.util'; - -export const mapOperationsToActivities = (address: string, operations: Array) => { - const activities: Array = []; - - for (const operation of operations) { - const { - id, - type, - status, - hash, - timestamp, - entrypoint, - contractBalance, - sender, - target, - level, - newDelegate, - originatedContract, - parameter - } = operation; - - const source = sender; - let destination: MemberInterface = { address: '' }; - const reciever: MemberInterface = { address: '' }; - let amount = '0'; - let tokenId = null; - let contractAddress = null; - - switch (type) { - case ActivityTypeEnum.Transaction: - destination = target; - amount = operation.amount.toString(); - const fa2Parameter = parameter as ParamterFa2; - const fa12Parameter = parameter as ParameterFa12; - const bakingParameter = parameter as ParameterLiquidityBaking; - - if ( - isDefined(fa2Parameter) && - fa2Parameter.value.length > 0 && - Array.isArray(fa2Parameter.value) && - isDefined(fa2Parameter.value[0].txs) - ) { - contractAddress = target.address; - let isUserSenderOrReceiverOfFa2Operation = false; - if (fa2Parameter.value[0].from_ === address) { - amount = fa2Parameter.value[0].txs.reduce((acc, tx) => acc.plus(tx.amount), new BigNumber(0)).toFixed(); - source.address = address; - isUserSenderOrReceiverOfFa2Operation = true; - tokenId = fa2Parameter.value[0].txs[0].token_id; - reciever.address = fa2Parameter.value[0].txs[0].to_; - } - for (const param of fa2Parameter.value) { - const val = param.txs.find(tx => { - return tx.to_ === address && (amount = tx.amount); - }); - if (isDefined(val)) { - isUserSenderOrReceiverOfFa2Operation = true; - amount = val.amount; - tokenId = val.token_id; - } - } - if (!isUserSenderOrReceiverOfFa2Operation) { - continue; - } - } else if (isDefined(fa12Parameter) && isDefined(fa12Parameter.value.value)) { - if (fa12Parameter.entrypoint === 'approve') { - continue; - } - if (isDefined(fa12Parameter.value.from) || isDefined(fa12Parameter.value.to)) { - reciever.address = fa12Parameter.value.to; - if (fa12Parameter.value.from === address) { - source.address = address; - } else if (fa12Parameter.value.to === address) { - source.address = fa12Parameter.value.from; - } else { - continue; - } - } - contractAddress = target.address; - amount = fa12Parameter.value.value; - } else if (isDefined(bakingParameter) && isDefined(bakingParameter.value.quantity)) { - contractAddress = target.address; - const tokenOrTezAmount = - isDefined(parameter) && isDefined((parameter as ParameterFa12).value.value) - ? (parameter as ParameterFa12).value.value - : amount.toString(); - amount = - isDefined(parameter) && isDefined((parameter as ParameterLiquidityBaking).value.quantity) - ? (parameter as ParameterLiquidityBaking).value.quantity - : target.address === address || - (isDefined(parameter) && (parameter as ParameterFa12).value.to === address) - ? tokenOrTezAmount - : `-${tokenOrTezAmount}`; - } else { - reciever.address = target.address; - } - if ( - !isDefined(operation.parameter) && - operation.target.address !== address && - operation.sender.address !== address - ) { - continue; - } - break; - - case ActivityTypeEnum.Delegation: - if (address !== source.address) { - continue; - } - isDefined(newDelegate) && (destination = newDelegate); - break; - - case ActivityTypeEnum.Origination: - isDefined(originatedContract) && (destination = originatedContract); - isDefined(contractBalance) && (amount = contractBalance.toString()); - break; - - default: - continue; - } - - activities.push({ - ...(isDefined(tokenId) ? { tokenId } : {}), - ...(isDefined(contractAddress) ? { address: contractAddress } : {}), - id, - type, - hash, - status: stringToActivityStatusEnum(status), - source, - entrypoint, - level, - destination, - reciever, - amount: source.address === address ? `-${amount}` : amount, - timestamp: new Date(timestamp).getTime() - }); - } - - return activities; -}; diff --git a/src/utils/operations.utils.spec.ts b/src/utils/operations.utils.spec.ts deleted file mode 100644 index 9d2dfd76d..000000000 --- a/src/utils/operations.utils.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { - mockActivitiesWithMatchedAddress, - mockActivitiesWithoutMatchedAddress -} from '../interfaces/activity.interface.mock'; -import { mockOperations } from '../interfaces/operation.interface.mock'; -import { mapOperationsToActivities } from './operation.utils'; - -describe('mapOperationsToActivities', () => { - it('map operations to activity, expecting operations array. Using transaction, delegation and origination types in array', () => { - expect(mapOperationsToActivities('address1', mockOperations)).toEqual(mockActivitiesWithMatchedAddress); - }); - - it('map operations to activity with address, which does not maches with target address', () => { - expect(mapOperationsToActivities('address12', mockOperations)).toEqual(mockActivitiesWithoutMatchedAddress); - }); - - it('map operations to activity with empty address', () => { - expect(mapOperationsToActivities('', mockOperations)).toEqual(mockActivitiesWithoutMatchedAddress); - }); -}); diff --git a/src/utils/string-to-activity-status-enum.util.ts b/src/utils/string-to-activity-status-enum.util.ts deleted file mode 100644 index baac63298..000000000 --- a/src/utils/string-to-activity-status-enum.util.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ActivityStatusEnum } from '../enums/activity-status.enum'; - -export const stringToActivityStatusEnum = (status: string): ActivityStatusEnum => { - switch (status) { - case 'applied': - return ActivityStatusEnum.Applied; - case 'backtracked': - return ActivityStatusEnum.Backtracked; - case 'skipped': - return ActivityStatusEnum.Skipped; - case 'failed': - return ActivityStatusEnum.Failed; - case 'pending': - return ActivityStatusEnum.Pending; - default: - return ActivityStatusEnum.Pending; - } -}; diff --git a/src/utils/token-operations.util.ts b/src/utils/token-operations.util.ts index c4090649e..a7440f3dc 100644 --- a/src/utils/token-operations.util.ts +++ b/src/utils/token-operations.util.ts @@ -1,13 +1,12 @@ import { Activity, TzktMemberInterface, TzktOperation, parseTransactions } from '@temple-wallet/transactions-parser'; import { LiquidityBakingMintOrBurnInterface } from '@temple-wallet/transactions-parser/dist/types/liquidity-baking'; import { Fa12TransferInterface, Fa2TransferInterface } from '@temple-wallet/transactions-parser/dist/types/transfers'; -import { uniq } from 'lodash-es'; +import { isEmpty, uniq } from 'lodash-es'; import { getTzktApi } from '../api.service'; import { OPERATION_LIMIT } from '../config/general'; import { ActivityTypeEnum } from '../enums/activity-type.enum'; import { AccountInterface } from '../interfaces/account.interface'; -import { ActivityInterface } from '../interfaces/activity.interface'; import { TokenTypeEnum } from '../interfaces/token-type.enum'; import { LIQUIDITY_BAKING_DEX_ADDRESS } from '../token/data/token-slugs'; import { TEZ_TOKEN_SLUG } from '../token/data/tokens-metadata'; @@ -20,12 +19,7 @@ const getOperationGroupByHash = (selectedRpcUrl: string, hash: string) => getTzktApi(selectedRpcUrl).get>(`operations/${hash}`); // LIQUIDITY BAKING ACTIVITY -const getContractOperations = ( - selectedRpcUrl: string, - account: string, - contractAddress: string, - lastLevel?: number -) => +const getContractOperations = (selectedRpcUrl: string, account: string, contractAddress: string) => getTzktApi(selectedRpcUrl) .get>(`accounts/${contractAddress}/operations`, { params: { @@ -33,19 +27,12 @@ const getContractOperations = ( limit: OPERATION_LIMIT, sort: '1', initiator: account, - entrypoint: 'mintOrBurn', - ...(isDefined(lastLevel) ? { 'level.lt': lastLevel } : undefined) + entrypoint: 'mintOrBurn' } }) .then(x => x.data); -const getTokenFa2Operations = ( - selectedRpcUrl: string, - account: string, - contractAddress: string, - tokenId = '0', - lastLevel?: number -) => +const getTokenFa2Operations = (selectedRpcUrl: string, account: string, contractAddress: string, tokenId = '0') => getTzktApi(selectedRpcUrl) .get>('operations/transactions', { params: { @@ -53,13 +40,12 @@ const getTokenFa2Operations = ( entrypoint: 'transfer', 'sort.desc': 'level', target: contractAddress, - 'parameter.[*].in': `[{"from_":"${account}","txs":[{"token_id":"${tokenId}"}]},{"txs":[{"to_":"${account}","token_id":"${tokenId}"}]}]`, - ...(isDefined(lastLevel) ? { 'level.lt': lastLevel } : undefined) + 'parameter.[*].in': `[{"from_":"${account}","txs":[{"token_id":"${tokenId}"}]},{"txs":[{"to_":"${account}","token_id":"${tokenId}"}]}]` } }) .then(x => x.data); -const getTokenFa12Operations = (selectedRpcUrl: string, account: string, contractAddress: string, lastLevel?: number) => +const getTokenFa12Operations = (selectedRpcUrl: string, account: string, contractAddress: string) => getTzktApi(selectedRpcUrl) .get>('operations/transactions', { params: { @@ -67,8 +53,7 @@ const getTokenFa12Operations = (selectedRpcUrl: string, account: string, contrac entrypoint: 'transfer', 'sort.desc': 'level', target: contractAddress, - 'parameter.in': `[{"from":"${account}"},{"to":"${account}"}]`, - ...(isDefined(lastLevel) ? { 'level.lt': lastLevel } : undefined) + 'parameter.in': `[{"from":"${account}"},{"to":"${account}"}]` } }) .then(x => x.data); @@ -157,7 +142,7 @@ const loadOperations = async ( selectedRpcUrl: string, selectedAccount: AccountInterface, tokenSlug?: string, - lastItem?: ActivityInterface + lastItem?: Activity ): Promise> => { const [contractAddress, tokenId] = (tokenSlug ?? '').split('_'); @@ -170,8 +155,7 @@ const loadOperations = async ( return getContractOperations( selectedRpcUrl, selectedAccount.publicKeyHash, - contractAddress, - lastItem?.level + contractAddress ); } @@ -180,17 +164,11 @@ const loadOperations = async ( const tokenType = getTokenType(contract); if (tokenType === TokenTypeEnum.FA_1_2) { - return getTokenFa12Operations(selectedRpcUrl, selectedAccount.publicKeyHash, contractAddress, lastItem?.level); + return getTokenFa12Operations(selectedRpcUrl, selectedAccount.publicKeyHash, contractAddress); } if (tokenType === TokenTypeEnum.FA_2) { - return getTokenFa2Operations( - selectedRpcUrl, - selectedAccount.publicKeyHash, - contractAddress, - tokenId, - lastItem?.level - ); + return getTokenFa2Operations(selectedRpcUrl, selectedAccount.publicKeyHash, contractAddress, tokenId); } } @@ -202,7 +180,7 @@ export const loadActivity = async ( selectedAccount: AccountInterface, tokenSlug?: string, knownBakers?: Array, - lastItem?: ActivityInterface + lastItem?: Activity ): Promise>> => { const operationsHashes = await loadOperations(selectedRpcUrl, selectedAccount, tokenSlug, lastItem) .then(operations => operations.map(operation => operation.hash)) @@ -216,7 +194,7 @@ export const loadActivity = async ( await sleep(100); } - const result = operationGroups.map(group => parseTransactions(group, selectedAccount.publicKeyHash, knownBakers)); - - return result; + return operationGroups + .map(group => parseTransactions(group, selectedAccount.publicKeyHash, knownBakers)) + .filter(group => !isEmpty(group)); }; diff --git a/src/utils/transfer.utils.spec.ts b/src/utils/transfer.utils.spec.ts deleted file mode 100644 index 8b6f61c76..000000000 --- a/src/utils/transfer.utils.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { TransferInterface } from '../interfaces/transfer.interface'; -import { mockAppliedTransfer, mockReceiverAddress, mockSenderAddress } from '../interfaces/transfer.interface.mock'; -import { mapTransfersToActivities } from './transfer.utils'; - -describe('mapTransfersToActivities', () => { - it('should set contract address & alias as source if there is no sender', () => { - const mockAppliedTransferWithoutSender: TransferInterface = { - ...mockAppliedTransfer, - from: '' - }; - - const result = mapTransfersToActivities(mockReceiverAddress, [mockAppliedTransferWithoutSender]); - - expect(result[0].source.address).toEqual(mockAppliedTransferWithoutSender.contract); - expect(result[0].source.alias).toEqual(mockAppliedTransferWithoutSender.alias); - }); - it('should set 0 as default token id', () => { - const mockAppliedTransferWithoutTokenId: TransferInterface = { - ...mockAppliedTransfer, - token_id: undefined - }; - - expect(mapTransfersToActivities(mockReceiverAddress, [mockAppliedTransfer])[0].id).toEqual( - mockAppliedTransfer.token_id - ); - expect(mapTransfersToActivities(mockReceiverAddress, [mockAppliedTransferWithoutTokenId])[0].id).toEqual(0); - }); - it('should correctly map sent amount sign for sender & receiver', () => { - expect(mapTransfersToActivities(mockReceiverAddress, [mockAppliedTransfer])[0].amount).toEqual( - mockAppliedTransfer.amount - ); - expect(mapTransfersToActivities(mockSenderAddress, [mockAppliedTransfer])[0].amount).toEqual( - `-${mockAppliedTransfer.amount}` - ); - }); -}); diff --git a/src/utils/transfer.utils.ts b/src/utils/transfer.utils.ts deleted file mode 100644 index a8f90e732..000000000 --- a/src/utils/transfer.utils.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { ActivityTypeEnum } from '../enums/activity-type.enum'; -import { ActivityInterface } from '../interfaces/activity.interface'; -import { MemberInterface } from '../interfaces/member.interface'; -import { TransferInterface } from '../interfaces/transfer.interface'; -import { isDefined } from './is-defined'; -import { stringToActivityStatusEnum } from './string-to-activity-status-enum.util'; - -export const mapTransfersToActivities = (address: string, transfers: TransferInterface[]) => { - const activities: ActivityInterface[] = []; - - for (const transfer of transfers) { - const { contract, token_id, status, amount, hash, timestamp, from, to, alias } = transfer; - const source: MemberInterface = { address: from }; - const destination: MemberInterface = { address: to }; - - if (from === '') { - source.address = contract; - isDefined(alias) && (source.alias = alias); - } - - activities.push({ - hash, - source, - status: stringToActivityStatusEnum(status), - destination, - address: contract, - id: token_id ?? 0, - type: ActivityTypeEnum.Transaction, - amount: source.address === address ? `-${amount}` : amount, - timestamp: new Date(timestamp).getTime() - }); - } - - return activities; -}; From a27e35c78b8307fe3e45e3f7fb6074b3f2ece933 Mon Sep 17 00:00:00 2001 From: herkoss Date: Mon, 7 Aug 2023 11:17:59 +0300 Subject: [PATCH 10/43] TW-786 Fixed snapshot --- src/utils/__snapshots__/activity.spec.ts.snap | 125 ------------------ 1 file changed, 125 deletions(-) delete mode 100644 src/utils/__snapshots__/activity.spec.ts.snap diff --git a/src/utils/__snapshots__/activity.spec.ts.snap b/src/utils/__snapshots__/activity.spec.ts.snap deleted file mode 100644 index bf46fcdc6..000000000 --- a/src/utils/__snapshots__/activity.spec.ts.snap +++ /dev/null @@ -1,125 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`groupActivitiesByHash should push operations and transfers with the same hash into one group and not mutate activities 1`] = ` -Array [ - Array [ - Object { - "amount": "1", - "destination": Object { - "address": "address3", - "alias": "alias3", - }, - "entrypoint": "", - "hash": "hash2", - "id": 1, - "source": Object { - "address": "address2", - "alias": "alias2", - }, - "status": "pending", - "timestamp": 10, - "type": "transaction", - }, - ], - Array [ - Object { - "amount": "0", - "destination": Object { - "address": "address3", - "alias": "alias3", - }, - "hash": "hash3", - "id": 2, - "source": Object { - "address": "address2", - "alias": "alias2", - }, - "status": "applied", - "timestamp": 6, - "type": "delegation", - }, - ], - Array [ - Object { - "address": "address1", - "amount": "0", - "destination": Object { - "address": "address1", - "alias": "alias1", - }, - "entrypoint": "transfer", - "hash": "hash1", - "id": 0, - "source": Object { - "address": "address2", - "alias": "alias2", - }, - "status": "applied", - "timestamp": 1, - "type": "transaction", - }, - ], -] -`; - -exports[`groupActivitiesByHash should sort operations and transfers by timestamp in descending order 1`] = ` -Array [ - Array [ - Object { - "amount": "1", - "destination": Object { - "address": "address3", - "alias": "alias3", - }, - "entrypoint": "", - "hash": "hash2", - "id": 1, - "source": Object { - "address": "address2", - "alias": "alias2", - }, - "status": "pending", - "timestamp": 10, - "type": "transaction", - }, - ], - Array [ - Object { - "amount": "0", - "destination": Object { - "address": "address3", - "alias": "alias3", - }, - "hash": "hash3", - "id": 2, - "source": Object { - "address": "address2", - "alias": "alias2", - }, - "status": "applied", - "timestamp": 6, - "type": "delegation", - }, - ], - Array [ - Object { - "address": "address1", - "amount": "0", - "destination": Object { - "address": "address1", - "alias": "alias1", - }, - "entrypoint": "transfer", - "hash": "hash1", - "id": 0, - "source": Object { - "address": "address2", - "alias": "alias2", - }, - "status": "applied", - "timestamp": 1, - "type": "transaction", - }, - ], -] -`; From 3675d004c63b76dba0a10e0edf6b570ff952928f Mon Sep 17 00:00:00 2001 From: herkoss Date: Mon, 7 Aug 2023 17:33:40 +0300 Subject: [PATCH 11/43] TW-786 Fixed comments --- src/interfaces/activity.interface.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/interfaces/activity.interface.ts b/src/interfaces/activity.interface.ts index f82a5e1d6..4d4556016 100644 --- a/src/interfaces/activity.interface.ts +++ b/src/interfaces/activity.interface.ts @@ -1,6 +1,8 @@ import { Activity, ActivityType, TzktOperationStatus } from '@temple-wallet/transactions-parser'; import { BigNumber } from 'bignumber.js'; +import { TEZ_TOKEN_SLUG } from 'src/token/data/tokens-metadata'; + import { emptyMember } from './member.interface'; export type ActivityGroup = Array; @@ -9,7 +11,7 @@ export const emptyActivity: Activity = { type: ActivityType.Send, status: TzktOperationStatus.Applied, hash: '', - tokensDeltas: [{ atomicAmount: new BigNumber(0), tokenSlug: 'tez' }], + tokensDeltas: [{ atomicAmount: new BigNumber(0), tokenSlug: TEZ_TOKEN_SLUG }], id: 0, timestamp: '', from: emptyMember, From 008c282392db33dbf55100be86507742ef7cbdc4 Mon Sep 17 00:00:00 2001 From: herkoss Date: Tue, 8 Aug 2023 16:22:16 +0300 Subject: [PATCH 12/43] TW-783 wip --- .../activity-details-card/unknown-details.tsx | 51 +++++++++++++++++++ .../activity-info/activity-info.tsx | 19 ++++++- .../activity-info/unknown-info.tsx | 28 ++++++++++ .../activity-groups-list.tsx | 22 ++++++++ 4 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 src/components/activity-groups-list/activity-group-item/activity-details-card/unknown-details.tsx create mode 100644 src/components/activity-groups-list/activity-group-item/activity-info/unknown-info.tsx diff --git a/src/components/activity-groups-list/activity-group-item/activity-details-card/unknown-details.tsx b/src/components/activity-groups-list/activity-group-item/activity-details-card/unknown-details.tsx new file mode 100644 index 000000000..bb2ea86b1 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-details-card/unknown-details.tsx @@ -0,0 +1,51 @@ +import React, { FC } from 'react'; +import { View, Text } from 'react-native'; + +import { Divider } from 'src/components/divider/divider'; +import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; +import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; +import { WalletAddress } from 'src/components/wallet-address/wallet-address'; +import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { formatSize } from 'src/styles/format-size'; +import { tzktUrl } from 'src/utils/linking.util'; + +import { ActivityGroupAmountChange, TextSize } from '../activity-group-amount-change/activity-group-amount-change'; +import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; +import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; +import { ActivityGroupItemSelectors } from '../selectors'; + +export const UnknownDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ + nonZeroAmounts, + address, + hash +}) => { + const selectedRpcUrl = useSelectedRpcUrlSelector(); + const styles = useActivityDetailsStyles(); + + const commonStyles = useActivityCommonStyles(); + + return ( + <> + + Sent: + + + + + + + To: + + + + TxHash: + + + + + + + + ); +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-info/activity-info.tsx b/src/components/activity-groups-list/activity-group-item/activity-info/activity-info.tsx index 742fbaed8..0dc2edb38 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-info/activity-info.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-info/activity-info.tsx @@ -1,4 +1,5 @@ import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; +import { BigNumber } from 'bignumber.js'; import React, { FC } from 'react'; import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; @@ -7,11 +8,27 @@ import { BakingRewardsInfo } from './baking-rewards-info'; import { DelegationInfo } from './delegation-info'; import { ReceiveInfo } from './receive-info'; import { SendInfo } from './send-info'; +import { UnknownInfo } from './unknown-info'; + +const nonZeroAmounts2: NonZeroAmounts = { + amounts: [ + { + parsedAmount: new BigNumber(888), + isPositive: true, + symbol: 'XTZ', + exchangeRate: 0.89 + } + ], + dollarSums: [new BigNumber(888)] +}; export const ActivityInfo: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = ({ activity, nonZeroAmounts }) => { + console.log('activity.type: ', activity.type); + console.log('activity.to: ', activity.to); + switch (activity.type) { case ActivityType.Send: return ; @@ -23,6 +40,6 @@ export const ActivityInfo: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmoun return ; default: - return null; + return ; } }; diff --git a/src/components/activity-groups-list/activity-group-item/activity-info/unknown-info.tsx b/src/components/activity-groups-list/activity-group-item/activity-info/unknown-info.tsx new file mode 100644 index 000000000..c3d431d08 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-info/unknown-info.tsx @@ -0,0 +1,28 @@ +import React, { FC } from 'react'; +import { View, Text } from 'react-native'; + +import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; + +import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; +import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; +import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; + +export const UnknownInfo: FC<{ nonZeroAmounts: NonZeroAmounts }> = ({ nonZeroAmounts }) => { + const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + + return ( + + + + Interaction + + + + - + + + + + ); +}; diff --git a/src/components/activity-groups-list/activity-groups-list.tsx b/src/components/activity-groups-list/activity-groups-list.tsx index a8739eed0..f1af02565 100644 --- a/src/components/activity-groups-list/activity-groups-list.tsx +++ b/src/components/activity-groups-list/activity-groups-list.tsx @@ -1,6 +1,10 @@ +import { TzktOperationStatus } from '@temple-wallet/transactions-parser'; +import { BigNumber } from 'bignumber.js'; import React, { FC, useMemo } from 'react'; import { SectionList, Text, View } from 'react-native'; +import { TEZ_TOKEN_SLUG } from 'src/token/data/tokens-metadata'; + import { emptyFn } from '../../config/general'; import { useFakeRefreshControlProps } from '../../hooks/use-fake-refresh-control-props.hook'; import { ActivityGroup, emptyActivity } from '../../interfaces/activity.interface'; @@ -51,6 +55,24 @@ export const ActivityGroupsList: FC = ({ prevActivityDate = date; } + result.unshift({ + title: 'Never', + data: [ + { + type: 'Unknown', + status: TzktOperationStatus.Applied, + hash: '', + tokensDeltas: [{ atomicAmount: new BigNumber(888), tokenSlug: TEZ_TOKEN_SLUG }], + id: 0, + timestamp: '', + from: { address: 'qweqweqwe' }, + to: { address: 'asdasdasd' } + } + ] as unknown as ActivityGroup[] + }); + + console.log('result: ', result); + return result; }, [activityGroups]); From b20c4a90c6d789403d990e4969906ac9c001adbf Mon Sep 17 00:00:00 2001 From: herkoss Date: Thu, 10 Aug 2023 22:16:47 +0300 Subject: [PATCH 13/43] TW-786 Fixed comments after review --- .../activity-group-item.tsx | 8 +-- .../activity-info/activity-info.tsx | 28 ----------- .../delegate.tsx} | 0 .../details-card.tsx} | 6 +-- .../receive-tokens.tsx} | 0 .../send-tokens.tsx} | 0 .../{activity-details.tsx => details.tsx} | 4 +- .../baking.tsx} | 5 +- .../delegation.tsx} | 2 +- .../activity-group-item/info/info.tsx | 25 ++++++++++ .../receive-info.tsx => info/receive.tsx} | 2 +- .../send-info.tsx => info/send.tsx} | 2 +- src/hooks/use-contract-activity.ts | 7 ++- src/hooks/use-non-zero-amounts.hook.ts | 6 +-- src/utils/token-operations.util.ts | 49 +++++++++++++++---- 15 files changed, 83 insertions(+), 61 deletions(-) delete mode 100644 src/components/activity-groups-list/activity-group-item/activity-info/activity-info.tsx rename src/components/activity-groups-list/activity-group-item/{activity-details-card/delegate-details.tsx => details-card/delegate.tsx} (100%) rename src/components/activity-groups-list/activity-group-item/{activity-details-card/activity-details-card.tsx => details-card/details-card.tsx} (83%) rename src/components/activity-groups-list/activity-group-item/{activity-details-card/receive-tokens-details.tsx => details-card/receive-tokens.tsx} (100%) rename src/components/activity-groups-list/activity-group-item/{activity-details-card/send-tokens-details.tsx => details-card/send-tokens.tsx} (100%) rename src/components/activity-groups-list/activity-group-item/{activity-details.tsx => details.tsx} (92%) rename src/components/activity-groups-list/activity-group-item/{activity-info/baking-rewards-info.tsx => info/baking.tsx} (93%) rename src/components/activity-groups-list/activity-group-item/{activity-info/delegation-info.tsx => info/delegation.tsx} (94%) create mode 100644 src/components/activity-groups-list/activity-group-item/info/info.tsx rename src/components/activity-groups-list/activity-group-item/{activity-info/receive-info.tsx => info/receive.tsx} (93%) rename src/components/activity-groups-list/activity-group-item/{activity-info/send-info.tsx => info/send.tsx} (93%) diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx index 14fe3e602..50f42694b 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx @@ -6,9 +6,9 @@ import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; import { ActivityGroup, emptyActivity } from 'src/interfaces/activity.interface'; import { formatSize } from 'src/styles/format-size'; -import { ActivityDetails } from './activity-details'; import { useActivityGroupItemStyles } from './activity-group-item.styles'; -import { ActivityInfo } from './activity-info/activity-info'; +import { Details } from './details'; +import { Info } from './info/info'; interface Props { group: ActivityGroup; @@ -21,9 +21,9 @@ export const ActivityGroupItem: FC = ({ group }) => { return ( - + - +
); }; diff --git a/src/components/activity-groups-list/activity-group-item/activity-info/activity-info.tsx b/src/components/activity-groups-list/activity-group-item/activity-info/activity-info.tsx deleted file mode 100644 index 742fbaed8..000000000 --- a/src/components/activity-groups-list/activity-group-item/activity-info/activity-info.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; -import React, { FC } from 'react'; - -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; - -import { BakingRewardsInfo } from './baking-rewards-info'; -import { DelegationInfo } from './delegation-info'; -import { ReceiveInfo } from './receive-info'; -import { SendInfo } from './send-info'; - -export const ActivityInfo: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = ({ - activity, - nonZeroAmounts -}) => { - switch (activity.type) { - case ActivityType.Send: - return ; - case ActivityType.Recieve: - return ; - case ActivityType.BakingRewards: - return ; - case ActivityType.Delegation: - return ; - - default: - return null; - } -}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-details-card/delegate-details.tsx b/src/components/activity-groups-list/activity-group-item/details-card/delegate.tsx similarity index 100% rename from src/components/activity-groups-list/activity-group-item/activity-details-card/delegate-details.tsx rename to src/components/activity-groups-list/activity-group-item/details-card/delegate.tsx diff --git a/src/components/activity-groups-list/activity-group-item/activity-details-card/activity-details-card.tsx b/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx similarity index 83% rename from src/components/activity-groups-list/activity-group-item/activity-details-card/activity-details-card.tsx rename to src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx index 633fc2177..2c7cef4ed 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-details-card/activity-details-card.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx @@ -3,9 +3,9 @@ import React, { FC } from 'react'; import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; -import { DelegateDetails } from './delegate-details'; -import { ReceiveTokensDetails } from './receive-tokens-details'; -import { SendTokensDetails } from './send-tokens-details'; +import { DelegateDetails } from './delegate'; +import { ReceiveTokensDetails } from './receive-tokens'; +import { SendTokensDetails } from './send-tokens'; export const ActivityDetailsCard: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = ({ activity, diff --git a/src/components/activity-groups-list/activity-group-item/activity-details-card/receive-tokens-details.tsx b/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx similarity index 100% rename from src/components/activity-groups-list/activity-group-item/activity-details-card/receive-tokens-details.tsx rename to src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx diff --git a/src/components/activity-groups-list/activity-group-item/activity-details-card/send-tokens-details.tsx b/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx similarity index 100% rename from src/components/activity-groups-list/activity-group-item/activity-details-card/send-tokens-details.tsx rename to src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx diff --git a/src/components/activity-groups-list/activity-group-item/activity-details.tsx b/src/components/activity-groups-list/activity-group-item/details.tsx similarity index 92% rename from src/components/activity-groups-list/activity-group-item/activity-details.tsx rename to src/components/activity-groups-list/activity-group-item/details.tsx index cb5b0f2d7..81f374ed5 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-details.tsx +++ b/src/components/activity-groups-list/activity-group-item/details.tsx @@ -9,7 +9,7 @@ import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics' import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; import { formatSize } from 'src/styles/format-size'; -import { ActivityDetailsCard } from './activity-details-card/activity-details-card'; +import { ActivityDetailsCard } from './details-card/details-card'; import { useActivityCommonStyles, useActivityDetailsStyles } from './activity-group-item.styles'; import { ActivityStatusBadge } from './activity-status-badge/activity-status-badge'; import { ActivityTime } from './activity-time/activity-time'; @@ -20,7 +20,7 @@ interface Props { nonZeroAmounts: NonZeroAmounts; } -export const ActivityDetails: FC = ({ activity, nonZeroAmounts }) => { +export const Details: FC = ({ activity, nonZeroAmounts }) => { const detailsStyles = useActivityDetailsStyles(); const commonStyles = useActivityCommonStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-info/baking-rewards-info.tsx b/src/components/activity-groups-list/activity-group-item/info/baking.tsx similarity index 93% rename from src/components/activity-groups-list/activity-group-item/activity-info/baking-rewards-info.tsx rename to src/components/activity-groups-list/activity-group-item/info/baking.tsx index 9c6de2de3..95e02890d 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-info/baking-rewards-info.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/baking.tsx @@ -14,10 +14,7 @@ import { ActivityGroupAmountChange } from '../activity-group-amount-change/activ import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; -export const BakingRewardsInfo: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ - address, - nonZeroAmounts -}) => { +export const BakingRewards: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ address, nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); const commonStyles = useActivityCommonStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-info/delegation-info.tsx b/src/components/activity-groups-list/activity-group-item/info/delegation.tsx similarity index 94% rename from src/components/activity-groups-list/activity-group-item/activity-info/delegation-info.tsx rename to src/components/activity-groups-list/activity-group-item/info/delegation.tsx index 9c1223d9d..32e8d2306 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-info/delegation-info.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/delegation.tsx @@ -11,7 +11,7 @@ import { isDefined } from 'src/utils/is-defined'; import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; -export const DelegationInfo: FC<{ address: string | undefined }> = ({ address = '' }) => { +export const Delegation: FC<{ address: string | undefined }> = ({ address = '' }) => { const styles = useActivityGroupItemStyles(); const commonStyles = useActivityCommonStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/info/info.tsx b/src/components/activity-groups-list/activity-group-item/info/info.tsx new file mode 100644 index 000000000..f560c5382 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/info/info.tsx @@ -0,0 +1,25 @@ +import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; +import React, { FC } from 'react'; + +import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; + +import { BakingRewards } from './baking'; +import { Delegation } from './delegation'; +import { Receive } from './receive'; +import { Send } from './send'; + +export const Info: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = ({ activity, nonZeroAmounts }) => { + switch (activity.type) { + case ActivityType.Send: + return ; + case ActivityType.Recieve: + return ; + case ActivityType.BakingRewards: + return ; + case ActivityType.Delegation: + return ; + + default: + return null; + } +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-info/receive-info.tsx b/src/components/activity-groups-list/activity-group-item/info/receive.tsx similarity index 93% rename from src/components/activity-groups-list/activity-group-item/activity-info/receive-info.tsx rename to src/components/activity-groups-list/activity-group-item/info/receive.tsx index 048a1a75f..79adb0b2d 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-info/receive-info.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/receive.tsx @@ -11,7 +11,7 @@ import { ActivityGroupAmountChange } from '../activity-group-amount-change/activ import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; -export const ReceiveInfo: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ address, nonZeroAmounts }) => { +export const Receive: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ address, nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); const commonStyles = useActivityCommonStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-info/send-info.tsx b/src/components/activity-groups-list/activity-group-item/info/send.tsx similarity index 93% rename from src/components/activity-groups-list/activity-group-item/activity-info/send-info.tsx rename to src/components/activity-groups-list/activity-group-item/info/send.tsx index c3f5eca50..2825071b5 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-info/send-info.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/send.tsx @@ -11,7 +11,7 @@ import { ActivityGroupAmountChange } from '../activity-group-amount-change/activ import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; -export const SendInfo: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ address, nonZeroAmounts }) => { +export const Send: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ address, nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); const commonStyles = useActivityCommonStyles(); diff --git a/src/hooks/use-contract-activity.ts b/src/hooks/use-contract-activity.ts index 1b25c31c3..b244ad20f 100644 --- a/src/hooks/use-contract-activity.ts +++ b/src/hooks/use-contract-activity.ts @@ -31,13 +31,12 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => const knownBakers = useMemo>( () => - [ - KNOWN_BAKERS, + KNOWN_BAKERS.concat( bakers.map(({ address, name }) => ({ address, alias: name })) - ].flat(), + ), [bakers] ); @@ -78,7 +77,7 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => const handleUpdate = async () => { if (activities.length > 0 && !isAllLoaded) { - const lastActivityGroup = activities[activities.length - 1].sort((a, b) => b.id - a.id); + const lastActivityGroup = activities[activities.length - 1]; if (lastActivityGroup.length > 0) { const lastItem = lastActivityGroup[lastActivityGroup.length - 1]; diff --git a/src/hooks/use-non-zero-amounts.hook.ts b/src/hooks/use-non-zero-amounts.hook.ts index e53dcd575..467f43862 100644 --- a/src/hooks/use-non-zero-amounts.hook.ts +++ b/src/hooks/use-non-zero-amounts.hook.ts @@ -24,8 +24,6 @@ interface ActivityNonZeroAmounts { dollarSums: Array; } -const DEFAULT_EXCHANGE_RATE = 1; - export const useNonZeroAmounts = (tokensDeltas: Array): ActivityNonZeroAmounts => { const dispatch = useDispatch(); const getTokenMetadata = useTokenMetadataGetter(); @@ -48,8 +46,8 @@ export const useNonZeroAmounts = (tokensDeltas: Array): ActivityNonZ const parsedAmount = mutezToTz(atomicAmount, decimals); const isPositive = parsedAmount.isPositive(); - if (isDefined(exchangeRate)) { - const summand = parsedAmount.multipliedBy(exchangeRate).multipliedBy(fiatToUsdRate ?? DEFAULT_EXCHANGE_RATE); + if (isDefined(exchangeRate) && isDefined(fiatToUsdRate)) { + const summand = parsedAmount.multipliedBy(exchangeRate).multipliedBy(fiatToUsdRate); if (isPositive) { positiveAmountSum = positiveAmountSum.plus(summand); } else { diff --git a/src/utils/token-operations.util.ts b/src/utils/token-operations.util.ts index a7440f3dc..9c03e8715 100644 --- a/src/utils/token-operations.util.ts +++ b/src/utils/token-operations.util.ts @@ -19,7 +19,12 @@ const getOperationGroupByHash = (selectedRpcUrl: string, hash: string) => getTzktApi(selectedRpcUrl).get>(`operations/${hash}`); // LIQUIDITY BAKING ACTIVITY -const getContractOperations = (selectedRpcUrl: string, account: string, contractAddress: string) => +const getContractOperations = ( + selectedRpcUrl: string, + account: string, + contractAddress: string, + lastTimestamp?: string +) => getTzktApi(selectedRpcUrl) .get>(`accounts/${contractAddress}/operations`, { params: { @@ -27,12 +32,19 @@ const getContractOperations = (selectedRpcUrl: string, account: string, contr limit: OPERATION_LIMIT, sort: '1', initiator: account, - entrypoint: 'mintOrBurn' + entrypoint: 'mintOrBurn', + ...(isDefined(lastTimestamp) ? { 'timestamp.lt': lastTimestamp } : undefined) } }) .then(x => x.data); -const getTokenFa2Operations = (selectedRpcUrl: string, account: string, contractAddress: string, tokenId = '0') => +const getTokenFa2Operations = ( + selectedRpcUrl: string, + account: string, + contractAddress: string, + tokenId = '0', + lastTimestamp?: string +) => getTzktApi(selectedRpcUrl) .get>('operations/transactions', { params: { @@ -40,12 +52,18 @@ const getTokenFa2Operations = (selectedRpcUrl: string, account: string, contract entrypoint: 'transfer', 'sort.desc': 'level', target: contractAddress, - 'parameter.[*].in': `[{"from_":"${account}","txs":[{"token_id":"${tokenId}"}]},{"txs":[{"to_":"${account}","token_id":"${tokenId}"}]}]` + 'parameter.[*].in': `[{"from_":"${account}","txs":[{"token_id":"${tokenId}"}]},{"txs":[{"to_":"${account}","token_id":"${tokenId}"}]}]`, + ...(isDefined(lastTimestamp) ? { 'timestamp.lt': lastTimestamp } : undefined) } }) .then(x => x.data); -const getTokenFa12Operations = (selectedRpcUrl: string, account: string, contractAddress: string) => +const getTokenFa12Operations = ( + selectedRpcUrl: string, + account: string, + contractAddress: string, + lastTimestamp?: string +) => getTzktApi(selectedRpcUrl) .get>('operations/transactions', { params: { @@ -53,7 +71,8 @@ const getTokenFa12Operations = (selectedRpcUrl: string, account: string, contrac entrypoint: 'transfer', 'sort.desc': 'level', target: contractAddress, - 'parameter.in': `[{"from":"${account}"},{"to":"${account}"}]` + 'parameter.in': `[{"from":"${account}"},{"to":"${account}"}]`, + ...(isDefined(lastTimestamp) ? { 'timestamp.lt': lastTimestamp } : undefined) } }) .then(x => x.data); @@ -155,7 +174,8 @@ const loadOperations = async ( return getContractOperations( selectedRpcUrl, selectedAccount.publicKeyHash, - contractAddress + contractAddress, + lastItem?.timestamp ); } @@ -164,11 +184,22 @@ const loadOperations = async ( const tokenType = getTokenType(contract); if (tokenType === TokenTypeEnum.FA_1_2) { - return getTokenFa12Operations(selectedRpcUrl, selectedAccount.publicKeyHash, contractAddress); + return getTokenFa12Operations( + selectedRpcUrl, + selectedAccount.publicKeyHash, + contractAddress, + lastItem?.timestamp + ); } if (tokenType === TokenTypeEnum.FA_2) { - return getTokenFa2Operations(selectedRpcUrl, selectedAccount.publicKeyHash, contractAddress, tokenId); + return getTokenFa2Operations( + selectedRpcUrl, + selectedAccount.publicKeyHash, + contractAddress, + tokenId, + lastItem?.timestamp + ); } } From caba37d4a8a73fdd1e44d0ba7a68f14cf89a119d Mon Sep 17 00:00:00 2001 From: herkoss Date: Fri, 11 Aug 2023 00:14:23 +0300 Subject: [PATCH 14/43] TW-786 Fixed comments after review --- .../activity-group-item/details-card/details-card.tsx | 2 +- .../activity-groups-list/activity-group-item/details.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx b/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx index 2c7cef4ed..6f7597c9e 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx @@ -7,7 +7,7 @@ import { DelegateDetails } from './delegate'; import { ReceiveTokensDetails } from './receive-tokens'; import { SendTokensDetails } from './send-tokens'; -export const ActivityDetailsCard: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = ({ +export const DetailsCard: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = ({ activity, nonZeroAmounts }) => { diff --git a/src/components/activity-groups-list/activity-group-item/details.tsx b/src/components/activity-groups-list/activity-group-item/details.tsx index 81f374ed5..ca689884e 100644 --- a/src/components/activity-groups-list/activity-group-item/details.tsx +++ b/src/components/activity-groups-list/activity-group-item/details.tsx @@ -9,10 +9,10 @@ import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics' import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; import { formatSize } from 'src/styles/format-size'; -import { ActivityDetailsCard } from './details-card/details-card'; import { useActivityCommonStyles, useActivityDetailsStyles } from './activity-group-item.styles'; import { ActivityStatusBadge } from './activity-status-badge/activity-status-badge'; import { ActivityTime } from './activity-time/activity-time'; +import { DetailsCard } from './details-card/details-card'; import { ActivityGroupItemSelectors } from './selectors'; interface Props { @@ -45,7 +45,7 @@ export const Details: FC = ({ activity, nonZeroAmounts }) => { {areDetailsVisible && ( - + )} From f24adc0aca149a74042750fd4eb66ff00a61b2e0 Mon Sep 17 00:00:00 2001 From: herkoss Date: Fri, 11 Aug 2023 16:03:00 +0300 Subject: [PATCH 15/43] TW-786 Added known bakers --- src/apis/baking-bad/consts.ts | 238 +++++++++++++++++- .../activity-group-item/info/baking.tsx | 2 +- .../activity-group-item/info/delegation.tsx | 2 +- src/hooks/use-contract-activity.ts | 23 +- src/store/baking/baking-selectors.ts | 12 +- 5 files changed, 252 insertions(+), 25 deletions(-) diff --git a/src/apis/baking-bad/consts.ts b/src/apis/baking-bad/consts.ts index d00b4978e..4bd61d452 100644 --- a/src/apis/baking-bad/consts.ts +++ b/src/apis/baking-bad/consts.ts @@ -46,8 +46,236 @@ export const mockBaker: BakerInterface = { insuranceCoverage: 44 }; -export const EVERSTAKE_PAYOUTS_BAKER = { - address: 'tz1W1en9UpMCH4ZJL8wQCh8JDKCZARyVx2co', - logo: 'https://services.tzkt.io/v1/avatars/tz1aRoaRhSpRYvFdyvgWLL6TGyRoGF51wDjM', - name: 'Everstake' -}; +export interface KnownBaker { + address: string; + name: string; + logo: string | null; +} + +export const KNOWN_BAKERS: Array = [ + { + address: 'tz1SvASb4xmkiM82ijexDHzn6bYakaReBypt', + name: 'Anonstake Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1SvASb4xmkiM82ijexDHzn6bYakaReBypt' + }, + { + address: 'tz1TqU5hwh6CtC8Ps5GYBi7YyawvtKLNCbvQ', + name: 'Ateza Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1TqU5hwh6CtC8Ps5GYBi7YyawvtKLNCbvQ' + }, + { + address: 'tz1Zrqm4TkJwqTxm5TiyVFh6taXG4Wrq7tko', + name: 'Bake’n’Rolls Payouts 2', + logo: null + }, + { + address: 'tz1iVCqjMRG7MfBoFnVjbLQyeLAeJQfLxXze', + name: 'Bakery-IL Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1iVCqjMRG7MfBoFnVjbLQyeLAeJQfLxXze' + }, + { + address: 'tz1NAozDvi5e7frVq9cUaC3uXQQannemB8Jw', + name: 'BakeTz Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1NAozDvi5e7frVq9cUaC3uXQQannemB8Jw' + }, + { + address: 'tz1PayLDWLg39fbkwKejnT3aijz4QEd5kgt3', + name: 'Baking Team Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1PayLDWLg39fbkwKejnT3aijz4QEd5kgt3' + }, + { + address: 'tz1UQvdfQ2cwyDa6k6U62mkHWeULwBqCcJwN', + name: 'Citadel.one Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1UQvdfQ2cwyDa6k6U62mkHWeULwBqCcJwN' + }, + { + address: 'tz1cNARmnRRrvZgspPr2rSTUWq5xtGTuKuHY', + name: 'Cryptium Labs Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1cNARmnRRrvZgspPr2rSTUWq5xtGTuKuHY' + }, + { + address: 'tz1ZbSrRrfhU8LYHELWNswx2JcFARXTGKKVk', + name: 'DNAG Delegation Payouts 1', + logo: 'https://services.tzkt.io/v1/avatars/tz1ZbSrRrfhU8LYHELWNswx2JcFARXTGKKVk' + }, + { + address: 'tz1aqYbUuXoraB7h39Ls3HvbDwiMhHRV199L', + name: 'Elite Tezos Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1aqYbUuXoraB7h39Ls3HvbDwiMhHRV199L' + }, + { + address: 'tz1W1en9UpMCH4ZJL8wQCh8JDKCZARyVx2co', + name: 'Everstake Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1W1en9UpMCH4ZJL8wQCh8JDKCZARyVx2co' + }, + { + address: 'tz1dXCHSN8uwnappk4uet1WQeuvbaJog4Jwi', + name: 'Figment Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1dXCHSN8uwnappk4uet1WQeuvbaJog4Jwi' + }, + { + address: 'tz1ePtw5wtQMNH1LkJaVXbeVmW7joWqdNzge', + name: 'GOLD TZ Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1ePtw5wtQMNH1LkJaVXbeVmW7joWqdNzge' + }, + { + address: 'tz1TyAEPtLt7oapQvZirVbswz1VRbdRqdfW7', + name: 'Happy Tezos Dexter Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1TyAEPtLt7oapQvZirVbswz1VRbdRqdfW7' + }, + { + address: 'tz1hodLFy8YDHtf1qJ3XH1gCyeXfwWEitkj9', + name: 'hodl.farm Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1hodLFy8YDHtf1qJ3XH1gCyeXfwWEitkj9' + }, + { + address: 'tz1MTAmuFmKu3MoxnkVsMj7xvSScj6d83hu5', + name: 'LetzBake! Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1MTAmuFmKu3MoxnkVsMj7xvSScj6d83hu5' + }, + { + address: 'tz1fRAiiDUxnXZwDmQghh1n6VytQUZWNPwWN', + name: 'Melange Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1fRAiiDUxnXZwDmQghh1n6VytQUZWNPwWN' + }, + { + address: 'tz1MdSsDBG8k8q1pxZrdpSC2Aw49ukFs8ACy', + name: 'Money Every 3 Days Payouts 1', + logo: 'https://services.tzkt.io/v1/avatars/tz1MdSsDBG8k8q1pxZrdpSC2Aw49ukFs8ACy' + }, + { + address: 'tz1XVBuWfdFpWCiMvsEV8KEX2nkMHN3mfuHJ', + name: 'Neokta Labs Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1XVBuWfdFpWCiMvsEV8KEX2nkMHN3mfuHJ' + }, + { + address: 'tz1c9HEyZdAWXZCLE7h3KcZCyykjZr7VY3QM', + name: 'PayTezos Payouts 2', + logo: 'https://services.tzkt.io/v1/avatars/tz1c9HEyZdAWXZCLE7h3KcZCyykjZr7VY3QM' + }, + { + address: 'tz1MoonPbyMJSqMVsVwExgVc5egnv18CgSDq', + name: 'P2P Validator Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1MoonPbyMJSqMVsVwExgVc5egnv18CgSDq' + }, + { + address: 'tz1VCP3MQdfxtRc83CRJZX43wc1oZUxb6KmH', + name: 'Spice Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1VCP3MQdfxtRc83CRJZX43wc1oZUxb6KmH' + }, + { + address: 'tz1fishChEERnSesm8mHe7xsJJwymbHVLcYf', + name: 'Stake.fish Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1fishChEERnSesm8mHe7xsJJwymbHVLcYf' + }, + { + address: 'tz1Ywgcavxq9D6hL32Q2AQWHAux9MrWqGoZC', + name: 'StakeNow Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1Ywgcavxq9D6hL32Q2AQWHAux9MrWqGoZC' + }, + { + address: 'tz1Y2rhY9nBKfd2jp7m4z8iAMKKARWS3BvFA', + name: "Shake 'n Bake Payouts", + logo: 'https://services.tzkt.io/v1/avatars/tz1Y2rhY9nBKfd2jp7m4z8iAMKKARWS3BvFA' + }, + { + address: 'tz1gs78wrxS34XhGPECmN5fABKpEuhUGwAXS', + name: 'Stakery Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1gs78wrxS34XhGPECmN5fABKpEuhUGwAXS' + }, + { + address: 'tz1iuZ76cLaaca8Dh4soYEHjYeVb5vHmmP5Z', + name: 'Staking Facilities Payouts 2', + logo: 'https://services.tzkt.io/v1/avatars/tz1iuZ76cLaaca8Dh4soYEHjYeVb5vHmmP5Z' + }, + { + address: 'tz1hxtCEcD7idQJEDiJEq37vBkoRcwF6KC2X', + name: 'Staking Shop Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1hxtCEcD7idQJEDiJEq37vBkoRcwF6KC2X' + }, + { + address: 'tz1hTJnYMKSDUv55yREM8ezmC5nsdbPUWao7', + name: 'Steak.and.Bake Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1hTJnYMKSDUv55yREM8ezmC5nsdbPUWao7' + }, + { + address: 'tz1iQRWn2zvdTqhJtGTBbYktodNtw67yE4a6', + name: 'Tezbaguette Payouts ', + logo: 'https://services.tzkt.io/v1/avatars/tz1iQRWn2zvdTqhJtGTBbYktodNtw67yE4a6' + }, + { + address: 'tz1TkQCxYhhpzMop7Da6g2tpa1Z2giUbPdqv', + name: 'Tez Baker Payouts 5', + logo: 'https://services.tzkt.io/v1/avatars/tz1TkQCxYhhpzMop7Da6g2tpa1Z2giUbPdqv' + }, + { + address: 'tz1g4o4a2wxpzJ7EgG3onFM5TLaPyiRFjFhL', + name: 'Tezgate Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1g4o4a2wxpzJ7EgG3onFM5TLaPyiRFjFhL' + }, + { + address: 'tz1RiSGsJwcN6roErVt4D3mfSCYSaWYWP9q8', + name: 'Tezoris Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1RiSGsJwcN6roErVt4D3mfSCYSaWYWP9q8' + }, + { + address: 'tz1LJycSuCT25AA5VJwNW1QYXVGyy7YLwZh9', + name: 'TezosAirGap Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1LJycSuCT25AA5VJwNW1QYXVGyy7YLwZh9' + }, + { + address: 'tz1LXaBkg3gZLVyB2awuboPAi6CnWxT4bCMt', + name: 'Tezos Boutique Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1LXaBkg3gZLVyB2awuboPAi6CnWxT4bCMt' + }, + { + address: 'tz1VfoA5qPksECBkvr2EUuT6u5VgLCi3vTPV', + name: 'Tezos.nu Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1VfoA5qPksECBkvr2EUuT6u5VgLCi3vTPV' + }, + { + address: 'tz1Y2bfsQAYHrWZpM1AwomYMw2KEtaJ5VMfU', + name: 'Tezos.Rio Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1Y2bfsQAYHrWZpM1AwomYMw2KEtaJ5VMfU' + }, + { + address: 'tz1LXz7C2wPr74nfMMHmqsqbnasPvi89o2U6', + name: 'TezosRus Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1LXz7C2wPr74nfMMHmqsqbnasPvi89o2U6' + }, + { + address: 'tz1Tnr7CDL5i45EHSPpPReBocDiGbMwpdTCn', + name: "Tezos Wake n' Bake Payouts", + logo: 'https://services.tzkt.io/v1/avatars/tz1Tnr7CDL5i45EHSPpPReBocDiGbMwpdTCn' + }, + { + address: 'tz1WntXgznbivRjyhE7Y5jEzoebAhMPB2iJa', + name: 'Tezzieland Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1WntXgznbivRjyhE7Y5jEzoebAhMPB2iJa' + }, + { + address: 'tz1ant4etDpDJKQqASYri7bse5tCv2FNbvR6', + name: 'XTZ Antipodes Payouts 2', + logo: 'https://services.tzkt.io/v1/avatars/tz1ant4etDpDJKQqASYri7bse5tCv2FNbvR6' + }, + { + address: 'tz1Z7HGaayrL4XDNQ7UyXe7L4wXboELkhBm3', + name: 'XTZ Delegate Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1Z7HGaayrL4XDNQ7UyXe7L4wXboELkhBm3' + }, + { + address: 'tz1aF8E89g1EqqzCmbNCLunTtCtxgkoQUX7N', + name: '0xb1 / PlusMinus Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1aF8E89g1EqqzCmbNCLunTtCtxgkoQUX7N' + }, + { + address: 'tz1KwdqMQGB75VDnSsLiteFKVX4HNzvbNvjZ', + name: '888XTZ Payouts', + logo: 'https://services.tzkt.io/v1/avatars/tz1KwdqMQGB75VDnSsLiteFKVX4HNzvbNvjZ' + }, + { + address: 'tz1ea4wfxxvjpic1DZCU2WnUCBmiPVrSXrSz', + name: 'Cerberus Bakery Payouts', + logo: null + } +]; diff --git a/src/components/activity-groups-list/activity-group-item/info/baking.tsx b/src/components/activity-groups-list/activity-group-item/info/baking.tsx index 95e02890d..130495c3c 100644 --- a/src/components/activity-groups-list/activity-group-item/info/baking.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/baking.tsx @@ -22,7 +22,7 @@ export const BakingRewards: FC<{ address: string; nonZeroAmounts: NonZeroAmounts return ( - {isDefined(baker) ? ( + {isDefined(baker) && isDefined(baker.logo) ? ( ) : ( diff --git a/src/components/activity-groups-list/activity-group-item/info/delegation.tsx b/src/components/activity-groups-list/activity-group-item/info/delegation.tsx index 32e8d2306..4a1568c42 100644 --- a/src/components/activity-groups-list/activity-group-item/info/delegation.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/delegation.tsx @@ -19,7 +19,7 @@ export const Delegation: FC<{ address: string | undefined }> = ({ address = '' } return ( - {isDefined(baker) ? ( + {isDefined(baker) && isDefined(baker.logo) ? ( ) : ( diff --git a/src/hooks/use-contract-activity.ts b/src/hooks/use-contract-activity.ts index b244ad20f..52aa8cb15 100644 --- a/src/hooks/use-contract-activity.ts +++ b/src/hooks/use-contract-activity.ts @@ -3,7 +3,7 @@ import { uniq } from 'lodash-es'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; -import { EVERSTAKE_PAYOUTS_BAKER } from 'src/apis/baking-bad/consts'; +import { KNOWN_BAKERS } from 'src/apis/baking-bad/consts'; import { ActivityGroup } from 'src/interfaces/activity.interface'; import { loadBakersListActions } from 'src/store/baking/baking-actions'; import { useBakersListSelector } from 'src/store/baking/baking-selectors'; @@ -14,10 +14,6 @@ import { useSelectedAccountSelector } from '../store/wallet/wallet-selectors'; import { isDefined } from '../utils/is-defined'; import { loadActivity } from '../utils/token-operations.util'; -const KNOWN_BAKERS: Array = [ - { address: EVERSTAKE_PAYOUTS_BAKER.address, alias: 'Everstake payouts' } -]; - export const useContractActivity = (tokenSlug?: string): UseActivityInterface => { const dispatch = useDispatch(); const selectedAccount = useSelectedAccountSelector(); @@ -30,13 +26,16 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => const [activities, setActivities] = useState>([]); const knownBakers = useMemo>( - () => - KNOWN_BAKERS.concat( - bakers.map(({ address, name }) => ({ - address, - alias: name - })) - ), + () => [ + ...KNOWN_BAKERS.map(({ address, name }) => ({ + address, + alias: name + })), + ...bakers.map(({ address, name }) => ({ + address, + alias: name + })) + ], [bakers] ); diff --git a/src/store/baking/baking-selectors.ts b/src/store/baking/baking-selectors.ts index 89963eaaa..c035fbf9c 100644 --- a/src/store/baking/baking-selectors.ts +++ b/src/store/baking/baking-selectors.ts @@ -1,7 +1,7 @@ import { useMemo } from 'react'; import { BakerInterface, emptyBaker } from 'src/apis/baking-bad'; -import { EVERSTAKE_PAYOUTS_BAKER } from 'src/apis/baking-bad/consts'; +import { KNOWN_BAKERS, KnownBaker } from 'src/apis/baking-bad/consts'; import { isDefined } from 'src/utils/is-defined'; import { useSelector } from '../selector'; @@ -15,14 +15,14 @@ export const useSelectedBakerSelector = (): [BakerInterface, boolean] => { export const useBakersListSelector = () => useSelector(state => state.baking.bakersList.data); -export const useBakerByAddressSelector = ( - address: string -): Pick | undefined => { +export const useBakerByAddressSelector = (address: string): KnownBaker | undefined => { const bakers = useSelector(state => state.baking.bakersList.data); return useMemo(() => { - if (address === EVERSTAKE_PAYOUTS_BAKER.address) { - return EVERSTAKE_PAYOUTS_BAKER; + const knownBaker = KNOWN_BAKERS.find(baker => baker.address === address); + + if (isDefined(knownBaker)) { + return knownBaker; } const baker = bakers.find(baker => baker.address === address); From fc92e1ba93ee6e11b72bd5933204e39988a6e420 Mon Sep 17 00:00:00 2001 From: herkoss Date: Mon, 14 Aug 2023 15:17:56 +0300 Subject: [PATCH 16/43] TW-783 upgraded parser --- package.json | 4 ++-- yarn.lock | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 126b172b6..d073be282 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "@taquito/tzip12": "17.0.0", "@taquito/tzip16": "17.0.0", "@taquito/utils": "17.0.0", - "@temple-wallet/transactions-parser": "^1.0.0", + "@temple-wallet/transactions-parser": "^2.0.0", "@temple-wallet/wallet-address-validator": "^0.4.2", "@tezos-domains/core": "1.26.0", "@tezos-domains/taquito-client": "1.26.0", @@ -69,8 +69,8 @@ "bip39": "^3.0.4", "buffer": "^6.0.3", "cross-fetch": "^3.1.5", - "date-fns": "^2.30.0", "currency-codes": "^2.1.0", + "date-fns": "^2.30.0", "ed25519-hd-key": "^1.3.0", "events": "^3.3.0", "formik": "^2.2.9", diff --git a/yarn.lock b/yarn.lock index a0a3c1dbf..24d8ffafb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3889,10 +3889,10 @@ elliptic "^6.5.4" typedarray-to-buffer "^4.0.0" -"@temple-wallet/transactions-parser@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@temple-wallet/transactions-parser/-/transactions-parser-1.0.0.tgz#2a78b25a9c5ff6b54c83ae0ed621260c5f28c062" - integrity sha512-Bwa3xB33zVaOd2xB5nRET1L2O9qElO6r3hkXNJmIVPD3skFkYlsU2yOegEn5/6ZsH0eZGQA1PMb3LMq3BWheDw== +"@temple-wallet/transactions-parser@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@temple-wallet/transactions-parser/-/transactions-parser-2.0.0.tgz#f1ef59ee5cbbd03f585784c890699855096fcc69" + integrity sha512-vcKBC/fthqEPypey3B6YdPU8coZe4rzx0Z8izHfBsHhQ3AfzQRNGi2v+Nl9lgwqgi6J+z7Ny7x/K1NvKV5+Aeg== dependencies: bignumber.js "^9.1.0" From 90f4f1cfda7f298621e6d2f6f4f2af772d56918e Mon Sep 17 00:00:00 2001 From: herkoss Date: Mon, 14 Aug 2023 18:41:37 +0300 Subject: [PATCH 17/43] TW-786 Fixed QA issues. Fixed activity loading and address styles --- .../activity-group-amount-change.tsx | 4 +- .../activity-group-item.styles.ts | 3 + .../details-card/baking-rewards.tsx | 62 +++++++++++++++++++ .../details-card/details-card.tsx | 7 ++- .../details-card/receive-tokens.tsx | 7 ++- .../details-card/send-tokens.tsx | 8 ++- .../info/{baking.tsx => baking-rewards.tsx} | 0 .../activity-group-item/info/info.tsx | 2 +- .../activity-group-item/selectors.ts | 1 + .../public-key-hash-text.styles.ts | 3 +- .../public-key-hash-text.tsx | 3 +- src/config/general.ts | 2 +- src/utils/token-metadata.utils.ts | 8 +++ src/utils/token-operations.util.ts | 4 +- 14 files changed, 104 insertions(+), 10 deletions(-) create mode 100644 src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx rename src/components/activity-groups-list/activity-group-item/info/{baking.tsx => baking-rewards.tsx} (100%) diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx index dfc3aaea2..af1804ac5 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx @@ -1,6 +1,8 @@ import React, { FC } from 'react'; import { Text, View } from 'react-native'; +import { shortizeSymbol } from 'src/utils/token-metadata.utils'; + import { NonZeroAmounts } from '../../../../interfaces/non-zero-amounts.interface'; import { conditionalStyle } from '../../../../utils/conditional-style'; import { formatAssetAmount } from '../../../../utils/number.util'; @@ -31,7 +33,7 @@ export const ActivityGroupAmountChange: FC = ({ nonZeroAmounts, textSize ]} > {isPositive && '+'} - {formatAssetAmount(parsedAmount)} {symbol} + {formatAssetAmount(parsedAmount)} {shortizeSymbol(symbol)} ))} diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts index c1121af50..7f852b109 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts @@ -61,6 +61,9 @@ export const useActivityDetailsStyles = createUseStyles(({ colors }) => ({ }, chevron: { padding: formatSize(4) + }, + hashHeight: { + height: formatSize(24) } })); diff --git a/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx b/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx new file mode 100644 index 000000000..d06f44b14 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx @@ -0,0 +1,62 @@ +import React, { FC } from 'react'; +import { View, Text } from 'react-native'; + +import { Divider } from 'src/components/divider/divider'; +import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; +import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; +import { WalletAddress } from 'src/components/wallet-address/wallet-address'; +import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { formatSize } from 'src/styles/format-size'; +import { tzktUrl } from 'src/utils/linking.util'; + +import { ActivityGroupAmountChange, TextSize } from '../activity-group-amount-change/activity-group-amount-change'; +import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; +import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; +import { ActivityGroupItemSelectors } from '../selectors'; + +export const BakingRewardsDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ + nonZeroAmounts, + address, + hash +}) => { + const selectedRpcUrl = useSelectedRpcUrlSelector(); + const styles = useActivityDetailsStyles(); + const commonStyles = useActivityCommonStyles(); + + return ( + <> + + Received: + + + + + + + From: + + + + + + + + TxHash: + + + + + + + + ); +}; diff --git a/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx b/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx index 6f7597c9e..225f43132 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx @@ -3,6 +3,7 @@ import React, { FC } from 'react'; import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { BakingRewardsDetails } from './baking-rewards'; import { DelegateDetails } from './delegate'; import { ReceiveTokensDetails } from './receive-tokens'; import { SendTokensDetails } from './send-tokens'; @@ -15,8 +16,12 @@ export const DetailsCard: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmount case ActivityType.Send: return ; - case ActivityType.Recieve: case ActivityType.BakingRewards: + return ( + + ); + + case ActivityType.Recieve: return ( ); diff --git a/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx b/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx index f3f58e488..ee58bda0f 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx @@ -40,7 +40,12 @@ export const ReceiveTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: TxHash: - + diff --git a/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx b/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx index 8038aa326..cf99d9dc8 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx @@ -36,12 +36,18 @@ export const SendTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: st To: + TxHash: - + diff --git a/src/components/activity-groups-list/activity-group-item/info/baking.tsx b/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx similarity index 100% rename from src/components/activity-groups-list/activity-group-item/info/baking.tsx rename to src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx diff --git a/src/components/activity-groups-list/activity-group-item/info/info.tsx b/src/components/activity-groups-list/activity-group-item/info/info.tsx index f560c5382..8e8ce1a27 100644 --- a/src/components/activity-groups-list/activity-group-item/info/info.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/info.tsx @@ -3,7 +3,7 @@ import React, { FC } from 'react'; import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; -import { BakingRewards } from './baking'; +import { BakingRewards } from './baking-rewards'; import { Delegation } from './delegation'; import { Receive } from './receive'; import { Send } from './send'; diff --git a/src/components/activity-groups-list/activity-group-item/selectors.ts b/src/components/activity-groups-list/activity-group-item/selectors.ts index 8746ac279..ac7d080e6 100644 --- a/src/components/activity-groups-list/activity-group-item/selectors.ts +++ b/src/components/activity-groups-list/activity-group-item/selectors.ts @@ -1,5 +1,6 @@ export enum ActivityGroupItemSelectors { operationHash = 'Activity group item/Operation hash', externalLink = 'Activity group item/External link', + externalBakerLink = 'Activity group item/External Baker link', details = 'Activity group item/Details' } diff --git a/src/components/public-key-hash-text/public-key-hash-text.styles.ts b/src/components/public-key-hash-text/public-key-hash-text.styles.ts index ad0d60651..6ccd6da76 100644 --- a/src/components/public-key-hash-text/public-key-hash-text.styles.ts +++ b/src/components/public-key-hash-text/public-key-hash-text.styles.ts @@ -3,7 +3,8 @@ import { formatSize } from '../../styles/format-size'; export const usePublicKeyHashTextStyles = createUseStyles(({ colors, typography }) => ({ container: { - width: formatSize(100), + flexDirection: 'row', + alignItems: 'baseline', paddingHorizontal: formatSize(4), paddingVertical: formatSize(2), backgroundColor: colors.blue10, diff --git a/src/components/public-key-hash-text/public-key-hash-text.tsx b/src/components/public-key-hash-text/public-key-hash-text.tsx index 6770a9800..1cba21e70 100644 --- a/src/components/public-key-hash-text/public-key-hash-text.tsx +++ b/src/components/public-key-hash-text/public-key-hash-text.tsx @@ -5,6 +5,7 @@ import { TouchableOpacity } from 'react-native-gesture-handler'; import { MarginProps } from 'src/interfaces/margin.props'; import { TestIdProps } from 'src/interfaces/test-id.props'; import { copyStringToClipboard } from 'src/utils/clipboard.utils'; +import { truncateLongAddress } from 'src/utils/exolix.util'; import { getTruncatedProps } from 'src/utils/style.util'; import { OriginalTouchableOpacityComponentType, TouchableWithAnalytics } from '../touchable-with-analytics'; @@ -47,7 +48,7 @@ export const PublicKeyHashText: FC = ({ testIDProperties={testIDProperties} > - {publicKeyHash} + {truncateLongAddress(publicKeyHash)} ); diff --git a/src/config/general.ts b/src/config/general.ts index 899146528..9cd13c213 100644 --- a/src/config/general.ts +++ b/src/config/general.ts @@ -5,5 +5,5 @@ export const emptyFn = () => void 0; export const emptyComponent = () => null; export const delegationApy = 5.6; -export const OPERATION_LIMIT = 50; +export const OPERATION_LIMIT = 75; export const UNKNOWN_TOKEN_SYMBOL = '???'; diff --git a/src/utils/token-metadata.utils.ts b/src/utils/token-metadata.utils.ts index 523abd022..f87a39992 100644 --- a/src/utils/token-metadata.utils.ts +++ b/src/utils/token-metadata.utils.ts @@ -212,3 +212,11 @@ export const applySortByDollarValueDecrease = (assets: TokenInterface[]) => return bDollarValue.minus(aDollarValue).toNumber(); }); + +export const shortizeSymbol = (symbol: string): string => { + if (symbol.length > 15) { + return symbol.slice(0, 12) + '...'; + } + + return symbol; +}; diff --git a/src/utils/token-operations.util.ts b/src/utils/token-operations.util.ts index 9c03e8715..be3cff711 100644 --- a/src/utils/token-operations.util.ts +++ b/src/utils/token-operations.util.ts @@ -163,9 +163,9 @@ const loadOperations = async ( tokenSlug?: string, lastItem?: Activity ): Promise> => { - const [contractAddress, tokenId] = (tokenSlug ?? '').split('_'); - if (isDefined(tokenSlug)) { + const [contractAddress, tokenId] = tokenSlug.split('_'); + if (tokenSlug === TEZ_TOKEN_SLUG) { return getTezosOperations(selectedRpcUrl, selectedAccount.publicKeyHash, lastItem?.id); } From 95f78ff7fd2d812a589ab10f23fd10aaf7193a87 Mon Sep 17 00:00:00 2001 From: herkoss Date: Tue, 15 Aug 2023 10:58:49 +0300 Subject: [PATCH 18/43] TW-783 wip --- .../details-card/details-card.tsx | 3 ++- .../details-card/unknown-details.tsx | 11 +-------- .../activity-group-item/info/info.tsx | 3 ++- .../activity-groups-list.tsx | 24 +++++++++---------- 4 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx b/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx index 225f43132..e78775d46 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx @@ -7,6 +7,7 @@ import { BakingRewardsDetails } from './baking-rewards'; import { DelegateDetails } from './delegate'; import { ReceiveTokensDetails } from './receive-tokens'; import { SendTokensDetails } from './send-tokens'; +import { UnknownDetails } from './unknown-details'; export const DetailsCard: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = ({ activity, @@ -30,6 +31,6 @@ export const DetailsCard: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmount return ; default: - return null; + return ; } }; diff --git a/src/components/activity-groups-list/activity-group-item/details-card/unknown-details.tsx b/src/components/activity-groups-list/activity-group-item/details-card/unknown-details.tsx index bb2ea86b1..d4b0478d5 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/unknown-details.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/unknown-details.tsx @@ -4,7 +4,6 @@ import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; -import { WalletAddress } from 'src/components/wallet-address/wallet-address'; import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; @@ -15,11 +14,7 @@ import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; import { ActivityGroupItemSelectors } from '../selectors'; -export const UnknownDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ - nonZeroAmounts, - address, - hash -}) => { +export const UnknownDetails: FC<{ nonZeroAmounts: NonZeroAmounts; hash: string }> = ({ nonZeroAmounts, hash }) => { const selectedRpcUrl = useSelectedRpcUrlSelector(); const styles = useActivityDetailsStyles(); @@ -34,10 +29,6 @@ export const UnknownDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: strin - - To: - - TxHash: diff --git a/src/components/activity-groups-list/activity-group-item/info/info.tsx b/src/components/activity-groups-list/activity-group-item/info/info.tsx index 8e8ce1a27..1f7d17533 100644 --- a/src/components/activity-groups-list/activity-group-item/info/info.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/info.tsx @@ -7,6 +7,7 @@ import { BakingRewards } from './baking-rewards'; import { Delegation } from './delegation'; import { Receive } from './receive'; import { Send } from './send'; +import { UnknownInfo } from './unknown-info'; export const Info: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = ({ activity, nonZeroAmounts }) => { switch (activity.type) { @@ -20,6 +21,6 @@ export const Info: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = return ; default: - return null; + return ; } }; diff --git a/src/components/activity-groups-list/activity-groups-list.tsx b/src/components/activity-groups-list/activity-groups-list.tsx index f1af02565..b529a3633 100644 --- a/src/components/activity-groups-list/activity-groups-list.tsx +++ b/src/components/activity-groups-list/activity-groups-list.tsx @@ -58,21 +58,21 @@ export const ActivityGroupsList: FC = ({ result.unshift({ title: 'Never', data: [ - { - type: 'Unknown', - status: TzktOperationStatus.Applied, - hash: '', - tokensDeltas: [{ atomicAmount: new BigNumber(888), tokenSlug: TEZ_TOKEN_SLUG }], - id: 0, - timestamp: '', - from: { address: 'qweqweqwe' }, - to: { address: 'asdasdasd' } - } + [ + { + type: 'Unknown', + status: TzktOperationStatus.Applied, + hash: 'oobqHGXAdHW43SWud7HJRCHqhePZmJ8JKFvPK84GD8JSpArQoc6', + tokensDeltas: [{ atomicAmount: new BigNumber(888), tokenSlug: TEZ_TOKEN_SLUG }], + id: 703070287691776, + timestamp: '2023-08-15T10:10:20Z', + from: { address: 'tz1L7QjtFG4KJBMZ8tppwMmTjMGwqxPFCSXM' }, + to: { address: 'tz1VNvjvQPufKb38KYF6DC3PHWR8SVWEiHUW' } + } + ] ] as unknown as ActivityGroup[] }); - console.log('result: ', result); - return result; }, [activityGroups]); From ae808dae8f35f2bea26390f9da272672a9db8554 Mon Sep 17 00:00:00 2001 From: herkoss Date: Tue, 15 Aug 2023 11:01:18 +0300 Subject: [PATCH 19/43] TW-786 Fixed imports --- .../activity-group-amount-change.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx index af1804ac5..3021577c2 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx @@ -1,11 +1,11 @@ import React, { FC } from 'react'; import { Text, View } from 'react-native'; +import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { conditionalStyle } from 'src/utils/conditional-style'; +import { formatAssetAmount } from 'src/utils/number.util'; import { shortizeSymbol } from 'src/utils/token-metadata.utils'; -import { NonZeroAmounts } from '../../../../interfaces/non-zero-amounts.interface'; -import { conditionalStyle } from '../../../../utils/conditional-style'; -import { formatAssetAmount } from '../../../../utils/number.util'; import { useActivityGroupAmountChangeStyles } from './activity-group-amount-change.styles'; export enum TextSize { From a81335d3ef4074e47e11e540922afa41ac87e4ed Mon Sep 17 00:00:00 2001 From: herkoss Date: Tue, 15 Aug 2023 16:17:16 +0300 Subject: [PATCH 20/43] TW-786 Fixed activity loading --- src/config/general.ts | 2 +- src/hooks/use-contract-activity.ts | 8 +++--- src/utils/token-operations.util.ts | 39 +++++++++--------------------- 3 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/config/general.ts b/src/config/general.ts index 9cd13c213..899146528 100644 --- a/src/config/general.ts +++ b/src/config/general.ts @@ -5,5 +5,5 @@ export const emptyFn = () => void 0; export const emptyComponent = () => null; export const delegationApy = 5.6; -export const OPERATION_LIMIT = 75; +export const OPERATION_LIMIT = 50; export const UNKNOWN_TOKEN_SYMBOL = '???'; diff --git a/src/hooks/use-contract-activity.ts b/src/hooks/use-contract-activity.ts index 52aa8cb15..8989e982c 100644 --- a/src/hooks/use-contract-activity.ts +++ b/src/hooks/use-contract-activity.ts @@ -14,6 +14,8 @@ import { useSelectedAccountSelector } from '../store/wallet/wallet-selectors'; import { isDefined } from '../utils/is-defined'; import { loadActivity } from '../utils/token-operations.util'; +const OLDEST_ACTIVITY_INDEX = 0; + export const useContractActivity = (tokenSlug?: string): UseActivityInterface => { const dispatch = useDispatch(); const selectedAccount = useSelectedAccountSelector(); @@ -49,10 +51,10 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => if (refresh === true) { setActivities(prev => { const allActivities = [...activities, ...prev]; - const allHashes = allActivities.map(x => x[0]).map(x => x.hash); + const allHashes = allActivities.map(x => x[OLDEST_ACTIVITY_INDEX]).map(x => x.hash); const onlyUniqueHashes = uniq(allHashes); const onlyUniqueActivitites = onlyUniqueHashes - .map(x => allActivities.find(y => y[0].hash === x)) + .map(x => allActivities.find(y => y[OLDEST_ACTIVITY_INDEX].hash === x)) .filter(isDefined); return onlyUniqueActivitites; @@ -79,7 +81,7 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => const lastActivityGroup = activities[activities.length - 1]; if (lastActivityGroup.length > 0) { - const lastItem = lastActivityGroup[lastActivityGroup.length - 1]; + const lastItem = lastActivityGroup[OLDEST_ACTIVITY_INDEX]; if (lastItem.hash !== lastActivityRef.current) { lastActivityRef.current = lastItem.hash; diff --git a/src/utils/token-operations.util.ts b/src/utils/token-operations.util.ts index be3cff711..8212d1ae8 100644 --- a/src/utils/token-operations.util.ts +++ b/src/utils/token-operations.util.ts @@ -19,12 +19,7 @@ const getOperationGroupByHash = (selectedRpcUrl: string, hash: string) => getTzktApi(selectedRpcUrl).get>(`operations/${hash}`); // LIQUIDITY BAKING ACTIVITY -const getContractOperations = ( - selectedRpcUrl: string, - account: string, - contractAddress: string, - lastTimestamp?: string -) => +const getContractOperations = (selectedRpcUrl: string, account: string, contractAddress: string, lastId?: number) => getTzktApi(selectedRpcUrl) .get>(`accounts/${contractAddress}/operations`, { params: { @@ -33,7 +28,7 @@ const getContractOperations = ( sort: '1', initiator: account, entrypoint: 'mintOrBurn', - ...(isDefined(lastTimestamp) ? { 'timestamp.lt': lastTimestamp } : undefined) + ...(isDefined(lastId) ? { lastId } : undefined) } }) .then(x => x.data); @@ -43,7 +38,7 @@ const getTokenFa2Operations = ( account: string, contractAddress: string, tokenId = '0', - lastTimestamp?: string + lastId?: number ) => getTzktApi(selectedRpcUrl) .get>('operations/transactions', { @@ -53,17 +48,12 @@ const getTokenFa2Operations = ( 'sort.desc': 'level', target: contractAddress, 'parameter.[*].in': `[{"from_":"${account}","txs":[{"token_id":"${tokenId}"}]},{"txs":[{"to_":"${account}","token_id":"${tokenId}"}]}]`, - ...(isDefined(lastTimestamp) ? { 'timestamp.lt': lastTimestamp } : undefined) + ...(isDefined(lastId) ? { 'id.lt': lastId } : undefined) } }) .then(x => x.data); -const getTokenFa12Operations = ( - selectedRpcUrl: string, - account: string, - contractAddress: string, - lastTimestamp?: string -) => +const getTokenFa12Operations = (selectedRpcUrl: string, account: string, contractAddress: string, lastId?: number) => getTzktApi(selectedRpcUrl) .get>('operations/transactions', { params: { @@ -72,7 +62,7 @@ const getTokenFa12Operations = ( 'sort.desc': 'level', target: contractAddress, 'parameter.in': `[{"from":"${account}"},{"to":"${account}"}]`, - ...(isDefined(lastTimestamp) ? { 'timestamp.lt': lastTimestamp } : undefined) + ...(isDefined(lastId) ? { 'id.lt': lastId } : undefined) } }) .then(x => x.data); @@ -162,10 +152,10 @@ const loadOperations = async ( selectedAccount: AccountInterface, tokenSlug?: string, lastItem?: Activity -): Promise> => { - if (isDefined(tokenSlug)) { - const [contractAddress, tokenId] = tokenSlug.split('_'); +) => { + const [contractAddress, tokenId] = (tokenSlug ?? '').split('_'); + if (isDefined(tokenSlug)) { if (tokenSlug === TEZ_TOKEN_SLUG) { return getTezosOperations(selectedRpcUrl, selectedAccount.publicKeyHash, lastItem?.id); } @@ -175,7 +165,7 @@ const loadOperations = async ( selectedRpcUrl, selectedAccount.publicKeyHash, contractAddress, - lastItem?.timestamp + lastItem?.id ); } @@ -184,12 +174,7 @@ const loadOperations = async ( const tokenType = getTokenType(contract); if (tokenType === TokenTypeEnum.FA_1_2) { - return getTokenFa12Operations( - selectedRpcUrl, - selectedAccount.publicKeyHash, - contractAddress, - lastItem?.timestamp - ); + return getTokenFa12Operations(selectedRpcUrl, selectedAccount.publicKeyHash, contractAddress, lastItem?.id); } if (tokenType === TokenTypeEnum.FA_2) { @@ -198,7 +183,7 @@ const loadOperations = async ( selectedAccount.publicKeyHash, contractAddress, tokenId, - lastItem?.timestamp + lastItem?.id ); } } From 76d11c56e8104e2b92c532795f3c5ed30531e448 Mon Sep 17 00:00:00 2001 From: herkoss Date: Tue, 15 Aug 2023 17:51:27 +0300 Subject: [PATCH 21/43] TW-786 Fixed comment --- .../activity-group-item/activity-group-item.styles.ts | 2 +- .../details-card/baking-rewards.tsx | 2 +- .../details-card/receive-tokens.tsx | 2 +- .../activity-group-item/details-card/send-tokens.tsx | 2 +- .../activity-group-item/info/baking-rewards.tsx | 2 +- .../activity-group-item/info/delegation.tsx | 2 +- .../activity-group-item/info/receive.tsx | 2 +- .../activity-group-item/info/send.tsx | 2 +- .../public-key-hash-text/public-key-hash-text.tsx | 2 +- src/screens/buy/crypto/exolix/components/copy-row.tsx | 11 ++++++----- src/screens/buy/crypto/exolix/steps/approve-step.tsx | 2 +- src/utils/address.utils.ts | 2 ++ src/utils/exolix.util.ts | 3 --- 13 files changed, 18 insertions(+), 18 deletions(-) create mode 100644 src/utils/address.utils.ts diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts index 7f852b109..674bf3a49 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts @@ -62,7 +62,7 @@ export const useActivityDetailsStyles = createUseStyles(({ colors }) => ({ chevron: { padding: formatSize(4) }, - hashHeight: { + hashChip: { height: formatSize(24) } })); diff --git a/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx b/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx index d06f44b14..f91cd9576 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx @@ -49,7 +49,7 @@ export const BakingRewardsDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: diff --git a/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx b/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx index ee58bda0f..e53880dd9 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx @@ -42,7 +42,7 @@ export const ReceiveTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: diff --git a/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx b/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx index cf99d9dc8..1e78bd94d 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx @@ -44,7 +44,7 @@ export const SendTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: st diff --git a/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx b/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx index 130495c3c..645638f5c 100644 --- a/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx @@ -7,7 +7,7 @@ import { RobotIcon } from 'src/components/robot-icon/robot-icon'; import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; import { useBakerByAddressSelector } from 'src/store/baking/baking-selectors'; import { formatSize } from 'src/styles/format-size'; -import { truncateLongAddress } from 'src/utils/exolix.util'; +import { truncateLongAddress } from 'src/utils/address.utils'; import { isDefined } from 'src/utils/is-defined'; import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; diff --git a/src/components/activity-groups-list/activity-group-item/info/delegation.tsx b/src/components/activity-groups-list/activity-group-item/info/delegation.tsx index 4a1568c42..473ea1dd8 100644 --- a/src/components/activity-groups-list/activity-group-item/info/delegation.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/delegation.tsx @@ -6,7 +6,7 @@ import { Divider } from 'src/components/divider/divider'; import { RobotIcon } from 'src/components/robot-icon/robot-icon'; import { useBakerByAddressSelector } from 'src/store/baking/baking-selectors'; import { formatSize } from 'src/styles/format-size'; -import { truncateLongAddress } from 'src/utils/exolix.util'; +import { truncateLongAddress } from 'src/utils/address.utils'; import { isDefined } from 'src/utils/is-defined'; import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; diff --git a/src/components/activity-groups-list/activity-group-item/info/receive.tsx b/src/components/activity-groups-list/activity-group-item/info/receive.tsx index 79adb0b2d..6b68505dc 100644 --- a/src/components/activity-groups-list/activity-group-item/info/receive.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/receive.tsx @@ -5,7 +5,7 @@ import { Divider } from 'src/components/divider/divider'; import { RobotIcon } from 'src/components/robot-icon/robot-icon'; import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; import { formatSize } from 'src/styles/format-size'; -import { truncateLongAddress } from 'src/utils/exolix.util'; +import { truncateLongAddress } from 'src/utils/address.utils'; import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; diff --git a/src/components/activity-groups-list/activity-group-item/info/send.tsx b/src/components/activity-groups-list/activity-group-item/info/send.tsx index 2825071b5..72c97f423 100644 --- a/src/components/activity-groups-list/activity-group-item/info/send.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/send.tsx @@ -5,7 +5,7 @@ import { Divider } from 'src/components/divider/divider'; import { RobotIcon } from 'src/components/robot-icon/robot-icon'; import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; import { formatSize } from 'src/styles/format-size'; -import { truncateLongAddress } from 'src/utils/exolix.util'; +import { truncateLongAddress } from 'src/utils/address.utils'; import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; diff --git a/src/components/public-key-hash-text/public-key-hash-text.tsx b/src/components/public-key-hash-text/public-key-hash-text.tsx index 1cba21e70..0f33aa9a0 100644 --- a/src/components/public-key-hash-text/public-key-hash-text.tsx +++ b/src/components/public-key-hash-text/public-key-hash-text.tsx @@ -4,8 +4,8 @@ import { TouchableOpacity } from 'react-native-gesture-handler'; import { MarginProps } from 'src/interfaces/margin.props'; import { TestIdProps } from 'src/interfaces/test-id.props'; +import { truncateLongAddress } from 'src/utils/address.utils'; import { copyStringToClipboard } from 'src/utils/clipboard.utils'; -import { truncateLongAddress } from 'src/utils/exolix.util'; import { getTruncatedProps } from 'src/utils/style.util'; import { OriginalTouchableOpacityComponentType, TouchableWithAnalytics } from '../touchable-with-analytics'; diff --git a/src/screens/buy/crypto/exolix/components/copy-row.tsx b/src/screens/buy/crypto/exolix/components/copy-row.tsx index 55654c94f..f136f2a84 100644 --- a/src/screens/buy/crypto/exolix/components/copy-row.tsx +++ b/src/screens/buy/crypto/exolix/components/copy-row.tsx @@ -2,11 +2,12 @@ import { TouchableOpacity } from '@gorhom/bottom-sheet'; import React, { FC } from 'react'; import { View, Text } from 'react-native'; -import { Divider } from '../../../../../components/divider/divider'; -import { formatSize } from '../../../../../styles/format-size'; -import { copyStringToClipboard } from '../../../../../utils/clipboard.utils'; -import { truncateLongAddress } from '../../../../../utils/exolix.util'; -import { isDefined } from '../../../../../utils/is-defined'; +import { Divider } from 'src/components/divider/divider'; +import { formatSize } from 'src/styles/format-size'; +import { truncateLongAddress } from 'src/utils/address.utils'; +import { copyStringToClipboard } from 'src/utils/clipboard.utils'; +import { isDefined } from 'src/utils/is-defined'; + import { useExolixStyles } from '../exolix.styles'; interface CopyRowProps { diff --git a/src/screens/buy/crypto/exolix/steps/approve-step.tsx b/src/screens/buy/crypto/exolix/steps/approve-step.tsx index 4ec7ae801..32e4d1384 100644 --- a/src/screens/buy/crypto/exolix/steps/approve-step.tsx +++ b/src/screens/buy/crypto/exolix/steps/approve-step.tsx @@ -17,10 +17,10 @@ import { restartExolixTopupAction, setExolixStepAction } from 'src/store/exolix/ import { useExolixExchangeData, useExolixStep } from 'src/store/exolix/exolix-selectors'; import { formatSize } from 'src/styles/format-size'; import { useColors } from 'src/styles/use-colors'; +import { truncateLongAddress } from 'src/utils/address.utils'; import { AnalyticsEventCategory } from 'src/utils/analytics/analytics-event.enum'; import { useAnalytics } from 'src/utils/analytics/use-analytics.hook'; import { copyStringToClipboard } from 'src/utils/clipboard.utils'; -import { truncateLongAddress } from 'src/utils/exolix.util'; import { isDefined } from 'src/utils/is-defined'; import { openUrl } from 'src/utils/linking.util'; diff --git a/src/utils/address.utils.ts b/src/utils/address.utils.ts new file mode 100644 index 000000000..843f07356 --- /dev/null +++ b/src/utils/address.utils.ts @@ -0,0 +1,2 @@ +export const truncateLongAddress = (data: string) => + data.length > 10 ? data.slice(0, 5) + '...' + data.slice(-5) : data; diff --git a/src/utils/exolix.util.ts b/src/utils/exolix.util.ts index b50cf2a8d..f29d1fc4d 100644 --- a/src/utils/exolix.util.ts +++ b/src/utils/exolix.util.ts @@ -79,6 +79,3 @@ export const submitExolixExchange = (data: SubmitExchangePayload) => export const loadExolixExchangeData = (exchangeId: string) => exolixApi.get(`/transactions/${exchangeId}`); - -export const truncateLongAddress = (data: string) => - data.length > 10 ? data.slice(0, 5) + '...' + data.slice(-5) : data; From ae78a60e86b01339a22dc9952b4f4dd12bfc7c49 Mon Sep 17 00:00:00 2001 From: herkoss Date: Tue, 15 Aug 2023 18:06:49 +0300 Subject: [PATCH 22/43] TW-786 FIed --- src/hooks/use-non-zero-amounts.hook.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hooks/use-non-zero-amounts.hook.ts b/src/hooks/use-non-zero-amounts.hook.ts index 467f43862..0aab30eb8 100644 --- a/src/hooks/use-non-zero-amounts.hook.ts +++ b/src/hooks/use-non-zero-amounts.hook.ts @@ -9,7 +9,7 @@ import { useUsdToTokenRates } from '../store/currency/currency-selectors'; import { loadTokenMetadataActions } from '../store/tokens-metadata/tokens-metadata-actions'; import { isDefined } from '../utils/is-defined'; import { isString } from '../utils/is-string'; -import { mutezToTz } from '../utils/tezos.util'; +import { isCollectible, mutezToTz } from '../utils/tezos.util'; import { useTokenMetadataGetter } from './use-token-metadata-getter.hook'; interface ActivityAmount { @@ -36,7 +36,8 @@ export const useNonZeroAmounts = (tokensDeltas: Array): ActivityNonZ let negativeAmountSum = new BigNumber(0); for (const { atomicAmount, tokenSlug } of tokensDeltas) { - const { decimals, symbol, name, artifactUri } = getTokenMetadata(tokenSlug); + const metadata = getTokenMetadata(tokenSlug); + const { decimals, symbol, name } = metadata; const [address, tokenId] = tokenSlug.split('_'); const exchangeRate: number | undefined = exchangeRates[tokenSlug]; if (isString(address) && !isString(name)) { @@ -59,7 +60,7 @@ export const useNonZeroAmounts = (tokensDeltas: Array): ActivityNonZ amounts.push({ parsedAmount, isPositive, - symbol: isDefined(artifactUri) ? name : symbol, + symbol: isCollectible(metadata) ? name : symbol, exchangeRate }); } From 3afc0afc86153298588510ea3d2a57652d21a67d Mon Sep 17 00:00:00 2001 From: herkoss Date: Wed, 16 Aug 2023 12:30:39 +0300 Subject: [PATCH 23/43] TW-783 Finished unknown operations --- .../activity-group-amount-change.styles.ts | 7 ++- .../activity-group-amount-change.tsx | 60 +++++++++++++++---- .../activity-group-dollar-amount-change.tsx | 18 +++--- .../activity-group-item.styles.ts | 3 + .../details-card/baking-rewards.tsx | 7 ++- .../details-card/details-card.tsx | 4 +- .../details-card/receive-tokens.tsx | 7 ++- .../details-card/send-tokens.tsx | 7 ++- .../details-card/unknown-details.tsx | 59 ++++++++++++++---- .../activity-group-item/details.tsx | 4 +- .../info/baking-rewards.tsx | 10 +++- .../activity-group-item/info/info.tsx | 7 ++- .../activity-group-item/info/receive.tsx | 10 +++- .../activity-group-item/info/send.tsx | 7 ++- .../activity-group-item/info/unknown-info.tsx | 7 ++- .../item-amount-change.styles.ts | 14 +++++ .../item-amount-change/item-amount-change.tsx | 30 ++++++++++ .../activity-groups-list.tsx | 22 ------- src/hooks/use-non-zero-amounts.hook.ts | 44 ++++++-------- src/interfaces/non-zero-amounts.interface.ts | 15 ++--- src/utils/activity.utils.ts | 20 +++++++ 21 files changed, 247 insertions(+), 115 deletions(-) create mode 100644 src/components/activity-groups-list/activity-group-item/item-amount-change/item-amount-change.styles.ts create mode 100644 src/components/activity-groups-list/activity-group-item/item-amount-change/item-amount-change.tsx create mode 100644 src/utils/activity.utils.ts diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.styles.ts b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.styles.ts index 97f741f73..fce9ffff3 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.styles.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.styles.ts @@ -2,7 +2,8 @@ import { createUseStyles } from '../../../../styles/create-use-styles'; export const useActivityGroupAmountChangeStyles = createUseStyles(({ colors, typography }) => ({ container: { - alignItems: 'flex-end' + alignItems: 'flex-end', + flexShrink: 1 }, amountWeight: { fontWeight: '400' @@ -18,5 +19,9 @@ export const useActivityGroupAmountChangeStyles = createUseStyles(({ colors, typ }, positiveAmountText: { color: colors.adding + }, + valueText: { + ...typography.numbersRegular11, + color: colors.gray1 } })); diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx index 3021577c2..6de5880bf 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx @@ -1,11 +1,12 @@ -import React, { FC } from 'react'; +import React, { FC, useMemo } from 'react'; import { Text, View } from 'react-native'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; +import { isDoubleTokenOperation, isSingleTokenOperation } from 'src/utils/activity.utils'; import { conditionalStyle } from 'src/utils/conditional-style'; -import { formatAssetAmount } from 'src/utils/number.util'; import { shortizeSymbol } from 'src/utils/token-metadata.utils'; +import { ItemAmountChange } from '../item-amount-change/item-amount-change'; import { useActivityGroupAmountChangeStyles } from './activity-group-amount-change.styles'; export enum TextSize { @@ -14,17 +15,36 @@ export enum TextSize { } interface Props { textSize?: TextSize; - nonZeroAmounts: NonZeroAmounts; + nonZeroAmounts: Array; } +const FIRST_AMOUNT_INDEX = 0; + export const ActivityGroupAmountChange: FC = ({ nonZeroAmounts, textSize = TextSize.Regular }) => { const styles = useActivityGroupAmountChangeStyles(); - return ( - - {nonZeroAmounts.amounts.map(({ parsedAmount, isPositive, symbol }, index) => ( + const children = useMemo(() => { + const { isPositive, parsedAmount, symbol } = nonZeroAmounts[FIRST_AMOUNT_INDEX]; + + if (isSingleTokenOperation(nonZeroAmounts)) { + return ( + + ); + } + + if (isDoubleTokenOperation(nonZeroAmounts)) { + const symbols = nonZeroAmounts.map(({ symbol }) => symbol).join(','); + + return ( = ({ nonZeroAmounts, textSize ]} > {isPositive && '+'} - {formatAssetAmount(parsedAmount)} {shortizeSymbol(symbol)} + {shortizeSymbol(symbols)} - ))} - - ); + ); + } + + return ( + + {isPositive ? '+' : '-'} + {shortizeSymbol(symbol)} and {nonZeroAmounts.length - 1} others + + ); + }, [nonZeroAmounts, textSize]); + + return {children}; }; diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.tsx index efef8e4ae..c671854e2 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.tsx @@ -1,22 +1,26 @@ +import { BigNumber } from 'bignumber.js'; import React, { FC } from 'react'; import { View } from 'react-native'; -import { NonZeroAmounts } from '../../../../interfaces/non-zero-amounts.interface'; -import { FormattedAmount } from '../../../formatted-amount'; +import { FormattedAmount } from 'src/components/formatted-amount'; +import { ZERO } from 'src/config/swap'; + import { useActivityGroupDollarAmountChangeStyles } from './activity-group-dollar-amount-change.styles'; interface Props { - nonZeroAmounts: NonZeroAmounts; + dollarValue: BigNumber; } -export const ActivityGroupDollarAmountChange: FC = ({ nonZeroAmounts }) => { +export const ActivityGroupDollarAmountChange: FC = ({ dollarValue }) => { const styles = useActivityGroupDollarAmountChangeStyles(); + if (dollarValue.isEqualTo(ZERO)) { + return null; + } + return ( - {nonZeroAmounts.dollarSums.map((amount, index) => ( - - ))} + ); }; diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts index 674bf3a49..da7519444 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts @@ -64,6 +64,9 @@ export const useActivityDetailsStyles = createUseStyles(({ colors }) => ({ }, hashChip: { height: formatSize(24) + }, + mb8: { + marginBottom: formatSize(8) } })); diff --git a/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx b/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx index f91cd9576..834638c47 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx @@ -5,9 +5,10 @@ import { Divider } from 'src/components/divider/divider'; import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; import { WalletAddress } from 'src/components/wallet-address/wallet-address'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; +import { calculateDollarValue } from 'src/utils/activity.utils'; import { tzktUrl } from 'src/utils/linking.util'; import { ActivityGroupAmountChange, TextSize } from '../activity-group-amount-change/activity-group-amount-change'; @@ -15,7 +16,7 @@ import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; import { ActivityGroupItemSelectors } from '../selectors'; -export const BakingRewardsDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ +export const BakingRewardsDetails: FC<{ nonZeroAmounts: Array; address: string; hash: string }> = ({ nonZeroAmounts, address, hash @@ -30,7 +31,7 @@ export const BakingRewardsDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: Received: - + diff --git a/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx b/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx index e78775d46..5e43e7cdf 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx @@ -1,7 +1,7 @@ import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; import React, { FC } from 'react'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { BakingRewardsDetails } from './baking-rewards'; import { DelegateDetails } from './delegate'; @@ -9,7 +9,7 @@ import { ReceiveTokensDetails } from './receive-tokens'; import { SendTokensDetails } from './send-tokens'; import { UnknownDetails } from './unknown-details'; -export const DetailsCard: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = ({ +export const DetailsCard: FC<{ activity: Activity; nonZeroAmounts: Array }> = ({ activity, nonZeroAmounts }) => { diff --git a/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx b/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx index e53880dd9..7181128ac 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx @@ -5,9 +5,10 @@ import { Divider } from 'src/components/divider/divider'; import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; import { WalletAddress } from 'src/components/wallet-address/wallet-address'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; +import { calculateDollarValue } from 'src/utils/activity.utils'; import { tzktUrl } from 'src/utils/linking.util'; import { ActivityGroupAmountChange, TextSize } from '../activity-group-amount-change/activity-group-amount-change'; @@ -15,7 +16,7 @@ import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; import { ActivityGroupItemSelectors } from '../selectors'; -export const ReceiveTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ +export const ReceiveTokensDetails: FC<{ nonZeroAmounts: Array; address: string; hash: string }> = ({ nonZeroAmounts, address, hash @@ -30,7 +31,7 @@ export const ReceiveTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: Received: - + diff --git a/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx b/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx index 1e78bd94d..13eac2c9e 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx @@ -5,9 +5,10 @@ import { Divider } from 'src/components/divider/divider'; import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; import { WalletAddress } from 'src/components/wallet-address/wallet-address'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; +import { calculateDollarValue } from 'src/utils/activity.utils'; import { tzktUrl } from 'src/utils/linking.util'; import { ActivityGroupAmountChange, TextSize } from '../activity-group-amount-change/activity-group-amount-change'; @@ -15,7 +16,7 @@ import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; import { ActivityGroupItemSelectors } from '../selectors'; -export const SendTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ +export const SendTokensDetails: FC<{ nonZeroAmounts: Array; address: string; hash: string }> = ({ nonZeroAmounts, address, hash @@ -31,7 +32,7 @@ export const SendTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: st Sent: - + diff --git a/src/components/activity-groups-list/activity-group-item/details-card/unknown-details.tsx b/src/components/activity-groups-list/activity-group-item/details-card/unknown-details.tsx index d4b0478d5..953578248 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/unknown-details.tsx +++ b/src/components/activity-groups-list/activity-group-item/details-card/unknown-details.tsx @@ -1,34 +1,73 @@ -import React, { FC } from 'react'; +import { isEmpty } from 'lodash-es'; +import React, { FC, useMemo } from 'react'; import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; +import { isDefined } from 'src/utils/is-defined'; import { tzktUrl } from 'src/utils/linking.util'; -import { ActivityGroupAmountChange, TextSize } from '../activity-group-amount-change/activity-group-amount-change'; import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; +import { ItemAmountChange } from '../item-amount-change/item-amount-change'; import { ActivityGroupItemSelectors } from '../selectors'; -export const UnknownDetails: FC<{ nonZeroAmounts: NonZeroAmounts; hash: string }> = ({ nonZeroAmounts, hash }) => { +export const UnknownDetails: FC<{ nonZeroAmounts: Array; hash: string }> = ({ + nonZeroAmounts, + hash +}) => { const selectedRpcUrl = useSelectedRpcUrlSelector(); const styles = useActivityDetailsStyles(); const commonStyles = useActivityCommonStyles(); + const { positiveAmounts, negativeAmounts } = useMemo(() => { + const positiveAmounts: Array = []; + const negativeAmounts: Array = []; + + for (const amount of nonZeroAmounts) { + if (amount.isPositive) { + positiveAmounts.push(amount); + } else { + negativeAmounts.push(amount); + } + } + + return { positiveAmounts, negativeAmounts }; + }, [nonZeroAmounts]); + return ( <> - - Sent: - - - + {!isEmpty(positiveAmounts) && ( + + Received: + + {positiveAmounts.map(amount => ( + + + {isDefined(amount.fiatAmount) && } + + ))} + - + )} + {!isEmpty(positiveAmounts) && ( + + Sent: + + {negativeAmounts.map(amount => ( + + + {isDefined(amount.fiatAmount) && } + + ))} + + + )} TxHash: diff --git a/src/components/activity-groups-list/activity-group-item/details.tsx b/src/components/activity-groups-list/activity-group-item/details.tsx index ca689884e..8b728db86 100644 --- a/src/components/activity-groups-list/activity-group-item/details.tsx +++ b/src/components/activity-groups-list/activity-group-item/details.tsx @@ -6,7 +6,7 @@ import { Divider } from 'src/components/divider/divider'; import { Icon } from 'src/components/icon/icon'; import { IconNameEnum } from 'src/components/icon/icon-name.enum'; import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { formatSize } from 'src/styles/format-size'; import { useActivityCommonStyles, useActivityDetailsStyles } from './activity-group-item.styles'; @@ -17,7 +17,7 @@ import { ActivityGroupItemSelectors } from './selectors'; interface Props { activity: Activity; - nonZeroAmounts: NonZeroAmounts; + nonZeroAmounts: Array; } export const Details: FC = ({ activity, nonZeroAmounts }) => { diff --git a/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx b/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx index 645638f5c..901ebf576 100644 --- a/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx @@ -4,9 +4,10 @@ import { View, Text } from 'react-native'; import { AvatarImage } from 'src/components/avatar-image/avatar-image'; import { Divider } from 'src/components/divider/divider'; import { RobotIcon } from 'src/components/robot-icon/robot-icon'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { useBakerByAddressSelector } from 'src/store/baking/baking-selectors'; import { formatSize } from 'src/styles/format-size'; +import { calculateDollarValue } from 'src/utils/activity.utils'; import { truncateLongAddress } from 'src/utils/address.utils'; import { isDefined } from 'src/utils/is-defined'; @@ -14,7 +15,10 @@ import { ActivityGroupAmountChange } from '../activity-group-amount-change/activ import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; -export const BakingRewards: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ address, nonZeroAmounts }) => { +export const BakingRewards: FC<{ address: string; nonZeroAmounts: Array }> = ({ + address, + nonZeroAmounts +}) => { const styles = useActivityGroupItemStyles(); const commonStyles = useActivityCommonStyles(); @@ -35,7 +39,7 @@ export const BakingRewards: FC<{ address: string; nonZeroAmounts: NonZeroAmounts From: {baker?.name ?? truncateLongAddress(address)} - + diff --git a/src/components/activity-groups-list/activity-group-item/info/info.tsx b/src/components/activity-groups-list/activity-group-item/info/info.tsx index 1f7d17533..ac65f4385 100644 --- a/src/components/activity-groups-list/activity-group-item/info/info.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/info.tsx @@ -1,7 +1,7 @@ import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; import React, { FC } from 'react'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { BakingRewards } from './baking-rewards'; import { Delegation } from './delegation'; @@ -9,7 +9,10 @@ import { Receive } from './receive'; import { Send } from './send'; import { UnknownInfo } from './unknown-info'; -export const Info: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = ({ activity, nonZeroAmounts }) => { +export const Info: FC<{ activity: Activity; nonZeroAmounts: Array }> = ({ + activity, + nonZeroAmounts +}) => { switch (activity.type) { case ActivityType.Send: return ; diff --git a/src/components/activity-groups-list/activity-group-item/info/receive.tsx b/src/components/activity-groups-list/activity-group-item/info/receive.tsx index 6b68505dc..39e79f426 100644 --- a/src/components/activity-groups-list/activity-group-item/info/receive.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/receive.tsx @@ -3,15 +3,19 @@ import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; import { RobotIcon } from 'src/components/robot-icon/robot-icon'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { formatSize } from 'src/styles/format-size'; +import { calculateDollarValue } from 'src/utils/activity.utils'; import { truncateLongAddress } from 'src/utils/address.utils'; import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; -export const Receive: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ address, nonZeroAmounts }) => { +export const Receive: FC<{ address: string; nonZeroAmounts: Array }> = ({ + address, + nonZeroAmounts +}) => { const styles = useActivityGroupItemStyles(); const commonStyles = useActivityCommonStyles(); @@ -26,7 +30,7 @@ export const Receive: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = From: {truncateLongAddress(address)} - + diff --git a/src/components/activity-groups-list/activity-group-item/info/send.tsx b/src/components/activity-groups-list/activity-group-item/info/send.tsx index 72c97f423..e94a11e73 100644 --- a/src/components/activity-groups-list/activity-group-item/info/send.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/send.tsx @@ -3,15 +3,16 @@ import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; import { RobotIcon } from 'src/components/robot-icon/robot-icon'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { formatSize } from 'src/styles/format-size'; +import { calculateDollarValue } from 'src/utils/activity.utils'; import { truncateLongAddress } from 'src/utils/address.utils'; import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; -export const Send: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ address, nonZeroAmounts }) => { +export const Send: FC<{ address: string; nonZeroAmounts: Array }> = ({ address, nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); const commonStyles = useActivityCommonStyles(); @@ -26,7 +27,7 @@ export const Send: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ To: {truncateLongAddress(address)} - + diff --git a/src/components/activity-groups-list/activity-group-item/info/unknown-info.tsx b/src/components/activity-groups-list/activity-group-item/info/unknown-info.tsx index c3d431d08..6949e1b1a 100644 --- a/src/components/activity-groups-list/activity-group-item/info/unknown-info.tsx +++ b/src/components/activity-groups-list/activity-group-item/info/unknown-info.tsx @@ -1,13 +1,14 @@ import React, { FC } from 'react'; import { View, Text } from 'react-native'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; +import { calculateDollarValue } from 'src/utils/activity.utils'; import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; -export const UnknownInfo: FC<{ nonZeroAmounts: NonZeroAmounts }> = ({ nonZeroAmounts }) => { +export const UnknownInfo: FC<{ nonZeroAmounts: Array }> = ({ nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); const commonStyles = useActivityCommonStyles(); @@ -20,7 +21,7 @@ export const UnknownInfo: FC<{ nonZeroAmounts: NonZeroAmounts }> = ({ nonZeroAmo - - + diff --git a/src/components/activity-groups-list/activity-group-item/item-amount-change/item-amount-change.styles.ts b/src/components/activity-groups-list/activity-group-item/item-amount-change/item-amount-change.styles.ts new file mode 100644 index 000000000..f7c5cdc5b --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/item-amount-change/item-amount-change.styles.ts @@ -0,0 +1,14 @@ +import { createUseStyles } from 'src/styles/create-use-styles'; + +export const useActivityGroupDollarAmountChangeStyles = createUseStyles(({ colors }) => ({ + container: { + alignItems: 'flex-end', + flexShrink: 1 + }, + positiveAmountText: { + color: colors.adding + }, + negativeAmountText: { + color: colors.destructive + } +})); diff --git a/src/components/activity-groups-list/activity-group-item/item-amount-change/item-amount-change.tsx b/src/components/activity-groups-list/activity-group-item/item-amount-change/item-amount-change.tsx new file mode 100644 index 000000000..57e89f1e7 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/item-amount-change/item-amount-change.tsx @@ -0,0 +1,30 @@ +import { BigNumber } from 'bignumber.js'; +import React, { FC } from 'react'; +import { View, Text, StyleProp, TextStyle } from 'react-native'; + +import { conditionalStyle } from 'src/utils/conditional-style'; +import { formatAssetAmount } from 'src/utils/number.util'; +import { shortizeSymbol } from 'src/utils/token-metadata.utils'; + +import { useActivityGroupDollarAmountChangeStyles } from './item-amount-change.styles'; + +interface Props { + amount: BigNumber; + symbol: string; + textStyle?: StyleProp; +} + +export const ItemAmountChange: FC = ({ symbol, amount, textStyle }) => { + const styles = useActivityGroupDollarAmountChangeStyles(); + + const isPositive = amount.isPositive(); + + return ( + + + {isPositive && '+'} + {formatAssetAmount(amount)} {shortizeSymbol(symbol)} + + + ); +}; diff --git a/src/components/activity-groups-list/activity-groups-list.tsx b/src/components/activity-groups-list/activity-groups-list.tsx index b529a3633..a8739eed0 100644 --- a/src/components/activity-groups-list/activity-groups-list.tsx +++ b/src/components/activity-groups-list/activity-groups-list.tsx @@ -1,10 +1,6 @@ -import { TzktOperationStatus } from '@temple-wallet/transactions-parser'; -import { BigNumber } from 'bignumber.js'; import React, { FC, useMemo } from 'react'; import { SectionList, Text, View } from 'react-native'; -import { TEZ_TOKEN_SLUG } from 'src/token/data/tokens-metadata'; - import { emptyFn } from '../../config/general'; import { useFakeRefreshControlProps } from '../../hooks/use-fake-refresh-control-props.hook'; import { ActivityGroup, emptyActivity } from '../../interfaces/activity.interface'; @@ -55,24 +51,6 @@ export const ActivityGroupsList: FC = ({ prevActivityDate = date; } - result.unshift({ - title: 'Never', - data: [ - [ - { - type: 'Unknown', - status: TzktOperationStatus.Applied, - hash: 'oobqHGXAdHW43SWud7HJRCHqhePZmJ8JKFvPK84GD8JSpArQoc6', - tokensDeltas: [{ atomicAmount: new BigNumber(888), tokenSlug: TEZ_TOKEN_SLUG }], - id: 703070287691776, - timestamp: '2023-08-15T10:10:20Z', - from: { address: 'tz1L7QjtFG4KJBMZ8tppwMmTjMGwqxPFCSXM' }, - to: { address: 'tz1VNvjvQPufKb38KYF6DC3PHWR8SVWEiHUW' } - } - ] - ] as unknown as ActivityGroup[] - }); - return result; }, [activityGroups]); diff --git a/src/hooks/use-non-zero-amounts.hook.ts b/src/hooks/use-non-zero-amounts.hook.ts index 0aab30eb8..f509a7afc 100644 --- a/src/hooks/use-non-zero-amounts.hook.ts +++ b/src/hooks/use-non-zero-amounts.hook.ts @@ -3,6 +3,7 @@ import { BigNumber } from 'bignumber.js'; import { useMemo } from 'react'; import { useDispatch } from 'react-redux'; +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { useFiatToUsdRateSelector } from 'src/store/settings/settings-selectors'; import { useUsdToTokenRates } from '../store/currency/currency-selectors'; @@ -12,34 +13,31 @@ import { isString } from '../utils/is-string'; import { isCollectible, mutezToTz } from '../utils/tezos.util'; import { useTokenMetadataGetter } from './use-token-metadata-getter.hook'; -interface ActivityAmount { - symbol: string; - isPositive: boolean; - exchangeRate: number; - parsedAmount: BigNumber; -} - -interface ActivityNonZeroAmounts { - amounts: Array; - dollarSums: Array; -} +const calculateFiatAmount = ( + parsedAmount: BigNumber, + exchangeRate: number | undefined, + fiatToUsdRate: number | undefined +) => { + if (isDefined(exchangeRate) && isDefined(fiatToUsdRate)) { + return parsedAmount.absoluteValue().multipliedBy(exchangeRate).multipliedBy(fiatToUsdRate); + } +}; -export const useNonZeroAmounts = (tokensDeltas: Array): ActivityNonZeroAmounts => { +export const useNonZeroAmounts = (tokensDeltas: Array): Array => { const dispatch = useDispatch(); const getTokenMetadata = useTokenMetadataGetter(); const exchangeRates = useUsdToTokenRates(); const fiatToUsdRate = useFiatToUsdRateSelector(); return useMemo(() => { - const amounts = []; - let positiveAmountSum = new BigNumber(0); - let negativeAmountSum = new BigNumber(0); + const amounts: Array = []; for (const { atomicAmount, tokenSlug } of tokensDeltas) { const metadata = getTokenMetadata(tokenSlug); const { decimals, symbol, name } = metadata; const [address, tokenId] = tokenSlug.split('_'); const exchangeRate: number | undefined = exchangeRates[tokenSlug]; + if (isString(address) && !isString(name)) { dispatch(loadTokenMetadataActions.submit({ address, id: Number(tokenId ?? '0') })); } @@ -47,25 +45,17 @@ export const useNonZeroAmounts = (tokensDeltas: Array): ActivityNonZ const parsedAmount = mutezToTz(atomicAmount, decimals); const isPositive = parsedAmount.isPositive(); - if (isDefined(exchangeRate) && isDefined(fiatToUsdRate)) { - const summand = parsedAmount.multipliedBy(exchangeRate).multipliedBy(fiatToUsdRate); - if (isPositive) { - positiveAmountSum = positiveAmountSum.plus(summand); - } else { - negativeAmountSum = negativeAmountSum.plus(summand); - } - } - if (!parsedAmount.isEqualTo(0)) { amounts.push({ - parsedAmount, isPositive, + parsedAmount, + exchangeRate, symbol: isCollectible(metadata) ? name : symbol, - exchangeRate + fiatAmount: calculateFiatAmount(parsedAmount, exchangeRate, fiatToUsdRate) }); } } - return { amounts, dollarSums: [negativeAmountSum, positiveAmountSum].filter(sum => !sum.isZero()) }; + return amounts; }, [tokensDeltas, getTokenMetadata, exchangeRates]); }; diff --git a/src/interfaces/non-zero-amounts.interface.ts b/src/interfaces/non-zero-amounts.interface.ts index 226d88b4d..23baa56d1 100644 --- a/src/interfaces/non-zero-amounts.interface.ts +++ b/src/interfaces/non-zero-amounts.interface.ts @@ -1,11 +1,8 @@ import { BigNumber } from 'bignumber.js'; - -export interface NonZeroAmounts { - amounts: { - parsedAmount: BigNumber; - isPositive: boolean; - symbol: string; - exchangeRate: number; - }[]; - dollarSums: BigNumber[]; +export interface ActivityAmount { + symbol: string; + isPositive: boolean; + exchangeRate: number; + parsedAmount: BigNumber; + fiatAmount: BigNumber | undefined; } diff --git a/src/utils/activity.utils.ts b/src/utils/activity.utils.ts new file mode 100644 index 000000000..757ef6102 --- /dev/null +++ b/src/utils/activity.utils.ts @@ -0,0 +1,20 @@ +import { BigNumber } from 'bignumber.js'; + +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; + +import { isDefined } from './is-defined'; + +export const isSingleTokenOperation = (amounts: Array) => amounts.length === 1; + +export const isDoubleTokenOperation = (amounts: Array) => amounts.length === 2; + +const ZERO = new BigNumber(0); + +export const calculateDollarValue = (amounts: Array) => + amounts.reduce((accum, curr) => { + if (isDefined(curr.fiatAmount)) { + return accum.plus(curr.fiatAmount); + } + + return accum; + }, ZERO); From 710ccfee9d47d9e92e9c995d8509d394a5d67bf0 Mon Sep 17 00:00:00 2001 From: herkoss Date: Wed, 16 Aug 2023 13:46:11 +0300 Subject: [PATCH 24/43] TW-786 Fixed bug while parser return empty array of activities --- package.json | 2 +- .../public-key-hash-text.styles.ts | 1 + src/hooks/use-contract-activity.ts | 44 +++++++++-------- src/utils/token-operations.util.ts | 47 ++++++++++++++----- yarn.lock | 6 +-- 5 files changed, 63 insertions(+), 37 deletions(-) diff --git a/package.json b/package.json index 126b172b6..56be5bd7f 100644 --- a/package.json +++ b/package.json @@ -69,8 +69,8 @@ "bip39": "^3.0.4", "buffer": "^6.0.3", "cross-fetch": "^3.1.5", - "date-fns": "^2.30.0", "currency-codes": "^2.1.0", + "date-fns": "^2.30.0", "ed25519-hd-key": "^1.3.0", "events": "^3.3.0", "formik": "^2.2.9", diff --git a/src/components/public-key-hash-text/public-key-hash-text.styles.ts b/src/components/public-key-hash-text/public-key-hash-text.styles.ts index 6ccd6da76..1726274b8 100644 --- a/src/components/public-key-hash-text/public-key-hash-text.styles.ts +++ b/src/components/public-key-hash-text/public-key-hash-text.styles.ts @@ -5,6 +5,7 @@ export const usePublicKeyHashTextStyles = createUseStyles(({ colors, typography container: { flexDirection: 'row', alignItems: 'baseline', + maxWidth: formatSize(100), paddingHorizontal: formatSize(4), paddingVertical: formatSize(2), backgroundColor: colors.blue10, diff --git a/src/hooks/use-contract-activity.ts b/src/hooks/use-contract-activity.ts index 8989e982c..1d0165288 100644 --- a/src/hooks/use-contract-activity.ts +++ b/src/hooks/use-contract-activity.ts @@ -1,4 +1,4 @@ -import { TzktMemberInterface } from '@temple-wallet/transactions-parser'; +import { TzktMemberInterface, TzktOperation } from '@temple-wallet/transactions-parser'; import { uniq } from 'lodash-es'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; @@ -22,7 +22,7 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => const selectedRpcUrl = useSelectedRpcUrlSelector(); const bakers = useBakersListSelector(); - const lastActivityRef = useRef(''); + const lastOperationRef = useRef(); const [isAllLoaded, setIsAllLoaded] = useState(false); const [activities, setActivities] = useState>([]); @@ -43,9 +43,19 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => const initialLoad = useCallback( async (refresh = false) => { - const activities = await loadActivity(selectedRpcUrl, selectedAccount, tokenSlug, knownBakers); - - if (activities.length === 0) { + const { activities, reachedTheEnd, oldestOperation } = await loadActivity( + selectedRpcUrl, + selectedAccount, + tokenSlug, + knownBakers + ); + console.log('activities: ', activities); + console.log('reachedTheEnd: ', reachedTheEnd); + console.log('oldestOperation: ', oldestOperation); + + lastOperationRef.current = oldestOperation ?? lastOperationRef.current; + + if (reachedTheEnd) { setIsAllLoaded(true); } if (refresh === true) { @@ -78,24 +88,18 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => const handleUpdate = async () => { if (activities.length > 0 && !isAllLoaded) { - const lastActivityGroup = activities[activities.length - 1]; - - if (lastActivityGroup.length > 0) { - const lastItem = lastActivityGroup[OLDEST_ACTIVITY_INDEX]; + const { + activities: newActivity, + reachedTheEnd, + oldestOperation + } = await loadActivity(selectedRpcUrl, selectedAccount, tokenSlug, knownBakers, lastOperationRef.current); - if (lastItem.hash !== lastActivityRef.current) { - lastActivityRef.current = lastItem.hash; + lastOperationRef.current = oldestOperation ?? lastOperationRef.current; - if (isDefined(lastItem)) { - const newActivity = await loadActivity(selectedRpcUrl, selectedAccount, tokenSlug, knownBakers, lastItem); - - if (newActivity.length === 0) { - setIsAllLoaded(true); - } - setActivities(prev => [...prev, ...newActivity]); - } - } + if (reachedTheEnd) { + setIsAllLoaded(true); } + setActivities(prev => [...prev, ...newActivity]); } }; diff --git a/src/utils/token-operations.util.ts b/src/utils/token-operations.util.ts index 8212d1ae8..60ef34f24 100644 --- a/src/utils/token-operations.util.ts +++ b/src/utils/token-operations.util.ts @@ -151,13 +151,13 @@ const loadOperations = async ( selectedRpcUrl: string, selectedAccount: AccountInterface, tokenSlug?: string, - lastItem?: Activity + oldestOperation?: TzktOperation ) => { const [contractAddress, tokenId] = (tokenSlug ?? '').split('_'); if (isDefined(tokenSlug)) { if (tokenSlug === TEZ_TOKEN_SLUG) { - return getTezosOperations(selectedRpcUrl, selectedAccount.publicKeyHash, lastItem?.id); + return getTezosOperations(selectedRpcUrl, selectedAccount.publicKeyHash, oldestOperation?.id); } if (tokenSlug === LIQUIDITY_BAKING_DEX_ADDRESS) { @@ -165,7 +165,7 @@ const loadOperations = async ( selectedRpcUrl, selectedAccount.publicKeyHash, contractAddress, - lastItem?.id + oldestOperation?.id ); } @@ -174,7 +174,12 @@ const loadOperations = async ( const tokenType = getTokenType(contract); if (tokenType === TokenTypeEnum.FA_1_2) { - return getTokenFa12Operations(selectedRpcUrl, selectedAccount.publicKeyHash, contractAddress, lastItem?.id); + return getTokenFa12Operations( + selectedRpcUrl, + selectedAccount.publicKeyHash, + contractAddress, + oldestOperation?.id + ); } if (tokenType === TokenTypeEnum.FA_2) { @@ -183,12 +188,12 @@ const loadOperations = async ( selectedAccount.publicKeyHash, contractAddress, tokenId, - lastItem?.id + oldestOperation?.id ); } } - return getAllOperations(selectedRpcUrl, selectedAccount.publicKeyHash, lastItem?.id); + return getAllOperations(selectedRpcUrl, selectedAccount.publicKeyHash, oldestOperation?.id); }; export const loadActivity = async ( @@ -196,21 +201,37 @@ export const loadActivity = async ( selectedAccount: AccountInterface, tokenSlug?: string, knownBakers?: Array, - lastItem?: Activity -): Promise>> => { - const operationsHashes = await loadOperations(selectedRpcUrl, selectedAccount, tokenSlug, lastItem) - .then(operations => operations.map(operation => operation.hash)) - .then(newHashes => uniq(newHashes.filter(x => x !== lastItem?.hash))); + oldestOperation?: TzktOperation +): Promise<{ activities: Array>; reachedTheEnd: boolean; oldestOperation?: TzktOperation }> => { + const operationsHashesRaw = await loadOperations(selectedRpcUrl, selectedAccount, tokenSlug, oldestOperation).then( + operations => operations.map(operation => operation.hash) + ); + + const operationsHashesUniq = uniq(operationsHashesRaw.filter(x => x !== oldestOperation?.hash)); const operationGroups: Array> = []; - for (const opHash of operationsHashes) { + for (const opHash of operationsHashesUniq) { const { data } = await getOperationGroupByHash(selectedRpcUrl, opHash); operationGroups.push(data); await sleep(100); } - return operationGroups + const reachedTheEnd = operationGroups.length === 0; + + if (reachedTheEnd) { + return { activities: [], reachedTheEnd }; + } + + const oldestOperationNew = operationGroups[operationGroups.length - 1]?.[0]; + + const activities = operationGroups .map(group => parseTransactions(group, selectedAccount.publicKeyHash, knownBakers)) .filter(group => !isEmpty(group)); + + if (activities.length === 0) { + return loadActivity(selectedRpcUrl, selectedAccount, tokenSlug, knownBakers, oldestOperationNew); + } + + return { activities, reachedTheEnd, oldestOperation: oldestOperationNew }; }; diff --git a/yarn.lock b/yarn.lock index a0a3c1dbf..86af9bba0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3890,9 +3890,9 @@ typedarray-to-buffer "^4.0.0" "@temple-wallet/transactions-parser@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@temple-wallet/transactions-parser/-/transactions-parser-1.0.0.tgz#2a78b25a9c5ff6b54c83ae0ed621260c5f28c062" - integrity sha512-Bwa3xB33zVaOd2xB5nRET1L2O9qElO6r3hkXNJmIVPD3skFkYlsU2yOegEn5/6ZsH0eZGQA1PMb3LMq3BWheDw== + version "1.0.1" + resolved "https://registry.yarnpkg.com/@temple-wallet/transactions-parser/-/transactions-parser-1.0.1.tgz#96eab0d1e738667518b82da83d5be113562a446e" + integrity sha512-S+ADFmvi9KEr+y/HRlte09Z9wO81JQ5mDwIN7mFF4/hIdcc7uQf79ETcM0waRQolCmXRsQfVq16GI+DkzVHyWA== dependencies: bignumber.js "^9.1.0" From 1a08041547e28d095937816206e9fb24e4a5a630 Mon Sep 17 00:00:00 2001 From: herkoss Date: Wed, 16 Aug 2023 14:46:01 +0300 Subject: [PATCH 25/43] TW-786 deleted console.logs --- src/hooks/use-contract-activity.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hooks/use-contract-activity.ts b/src/hooks/use-contract-activity.ts index 1d0165288..695d788fd 100644 --- a/src/hooks/use-contract-activity.ts +++ b/src/hooks/use-contract-activity.ts @@ -49,9 +49,6 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => tokenSlug, knownBakers ); - console.log('activities: ', activities); - console.log('reachedTheEnd: ', reachedTheEnd); - console.log('oldestOperation: ', oldestOperation); lastOperationRef.current = oldestOperation ?? lastOperationRef.current; From b1d931935f56c6259abeac4fdb15308b9f03785d Mon Sep 17 00:00:00 2001 From: herkoss Date: Wed, 23 Aug 2023 16:41:05 +0300 Subject: [PATCH 26/43] TW-786 Fixed QA issues --- .../activity-group-item.tsx | 6 +- .../activity-groups-list.tsx | 134 +++++++++--------- .../public-key-hash-text.styles.ts | 4 +- src/hooks/use-contract-activity.ts | 70 +++++---- 4 files changed, 109 insertions(+), 105 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx index 50f42694b..c050c9748 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx @@ -1,4 +1,4 @@ -import React, { FC } from 'react'; +import React, { FC, memo } from 'react'; import { View } from 'react-native'; import { Divider } from 'src/components/divider/divider'; @@ -14,7 +14,7 @@ interface Props { group: ActivityGroup; } -export const ActivityGroupItem: FC = ({ group }) => { +export const ActivityGroupItem: FC = memo(({ group }) => { const styles = useActivityGroupItemStyles(); const firstActivity = group[0] ?? emptyActivity; const nonZeroAmounts = useNonZeroAmounts(firstActivity.tokensDeltas); @@ -26,4 +26,4 @@ export const ActivityGroupItem: FC = ({ group }) => {
); -}; +}); diff --git a/src/components/activity-groups-list/activity-groups-list.tsx b/src/components/activity-groups-list/activity-groups-list.tsx index a8739eed0..bbc2e6872 100644 --- a/src/components/activity-groups-list/activity-groups-list.tsx +++ b/src/components/activity-groups-list/activity-groups-list.tsx @@ -1,4 +1,4 @@ -import React, { FC, useMemo } from 'react'; +import React, { FC, memo, useMemo, useRef } from 'react'; import { SectionList, Text, View } from 'react-native'; import { emptyFn } from '../../config/general'; @@ -19,88 +19,84 @@ interface Props { onOptimalPromotionError?: () => void; } -export const ActivityGroupsList: FC = ({ - activityGroups, - handleUpdate = emptyFn, - shouldShowPromotion = false, - onOptimalPromotionError -}) => { - const styles = useActivityGroupsListStyles(); +const renderItem = (item: ActivityGroup) => ; - const fakeRefreshControlProps = useFakeRefreshControlProps(); +export const ActivityGroupsList: FC = memo( + ({ activityGroups, handleUpdate = emptyFn, shouldShowPromotion = false, onOptimalPromotionError }) => { + const styles = useActivityGroupsListStyles(); - const sections = useMemo(() => { - const result = []; - let prevActivityDate = new Date(-1); + const onEndReachedCalledDuringMomentum = useRef(false); - for (const activityGroup of activityGroups) { - const firstActivity = activityGroup[0] ?? emptyActivity; - const date = new Date(firstActivity.timestamp); + const fakeRefreshControlProps = useFakeRefreshControlProps(); - if (isTheSameDay(date, prevActivityDate)) { - result[result.length - 1]?.data.push(activityGroup); - } else { - let title = date.toLocaleString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' }).toUpperCase(); + const sections = useMemo(() => { + const result = []; + let prevActivityDate = new Date(-1); - isToday(date) && (title = 'Today'); - isYesterday(date) && (title = 'Yesterday'); + for (const activityGroup of activityGroups) { + const firstActivity = activityGroup[0] ?? emptyActivity; + const date = new Date(firstActivity.timestamp); - result.push({ title, data: [activityGroup] }); - } + if (isTheSameDay(date, prevActivityDate)) { + result[result.length - 1]?.data.push(activityGroup); + } else { + let title = date.toLocaleString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' }).toUpperCase(); + + isToday(date) && (title = 'Today'); + isYesterday(date) && (title = 'Yesterday'); + + result.push({ title, data: [activityGroup] }); + } - prevActivityDate = date; - } + prevActivityDate = date; + } - return result; - }, [activityGroups]); + return result; + }, [activityGroups]); - const isShowPlaceholder = useMemo(() => activityGroups.length === 0, [activityGroups]); + const isShowPlaceholder: boolean = useMemo(() => activityGroups.length === 0, [activityGroups]); - return ( - <> - {isShowPlaceholder ? ( - <> - {shouldShowPromotion && ( - - - - )} - - - ) : ( - <> + return ( + <> + {isShowPlaceholder ? ( + <> + {shouldShowPromotion && ( + + + + )} + + + ) : ( item[0]?.hash ?? index} - renderItem={({ item, index, section }) => ( - <> - - {index === 0 && section.title === sections[0].title && shouldShowPromotion && ( - - - - )} - - )} + onEndReachedThreshold={0.5} + onMomentumScrollBegin={() => { + onEndReachedCalledDuringMomentum.current = false; + }} + onEndReached={() => { + if (!onEndReachedCalledDuringMomentum.current || sections.length < 10) { + handleUpdate(); + onEndReachedCalledDuringMomentum.current = true; + } + }} + keyExtractor={item => item[0].hash} + bounces={false} + renderItem={({ item }) => renderItem(item)} renderSectionHeader={({ section: { title } }) => {title}} refreshControl={} /> - - )} - - ); -}; + )} + + ); + } +); diff --git a/src/components/public-key-hash-text/public-key-hash-text.styles.ts b/src/components/public-key-hash-text/public-key-hash-text.styles.ts index 1726274b8..ad0d60651 100644 --- a/src/components/public-key-hash-text/public-key-hash-text.styles.ts +++ b/src/components/public-key-hash-text/public-key-hash-text.styles.ts @@ -3,9 +3,7 @@ import { formatSize } from '../../styles/format-size'; export const usePublicKeyHashTextStyles = createUseStyles(({ colors, typography }) => ({ container: { - flexDirection: 'row', - alignItems: 'baseline', - maxWidth: formatSize(100), + width: formatSize(100), paddingHorizontal: formatSize(4), paddingVertical: formatSize(2), backgroundColor: colors.blue10, diff --git a/src/hooks/use-contract-activity.ts b/src/hooks/use-contract-activity.ts index 695d788fd..eae9b8caa 100644 --- a/src/hooks/use-contract-activity.ts +++ b/src/hooks/use-contract-activity.ts @@ -16,6 +16,16 @@ import { loadActivity } from '../utils/token-operations.util'; const OLDEST_ACTIVITY_INDEX = 0; +const getUniqActivities = (activityGroups: Array) => { + const allHashes = activityGroups.map(x => x[OLDEST_ACTIVITY_INDEX]).map(x => x.hash); + const onlyUniqueHashes = uniq(allHashes); + const onlyUniqueActivitites = onlyUniqueHashes + .map(x => activityGroups.find(y => y[OLDEST_ACTIVITY_INDEX].hash === x)) + .filter(isDefined); + + return onlyUniqueActivitites; +}; + export const useContractActivity = (tokenSlug?: string): UseActivityInterface => { const dispatch = useDispatch(); const selectedAccount = useSelectedAccountSelector(); @@ -25,6 +35,7 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => const lastOperationRef = useRef(); const [isAllLoaded, setIsAllLoaded] = useState(false); + const [isLoading, setIsLoading] = useState(false); const [activities, setActivities] = useState>([]); const knownBakers = useMemo>( @@ -43,31 +54,21 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => const initialLoad = useCallback( async (refresh = false) => { - const { activities, reachedTheEnd, oldestOperation } = await loadActivity( - selectedRpcUrl, - selectedAccount, - tokenSlug, - knownBakers - ); + const { + activities: newActivity, + reachedTheEnd, + oldestOperation + } = await loadActivity(selectedRpcUrl, selectedAccount, tokenSlug, knownBakers, lastOperationRef.current); - lastOperationRef.current = oldestOperation ?? lastOperationRef.current; + lastOperationRef.current = oldestOperation; if (reachedTheEnd) { setIsAllLoaded(true); } if (refresh === true) { - setActivities(prev => { - const allActivities = [...activities, ...prev]; - const allHashes = allActivities.map(x => x[OLDEST_ACTIVITY_INDEX]).map(x => x.hash); - const onlyUniqueHashes = uniq(allHashes); - const onlyUniqueActivitites = onlyUniqueHashes - .map(x => allActivities.find(y => y[OLDEST_ACTIVITY_INDEX].hash === x)) - .filter(isDefined); - - return onlyUniqueActivitites; - }); + setActivities(prev => getUniqActivities([...prev, ...newActivity])); } else { - setActivities(activities); + setActivities(newActivity); } }, [selectedRpcUrl, selectedAccount, tokenSlug, knownBakers] @@ -83,22 +84,31 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => initialLoad(true); }; - const handleUpdate = async () => { - if (activities.length > 0 && !isAllLoaded) { - const { - activities: newActivity, - reachedTheEnd, - oldestOperation - } = await loadActivity(selectedRpcUrl, selectedAccount, tokenSlug, knownBakers, lastOperationRef.current); + const handleUpdate = useCallback(async () => { + try { + if (!isAllLoaded && !isLoading) { + setIsLoading(true); - lastOperationRef.current = oldestOperation ?? lastOperationRef.current; + const { + activities: newActivity, + reachedTheEnd, + oldestOperation + } = await loadActivity(selectedRpcUrl, selectedAccount, tokenSlug, knownBakers, lastOperationRef.current); - if (reachedTheEnd) { - setIsAllLoaded(true); + lastOperationRef.current = oldestOperation; + + setActivities(prev => getUniqActivities([...prev, ...newActivity])); + + if (reachedTheEnd) { + setIsAllLoaded(true); + } } - setActivities(prev => [...prev, ...newActivity]); + } catch (error) { + console.error('handleUpdate Error: ', error); + } finally { + setIsLoading(false); } - }; + }, [selectedRpcUrl, selectedAccount, tokenSlug, knownBakers, isLoading]); return { handleUpdate, From fec1db620e59ce9471bbd5b9dcdd3085573d45da Mon Sep 17 00:00:00 2001 From: herkoss Date: Fri, 25 Aug 2023 10:46:14 +0300 Subject: [PATCH 27/43] TW-786 Added memo to callbacks --- .../activity-groups-list.tsx | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/components/activity-groups-list/activity-groups-list.tsx b/src/components/activity-groups-list/activity-groups-list.tsx index bbc2e6872..839fe63b1 100644 --- a/src/components/activity-groups-list/activity-groups-list.tsx +++ b/src/components/activity-groups-list/activity-groups-list.tsx @@ -1,4 +1,4 @@ -import React, { FC, memo, useMemo, useRef } from 'react'; +import React, { FC, memo, useCallback, useMemo, useRef } from 'react'; import { SectionList, Text, View } from 'react-native'; import { emptyFn } from '../../config/general'; @@ -19,6 +19,8 @@ interface Props { onOptimalPromotionError?: () => void; } +const SECTIONS_AMOUNT_TO_RENDER = 10; + const renderItem = (item: ActivityGroup) => ; export const ActivityGroupsList: FC = memo( @@ -56,6 +58,17 @@ export const ActivityGroupsList: FC = memo( const isShowPlaceholder: boolean = useMemo(() => activityGroups.length === 0, [activityGroups]); + const onEndReached = useCallback(() => { + if (!onEndReachedCalledDuringMomentum.current || sections.length < SECTIONS_AMOUNT_TO_RENDER) { + handleUpdate(); + onEndReachedCalledDuringMomentum.current = true; + } + }, [handleUpdate, sections]); + + const onMomentumScrollBegin = useCallback(() => { + onEndReachedCalledDuringMomentum.current = false; + }, []); + return ( <> {isShowPlaceholder ? ( @@ -75,20 +88,13 @@ export const ActivityGroupsList: FC = memo( ) : ( { - onEndReachedCalledDuringMomentum.current = false; - }} - onEndReached={() => { - if (!onEndReachedCalledDuringMomentum.current || sections.length < 10) { - handleUpdate(); - onEndReachedCalledDuringMomentum.current = true; - } - }} + onMomentumScrollBegin={onMomentumScrollBegin} + onEndReached={onEndReached} keyExtractor={item => item[0].hash} bounces={false} renderItem={({ item }) => renderItem(item)} From 02ccc416109a27581e1fe57d11a983204e5bf538 Mon Sep 17 00:00:00 2001 From: herkoss Date: Fri, 25 Aug 2023 13:50:06 +0300 Subject: [PATCH 28/43] TW-786 FIxed comments --- .../activity-groups-list.tsx | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/components/activity-groups-list/activity-groups-list.tsx b/src/components/activity-groups-list/activity-groups-list.tsx index 839fe63b1..ef702545b 100644 --- a/src/components/activity-groups-list/activity-groups-list.tsx +++ b/src/components/activity-groups-list/activity-groups-list.tsx @@ -1,5 +1,5 @@ import React, { FC, memo, useCallback, useMemo, useRef } from 'react'; -import { SectionList, Text, View } from 'react-native'; +import { SectionList, SectionListData, SectionListRenderItemInfo, Text, View } from 'react-native'; import { emptyFn } from '../../config/general'; import { useFakeRefreshControlProps } from '../../hooks/use-fake-refresh-control-props.hook'; @@ -12,6 +12,11 @@ import { ActivityGroupItem } from './activity-group-item/activity-group-item'; import { ActivityGroupsListSelectors } from './activity-groups-list.selectors'; import { useActivityGroupsListStyles } from './activity-groups-list.styles'; +type RenderItem = SectionListRenderItemInfo; +type RenderSectionHeader = { + section: SectionListData; +}; + interface Props { activityGroups: ActivityGroup[]; shouldShowPromotion?: boolean; @@ -19,9 +24,9 @@ interface Props { onOptimalPromotionError?: () => void; } -const SECTIONS_AMOUNT_TO_RENDER = 10; +const SECTIONS_AMOUNT_TO_RENDER_PER_BATCH = 10; -const renderItem = (item: ActivityGroup) => ; +const keyExtractor = (item: ActivityGroup) => item[0].hash; export const ActivityGroupsList: FC = memo( ({ activityGroups, handleUpdate = emptyFn, shouldShowPromotion = false, onOptimalPromotionError }) => { @@ -59,7 +64,7 @@ export const ActivityGroupsList: FC = memo( const isShowPlaceholder: boolean = useMemo(() => activityGroups.length === 0, [activityGroups]); const onEndReached = useCallback(() => { - if (!onEndReachedCalledDuringMomentum.current || sections.length < SECTIONS_AMOUNT_TO_RENDER) { + if (!onEndReachedCalledDuringMomentum.current || sections.length < SECTIONS_AMOUNT_TO_RENDER_PER_BATCH) { handleUpdate(); onEndReachedCalledDuringMomentum.current = true; } @@ -69,6 +74,13 @@ export const ActivityGroupsList: FC = memo( onEndReachedCalledDuringMomentum.current = false; }, []); + const renderItem = useCallback(({ item }: RenderItem) => , []); + + const renderSectionHeader = useCallback( + ({ section: { title } }: RenderSectionHeader) => {title}, + [] + ); + return ( <> {isShowPlaceholder ? ( @@ -88,17 +100,17 @@ export const ActivityGroupsList: FC = memo( ) : ( item[0].hash} + keyExtractor={keyExtractor} bounces={false} - renderItem={({ item }) => renderItem(item)} - renderSectionHeader={({ section: { title } }) => {title}} + renderItem={renderItem} + renderSectionHeader={renderSectionHeader} refreshControl={} /> )} From 7965bfcee1884d4182cbaecf1d098b59f5d26645 Mon Sep 17 00:00:00 2001 From: herkoss Date: Fri, 25 Aug 2023 14:43:27 +0300 Subject: [PATCH 29/43] TW-786 FIxed render item functinon --- .../activity-groups-list.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/components/activity-groups-list/activity-groups-list.tsx b/src/components/activity-groups-list/activity-groups-list.tsx index ef702545b..37ffe334c 100644 --- a/src/components/activity-groups-list/activity-groups-list.tsx +++ b/src/components/activity-groups-list/activity-groups-list.tsx @@ -74,7 +74,24 @@ export const ActivityGroupsList: FC = memo( onEndReachedCalledDuringMomentum.current = false; }, []); - const renderItem = useCallback(({ item }: RenderItem) => , []); + const renderItem = useCallback( + ({ item, index, section }: RenderItem) => ( + <> + + {index === 0 && section.title === sections[0].title && shouldShowPromotion && ( + + + + )} + + ), + [sections] + ); const renderSectionHeader = useCallback( ({ section: { title } }: RenderSectionHeader) => {title}, From 5cec3e2d47003fd66dde80c69aae0bb35b77f317 Mon Sep 17 00:00:00 2001 From: Dmytro Herko <61412282+herkoss@users.noreply.github.com> Date: Mon, 28 Aug 2023 11:20:13 +0300 Subject: [PATCH 30/43] Update src/hooks/use-contract-activity.ts Co-authored-by: Alex --- src/hooks/use-contract-activity.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/use-contract-activity.ts b/src/hooks/use-contract-activity.ts index eae9b8caa..5c3edaa63 100644 --- a/src/hooks/use-contract-activity.ts +++ b/src/hooks/use-contract-activity.ts @@ -104,7 +104,7 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => } } } catch (error) { - console.error('handleUpdate Error: ', error); + console.error(error); } finally { setIsLoading(false); } From 92fda8148da9f3c289a4da3bdd06ad3ae3a02875 Mon Sep 17 00:00:00 2001 From: herkoss Date: Mon, 28 Aug 2023 12:50:08 +0300 Subject: [PATCH 31/43] TW-786 Fixed comments --- .../activity-groups-list.tsx | 18 ++---------------- src/hooks/use-contract-activity.ts | 18 ++---------------- 2 files changed, 4 insertions(+), 32 deletions(-) diff --git a/src/components/activity-groups-list/activity-groups-list.tsx b/src/components/activity-groups-list/activity-groups-list.tsx index 37ffe334c..c67b26dfb 100644 --- a/src/components/activity-groups-list/activity-groups-list.tsx +++ b/src/components/activity-groups-list/activity-groups-list.tsx @@ -1,4 +1,4 @@ -import React, { FC, memo, useCallback, useMemo, useRef } from 'react'; +import React, { FC, memo, useCallback, useMemo } from 'react'; import { SectionList, SectionListData, SectionListRenderItemInfo, Text, View } from 'react-native'; import { emptyFn } from '../../config/general'; @@ -32,8 +32,6 @@ export const ActivityGroupsList: FC = memo( ({ activityGroups, handleUpdate = emptyFn, shouldShowPromotion = false, onOptimalPromotionError }) => { const styles = useActivityGroupsListStyles(); - const onEndReachedCalledDuringMomentum = useRef(false); - const fakeRefreshControlProps = useFakeRefreshControlProps(); const sections = useMemo(() => { @@ -63,17 +61,6 @@ export const ActivityGroupsList: FC = memo( const isShowPlaceholder: boolean = useMemo(() => activityGroups.length === 0, [activityGroups]); - const onEndReached = useCallback(() => { - if (!onEndReachedCalledDuringMomentum.current || sections.length < SECTIONS_AMOUNT_TO_RENDER_PER_BATCH) { - handleUpdate(); - onEndReachedCalledDuringMomentum.current = true; - } - }, [handleUpdate, sections]); - - const onMomentumScrollBegin = useCallback(() => { - onEndReachedCalledDuringMomentum.current = false; - }, []); - const renderItem = useCallback( ({ item, index, section }: RenderItem) => ( <> @@ -122,8 +109,7 @@ export const ActivityGroupsList: FC = memo( stickySectionHeadersEnabled={true} contentContainerStyle={styles.sectionListContentContainer} onEndReachedThreshold={0.5} - onMomentumScrollBegin={onMomentumScrollBegin} - onEndReached={onEndReached} + onEndReached={handleUpdate} keyExtractor={keyExtractor} bounces={false} renderItem={renderItem} diff --git a/src/hooks/use-contract-activity.ts b/src/hooks/use-contract-activity.ts index 5c3edaa63..861045994 100644 --- a/src/hooks/use-contract-activity.ts +++ b/src/hooks/use-contract-activity.ts @@ -1,5 +1,4 @@ import { TzktMemberInterface, TzktOperation } from '@temple-wallet/transactions-parser'; -import { uniq } from 'lodash-es'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; @@ -11,21 +10,8 @@ import { useBakersListSelector } from 'src/store/baking/baking-selectors'; import { UseActivityInterface } from '../interfaces/use-activity.interface'; import { useSelectedRpcUrlSelector } from '../store/settings/settings-selectors'; import { useSelectedAccountSelector } from '../store/wallet/wallet-selectors'; -import { isDefined } from '../utils/is-defined'; import { loadActivity } from '../utils/token-operations.util'; -const OLDEST_ACTIVITY_INDEX = 0; - -const getUniqActivities = (activityGroups: Array) => { - const allHashes = activityGroups.map(x => x[OLDEST_ACTIVITY_INDEX]).map(x => x.hash); - const onlyUniqueHashes = uniq(allHashes); - const onlyUniqueActivitites = onlyUniqueHashes - .map(x => activityGroups.find(y => y[OLDEST_ACTIVITY_INDEX].hash === x)) - .filter(isDefined); - - return onlyUniqueActivitites; -}; - export const useContractActivity = (tokenSlug?: string): UseActivityInterface => { const dispatch = useDispatch(); const selectedAccount = useSelectedAccountSelector(); @@ -66,7 +52,7 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => setIsAllLoaded(true); } if (refresh === true) { - setActivities(prev => getUniqActivities([...prev, ...newActivity])); + setActivities(prev => [...prev, ...newActivity]); } else { setActivities(newActivity); } @@ -97,7 +83,7 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => lastOperationRef.current = oldestOperation; - setActivities(prev => getUniqActivities([...prev, ...newActivity])); + setActivities(prev => [...prev, ...newActivity]); if (reachedTheEnd) { setIsAllLoaded(true); From bf42b6e9eb9cf482912635d9b05e96320660a1a8 Mon Sep 17 00:00:00 2001 From: herkoss Date: Wed, 30 Aug 2023 16:09:14 +0300 Subject: [PATCH 32/43] WIP --- package.json | 4 +-- .../activity-group-amount-change.tsx | 3 ++ .../activity-group-item.tsx | 20 +++++------- .../activity-item/activity-item.tsx | 27 ++++++++++++++++ .../activity-group-item/info/approve.tsx | 17 ++++++++++ src/hooks/use-contract-activity.ts | 32 +++++++++++-------- src/interfaces/activity.interface.ts | 3 +- src/utils/token-operations.util.ts | 4 +-- yarn.lock | 22 ++++++------- 9 files changed, 91 insertions(+), 41 deletions(-) create mode 100644 src/components/activity-groups-list/activity-group-item/activity-item/activity-item.tsx create mode 100644 src/components/activity-groups-list/activity-group-item/info/approve.tsx diff --git a/package.json b/package.json index d073be282..f8b70753b 100644 --- a/package.json +++ b/package.json @@ -57,8 +57,8 @@ "@taquito/tzip12": "17.0.0", "@taquito/tzip16": "17.0.0", "@taquito/utils": "17.0.0", - "@temple-wallet/transactions-parser": "^2.0.0", - "@temple-wallet/wallet-address-validator": "^0.4.2", + "@temple-wallet/transactions-parser": "^3.0.0", + "@temple-wallet/wallet-address-validator": "^0.4.3", "@tezos-domains/core": "1.26.0", "@tezos-domains/taquito-client": "1.26.0", "@tradle/react-native-http": "^2.0.1", diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx index 6de5880bf..a189255c2 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx @@ -24,6 +24,9 @@ export const ActivityGroupAmountChange: FC = ({ nonZeroAmounts, textSize const styles = useActivityGroupAmountChangeStyles(); const children = useMemo(() => { + if (nonZeroAmounts.length === 0) { + return No amount; + } const { isPositive, parsedAmount, symbol } = nonZeroAmounts[FIRST_AMOUNT_INDEX]; if (isSingleTokenOperation(nonZeroAmounts)) { diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx index c050c9748..9df89e508 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.tsx @@ -1,14 +1,10 @@ import React, { FC, memo } from 'react'; import { View } from 'react-native'; -import { Divider } from 'src/components/divider/divider'; -import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; -import { ActivityGroup, emptyActivity } from 'src/interfaces/activity.interface'; -import { formatSize } from 'src/styles/format-size'; +import { ActivityGroup } from 'src/interfaces/activity.interface'; import { useActivityGroupItemStyles } from './activity-group-item.styles'; -import { Details } from './details'; -import { Info } from './info/info'; +import { ActivityItem } from './activity-item/activity-item'; interface Props { group: ActivityGroup; @@ -16,14 +12,14 @@ interface Props { export const ActivityGroupItem: FC = memo(({ group }) => { const styles = useActivityGroupItemStyles(); - const firstActivity = group[0] ?? emptyActivity; - const nonZeroAmounts = useNonZeroAmounts(firstActivity.tokensDeltas); return ( - - - -
+ + {group.map(activity => ( + + + + ))} ); }); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/activity-item.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/activity-item.tsx new file mode 100644 index 000000000..6834fc7a0 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-item/activity-item.tsx @@ -0,0 +1,27 @@ +import { Activity } from '@temple-wallet/transactions-parser'; +import React, { FC } from 'react'; +import { View } from 'react-native'; + +import { Divider } from 'src/components/divider/divider'; +import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; +import { formatSize } from 'src/styles/format-size'; + +import { Details } from '../details'; +import { Info } from '../info/info'; + +interface Props { + activity: Activity; +} + +export const ActivityItem: FC = ({ activity }) => { + const nonZeroAmounts = useNonZeroAmounts(activity.tokensDeltas); + console.log('nonZeroAmounts: ', nonZeroAmounts); + + return ( + + + +
+ + ); +}; diff --git a/src/components/activity-groups-list/activity-group-item/info/approve.tsx b/src/components/activity-groups-list/activity-group-item/info/approve.tsx new file mode 100644 index 000000000..5f5f60b0c --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/info/approve.tsx @@ -0,0 +1,17 @@ +import React, { FC } from 'react'; +import { View, Text } from 'react-native'; + +interface Props { + spender: string; + symbol: string; +} + +export const Approve: FC = ({ spender, symbol }) => { + return ( + + Approve + To: {spender} + {symbol} + + ); +}; diff --git a/src/hooks/use-contract-activity.ts b/src/hooks/use-contract-activity.ts index 861045994..9e4da7577 100644 --- a/src/hooks/use-contract-activity.ts +++ b/src/hooks/use-contract-activity.ts @@ -40,21 +40,25 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => const initialLoad = useCallback( async (refresh = false) => { - const { - activities: newActivity, - reachedTheEnd, - oldestOperation - } = await loadActivity(selectedRpcUrl, selectedAccount, tokenSlug, knownBakers, lastOperationRef.current); + try { + const { + activities: newActivity, + reachedTheEnd, + oldestOperation + } = await loadActivity(selectedRpcUrl, selectedAccount, tokenSlug, knownBakers, lastOperationRef.current); - lastOperationRef.current = oldestOperation; + lastOperationRef.current = oldestOperation; - if (reachedTheEnd) { - setIsAllLoaded(true); - } - if (refresh === true) { - setActivities(prev => [...prev, ...newActivity]); - } else { - setActivities(newActivity); + if (reachedTheEnd) { + setIsAllLoaded(true); + } + if (refresh === true) { + setActivities(prev => [...prev, ...newActivity]); + } else { + setActivities(newActivity); + } + } catch (error) { + console.error(error); } }, [selectedRpcUrl, selectedAccount, tokenSlug, knownBakers] @@ -96,6 +100,8 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => } }, [selectedRpcUrl, selectedAccount, tokenSlug, knownBakers, isLoading]); + console.log('activities: ', activities); + return { handleUpdate, handleRefresh, diff --git a/src/interfaces/activity.interface.ts b/src/interfaces/activity.interface.ts index 4d4556016..e35cdc268 100644 --- a/src/interfaces/activity.interface.ts +++ b/src/interfaces/activity.interface.ts @@ -15,5 +15,6 @@ export const emptyActivity: Activity = { id: 0, timestamp: '', from: emptyMember, - to: emptyMember + to: emptyMember, + _isSecondary: false }; diff --git a/src/utils/token-operations.util.ts b/src/utils/token-operations.util.ts index 60ef34f24..c87d0a0ea 100644 --- a/src/utils/token-operations.util.ts +++ b/src/utils/token-operations.util.ts @@ -1,4 +1,4 @@ -import { Activity, TzktMemberInterface, TzktOperation, parseTransactions } from '@temple-wallet/transactions-parser'; +import { Activity, TzktMemberInterface, TzktOperation, parseOperations } from '@temple-wallet/transactions-parser'; import { LiquidityBakingMintOrBurnInterface } from '@temple-wallet/transactions-parser/dist/types/liquidity-baking'; import { Fa12TransferInterface, Fa2TransferInterface } from '@temple-wallet/transactions-parser/dist/types/transfers'; import { isEmpty, uniq } from 'lodash-es'; @@ -226,7 +226,7 @@ export const loadActivity = async ( const oldestOperationNew = operationGroups[operationGroups.length - 1]?.[0]; const activities = operationGroups - .map(group => parseTransactions(group, selectedAccount.publicKeyHash, knownBakers)) + .map(group => parseOperations(group, selectedAccount.publicKeyHash, knownBakers)) .filter(group => !isEmpty(group)); if (activities.length === 0) { diff --git a/yarn.lock b/yarn.lock index a0a3c1dbf..904ccbc75 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2931,9 +2931,9 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@noble/hashes@^1.2.0": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" - integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -3889,17 +3889,17 @@ elliptic "^6.5.4" typedarray-to-buffer "^4.0.0" -"@temple-wallet/transactions-parser@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@temple-wallet/transactions-parser/-/transactions-parser-1.0.0.tgz#2a78b25a9c5ff6b54c83ae0ed621260c5f28c062" - integrity sha512-Bwa3xB33zVaOd2xB5nRET1L2O9qElO6r3hkXNJmIVPD3skFkYlsU2yOegEn5/6ZsH0eZGQA1PMb3LMq3BWheDw== +"@temple-wallet/transactions-parser@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@temple-wallet/transactions-parser/-/transactions-parser-3.0.0.tgz#4977f7bc6c836b0108beeae26c741acf2ff08b86" + integrity sha512-npEvtbjCgWASH1gWzsYKZOANGYCDy53dyAfhX0oN6swqIxZq3xd8tP+AZnYj0NzAq/eRIZk/5yJoQKKJD8kAxA== dependencies: bignumber.js "^9.1.0" -"@temple-wallet/wallet-address-validator@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@temple-wallet/wallet-address-validator/-/wallet-address-validator-0.4.2.tgz#1334a67aa71d0c397dd7c20a94245a612fd7feff" - integrity sha512-FPsHW+IYKBu1/qvGDGtwaCfyP60xPIKMPhGgbU+mUVN/AMsdgNf3FkG2hTuBC0jylToxuI+ijGGSzpIj+Yl1Qg== +"@temple-wallet/wallet-address-validator@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@temple-wallet/wallet-address-validator/-/wallet-address-validator-0.4.3.tgz#4bb7905a824e290872b7a7fc449df2e8c332e9e1" + integrity sha512-vP+K1bEXLw/2MRbSAaGrT7ZEFYyrb/C/NfdTBZdeKjwinqduz2aFHrun8bBOUMc9MQnKxyTIkiZu2g6i2z9tyw== dependencies: base-x "^3.0.4" bs58check "^3.0.1" From 7dbb94bdcf50876a37f84e81246d8daf91ba2a65 Mon Sep 17 00:00:00 2001 From: herkoss Date: Fri, 1 Sep 2023 04:40:02 +0300 Subject: [PATCH 33/43] TW-783 Finished working on unknown operations --- .../activity-group-amount-change.tsx | 3 +- .../activity-group-item.styles.ts | 28 +-- .../activity-item/abstract-item.tsx | 47 +++++ .../activity-item/activity-item.tsx | 45 ++--- .../baking-rewards.tsx | 63 ++++++- .../activity-item/change-allowance.tsx | 160 ++++++++++++++++++ .../activity-item/delegate.tsx | 89 ++++++++++ .../activity-item/interaction.tsx | 128 ++++++++++++++ .../activity-item/item.props.ts | 5 + .../receive.tsx} | 57 ++++++- .../send.tsx} | 57 ++++++- .../unknown.tsx} | 59 +++++-- .../details-card/delegate.tsx | 40 ----- .../details-card/details-card.tsx | 36 ---- .../activity-group-item/details.tsx | 53 ------ .../activity-group-item/info/approve.tsx | 17 -- .../info/baking-rewards.tsx | 47 ----- .../activity-group-item/info/delegation.tsx | 39 ----- .../activity-group-item/info/info.tsx | 29 ---- .../activity-group-item/info/receive.tsx | 38 ----- .../activity-group-item/info/send.tsx | 35 ---- .../activity-group-item/info/unknown-info.tsx | 29 ---- src/hooks/use-contract-activity.ts | 2 - 23 files changed, 678 insertions(+), 428 deletions(-) create mode 100644 src/components/activity-groups-list/activity-group-item/activity-item/abstract-item.tsx rename src/components/activity-groups-list/activity-group-item/{details-card => activity-item}/baking-rewards.tsx (51%) create mode 100644 src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx create mode 100644 src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx create mode 100644 src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx create mode 100644 src/components/activity-groups-list/activity-group-item/activity-item/item.props.ts rename src/components/activity-groups-list/activity-group-item/{details-card/receive-tokens.tsx => activity-item/receive.tsx} (53%) rename src/components/activity-groups-list/activity-group-item/{details-card/send-tokens.tsx => activity-item/send.tsx} (53%) rename src/components/activity-groups-list/activity-group-item/{details-card/unknown-details.tsx => activity-item/unknown.tsx} (58%) delete mode 100644 src/components/activity-groups-list/activity-group-item/details-card/delegate.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/details.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/info/approve.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/info/delegation.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/info/info.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/info/receive.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/info/send.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/info/unknown-info.tsx diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx index a189255c2..75a74e69b 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx @@ -25,8 +25,9 @@ export const ActivityGroupAmountChange: FC = ({ nonZeroAmounts, textSize const children = useMemo(() => { if (nonZeroAmounts.length === 0) { - return No amount; + return null; } + const { isPositive, parsedAmount, symbol } = nonZeroAmounts[FIRST_AMOUNT_INDEX]; if (isSingleTokenOperation(nonZeroAmounts)) { diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts index da7519444..cb312a6e2 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts @@ -9,12 +9,6 @@ export const useActivityGroupItemStyles = createUseStyles(({ colors, typography flex: { flex: 1 }, - card: { - marginTop: formatSize(12), - paddingHorizontal: formatSize(12), - borderRadius: formatSize(8), - backgroundColor: colors.cardBG - }, oprationTitle: { ...typography.numbersRegular15, color: colors.black @@ -37,16 +31,25 @@ export const useActivityGroupItemStyles = createUseStyles(({ colors, typography }, robotBackground: { backgroundColor: colors.navigation - } -})); - -export const useActivityDetailsStyles = createUseStyles(({ colors }) => ({ + }, + red: { + backgroundColor: 'red' + }, + green: { + backgroundColor: 'green' + }, + chevron: { + padding: formatSize(4) + }, card: { marginTop: formatSize(12), paddingHorizontal: formatSize(12), borderRadius: formatSize(8), backgroundColor: colors.cardBG - }, + } +})); + +export const useActivityDetailsStyles = createUseStyles(({ colors }) => ({ itemWrapper: { flexDirection: 'row', justifyContent: 'space-between', @@ -59,9 +62,6 @@ export const useActivityDetailsStyles = createUseStyles(({ colors }) => ({ borderBottomWidth: formatSize(0.5), borderBottomColor: colors.lines }, - chevron: { - padding: formatSize(4) - }, hashChip: { height: formatSize(24) }, diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/abstract-item.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/abstract-item.tsx new file mode 100644 index 000000000..7dd80d2fe --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-item/abstract-item.tsx @@ -0,0 +1,47 @@ +import { TzktOperationStatus } from '@temple-wallet/transactions-parser'; +import React, { FC, ReactNode, useCallback, useState } from 'react'; +import { View } from 'react-native'; + +import { Divider } from 'src/components/divider/divider'; +import { Icon } from 'src/components/icon/icon'; +import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics'; +import { formatSize } from 'src/styles/format-size'; + +import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; +import { ActivityStatusBadge } from '../activity-status-badge/activity-status-badge'; +import { ActivityTime } from '../activity-time/activity-time'; +import { ActivityGroupItemSelectors } from '../selectors'; + +export const AbstractItem: FC<{ status: TzktOperationStatus; timestamp: string; face: ReactNode; details: ReactNode }> = + ({ status, timestamp, face, details }) => { + const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + + const [areDetailsVisible, setAreDetailsVisible] = useState(false); + const handleOpenActivityDetailsPress = useCallback(() => setAreDetailsVisible(prevState => !prevState), []); + + return ( + + {face} + + + + + + + + + + + + + {areDetailsVisible && {details}} + + + ); + }; diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/activity-item.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/activity-item.tsx index 6834fc7a0..a7eed7840 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/activity-item.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/activity-item.tsx @@ -1,27 +1,28 @@ -import { Activity } from '@temple-wallet/transactions-parser'; +import { ActivityType } from '@temple-wallet/transactions-parser'; import React, { FC } from 'react'; -import { View } from 'react-native'; -import { Divider } from 'src/components/divider/divider'; -import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; -import { formatSize } from 'src/styles/format-size'; +import { BakingRewards } from './baking-rewards'; +import { Delegate } from './delegate'; +import { Interaction } from './interaction'; +import { ActivityItemProps } from './item.props'; +import { Receive } from './receive'; +import { Send } from './send'; +import { Unknown } from './unknown'; -import { Details } from '../details'; -import { Info } from '../info/info'; +export const ActivityItem: FC = ({ activity }) => { + switch (activity.type) { + case ActivityType.Send: + return ; + case ActivityType.Recieve: + return ; + case ActivityType.BakingRewards: + return ; + case ActivityType.Delegation: + return ; + case ActivityType.Interaction: + return ; -interface Props { - activity: Activity; -} - -export const ActivityItem: FC = ({ activity }) => { - const nonZeroAmounts = useNonZeroAmounts(activity.tokensDeltas); - console.log('nonZeroAmounts: ', nonZeroAmounts); - - return ( - - - -
- - ); + default: + return ; + } }; diff --git a/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx similarity index 51% rename from src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx rename to src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx index 834638c47..5f5f70a13 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx @@ -1,29 +1,82 @@ import React, { FC } from 'react'; import { View, Text } from 'react-native'; +import { AvatarImage } from 'src/components/avatar-image/avatar-image'; import { Divider } from 'src/components/divider/divider'; import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; +import { RobotIcon } from 'src/components/robot-icon/robot-icon'; import { WalletAddress } from 'src/components/wallet-address/wallet-address'; +import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; +import { useBakerByAddressSelector } from 'src/store/baking/baking-selectors'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; import { calculateDollarValue } from 'src/utils/activity.utils'; +import { truncateLongAddress } from 'src/utils/address.utils'; +import { isDefined } from 'src/utils/is-defined'; import { tzktUrl } from 'src/utils/linking.util'; import { ActivityGroupAmountChange, TextSize } from '../activity-group-amount-change/activity-group-amount-change'; import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; +import { + useActivityCommonStyles, + useActivityDetailsStyles, + useActivityGroupItemStyles +} from '../activity-group-item.styles'; import { ActivityGroupItemSelectors } from '../selectors'; +import { AbstractItem } from './abstract-item'; +import { ActivityItemProps } from './item.props'; -export const BakingRewardsDetails: FC<{ nonZeroAmounts: Array; address: string; hash: string }> = ({ - nonZeroAmounts, +export const BakingRewards: FC = ({ activity }) => { + const nonZeroAmounts = useNonZeroAmounts(activity.tokensDeltas); + + return ( + } + details={
} + status={activity.status} + timestamp={activity.timestamp} + /> + ); +}; + +const Face: FC<{ address: string; nonZeroAmounts: Array }> = ({ address, nonZeroAmounts }) => { + const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + + const baker = useBakerByAddressSelector(address); + + return ( + + {isDefined(baker) && isDefined(baker.logo) ? ( + + ) : ( + + )} + + + + Baking rewards + + + + From: {baker?.name ?? truncateLongAddress(address)} + + + + + ); +}; + +const Details: FC<{ hash: string; address: string; nonZeroAmounts: Array }> = ({ + hash, address, - hash + nonZeroAmounts }) => { - const selectedRpcUrl = useSelectedRpcUrlSelector(); const styles = useActivityDetailsStyles(); const commonStyles = useActivityCommonStyles(); + const selectedRpcUrl = useSelectedRpcUrlSelector(); return ( <> diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx new file mode 100644 index 000000000..c9c04c12f --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx @@ -0,0 +1,160 @@ +import { AllowanceInteractionActivity } from '@temple-wallet/transactions-parser'; +import React, { FC } from 'react'; +import { View, Text } from 'react-native'; + +import { Divider } from 'src/components/divider/divider'; +import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; +import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; +import { WalletAddress } from 'src/components/wallet-address/wallet-address'; +import { useTokenMetadataGetter } from 'src/hooks/use-token-metadata-getter.hook'; +import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { formatSize } from 'src/styles/format-size'; +import { truncateLongAddress } from 'src/utils/address.utils'; +import { tzktUrl } from 'src/utils/linking.util'; + +import { + useActivityCommonStyles, + useActivityDetailsStyles, + useActivityGroupItemStyles +} from '../activity-group-item.styles'; +import { ActivityGroupItemSelectors } from '../selectors'; +import { AbstractItem } from './abstract-item'; + +const AMOUNT_INDEX = 0; + +export const ChangeAllowance: FC<{ activity: AllowanceInteractionActivity }> = ({ activity }) => { + const getTokenMetadata = useTokenMetadataGetter(); + + const metadata = getTokenMetadata(activity.allowanceChanges[AMOUNT_INDEX].tokenSlug); + const isRevoke = activity.allowanceChanges[AMOUNT_INDEX].atomicAmount.isZero(); + + if (isRevoke) { + return ( + } + details={} + /> + ); + } + + return ( + } + details={} + /> + ); +}; + +const ApproveFace: FC<{ address: string; symbol: string }> = ({ address, symbol }) => { + const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + + return ( + + + + Approve + {symbol} + + + To: {truncateLongAddress(address)} + + + + ); +}; +const RevokeFace: FC<{ address: string; symbol: string }> = ({ address, symbol }) => { + const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + + return ( + + + + Revoke + {symbol} + + + From: {truncateLongAddress(address)} + + + + ); +}; + +const ApproveDetails: FC<{ address: string; symbol: string; hash: string }> = ({ address, symbol, hash }) => { + const styles = useActivityDetailsStyles(); + const commonStyles = useActivityCommonStyles(); + const selectedRpcUrl = useSelectedRpcUrlSelector(); + + return ( + <> + + Approved: + + {symbol} + + + + + To: + + + + + + TxHash: + + + + + + + + ); +}; +const RevokeDetails: FC<{ address: string; symbol: string; hash: string }> = ({ address, symbol, hash }) => { + const styles = useActivityDetailsStyles(); + const commonStyles = useActivityCommonStyles(); + const selectedRpcUrl = useSelectedRpcUrlSelector(); + + return ( + <> + + Revoked: + + {symbol} + + + + + From: + + + + + + TxHash: + + + + + + + + ); +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx new file mode 100644 index 000000000..13610bd8a --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx @@ -0,0 +1,89 @@ +import React, { FC } from 'react'; +import { View, Text } from 'react-native'; + +import { AvatarImage } from 'src/components/avatar-image/avatar-image'; +import { Divider } from 'src/components/divider/divider'; +import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; +import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; +import { RobotIcon } from 'src/components/robot-icon/robot-icon'; +import { WalletAddress } from 'src/components/wallet-address/wallet-address'; +import { useBakerByAddressSelector } from 'src/store/baking/baking-selectors'; +import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { formatSize } from 'src/styles/format-size'; +import { truncateLongAddress } from 'src/utils/address.utils'; +import { isDefined } from 'src/utils/is-defined'; +import { tzktUrl } from 'src/utils/linking.util'; + +import { + useActivityCommonStyles, + useActivityDetailsStyles, + useActivityGroupItemStyles +} from '../activity-group-item.styles'; +import { ActivityGroupItemSelectors } from '../selectors'; +import { AbstractItem } from './abstract-item'; +import { ActivityItemProps } from './item.props'; + +export const Delegate: FC = ({ activity }) => { + return ( + } + details={
} + status={activity.status} + timestamp={activity.timestamp} + /> + ); +}; + +const Face: FC<{ address: string }> = ({ address }) => { + const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + + const baker = useBakerByAddressSelector(address); + + return ( + + {isDefined(baker) && isDefined(baker.logo) ? ( + + ) : ( + + )} + + + + + Delegate + + + To: {baker?.name ?? truncateLongAddress(address)} + + + + ); +}; + +const Details: FC<{ hash: string; address: string }> = ({ hash, address }) => { + const styles = useActivityDetailsStyles(); + const commonStyles = useActivityCommonStyles(); + const selectedRpcUrl = useSelectedRpcUrlSelector(); + + return ( + <> + + To: + + + + + + + + TxHash: + + + + + + + + ); +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx new file mode 100644 index 000000000..f7d6ad1be --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx @@ -0,0 +1,128 @@ +import { ActivitySubtype, AllowanceInteractionActivity, InteractionActivity } from '@temple-wallet/transactions-parser'; +import { isEmpty } from 'lodash-es'; +import React, { FC, useMemo } from 'react'; +import { View, Text } from 'react-native'; + +import { Divider } from 'src/components/divider/divider'; +import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; +import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; +import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; +import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; +import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { formatSize } from 'src/styles/format-size'; +import { calculateDollarValue } from 'src/utils/activity.utils'; +import { isDefined } from 'src/utils/is-defined'; +import { tzktUrl } from 'src/utils/linking.util'; + +import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; +import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; +import { + useActivityCommonStyles, + useActivityDetailsStyles, + useActivityGroupItemStyles +} from '../activity-group-item.styles'; +import { ItemAmountChange } from '../item-amount-change/item-amount-change'; +import { ActivityGroupItemSelectors } from '../selectors'; +import { AbstractItem } from './abstract-item'; +import { ChangeAllowance } from './change-allowance'; +import { ActivityItemProps } from './item.props'; + +export const Interaction: FC = ({ activity }) => { + const nonZeroAmounts = useNonZeroAmounts(activity.tokensDeltas); + + switch ((activity as InteractionActivity).subtype) { + case ActivitySubtype.ChangeAllowance: + return ; + + default: + return ( + } + details={
} + /> + ); + } +}; + +const Face: FC<{ nonZeroAmounts: Array }> = ({ nonZeroAmounts }) => { + const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + + return ( + + + + Interaction + + + + - + + + + + ); +}; + +const Details: FC<{ hash: string; nonZeroAmounts: Array }> = ({ hash, nonZeroAmounts }) => { + const selectedRpcUrl = useSelectedRpcUrlSelector(); + const styles = useActivityDetailsStyles(); + + const commonStyles = useActivityCommonStyles(); + + const { positiveAmounts, negativeAmounts } = useMemo(() => { + const positiveAmounts: Array = []; + const negativeAmounts: Array = []; + + for (const amount of nonZeroAmounts) { + if (amount.isPositive) { + positiveAmounts.push(amount); + } else { + negativeAmounts.push(amount); + } + } + + return { positiveAmounts, negativeAmounts }; + }, [nonZeroAmounts]); + + return ( + <> + {!isEmpty(positiveAmounts) && ( + + Received: + + {positiveAmounts.map((amount, index) => ( + + + {isDefined(amount.fiatAmount) && } + + ))} + + + )} + {!isEmpty(negativeAmounts) && ( + + Sent: + + {negativeAmounts.map((amount, index) => ( + + + {isDefined(amount.fiatAmount) && } + + ))} + + + )} + + TxHash: + + + + + + + + ); +}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/item.props.ts b/src/components/activity-groups-list/activity-group-item/activity-item/item.props.ts new file mode 100644 index 000000000..29e26bd28 --- /dev/null +++ b/src/components/activity-groups-list/activity-group-item/activity-item/item.props.ts @@ -0,0 +1,5 @@ +import { Activity } from '@temple-wallet/transactions-parser'; + +export interface ActivityItemProps { + activity: Activity; +} diff --git a/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx similarity index 53% rename from src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx rename to src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx index 7181128ac..210ea5adb 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx @@ -4,26 +4,70 @@ import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; +import { RobotIcon } from 'src/components/robot-icon/robot-icon'; import { WalletAddress } from 'src/components/wallet-address/wallet-address'; +import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; import { calculateDollarValue } from 'src/utils/activity.utils'; +import { truncateLongAddress } from 'src/utils/address.utils'; import { tzktUrl } from 'src/utils/linking.util'; import { ActivityGroupAmountChange, TextSize } from '../activity-group-amount-change/activity-group-amount-change'; import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; +import { + useActivityCommonStyles, + useActivityDetailsStyles, + useActivityGroupItemStyles +} from '../activity-group-item.styles'; import { ActivityGroupItemSelectors } from '../selectors'; +import { AbstractItem } from './abstract-item'; +import { ActivityItemProps } from './item.props'; -export const ReceiveTokensDetails: FC<{ nonZeroAmounts: Array; address: string; hash: string }> = ({ - nonZeroAmounts, +export const Receive: FC = ({ activity }) => { + const nonZeroAmounts = useNonZeroAmounts(activity.tokensDeltas); + + return ( + } + details={
} + status={activity.status} + timestamp={activity.timestamp} + /> + ); +}; + +const Face: FC<{ address: string; nonZeroAmounts: Array }> = ({ address, nonZeroAmounts }) => { + const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + + return ( + <> + + + + + Receive + + + + From: {truncateLongAddress(address)} + + + + + ); +}; + +const Details: FC<{ hash: string; address: string; nonZeroAmounts: Array }> = ({ + hash, address, - hash + nonZeroAmounts }) => { - const selectedRpcUrl = useSelectedRpcUrlSelector(); const styles = useActivityDetailsStyles(); const commonStyles = useActivityCommonStyles(); + const selectedRpcUrl = useSelectedRpcUrlSelector(); return ( <> @@ -34,10 +78,13 @@ export const ReceiveTokensDetails: FC<{ nonZeroAmounts: Array; a + From: + + TxHash: diff --git a/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/send.tsx similarity index 53% rename from src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx rename to src/components/activity-groups-list/activity-group-item/activity-item/send.tsx index 13eac2c9e..4a0d2f81d 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/send.tsx @@ -4,27 +4,70 @@ import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; +import { RobotIcon } from 'src/components/robot-icon/robot-icon'; import { WalletAddress } from 'src/components/wallet-address/wallet-address'; +import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; import { calculateDollarValue } from 'src/utils/activity.utils'; +import { truncateLongAddress } from 'src/utils/address.utils'; import { tzktUrl } from 'src/utils/linking.util'; import { ActivityGroupAmountChange, TextSize } from '../activity-group-amount-change/activity-group-amount-change'; import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; +import { + useActivityCommonStyles, + useActivityDetailsStyles, + useActivityGroupItemStyles +} from '../activity-group-item.styles'; import { ActivityGroupItemSelectors } from '../selectors'; +import { AbstractItem } from './abstract-item'; +import { ActivityItemProps } from './item.props'; -export const SendTokensDetails: FC<{ nonZeroAmounts: Array; address: string; hash: string }> = ({ - nonZeroAmounts, +export const Send: FC = ({ activity }) => { + const nonZeroAmounts = useNonZeroAmounts(activity.tokensDeltas); + + return ( + } + details={
} + status={activity.status} + timestamp={activity.timestamp} + /> + ); +}; + +const Face: FC<{ address: string; nonZeroAmounts: Array }> = ({ address, nonZeroAmounts }) => { + const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + + return ( + <> + + + + + Send + + + + To: {truncateLongAddress(address)} + + + + + ); +}; + +const Details: FC<{ hash: string; address: string; nonZeroAmounts: Array }> = ({ + hash, address, - hash + nonZeroAmounts }) => { - const selectedRpcUrl = useSelectedRpcUrlSelector(); const styles = useActivityDetailsStyles(); - const commonStyles = useActivityCommonStyles(); + const selectedRpcUrl = useSelectedRpcUrlSelector(); return ( <> @@ -35,11 +78,13 @@ export const SendTokensDetails: FC<{ nonZeroAmounts: Array; addr + To: + TxHash: diff --git a/src/components/activity-groups-list/activity-group-item/details-card/unknown-details.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx similarity index 58% rename from src/components/activity-groups-list/activity-group-item/details-card/unknown-details.tsx rename to src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx index 953578248..7d37589f8 100644 --- a/src/components/activity-groups-list/activity-group-item/details-card/unknown-details.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx @@ -5,21 +5,60 @@ import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; +import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; +import { calculateDollarValue } from 'src/utils/activity.utils'; import { isDefined } from 'src/utils/is-defined'; import { tzktUrl } from 'src/utils/linking.util'; +import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; +import { + useActivityCommonStyles, + useActivityDetailsStyles, + useActivityGroupItemStyles +} from '../activity-group-item.styles'; import { ItemAmountChange } from '../item-amount-change/item-amount-change'; import { ActivityGroupItemSelectors } from '../selectors'; +import { AbstractItem } from './abstract-item'; +import { ActivityItemProps } from './item.props'; -export const UnknownDetails: FC<{ nonZeroAmounts: Array; hash: string }> = ({ - nonZeroAmounts, - hash -}) => { +export const Unknown: FC = ({ activity }) => { + const nonZeroAmounts = useNonZeroAmounts(activity.tokensDeltas); + + return ( + } + details={
} + /> + ); +}; + +const Face: FC<{ nonZeroAmounts: Array }> = ({ nonZeroAmounts }) => { + const styles = useActivityGroupItemStyles(); + const commonStyles = useActivityCommonStyles(); + + return ( + + + + Interaction + + + + - + + + + + ); +}; + +const Details: FC<{ hash: string; nonZeroAmounts: Array }> = ({ hash, nonZeroAmounts }) => { const selectedRpcUrl = useSelectedRpcUrlSelector(); const styles = useActivityDetailsStyles(); @@ -46,8 +85,8 @@ export const UnknownDetails: FC<{ nonZeroAmounts: Array; hash: s Received: - {positiveAmounts.map(amount => ( - + {positiveAmounts.map((amount, index) => ( + {isDefined(amount.fiatAmount) && } @@ -55,12 +94,12 @@ export const UnknownDetails: FC<{ nonZeroAmounts: Array; hash: s )} - {!isEmpty(positiveAmounts) && ( + {!isEmpty(negativeAmounts) && ( Sent: - {negativeAmounts.map(amount => ( - + {negativeAmounts.map((amount, index) => ( + {isDefined(amount.fiatAmount) && } diff --git a/src/components/activity-groups-list/activity-group-item/details-card/delegate.tsx b/src/components/activity-groups-list/activity-group-item/details-card/delegate.tsx deleted file mode 100644 index fccf094e7..000000000 --- a/src/components/activity-groups-list/activity-group-item/details-card/delegate.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -import { Divider } from 'src/components/divider/divider'; -import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; -import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; -import { WalletAddress } from 'src/components/wallet-address/wallet-address'; -import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; -import { formatSize } from 'src/styles/format-size'; -import { tzktUrl } from 'src/utils/linking.util'; - -import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; -import { ActivityGroupItemSelectors } from '../selectors'; - -export const DelegateDetails: FC<{ address: string | undefined; hash: string }> = ({ hash, address = '' }) => { - const selectedRpcUrl = useSelectedRpcUrlSelector(); - const styles = useActivityDetailsStyles(); - const commonStyles = useActivityCommonStyles(); - - return ( - <> - - To: - - - - - - - - TxHash: - - - - - - - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx b/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx deleted file mode 100644 index 5e43e7cdf..000000000 --- a/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; -import React, { FC } from 'react'; - -import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; - -import { BakingRewardsDetails } from './baking-rewards'; -import { DelegateDetails } from './delegate'; -import { ReceiveTokensDetails } from './receive-tokens'; -import { SendTokensDetails } from './send-tokens'; -import { UnknownDetails } from './unknown-details'; - -export const DetailsCard: FC<{ activity: Activity; nonZeroAmounts: Array }> = ({ - activity, - nonZeroAmounts -}) => { - switch (activity.type) { - case ActivityType.Send: - return ; - - case ActivityType.BakingRewards: - return ( - - ); - - case ActivityType.Recieve: - return ( - - ); - - case ActivityType.Delegation: - return ; - - default: - return ; - } -}; diff --git a/src/components/activity-groups-list/activity-group-item/details.tsx b/src/components/activity-groups-list/activity-group-item/details.tsx deleted file mode 100644 index 8b728db86..000000000 --- a/src/components/activity-groups-list/activity-group-item/details.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { Activity } from '@temple-wallet/transactions-parser'; -import React, { FC, useState, useCallback } from 'react'; -import { View } from 'react-native'; - -import { Divider } from 'src/components/divider/divider'; -import { Icon } from 'src/components/icon/icon'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; -import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics'; -import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; -import { formatSize } from 'src/styles/format-size'; - -import { useActivityCommonStyles, useActivityDetailsStyles } from './activity-group-item.styles'; -import { ActivityStatusBadge } from './activity-status-badge/activity-status-badge'; -import { ActivityTime } from './activity-time/activity-time'; -import { DetailsCard } from './details-card/details-card'; -import { ActivityGroupItemSelectors } from './selectors'; - -interface Props { - activity: Activity; - nonZeroAmounts: Array; -} - -export const Details: FC = ({ activity, nonZeroAmounts }) => { - const detailsStyles = useActivityDetailsStyles(); - const commonStyles = useActivityCommonStyles(); - - const [areDetailsVisible, setAreDetailsVisible] = useState(false); - const handleOpenActivityDetailsPress = useCallback(() => setAreDetailsVisible(prevState => !prevState), []); - - return ( - - - - - - - - - - - - {areDetailsVisible && ( - - - - )} - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/info/approve.tsx b/src/components/activity-groups-list/activity-group-item/info/approve.tsx deleted file mode 100644 index 5f5f60b0c..000000000 --- a/src/components/activity-groups-list/activity-group-item/info/approve.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -interface Props { - spender: string; - symbol: string; -} - -export const Approve: FC = ({ spender, symbol }) => { - return ( - - Approve - To: {spender} - {symbol} - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx b/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx deleted file mode 100644 index 901ebf576..000000000 --- a/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -import { AvatarImage } from 'src/components/avatar-image/avatar-image'; -import { Divider } from 'src/components/divider/divider'; -import { RobotIcon } from 'src/components/robot-icon/robot-icon'; -import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; -import { useBakerByAddressSelector } from 'src/store/baking/baking-selectors'; -import { formatSize } from 'src/styles/format-size'; -import { calculateDollarValue } from 'src/utils/activity.utils'; -import { truncateLongAddress } from 'src/utils/address.utils'; -import { isDefined } from 'src/utils/is-defined'; - -import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; -import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; - -export const BakingRewards: FC<{ address: string; nonZeroAmounts: Array }> = ({ - address, - nonZeroAmounts -}) => { - const styles = useActivityGroupItemStyles(); - const commonStyles = useActivityCommonStyles(); - - const baker = useBakerByAddressSelector(address); - - return ( - - {isDefined(baker) && isDefined(baker.logo) ? ( - - ) : ( - - )} - - - - Baking rewards - - - - From: {baker?.name ?? truncateLongAddress(address)} - - - - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/info/delegation.tsx b/src/components/activity-groups-list/activity-group-item/info/delegation.tsx deleted file mode 100644 index 473ea1dd8..000000000 --- a/src/components/activity-groups-list/activity-group-item/info/delegation.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -import { AvatarImage } from 'src/components/avatar-image/avatar-image'; -import { Divider } from 'src/components/divider/divider'; -import { RobotIcon } from 'src/components/robot-icon/robot-icon'; -import { useBakerByAddressSelector } from 'src/store/baking/baking-selectors'; -import { formatSize } from 'src/styles/format-size'; -import { truncateLongAddress } from 'src/utils/address.utils'; -import { isDefined } from 'src/utils/is-defined'; - -import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; - -export const Delegation: FC<{ address: string | undefined }> = ({ address = '' }) => { - const styles = useActivityGroupItemStyles(); - const commonStyles = useActivityCommonStyles(); - - const baker = useBakerByAddressSelector(address); - - return ( - - {isDefined(baker) && isDefined(baker.logo) ? ( - - ) : ( - - )} - - - - - Delegate - - - To: {baker?.name ?? truncateLongAddress(address)} - - - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/info/info.tsx b/src/components/activity-groups-list/activity-group-item/info/info.tsx deleted file mode 100644 index ac65f4385..000000000 --- a/src/components/activity-groups-list/activity-group-item/info/info.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; -import React, { FC } from 'react'; - -import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; - -import { BakingRewards } from './baking-rewards'; -import { Delegation } from './delegation'; -import { Receive } from './receive'; -import { Send } from './send'; -import { UnknownInfo } from './unknown-info'; - -export const Info: FC<{ activity: Activity; nonZeroAmounts: Array }> = ({ - activity, - nonZeroAmounts -}) => { - switch (activity.type) { - case ActivityType.Send: - return ; - case ActivityType.Recieve: - return ; - case ActivityType.BakingRewards: - return ; - case ActivityType.Delegation: - return ; - - default: - return ; - } -}; diff --git a/src/components/activity-groups-list/activity-group-item/info/receive.tsx b/src/components/activity-groups-list/activity-group-item/info/receive.tsx deleted file mode 100644 index 39e79f426..000000000 --- a/src/components/activity-groups-list/activity-group-item/info/receive.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -import { Divider } from 'src/components/divider/divider'; -import { RobotIcon } from 'src/components/robot-icon/robot-icon'; -import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; -import { formatSize } from 'src/styles/format-size'; -import { calculateDollarValue } from 'src/utils/activity.utils'; -import { truncateLongAddress } from 'src/utils/address.utils'; - -import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; -import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; - -export const Receive: FC<{ address: string; nonZeroAmounts: Array }> = ({ - address, - nonZeroAmounts -}) => { - const styles = useActivityGroupItemStyles(); - const commonStyles = useActivityCommonStyles(); - - return ( - - - - - - Receive - - - - From: {truncateLongAddress(address)} - - - - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/info/send.tsx b/src/components/activity-groups-list/activity-group-item/info/send.tsx deleted file mode 100644 index e94a11e73..000000000 --- a/src/components/activity-groups-list/activity-group-item/info/send.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -import { Divider } from 'src/components/divider/divider'; -import { RobotIcon } from 'src/components/robot-icon/robot-icon'; -import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; -import { formatSize } from 'src/styles/format-size'; -import { calculateDollarValue } from 'src/utils/activity.utils'; -import { truncateLongAddress } from 'src/utils/address.utils'; - -import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; -import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; - -export const Send: FC<{ address: string; nonZeroAmounts: Array }> = ({ address, nonZeroAmounts }) => { - const styles = useActivityGroupItemStyles(); - const commonStyles = useActivityCommonStyles(); - - return ( - - - - - - Send - - - - To: {truncateLongAddress(address)} - - - - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/info/unknown-info.tsx b/src/components/activity-groups-list/activity-group-item/info/unknown-info.tsx deleted file mode 100644 index 6949e1b1a..000000000 --- a/src/components/activity-groups-list/activity-group-item/info/unknown-info.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; -import { calculateDollarValue } from 'src/utils/activity.utils'; - -import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; -import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; - -export const UnknownInfo: FC<{ nonZeroAmounts: Array }> = ({ nonZeroAmounts }) => { - const styles = useActivityGroupItemStyles(); - const commonStyles = useActivityCommonStyles(); - - return ( - - - - Interaction - - - - - - - - - - ); -}; diff --git a/src/hooks/use-contract-activity.ts b/src/hooks/use-contract-activity.ts index 9e4da7577..8bbb1fae2 100644 --- a/src/hooks/use-contract-activity.ts +++ b/src/hooks/use-contract-activity.ts @@ -100,8 +100,6 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => } }, [selectedRpcUrl, selectedAccount, tokenSlug, knownBakers, isLoading]); - console.log('activities: ', activities); - return { handleUpdate, handleRefresh, From a3bc8ceef6c8201c850560478517d9ca597921e0 Mon Sep 17 00:00:00 2001 From: herkoss Date: Fri, 1 Sep 2023 10:41:56 +0300 Subject: [PATCH 34/43] TW-783 Fixed activity order --- .../details-card/baking-rewards.tsx | 62 ------------------- .../details-card/delegate.tsx | 40 ------------ .../details-card/details-card.tsx | 35 ----------- .../details-card/receive-tokens.tsx | 55 ---------------- .../details-card/send-tokens.tsx | 57 ----------------- .../activity-group-item/details.tsx | 53 ---------------- .../info/baking-rewards.tsx | 43 ------------- .../activity-group-item/info/delegation.tsx | 39 ------------ .../activity-group-item/info/info.tsx | 25 -------- .../activity-group-item/info/receive.tsx | 34 ---------- .../activity-group-item/info/send.tsx | 34 ---------- src/utils/token-operations.util.ts | 2 +- 12 files changed, 1 insertion(+), 478 deletions(-) delete mode 100644 src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/details-card/delegate.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/details.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/info/delegation.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/info/info.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/info/receive.tsx delete mode 100644 src/components/activity-groups-list/activity-group-item/info/send.tsx diff --git a/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx b/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx deleted file mode 100644 index f91cd9576..000000000 --- a/src/components/activity-groups-list/activity-group-item/details-card/baking-rewards.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -import { Divider } from 'src/components/divider/divider'; -import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; -import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; -import { WalletAddress } from 'src/components/wallet-address/wallet-address'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; -import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; -import { formatSize } from 'src/styles/format-size'; -import { tzktUrl } from 'src/utils/linking.util'; - -import { ActivityGroupAmountChange, TextSize } from '../activity-group-amount-change/activity-group-amount-change'; -import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; -import { ActivityGroupItemSelectors } from '../selectors'; - -export const BakingRewardsDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ - nonZeroAmounts, - address, - hash -}) => { - const selectedRpcUrl = useSelectedRpcUrlSelector(); - const styles = useActivityDetailsStyles(); - const commonStyles = useActivityCommonStyles(); - - return ( - <> - - Received: - - - - - - - From: - - - - - - - - TxHash: - - - - - - - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/details-card/delegate.tsx b/src/components/activity-groups-list/activity-group-item/details-card/delegate.tsx deleted file mode 100644 index fccf094e7..000000000 --- a/src/components/activity-groups-list/activity-group-item/details-card/delegate.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -import { Divider } from 'src/components/divider/divider'; -import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; -import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; -import { WalletAddress } from 'src/components/wallet-address/wallet-address'; -import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; -import { formatSize } from 'src/styles/format-size'; -import { tzktUrl } from 'src/utils/linking.util'; - -import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; -import { ActivityGroupItemSelectors } from '../selectors'; - -export const DelegateDetails: FC<{ address: string | undefined; hash: string }> = ({ hash, address = '' }) => { - const selectedRpcUrl = useSelectedRpcUrlSelector(); - const styles = useActivityDetailsStyles(); - const commonStyles = useActivityCommonStyles(); - - return ( - <> - - To: - - - - - - - - TxHash: - - - - - - - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx b/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx deleted file mode 100644 index 225f43132..000000000 --- a/src/components/activity-groups-list/activity-group-item/details-card/details-card.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; -import React, { FC } from 'react'; - -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; - -import { BakingRewardsDetails } from './baking-rewards'; -import { DelegateDetails } from './delegate'; -import { ReceiveTokensDetails } from './receive-tokens'; -import { SendTokensDetails } from './send-tokens'; - -export const DetailsCard: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = ({ - activity, - nonZeroAmounts -}) => { - switch (activity.type) { - case ActivityType.Send: - return ; - - case ActivityType.BakingRewards: - return ( - - ); - - case ActivityType.Recieve: - return ( - - ); - - case ActivityType.Delegation: - return ; - - default: - return null; - } -}; diff --git a/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx b/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx deleted file mode 100644 index e53880dd9..000000000 --- a/src/components/activity-groups-list/activity-group-item/details-card/receive-tokens.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -import { Divider } from 'src/components/divider/divider'; -import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; -import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; -import { WalletAddress } from 'src/components/wallet-address/wallet-address'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; -import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; -import { formatSize } from 'src/styles/format-size'; -import { tzktUrl } from 'src/utils/linking.util'; - -import { ActivityGroupAmountChange, TextSize } from '../activity-group-amount-change/activity-group-amount-change'; -import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; -import { ActivityGroupItemSelectors } from '../selectors'; - -export const ReceiveTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ - nonZeroAmounts, - address, - hash -}) => { - const selectedRpcUrl = useSelectedRpcUrlSelector(); - const styles = useActivityDetailsStyles(); - const commonStyles = useActivityCommonStyles(); - - return ( - <> - - Received: - - - - - - - From: - - - - TxHash: - - - - - - - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx b/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx deleted file mode 100644 index 1e78bd94d..000000000 --- a/src/components/activity-groups-list/activity-group-item/details-card/send-tokens.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -import { Divider } from 'src/components/divider/divider'; -import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; -import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; -import { WalletAddress } from 'src/components/wallet-address/wallet-address'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; -import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; -import { formatSize } from 'src/styles/format-size'; -import { tzktUrl } from 'src/utils/linking.util'; - -import { ActivityGroupAmountChange, TextSize } from '../activity-group-amount-change/activity-group-amount-change'; -import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityDetailsStyles } from '../activity-group-item.styles'; -import { ActivityGroupItemSelectors } from '../selectors'; - -export const SendTokensDetails: FC<{ nonZeroAmounts: NonZeroAmounts; address: string; hash: string }> = ({ - nonZeroAmounts, - address, - hash -}) => { - const selectedRpcUrl = useSelectedRpcUrlSelector(); - const styles = useActivityDetailsStyles(); - - const commonStyles = useActivityCommonStyles(); - - return ( - <> - - Sent: - - - - - - - To: - - - - - TxHash: - - - - - - - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/details.tsx b/src/components/activity-groups-list/activity-group-item/details.tsx deleted file mode 100644 index ca689884e..000000000 --- a/src/components/activity-groups-list/activity-group-item/details.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { Activity } from '@temple-wallet/transactions-parser'; -import React, { FC, useState, useCallback } from 'react'; -import { View } from 'react-native'; - -import { Divider } from 'src/components/divider/divider'; -import { Icon } from 'src/components/icon/icon'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; -import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; -import { formatSize } from 'src/styles/format-size'; - -import { useActivityCommonStyles, useActivityDetailsStyles } from './activity-group-item.styles'; -import { ActivityStatusBadge } from './activity-status-badge/activity-status-badge'; -import { ActivityTime } from './activity-time/activity-time'; -import { DetailsCard } from './details-card/details-card'; -import { ActivityGroupItemSelectors } from './selectors'; - -interface Props { - activity: Activity; - nonZeroAmounts: NonZeroAmounts; -} - -export const Details: FC = ({ activity, nonZeroAmounts }) => { - const detailsStyles = useActivityDetailsStyles(); - const commonStyles = useActivityCommonStyles(); - - const [areDetailsVisible, setAreDetailsVisible] = useState(false); - const handleOpenActivityDetailsPress = useCallback(() => setAreDetailsVisible(prevState => !prevState), []); - - return ( - - - - - - - - - - - - {areDetailsVisible && ( - - - - )} - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx b/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx deleted file mode 100644 index 645638f5c..000000000 --- a/src/components/activity-groups-list/activity-group-item/info/baking-rewards.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -import { AvatarImage } from 'src/components/avatar-image/avatar-image'; -import { Divider } from 'src/components/divider/divider'; -import { RobotIcon } from 'src/components/robot-icon/robot-icon'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; -import { useBakerByAddressSelector } from 'src/store/baking/baking-selectors'; -import { formatSize } from 'src/styles/format-size'; -import { truncateLongAddress } from 'src/utils/address.utils'; -import { isDefined } from 'src/utils/is-defined'; - -import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; -import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; - -export const BakingRewards: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ address, nonZeroAmounts }) => { - const styles = useActivityGroupItemStyles(); - const commonStyles = useActivityCommonStyles(); - - const baker = useBakerByAddressSelector(address); - - return ( - - {isDefined(baker) && isDefined(baker.logo) ? ( - - ) : ( - - )} - - - - Baking rewards - - - - From: {baker?.name ?? truncateLongAddress(address)} - - - - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/info/delegation.tsx b/src/components/activity-groups-list/activity-group-item/info/delegation.tsx deleted file mode 100644 index 473ea1dd8..000000000 --- a/src/components/activity-groups-list/activity-group-item/info/delegation.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -import { AvatarImage } from 'src/components/avatar-image/avatar-image'; -import { Divider } from 'src/components/divider/divider'; -import { RobotIcon } from 'src/components/robot-icon/robot-icon'; -import { useBakerByAddressSelector } from 'src/store/baking/baking-selectors'; -import { formatSize } from 'src/styles/format-size'; -import { truncateLongAddress } from 'src/utils/address.utils'; -import { isDefined } from 'src/utils/is-defined'; - -import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; - -export const Delegation: FC<{ address: string | undefined }> = ({ address = '' }) => { - const styles = useActivityGroupItemStyles(); - const commonStyles = useActivityCommonStyles(); - - const baker = useBakerByAddressSelector(address); - - return ( - - {isDefined(baker) && isDefined(baker.logo) ? ( - - ) : ( - - )} - - - - - Delegate - - - To: {baker?.name ?? truncateLongAddress(address)} - - - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/info/info.tsx b/src/components/activity-groups-list/activity-group-item/info/info.tsx deleted file mode 100644 index 8e8ce1a27..000000000 --- a/src/components/activity-groups-list/activity-group-item/info/info.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { Activity, ActivityType } from '@temple-wallet/transactions-parser'; -import React, { FC } from 'react'; - -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; - -import { BakingRewards } from './baking-rewards'; -import { Delegation } from './delegation'; -import { Receive } from './receive'; -import { Send } from './send'; - -export const Info: FC<{ activity: Activity; nonZeroAmounts: NonZeroAmounts }> = ({ activity, nonZeroAmounts }) => { - switch (activity.type) { - case ActivityType.Send: - return ; - case ActivityType.Recieve: - return ; - case ActivityType.BakingRewards: - return ; - case ActivityType.Delegation: - return ; - - default: - return null; - } -}; diff --git a/src/components/activity-groups-list/activity-group-item/info/receive.tsx b/src/components/activity-groups-list/activity-group-item/info/receive.tsx deleted file mode 100644 index 6b68505dc..000000000 --- a/src/components/activity-groups-list/activity-group-item/info/receive.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -import { Divider } from 'src/components/divider/divider'; -import { RobotIcon } from 'src/components/robot-icon/robot-icon'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; -import { formatSize } from 'src/styles/format-size'; -import { truncateLongAddress } from 'src/utils/address.utils'; - -import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; -import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; - -export const Receive: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ address, nonZeroAmounts }) => { - const styles = useActivityGroupItemStyles(); - const commonStyles = useActivityCommonStyles(); - - return ( - - - - - - Receive - - - - From: {truncateLongAddress(address)} - - - - - ); -}; diff --git a/src/components/activity-groups-list/activity-group-item/info/send.tsx b/src/components/activity-groups-list/activity-group-item/info/send.tsx deleted file mode 100644 index 72c97f423..000000000 --- a/src/components/activity-groups-list/activity-group-item/info/send.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React, { FC } from 'react'; -import { View, Text } from 'react-native'; - -import { Divider } from 'src/components/divider/divider'; -import { RobotIcon } from 'src/components/robot-icon/robot-icon'; -import { NonZeroAmounts } from 'src/interfaces/non-zero-amounts.interface'; -import { formatSize } from 'src/styles/format-size'; -import { truncateLongAddress } from 'src/utils/address.utils'; - -import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; -import { ActivityGroupDollarAmountChange } from '../activity-group-dollar-amount-change/activity-group-dollar-amount-change'; -import { useActivityCommonStyles, useActivityGroupItemStyles } from '../activity-group-item.styles'; - -export const Send: FC<{ address: string; nonZeroAmounts: NonZeroAmounts }> = ({ address, nonZeroAmounts }) => { - const styles = useActivityGroupItemStyles(); - const commonStyles = useActivityCommonStyles(); - - return ( - - - - - - Send - - - - To: {truncateLongAddress(address)} - - - - - ); -}; diff --git a/src/utils/token-operations.util.ts b/src/utils/token-operations.util.ts index c87d0a0ea..c10c42d0c 100644 --- a/src/utils/token-operations.util.ts +++ b/src/utils/token-operations.util.ts @@ -213,7 +213,7 @@ export const loadActivity = async ( for (const opHash of operationsHashesUniq) { const { data } = await getOperationGroupByHash(selectedRpcUrl, opHash); - operationGroups.push(data); + operationGroups.push(data.sort((a, b) => b.id - a.id)); await sleep(100); } From e8626ab93015cb684df4585cf0d72c31506595ce Mon Sep 17 00:00:00 2001 From: herkoss Date: Mon, 4 Sep 2023 16:47:16 +0300 Subject: [PATCH 35/43] TW-783 Fixed comments, added memo --- .../activity-group-dollar-amount-change.tsx | 27 ++++++++++-------- .../activity-item/baking-rewards.tsx | 6 ++-- .../activity-item/change-allowance.tsx | 28 ++++++++++--------- .../activity-item/delegate.tsx | 6 ++-- .../activity-item/interaction.tsx | 23 ++++----------- .../activity-item/receive.tsx | 6 ++-- .../activity-item/send.tsx | 6 ++-- .../activity-item/unknown.tsx | 23 ++++----------- src/utils/activity.utils.ts | 15 ++++++++++ 9 files changed, 67 insertions(+), 73 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.tsx index c671854e2..4207120b7 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-dollar-amount-change/activity-group-dollar-amount-change.tsx @@ -1,5 +1,5 @@ import { BigNumber } from 'bignumber.js'; -import React, { FC } from 'react'; +import React, { FC, memo } from 'react'; import { View } from 'react-native'; import { FormattedAmount } from 'src/components/formatted-amount'; @@ -11,16 +11,19 @@ interface Props { dollarValue: BigNumber; } -export const ActivityGroupDollarAmountChange: FC = ({ dollarValue }) => { - const styles = useActivityGroupDollarAmountChangeStyles(); +export const ActivityGroupDollarAmountChange: FC = memo( + ({ dollarValue }) => { + const styles = useActivityGroupDollarAmountChangeStyles(); - if (dollarValue.isEqualTo(ZERO)) { - return null; - } + if (dollarValue.isEqualTo(ZERO)) { + return null; + } - return ( - - - - ); -}; + return ( + + + + ); + }, + (prevProps, nextProps) => prevProps.dollarValue.toFixed() === nextProps.dollarValue.toFixed() +); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx index 5f5f70a13..b914d41b6 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx @@ -1,4 +1,4 @@ -import React, { FC } from 'react'; +import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; import { AvatarImage } from 'src/components/avatar-image/avatar-image'; @@ -28,7 +28,7 @@ import { ActivityGroupItemSelectors } from '../selectors'; import { AbstractItem } from './abstract-item'; import { ActivityItemProps } from './item.props'; -export const BakingRewards: FC = ({ activity }) => { +export const BakingRewards: FC = memo(({ activity }) => { const nonZeroAmounts = useNonZeroAmounts(activity.tokensDeltas); return ( @@ -39,7 +39,7 @@ export const BakingRewards: FC = ({ activity }) => { timestamp={activity.timestamp} /> ); -}; +}); const Face: FC<{ address: string; nonZeroAmounts: Array }> = ({ address, nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx index c9c04c12f..a5f8bf1d0 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx @@ -1,5 +1,5 @@ import { AllowanceInteractionActivity } from '@temple-wallet/transactions-parser'; -import React, { FC } from 'react'; +import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; @@ -22,11 +22,13 @@ import { AbstractItem } from './abstract-item'; const AMOUNT_INDEX = 0; -export const ChangeAllowance: FC<{ activity: AllowanceInteractionActivity }> = ({ activity }) => { +export const ChangeAllowance: FC<{ activity: AllowanceInteractionActivity }> = memo(({ activity }) => { const getTokenMetadata = useTokenMetadataGetter(); - const metadata = getTokenMetadata(activity.allowanceChanges[AMOUNT_INDEX].tokenSlug); - const isRevoke = activity.allowanceChanges[AMOUNT_INDEX].atomicAmount.isZero(); + const firstChange = activity.allowanceChanges[AMOUNT_INDEX]; + + const metadata = getTokenMetadata(firstChange.tokenSlug); + const isRevoke = firstChange.atomicAmount.isZero(); if (isRevoke) { return ( @@ -47,9 +49,9 @@ export const ChangeAllowance: FC<{ activity: AllowanceInteractionActivity }> = ( details={} /> ); -}; +}); -const ApproveFace: FC<{ address: string; symbol: string }> = ({ address, symbol }) => { +const ApproveFace: FC<{ address: string; symbol: string }> = memo(({ address, symbol }) => { const styles = useActivityGroupItemStyles(); const commonStyles = useActivityCommonStyles(); @@ -66,8 +68,8 @@ const ApproveFace: FC<{ address: string; symbol: string }> = ({ address, symbol ); -}; -const RevokeFace: FC<{ address: string; symbol: string }> = ({ address, symbol }) => { +}); +const RevokeFace: FC<{ address: string; symbol: string }> = memo(({ address, symbol }) => { const styles = useActivityGroupItemStyles(); const commonStyles = useActivityCommonStyles(); @@ -84,9 +86,9 @@ const RevokeFace: FC<{ address: string; symbol: string }> = ({ address, symbol } ); -}; +}); -const ApproveDetails: FC<{ address: string; symbol: string; hash: string }> = ({ address, symbol, hash }) => { +const ApproveDetails: FC<{ address: string; symbol: string; hash: string }> = memo(({ address, symbol, hash }) => { const styles = useActivityDetailsStyles(); const commonStyles = useActivityCommonStyles(); const selectedRpcUrl = useSelectedRpcUrlSelector(); @@ -121,8 +123,8 @@ const ApproveDetails: FC<{ address: string; symbol: string; hash: string }> = ({ ); -}; -const RevokeDetails: FC<{ address: string; symbol: string; hash: string }> = ({ address, symbol, hash }) => { +}); +const RevokeDetails: FC<{ address: string; symbol: string; hash: string }> = memo(({ address, symbol, hash }) => { const styles = useActivityDetailsStyles(); const commonStyles = useActivityCommonStyles(); const selectedRpcUrl = useSelectedRpcUrlSelector(); @@ -157,4 +159,4 @@ const RevokeDetails: FC<{ address: string; symbol: string; hash: string }> = ({ ); -}; +}); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx index 13610bd8a..bbbfffa37 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx @@ -1,4 +1,4 @@ -import React, { FC } from 'react'; +import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; import { AvatarImage } from 'src/components/avatar-image/avatar-image'; @@ -23,7 +23,7 @@ import { ActivityGroupItemSelectors } from '../selectors'; import { AbstractItem } from './abstract-item'; import { ActivityItemProps } from './item.props'; -export const Delegate: FC = ({ activity }) => { +export const Delegate: FC = memo(({ activity }) => { return ( } @@ -32,7 +32,7 @@ export const Delegate: FC = ({ activity }) => { timestamp={activity.timestamp} /> ); -}; +}); const Face: FC<{ address: string }> = ({ address }) => { const styles = useActivityGroupItemStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx index f7d6ad1be..5fab565ea 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx @@ -1,6 +1,6 @@ import { ActivitySubtype, AllowanceInteractionActivity, InteractionActivity } from '@temple-wallet/transactions-parser'; import { isEmpty } from 'lodash-es'; -import React, { FC, useMemo } from 'react'; +import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; @@ -10,7 +10,7 @@ import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; -import { calculateDollarValue } from 'src/utils/activity.utils'; +import { calculateDollarValue, separateAmountsBySign } from 'src/utils/activity.utils'; import { isDefined } from 'src/utils/is-defined'; import { tzktUrl } from 'src/utils/linking.util'; @@ -27,7 +27,7 @@ import { AbstractItem } from './abstract-item'; import { ChangeAllowance } from './change-allowance'; import { ActivityItemProps } from './item.props'; -export const Interaction: FC = ({ activity }) => { +export const Interaction: FC = memo(({ activity }) => { const nonZeroAmounts = useNonZeroAmounts(activity.tokensDeltas); switch ((activity as InteractionActivity).subtype) { @@ -44,7 +44,7 @@ export const Interaction: FC = ({ activity }) => { /> ); } -}; +}); const Face: FC<{ nonZeroAmounts: Array }> = ({ nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); @@ -72,20 +72,7 @@ const Details: FC<{ hash: string; nonZeroAmounts: Array }> = ({ const commonStyles = useActivityCommonStyles(); - const { positiveAmounts, negativeAmounts } = useMemo(() => { - const positiveAmounts: Array = []; - const negativeAmounts: Array = []; - - for (const amount of nonZeroAmounts) { - if (amount.isPositive) { - positiveAmounts.push(amount); - } else { - negativeAmounts.push(amount); - } - } - - return { positiveAmounts, negativeAmounts }; - }, [nonZeroAmounts]); + const { positiveAmounts, negativeAmounts } = separateAmountsBySign(nonZeroAmounts); return ( <> diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx index 210ea5adb..26ad413ff 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx @@ -1,4 +1,4 @@ -import React, { FC } from 'react'; +import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; @@ -25,7 +25,7 @@ import { ActivityGroupItemSelectors } from '../selectors'; import { AbstractItem } from './abstract-item'; import { ActivityItemProps } from './item.props'; -export const Receive: FC = ({ activity }) => { +export const Receive: FC = memo(({ activity }) => { const nonZeroAmounts = useNonZeroAmounts(activity.tokensDeltas); return ( @@ -36,7 +36,7 @@ export const Receive: FC = ({ activity }) => { timestamp={activity.timestamp} /> ); -}; +}); const Face: FC<{ address: string; nonZeroAmounts: Array }> = ({ address, nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/send.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/send.tsx index 4a0d2f81d..498451ef6 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/send.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/send.tsx @@ -1,4 +1,4 @@ -import React, { FC } from 'react'; +import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; @@ -25,7 +25,7 @@ import { ActivityGroupItemSelectors } from '../selectors'; import { AbstractItem } from './abstract-item'; import { ActivityItemProps } from './item.props'; -export const Send: FC = ({ activity }) => { +export const Send: FC = memo(({ activity }) => { const nonZeroAmounts = useNonZeroAmounts(activity.tokensDeltas); return ( @@ -36,7 +36,7 @@ export const Send: FC = ({ activity }) => { timestamp={activity.timestamp} /> ); -}; +}); const Face: FC<{ address: string; nonZeroAmounts: Array }> = ({ address, nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx index 7d37589f8..a65abe608 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx @@ -1,5 +1,5 @@ import { isEmpty } from 'lodash-es'; -import React, { FC, useMemo } from 'react'; +import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; @@ -9,7 +9,7 @@ import { useNonZeroAmounts } from 'src/hooks/use-non-zero-amounts.hook'; import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; -import { calculateDollarValue } from 'src/utils/activity.utils'; +import { calculateDollarValue, separateAmountsBySign } from 'src/utils/activity.utils'; import { isDefined } from 'src/utils/is-defined'; import { tzktUrl } from 'src/utils/linking.util'; @@ -25,7 +25,7 @@ import { ActivityGroupItemSelectors } from '../selectors'; import { AbstractItem } from './abstract-item'; import { ActivityItemProps } from './item.props'; -export const Unknown: FC = ({ activity }) => { +export const Unknown: FC = memo(({ activity }) => { const nonZeroAmounts = useNonZeroAmounts(activity.tokensDeltas); return ( @@ -36,7 +36,7 @@ export const Unknown: FC = ({ activity }) => { details={
} /> ); -}; +}); const Face: FC<{ nonZeroAmounts: Array }> = ({ nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); @@ -64,20 +64,7 @@ const Details: FC<{ hash: string; nonZeroAmounts: Array }> = ({ const commonStyles = useActivityCommonStyles(); - const { positiveAmounts, negativeAmounts } = useMemo(() => { - const positiveAmounts: Array = []; - const negativeAmounts: Array = []; - - for (const amount of nonZeroAmounts) { - if (amount.isPositive) { - positiveAmounts.push(amount); - } else { - negativeAmounts.push(amount); - } - } - - return { positiveAmounts, negativeAmounts }; - }, [nonZeroAmounts]); + const { positiveAmounts, negativeAmounts } = separateAmountsBySign(nonZeroAmounts); return ( <> diff --git a/src/utils/activity.utils.ts b/src/utils/activity.utils.ts index 757ef6102..0f7c7615b 100644 --- a/src/utils/activity.utils.ts +++ b/src/utils/activity.utils.ts @@ -18,3 +18,18 @@ export const calculateDollarValue = (amounts: Array) => return accum; }, ZERO); + +export const separateAmountsBySign = (nonZeroAmounts: Array) => { + const positiveAmounts: Array = []; + const negativeAmounts: Array = []; + + for (const amount of nonZeroAmounts) { + if (amount.isPositive) { + positiveAmounts.push(amount); + } else { + negativeAmounts.push(amount); + } + } + + return { positiveAmounts, negativeAmounts }; +}; From 2bc8e4db5ac5da98353da218ee14d5f1ba8b17e5 Mon Sep 17 00:00:00 2001 From: herkoss Date: Mon, 4 Sep 2023 18:27:39 +0300 Subject: [PATCH 36/43] TW-783 Added equality fn --- .../activity-group-item/activity-item/baking-rewards.tsx | 3 ++- .../activity-item/change-allowance.tsx | 9 ++++----- .../activity-group-item/activity-item/delegate.tsx | 3 ++- .../activity-group-item/activity-item/interaction.tsx | 8 ++++---- .../activity-group-item/activity-item/receive.tsx | 3 ++- .../activity-group-item/activity-item/send.tsx | 3 ++- .../activity-group-item/activity-item/unknown.tsx | 8 ++++---- 7 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx index b914d41b6..63db2dc76 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx @@ -1,3 +1,4 @@ +import { isEqual } from 'lodash-es'; import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; @@ -39,7 +40,7 @@ export const BakingRewards: FC = memo(({ activity }) => { timestamp={activity.timestamp} /> ); -}); +}, isEqual); const Face: FC<{ address: string; nonZeroAmounts: Array }> = ({ address, nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx index a5f8bf1d0..9baee7b52 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx @@ -1,4 +1,5 @@ import { AllowanceInteractionActivity } from '@temple-wallet/transactions-parser'; +import { isEqual } from 'lodash-es'; import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; @@ -6,8 +7,8 @@ import { Divider } from 'src/components/divider/divider'; import { ExternalLinkButton } from 'src/components/icon/external-link-button/external-link-button'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; import { WalletAddress } from 'src/components/wallet-address/wallet-address'; -import { useTokenMetadataGetter } from 'src/hooks/use-token-metadata-getter.hook'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { useTokenMetadataSelector } from 'src/store/tokens-metadata/tokens-metadata-selectors'; import { formatSize } from 'src/styles/format-size'; import { truncateLongAddress } from 'src/utils/address.utils'; import { tzktUrl } from 'src/utils/linking.util'; @@ -23,11 +24,9 @@ import { AbstractItem } from './abstract-item'; const AMOUNT_INDEX = 0; export const ChangeAllowance: FC<{ activity: AllowanceInteractionActivity }> = memo(({ activity }) => { - const getTokenMetadata = useTokenMetadataGetter(); - const firstChange = activity.allowanceChanges[AMOUNT_INDEX]; - const metadata = getTokenMetadata(firstChange.tokenSlug); + const metadata = useTokenMetadataSelector(firstChange.tokenSlug); const isRevoke = firstChange.atomicAmount.isZero(); if (isRevoke) { @@ -49,7 +48,7 @@ export const ChangeAllowance: FC<{ activity: AllowanceInteractionActivity }> = m details={} /> ); -}); +}, isEqual); const ApproveFace: FC<{ address: string; symbol: string }> = memo(({ address, symbol }) => { const styles = useActivityGroupItemStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx index bbbfffa37..e61bbb474 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx @@ -1,3 +1,4 @@ +import { isEqual } from 'lodash-es'; import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; @@ -32,7 +33,7 @@ export const Delegate: FC = memo(({ activity }) => { timestamp={activity.timestamp} /> ); -}); +}, isEqual); const Face: FC<{ address: string }> = ({ address }) => { const styles = useActivityGroupItemStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx index 5fab565ea..c1990d0f3 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx @@ -1,6 +1,6 @@ import { ActivitySubtype, AllowanceInteractionActivity, InteractionActivity } from '@temple-wallet/transactions-parser'; -import { isEmpty } from 'lodash-es'; -import React, { FC, memo } from 'react'; +import { isEmpty, isEqual } from 'lodash-es'; +import React, { FC, memo, useMemo } from 'react'; import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; @@ -44,7 +44,7 @@ export const Interaction: FC = memo(({ activity }) => { /> ); } -}); +}, isEqual); const Face: FC<{ nonZeroAmounts: Array }> = ({ nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); @@ -72,7 +72,7 @@ const Details: FC<{ hash: string; nonZeroAmounts: Array }> = ({ const commonStyles = useActivityCommonStyles(); - const { positiveAmounts, negativeAmounts } = separateAmountsBySign(nonZeroAmounts); + const { positiveAmounts, negativeAmounts } = useMemo(() => separateAmountsBySign(nonZeroAmounts), [nonZeroAmounts]); return ( <> diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx index 26ad413ff..d2efb1e8a 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx @@ -1,3 +1,4 @@ +import { isEqual } from 'lodash-es'; import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; @@ -36,7 +37,7 @@ export const Receive: FC = memo(({ activity }) => { timestamp={activity.timestamp} /> ); -}); +}, isEqual); const Face: FC<{ address: string; nonZeroAmounts: Array }> = ({ address, nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/send.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/send.tsx index 498451ef6..6c4ab3d80 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/send.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/send.tsx @@ -1,3 +1,4 @@ +import { isEqual } from 'lodash-es'; import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; @@ -36,7 +37,7 @@ export const Send: FC = memo(({ activity }) => { timestamp={activity.timestamp} /> ); -}); +}, isEqual); const Face: FC<{ address: string; nonZeroAmounts: Array }> = ({ address, nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx index a65abe608..36462ec3d 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx @@ -1,5 +1,5 @@ -import { isEmpty } from 'lodash-es'; -import React, { FC, memo } from 'react'; +import { isEmpty, isEqual } from 'lodash-es'; +import React, { FC, memo, useMemo } from 'react'; import { View, Text } from 'react-native'; import { Divider } from 'src/components/divider/divider'; @@ -36,7 +36,7 @@ export const Unknown: FC = memo(({ activity }) => { details={
} /> ); -}); +}, isEqual); const Face: FC<{ nonZeroAmounts: Array }> = ({ nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); @@ -64,7 +64,7 @@ const Details: FC<{ hash: string; nonZeroAmounts: Array }> = ({ const commonStyles = useActivityCommonStyles(); - const { positiveAmounts, negativeAmounts } = separateAmountsBySign(nonZeroAmounts); + const { positiveAmounts, negativeAmounts } = useMemo(() => separateAmountsBySign(nonZeroAmounts), [nonZeroAmounts]); return ( <> From 7156d807d39c49ce467346ea1d39c07f4ee1c9e4 Mon Sep 17 00:00:00 2001 From: herkoss Date: Tue, 5 Sep 2023 16:41:44 +0300 Subject: [PATCH 37/43] TW-783 Fixed undefined matadata --- .../activity-group-amount-change.tsx | 13 ++++++- .../activity-group-dollar-amount-change.tsx | 14 ++++--- .../activity-item/baking-rewards.tsx | 3 +- .../activity-item/change-allowance.tsx | 3 +- .../activity-item/delegate.tsx | 3 +- .../activity-item/interaction.tsx | 13 +++---- .../activity-item/receive.tsx | 3 +- .../activity-item/send.tsx | 3 +- .../activity-item/unknown.tsx | 8 ++-- .../item-amount-change/item-amount-change.tsx | 13 +++++-- src/hooks/use-non-zero-amounts.hook.ts | 38 ++++++++++++------- src/hooks/use-token-metadata-getter.hook.ts | 25 +++++++++++- src/interfaces/non-zero-amounts.interface.ts | 4 +- src/utils/token-metadata.utils.ts | 10 +++++ 14 files changed, 106 insertions(+), 47 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx index 75a74e69b..dc65b26a7 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx @@ -25,7 +25,17 @@ export const ActivityGroupAmountChange: FC = ({ nonZeroAmounts, textSize const children = useMemo(() => { if (nonZeroAmounts.length === 0) { - return null; + return ( + + --- + + ); } const { isPositive, parsedAmount, symbol } = nonZeroAmounts[FIRST_AMOUNT_INDEX]; @@ -34,6 +44,7 @@ export const ActivityGroupAmountChange: FC = ({ nonZeroAmounts, textSize return ( = memo( ({ dollarValue }) => { const styles = useActivityGroupDollarAmountChangeStyles(); - if (dollarValue.isEqualTo(ZERO)) { - return null; + if (dollarValue === undefined || dollarValue.isEqualTo(ZERO)) { + return ( + + --- + + ); } return ( @@ -25,5 +29,5 @@ export const ActivityGroupDollarAmountChange: FC = memo( ); }, - (prevProps, nextProps) => prevProps.dollarValue.toFixed() === nextProps.dollarValue.toFixed() + (prevProps, nextProps) => prevProps.dollarValue?.toFixed() === nextProps.dollarValue?.toFixed() ); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx index 63db2dc76..b914d41b6 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/baking-rewards.tsx @@ -1,4 +1,3 @@ -import { isEqual } from 'lodash-es'; import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; @@ -40,7 +39,7 @@ export const BakingRewards: FC = memo(({ activity }) => { timestamp={activity.timestamp} /> ); -}, isEqual); +}); const Face: FC<{ address: string; nonZeroAmounts: Array }> = ({ address, nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx index 9baee7b52..f24421d4d 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx @@ -1,5 +1,4 @@ import { AllowanceInteractionActivity } from '@temple-wallet/transactions-parser'; -import { isEqual } from 'lodash-es'; import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; @@ -48,7 +47,7 @@ export const ChangeAllowance: FC<{ activity: AllowanceInteractionActivity }> = m details={} /> ); -}, isEqual); +}); const ApproveFace: FC<{ address: string; symbol: string }> = memo(({ address, symbol }) => { const styles = useActivityGroupItemStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx index e61bbb474..bbbfffa37 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx @@ -1,4 +1,3 @@ -import { isEqual } from 'lodash-es'; import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; @@ -33,7 +32,7 @@ export const Delegate: FC = memo(({ activity }) => { timestamp={activity.timestamp} /> ); -}, isEqual); +}); const Face: FC<{ address: string }> = ({ address }) => { const styles = useActivityGroupItemStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx index c1990d0f3..e0bb8ab86 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/interaction.tsx @@ -1,5 +1,5 @@ import { ActivitySubtype, AllowanceInteractionActivity, InteractionActivity } from '@temple-wallet/transactions-parser'; -import { isEmpty, isEqual } from 'lodash-es'; +import { isEmpty } from 'lodash-es'; import React, { FC, memo, useMemo } from 'react'; import { View, Text } from 'react-native'; @@ -11,7 +11,6 @@ import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; import { calculateDollarValue, separateAmountsBySign } from 'src/utils/activity.utils'; -import { isDefined } from 'src/utils/is-defined'; import { tzktUrl } from 'src/utils/linking.util'; import { ActivityGroupAmountChange } from '../activity-group-amount-change/activity-group-amount-change'; @@ -44,7 +43,7 @@ export const Interaction: FC = memo(({ activity }) => { /> ); } -}, isEqual); +}); const Face: FC<{ nonZeroAmounts: Array }> = ({ nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); @@ -82,8 +81,8 @@ const Details: FC<{ hash: string; nonZeroAmounts: Array }> = ({ {positiveAmounts.map((amount, index) => ( - - {isDefined(amount.fiatAmount) && } + + ))} @@ -95,8 +94,8 @@ const Details: FC<{ hash: string; nonZeroAmounts: Array }> = ({ {negativeAmounts.map((amount, index) => ( - - {isDefined(amount.fiatAmount) && } + + ))} diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx index d2efb1e8a..26ad413ff 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/receive.tsx @@ -1,4 +1,3 @@ -import { isEqual } from 'lodash-es'; import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; @@ -37,7 +36,7 @@ export const Receive: FC = memo(({ activity }) => { timestamp={activity.timestamp} /> ); -}, isEqual); +}); const Face: FC<{ address: string; nonZeroAmounts: Array }> = ({ address, nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/send.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/send.tsx index 6c4ab3d80..498451ef6 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/send.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/send.tsx @@ -1,4 +1,3 @@ -import { isEqual } from 'lodash-es'; import React, { FC, memo } from 'react'; import { View, Text } from 'react-native'; @@ -37,7 +36,7 @@ export const Send: FC = memo(({ activity }) => { timestamp={activity.timestamp} /> ); -}, isEqual); +}); const Face: FC<{ address: string; nonZeroAmounts: Array }> = ({ address, nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx index 36462ec3d..1f4fea356 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/unknown.tsx @@ -1,4 +1,4 @@ -import { isEmpty, isEqual } from 'lodash-es'; +import { isEmpty } from 'lodash-es'; import React, { FC, memo, useMemo } from 'react'; import { View, Text } from 'react-native'; @@ -36,7 +36,7 @@ export const Unknown: FC = memo(({ activity }) => { details={
} /> ); -}, isEqual); +}); const Face: FC<{ nonZeroAmounts: Array }> = ({ nonZeroAmounts }) => { const styles = useActivityGroupItemStyles(); @@ -74,7 +74,7 @@ const Details: FC<{ hash: string; nonZeroAmounts: Array }> = ({ {positiveAmounts.map((amount, index) => ( - + {isDefined(amount.fiatAmount) && } ))} @@ -87,7 +87,7 @@ const Details: FC<{ hash: string; nonZeroAmounts: Array }> = ({ {negativeAmounts.map((amount, index) => ( - + {isDefined(amount.fiatAmount) && } ))} diff --git a/src/components/activity-groups-list/activity-group-item/item-amount-change/item-amount-change.tsx b/src/components/activity-groups-list/activity-group-item/item-amount-change/item-amount-change.tsx index 57e89f1e7..124996e8d 100644 --- a/src/components/activity-groups-list/activity-group-item/item-amount-change/item-amount-change.tsx +++ b/src/components/activity-groups-list/activity-group-item/item-amount-change/item-amount-change.tsx @@ -9,15 +9,22 @@ import { shortizeSymbol } from 'src/utils/token-metadata.utils'; import { useActivityGroupDollarAmountChangeStyles } from './item-amount-change.styles'; interface Props { - amount: BigNumber; + amount: BigNumber | undefined; + isPositive: boolean; symbol: string; textStyle?: StyleProp; } -export const ItemAmountChange: FC = ({ symbol, amount, textStyle }) => { +export const ItemAmountChange: FC = ({ symbol, amount, isPositive, textStyle }) => { const styles = useActivityGroupDollarAmountChangeStyles(); - const isPositive = amount.isPositive(); + if (amount === undefined) { + return ( + + --- + + ); + } return ( diff --git a/src/hooks/use-non-zero-amounts.hook.ts b/src/hooks/use-non-zero-amounts.hook.ts index f509a7afc..8dd63336e 100644 --- a/src/hooks/use-non-zero-amounts.hook.ts +++ b/src/hooks/use-non-zero-amounts.hook.ts @@ -11,7 +11,7 @@ import { loadTokenMetadataActions } from '../store/tokens-metadata/tokens-metada import { isDefined } from '../utils/is-defined'; import { isString } from '../utils/is-string'; import { isCollectible, mutezToTz } from '../utils/tezos.util'; -import { useTokenMetadataGetter } from './use-token-metadata-getter.hook'; +import { useTokenMetadataGetterNew } from './use-token-metadata-getter.hook'; const calculateFiatAmount = ( parsedAmount: BigNumber, @@ -25,7 +25,7 @@ const calculateFiatAmount = ( export const useNonZeroAmounts = (tokensDeltas: Array): Array => { const dispatch = useDispatch(); - const getTokenMetadata = useTokenMetadataGetter(); + const getTokenMetadata = useTokenMetadataGetterNew(); const exchangeRates = useUsdToTokenRates(); const fiatToUsdRate = useFiatToUsdRateSelector(); @@ -34,24 +34,34 @@ export const useNonZeroAmounts = (tokensDeltas: Array): Array { @@ -24,3 +26,24 @@ export const useTokenMetadataGetter = () => { [tokensMetadata, getTokenExchangeRate] ); }; + +export const useTokenMetadataGetterNew = () => { + const tokensMetadata = useTokensMetadataSelector(); + const getTokenExchangeRate = useTokenExchangeRateGetter(); + const selectedRpcUrl = useSelectedRpcUrlSelector(); + + return useCallback( + (slug: string): TokenMetadataInterface | undefined => { + const tokenMetadata = normalizeTokenMetadataNew(selectedRpcUrl, slug, tokensMetadata[slug]); + const exchangeRate = getTokenExchangeRate(slug); + + if (isDefined(tokenMetadata)) { + return { + ...tokenMetadata, + exchangeRate + }; + } + }, + [tokensMetadata, getTokenExchangeRate] + ); +}; diff --git a/src/interfaces/non-zero-amounts.interface.ts b/src/interfaces/non-zero-amounts.interface.ts index 23baa56d1..7dd2b4afc 100644 --- a/src/interfaces/non-zero-amounts.interface.ts +++ b/src/interfaces/non-zero-amounts.interface.ts @@ -2,7 +2,7 @@ import { BigNumber } from 'bignumber.js'; export interface ActivityAmount { symbol: string; isPositive: boolean; - exchangeRate: number; - parsedAmount: BigNumber; + exchangeRate: number | undefined; + parsedAmount: BigNumber | undefined; fiatAmount: BigNumber | undefined; } diff --git a/src/utils/token-metadata.utils.ts b/src/utils/token-metadata.utils.ts index f87a39992..46d1e45f4 100644 --- a/src/utils/token-metadata.utils.ts +++ b/src/utils/token-metadata.utils.ts @@ -97,6 +97,16 @@ export const normalizeTokenMetadata = ( }; }; +export const normalizeTokenMetadataNew = ( + selectedRpcUrl: string, + slug: string, + rawMetadata?: TokenMetadataInterface +): TokenMetadataInterface | undefined => { + const gasTokenMetadata = getNetworkGasTokenMetadata(selectedRpcUrl); + + return slug === TEZ_TOKEN_SLUG ? gasTokenMetadata : rawMetadata; +}; + export const getFiatToUsdRate = (state: RootState) => { const fiatExchangeRates = state.currency.fiatToTezosRates.data; const fiatCurrency = state.settings.fiatCurrency; From 3d54c496aca9dfeb8dde1d1082c40a4532b1aeae Mon Sep 17 00:00:00 2001 From: herkoss Date: Wed, 6 Sep 2023 12:56:40 +0300 Subject: [PATCH 38/43] TW-783 Added memo --- .../activity-group-item/activity-item/activity-item.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/activity-item.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/activity-item.tsx index a7eed7840..d54f29163 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/activity-item.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/activity-item.tsx @@ -1,5 +1,5 @@ import { ActivityType } from '@temple-wallet/transactions-parser'; -import React, { FC } from 'react'; +import React, { FC, memo } from 'react'; import { BakingRewards } from './baking-rewards'; import { Delegate } from './delegate'; @@ -9,7 +9,7 @@ import { Receive } from './receive'; import { Send } from './send'; import { Unknown } from './unknown'; -export const ActivityItem: FC = ({ activity }) => { +export const ActivityItem: FC = memo(({ activity }) => { switch (activity.type) { case ActivityType.Send: return ; @@ -25,4 +25,4 @@ export const ActivityItem: FC = ({ activity }) => { default: return ; } -}; +}); From 76fb83bf6aa7eec0d52b83d259daf75b63aaffc4 Mon Sep 17 00:00:00 2001 From: herkoss Date: Wed, 6 Sep 2023 14:43:49 +0300 Subject: [PATCH 39/43] TW-783 Fixed dispatching metadata --- src/hooks/use-non-zero-amounts.hook.ts | 13 +++---------- src/hooks/use-token-metadata-getter.hook.ts | 19 ++++++++----------- src/utils/token-metadata.utils.ts | 10 ---------- 3 files changed, 11 insertions(+), 31 deletions(-) diff --git a/src/hooks/use-non-zero-amounts.hook.ts b/src/hooks/use-non-zero-amounts.hook.ts index 8dd63336e..e2887e1da 100644 --- a/src/hooks/use-non-zero-amounts.hook.ts +++ b/src/hooks/use-non-zero-amounts.hook.ts @@ -1,15 +1,12 @@ import { TokenDelta } from '@temple-wallet/transactions-parser'; import { BigNumber } from 'bignumber.js'; import { useMemo } from 'react'; -import { useDispatch } from 'react-redux'; import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; import { useFiatToUsdRateSelector } from 'src/store/settings/settings-selectors'; import { useUsdToTokenRates } from '../store/currency/currency-selectors'; -import { loadTokenMetadataActions } from '../store/tokens-metadata/tokens-metadata-actions'; import { isDefined } from '../utils/is-defined'; -import { isString } from '../utils/is-string'; import { isCollectible, mutezToTz } from '../utils/tezos.util'; import { useTokenMetadataGetterNew } from './use-token-metadata-getter.hook'; @@ -24,7 +21,6 @@ const calculateFiatAmount = ( }; export const useNonZeroAmounts = (tokensDeltas: Array): Array => { - const dispatch = useDispatch(); const getTokenMetadata = useTokenMetadataGetterNew(); const exchangeRates = useUsdToTokenRates(); const fiatToUsdRate = useFiatToUsdRateSelector(); @@ -34,15 +30,12 @@ export const useNonZeroAmounts = (tokensDeltas: Array): Array): Array { @@ -34,16 +35,12 @@ export const useTokenMetadataGetterNew = () => { return useCallback( (slug: string): TokenMetadataInterface | undefined => { - const tokenMetadata = normalizeTokenMetadataNew(selectedRpcUrl, slug, tokensMetadata[slug]); - const exchangeRate = getTokenExchangeRate(slug); - - if (isDefined(tokenMetadata)) { - return { - ...tokenMetadata, - exchangeRate - }; + if (slug === TEZ_TOKEN_SLUG) { + return getNetworkGasTokenMetadata(selectedRpcUrl); } + + return tokensMetadata[slug]; }, - [tokensMetadata, getTokenExchangeRate] + [tokensMetadata, selectedRpcUrl, getTokenExchangeRate] ); }; diff --git a/src/utils/token-metadata.utils.ts b/src/utils/token-metadata.utils.ts index 46d1e45f4..f87a39992 100644 --- a/src/utils/token-metadata.utils.ts +++ b/src/utils/token-metadata.utils.ts @@ -97,16 +97,6 @@ export const normalizeTokenMetadata = ( }; }; -export const normalizeTokenMetadataNew = ( - selectedRpcUrl: string, - slug: string, - rawMetadata?: TokenMetadataInterface -): TokenMetadataInterface | undefined => { - const gasTokenMetadata = getNetworkGasTokenMetadata(selectedRpcUrl); - - return slug === TEZ_TOKEN_SLUG ? gasTokenMetadata : rawMetadata; -}; - export const getFiatToUsdRate = (state: RootState) => { const fiatExchangeRates = state.currency.fiatToTezosRates.data; const fiatCurrency = state.settings.fiatCurrency; From 88c8718dca9fd8a224acea5fc316414b8fe7687f Mon Sep 17 00:00:00 2001 From: herkoss Date: Fri, 8 Sep 2023 22:10:19 +0300 Subject: [PATCH 40/43] TW-783 Fixed qa issues --- .../activity-group-amount-change.tsx | 114 ++++++++++++++---- .../activity-item/change-allowance.tsx | 13 +- src/utils/activity.utils.ts | 2 - src/utils/token-operations.util.ts | 3 +- 4 files changed, 103 insertions(+), 29 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx index dc65b26a7..3813c97fa 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx @@ -2,7 +2,7 @@ import React, { FC, useMemo } from 'react'; import { Text, View } from 'react-native'; import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; -import { isDoubleTokenOperation, isSingleTokenOperation } from 'src/utils/activity.utils'; +import { isSingleTokenOperation, separateAmountsBySign } from 'src/utils/activity.utils'; import { conditionalStyle } from 'src/utils/conditional-style'; import { shortizeSymbol } from 'src/utils/token-metadata.utils'; @@ -38,9 +38,9 @@ export const ActivityGroupAmountChange: FC = ({ nonZeroAmounts, textSize ); } - const { isPositive, parsedAmount, symbol } = nonZeroAmounts[FIRST_AMOUNT_INDEX]; - if (isSingleTokenOperation(nonZeroAmounts)) { + const { isPositive, parsedAmount, symbol } = nonZeroAmounts[FIRST_AMOUNT_INDEX]; + return ( = ({ nonZeroAmounts, textSize ); } - if (isDoubleTokenOperation(nonZeroAmounts)) { - const symbols = nonZeroAmounts.map(({ symbol }) => symbol).join(','); + const { positiveAmounts, negativeAmounts } = separateAmountsBySign(nonZeroAmounts); + + if (positiveAmounts.length === 0) { + if (negativeAmounts.length === 0) { + return null; + } + const { symbol, parsedAmount } = negativeAmounts[FIRST_AMOUNT_INDEX]; + if (negativeAmounts.length === 1) { + return ( + + ); + } + if (negativeAmounts.length === 2) { + const symbols = negativeAmounts.map(({ symbol }) => symbol).join(','); + + return ( + + -{shortizeSymbol(symbols)} + + ); + } return ( - {isPositive && '+'} - {shortizeSymbol(symbols)} + -{shortizeSymbol(symbol)} and {negativeAmounts.length - 1} others ); - } + } else { + if (positiveAmounts.length === 0) { + return null; + } + const { symbol, parsedAmount } = positiveAmounts[FIRST_AMOUNT_INDEX]; + if (positiveAmounts.length === 1) { + return ( + + ); + } + if (positiveAmounts.length === 2) { + const symbols = positiveAmounts.map(({ symbol }) => symbol).join(','); + + return ( + + +{shortizeSymbol(symbols)} + + ); + } - return ( - - {isPositive ? '+' : '-'} - {shortizeSymbol(symbol)} and {nonZeroAmounts.length - 1} others - - ); + return ( + + +{shortizeSymbol(symbol)} and {positiveAmounts.length - 1} others + + ); + } }, [nonZeroAmounts, textSize]); return {children}; diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx index f24421d4d..d0e4339fe 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx @@ -103,7 +103,11 @@ const ApproveDetails: FC<{ address: string; symbol: string; hash: string }> = me To: - + + + + + @@ -138,8 +142,11 @@ const RevokeDetails: FC<{ address: string; symbol: string; hash: string }> = mem From: - - + + + + + diff --git a/src/utils/activity.utils.ts b/src/utils/activity.utils.ts index 0f7c7615b..45c8a66c4 100644 --- a/src/utils/activity.utils.ts +++ b/src/utils/activity.utils.ts @@ -6,8 +6,6 @@ import { isDefined } from './is-defined'; export const isSingleTokenOperation = (amounts: Array) => amounts.length === 1; -export const isDoubleTokenOperation = (amounts: Array) => amounts.length === 2; - const ZERO = new BigNumber(0); export const calculateDollarValue = (amounts: Array) => diff --git a/src/utils/token-operations.util.ts b/src/utils/token-operations.util.ts index c10c42d0c..282f94f65 100644 --- a/src/utils/token-operations.util.ts +++ b/src/utils/token-operations.util.ts @@ -223,7 +223,8 @@ export const loadActivity = async ( return { activities: [], reachedTheEnd }; } - const oldestOperationNew = operationGroups[operationGroups.length - 1]?.[0]; + const lastGroup = operationGroups[operationGroups.length - 1]; + const oldestOperationNew = lastGroup[lastGroup.length - 1]; const activities = operationGroups .map(group => parseOperations(group, selectedAccount.publicKeyHash, knownBakers)) From dfe06d9fbfdfe5776c1be95e1aafe93b90edde30 Mon Sep 17 00:00:00 2001 From: herkoss Date: Mon, 11 Sep 2023 17:01:30 +0300 Subject: [PATCH 41/43] TW-783 Fixed comments --- .../activity-group-amount-change.tsx | 83 +++++-------------- 1 file changed, 20 insertions(+), 63 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx index 3813c97fa..5869b36ea 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-group-amount-change/activity-group-amount-change.tsx @@ -57,16 +57,20 @@ export const ActivityGroupAmountChange: FC = ({ nonZeroAmounts, textSize const { positiveAmounts, negativeAmounts } = separateAmountsBySign(nonZeroAmounts); - if (positiveAmounts.length === 0) { - if (negativeAmounts.length === 0) { - return null; - } - const { symbol, parsedAmount } = negativeAmounts[FIRST_AMOUNT_INDEX]; - if (negativeAmounts.length === 1) { + if (positiveAmounts.length === 0 && negativeAmounts.length === 0) { + return null; + } + + const isPositiveAmount = positiveAmounts.length > 0; + const source = isPositiveAmount ? positiveAmounts : negativeAmounts; + const { symbol, parsedAmount } = source[FIRST_AMOUNT_INDEX]; + + switch (source.length) { + case 1: return ( = ({ nonZeroAmounts, textSize ]} /> ); - } - if (negativeAmounts.length === 2) { - const symbols = negativeAmounts.map(({ symbol }) => symbol).join(','); + case 2: + const symbols = source.map(({ symbol }) => symbol).join(','); return ( - -{shortizeSymbol(symbols)} + {isPositiveAmount ? '+' : '-'} + {shortizeSymbol(symbols)} ); - } - - return ( - - -{shortizeSymbol(symbol)} and {negativeAmounts.length - 1} others - - ); - } else { - if (positiveAmounts.length === 0) { - return null; - } - const { symbol, parsedAmount } = positiveAmounts[FIRST_AMOUNT_INDEX]; - if (positiveAmounts.length === 1) { - return ( - - ); - } - if (positiveAmounts.length === 2) { - const symbols = positiveAmounts.map(({ symbol }) => symbol).join(','); + default: return ( - +{shortizeSymbol(symbols)} + {isPositiveAmount ? '+' : '-'} + {shortizeSymbol(symbol)} and {negativeAmounts.length - 1} others ); - } - - return ( - - +{shortizeSymbol(symbol)} and {positiveAmounts.length - 1} others - - ); } }, [nonZeroAmounts, textSize]); From 17cfeae37202b8f263e9c7dabd4dfb8479c1023e Mon Sep 17 00:00:00 2001 From: herkoss Date: Tue, 12 Sep 2023 22:53:42 +0300 Subject: [PATCH 42/43] TW-783 Fixed qa issues --- .../activity-group-item.styles.ts | 6 ++++- .../activity-item/change-allowance.tsx | 4 ++-- src/utils/activity.utils.ts | 24 ++++++++++++------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts index cb312a6e2..b3e603fa4 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-item.styles.ts @@ -49,7 +49,7 @@ export const useActivityGroupItemStyles = createUseStyles(({ colors, typography } })); -export const useActivityDetailsStyles = createUseStyles(({ colors }) => ({ +export const useActivityDetailsStyles = createUseStyles(({ colors, typography }) => ({ itemWrapper: { flexDirection: 'row', justifyContent: 'space-between', @@ -67,6 +67,10 @@ export const useActivityDetailsStyles = createUseStyles(({ colors }) => ({ }, mb8: { marginBottom: formatSize(8) + }, + symbolText: { + ...typography.numbersRegular13, + color: colors.black } })); diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx index d0e4339fe..4f2f30abe 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/change-allowance.tsx @@ -96,7 +96,7 @@ const ApproveDetails: FC<{ address: string; symbol: string; hash: string }> = me Approved: - {symbol} + {symbol} @@ -136,7 +136,7 @@ const RevokeDetails: FC<{ address: string; symbol: string; hash: string }> = mem Revoked: - {symbol} + {symbol} diff --git a/src/utils/activity.utils.ts b/src/utils/activity.utils.ts index 45c8a66c4..c517aee44 100644 --- a/src/utils/activity.utils.ts +++ b/src/utils/activity.utils.ts @@ -1,4 +1,5 @@ import { BigNumber } from 'bignumber.js'; +import { isEmpty } from 'lodash-es'; import { ActivityAmount } from 'src/interfaces/non-zero-amounts.interface'; @@ -8,15 +9,6 @@ export const isSingleTokenOperation = (amounts: Array) => amount const ZERO = new BigNumber(0); -export const calculateDollarValue = (amounts: Array) => - amounts.reduce((accum, curr) => { - if (isDefined(curr.fiatAmount)) { - return accum.plus(curr.fiatAmount); - } - - return accum; - }, ZERO); - export const separateAmountsBySign = (nonZeroAmounts: Array) => { const positiveAmounts: Array = []; const negativeAmounts: Array = []; @@ -31,3 +23,17 @@ export const separateAmountsBySign = (nonZeroAmounts: Array) => return { positiveAmounts, negativeAmounts }; }; + +export const calculateDollarValue = (amounts: Array) => { + const { positiveAmounts, negativeAmounts } = separateAmountsBySign(amounts); + + const source = isEmpty(positiveAmounts) ? negativeAmounts : positiveAmounts; + + return source.reduce((accum, curr) => { + if (isDefined(curr.fiatAmount)) { + return accum.plus(curr.fiatAmount); + } + + return accum; + }, ZERO); +}; From 6ea5b28d1dd7234c27840b6b6139853a3e63ef01 Mon Sep 17 00:00:00 2001 From: herkoss Date: Mon, 18 Sep 2023 17:37:39 +0300 Subject: [PATCH 43/43] TW-783 Fixed delegation components and render list --- .../activity-group-item/activity-item/delegate.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx b/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx index bbbfffa37..5b6c2db1c 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx +++ b/src/components/activity-groups-list/activity-group-item/activity-item/delegate.tsx @@ -26,15 +26,15 @@ import { ActivityItemProps } from './item.props'; export const Delegate: FC = memo(({ activity }) => { return ( } - details={
} + face={} + details={
} status={activity.status} timestamp={activity.timestamp} /> ); }); -const Face: FC<{ address: string }> = ({ address }) => { +const Face: FC<{ address: string | undefined }> = ({ address = '' }) => { const styles = useActivityGroupItemStyles(); const commonStyles = useActivityCommonStyles(); @@ -61,7 +61,7 @@ const Face: FC<{ address: string }> = ({ address }) => { ); }; -const Details: FC<{ hash: string; address: string }> = ({ hash, address }) => { +const Details: FC<{ hash: string; address: string | undefined }> = ({ hash, address = '' }) => { const styles = useActivityDetailsStyles(); const commonStyles = useActivityCommonStyles(); const selectedRpcUrl = useSelectedRpcUrlSelector();