-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(april-fools): add
I'm Feeling Lucky
(#4094)
* feat: add initial I'm Feeling Luck flow * feat: add sound on click Im feeling lucky * feat: disable buy token selector completely for april fools * fix: do show the buy token selector in more cases 1. When not connected 2. When not in SWAP form * chore: move isAprilFoolsEnabled to feature flag and don't show it for the widget * refactor: move useImFeelingLucky to its own file * chore: add lucky list to default enabled lists * feat: load lucky list for mainnet * fix: update import * chore: bump localStorage keys to trigger list update * chore: show unsupported network when network is unsupported * chore: add wasImFeelingLuckyClickedAtom * fix: add missing hook dependency * refactor: move useImFeelingLucky hook to a folder * fix: use regular token list if there are not lucky tokens loaded * chore: remove debug statement * chore: use a local token list rather than importing from url twice * chore: use token address to avoid clashes * chore: april fools 2024 styling (#4099) * feat: progress * feat: progress * feat: progress * chore: remove unsupported tokens from lucky list * chore: move aprilFools logic to SwapWidget and rely on button status * chore: use only gchain addresses from CoWSwap token list * chore: fix build * fix: do not show lucky button unless sell token is selected * chore: only show fees error when both tokens are selected * chore: use a modified uniswap list for now --------- Co-authored-by: fairlight <[email protected]>
- Loading branch information
1 parent
9c69a01
commit 895991b
Showing
26 changed files
with
1,077 additions
and
58 deletions.
There are no files selected for viewing
Binary file not shown.
8 changes: 8 additions & 0 deletions
8
apps/cowswap-frontend/src/common/hooks/featureFlags/useIsAprilFoolsEnabled.ts
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,8 @@ | ||
import { useFeatureFlags } from '@cowprotocol/common-hooks' | ||
import { isInjectedWidget } from '@cowprotocol/common-utils' | ||
|
||
export function useIsAprilFoolsEnabled(): boolean { | ||
const { isAprilFoolsEnabled } = useFeatureFlags() | ||
|
||
return isAprilFoolsEnabled && !isInjectedWidget() | ||
} |
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
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
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
25 changes: 25 additions & 0 deletions
25
apps/cowswap-frontend/src/modules/swap/hooks/useImFeelingLucky/gchainTokenAddresses.json
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,25 @@ | ||
[ | ||
"0x1509706a6c66ca549ff0cb464de88231ddbe213b", | ||
"0x177127622c4a00f3d409b75571e12cb3c8973d3c", | ||
"0x2bf2ba13735160624a0feae98f6ac8f70885ea61", | ||
"0x3a97704a1b25f08aa230ae53b352e2e72ef52843", | ||
"0x44fa8e6f47987339850636f88629646662444217", | ||
"0x5cb9073902f2035222b9749f8fb0c9bfe5527108", | ||
"0x63e62989d9eb2d37dfdb1f93a22f063635b07d51", | ||
"0x6a023ccd1ff6f2045c3309768ead9e68f978f6e1", | ||
"0x6c76971f98945ae98dd7d4dfca8711ebea946ea6", | ||
"0x6de572faa138048ce8142c4a206eb09a8ec39e45", | ||
"0x71850b7e9ee3f13ab46d67167341e4bdc905eef9", | ||
"0x8e5bbbb09ed1ebde8674cda39a0c169401db4252", | ||
"0x9c58bacc331c9aa871afd802db6379a98e80cedb", | ||
"0xa4ef9da5ba71cc0d2e5e877a910a37ec43420445", | ||
"0xaf204776c7245bf4147c2612bf6e5972ee483701", | ||
"0xb0c5f3100a4d9d9532a4cfd68c55f1ae8da987eb", | ||
"0xb7d311e2eb55f2f68a9440da38e7989210b9a05e", | ||
"0xc45b3c1c24d5f54e7a2cf288ac668c74dd507a84", | ||
"0xcb444e90d8198415266c6a2724b7900fb12fc56e", | ||
"0xce11e14225575945b8e6dc0d4f2dd4c570f79d9f", | ||
"0xddafbb505ad214d7b80b1f830fccc89b60fb7a83", | ||
"0xe2e73a1c69ecf83f464efce6a5be353a37ca09b2", | ||
"0xe91d153e0b41518a2ce8dd3d7944fa863463a97d" | ||
] |
84 changes: 84 additions & 0 deletions
84
apps/cowswap-frontend/src/modules/swap/hooks/useImFeelingLucky/index.ts
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,84 @@ | ||
import { atom, useSetAtom } from 'jotai' | ||
import { useCallback } from 'react' | ||
|
||
import { NATIVE_CURRENCIES, SWR_NO_REFRESH_OPTIONS, TokenWithLogo } from '@cowprotocol/common-const' | ||
import { getImFeelingLuckySound } from '@cowprotocol/common-utils' | ||
import { SupportedChainId } from '@cowprotocol/cow-sdk' | ||
import { useAllTokens } from '@cowprotocol/tokens' | ||
import { useWalletInfo } from '@cowprotocol/wallet' | ||
|
||
import useSWR from 'swr' | ||
import { Nullish } from 'types' | ||
|
||
import { useTradeNavigate } from 'modules/trade/hooks/useTradeNavigate' | ||
import { useTradeState } from 'modules/trade/hooks/useTradeState' | ||
|
||
import gchainAddresses from './gchainTokenAddresses.json' | ||
import mainnetLuckyTokens from './luckyTokens.tokenlist.json' | ||
|
||
const GCHAIN_ADDRESS = new Set(gchainAddresses) | ||
|
||
export function useImFeelingLucky() { | ||
const { state } = useTradeState() | ||
const inputCurrencyId = state?.inputCurrencyId | ||
const setWasImFeelingLuckyClicked = useSetAtom(wasImFeelingLuckyClickedAtom) | ||
|
||
const { chainId } = useWalletInfo() | ||
const navigate = useTradeNavigate() | ||
|
||
const tokens = useImFeelingLuckyTokens(chainId, inputCurrencyId) | ||
|
||
return useCallback(() => { | ||
const selected = pickRandom(tokens) | ||
|
||
getImFeelingLuckySound().play() | ||
setWasImFeelingLuckyClicked(true) | ||
navigate(chainId, { | ||
inputCurrencyId: inputCurrencyId || NATIVE_CURRENCIES[chainId].symbol || null, | ||
outputCurrencyId: selected?.address || null, | ||
}) | ||
}, [tokens, setWasImFeelingLuckyClicked, navigate, chainId, inputCurrencyId]) | ||
} | ||
|
||
function pickRandom<T>(list: T[]): T | undefined { | ||
if (list.length === 0) { | ||
return undefined | ||
} | ||
|
||
const randomIndex = Math.floor(Math.random() * list.length) | ||
return list[randomIndex] | ||
} | ||
|
||
function useImFeelingLuckyTokens(chainId: SupportedChainId, sellTokenId: Nullish<string>): TokenWithLogo[] { | ||
const isMainnet = chainId === SupportedChainId.MAINNET | ||
const isGchain = chainId === SupportedChainId.GNOSIS_CHAIN | ||
|
||
const tokens = useAllTokens() | ||
|
||
const { data: mainnetList } = useSWR<TokenWithLogo[]>( | ||
'luckyTokens', | ||
() => mainnetLuckyTokens.tokens.map((t) => TokenWithLogo.fromToken(t)), | ||
{ ...SWR_NO_REFRESH_OPTIONS, fallbackData: [] } | ||
) | ||
|
||
if (isMainnet && mainnetList?.length) { | ||
return mainnetList.filter(sellTokenFilterFactory(sellTokenId)) | ||
} else if (isGchain) { | ||
return tokens | ||
.filter(({ address }) => GCHAIN_ADDRESS.has(address.toLowerCase())) | ||
.filter(sellTokenFilterFactory(sellTokenId)) | ||
} | ||
return tokens.filter(sellTokenFilterFactory(sellTokenId)) | ||
} | ||
|
||
function sellTokenFilterFactory(sellTokenId: Nullish<string>) { | ||
return ({ symbol, address }: TokenWithLogo) => symbol !== sellTokenId && address !== sellTokenId | ||
} | ||
|
||
export const wasImFeelingLuckyClickedAtom = atom(false) | ||
|
||
export function useResetWasImFeelingLuckyClicked() { | ||
const setAtom = useSetAtom(wasImFeelingLuckyClickedAtom) | ||
|
||
return useCallback(() => setAtom(false), [setAtom]) | ||
} |
Oops, something went wrong.