Commit 5711f049 authored by ioedeveloper's avatar ioedeveloper

Implemented loadmore using reducer

parent 1284594b
import React, { useState, useEffect } from 'react'
import React, { useState, useEffect, useReducer } from 'react'
import { TreeView, TreeViewItem } from '@remix-ui/tree-view'
import { DropdownPanelProps, ExtractData, ExtractFunc } from '../../types'
import { CopyToClipboard } from '@remix-ui/clipboard'
import { default as deepequal } from 'deep-equal'
import { initialState, reducer } from '../../reducers/calldata'
import './styles/dropdown-panel.css'
export const DropdownPanel = (props: DropdownPanelProps) => {
const { dropdownName, dropdownMessage, calldata, header, loading, extractFunc, formatSelfFunc, loadMore } = props
const [calldataObj, dispatch] = useReducer(reducer, initialState)
const { dropdownName, dropdownMessage, calldata, header, loading, extractFunc, formatSelfFunc, registerEvent, triggerEvent, loadMoreEvent, loadMoreCompletedEvent } = props
const extractDataDefault: ExtractFunc = (item, parent?) => {
const ret: ExtractData = {}
......@@ -57,15 +58,25 @@ export const DropdownPanel = (props: DropdownPanelProps) => {
},
copiableContent: '',
updating: false,
data: null,
expandPath: []
expandPath: [],
data: null
})
useEffect(() => {
if (!deepequal(state.data, calldata)) update(calldata)
registerEvent && registerEvent(loadMoreCompletedEvent, (updatedCalldata) => {
dispatch({ type: 'UPDATE_CALLDATA_SUCCESS', payload: updatedCalldata })
})
}, [])
useEffect(() => {
dispatch({ type: 'FETCH_CALLDATA_SUCCESS', payload: calldata })
}, [calldata])
useEffect(() => {
update(calldata)
}, [calldataObj.calldata])
useEffect(() => {
message(dropdownMessage)
}, [dropdownMessage])
......@@ -160,7 +171,7 @@ export const DropdownPanel = (props: DropdownPanelProps) => {
<TreeViewItem id={`treeViewItem${key}`} key={keyPath} label={ formatSelfFunc ? formatSelfFunc(key, data) : formatSelfDefault(key, data) } onClick={() => handleExpand(keyPath)} expand={state.expandPath.includes(keyPath)}>
<TreeView id={`treeView${key}`} key={keyPath}>
{ children }
{ data.hasNext && <TreeViewItem id={`treeViewLoadMore`} className="cursor_pointer" label="Load more" onClick={() => { loadMore(data.cursor) }} /> }
{ data.hasNext && <TreeViewItem id={`treeViewLoadMore`} className="cursor_pointer" label="Load more" onClick={() => { triggerEvent(loadMoreEvent, [data.cursor]) }} /> }
</TreeView>
</TreeViewItem>
)
......
......@@ -3,17 +3,13 @@ import DropdownPanel from './dropdown-panel'
import { extractData } from '../../utils/solidityTypeFormatter'
import { ExtractData } from '../../types'
export const SolidityLocals = ({ data, updatedData, message, triggerEvent }) => {
export const SolidityLocals = ({ data, message, registerEvent, triggerEvent }) => {
const [calldata, setCalldata] = useState(null)
useEffect(() => {
data && setCalldata(data)
}, [data])
useEffect(() => {
updatedData && mergeLocals(updatedData, calldata)
}, [updatedData])
const formatSelf = (key: string, data: ExtractData) => {
let color = 'var(--primary)'
if (data.isArray || data.isStruct || data.isMapping) {
......@@ -46,22 +42,6 @@ export const SolidityLocals = ({ data, updatedData, message, triggerEvent }) =>
)
}
const mergeLocals = (locals1, locals2) => {
Object.keys(locals2).map(item => {
if (locals2[item].cursor && (parseInt(locals2[item].cursor) < parseInt(locals1[item].cursor))) {
locals2[item] = {
...locals1[item],
value: [...locals2[item].value, ...locals1[item].value]
}
}
})
setCalldata(() => locals2)
}
const loadMore = (cursor) => {
triggerEvent('solidityLocalsLoadMore', [cursor])
}
return (
<div id='soliditylocals' data-id="solidityLocals">
<DropdownPanel
......@@ -70,7 +50,10 @@ export const SolidityLocals = ({ data, updatedData, message, triggerEvent }) =>
calldata={calldata || {}}
extractFunc={extractData}
formatSelfFunc={formatSelf}
loadMore={loadMore}
registerEvent={registerEvent}
triggerEvent={triggerEvent}
loadMoreEvent='solidityLocalsLoadMore'
loadMoreCompletedEvent='solidityLocalsLoadMoreCompleted'
/>
</div>
)
......
......@@ -23,7 +23,6 @@ export const VmDebuggerHead = ({ vmDebugger: { registerEvent, triggerEvent } })
calldata: null,
message: null,
})
const [updatedSolidityLocals, setUpdatedSolidityLocals] = useState(null)
useEffect(() => {
registerEvent && registerEvent('functionsStackUpdate', (stack) => {
......@@ -86,7 +85,6 @@ export const VmDebuggerHead = ({ vmDebugger: { registerEvent, triggerEvent } })
})
})
registerEvent && registerEvent('solidityLocals', (calldata) => {
console.log('solidityLocals: ', calldata)
setSolidityLocals(() => {
return { ...solidityLocals, calldata }
})
......@@ -96,9 +94,6 @@ export const VmDebuggerHead = ({ vmDebugger: { registerEvent, triggerEvent } })
return { ...solidityLocals, message }
})
})
registerEvent && registerEvent('solidityLocalsLoadMoreCompleted', (updatedCalldata) => {
setUpdatedSolidityLocals(() => updatedCalldata)
})
}, [registerEvent])
return (
......@@ -106,7 +101,7 @@ export const VmDebuggerHead = ({ vmDebugger: { registerEvent, triggerEvent } })
<div className="d-flex flex-column">
<div className="w-100">
<FunctionPanel data={functionPanel} />
<SolidityLocals data={solidityLocals.calldata} updatedData={updatedSolidityLocals} message={solidityLocals.message} triggerEvent={triggerEvent} />
<SolidityLocals data={solidityLocals.calldata} message={solidityLocals.message} registerEvent={registerEvent} triggerEvent={triggerEvent} />
<SolidityState calldata={solidityState.calldata} message={solidityState.message} />
</div>
<div className="w-100"><CodeListView registerEvent={registerEvent} /></div>
......
......@@ -33,7 +33,40 @@ export const reducer = (state = initialState, action: Action) => {
isSuccessful: false,
hasError: action.payload
};
case 'UPDATE_CALLDATA_REQUEST':
return {
...state,
isRequesting: true,
isSuccessful: false,
hasError: null
};
case 'UPDATE_CALLDATA_SUCCESS':
return {
calldata: mergeLocals(action.payload, state.calldata),
isRequesting: false,
isSuccessful: true,
hasError: null
};
case 'UPDATE_CALLDATA_ERROR':
return {
...state,
isRequesting: false,
isSuccessful: false,
hasError: action.payload
};
default:
throw new Error();
}
}
function mergeLocals (locals1, locals2) {
Object.keys(locals2).map(item => {
if (locals2[item].cursor && (parseInt(locals2[item].cursor) < parseInt(locals1[item].cursor))) {
locals2[item] = {
...locals1[item],
value: [...locals2[item].value, ...locals1[item].value]
}
}
})
return locals2
}
\ No newline at end of file
......@@ -21,10 +21,13 @@ export interface DropdownPanelProps {
[key: string]: string
},
header?: string,
loading?: boolean
loading?: boolean,
extractFunc?: ExtractFunc,
formatSelfFunc?: FormatSelfFunc,
loadMore?: Function
registerEvent?: Function,
triggerEvent?: Function,
loadMoreEvent?: string,
loadMoreCompletedEvent?: string
}
export type FormatSelfFunc = (key: string | number, data: ExtractData) => JSX.Element
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment