Skip to content

Commit 0656f4a

Browse files
authored
feat: merge rfox into rfox ecosystem (#10323)
1 parent 9d64b32 commit 0656f4a

File tree

39 files changed

+1022
-91
lines changed

39 files changed

+1022
-91
lines changed

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,4 @@ VITE_FEATURE_THORCHAIN_TCY=true
188188
VITE_FEATURE_THORCHAIN_TCY_WIDGET=true
189189

190190
VITE_FEATURE_TX_HISTORY_BYE_BYE=false
191+
VITE_FEATURE_RFOX_FOX_ECOSYSTEM_PAGE=false

.env.development

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,4 @@ NODE_ENV=development
7373
VITE_FEATURE_MIXPANEL=true
7474

7575
VITE_FEATURE_TX_HISTORY_BYE_BYE=true
76+
VITE_FEATURE_RFOX_FOX_ECOSYSTEM_PAGE=true

src/Routes/RoutesCommon.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { RouteCategory } from './helpers'
99

1010
import { ExploreIcon } from '@/components/Icons/Explore'
1111
import { FoxIcon } from '@/components/Icons/FoxIcon'
12+
import { FoxPageIcon } from '@/components/Icons/FoxPageIcon'
1213
import { HomeIcon } from '@/components/Icons/Home'
1314
import { PoolsIcon } from '@/components/Icons/Pools'
1415
import { RFOXIcon } from '@/components/Icons/RFOX'
@@ -22,6 +23,7 @@ import { getConfig } from '@/config'
2223
import { assetIdPaths } from '@/hooks/useRouteAssetId/useRouteAssetId'
2324
import { Accounts } from '@/pages/Accounts/Accounts'
2425
import { ExploreCategory } from '@/pages/Explore/ExploreCategory'
26+
import { FoxEcosystemPage } from '@/pages/Fox/FoxEcosystemPage'
2527
import { FoxPage } from '@/pages/Fox/FoxPage'
2628
import { History } from '@/pages/History/History'
2729
import { RFOX } from '@/pages/RFOX/RFOX'
@@ -269,7 +271,7 @@ export const routes: Route[] = [
269271
priority: 1,
270272
main: RFOX,
271273
category: RouteCategory.Fox,
272-
disable: !getConfig().VITE_FEATURE_RFOX,
274+
disable: !getConfig().VITE_FEATURE_RFOX || getConfig().VITE_FEATURE_RFOX_FOX_ECOSYSTEM_PAGE,
273275
},
274276
{
275277
path: '/fox',
@@ -279,7 +281,16 @@ export const routes: Route[] = [
279281
category: RouteCategory.Fox,
280282
priority: 6,
281283
mobileNav: false,
282-
disable: !getConfig().VITE_FEATURE_FOX_PAGE,
284+
disable: !getConfig().VITE_FEATURE_FOX_PAGE || getConfig().VITE_FEATURE_RFOX_FOX_ECOSYSTEM_PAGE,
285+
},
286+
{
287+
path: '/fox-ecosystem/*',
288+
label: 'navBar.foxEcosystem',
289+
icon: <FoxPageIcon />,
290+
main: FoxEcosystemPage,
291+
priority: 6,
292+
mobileNav: false,
293+
disable: !getConfig().VITE_FEATURE_RFOX_FOX_ECOSYSTEM_PAGE,
283294
},
284295
{
285296
path: '/tcy/*',

src/assets/translations/en/main.json

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,19 @@
11211121
"youGotMore": "You got %{cryptoUpside} more on this trade"
11221122
},
11231123
"networkFee": "Network Fee",
1124-
"feeExplainer": "Quote includes a %{feePercentage}% ShapeShift fee"
1124+
"feeExplainer": "Quote includes a %{feePercentage}% ShapeShift fee",
1125+
"claim": {
1126+
"pending": "Your claim of %{amount} %{symbol} is being processed.",
1127+
"complete": "Your claim of %{amount} %{symbol} is complete."
1128+
},
1129+
"rewardDistribution": {
1130+
"pending": {
1131+
"description": "Your reward of %{amountAndSymbol} is processing..."
1132+
},
1133+
"complete": {
1134+
"description": "Your reward of %{amountAndSymbol} is complete."
1135+
}
1136+
}
11251137
},
11261138
"limitOrder": {
11271139
"heading": "Limit",
@@ -1352,7 +1364,7 @@
13521364
},
13531365
"skip": {
13541366
"title": "Skip this step?",
1355-
"description": "Skipping the backup means you won't be able to recover your wallet if you lose access to your device.",
1367+
"description": "Skipping the backup means you wont be able to recover your wallet if you lose access to your device.",
13561368
"confirmCta": "Yes, I’ve saved my seed phrase"
13571369
}
13581370
}
@@ -2715,6 +2727,9 @@
27152727
}
27162728
},
27172729
"RFOX": {
2730+
"stakeInitiated": "Stake Initiated",
2731+
"unstakeInitiated": "Unstake Initiated",
2732+
"claimWithdraw": "Claim Withdraw",
27182733
"staking": "rFOX Staking",
27192734
"bridge": "Bridge",
27202735
"bridgeFunds": "Bridge Funds",
@@ -2879,7 +2894,7 @@
28792894
"confirmTitle": "Confirm Claim",
28802895
"networkFee": "Network Fee",
28812896
"confirmAndClaim": "Claim & Stake",
2882-
"notice": "You’re claiming %{amount} TCY. It’ll be automatically staked — unstake anytime after to receive it in your wallet."
2897+
"notice": "You’re claiming %{amount} TCY. It’ll be automatically staked — unstake anytime after to receive it in your wallet."
28832898
},
28842899
"assetClaimButton": {
28852900
"claimAction": "Claim"
@@ -3126,6 +3141,14 @@
31263141
"limitOrderTitle": "%{sellAmount} %{sellSymbol} → %{buyAmount} %{buySymbol}",
31273142
"pendingTransactions": "%{count} Pending",
31283143
"orderCancelled": "Order Cancelled",
3129-
"orderExpired": "Order Expired"
3144+
"orderExpired": "Order Expired",
3145+
"rewardDistribution": {
3146+
"pending": {
3147+
"description": "Your reward of %{amountAndSymbol} is processing..."
3148+
},
3149+
"complete": {
3150+
"description": "Your reward of %{amountAndSymbol} is complete."
3151+
}
3152+
}
31303153
}
31313154
}

src/components/AssetSearch/components/AssetRow.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,13 @@ export const AssetRow: FC<{ asset: Asset; index: number; data: AssetData }> = me
4040
)
4141
const userCurrencyBalance =
4242
useAppSelector(s => selectPortfolioUserCurrencyBalanceByAssetId(s, filter)) ?? '0'
43-
const handleOnClick = useCallback(() => handleClick(asset), [asset, handleClick])
43+
const handleOnClick = useCallback(
44+
(event: React.MouseEvent<HTMLButtonElement>) => {
45+
event.stopPropagation()
46+
handleClick(asset)
47+
},
48+
[asset, handleClick],
49+
)
4450

4551
if (!asset) return null
4652

src/components/ButtonWalletPredicate/ButtonWalletPredicate.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import type { ButtonProps } from '@chakra-ui/react'
2-
import { Button } from '@chakra-ui/react'
2+
import { Button, useMediaQuery } from '@chakra-ui/react'
33
import { useCallback } from 'react'
44
import { useTranslate } from 'react-polyglot'
5+
import { Drawer } from 'vaul'
56

7+
import { useSafeDialog } from '@/context/DialogContextProvider/DialogContextProvider'
68
import { WalletActions } from '@/context/WalletProvider/actions'
79
import { useWallet } from '@/hooks/useWallet/useWallet'
10+
import { breakpoints } from '@/theme/theme'
811

912
type ButtonWalletPredicateProps = {
1013
isValidWallet: boolean
@@ -20,17 +23,31 @@ export const ButtonWalletPredicate = ({
2023
dispatch,
2124
state: { isConnected },
2225
} = useWallet()
26+
const { isOpen } = useSafeDialog()
27+
const [isLargerThanMd] = useMediaQuery(`(min-width: ${breakpoints['md']})`, { ssr: false })
2328

2429
const handleConnect = useCallback(() => {
2530
dispatch({ type: WalletActions.SET_WALLET_MODAL, payload: true })
2631
}, [dispatch])
2732

28-
if (!isConnected)
33+
if (!isConnected) {
34+
// @TODO: This is a hack to close any drawer if this button is in the context of a drawer, remove me if we have a better way to handle multiple modal stacking
35+
if (isOpen && !isLargerThanMd) {
36+
return (
37+
<Drawer.Close>
38+
<Button {...restProps} onClick={handleConnect} isDisabled={false} colorScheme='blue'>
39+
{translate('common.connectWallet')}
40+
</Button>
41+
</Drawer.Close>
42+
)
43+
}
44+
2945
return (
3046
<Button {...restProps} onClick={handleConnect} isDisabled={false} colorScheme='blue'>
3147
{translate('common.connectWallet')}
3248
</Button>
3349
)
50+
}
3451

3552
return (
3653
<>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { createIcon } from '@chakra-ui/react'
2+
3+
export const FoxPageIcon = createIcon({
4+
displayName: 'FoxPageIcon',
5+
path: (
6+
<>
7+
<path
8+
d='M 395.500 1.448 C 393.300 2.144, 373.950 10.134, 352.500 19.204 C 331.050 28.273, 302.925 39.925, 290 45.097 L 266.500 54.500 208.139 54.774 L 149.777 55.047 124.139 44.870 C 110.037 39.272, 80.950 27.289, 59.500 18.240 C 17.440 0.497, 15.050 -0.185, 7.632 3.446 C 2.336 6.039, 0.008 10.183, 0.004 17.026 C 0.002 20.066, 6.267 60.241, 13.926 106.303 L 27.851 190.054 13.926 235.134 C -1.313 284.464, -1.923 287.561, 2.542 292.867 C 3.940 294.529, 12.262 300.301, 21.036 305.694 C 29.809 311.087, 36.990 315.847, 36.994 316.272 C 36.997 316.696, 31.938 324.571, 25.750 333.772 L 14.500 350.500 14.500 357 C 14.500 362.097, 14.975 364.166, 16.701 366.586 C 19.491 370.496, 36.725 381.923, 41.436 382.986 C 45.859 383.983, 51.831 382.548, 55.231 379.671 C 56.642 378.477, 72.492 355.565, 90.452 328.756 C 108.413 301.947, 123.955 279.560, 124.989 279.006 C 130.049 276.298, 133.383 277.612, 157.772 291.934 C 171.475 299.981, 183.530 306.374, 186.306 307.067 C 195.359 309.325, 207 305.973, 213.128 299.343 C 214.574 297.779, 227.334 278.050, 241.484 255.500 C 255.633 232.950, 267.728 213.951, 268.361 213.280 C 269.252 212.335, 274.322 215.085, 290.937 225.530 C 312.409 239.028, 315.548 240.382, 319.929 238.038 C 320.917 237.509, 322.271 235.759, 322.938 234.149 C 324 231.587, 322.890 224.889, 314.029 180.361 C 308.462 152.388, 303.412 128.235, 302.807 126.689 C 301.306 122.855, 295.870 118.919, 291.287 118.348 C 287.279 117.848, 184.454 138.950, 180.316 141.121 C 177.478 142.610, 175.706 146.982, 176.561 150.386 C 177.416 153.792, 179.010 154.969, 204.500 171.008 C 216.050 178.276, 225.632 184.342, 225.794 184.488 C 226.419 185.055, 189.709 242.624, 187.367 244.750 C 186.004 245.987, 184.111 247, 183.160 247 C 182.209 247, 170.646 240.647, 157.465 232.881 C 126.446 214.607, 124.398 213.659, 117.089 214.187 C 105.944 214.993, 104.529 216.425, 82.930 248.752 C 72.366 264.563, 63.335 277.927, 62.862 278.450 C 61.665 279.769, 53.471 275.649, 51.594 272.784 C 50.193 270.646, 50.920 268.050, 62.675 233.194 L 75.256 195.891 64.132 128.274 C 58.015 91.085, 53.120 60.551, 53.255 60.420 C 53.659 60.028, 95.860 77.005, 120.312 87.397 C 132.858 92.728, 145.560 97.541, 148.537 98.092 C 151.871 98.708, 175.771 98.979, 210.726 98.796 L 267.500 98.500 289.500 89.124 C 317.800 77.064, 360.240 59.907, 360.681 60.348 C 360.869 60.536, 356.009 91.109, 349.880 128.288 L 338.737 195.887 351.378 233.193 C 363.971 270.357, 364.011 270.508, 362.175 272.968 C 361.111 274.393, 351.269 280.129, 338.915 286.525 C 287.983 312.895, 257.277 336.995, 219.141 380.532 C 212.894 387.665, 207.494 393.609, 207.141 393.743 C 206.789 393.876, 200.875 387.887, 194 380.435 C 175.378 360.248, 134.619 323, 131.152 323 C 130.058 323, 107 357.358, 107 358.988 C 107 359.465, 110.262 362.389, 114.250 365.485 C 133.664 380.559, 156.155 403.208, 183.443 435.162 C 190.342 443.241, 196.478 449.473, 198.456 450.412 C 202.841 452.493, 211.019 452.435, 215.514 450.292 C 217.766 449.218, 223.387 443.557, 230.657 435.042 C 257.355 403.768, 278.531 382.363, 299 365.957 C 309.329 357.678, 339.815 337.873, 375 316.582 C 412.414 293.943, 415 291.792, 415 283.312 C 415 280.326, 414.658 278.093, 414.240 278.352 C 413.822 278.610, 407.318 258.724, 399.787 234.161 L 386.093 189.500 399.831 107.299 C 407.387 62.088, 413.891 24.776, 414.284 24.382 C 414.678 23.989, 415 20.517, 415 16.667 C 415 12.817, 414.712 9.955, 414.360 10.307 C 414.008 10.659, 412.945 9.496, 411.997 7.723 C 408.929 1.984, 402.062 -0.628, 395.500 1.448 M 0.336 18 C 0.336 22.125, 0.513 23.813, 0.728 21.750 C 0.944 19.688, 0.944 16.313, 0.728 14.250 C 0.513 12.188, 0.336 13.875, 0.336 18 M 0.310 284.500 C 0.315 287.800, 0.502 289.029, 0.725 287.232 C 0.947 285.435, 0.943 282.735, 0.715 281.232 C 0.486 279.729, 0.304 281.200, 0.310 284.500'
9+
stroke='none'
10+
fill='currentColor'
11+
fill-rule='evenodd'
12+
/>
13+
<path d='' stroke='none' fill='currentColor' fill-rule='evenodd' />
14+
</>
15+
),
16+
viewBox: '0 0 414 452',
17+
})

src/components/Layout/Header/ActionCenter/ActionCenter.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,21 @@ import { AppUpdateActionCard } from './components/AppUpdateActionCard'
2121
import { EmptyState } from './components/EmptyState'
2222
import { GenericTransactionActionCard } from './components/GenericTransactionActionCard'
2323
import { LimitOrderActionCard } from './components/LimitOrderActionCard'
24+
import { RewardDistributionActionCard } from './components/RewardDistributionActionCard'
2425
import { RfoxClaimActionCard } from './components/RfoxClaimActionCard'
2526
import { SwapActionCard } from './components/SwapActionCard'
2627
import { TcyClaimActionCard } from './components/TcyClaimActionCard'
2728

2829
import { Display } from '@/components/Display'
30+
import { RfoxInitiatedActionCard } from '@/components/Layout/Header/ActionCenter/components/RfoxInitiatedActionCard'
2931
import { CancelLimitOrder } from '@/components/MultiHopTrade/components/LimitOrder/components/CancelLimitOrder'
3032
import { useLimitOrders } from '@/components/MultiHopTrade/components/LimitOrder/hooks/useLimitOrders'
3133
import type { OrderToCancel } from '@/components/MultiHopTrade/components/LimitOrder/types'
3234
import {
3335
selectWalletActionsSorted,
3436
selectWalletPendingActions,
3537
} from '@/state/slices/actionSlice/selectors'
36-
import { ActionType } from '@/state/slices/actionSlice/types'
38+
import { ActionType, GenericTransactionDisplayType } from '@/state/slices/actionSlice/types'
3739
import { swapSlice } from '@/state/slices/swapSlice/swapSlice'
3840
import { useAppSelector } from '@/state/store'
3941

@@ -105,6 +107,10 @@ export const ActionCenter = memo(() => {
105107
case ActionType.ChangeAddress:
106108
case ActionType.Approve:
107109
case ActionType.Claim: {
110+
if (action.transactionMetadata.displayType === GenericTransactionDisplayType.RFOX) {
111+
return <RfoxInitiatedActionCard key={action.id} action={action} />
112+
}
113+
108114
return <GenericTransactionActionCard key={action.id} action={action} />
109115
}
110116
case ActionType.RfoxClaim: {
@@ -113,6 +119,9 @@ export const ActionCenter = memo(() => {
113119
case ActionType.TcyClaim: {
114120
return <TcyClaimActionCard key={action.id} action={action} />
115121
}
122+
case ActionType.RewardDistribution: {
123+
return <RewardDistributionActionCard key={action.id} action={action} />
124+
}
116125
default:
117126
return null
118127
}

src/components/Layout/Header/ActionCenter/components/GenericTransactionActionCard.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,7 @@ export const GenericTransactionActionCard = ({ action }: GenericTransactionActio
7474
}, [asset, action.transactionMetadata.assetId, action.status])
7575

7676
const footer = useMemo(() => {
77-
return (
78-
<>
79-
<ActionStatusTag status={action.status} />
80-
</>
81-
)
77+
return <ActionStatusTag status={action.status} />
8278
}, [action.status])
8379

8480
return (
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { Box, Flex, HStack, Stack } from '@chakra-ui/react'
2+
import type { RenderProps } from '@chakra-ui/react/dist/types/toast/toast.types'
3+
import { thorchainAssetId } from '@shapeshiftoss/caip'
4+
import { fromBaseUnit } from '@shapeshiftoss/utils'
5+
import { useMemo } from 'react'
6+
7+
import { NotificationWrapper } from './NotificationWrapper'
8+
9+
import { Amount } from '@/components/Amount/Amount'
10+
import { AssetIconWithBadge } from '@/components/AssetIconWithBadge'
11+
import { ActionStatusIcon } from '@/components/Layout/Header/ActionCenter/components/ActionStatusIcon'
12+
import type { TextPropTypes } from '@/components/Text/Text'
13+
import { Text } from '@/components/Text/Text'
14+
import type { RewardDistributionWithMetadata } from '@/pages/RFOX/hooks/useLifetimeRewardDistributionsQuery'
15+
import { actionSlice } from '@/state/slices/actionSlice/actionSlice'
16+
import { ActionStatus } from '@/state/slices/actionSlice/types'
17+
import { selectAssetById } from '@/state/slices/selectors'
18+
import { useAppSelector } from '@/state/store'
19+
20+
type RewardDistributionNotificationProps = {
21+
distribution: RewardDistributionWithMetadata
22+
actionId: string
23+
handleClick: () => void
24+
onClose: () => void
25+
} & RenderProps
26+
27+
export const RewardDistributionNotification = ({
28+
distribution,
29+
actionId,
30+
handleClick,
31+
onClose,
32+
}: RewardDistributionNotificationProps) => {
33+
const runeAsset = useAppSelector(state => selectAssetById(state, thorchainAssetId))
34+
const actions = useAppSelector(actionSlice.selectors.selectActionsById)
35+
const action = actions[actionId]
36+
const isComplete = action?.status === ActionStatus.Complete
37+
38+
const rewardDistributionTranslationComponents: TextPropTypes['components'] = useMemo(() => {
39+
if (!runeAsset) return
40+
41+
return {
42+
amountAndSymbol: (
43+
<Amount.Crypto
44+
value={fromBaseUnit(distribution.amount.toString(), runeAsset.precision ?? 0)}
45+
symbol={runeAsset?.symbol}
46+
fontSize='sm'
47+
fontWeight='bold'
48+
maximumFractionDigits={6}
49+
omitDecimalTrailingZeros
50+
display='inline'
51+
/>
52+
),
53+
}
54+
}, [distribution.amount, runeAsset])
55+
56+
const rewardDistributionTitleTranslation = useMemo(() => {
57+
if (isComplete) return 'actionCenter.rewardDistribution.complete.description'
58+
return 'actionCenter.rewardDistribution.pending.description'
59+
}, [isComplete])
60+
61+
if (!distribution) return null
62+
63+
return (
64+
<NotificationWrapper handleClick={handleClick} onClose={onClose}>
65+
<Stack spacing={3}>
66+
<Flex alignItems='center' justifyContent='space-between' pe={6}>
67+
<HStack spacing={2}>
68+
<AssetIconWithBadge assetId={thorchainAssetId} size='md'>
69+
<ActionStatusIcon status={action.status} />
70+
</AssetIconWithBadge>
71+
72+
<Box ml={2}>
73+
<Text
74+
flex={1}
75+
fontSize='sm'
76+
letterSpacing='0.02em'
77+
translation={rewardDistributionTitleTranslation}
78+
components={rewardDistributionTranslationComponents}
79+
/>
80+
</Box>
81+
</HStack>
82+
</Flex>
83+
</Stack>
84+
</NotificationWrapper>
85+
)
86+
}

0 commit comments

Comments
 (0)