Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
464c15f9
Commit
464c15f9
authored
Jun 07, 2023
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
base implementation of the selector
parent
f3412634
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
103 additions
and
36 deletions
+103
-36
AddressContract.tsx
ui/address/AddressContract.tsx
+6
-2
ContractCode.tsx
ui/address/contract/ContractCode.tsx
+4
-12
ContractSourceCode.tsx
ui/address/contract/ContractSourceCode.tsx
+92
-22
context.tsx
ui/address/contract/context.tsx
+1
-0
No files found.
ui/address/AddressContract.tsx
View file @
464c15f9
...
@@ -18,8 +18,12 @@ const TAB_LIST_PROPS = {
...
@@ -18,8 +18,12 @@ const TAB_LIST_PROPS = {
const
AddressContract
=
({
addressHash
,
tabs
}:
Props
)
=>
{
const
AddressContract
=
({
addressHash
,
tabs
}:
Props
)
=>
{
const
fallback
=
React
.
useCallback
(()
=>
{
const
fallback
=
React
.
useCallback
(()
=>
{
const
noProviderTabs
=
tabs
.
filter
(({
id
})
=>
id
===
'
contact_code
'
);
const
noProviderTabs
=
tabs
.
filter
(({
id
})
=>
id
===
'
contact_code
'
);
return
<
RoutedTabs
tabs=
{
noProviderTabs
}
variant=
"outline"
colorScheme=
"gray"
size=
"sm"
tabListProps=
{
TAB_LIST_PROPS
}
/>;
return
(
},
[
tabs
]);
<
ContractContextProvider
addressHash=
{
addressHash
}
>
<
RoutedTabs
tabs=
{
noProviderTabs
}
variant=
"outline"
colorScheme=
"gray"
size=
"sm"
tabListProps=
{
TAB_LIST_PROPS
}
/>
</
ContractContextProvider
>
);
},
[
addressHash
,
tabs
]);
return
(
return
(
<
Web3ModalProvider
fallback=
{
fallback
}
>
<
Web3ModalProvider
fallback=
{
fallback
}
>
...
...
ui/address/contract/ContractCode.tsx
View file @
464c15f9
...
@@ -212,18 +212,10 @@ const ContractCode = ({ addressHash, noSocket }: Props) => {
...
@@ -212,18 +212,10 @@ const ContractCode = ({ addressHash, noSocket }: Props) => {
isLoading={ isPlaceholderData }
isLoading={ isPlaceholderData }
/>
/>
) }
) }
{ data?.source_code && (
<ContractSourceCode
<ContractSourceCode
address={ addressHash }
data={ data.source_code }
isLoading={ isPlaceholderData }
hasSol2Yml={ Boolean(data.can_be_visualized_via_sol2uml) }
/>
address={ addressHash }
isViper={ Boolean(data.is_vyper_contract) }
filePath={ data.file_path }
additionalSource={ data.additional_sources }
remappings={ data.compiler_settings?.remappings }
isLoading={ isPlaceholderData }
/>
) }
{ data?.compiler_settings ? (
{ data?.compiler_settings ? (
<RawDataSnippet
<RawDataSnippet
data={ JSON.stringify(data.compiler_settings, undefined, 4) }
data={ JSON.stringify(data.compiler_settings, undefined, 4) }
...
...
ui/address/contract/ContractSourceCode.tsx
View file @
464c15f9
import
{
Flex
,
Skeleton
,
Text
,
Tooltip
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
Flex
,
Select
,
Skeleton
,
Text
,
Tooltip
}
from
'
@chakra-ui/react
'
;
import
{
route
}
from
'
nextjs-routes
'
;
import
{
route
}
from
'
nextjs-routes
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
SmartContract
}
from
'
types/api/contract
'
;
import
type
{
SmartContract
}
from
'
types/api/contract
'
;
import
type
{
ArrayElement
}
from
'
types/utils
'
;
import
CopyToClipboard
from
'
ui/shared/CopyToClipboard
'
;
import
CopyToClipboard
from
'
ui/shared/CopyToClipboard
'
;
import
LinkInternal
from
'
ui/shared/LinkInternal
'
;
import
LinkInternal
from
'
ui/shared/LinkInternal
'
;
import
CodeEditor
from
'
ui/shared/monaco/CodeEditor
'
;
import
CodeEditor
from
'
ui/shared/monaco/CodeEditor
'
;
import
formatFilePath
from
'
ui/shared/monaco/utils/formatFilePath
'
;
import
formatFilePath
from
'
ui/shared/monaco/utils/formatFilePath
'
;
import
{
useContractContext
}
from
'
./context
'
;
const
SOURCE_CODE_OPTIONS
=
[
{
id
:
'
primary
'
,
label
:
'
Proxy
'
}
as
const
,
{
id
:
'
secondary
'
,
label
:
'
Implementation
'
}
as
const
,
];
type
SourceCodeType
=
ArrayElement
<
typeof
SOURCE_CODE_OPTIONS
>
[
'
id
'
];
function
getEditorData
(
contractInfo
:
SmartContract
|
undefined
)
{
if
(
!
contractInfo
||
!
contractInfo
.
source_code
)
{
return
undefined
;
}
const
defaultName
=
contractInfo
.
is_vyper_contract
?
'
/index.vy
'
:
'
/index.sol
'
;
return
[
{
file_path
:
formatFilePath
(
contractInfo
.
file_path
||
defaultName
),
source_code
:
contractInfo
.
source_code
},
...(
contractInfo
.
additional_sources
||
[]).
map
((
source
)
=>
({
...
source
,
file_path
:
formatFilePath
(
source
.
file_path
)
})),
];
}
interface
Props
{
interface
Props
{
data
:
string
;
address
?:
string
;
// todo_tom need address of proxy contract
hasSol2Yml
:
boolean
;
isLoading
?:
boolean
;
// todo_tom should be true if proxyInfo is not loaded
address
?:
string
;
isViper
:
boolean
;
filePath
?:
string
;
additionalSource
?:
SmartContract
[
'
additional_sources
'
];
remappings
?:
Array
<
string
>
;
isLoading
?:
boolean
;
}
}
const
ContractSourceCode
=
({
data
,
hasSol2Yml
,
address
,
isViper
,
filePath
,
additionalSource
,
remappings
,
isLoading
}:
Props
)
=>
{
// todo_tom fix mobile layout
const
ContractSourceCode
=
({
address
,
isLoading
}:
Props
)
=>
{
const
[
sourceType
,
setSourceType
]
=
React
.
useState
<
SourceCodeType
>
(
'
primary
'
);
const
{
contractInfo
:
primaryContract
,
proxyInfo
:
secondaryContract
}
=
useContractContext
();
const
editorDataPrimary
=
React
.
useMemo
(()
=>
{
return
getEditorData
(
primaryContract
);
},
[
primaryContract
]);
const
editorDataSecondary
=
React
.
useMemo
(()
=>
{
return
getEditorData
(
secondaryContract
);
},
[
secondaryContract
]);
const
activeContract
=
sourceType
===
'
secondary
'
?
secondaryContract
:
primaryContract
;
const
activeContractData
=
sourceType
===
'
secondary
'
?
editorDataSecondary
:
editorDataPrimary
;
const
heading
=
(
const
heading
=
(
<
Skeleton
isLoaded=
{
!
isLoading
}
fontWeight=
{
500
}
>
<
Skeleton
isLoaded=
{
!
isLoading
}
fontWeight=
{
500
}
>
<
span
>
Contract source code
</
span
>
<
span
>
Contract source code
</
span
>
<
Text
whiteSpace=
"pre"
as=
"span"
variant=
"secondary"
>
(
{
isViper
?
'
Vyper
'
:
'
Solidity
'
}
)
</
Text
>
<
Text
whiteSpace=
"pre"
as=
"span"
variant=
"secondary"
>
(
{
activeContract
?.
is_vyper_contract
?
'
Vyper
'
:
'
Solidity
'
}
)
</
Text
>
</
Skeleton
>
</
Skeleton
>
);
);
const
diagramLink
=
hasSol2Y
ml
&&
address
?
(
const
diagramLink
=
activeContract
?.
can_be_visualized_via_sol2u
ml
&&
address
?
(
<
Tooltip
label=
"Visualize contract code using Sol2Uml JS library"
>
<
Tooltip
label=
"Visualize contract code using Sol2Uml JS library"
>
<
LinkInternal
<
LinkInternal
href=
{
route
({
pathname
:
'
/visualize/sol2uml
'
,
query
:
{
address
}
})
}
href=
{
route
({
pathname
:
'
/visualize/sol2uml
'
,
query
:
{
address
}
})
}
...
@@ -41,25 +72,64 @@ const ContractSourceCode = ({ data, hasSol2Yml, address, isViper, filePath, addi
...
@@ -41,25 +72,64 @@ const ContractSourceCode = ({ data, hasSol2Yml, address, isViper, filePath, addi
</
Tooltip
>
</
Tooltip
>
)
:
null
;
)
:
null
;
const
editorData
=
React
.
useMemo
(()
=>
{
const
copyToClipboard
=
activeContractData
?.
length
===
1
?
const
defaultName
=
isViper
?
'
/index.vy
'
:
'
/index.sol
'
;
<
CopyToClipboard
text=
{
activeContractData
[
0
].
source_code
}
isLoading=
{
isLoading
}
ml=
{
3
}
/>
:
return
[
{
file_path
:
formatFilePath
(
filePath
||
defaultName
),
source_code
:
data
},
...(
additionalSource
||
[]).
map
((
source
)
=>
({
...
source
,
file_path
:
formatFilePath
(
source
.
file_path
)
}))
];
},
[
additionalSource
,
data
,
filePath
,
isViper
]);
const
copyToClipboard
=
editorData
.
length
===
1
?
<
CopyToClipboard
text=
{
editorData
[
0
].
source_code
}
isLoading=
{
isLoading
}
ml=
{
3
}
/>
:
null
;
null
;
const
handleSelectChange
=
React
.
useCallback
((
event
:
React
.
ChangeEvent
<
HTMLSelectElement
>
)
=>
{
setSourceType
(
event
.
target
.
value
as
SourceCodeType
);
},
[]);
const
editorSourceTypeSelector
=
secondaryContract
?.
source_code
?
(
<
Select
size=
"xs"
borderRadius=
"base"
value=
{
sourceType
}
onChange=
{
handleSelectChange
}
focusBorderColor=
"none"
w=
"auto"
ml=
{
3
}
>
{
SOURCE_CODE_OPTIONS
.
map
((
option
)
=>
<
option
key=
{
option
.
id
}
value=
{
option
.
id
}
>
{
option
.
label
}
</
option
>)
}
</
Select
>
)
:
null
;
const
content
=
(()
=>
{
if
(
isLoading
)
{
return
<
Skeleton
h=
"557px"
w=
"100%"
/>;
}
if
(
!
editorDataPrimary
)
{
return
null
;
}
return
(
<>
<
Box
display=
{
sourceType
===
'
primary
'
?
'
block
'
:
'
none
'
}
>
<
CodeEditor
data=
{
editorDataPrimary
}
remappings=
{
primaryContract
?.
compiler_settings
?.
remappings
}
/>
</
Box
>
{
editorDataSecondary
&&
(
<
Box
display=
{
sourceType
===
'
secondary
'
?
'
block
'
:
'
none
'
}
>
<
CodeEditor
data=
{
editorDataSecondary
}
remappings=
{
secondaryContract
?.
compiler_settings
?.
remappings
}
/>
</
Box
>
)
}
</>
);
})();
if
(
!
editorDataPrimary
)
{
return
null
;
}
return
(
return
(
<
section
>
<
section
>
<
Flex
justifyContent=
"space-between"
alignItems=
"center"
mb=
{
3
}
>
<
Flex
justifyContent=
"space-between"
alignItems=
"center"
mb=
{
3
}
>
{
heading
}
{
heading
}
{
editorSourceTypeSelector
}
{
diagramLink
}
{
diagramLink
}
{
copyToClipboard
}
{
copyToClipboard
}
</
Flex
>
</
Flex
>
{
isLoading
?
<
Skeleton
h=
"557px"
w=
"100%"
/>
:
<
CodeEditor
data=
{
editorData
}
remappings=
{
remappings
}
/>
}
{
content
}
</
section
>
</
section
>
);
);
};
};
...
...
ui/address/contract/context.tsx
View file @
464c15f9
...
@@ -46,6 +46,7 @@ export function ContractContextProvider({ addressHash, children }: ProviderProps
...
@@ -46,6 +46,7 @@ export function ContractContextProvider({ addressHash, children }: ProviderProps
},
},
});
});
// todo_tom check custom abi case
const
{
data
:
customInfo
}
=
useApiQuery
(
'
contract_methods_write
'
,
{
const
{
data
:
customInfo
}
=
useApiQuery
(
'
contract_methods_write
'
,
{
pathParams
:
{
hash
:
addressHash
},
pathParams
:
{
hash
:
addressHash
},
queryParams
:
{
is_custom_abi
:
'
true
'
},
queryParams
:
{
is_custom_abi
:
'
true
'
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment