Skip to content

Commit

Permalink
Merge pull request #8682 from brave/wallet-page
Browse files Browse the repository at this point in the history
New Wallet page and common state for panel and page
  • Loading branch information
bbondy authored May 11, 2021
2 parents 7b2903b + e494462 commit e8852aa
Show file tree
Hide file tree
Showing 21 changed files with 384 additions and 117 deletions.
15 changes: 15 additions & 0 deletions components/brave_wallet_ui/common/reducers/wallet_reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* Copyright (c) 2021 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/* global window */

import { createReducer } from 'redux-act'
import { WalletState } from '../../constants/types'

const defaultState: WalletState = {
}

const reducer = createReducer<WalletState>({}, defaultState)

export default reducer
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import * as React from 'react'
import OptIn from './opt-in'

export default class App extends React.PureComponent<{}, {}> {
export default class LegacyApp extends React.PureComponent<{}, {}> {

onWalletOptin = () => {
chrome.braveWallet.loadUI(() => {
Expand Down
19 changes: 16 additions & 3 deletions components/brave_wallet_ui/constants/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,26 @@ export interface PriceDataObjectType {
close: number
}

export interface State {
walletPanelReducer: WalletPanelReducerState
export interface WalletState {
}

export interface WalletPanelReducerState {
export interface PanelState {
hasInitialized: boolean
isConnected: boolean
connectedSiteOrigin: string
accounts: WalletAccountType[]
}

export interface PageState {
hasInitialized: boolean
}

export interface WalletPageState {
wallet: WalletState
page: PageState
}

export interface WalletPanelState {
wallet: WalletState
panel: PanelState
}
10 changes: 10 additions & 0 deletions components/brave_wallet_ui/page/actions/wallet_page_actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* Copyright (c) 2021 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

import { createAction } from 'redux-act'
import { InitializedPayloadType } from '../constants/action_types'

export const initialize = createAction('initialize')
export const initialized = createAction<InitializedPayloadType>('initialized')
29 changes: 29 additions & 0 deletions components/brave_wallet_ui/page/async/wallet_page_async_handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2021 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.

import { MiddlewareAPI, Dispatch, AnyAction } from 'redux'
import AsyncActionHandler from '../../../common/AsyncActionHandler'
import * as Actions from '../actions/wallet_page_actions'
import { PageState, WalletPageState } from '../../constants/types'

const handler = new AsyncActionHandler()

function getPageState (store: MiddlewareAPI<Dispatch<AnyAction>, any>): PageState {
return (store.getState() as WalletPageState).page
}

handler.on(Actions.initialize.getType(), async (store) => {
const state = getPageState(store)
// Sanity check we only initialize once
if (state.hasInitialized) {
return
}
// TODO: Fetch any data we need for initial display, instead of fake wait.
await new Promise(resolve => setTimeout(resolve, 400))
store.dispatch(Actions.initialized({ isConnected: true }))
return
})

export default handler.middleware
8 changes: 8 additions & 0 deletions components/brave_wallet_ui/page/constants/action_types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2021 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.

export type InitializedPayloadType = {
isConnected: boolean
}
89 changes: 89 additions & 0 deletions components/brave_wallet_ui/page/container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright (c) 2020 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.

import * as React from 'react'
import { connect } from 'react-redux'
import { bindActionCreators, Dispatch } from 'redux'

import * as WalletPageActions from './actions/wallet_page_actions'
import store from './store'

import 'emptykit.css'
import '../../../ui/webui/resources/fonts/poppins.css'
import '../../../ui/webui/resources/fonts/muli.css'

import { WalletWidgetStandIn } from '../stories/style'
import {
SideNav,
WalletPageLayout,
WalletSubViewLayout,
CryptoView
} from '../components/desktop'
import {
NavTypes,
NavObjectType,
WalletState,
PageState,
WalletPageState
} from '../constants/types'
import { LinkedAccountsOptions, NavOptions, StaticOptions } from '../options/side-nav-options'
import BuySendSwap from '../components/buy-send-swap'

type Props = {
wallet: WalletState
page: PageState
actions: typeof WalletPageActions
}

function Container (props: Props) {
const [view, setView] = React.useState<NavTypes>('crypto')
const [linkedAccounts] = React.useState<NavObjectType[]>(LinkedAccountsOptions)

// In the future these will be actual paths
// for example wallet/rewards
const navigateTo = (path: NavTypes) => {
setView(path)
}

return (
<WalletPageLayout>
<SideNav
navList={NavOptions}
staticList={StaticOptions}
selectedButton={view}
onSubmit={navigateTo}
linkedAccountsList={linkedAccounts}
/>
<WalletSubViewLayout>
{view === 'crypto' ? (
<CryptoView />
) : (
<div style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<h2>{view} view</h2>
</div>
)}

</WalletSubViewLayout>
<WalletWidgetStandIn>
<BuySendSwap />
</WalletWidgetStandIn>
</WalletPageLayout>
)
}

function mapStateToProps (state: WalletPageState): Partial<Props> {
return {
page: state.page,
wallet: state.wallet
}
}

function mapDispatchToProps (dispatch: Dispatch): Partial<Props> {
return {
actions: bindActionCreators(WalletPageActions, store.dispatch.bind(store))
}
}

export default connect(mapStateToProps, mapDispatchToProps)(Container)
14 changes: 14 additions & 0 deletions components/brave_wallet_ui/page/reducers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* Copyright (c) 2021 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

import { combineReducers } from 'redux'

import pageReducer from './page_reducer'
import walletReducer from '../../common/reducers/wallet_reducer'

export default combineReducers({
page: pageReducer,
wallet: walletReducer
})
26 changes: 26 additions & 0 deletions components/brave_wallet_ui/page/reducers/page_reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* Copyright (c) 2021 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/* global window */

import { createReducer } from 'redux-act'
import * as Actions from '../actions/wallet_page_actions'
import { PageState } from '../../constants/types'
import { InitializedPayloadType } from '../constants/action_types'

const defaultState: PageState = {
hasInitialized: false
}

const reducer = createReducer<PageState>({}, defaultState)

reducer.on(Actions.initialized, (state: PageState, payload: InitializedPayloadType) => {
return {
...state,
hasInitialized: true,
isConnected: payload.isConnected
}
})

export default reducer
15 changes: 15 additions & 0 deletions components/brave_wallet_ui/page/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* Copyright (c) 2021 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

import { createStore, applyMiddleware } from 'redux'

// Utils
import reducers from './reducers'
import walletPageAsyncHandler from './async/wallet_page_async_handler'

export default createStore(
reducers,
applyMiddleware(walletPageAsyncHandler)
)
50 changes: 42 additions & 8 deletions components/brave_wallet_ui/page/wallet_page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,68 @@

import * as React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { initLocale } from 'brave-ui'

import 'emptykit.css'
import Container from './container'
import * as WalletPageActions from './actions/wallet_page_actions'
import store from './store'

// Fonts
import 'emptykit.css'
import '../../../ui/webui/resources/fonts/poppins.css'
import '../../../ui/webui/resources/fonts/muli.css'

// Components
import App from '../components/app'
import LegacyApp from '../components/legacy_app'
import Theme from 'brave-ui/theme/brave-default'
import DarkTheme from 'brave-ui/theme/brave-dark'
import BraveCoreThemeProvider from '../../common/BraveCoreThemeProvider'
import walletDarkTheme from '../theme/wallet-dark'
import walletLightTheme from '../theme/wallet-light'

function App () {
const [initialThemeType, setInitialThemeType] = React.useState<chrome.braveTheme.ThemeType>()
React.useEffect(() => {
chrome.braveTheme.getBraveThemeType(setInitialThemeType)
}, [])
return (
<Provider store={store}>
{initialThemeType &&
<BraveCoreThemeProvider
initialThemeType={initialThemeType}
dark={walletDarkTheme}
light={walletLightTheme}
>
<Container />
</BraveCoreThemeProvider>
}
</Provider>
)
}

function initialize () {
chrome.braveWallet.isNativeWalletEnabled((enabled: boolean) => {
if (enabled) {
store.dispatch(WalletPageActions.initialize())
render(<App />, document.getElementById('root'))
} else {
initializeOldWallet()
}
})
}

function initializeOldWallet () {
chrome.braveWallet.shouldPromptForSetup((prompt: boolean) => {
if (!prompt) {
chrome.braveWallet.loadUI(() => {
window.location.href = 'chrome://wallet'
})
return
}

renderWebUIView()
renderOldWebUIView()
})
}

function renderWebUIView () {
function renderOldWebUIView () {
new Promise(resolve => chrome.braveTheme.getBraveThemeType(resolve))
.then((themeType: chrome.braveTheme.ThemeType) => {
window.i18nTemplate.process(window.document, window.loadTimeData)
Expand All @@ -46,7 +80,7 @@ function renderWebUIView () {
dark={DarkTheme}
light={Theme}
>
<App />
<LegacyApp />
</BraveCoreThemeProvider>,
document.getElementById('root')
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { MiddlewareAPI, Dispatch, AnyAction } from 'redux'
import AsyncActionHandler from '../../../common/AsyncActionHandler'
import * as Actions from '../actions/wallet_panel_actions'
import { State, WalletPanelReducerState } from '../../constants/types'
import { WalletPanelState, PanelState } from '../../constants/types'
import { AccountPayloadType } from '../constants/action_types'

const handler = new AsyncActionHandler()
Expand All @@ -17,12 +17,12 @@ async function getAPIProxy () {
return api.default.getInstance()
}

function getState (store: MiddlewareAPI<Dispatch<AnyAction>, any>): WalletPanelReducerState {
return (store.getState() as State).walletPanelReducer
function getPanelState (store: MiddlewareAPI<Dispatch<AnyAction>, any>): PanelState {
return (store.getState() as WalletPanelState).panel
}

handler.on(Actions.initialize.getType(), async (store) => {
const state = getState(store)
const state = getPanelState(store)
// Sanity check we only initialize once
if (state.hasInitialized) {
return
Expand Down
Loading

0 comments on commit e8852aa

Please sign in to comment.