Skip to content

Commit

Permalink
update vector input field
Browse files Browse the repository at this point in the history
  • Loading branch information
daoauth committed Jan 16, 2025
1 parent 70b12ed commit 88d4bce
Show file tree
Hide file tree
Showing 3 changed files with 264 additions and 122 deletions.
6 changes: 5 additions & 1 deletion src/webview/activitybar/src/components/Function.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,11 @@ export const Function = ({
? `Invalid value for type ${getTypeName(item)}`
: undefined
}
paramType={(item as any).Vector}
paramType={
(item as any).Vector ||
(item as any).Reference?.Vector ||
(item as any).MutableReference?.Vector
}
update={(params: string[]) => {
handleInputChange(key, params);
}}
Expand Down
228 changes: 161 additions & 67 deletions src/webview/activitybar/src/components/VectorInputFields.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import {
VSCodeButton,
VSCodeTextArea,
VSCodeTextField,
} from '@vscode/webview-ui-toolkit/react';
import { SuiMoveNormalizedType } from '@mysten/sui/client';
Expand All @@ -25,7 +26,9 @@ export const VectorInputFields = ({
paramType: SuiMoveNormalizedType;
update: (params: string[]) => void;
}) => {
const debounceTimeout = useRef<NodeJS.Timeout | null>(null);
const [vectorValues, setVectorValues] = useState<string[]>(['']);
const [hexInput, setHexInput] = useState('');

const handleAddField = () => {
setVectorValues([...vectorValues, '']);
Expand All @@ -43,77 +46,168 @@ export const VectorInputFields = ({
update(newVectorValues);
};

const getChunkSize = (): number => {
switch (paramType) {
case 'U8':
return 2;
case 'U16':
return 4;
case 'U32':
return 8;
case 'U64':
return 16;
case 'U128':
return 32;
case 'U256':
return 64;
default:
return 2;
}
};

const handleInput = (e: any) => {
const rawValue = e.target.value
.replace(/^0x/i, '')
.replace(/[^0-9A-F]/gi, '')
.toUpperCase();
setHexInput(rawValue);

if (debounceTimeout.current) {
clearTimeout(debounceTimeout.current);
}

debounceTimeout.current = setTimeout(() => {
const chunkSize = getChunkSize();
const formatted =
rawValue.match(new RegExp(`.{1,${chunkSize}}`, 'g'))?.join(' ') || '';
setHexInput(formatted);
setVectorValues(
rawValue.match(new RegExp(`.{1,${chunkSize}}`, 'g')) || [],
);
update(rawValue.match(new RegExp(`.{1,${chunkSize}}`, 'g')) || []);
}, 300);
};

useEffect(() => {
return () => {
if (debounceTimeout.current) {
clearTimeout(debounceTimeout.current);
}
};
}, []);

return (
<div style={cardStyles.card}>
<div style={{ flexDirection: 'column', padding: '8px' }}>
{vectorValues.map((value, index) => (
<div
key={index}
style={{
display: 'flex',
marginBottom: '8px',
width: '100%',
}}
>
<VSCodeTextField
style={{ width: '100%' }}
value={value}
placeholder={getTypeName(paramType)}
onInput={(e) =>
handleChange(index, (e.target as HTMLInputElement).value)
}
/>
{vectorValues.length > 1 && (
<VSCodeButton
appearance="icon"
onClick={() => handleRemoveField(index)}
style={{ marginLeft: '8px' }}
>
<svg
width="16px"
height="16px"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M7.116 8l-4.558 4.558.884.884L8 8.884l4.558 4.558.884-.884L8.884 8l4.558-4.558-.884-.884L8 7.116 3.442 2.558l-.884.884L7.116 8z"
/>
</svg>
</VSCodeButton>
)}
</div>
))}
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginTop: '8px',
width: '100%',
}}
>
{error ? (
<span
<>
{paramType === 'U8' ||
paramType === 'U16' ||
paramType === 'U32' ||
paramType === 'U64' ||
paramType === 'U128' ||
paramType === 'U256' ? (
<div style={{ flexDirection: 'column', padding: '8px' }}>
<VSCodeTextArea
rows={3}
style={{ width: '100%' }}
placeholder={`Vector<${paramType}>`}
value={hexInput}
onInput={handleInput}
/>
{error && (
<div
style={{
color: 'red',
fontSize: '11px',
wordWrap: 'break-word',
whiteSpace: 'pre-wrap',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginTop: '8px',
width: '100%',
}}
>
{error}
</span>
) : (
<>&nbsp;</>
<span
style={{
color: 'red',
fontSize: '11px',
wordWrap: 'break-word',
whiteSpace: 'pre-wrap',
}}
>
{error}
</span>
</div>
)}
<VSCodeButton style={{ height: '16px' }} onClick={handleAddField}>
<div style={{ fontSize: '8px' }}>Add</div>
</VSCodeButton>
</div>
</div>
</div>
) : (
<div style={cardStyles.card}>
<div style={{ flexDirection: 'column', padding: '8px' }}>
{vectorValues.map((value, index) => (
<div
key={index}
style={{
display: 'flex',
marginBottom: '8px',
width: '100%',
}}
>
<VSCodeTextField
style={{ width: '100%' }}
value={value}
placeholder={getTypeName(paramType)}
onInput={(e) =>
handleChange(index, (e.target as HTMLInputElement).value)
}
/>
{vectorValues.length > 1 && (
<VSCodeButton
appearance="icon"
onClick={() => handleRemoveField(index)}
style={{ marginLeft: '8px' }}
>
<svg
width="16px"
height="16px"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M7.116 8l-4.558 4.558.884.884L8 8.884l4.558 4.558.884-.884L8.884 8l4.558-4.558-.884-.884L8 7.116 3.442 2.558l-.884.884L7.116 8z"
/>
</svg>
</VSCodeButton>
)}
</div>
))}
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginTop: '8px',
width: '100%',
}}
>
{error ? (
<span
style={{
color: 'red',
fontSize: '11px',
wordWrap: 'break-word',
whiteSpace: 'pre-wrap',
}}
>
{error}
</span>
) : (
<>&nbsp;</>
)}
<VSCodeButton style={{ height: '16px' }} onClick={handleAddField}>
<div style={{ fontSize: '8px' }}>Add</div>
</VSCodeButton>
</div>
</div>
</div>
)}
</>
);
};
Loading

0 comments on commit 88d4bce

Please sign in to comment.