Skip to content

Commit

Permalink
feat: Navbar2 from UI2 (#657)
Browse files Browse the repository at this point in the history
* feat: Navbar2 from UI2

* feat: update decentraland-ui2 v 0.8.3
  • Loading branch information
braianj authored Jan 6, 2025
1 parent 41a09d8 commit f0a8de7
Show file tree
Hide file tree
Showing 8 changed files with 939 additions and 51 deletions.
702 changes: 651 additions & 51 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"decentraland-crypto-fetch": "^2.0.1",
"decentraland-transactions": "^2.18.0",
"decentraland-ui": "^6.11.0",
"decentraland-ui2": "^0.8.3",
"ethers": "^5.6.8",
"events": "^3.3.0",
"flat": "^5.0.2",
Expand Down
17 changes: 17 additions & 0 deletions src/containers/Navbar/Navbar.types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Dispatch } from 'redux'
import { ChainId } from '@dcl/schemas/dist/dapps/chain-id'
import { AuthIdentity } from '@dcl/crypto'
import { NavbarProps as NavbarComponentProps } from 'decentraland-ui/dist/components/Navbar/Navbar.types'
import { NavbarProps as NavbarComponentProps2 } from 'decentraland-ui2'
import {
disconnectWalletRequest,
switchNetworkRequest,
Expand All @@ -24,6 +25,22 @@ export type NavbarProps = NavbarComponentProps & {
onSignIn: () => void
}

export type NavbarProps2 = NavbarComponentProps2 & {
withChainSelector?: boolean
chainId?: ChainId
appChainId: ChainId
docsUrl?: string
enablePartialSupportAlert?: boolean
isSwitchingNetwork?: boolean
withNotifications?: boolean
identity?: AuthIdentity
locale: string
walletError: string | null
onSwitchNetwork: typeof switchNetworkRequest
onSignOut: typeof disconnectWalletRequest
onSignIn: () => void
}

export type MapStateProps = Pick<
NavbarProps,
| 'manaBalances'
Expand Down
58 changes: 58 additions & 0 deletions src/containers/Navbar/Navbar2.container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { connect } from 'react-redux'
import {
isConnected,
isConnecting,
getAddress,
getChainId,
getAppChainId,
getManaBalances,
isSwitchingNetwork,
isDisconnecting
} from '../../modules/wallet/selectors'
import { getData as getProfiles } from '../../modules/profile/selectors'
import { getError as getWalletError } from '../../modules/wallet/selectors'
import { getLocale } from '../../modules/translation/selectors'
import {
disconnectWalletRequest,
switchNetworkRequest
} from '../../modules/wallet/actions'
import { RootDispatch } from '../../types'
import { NavbarProps2, MapStateProps, MapDispatchProps } from './Navbar.types'
import Navbar2 from './Navbar2'
import { ChainId } from '@dcl/schemas'

const mapState = (state: any): MapStateProps => {
const address = getAddress(state)
const profile = address ? getProfiles(state)[address] : undefined
return {
avatar: profile ? profile.avatars[0] : undefined,
chainId: getChainId(state),
manaBalances: getManaBalances(state),
address: getAddress(state),
locale: getLocale(state),
isSignedIn: isConnected(state),
isDisconnecting: isDisconnecting(state),
isSigningIn: isConnecting(state),
appChainId: getAppChainId(state),
isSwitchingNetwork: isSwitchingNetwork(state),
walletError: getWalletError(state)
}
}

const mapDispatch = (dispatch: RootDispatch): MapDispatchProps => ({
onSwitchNetwork: (chainId: ChainId, fromChainId: ChainId) =>
dispatch(switchNetworkRequest(chainId, fromChainId)),
onSignOut: () => dispatch(disconnectWalletRequest())
})

const mergeProps = (
stateProps: MapStateProps,
dispatchProps: MapDispatchProps,
ownProps: NavbarProps2
): NavbarProps2 => ({
...stateProps,
...dispatchProps,
...ownProps
})

export default connect(mapState, mapDispatch, mergeProps)(Navbar2) as any
8 changes: 8 additions & 0 deletions src/containers/Navbar/Navbar2.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Box, styled } from 'decentraland-ui2'

const NavbarContainer = styled(Box)({
paddingTop: '66px',
width: '100%'
})

export { NavbarContainer }
200 changes: 200 additions & 0 deletions src/containers/Navbar/Navbar2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
import React, { useCallback, useEffect, useState } from 'react'
import { Navbar as NavbarComponent } from 'decentraland-ui2'
import { NotificationLocale } from 'decentraland-ui/dist/components/Notifications/types'
import { ChainId, getChainName } from '@dcl/schemas/dist/dapps/chain-id'
import { ProviderType } from '@dcl/schemas'
import { Network } from '@dcl/schemas/dist/dapps/network'
import { getAnalytics } from '../../modules/analytics/utils'
import { t } from '../../modules/translation'
import UnsupportedNetworkModal from '../UnsupportedNetworkModal'
import { getAvailableChains } from '../../lib/chainConfiguration'
import { getConnectedProviderType } from '../../lib'
import { getBaseUrl } from '../../lib/utils'
import ChainProvider from '../ChainProvider'
import {
CHANGE_NETWORK,
DROPDOWN_MENU_BALANCE_CLICK_EVENT,
DROPDOWN_MENU_DISPLAY_EVENT,
DROPDOWN_MENU_ITEM_CLICK_EVENT,
DROPDOWN_MENU_SIGN_OUT_EVENT
} from './constants'
import { NavbarProps2 } from './Navbar.types'
import { NAVBAR_CLICK_EVENT } from './constants'
import useNotifications from '../../hooks/useNotifications'
import { NavbarContainer } from './Navbar2.styled'

const BASE_URL = getBaseUrl()

const Navbar2: React.FC<NavbarProps2> = ({
appChainId,
isSwitchingNetwork,
withNotifications,
withChainSelector,
identity,
docsUrl = 'https://docs.decentraland.org',
enablePartialSupportAlert = true,
walletError,
...props
}: NavbarProps2) => {
const expectedChainName = getChainName(appChainId)
const analytics = getAnalytics()

const {
isModalOpen,
isNotificationsOnboarding,
modalActiveTab,
isLoading,
notifications,
handleNotificationsOpen,
handleOnBegin,
handleOnChangeModalTab,
handleRenderProfile
} = useNotifications(identity, withNotifications || false)

const handleSwitchNetwork = useCallback(() => {
props.onSwitchNetwork(appChainId)
}, [])

const [chainSelected, setChainSelected] = useState<ChainId | undefined>(
undefined
)

useEffect(() => {
if (walletError && chainSelected && withChainSelector) {
setChainSelected(undefined)
}
}, [walletError, chainSelected, withChainSelector])

const handleSwitchChain = useCallback(
(chainId: ChainId) => {
setChainSelected(chainId)
props.onSwitchNetwork(chainId, props.chainId)
analytics.track(CHANGE_NETWORK, {
from_chain_id: props.chainId,
to_chain_id: chainId
})
},
[analytics]
)

const handleClickBalance = useCallback(
(
e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement, MouseEvent>,
network?: Network
) => {
e.preventDefault()
analytics.track(DROPDOWN_MENU_BALANCE_CLICK_EVENT, { network })

setTimeout(() => {
window.open(`${BASE_URL}/account`, '_blank', 'noopener')
}, 300)
},
[analytics]
)

const handleClickNavbarItem = useCallback(
(
_e: React.MouseEvent,
options: { eventTrackingName: string; url?: string; isExternal?: boolean }
) => {
analytics.track(NAVBAR_CLICK_EVENT, options)
},
[analytics]
)

const handleClickUserMenuItem = useCallback(
(
_e: React.MouseEvent,
options: { type: string; url?: string; track_uuid?: string }
) => {
analytics.track(DROPDOWN_MENU_ITEM_CLICK_EVENT, options)
},
[analytics]
)

const handleClickOpen = useCallback(
(_e: React.MouseEvent, track_uuid: string) => {
analytics.track(DROPDOWN_MENU_DISPLAY_EVENT, { track_uuid })
},
[analytics]
)

const handleClickSignIn = useCallback(
(_e: React.MouseEvent<HTMLElement, MouseEvent>) => {
props.onSignIn()
},
[analytics]
)

const handleClickSignOut = useCallback(
(_e: React.MouseEvent<HTMLElement, MouseEvent>, track_uuid: string) => {
analytics.track(DROPDOWN_MENU_SIGN_OUT_EVENT, { track_uuid })
setTimeout(() => {
props.onSignOut()
}, 300)
},
[analytics]
)

return (
<NavbarContainer>
<ChainProvider>
{({ chainId, isUnsupported }) => (
<>
<NavbarComponent
{...props}
notifications={
withNotifications
? {
locale: props.locale as NotificationLocale,
isLoading,
isOnboarding: isNotificationsOnboarding,
isOpen: isModalOpen,
items: notifications,
activeTab: modalActiveTab,
onClick: handleNotificationsOpen,
onClose: handleNotificationsOpen,
onBegin: handleOnBegin,
onChangeTab: (_, tab) => handleOnChangeModalTab(tab),
renderProfile: handleRenderProfile
}
: undefined
}
onClickBalance={handleClickBalance}
onClickNavbarItem={handleClickNavbarItem}
onClickUserMenuItem={handleClickUserMenuItem}
onClickOpen={handleClickOpen}
onClickSignIn={handleClickSignIn}
onClickSignOut={handleClickSignOut}
{...(withChainSelector && {
chains: getAvailableChains(),
selectedChain: chainId ?? undefined,
chainBeingConfirmed:
chainSelected !== chainId ? chainSelected : undefined,
onSelectChain: handleSwitchChain,
i18nChainSelector: {
title: t('@dapps.chain_selector.title'),
connected: t('@dapps.chain_selector.connected'),
confirmInWallet:
getConnectedProviderType() === ProviderType.INJECTED // for injected ones, show label to confirm in wallet, the rest won't ask for confirmation
? t('@dapps.chain_selector.confirm_in_wallet')
: t('@dapps.chain_selector.switching')
}
})}
/>
{isUnsupported ? (
<UnsupportedNetworkModal
chainName={getChainName(chainId!)}
expectedChainName={expectedChainName!}
isSwitchingNetwork={isSwitchingNetwork}
onSwitchNetwork={handleSwitchNetwork}
/>
) : null}
</>
)}
</ChainProvider>
</NavbarContainer>
)
}

export default React.memo(Navbar2)
3 changes: 3 additions & 0 deletions src/containers/Navbar/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
import Navbar from './Navbar.container'
import Navbar2 from './Navbar2.container'

export default Navbar
export { Navbar2 }
1 change: 1 addition & 0 deletions src/containers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export { default as Footer } from './Footer'
export { default as LoginModal } from './LoginModal'
export { default as Modal } from './Modal'
export { default as Navbar } from './Navbar'
export { Navbar2 } from './Navbar'
export { default as NetworkButton } from './NetworkButton'
export { default as NetworkCheck } from './NetworkCheck'
export { default as Profile } from './Profile'
Expand Down

0 comments on commit f0a8de7

Please sign in to comment.