Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/codec-components/EditCodec/CEnum.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SearchableSelect } from "@/components/Select"
import { isEnumComplex, isEnumVoid } from "@/utils/shape"
import { getEnumDefaultValue, isEnumComplex } from "@/utils/shape"
import { EditEnum, NOTIN } from "@polkadot-api/react-builder"
import { Marker } from "../common/Markers"
import { useSubtreeFocus } from "../common/SubtreeFocus"
Expand Down Expand Up @@ -43,7 +43,7 @@ export const CEnum: EditEnum = ({
<SearchableSelect
setValue={(selected: string | null) => {
if (selected && options.includes(selected)) {
const value = isEnumVoid(shape, selected) ? null : NOTIN
const value = getEnumDefaultValue(shape, selected)
onValueChanged({ type: selected, value })
}
}}
Expand Down
4 changes: 3 additions & 1 deletion src/codec-components/EditCodec/CSequence.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { CirclePlus } from "lucide-react"
import { twMerge as clsx } from "tailwind-merge"
import { ListItem } from "../common/ListItem"
import { useSubtreeFocus } from "../common/SubtreeFocus"
import { getDefaultValue } from "@/utils"

export const CSequence: EditSequence = ({
innerComponents,
value,
onValueChanged,
path,
shape,
}) => {
const focus = useSubtreeFocus()
const sub = focus.getNextPath(path)
Expand All @@ -18,7 +20,7 @@ export const CSequence: EditSequence = ({

const addItem = () => {
const curr = value !== NOTIN ? value.slice() : []
curr.push(NOTIN)
curr.push(getDefaultValue(shape.value))
onValueChanged([...curr])
}

Expand Down
13 changes: 10 additions & 3 deletions src/codec-components/EditCodec/codec-components.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import SliderToggle from "@/components/Toggle"
import { getDefaultValue } from "@/utils"
import {
EditArray,
EditBool,
EditOption,
EditResult,
EditVoid,
NOTIN,
} from "@polkadot-api/react-builder"
import { FC, ReactNode, useState } from "react"
import { twMerge } from "tailwind-merge"
Expand Down Expand Up @@ -61,15 +61,22 @@ export const CArray: EditArray = ({ innerComponents, path }) => {
)
}

export const COption: EditOption = ({ value, inner, onValueChanged }) => {
export const COption: EditOption = ({
value,
inner,
shape,
onValueChanged,
}) => {
const selected = value !== undefined
return (
<div>
<label className="flex items-center gap-2 py-1 mb-1">
<SliderToggle
isToggled={selected}
toggle={() =>
!selected ? onValueChanged(NOTIN) : onValueChanged(undefined)
!selected
? onValueChanged(getDefaultValue(shape.value))
: onValueChanged(undefined)
}
/>
<span className="text-base">
Expand Down
50 changes: 44 additions & 6 deletions src/utils/shape.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { EnumVar, StructVar, Var } from "@polkadot-api/metadata-builders"
import { NOTIN } from "@polkadot-api/react-builder"
import { Enum } from "polkadot-api"
import { mapObject } from "polkadot-api/utils"

const complexTypes = new Set<Var["type"]>([
"tuple",
Expand Down Expand Up @@ -40,14 +43,49 @@ export const getStructInnerType = <T extends StructVar>(
return shape.value[key].type
}

export const isEnumVoid = <T extends EnumVar>(
const MAX_DEPTH = 5
export const getDefaultValue = (innerVar: Var, depth = 0): any => {
if (depth > MAX_DEPTH) return NOTIN
const nextDefault = (v: Var) => getDefaultValue(v, depth + 1)

switch (innerVar.type) {
case "void":
return null
case "option":
return undefined
case "sequence":
return []
case "struct":
return mapObject(innerVar.value, (v) => nextDefault(v))
case "array":
return new Array(innerVar.len)
.fill(0)
.map(() => nextDefault(innerVar.value))
case "tuple":
return innerVar.value.map(nextDefault)
case "enum": {
const selected = Object.entries(innerVar.value)[0]
return selected
? Enum(
selected[0],
nextDefault(
selected[1].type === "lookupEntry"
? selected[1].value
: selected[1],
),
)
: NOTIN
}
}
return NOTIN
}

export const getEnumDefaultValue = <T extends EnumVar>(
shape: T,
type: keyof T["value"],
): boolean => {
const innerShape = shape.value[type]
const innerType =
innerShape.type === "lookupEntry" ? innerShape.value.type : innerShape.type
return innerType === "void"
) => {
const innerVar = getEnumInnerVar(shape, type)
return getDefaultValue(innerVar)
}

export const getFinalType = (shape: any, name: string) => {
Expand Down