Skip to content

Commit

Permalink
refactor: update enable/disable chains and networks logics on demo (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
enesozturk authored Feb 19, 2025
1 parent 9a5e7ec commit e50bcf2
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 66 deletions.
31 changes: 17 additions & 14 deletions apps/builder/components/chain-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,29 @@ export function ChainList() {
removeChain(chainId)
}
} else {
addChain(chainId)
addChain(chainId, undefined)
}
}

return (
<div className="flex flex-col gap-2">
<div className="flex gap-2">
{CHAIN_OPTIONS.map(chain => (
<RoundOptionItem
key={chain.id}
enabled={enabledChains.includes(chain.id)}
disabled={
Boolean(caipAddress) ||
(enabledChains.includes(chain.id) && enabledChains.length === 1)
}
imageSrc={chain.imageSrc}
onChange={() => handleChainChange(chain.id)}
name={chain.name}
/>
))}
{CHAIN_OPTIONS.map(chain => {
const isLastChainInNamespace =
enabledChains.includes(chain.id) && enabledChains.length === 1

return (
<RoundOptionItem
key={chain.id}
enabled={enabledChains.includes(chain.id)}
imageSrc={chain.imageSrc}
onChange={() => handleChainChange(chain.id)}
name={chain.name}
disabled={isLastChainInNamespace}
message={isLastChainInNamespace ? 'Have at least one chain enabled' : ''}
/>
)
})}
</div>
{caipAddress ? (
<Alert>
Expand Down
46 changes: 24 additions & 22 deletions apps/builder/components/network-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,54 @@ import { ExclamationMarkIcon } from '@/components/icon/exclamation-mark'
import { AlertDescription } from '@/components/ui/alert'
import { Alert } from '@/components/ui/alert'
import { useAppKitContext } from '@/hooks/use-appkit'
import { NETWORK_ID_NAMESPACE_MAP, NETWORK_OPTIONS } from '@/lib/constants'
import { NETWORK_OPTIONS, NetworkOption } from '@/lib/constants'
import { getImageDeliveryURL, networkImages } from '@/lib/presets'

import { RoundOptionItem } from './ui/round-option-item'

export function NetworkList() {
const { caipAddress } = useAppKitAccount()
const { enabledChains, enabledNetworks, removeNetwork, addNetwork } = useAppKitContext()
const {
enabledChains,
enabledNetworks,
removeNetwork,
addNetwork,
getEnabledNetworksInNamespace
} = useAppKitContext()

function getIsLastNetworkInNamespace(network: NetworkOption) {
const enabledNetworksInNamespace = getEnabledNetworksInNamespace(network.namespace)

return (
enabledNetworksInNamespace.length === 1 &&
enabledNetworksInNamespace.includes(network.network.id)
)
}

const isLastChain = enabledChains.length === 1

return (
<div className="flex flex-col gap-2">
<div className="flex gap-2 flex-wrap">
{NETWORK_OPTIONS.map(n => {
const isLastNetworkInNamespace =
enabledNetworks.filter(
id =>
NETWORK_ID_NAMESPACE_MAP[id as keyof typeof NETWORK_ID_NAMESPACE_MAP] ===
n.namespace
).length === 1 && enabledNetworks.includes(n.network.id)
const isLastNetworkInNamespace = getIsLastNetworkInNamespace(n)
const isLastChainEnabled = isLastNetworkInNamespace && isLastChain

return (
<RoundOptionItem
message={
isLastNetworkInNamespace
? `Have at least one network enabled on ${
ConstantsUtil.CHAIN_NAME_MAP[n.namespace]
}`
: ''
isLastChainEnabled ? 'Have at least one chain enabled to disable network' : ''
}
size="sm"
key={n.network.id}
enabled={enabledNetworks.includes(n.network.id)}
disabled={
Boolean(caipAddress) ||
(enabledNetworks.includes(n.network.id) && enabledNetworks.length === 1) ||
!enabledChains.includes(n.namespace) ||
isLastNetworkInNamespace
}
disabled={isLastChainEnabled}
imageSrc={getImageDeliveryURL(
networkImages[n.network.id as keyof typeof networkImages]
)}
onChange={() => {
if (enabledNetworks.includes(n.network.id)) {
if (enabledNetworks.length > 1) {
removeNetwork(n)
}
removeNetwork(n)
} else {
addNetwork(n)
}
Expand Down
4 changes: 2 additions & 2 deletions apps/builder/components/ui/round-option-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function RoundOptionItem({
enabled
? 'border border-border-accent bg-background-accent-primary/10 dark:bg-background-accent-primary/10'
: 'border border-neutral-300 dark:border-neutral-700',
disabled && 'opacity-50 cursor-not-allowed'
disabled && 'cursor-not-allowed'
)}
>
<Image
Expand All @@ -50,7 +50,7 @@ export function RoundOptionItem({
</button>
</TooltipTrigger>
<TooltipContent>
<p>{message || name}</p>
<p className="text-sm leading-none text-center">{message || name}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
Expand Down
5 changes: 3 additions & 2 deletions apps/builder/contexts/appkit-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createContext } from 'react'

import { UniqueIdentifier } from '@dnd-kit/core'

import type { ChainNamespace } from '@reown/appkit-common'
import type { AppKitNetwork, ChainNamespace } from '@reown/appkit-common'
import type { Features, SocialProvider, ThemeMode } from '@reown/appkit-core'

import { NetworkOption } from '@/lib/constants'
Expand All @@ -18,7 +18,7 @@ interface AppKitContextType {
isDraggingByKey: Record<string, boolean>
enabledChains: ChainNamespace[]
removeChain: (chain: ChainNamespace) => void
addChain: (chain: ChainNamespace) => void
addChain: (chain: ChainNamespace, network: AppKitNetwork | undefined) => void
removeNetwork: (network: NetworkOption) => void
addNetwork: (network: NetworkOption) => void
updateThemeMode: (mode: ThemeMode) => void
Expand All @@ -30,6 +30,7 @@ interface AppKitContextType {
setSocialsOrder: ((order: SocialProvider[]) => void) | undefined
updateDraggingState: (key: UniqueIdentifier, dragging: boolean) => void
resetConfigs: () => void
getEnabledNetworksInNamespace: (namespace: ChainNamespace) => (string | number)[]
}

export const AppKitContext = createContext<AppKitContextType | undefined>(undefined)
77 changes: 51 additions & 26 deletions apps/builder/providers/appkit-context-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useTheme } from 'next-themes'
import { Toaster } from 'sonner'
import { useSnapshot } from 'valtio'

import { type ChainNamespace } from '@reown/appkit-common'
import { AppKitNetwork, type ChainNamespace } from '@reown/appkit-common'
import { ConnectMethod, ConstantsUtil } from '@reown/appkit-core'
import { Features, ThemeMode, ThemeVariables, useAppKitState } from '@reown/appkit/react'

Expand All @@ -18,7 +18,12 @@ import {
initialEnabledNetworks,
namespaceNetworksMap
} from '@/lib/config'
import { NAMESPACE_NETWORK_IDS_MAP, NETWORK_OPTIONS, NetworkOption } from '@/lib/constants'
import {
NAMESPACE_NETWORK_IDS_MAP,
NETWORK_ID_NAMESPACE_MAP,
NETWORK_OPTIONS,
NetworkOption
} from '@/lib/constants'
import { defaultCustomizationConfig } from '@/lib/defaultConfig'
import { inter } from '@/lib/fonts'
import { URLState, urlStateUtils } from '@/lib/url-state'
Expand Down Expand Up @@ -69,6 +74,16 @@ export const ContextProvider: React.FC<AppKitProviderProps> = ({ children }) =>
}))
}

function getEnabledNetworksInNamespace(namespace: ChainNamespace) {
return Array.from(
new Set(
enabledNetworks.filter(
id => NETWORK_ID_NAMESPACE_MAP[id as keyof typeof NETWORK_ID_NAMESPACE_MAP] === namespace
)
)
)
}

function removeChain(chain: ChainNamespace) {
setEnabledChains(prev => {
const newEnabledChains = prev.filter(c => c !== chain)
Expand All @@ -88,49 +103,58 @@ export const ContextProvider: React.FC<AppKitProviderProps> = ({ children }) =>
})
}

function addChain(chain: ChainNamespace) {
function addChain(chain: ChainNamespace, network: AppKitNetwork | undefined) {
setEnabledChains(prev => {
const newEnabledChains = [...prev, chain]
urlStateUtils.updateURLWithState({ enabledChains: newEnabledChains })
return newEnabledChains
})
const adapter = allAdapters.find(a => a.namespace === chain)
if (adapter) {
appKit?.addAdapter(adapter, namespaceNetworksMap[chain])
appKit?.addAdapter(adapter, network ? [network] : namespaceNetworksMap[chain])
}

// Update enabled networks state
setEnabledNetworks(prev => {
const newNetworks = [...prev, ...NAMESPACE_NETWORK_IDS_MAP[chain]]
const newNetworks = [...prev, ...(network ? [network.id] : NAMESPACE_NETWORK_IDS_MAP[chain])]
urlStateUtils.updateURLWithState({ enabledNetworks: newNetworks as string[] })
return newNetworks
})
}

function removeNetwork(network: NetworkOption) {
setEnabledNetworks(prev => {
const networksInNamespace = NETWORK_OPTIONS.filter(
n => n.namespace === network.namespace && prev.includes(n.network.id)
).map(n => n.network.id)

if (networksInNamespace.length === 1 && networksInNamespace[0] === network.network.id) {
return prev
}

const newNetworks = prev.filter(n => n !== network.network.id)
urlStateUtils.updateURLWithState({ enabledNetworks: newNetworks as string[] })
return newNetworks
})
appKit?.removeNetwork(network.namespace, network.network.id)
const enabledNetworksInNamespace = getEnabledNetworksInNamespace(network.namespace)

if (enabledNetworksInNamespace.length === 1) {
removeChain(network.namespace)
} else {
setEnabledNetworks(prev => {
if (
enabledNetworksInNamespace.length === 1 &&
enabledNetworksInNamespace[0] === network.network.id
) {
return prev
}

const newNetworks = prev.filter(n => n !== network.network.id)
urlStateUtils.updateURLWithState({ enabledNetworks: newNetworks as string[] })
return newNetworks
})
appKit?.removeNetwork(network.namespace, network.network.id)
}
}

function addNetwork(network: NetworkOption) {
setEnabledNetworks(prev => {
const newNetworks = [...prev, network.network.id]
urlStateUtils.updateURLWithState({ enabledNetworks: newNetworks as string[] })
return newNetworks
})
appKit?.addNetwork(network.namespace, network.network)
if (!enabledChains.includes(network.namespace)) {
addChain(network.namespace, network.network)
} else {
setEnabledNetworks(prev => {
const newNetworks = [...prev, network.network.id]
urlStateUtils.updateURLWithState({ enabledNetworks: newNetworks as string[] })
return newNetworks
})
appKit?.addNetwork(network.namespace, network.network)
}
}

function updateFeatures(newFeatures: Partial<Features>) {
Expand Down Expand Up @@ -257,7 +281,8 @@ export const ContextProvider: React.FC<AppKitProviderProps> = ({ children }) =>
setEnableWallets: updateEnableWallets,
setSocialsOrder: appKit?.setSocialsOrder,
updateDraggingState,
resetConfigs
resetConfigs,
getEnabledNetworksInNamespace
}}
>
<Toaster theme={theme as ThemeMode} />
Expand Down

0 comments on commit e50bcf2

Please sign in to comment.