-
Notifications
You must be signed in to change notification settings - Fork 333
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CN-508: stake filters for eth staking modal (#7870)
* feat: Select staking provider modal desktop v2 * feat: Select staking provider modal mobile v2 * chore: update V1 modal's folder to _deprecated * chore: add KelpDAO svg icon to mobile * chore: add P2P and RocketPool logos to mobile * chore: minor fixes * chore: changeset * feat: guard new modal behind feature flag * fix: broken types import * chore: cleanup * fix: size prop for native ChipTabs * fix: braze transform ignore on jest config * chore: update copy and add disabled filter to deprecated banner * chore: final copy * fix: icon sizes and outline for light mode * fix: visual updates to the modals * fix: visual updates to the gradient effect * feat: tracking interactions * chore: replace Braze feature flag with Firebase's * chore: address PR comments pt 1 * chore: use camelCase for translation keys * chore: extract styled-components from StakeFlowModal * chore: revert modal radius change * chore: re-arrange paddings of modal * chore: remove unnecessary check * chore: remove autoredirect with one provider on mobile version of modal
- Loading branch information
1 parent
191b105
commit 1b3a21d
Showing
44 changed files
with
1,903 additions
and
415 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
--- | ||
"ledger-live-desktop": minor | ||
"live-mobile": minor | ||
"@ledgerhq/icons-ui": minor | ||
"@ledgerhq/types-live": patch | ||
"@ledgerhq/native-ui": patch | ||
--- | ||
|
||
ledger-live-desktop: Updated staking modal. Filtering per category. New copy and design | ||
live-mobile: Updated staking modal. Filtering per category. New copy and design | ||
@ledgerhq/icons-ui: Add book-graduation icon | ||
@ledgerhq/types-live: Update schema of ethStakingProviders flag | ||
@ledgerhq/native-ui: Add `xs` size to Button |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 80 additions & 61 deletions
141
apps/ledger-live-desktop/src/renderer/families/evm/StakeFlowModal/component/ProviderItem.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,94 +1,113 @@ | ||
import { useRemoteLiveAppManifest } from "@ledgerhq/live-common/platform/providers/RemoteLiveAppProvider/index"; | ||
import { Flex, Icon, Tag as TagCore, Text } from "@ledgerhq/react-ui"; | ||
import React, { useCallback, useEffect, useMemo } from "react"; | ||
import { useLocalLiveAppManifest } from "@ledgerhq/live-common/wallet-api/LocalLiveAppProvider/index"; | ||
import { CryptoIcon, Flex, Icon, Text } from "@ledgerhq/react-ui"; | ||
import { EthStakingProvider } from "@ledgerhq/types-live"; | ||
import React, { useCallback, useMemo } from "react"; | ||
import { useTranslation } from "react-i18next"; | ||
import styled, { DefaultTheme, StyledComponent } from "styled-components"; | ||
import ProviderIcon from "~/renderer/components/ProviderIcon"; | ||
import { StakeOnClickProps } from "../EthStakingModalBody"; | ||
import { StakingIcon } from "../StakingIcon"; | ||
import { ListProvider } from "../types"; | ||
import { useLocalLiveAppManifest } from "@ledgerhq/live-common/wallet-api/LocalLiveAppProvider/index"; | ||
|
||
export const Container: StyledComponent< | ||
"div", | ||
DefaultTheme, | ||
Record<string, unknown>, | ||
never | ||
> = styled(Flex)` | ||
const IconContainer = styled.div( | ||
({ theme }) => ` | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
width: ${theme.space[6]}px; | ||
height: ${theme.space[6]}px; | ||
border-radius: 100%; | ||
background-color: ${theme.colors.opacityDefault.c05}; | ||
margin-top: ${theme.space[3]}px; | ||
`, | ||
); | ||
|
||
function StakingIcon({ icon }: { icon?: string }) { | ||
if (!icon) { | ||
return null; | ||
} | ||
|
||
const [iconName, iconType] = icon.split(":"); | ||
|
||
// if no icon type then treat as "normal" icon. | ||
if (!iconType) { | ||
return ( | ||
<IconContainer> | ||
<Icon name={iconName} size={14} /> | ||
</IconContainer> | ||
); | ||
} | ||
if (iconType === "crypto") { | ||
return <CryptoIcon name={iconName} size={40} />; | ||
} | ||
if (iconType === "provider") { | ||
return ( | ||
<Flex> | ||
<ProviderIcon name={iconName} size="M" /> | ||
</Flex> | ||
); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
const Container: StyledComponent<"div", DefaultTheme, Record<string, unknown>, never> = styled( | ||
Flex, | ||
)` | ||
cursor: pointer; | ||
border-radius: 8px; | ||
background-color: ${p => p.theme.colors.opacityDefault.c05}; | ||
:hover { | ||
background-color: ${p => p.theme.colors.primary.c10}; | ||
} | ||
`; | ||
|
||
export const Tag = styled(TagCore)` | ||
padding: 3px 6px; | ||
> span { | ||
font-size: 11px; | ||
text-transform: none; | ||
font-weight: bold; | ||
line-height: 11.66px; | ||
} | ||
`; | ||
|
||
type Props = { | ||
provider: ListProvider; | ||
interface Props { | ||
provider: EthStakingProvider; | ||
stakeOnClick(_: StakeOnClickProps): void; | ||
redirectIfOnlyProvider(_: StakeOnClickProps): void; | ||
}; | ||
} | ||
|
||
const ProviderItem = ({ provider, stakeOnClick, redirectIfOnlyProvider }: Props) => { | ||
const { t, i18n } = useTranslation(); | ||
export const ProviderItem = ({ provider, stakeOnClick }: Props) => { | ||
const { t } = useTranslation(); | ||
|
||
const localManifest = useLocalLiveAppManifest(provider.liveAppId); | ||
const remoteManifest = useRemoteLiveAppManifest(provider.liveAppId); | ||
|
||
const manifest = useMemo(() => remoteManifest || localManifest, [localManifest, remoteManifest]); | ||
|
||
const hasTag = !!provider?.min && i18n.exists(`ethereum.stake.${provider.id}.tag`); | ||
|
||
useEffect(() => { | ||
if (manifest) redirectIfOnlyProvider({ provider, manifest }); | ||
}, [redirectIfOnlyProvider, provider, manifest]); | ||
|
||
const stakeLink = useCallback(() => { | ||
if (manifest) stakeOnClick({ provider, manifest }); | ||
const handleClick = useCallback(() => { | ||
if (manifest) { | ||
stakeOnClick({ provider, manifest }); | ||
} | ||
}, [provider, stakeOnClick, manifest]); | ||
|
||
return ( | ||
<Container | ||
pl={3} | ||
onClick={stakeLink} | ||
py={4} | ||
alignItems="center" | ||
borderRadius={2} | ||
columnGap={4} | ||
data-testid={`stake-provider-container-${provider.id}`} | ||
onClick={handleClick} | ||
p={3} | ||
> | ||
<StakingIcon icon={provider.icon} /> | ||
<Flex flexDirection={"column"} ml={5} flex={"auto"} alignItems="flex-start"> | ||
<Flex alignItems="center"> | ||
<Text variant="bodyLineHeight" fontSize={14} fontWeight="semiBold" mr={2}> | ||
{t(`ethereum.stake.${provider.id}.title`)} | ||
</Text> | ||
{hasTag && ( | ||
<Tag | ||
size="small" | ||
active | ||
type="plain" | ||
style={{ fontFamily: "14px", textTransform: "none" }} | ||
> | ||
{t(`ethereum.stake.${provider.id}.tag`)} | ||
</Tag> | ||
)} | ||
</Flex> | ||
|
||
<Flex alignItems="flex-start" flex={2} flexDirection="column"> | ||
<Text variant="bodyLineHeight" fontSize={14} fontWeight="semiBold" mr={2}> | ||
{t(`ethereum.stake.provider.${provider.id}.title`)} | ||
</Text> | ||
<Text variant="paragraph" fontSize={13} color="neutral.c70"> | ||
{t(`ethereum.stake.${provider.id}.description`)} | ||
{provider.lst | ||
? t("ethereum.stake.lst") | ||
: provider.min | ||
? t("ethereum.stake.requiredMinimum", { | ||
min: provider.min, | ||
}) | ||
: t("ethereum.stake.noMinimum")} | ||
</Text> | ||
</Flex> | ||
<Flex width={40} justifyContent="center" alignItems="center"> | ||
<Icon name="ChevronRight" size={25} /> | ||
<Flex flex={1} flexWrap="wrap" justifyContent="right"> | ||
<Text variant="paragraph" fontSize={13} color="neutral.c70" textAlign="right"> | ||
{t(`ethereum.stake.rewardsStrategy.${provider.rewardsStrategy}`)} | ||
</Text> | ||
</Flex> | ||
</Container> | ||
); | ||
}; | ||
|
||
export default ProviderItem; |
Oops, something went wrong.