Compare commits
2 Commits
feat/flags
...
mobile-opt
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3b0fef406 | ||
|
|
4cbc316c62 |
@@ -6,11 +6,14 @@ const ButtonGroup = styled('div', {
|
||||
marginLeft: '1px',
|
||||
[`& ${StyledButton}`]: {
|
||||
marginLeft: '-1px',
|
||||
px: '$4',
|
||||
px: '0.65rem',
|
||||
zIndex: 2,
|
||||
position: 'relative',
|
||||
'&:hover, &:focus': {
|
||||
zIndex: 200
|
||||
},
|
||||
'@sm': {
|
||||
px: '$4'
|
||||
}
|
||||
},
|
||||
[`& ${StyledButton}:not(:only-of-type):not(:first-child):not(:last-child)`]: {
|
||||
|
||||
@@ -40,11 +40,10 @@ const StyledContent = styled(DialogPrimitive.Content, {
|
||||
color: '$mauve12',
|
||||
borderRadius: '$md',
|
||||
position: 'relative',
|
||||
mb: '15%',
|
||||
mb: '0%',
|
||||
boxShadow: '0px 10px 38px -5px rgba(22, 23, 24, 0.25), 0px 10px 20px -5px rgba(22, 23, 24, 0.2)',
|
||||
width: '90vw',
|
||||
maxWidth: '450px',
|
||||
// maxHeight: "85vh",
|
||||
padding: 25,
|
||||
'@media (prefers-reduced-motion: no-preference)': {
|
||||
animation: `${contentShow} 150ms cubic-bezier(0.16, 1, 0.3, 1)`
|
||||
@@ -53,6 +52,9 @@ const StyledContent = styled(DialogPrimitive.Content, {
|
||||
'.dark &': {
|
||||
backgroundColor: '$mauve5',
|
||||
boxShadow: '0px 10px 38px 0px rgba(0, 0, 0, 0.85), 0px 10px 20px 0px rgba(0, 0, 0, 0.6)'
|
||||
},
|
||||
'@md': {
|
||||
mb: '8%'
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -78,7 +78,6 @@ const EditorNavigation = ({ renderNav }: { renderNav?: () => ReactNode }) => {
|
||||
return (
|
||||
<Flex css={{ flexShrink: 0, gap: '$0' }}>
|
||||
<Flex
|
||||
id="kissa"
|
||||
ref={scrollRef}
|
||||
css={{
|
||||
overflowX: 'scroll',
|
||||
@@ -181,7 +180,21 @@ const EditorNavigation = ({ renderNav }: { renderNav?: () => ReactNode }) => {
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
) : (
|
||||
<Button outline size="sm" css={{ mr: '$3' }} onClick={() => setPopUp(true)}>
|
||||
<Button
|
||||
outline
|
||||
size="sm"
|
||||
css={{
|
||||
mr: '-1px',
|
||||
borderTopRightRadius: 0,
|
||||
borderBottomRightRadius: 0,
|
||||
'@sm': {
|
||||
borderTopRightRadius: '$sm',
|
||||
borderBottomRightRadius: '$sm',
|
||||
mr: '$3'
|
||||
}
|
||||
}}
|
||||
onClick={() => setPopUp(true)}
|
||||
>
|
||||
<GithubLogo size="16px" /> Login
|
||||
</Button>
|
||||
)}
|
||||
@@ -202,6 +215,9 @@ const EditorNavigation = ({ renderNav }: { renderNav?: () => ReactNode }) => {
|
||||
alignSelf: 'flex-start',
|
||||
boxShadow: 'none'
|
||||
},
|
||||
'button:not(:last-child)': {
|
||||
display: 'none'
|
||||
},
|
||||
'button:not(:first-child):not(:last-child)': {
|
||||
borderRight: 0,
|
||||
borderLeft: 0
|
||||
@@ -217,6 +233,11 @@ const EditorNavigation = ({ renderNav }: { renderNav?: () => ReactNode }) => {
|
||||
'&:hover': {
|
||||
boxShadow: 'inset 0px 0px 0px 1px $colors$mauve12'
|
||||
}
|
||||
},
|
||||
'@sm': {
|
||||
'button:not(:last-child)': {
|
||||
display: 'flex'
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -200,15 +200,15 @@ const HooksEditor = () => {
|
||||
defaultValue={file?.content}
|
||||
// onChange={val => (state.files[snap.active].content = val)} // Auto save?
|
||||
beforeMount={monaco => {
|
||||
// if (!snap.editorCtx) {
|
||||
// snap.files.forEach(file =>
|
||||
// monaco.editor.createModel(
|
||||
// file.content,
|
||||
// file.language,
|
||||
// monaco.Uri.parse(`file:///work/c/${file.name}`)
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
if (!snap.editorCtx) {
|
||||
snap.files.forEach(file =>
|
||||
monaco.editor.createModel(
|
||||
file.content,
|
||||
file.language,
|
||||
monaco.Uri.parse(`file:///work/c/${file.name}`)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// create the web socket
|
||||
if (!subscriptionRef.current) {
|
||||
@@ -218,11 +218,6 @@ const HooksEditor = () => {
|
||||
aliases: ['C', 'c', 'H', 'h'],
|
||||
mimetypes: ['text/plain']
|
||||
})
|
||||
monaco.languages.register({
|
||||
id: 'text',
|
||||
extensions: ['.txt'],
|
||||
mimetypes: ['text/plain'],
|
||||
})
|
||||
MonacoServices.install(monaco)
|
||||
const webSocket = createWebSocket(
|
||||
process.env.NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT || ''
|
||||
|
||||
@@ -33,7 +33,7 @@ import { styled } from '../stitches.config'
|
||||
const ImageWrapper = styled(Flex, {
|
||||
position: 'relative',
|
||||
mt: '$2',
|
||||
mb: '$10',
|
||||
mb: '$6',
|
||||
svg: {
|
||||
// fill: "red",
|
||||
'.angle': {
|
||||
@@ -66,16 +66,23 @@ const Navigation = () => {
|
||||
<Container
|
||||
css={{
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
alignItems: 'center',
|
||||
px: '$3',
|
||||
'@sm': {
|
||||
px: '$4'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
css={{
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
borderRight: '1px solid $colors$mauve6',
|
||||
py: '$3',
|
||||
pr: '$4'
|
||||
pr: '$0',
|
||||
'@sm': {
|
||||
borderRight: '1px solid $colors$mauve6',
|
||||
pr: '$4'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Link href={gistId ? `/develop/${gistId}` : '/develop'} passHref>
|
||||
@@ -84,7 +91,11 @@ const Navigation = () => {
|
||||
css={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
color: '$textColor'
|
||||
color: '$textColor',
|
||||
mr: '$2',
|
||||
'@sm': {
|
||||
mr: '$4'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Logo width="32px" height="32px" />
|
||||
@@ -92,9 +103,12 @@ const Navigation = () => {
|
||||
</Link>
|
||||
<Flex
|
||||
css={{
|
||||
ml: '$5',
|
||||
flexDirection: 'column',
|
||||
gap: '1px'
|
||||
gap: '1px',
|
||||
display: 'none',
|
||||
'@md': {
|
||||
display: 'flex'
|
||||
}
|
||||
}}
|
||||
>
|
||||
{snap.loading ? (
|
||||
@@ -135,8 +149,8 @@ const Navigation = () => {
|
||||
css={{
|
||||
display: 'flex',
|
||||
maxWidth: '1080px',
|
||||
width: '80vw',
|
||||
maxHeight: '80%',
|
||||
width: '90vw',
|
||||
maxHeight: '90%',
|
||||
backgroundColor: '$mauve1 !important',
|
||||
overflowY: 'auto',
|
||||
background: 'black',
|
||||
@@ -265,15 +279,18 @@ const Navigation = () => {
|
||||
gridTemplateColumns: '1fr',
|
||||
gridTemplateRows: 'max-content',
|
||||
flex: 1,
|
||||
p: '$7',
|
||||
pb: '$16',
|
||||
p: '$4',
|
||||
pb: '$8',
|
||||
gap: '$3',
|
||||
alignItems: 'normal',
|
||||
flexWrap: 'wrap',
|
||||
backgroundColor: '$mauve1',
|
||||
'@md': {
|
||||
gridTemplateColumns: '1fr 1fr',
|
||||
gridTemplateRows: 'max-content'
|
||||
gridTemplateRows: 'max-content',
|
||||
p: '$7',
|
||||
pb: '$10',
|
||||
paddingRight: '$12'
|
||||
},
|
||||
'@lg': {
|
||||
gridTemplateColumns: '1fr 1fr 1fr',
|
||||
@@ -316,23 +333,30 @@ const Navigation = () => {
|
||||
<Flex
|
||||
css={{
|
||||
flexWrap: 'nowrap',
|
||||
marginLeft: '$4',
|
||||
marginLeft: '$2',
|
||||
overflowX: 'scroll',
|
||||
'&::-webkit-scrollbar': {
|
||||
height: 0,
|
||||
background: 'transparent'
|
||||
},
|
||||
scrollbarColor: 'transparent',
|
||||
scrollbarWidth: 'none'
|
||||
scrollbarWidth: 'none',
|
||||
'@sm': {
|
||||
marginLeft: '$4'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Stack
|
||||
css={{
|
||||
ml: '$4',
|
||||
gap: '$3',
|
||||
ml: '$0',
|
||||
gap: '$2',
|
||||
flexWrap: 'nowrap',
|
||||
alignItems: 'center',
|
||||
marginLeft: 'auto'
|
||||
marginLeft: 'auto',
|
||||
'@sm': {
|
||||
marginLeft: '$4',
|
||||
gap: '$3'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ButtonGroup>
|
||||
|
||||
@@ -7,7 +7,7 @@ const PanelBox = styled('div', {
|
||||
flexDirection: 'column',
|
||||
border: '1px solid $colors$mauve6',
|
||||
backgroundColor: '$mauve2',
|
||||
padding: '$3',
|
||||
padding: '$5',
|
||||
borderRadius: '$sm',
|
||||
fontWeight: 'lighter',
|
||||
height: 'auto',
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from './Dialog'
|
||||
import { Plus, X } from 'phosphor-react'
|
||||
import { styled } from '../stitches.config'
|
||||
import { capitalize, getFileExtention } from '../utils/helpers'
|
||||
import { capitalize } from '../utils/helpers'
|
||||
import ContextMenu, { ContentMenuOption } from './ContextMenu'
|
||||
|
||||
const ErrorText = styled(Text, {
|
||||
@@ -97,7 +97,7 @@ export const Tabs = ({
|
||||
if (!tabname) {
|
||||
return { error: `Please enter ${label.toLocaleLowerCase()} name.` }
|
||||
}
|
||||
let ext = getFileExtention(tabname)
|
||||
let ext = (tabname.includes('.') && tabname.split('.').pop()) || ''
|
||||
|
||||
if (!ext && defaultExtension) {
|
||||
ext = defaultExtension
|
||||
@@ -109,7 +109,7 @@ export const Tabs = ({
|
||||
if (extensionRequired && !ext) {
|
||||
return { error: 'File extension is required!' }
|
||||
}
|
||||
if (allowedExtensions && ext && !allowedExtensions.includes(ext)) {
|
||||
if (allowedExtensions && !allowedExtensions.includes(ext)) {
|
||||
return { error: 'This file extension is not allowed!' }
|
||||
}
|
||||
if (headerExtraValidation && !tabname.match(headerExtraValidation.regex)) {
|
||||
|
||||
@@ -19,7 +19,6 @@ import { TxJson } from './json'
|
||||
import { TxUI } from './ui'
|
||||
import { default as _estimateFee } from '../../utils/estimateFee'
|
||||
import toast from 'react-hot-toast'
|
||||
import { combineFlags, extractFlags, transactionFlags } from '../../state/constants/flags'
|
||||
|
||||
export interface TransactionProps {
|
||||
header: string
|
||||
@@ -40,17 +39,14 @@ const Transaction: FC<TransactionProps> = ({ header, state: txState, ...props })
|
||||
|
||||
const prepareOptions = useCallback(
|
||||
(state: Partial<TransactionState> = txState) => {
|
||||
const { selectedTransaction, selectedDestAccount, selectedAccount, txFields, selectedFlags } =
|
||||
state
|
||||
const { selectedTransaction, selectedDestAccount, selectedAccount, txFields } = state
|
||||
|
||||
const TransactionType = selectedTransaction?.value || null
|
||||
const Destination = selectedDestAccount?.value || txFields?.Destination
|
||||
const Account = selectedAccount?.value || null
|
||||
const Flags = combineFlags(selectedFlags?.map(flag => flag.value)) || txFields?.Flags
|
||||
|
||||
return prepareTransaction({
|
||||
...txFields,
|
||||
Flags,
|
||||
TransactionType,
|
||||
Destination,
|
||||
Account
|
||||
@@ -140,13 +136,8 @@ const Transaction: FC<TransactionProps> = ({ header, state: txState, ...props })
|
||||
} else {
|
||||
fields.Destination = undefined
|
||||
}
|
||||
|
||||
if (transactionType?.value && transactionFlags[transactionType?.value] && fields.Flags) {
|
||||
nwState.selectedFlags = extractFlags(transactionType.value, fields.Flags)
|
||||
fields.Flags = undefined
|
||||
}
|
||||
|
||||
nwState.txFields = fields
|
||||
|
||||
const state = modifyTxState(header, nwState, { replaceState: true })
|
||||
const editorValue = getJsonString(state)
|
||||
return setState({ editorValue })
|
||||
@@ -188,22 +179,22 @@ const Transaction: FC<TransactionProps> = ({ header, state: txState, ...props })
|
||||
estimateFee={estimateFee}
|
||||
/>
|
||||
) : (
|
||||
<TxUI
|
||||
state={txState}
|
||||
resetState={resetState}
|
||||
setState={setState}
|
||||
estimateFee={estimateFee}
|
||||
/>
|
||||
<TxUI state={txState} setState={setState} estimateFee={estimateFee} />
|
||||
)}
|
||||
<Flex
|
||||
row
|
||||
css={{
|
||||
justifyContent: 'space-between',
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
width: '100%',
|
||||
mb: '$1'
|
||||
mb: '$2',
|
||||
mt: '$1',
|
||||
'@md': {
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
mt: '$0',
|
||||
mb: '$2'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
|
||||
@@ -17,19 +17,16 @@ import state from '../../state'
|
||||
import { streamState } from '../DebugStream'
|
||||
import { Button } from '..'
|
||||
import Textarea from '../Textarea'
|
||||
import { getFlags } from '../../state/constants/flags'
|
||||
|
||||
interface UIProps {
|
||||
setState: (pTx?: Partial<TransactionState> | undefined) => TransactionState | undefined
|
||||
resetState: (tt?: SelectOption) => TransactionState | undefined
|
||||
state: TransactionState
|
||||
estimateFee?: (...arg: any) => Promise<string | undefined>
|
||||
}
|
||||
|
||||
export const TxUI: FC<UIProps> = ({ state: txState, setState, resetState, estimateFee }) => {
|
||||
export const TxUI: FC<UIProps> = ({ state: txState, setState, estimateFee }) => {
|
||||
const { accounts } = useSnapshot(state)
|
||||
const { selectedAccount, selectedDestAccount, selectedTransaction, txFields, selectedFlags } =
|
||||
txState
|
||||
const { selectedAccount, selectedDestAccount, selectedTransaction, txFields } = txState
|
||||
|
||||
const accountOptions: SelectOption[] = accounts.map(acc => ({
|
||||
label: acc.name,
|
||||
@@ -43,15 +40,23 @@ export const TxUI: FC<UIProps> = ({ state: txState, setState, resetState, estima
|
||||
}))
|
||||
.filter(acc => acc.value !== selectedAccount?.value)
|
||||
|
||||
const flagsOptions: SelectOption[] = Object.entries(
|
||||
getFlags(selectedTransaction?.value) || {}
|
||||
).map(([label, value]) => ({
|
||||
label,
|
||||
value
|
||||
}))
|
||||
|
||||
const [feeLoading, setFeeLoading] = useState(false)
|
||||
|
||||
const resetFields = useCallback(
|
||||
(tt: string) => {
|
||||
const fields = getTxFields(tt)
|
||||
|
||||
if (fields.Destination !== undefined) {
|
||||
setState({ selectedDestAccount: null })
|
||||
fields.Destination = ''
|
||||
} else {
|
||||
fields.Destination = undefined
|
||||
}
|
||||
return setState({ txFields: fields })
|
||||
},
|
||||
[setState]
|
||||
)
|
||||
|
||||
const handleSetAccount = (acc: SelectOption) => {
|
||||
setState({ selectedAccount: acc })
|
||||
streamState.selectedAccount = acc
|
||||
@@ -87,11 +92,11 @@ export const TxUI: FC<UIProps> = ({ state: txState, setState, resetState, estima
|
||||
(tt: SelectOption) => {
|
||||
setState({ selectedTransaction: tt })
|
||||
|
||||
const newState = resetState(tt)
|
||||
const newState = resetFields(tt.value)
|
||||
|
||||
handleEstimateFee(newState, true)
|
||||
},
|
||||
[handleEstimateFee, resetState, setState]
|
||||
[handleEstimateFee, resetFields, setState]
|
||||
)
|
||||
|
||||
const switchToJson = () => setState({ viewType: 'json' })
|
||||
@@ -110,16 +115,14 @@ export const TxUI: FC<UIProps> = ({ state: txState, setState, resetState, estima
|
||||
[selectedTransaction?.value]
|
||||
)
|
||||
|
||||
const richFields = ['TransactionType', 'Account']
|
||||
const specialFields = ['TransactionType', 'Account']
|
||||
if (fields.Destination !== undefined) {
|
||||
richFields.push('Destination')
|
||||
specialFields.push('Destination')
|
||||
}
|
||||
|
||||
if (flagsOptions.length) {
|
||||
richFields.push('Flags')
|
||||
}
|
||||
|
||||
const otherFields = Object.keys(txFields).filter(k => !richFields.includes(k)) as [keyof TxFields]
|
||||
const otherFields = Object.keys(txFields).filter(k => !specialFields.includes(k)) as [
|
||||
keyof TxFields
|
||||
]
|
||||
|
||||
return (
|
||||
<Container
|
||||
@@ -134,11 +137,14 @@ export const TxUI: FC<UIProps> = ({ state: txState, setState, resetState, estima
|
||||
row
|
||||
fluid
|
||||
css={{
|
||||
justifyContent: 'flex-end',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
mb: '$3',
|
||||
mt: '1px',
|
||||
pr: '1px'
|
||||
pr: '1px',
|
||||
'@xl': {
|
||||
justifyContent: 'flex-end'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text muted css={{ mr: '$3' }}>
|
||||
@@ -149,7 +155,13 @@ export const TxUI: FC<UIProps> = ({ state: txState, setState, resetState, estima
|
||||
placeholder="Select transaction type"
|
||||
options={transactionsOptions}
|
||||
hideSelectedOptions
|
||||
css={{ width: '70%' }}
|
||||
css={{
|
||||
width: '60%',
|
||||
minWidth: '200px',
|
||||
'@lg': {
|
||||
width: '70%'
|
||||
}
|
||||
}}
|
||||
value={selectedTransaction}
|
||||
onChange={(tt: any) => handleChangeTxType(tt)}
|
||||
/>
|
||||
@@ -158,10 +170,13 @@ export const TxUI: FC<UIProps> = ({ state: txState, setState, resetState, estima
|
||||
row
|
||||
fluid
|
||||
css={{
|
||||
justifyContent: 'flex-end',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
mb: '$3',
|
||||
pr: '1px'
|
||||
pr: '1px',
|
||||
'@xl': {
|
||||
justifyContent: 'flex-end'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text muted css={{ mr: '$3' }}>
|
||||
@@ -170,30 +185,45 @@ export const TxUI: FC<UIProps> = ({ state: txState, setState, resetState, estima
|
||||
<Select
|
||||
instanceId="from-account"
|
||||
placeholder="Select your account"
|
||||
css={{ width: '70%' }}
|
||||
css={{
|
||||
width: '60%',
|
||||
minWidth: '200px',
|
||||
'@lg': {
|
||||
width: '70%'
|
||||
}
|
||||
}}
|
||||
options={accountOptions}
|
||||
value={selectedAccount}
|
||||
onChange={(acc: any) => handleSetAccount(acc)} // TODO make react-select have correct types for acc
|
||||
/>
|
||||
</Flex>
|
||||
{richFields.includes('Destination') && (
|
||||
{fields.Destination !== undefined && (
|
||||
<Flex
|
||||
row
|
||||
fluid
|
||||
css={{
|
||||
justifyContent: 'flex-end',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
mb: '$3',
|
||||
pr: '1px'
|
||||
pr: '1px',
|
||||
'@xl': {
|
||||
justifyContent: 'flex-end'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text muted css={{ mr: '$3', textAlign: 'end' }}>
|
||||
<Text muted css={{ mr: '$3' }}>
|
||||
Destination account:{' '}
|
||||
</Text>
|
||||
<Select
|
||||
instanceId="to-account"
|
||||
placeholder="Select the destination account"
|
||||
css={{ width: '70%' }}
|
||||
css={{
|
||||
width: '60%',
|
||||
minWidth: '200px',
|
||||
'@lg': {
|
||||
width: '70%'
|
||||
}
|
||||
}}
|
||||
options={destAccountOptions}
|
||||
value={selectedDestAccount}
|
||||
isClearable
|
||||
@@ -201,36 +231,6 @@ export const TxUI: FC<UIProps> = ({ state: txState, setState, resetState, estima
|
||||
/>
|
||||
</Flex>
|
||||
)}
|
||||
{richFields.includes('Flags') && (
|
||||
<Flex
|
||||
row
|
||||
fluid
|
||||
css={{
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: 'center',
|
||||
mb: '$3',
|
||||
pr: '1px'
|
||||
}}
|
||||
>
|
||||
<Text muted css={{ mr: '$3' }}>
|
||||
Flags:{' '}
|
||||
</Text>
|
||||
<Select
|
||||
isClearable
|
||||
css={{ width: '70%' }}
|
||||
instanceId="flags"
|
||||
placeholder="Select flags to apply"
|
||||
menuPosition="fixed"
|
||||
value={selectedFlags}
|
||||
isMulti
|
||||
options={flagsOptions}
|
||||
onChange={flags => setState({ selectedFlags: flags as any })}
|
||||
closeMenuOnSelect={
|
||||
selectedFlags ? selectedFlags.length >= flagsOptions.length - 1 : false
|
||||
}
|
||||
/>
|
||||
</Flex>
|
||||
)}
|
||||
{otherFields.map(field => {
|
||||
let _value = txFields[field]
|
||||
|
||||
@@ -256,9 +256,12 @@ export const TxUI: FC<UIProps> = ({ state: txState, setState, resetState, estima
|
||||
row
|
||||
fluid
|
||||
css={{
|
||||
justifyContent: 'flex-end',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
position: 'relative'
|
||||
position: 'relative',
|
||||
'@xl': {
|
||||
justifyContent: 'flex-end'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text muted css={{ mr: '$3' }}>
|
||||
@@ -271,9 +274,13 @@ export const TxUI: FC<UIProps> = ({ state: txState, setState, resetState, estima
|
||||
spellCheck={false}
|
||||
onChange={switchToJson}
|
||||
css={{
|
||||
width: '70%',
|
||||
width: '60%',
|
||||
minWidth: '200px',
|
||||
flex: 'inherit',
|
||||
resize: 'vertical'
|
||||
resize: 'vertical',
|
||||
'@lg': {
|
||||
width: '70%'
|
||||
}
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
@@ -298,7 +305,8 @@ export const TxUI: FC<UIProps> = ({ state: txState, setState, resetState, estima
|
||||
: undefined
|
||||
}
|
||||
css={{
|
||||
width: '70%',
|
||||
width: '60%',
|
||||
minWidth: '200px',
|
||||
flex: 'inherit',
|
||||
'-moz-appearance': 'textfield',
|
||||
'&::-webkit-outer-spin-button': {
|
||||
@@ -308,6 +316,9 @@ export const TxUI: FC<UIProps> = ({ state: txState, setState, resetState, estima
|
||||
'&::-webkit-inner-spin-button ': {
|
||||
'-webkit-appearance': 'none',
|
||||
margin: 0
|
||||
},
|
||||
'@lg': {
|
||||
width: '70%'
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"DestinationTag": 13,
|
||||
"Fee": "2000000",
|
||||
"Sequence": 2470665,
|
||||
"Flags": "2147483648"
|
||||
"Flags": 2147483648
|
||||
},
|
||||
{
|
||||
"TransactionType": "AccountSet",
|
||||
@@ -48,7 +48,7 @@
|
||||
"Account": "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8",
|
||||
"Authorize": "rEhxGqkqPPSxQ3P25J66ft5TwpzV14k2de",
|
||||
"Fee": "10",
|
||||
"Flags": "2147483648",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 2
|
||||
},
|
||||
{
|
||||
@@ -109,9 +109,7 @@
|
||||
"Fee": "10",
|
||||
"NFTokenOffers": {
|
||||
"$type": "json",
|
||||
"$value": [
|
||||
"4AAAEEA76E3C8148473CB3840CE637676E561FB02BD4CA22CA59729EA815B862"
|
||||
]
|
||||
"$value": ["4AAAEEA76E3C8148473CB3840CE637676E561FB02BD4CA22CA59729EA815B862"]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -122,7 +120,7 @@
|
||||
"$value": "100",
|
||||
"$type": "xrp"
|
||||
},
|
||||
"Flags": "1",
|
||||
"Flags": 1,
|
||||
"Destination": "",
|
||||
"Fee": "10"
|
||||
},
|
||||
@@ -130,7 +128,7 @@
|
||||
"TransactionType": "OfferCancel",
|
||||
"Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
|
||||
"Fee": "12",
|
||||
"Flags": "0",
|
||||
"Flags": 0,
|
||||
"LastLedgerSequence": 7108629,
|
||||
"OfferSequence": 6,
|
||||
"Sequence": 7
|
||||
@@ -139,7 +137,7 @@
|
||||
"TransactionType": "OfferCreate",
|
||||
"Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
|
||||
"Fee": "12",
|
||||
"Flags": "0",
|
||||
"Flags": 0,
|
||||
"LastLedgerSequence": 7108682,
|
||||
"Sequence": 8,
|
||||
"TakerGets": "6000000",
|
||||
@@ -157,7 +155,7 @@
|
||||
"$type": "xrp"
|
||||
},
|
||||
"Fee": "12",
|
||||
"Flags": "2147483648",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 2
|
||||
},
|
||||
{
|
||||
@@ -187,14 +185,14 @@
|
||||
"Fee": "10"
|
||||
},
|
||||
{
|
||||
"Flags": "0",
|
||||
"Flags": 0,
|
||||
"TransactionType": "SetRegularKey",
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Fee": "12",
|
||||
"RegularKey": "rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD"
|
||||
},
|
||||
{
|
||||
"Flags": "0",
|
||||
"Flags": 0,
|
||||
"TransactionType": "SignerListSet",
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Fee": "12",
|
||||
@@ -234,7 +232,7 @@
|
||||
"TransactionType": "TrustSet",
|
||||
"Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
|
||||
"Fee": "12",
|
||||
"Flags": "262144",
|
||||
"Flags": 262144,
|
||||
"LastLedgerSequence": 8007750,
|
||||
"LimitAmount": {
|
||||
"$type": "json",
|
||||
@@ -246,4 +244,4 @@
|
||||
},
|
||||
"Sequence": 12
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -10,11 +10,10 @@ import Box from '../../components/Box'
|
||||
import Button from '../../components/Button'
|
||||
import Popover from '../../components/Popover'
|
||||
import RunScript from '../../components/RunScript'
|
||||
import state, { IFile } from '../../state'
|
||||
import state from '../../state'
|
||||
import { compileCode } from '../../state/actions'
|
||||
import { getSplit, saveSplit } from '../../state/actions/persistSplits'
|
||||
import { styled } from '../../stitches.config'
|
||||
import { getFileExtention } from '../../utils/helpers'
|
||||
|
||||
const HooksEditor = dynamic(() => import('../../components/HooksEditor'), {
|
||||
ssr: false
|
||||
@@ -148,8 +147,6 @@ const CompilerSettings = () => {
|
||||
const Home: NextPage = () => {
|
||||
const snap = useSnapshot(state)
|
||||
|
||||
const activeFile = snap.files[snap.active] as IFile | undefined
|
||||
const activeFileExt = getFileExtention(activeFile?.name)
|
||||
return (
|
||||
<Split
|
||||
direction="vertical"
|
||||
@@ -162,7 +159,7 @@ const Home: NextPage = () => {
|
||||
>
|
||||
<main style={{ display: 'flex', flex: 1, position: 'relative' }}>
|
||||
<HooksEditor />
|
||||
{activeFileExt === 'c' && (
|
||||
{snap.files[snap.active]?.name?.split('.')?.[1]?.toLowerCase() === 'c' && (
|
||||
<Hotkeys
|
||||
keyName="command+b,ctrl+b"
|
||||
onKeyDown={() => !snap.compiling && snap.files.length && compileCode(snap.active)}
|
||||
@@ -196,7 +193,7 @@ const Home: NextPage = () => {
|
||||
</Flex>
|
||||
</Hotkeys>
|
||||
)}
|
||||
{activeFileExt === 'js' && (
|
||||
{snap.files[snap.active]?.name?.split('.')?.[1]?.toLowerCase() === 'js' && (
|
||||
<Hotkeys
|
||||
keyName="command+b,ctrl+b"
|
||||
onKeyDown={() => !snap.compiling && snap.files.length && compileCode(snap.active)}
|
||||
@@ -212,7 +209,7 @@ const Home: NextPage = () => {
|
||||
gap: '$2'
|
||||
}}
|
||||
>
|
||||
<RunScript file={activeFile as IFile} />
|
||||
<RunScript file={snap.files[snap.active]} />
|
||||
</Flex>
|
||||
</Hotkeys>
|
||||
)}
|
||||
@@ -228,7 +225,7 @@ const Home: NextPage = () => {
|
||||
>
|
||||
<LogBox title="Development Log" clearLog={() => (state.logs = [])} logs={snap.logs} />
|
||||
</Flex>
|
||||
{activeFileExt === 'js' && (
|
||||
{snap.files[snap.active]?.name?.split('.')?.[1]?.toLowerCase() === 'js' && (
|
||||
<Flex
|
||||
css={{
|
||||
flex: 1
|
||||
|
||||
@@ -68,6 +68,7 @@ const Test = () => {
|
||||
justifyContent: 'center',
|
||||
p: '$3 $2'
|
||||
}}
|
||||
className="split-mobile-forceAutoHeight"
|
||||
>
|
||||
<Split
|
||||
direction="horizontal"
|
||||
@@ -82,6 +83,7 @@ const Test = () => {
|
||||
height: '100%'
|
||||
}}
|
||||
onDragEnd={e => saveSplit('testHorizontal', e)}
|
||||
className="split-mobile-forceVertical"
|
||||
>
|
||||
<Box css={{ width: '55%', px: '$2' }}>
|
||||
<Tabs
|
||||
@@ -105,7 +107,18 @@ const Test = () => {
|
||||
))}
|
||||
</Tabs>
|
||||
</Box>
|
||||
<Box css={{ width: '45%', mx: '$2', height: '100%' }}>
|
||||
<Box
|
||||
css={{
|
||||
width: '45%',
|
||||
mx: '$0',
|
||||
mt: '$1',
|
||||
height: '100%',
|
||||
'@md': {
|
||||
mx: '$2',
|
||||
mt: '$0'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Accounts card hideDeployBtn showHookStats />
|
||||
</Box>
|
||||
</Split>
|
||||
@@ -131,6 +144,7 @@ const Test = () => {
|
||||
<Flex>
|
||||
<Split
|
||||
direction="horizontal"
|
||||
className="split-mobile-forceVertical"
|
||||
sizes={[50, 50]}
|
||||
minSize={[320, 160]}
|
||||
gutterSize={4}
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
import { getFileExtention } from '../../utils/helpers'
|
||||
import state, { IFile } from '../index'
|
||||
|
||||
const languageMapping: Record<string, string | undefined> = {
|
||||
const languageMapping = {
|
||||
ts: 'typescript',
|
||||
js: 'javascript',
|
||||
md: 'markdown',
|
||||
c: 'c',
|
||||
h: 'c',
|
||||
txt: 'text'
|
||||
}
|
||||
|
||||
other: ''
|
||||
} /* Initializes empty file to global state */
|
||||
export const createNewFile = (name: string) => {
|
||||
const ext = getFileExtention(name) || ''
|
||||
|
||||
const emptyFile: IFile = { name, language: languageMapping[ext] || 'text', content: '' }
|
||||
const tempName = name.split('.')
|
||||
const fileExt = tempName[tempName.length - 1] || 'other'
|
||||
const emptyFile: IFile = {
|
||||
name,
|
||||
language: languageMapping[fileExt as 'ts' | 'js' | 'md' | 'c' | 'h' | 'other'],
|
||||
content: ''
|
||||
}
|
||||
state.files.push(emptyFile)
|
||||
state.active = state.files.length - 1
|
||||
}
|
||||
@@ -22,8 +24,5 @@ export const renameFile = (oldName: string, nwName: string) => {
|
||||
const file = state.files.find(file => file.name === oldName)
|
||||
if (!file) throw Error(`No file exists with name ${oldName}`)
|
||||
|
||||
const ext = getFileExtention(nwName) || ''
|
||||
const language = languageMapping[ext] || 'text'
|
||||
file.name = nwName
|
||||
file.language = language
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
import { SelectOption } from '../transactions';
|
||||
|
||||
interface Flags {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export const transactionFlags: { [key: /* TransactionType */ string]: Flags } = {
|
||||
"*": {
|
||||
tfFullyCanonicalSig: '0x80000000'
|
||||
},
|
||||
Payment: {
|
||||
tfNoDirectRipple: '0x00010000',
|
||||
tfPartialPayment: '0x00020000',
|
||||
tfLimitQuality: '0x00040000',
|
||||
},
|
||||
AccountSet: {
|
||||
tfRequireDestTag: '0x00010000',
|
||||
tfOptionalDestTag: '0x00020000',
|
||||
tfRequireAuth: '0x00040000',
|
||||
tfOptionalAuth: '0x00080000',
|
||||
tfDisallowXRP: '0x00100000',
|
||||
tfAllowXRP: '0x00200000',
|
||||
},
|
||||
NFTokenCreateOffer: {
|
||||
tfSellNFToken: '0x00000001',
|
||||
},
|
||||
NFTokenMint: {
|
||||
tfBurnable: '0x00000001',
|
||||
tfOnlyXRP: '0x00000002',
|
||||
tfTrustLine: '0x00000004',
|
||||
tfTransferable: '0x00000008',
|
||||
},
|
||||
OfferCreate: {
|
||||
tfPassive: '0x00010000',
|
||||
tfImmediateOrCancel: '0x00020000',
|
||||
tfFillOrKill: '0x00040000',
|
||||
tfSell: '0x00080000',
|
||||
},
|
||||
PaymentChannelClaim: {
|
||||
tfRenew: '0x00010000',
|
||||
tfClose: '0x00020000',
|
||||
},
|
||||
TrustSet: {
|
||||
tfSetfAuth: '0x00010000',
|
||||
tfSetNoRipple: '0x00020000',
|
||||
tfClearNoRipple: '0x00040000',
|
||||
tfSetFreeze: '0x00100000',
|
||||
tfClearFreeze: '0x00200000',
|
||||
},
|
||||
}
|
||||
|
||||
export const getFlags = (tt?: string) => {
|
||||
if (!tt) return
|
||||
const flags = {
|
||||
...transactionFlags['*'],
|
||||
...transactionFlags[tt]
|
||||
}
|
||||
|
||||
return flags
|
||||
}
|
||||
|
||||
|
||||
export function combineFlags(flags?: string[]): string | undefined {
|
||||
if (!flags) return
|
||||
|
||||
const num = flags.reduce((cumm, curr) => cumm | BigInt(curr), BigInt(0))
|
||||
return num.toString()
|
||||
}
|
||||
|
||||
export function extractFlags(transactionType: string, flags?: string | number,): SelectOption[] {
|
||||
const flagsObj = getFlags(transactionType)
|
||||
if (!flags || !flagsObj) return []
|
||||
|
||||
const extracted = Object.entries(flagsObj).reduce((cumm, [label, value]) => {
|
||||
return (BigInt(flags) & BigInt(value)) ? cumm.concat({ label, value }) : cumm
|
||||
}, [] as SelectOption[])
|
||||
|
||||
return extracted
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import transactionsData from '../content/transactions.json'
|
||||
import state from '.'
|
||||
import { showAlert } from '../state/actions/showAlert'
|
||||
import { parseJSON } from '../utils/json'
|
||||
import { extractFlags, getFlags } from './constants/flags'
|
||||
|
||||
export type SelectOption = {
|
||||
value: string
|
||||
@@ -15,7 +14,6 @@ export interface TransactionState {
|
||||
selectedTransaction: SelectOption | null
|
||||
selectedAccount: SelectOption | null
|
||||
selectedDestAccount: SelectOption | null
|
||||
selectedFlags: SelectOption[] | null
|
||||
txIsLoading: boolean
|
||||
txIsDisabled: boolean
|
||||
txFields: TxFields
|
||||
@@ -33,7 +31,6 @@ export const defaultTransaction: TransactionState = {
|
||||
selectedTransaction: null,
|
||||
selectedAccount: null,
|
||||
selectedDestAccount: null,
|
||||
selectedFlags: null,
|
||||
txIsLoading: false,
|
||||
txIsDisabled: false,
|
||||
txFields: {},
|
||||
@@ -131,8 +128,9 @@ export const prepareTransaction = (data: any) => {
|
||||
try {
|
||||
options[field] = JSON.parse(_value.$value)
|
||||
} catch (error) {
|
||||
const message = `Input error for json field '${field}': ${error instanceof Error ? error.message : ''
|
||||
}`
|
||||
const message = `Input error for json field '${field}': ${
|
||||
error instanceof Error ? error.message : ''
|
||||
}`
|
||||
console.error(message)
|
||||
options[field] = _value.$value
|
||||
}
|
||||
@@ -207,13 +205,6 @@ export const prepareState = (value: string, transactionType?: string) => {
|
||||
rest.Destination = Destination
|
||||
}
|
||||
|
||||
if (getFlags(TransactionType) && rest.Flags) {
|
||||
const flags = extractFlags(TransactionType, rest.Flags)
|
||||
|
||||
rest.Flags = undefined
|
||||
tx.selectedFlags = flags
|
||||
}
|
||||
|
||||
Object.keys(rest).forEach(field => {
|
||||
const value = rest[field]
|
||||
const schemaVal = schema[field as keyof TxFields]
|
||||
|
||||
@@ -54,3 +54,15 @@ html.light .gutter-horizontal:hover {
|
||||
.monaco-editor .monaco-hover {
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 48rem) {
|
||||
.split-mobile-forceAutoHeight {
|
||||
height: auto !important;
|
||||
}
|
||||
.split-mobile-forceVertical {
|
||||
flex-direction: column !important;
|
||||
}
|
||||
.split-mobile-forceVertical > div {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,3 @@ export const capitalize = (value?: string) => {
|
||||
|
||||
return value[0].toLocaleUpperCase() + value.slice(1)
|
||||
}
|
||||
|
||||
export const getFileExtention = (filename?: string): string | undefined => {
|
||||
if (!filename) return
|
||||
const ext = (filename.includes('.') && filename.split('.').pop()) || undefined
|
||||
return ext
|
||||
}
|
||||
|
||||
@@ -2725,9 +2725,9 @@ javascript-time-ago@^2.3.11:
|
||||
relative-time-format "^1.0.7"
|
||||
|
||||
jose@^4.1.4, jose@^4.3.7:
|
||||
version "4.10.0"
|
||||
resolved "https://registry.yarnpkg.com/jose/-/jose-4.10.0.tgz#2e0b7bcc80dd0775f8a4588e55beb9460c37d60a"
|
||||
integrity sha512-KEhB/eLGLomWGPTb+/RNbYsTjIyx03JmbqAyIyiXBuNSa7CmNrJd5ysFhblayzs/e/vbOPMUaLnjHUMhGp4yLw==
|
||||
version "4.6.0"
|
||||
resolved "https://registry.npmjs.org/jose/-/jose-4.6.0.tgz"
|
||||
integrity sha512-0hNAkhMBNi4soKSAX4zYOFV+aqJlEz/4j4fregvasJzEVtjDChvWqRjPvHwLqr5hx28Ayr6bsOs1Kuj87V0O8w==
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
||||
Reference in New Issue
Block a user