mirror of
https://github.com/Permissionless-Software-Foundation/psf-memo-client.git
synced 2026-09-21 16:52:02 -07:00
fix(refactor): Refactoring and restructuring
This commit is contained in:
+41
-137
@@ -3,201 +3,105 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Global npm libraries
|
// Global npm libraries
|
||||||
import React, { useState, useEffect } from 'react'
|
import React, { useEffect, useCallback } from 'react'
|
||||||
import { useQueryParam, StringParam } from 'use-query-params'
|
|
||||||
|
|
||||||
// Local libraries
|
// Local libraries
|
||||||
import './App.css'
|
import './App.css'
|
||||||
import LoadScripts from './components/load-scripts'
|
import LoadScripts from './components/load-scripts'
|
||||||
import WaitingModal from './components/waiting-modal'
|
|
||||||
import AsyncLoad from './services/async-load'
|
import AsyncLoad from './services/async-load'
|
||||||
import SelectServerButton from './components/servers/select-server-button'
|
import SelectServerButton from './components/servers/select-server-button'
|
||||||
import Footer from './components/footer'
|
import Footer from './components/footer'
|
||||||
import NavMenu from './components/nav-menu'
|
import NavMenu from './components/nav-menu'
|
||||||
import AppBody from './components/app-body'
|
import useAppState from './hooks/state'
|
||||||
|
import { UninitializedView, InitializedView } from './components/starter-views'
|
||||||
|
|
||||||
function App (props) {
|
function App (props) {
|
||||||
// BEGIN STATE
|
|
||||||
|
|
||||||
// Get the CashStack URL from a query parameter, if it exists.
|
|
||||||
let [restURL] = useQueryParam('restURL', StringParam)
|
|
||||||
// Otherwise default to free-bch.fullstack.cash
|
|
||||||
if (!restURL) restURL = 'https://free-bch.fullstack.cash'
|
|
||||||
// console.log('restURL: ', restURL)
|
|
||||||
const [serverUrl, setServerUrl] = useState(restURL)
|
|
||||||
|
|
||||||
const [menuState, setMenuState] = useState(0)
|
|
||||||
const [wallet, setWallet] = useState(false)
|
|
||||||
const [servers, setServers] = useState([])
|
|
||||||
|
|
||||||
// Startup state
|
|
||||||
// When the page is loaded, it goes through a series of async network calls
|
|
||||||
// to initialize the app. These variables track the state of this startup
|
|
||||||
// process.
|
|
||||||
const [asyncInitStarted, setAsyncInitStarted] = useState(false)
|
|
||||||
const [asyncInitFinished, setAsyncInitFinished] = useState(false)
|
|
||||||
const [asyncInitSucceeded, setAsyncInitSucceeded] = useState(null)
|
|
||||||
|
|
||||||
// Startup Modal
|
|
||||||
const [showStartModal, setShowStartModal] = useState(true)
|
|
||||||
const [modalBody, setModalBody] = useState([])
|
|
||||||
const [hideSpinner, setHideSpinner] = useState(false)
|
|
||||||
const [denyClose, setDenyClose] = useState(false) // Deny modal to be closed
|
|
||||||
|
|
||||||
// Load all the app state into a single object that can be passed to child
|
// Load all the app state into a single object that can be passed to child
|
||||||
// components.
|
// components.
|
||||||
const appData = {
|
const appData = useAppState()
|
||||||
wallet,
|
|
||||||
setWallet,
|
|
||||||
serverUrl,
|
|
||||||
setServerUrl,
|
|
||||||
servers,
|
|
||||||
setServers,
|
|
||||||
showStartModal,
|
|
||||||
setShowStartModal,
|
|
||||||
menuState,
|
|
||||||
setMenuState,
|
|
||||||
asyncInitFinished,
|
|
||||||
setAsyncInitFinished,
|
|
||||||
asyncInitSucceeded,
|
|
||||||
setAsyncInitSucceeded,
|
|
||||||
modalBody,
|
|
||||||
setModalBody,
|
|
||||||
hideSpinner,
|
|
||||||
setHideSpinner,
|
|
||||||
denyClose,
|
|
||||||
setDenyClose
|
|
||||||
}
|
|
||||||
|
|
||||||
// END STATE
|
// Add a new line to the waiting modal.
|
||||||
|
const addToModal = useCallback((inStr, appData) => {
|
||||||
// Encasulate dependencies
|
// console.log('addToModal() inStr: ', inStr)
|
||||||
const asyncLoad = new AsyncLoad()
|
|
||||||
|
|
||||||
|
appData.setModalBody(prevBody => {
|
||||||
|
// console.log('prevBody: ', prevBody)
|
||||||
|
prevBody.push(inStr)
|
||||||
|
return prevBody
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
/** Load all required data before component start. */
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function asyncEffect () {
|
async function asyncEffect () {
|
||||||
// console.log('asyncInitStarted: ', asyncInitStarted)
|
console.log('asyncInitStarted: ', appData.asyncInitStarted)
|
||||||
if (!asyncInitStarted) {
|
|
||||||
|
if (!appData.asyncInitStarted) {
|
||||||
try {
|
try {
|
||||||
setAsyncInitStarted(true)
|
// Instantiate the async load object.
|
||||||
|
const asyncLoad = new AsyncLoad()
|
||||||
|
appData.setAsyncInitStarted(true)
|
||||||
|
|
||||||
addToModal('Loading minimal-slp-wallet', appData)
|
addToModal('Loading minimal-slp-wallet', appData)
|
||||||
|
appData.setDenyClose(true)
|
||||||
setDenyClose(true)
|
|
||||||
|
|
||||||
await asyncLoad.loadWalletLib()
|
await asyncLoad.loadWalletLib()
|
||||||
// console.log('Wallet: ', Wallet)
|
// console.log('Wallet: ', Wallet)
|
||||||
|
|
||||||
addToModal('Getting alternative servers', appData)
|
addToModal('Getting alternative servers', appData)
|
||||||
const gistServers = await asyncLoad.getServers()
|
const gistServers = await asyncLoad.getServers()
|
||||||
setServers(gistServers)
|
appData.setServers(gistServers)
|
||||||
// console.log('servers: ', servers)
|
// console.log('servers: ', servers)
|
||||||
|
|
||||||
// throw new Error('test error')
|
|
||||||
|
|
||||||
addToModal('Initializing wallet', appData)
|
addToModal('Initializing wallet', appData)
|
||||||
console.log(`Initializing wallet with back end server ${serverUrl}`)
|
console.log(`Initializing wallet with back end server ${appData.serverUrl}`)
|
||||||
|
|
||||||
const walletTemp = await asyncLoad.initWallet(serverUrl)
|
const walletTemp = await asyncLoad.initWallet(appData.serverUrl)
|
||||||
setWallet(walletTemp)
|
appData.setWallet(walletTemp)
|
||||||
|
|
||||||
// Update state
|
// Update state
|
||||||
setShowStartModal(false)
|
appData.setShowStartModal(false)
|
||||||
setDenyClose(false)
|
appData.setDenyClose(false)
|
||||||
|
|
||||||
// Update the startup state.
|
// Update the startup state.
|
||||||
setAsyncInitFinished(true)
|
appData.setAsyncInitFinished(true)
|
||||||
setAsyncInitSucceeded(true)
|
appData.setAsyncInitSucceeded(true)
|
||||||
console.log('App.js useEffect() startup finished successfully')
|
console.log('App.js useEffect() startup finished successfully')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const errModalBody = [
|
const errModalBody = [
|
||||||
`Error: ${err.message}`,
|
`Error: ${err.message}`,
|
||||||
'Try selecting a different back end server using the drop-down menu at the bottom of the app.'
|
'Try selecting a different back end server using the drop-down menu at the bottom of the app.'
|
||||||
]
|
]
|
||||||
setModalBody(errModalBody)
|
appData.setModalBody(errModalBody)
|
||||||
|
|
||||||
// Update Modal State
|
// Update Modal State
|
||||||
setHideSpinner(true)
|
appData.setHideSpinner(true)
|
||||||
setShowStartModal(true)
|
appData.setShowStartModal(true)
|
||||||
setDenyClose(false)
|
appData.setDenyClose(false)
|
||||||
|
|
||||||
// Update the startup state.
|
// Update the startup state.
|
||||||
setAsyncInitFinished(true)
|
appData.setAsyncInitFinished(true)
|
||||||
setAsyncInitSucceeded(false)
|
appData.setAsyncInitSucceeded(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
asyncEffect()
|
asyncEffect()
|
||||||
})
|
}, [appData, addToModal])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<LoadScripts />
|
<LoadScripts />
|
||||||
<NavMenu menuHandler={onMenuClick} appData={appData} />
|
<NavMenu appData={appData} />
|
||||||
|
{/** Define View to show */}
|
||||||
{
|
{
|
||||||
showStartModal
|
appData.showStartModal
|
||||||
? (<UninitializedView appData={appData} />)
|
? (<UninitializedView appData={appData} />)
|
||||||
: (<InitializedView menuState={menuState} appData={appData} />)
|
: (<InitializedView menuState={appData.menuState} appData={appData} />)
|
||||||
}
|
}
|
||||||
|
|
||||||
<SelectServerButton menuHandler={onMenuClick} appData={appData} />
|
<SelectServerButton appData={appData} />
|
||||||
<Footer appData={appData} />
|
<Footer appData={appData} />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new line to the waiting modal.
|
|
||||||
function addToModal (inStr, appData) {
|
|
||||||
// console.log('addToModal() inStr: ', inStr)
|
|
||||||
|
|
||||||
appData.setModalBody(prevBody => {
|
|
||||||
// console.log('prevBody: ', prevBody)
|
|
||||||
prevBody.push(inStr)
|
|
||||||
return prevBody
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// This handler is passed into the child menu component. When an item in the
|
|
||||||
// nav menu is clicked, this handler will update the state. The state is
|
|
||||||
// used by the AppBody component to determine which View component to display.
|
|
||||||
function onMenuClick (menuState, appData) {
|
|
||||||
// console.log('onMenuClick() menuState: ', menuState)
|
|
||||||
|
|
||||||
appData.setMenuState(menuState)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is rendered *before* the BCH wallet is initialized.
|
|
||||||
function UninitializedView (props = {}) {
|
|
||||||
// console.log('UninitializedView props: ', props)
|
|
||||||
|
|
||||||
const heading = 'Connecting to BCH blockchain...'
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<WaitingModal
|
|
||||||
heading={heading}
|
|
||||||
body={props.appData.modalBody}
|
|
||||||
hideSpinner={props.appData.hideSpinner}
|
|
||||||
denyClose={props.appData.denyClose}
|
|
||||||
/>
|
|
||||||
{
|
|
||||||
props.asyncInitFinished
|
|
||||||
? <AppBody menuState={100} wallet={props.appData.wallet} appData={props.appData} />
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is rendered *after* the BCH wallet is initialized.
|
|
||||||
function InitializedView (props) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<br />
|
|
||||||
<AppBody menuState={props.menuState} appData={props.appData} />
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App
|
export default App
|
||||||
|
|||||||
@@ -10,9 +10,9 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
// Local libraries
|
// Local libraries
|
||||||
import GetBalance from '../balance'
|
import GetBalance from './balance'
|
||||||
import Placeholder2 from '../placeholder2'
|
import Placeholder2 from './placeholder2'
|
||||||
import Placeholder3 from '../placeholder3'
|
import Placeholder3 from './placeholder3'
|
||||||
import ServerSelectView from '../servers/select-server-view'
|
import ServerSelectView from '../servers/select-server-view'
|
||||||
|
|
||||||
function AppBody (props) {
|
function AppBody (props) {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import Logo from './psf-logo.png'
|
|||||||
function NavMenu (props) {
|
function NavMenu (props) {
|
||||||
const handleClickEvent = (menuItem) => {
|
const handleClickEvent = (menuItem) => {
|
||||||
// Pass the selected menu item up to the parent component.
|
// Pass the selected menu item up to the parent component.
|
||||||
props.menuHandler(menuItem, props.appData)
|
props.appData.setMenuState(menuItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class ServerSelect extends React.Component {
|
|||||||
handleServerSelect () {
|
handleServerSelect () {
|
||||||
console.log('This function should navigate to the server selection view.')
|
console.log('This function should navigate to the server selection view.')
|
||||||
|
|
||||||
this.state.menuHandler(100, this.state.appData)
|
this.state.appData.setMenuState(100)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* This file contains the views that are displayed before and after the BCH wallet is initialized.
|
||||||
|
*/
|
||||||
|
import React from 'react'
|
||||||
|
import WaitingModal from './waiting-modal'
|
||||||
|
import AppBody from './app-body'
|
||||||
|
|
||||||
|
// This is rendered *before* the BCH wallet is initialized.
|
||||||
|
export function UninitializedView (props = {}) {
|
||||||
|
// console.log('UninitializedView props: ', props)
|
||||||
|
const { appData } = props
|
||||||
|
|
||||||
|
const heading = 'Connecting to BCH blockchain...'
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<WaitingModal
|
||||||
|
heading={heading}
|
||||||
|
body={appData.modalBody}
|
||||||
|
hideSpinner={appData.hideSpinner}
|
||||||
|
denyClose={appData.denyClose}
|
||||||
|
/>
|
||||||
|
{
|
||||||
|
props.asyncInitFinished
|
||||||
|
? <AppBody menuState={100} wallet={appData.wallet} appData={appData} />
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is rendered *after* the BCH wallet is initialized.
|
||||||
|
export function InitializedView (props) {
|
||||||
|
const { appData } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<br />
|
||||||
|
<AppBody menuState={appData.menuState} appData={appData} />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import { useState } from 'react'
|
||||||
|
import { useQueryParam, StringParam } from 'use-query-params'
|
||||||
|
|
||||||
|
function useAppState () {
|
||||||
|
// Get the CashStack URL from query parameter or use default
|
||||||
|
let [restURL] = useQueryParam('restURL', StringParam)
|
||||||
|
if (!restURL) restURL = 'https://free-bch.fullstack.cash'
|
||||||
|
|
||||||
|
const [serverUrl, setServerUrl] = useState(restURL)
|
||||||
|
const [menuState, setMenuState] = useState(0)
|
||||||
|
const [wallet, setWallet] = useState(false)
|
||||||
|
const [servers, setServers] = useState([])
|
||||||
|
|
||||||
|
// Startup state management
|
||||||
|
const [asyncInitStarted, setAsyncInitStarted] = useState(false)
|
||||||
|
const [asyncInitFinished, setAsyncInitFinished] = useState(false)
|
||||||
|
const [asyncInitSucceeded, setAsyncInitSucceeded] = useState(null)
|
||||||
|
|
||||||
|
// Modal state management
|
||||||
|
const [showStartModal, setShowStartModal] = useState(true)
|
||||||
|
const [modalBody, setModalBody] = useState([])
|
||||||
|
const [hideSpinner, setHideSpinner] = useState(false)
|
||||||
|
const [denyClose, setDenyClose] = useState(false)
|
||||||
|
|
||||||
|
return {
|
||||||
|
serverUrl,
|
||||||
|
setServerUrl,
|
||||||
|
menuState,
|
||||||
|
setMenuState,
|
||||||
|
wallet,
|
||||||
|
setWallet,
|
||||||
|
servers,
|
||||||
|
setServers,
|
||||||
|
asyncInitStarted,
|
||||||
|
setAsyncInitStarted,
|
||||||
|
asyncInitFinished,
|
||||||
|
setAsyncInitFinished,
|
||||||
|
asyncInitSucceeded,
|
||||||
|
setAsyncInitSucceeded,
|
||||||
|
showStartModal,
|
||||||
|
setShowStartModal,
|
||||||
|
modalBody,
|
||||||
|
setModalBody,
|
||||||
|
hideSpinner,
|
||||||
|
setHideSpinner,
|
||||||
|
denyClose,
|
||||||
|
setDenyClose
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useAppState
|
||||||
@@ -19,7 +19,7 @@ class GistServers {
|
|||||||
|
|
||||||
// Retrieve the gist from github.com.
|
// Retrieve the gist from github.com.
|
||||||
const result = await this.axios.get(gistUrl)
|
const result = await this.axios.get(gistUrl)
|
||||||
console.log('result.data: ', result.data)
|
// console.log('result.data: ', result.data)
|
||||||
|
|
||||||
// Get the current content of the gist.
|
// Get the current content of the gist.
|
||||||
const content = result.data.servers
|
const content = result.data.servers
|
||||||
|
|||||||
Reference in New Issue
Block a user