Skip to content

Commit 92c4158

Browse files
authored
Merge pull request #6578 from remix-project-org/patch-ai-dapp-generator
Patch ai dapp generator
2 parents 5cd77c4 + 2c538e0 commit 92c4158

File tree

8 files changed

+222
-122
lines changed

8 files changed

+222
-122
lines changed

apps/quick-dapp-v2/src/App.tsx

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,20 +68,28 @@ function App(): JSX.Element {
6868
appState,
6969
}}
7070
>
71-
<IntlProvider locale={locale.code} messages={locale.messages}>
72-
{appState.instance.htmlTemplate ? (
73-
<div className="container-fluid pt-3">
74-
<EditHtmlTemplate />
75-
</div>
76-
) : Object.keys(appState.instance.abi).length > 0 ? (
77-
<div className="row m-0 pt-3">
78-
<EditInstance />
79-
<DeployPanel />
71+
<IntlProvider locale={locale.code} messages={locale.messages || {}}>
72+
{!locale.messages ? (
73+
<div className="text-center pt-5">
74+
<i className="fas fa-spinner fa-spin fa-2x"></i>
8075
</div>
8176
) : (
82-
<div className="row m-0 pt-3">
83-
<CreateInstance isAiLoading={isAiLoading} />
84-
</div>
77+
<>
78+
{appState.instance.htmlTemplate ? (
79+
<div className="container-fluid pt-3">
80+
<EditHtmlTemplate />
81+
</div>
82+
) : Object.keys(appState.instance.abi).length > 0 ? (
83+
<div className="row m-0 pt-3">
84+
<EditInstance />
85+
<DeployPanel />
86+
</div>
87+
) : (
88+
<div className="row m-0 pt-3">
89+
<CreateInstance isAiLoading={isAiLoading} />
90+
</div>
91+
)}
92+
</>
8593
)}
8694
<LoadingScreen />
8795
</IntlProvider>

apps/quick-dapp-v2/src/components/ChatBox/ChatBox.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717
display: flex;
1818
gap: 8px;
1919
background-color: var(--light);
20-
border: 1px solid var(--border);
20+
border: 1px solid rgba(128, 128, 128, 0.5);
2121
border-radius: 4px;
2222
padding: 6px;
23+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
2324
transition: border-color 0.15s ease-in-out;
2425
}
2526

apps/quick-dapp-v2/src/components/DeployPanel/index.tsx

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,21 @@ function DeployPanel(): JSX.Element {
3030
const [isDetailsOpen, setIsDetailsOpen] = useState(true);
3131
const [isPublishOpen, setIsPublishOpen] = useState(true);
3232
const [isEnsOpen, setIsEnsOpen] = useState(true);
33+
const [ensError, setEnsError] = useState('');
3334

3435
const logoInputRef = useRef<HTMLInputElement>(null);
3536

37+
const validateEnsName = (name: string) => {
38+
const regex = /^[a-z0-9-]+$/;
39+
40+
if (!name) return '';
41+
if (name.length < 3) return 'Name must be at least 3 characters.';
42+
if (!regex.test(name)) return 'Only lowercase letters, numbers, and hyphens are allowed.';
43+
if (name.startsWith('-') || name.endsWith('-')) return 'Name cannot start or end with a hyphen.';
44+
45+
return '';
46+
};
47+
3648
const handleRemoveLogo = () => {
3749
dispatch({ type: 'SET_INSTANCE', payload: { logo: null } });
3850
if (logoInputRef.current) {
@@ -159,6 +171,12 @@ function DeployPanel(): JSX.Element {
159171

160172
const label = ensName.trim().toLowerCase();
161173

174+
const validationError = validateEnsName(label);
175+
if (validationError) {
176+
setEnsError(validationError);
177+
return;
178+
}
179+
162180
if (!label || !deployResult.cid) {
163181
setEnsResult({ ...ensResult, error: 'ENS label or IPFS CID is missing.' });
164182
setIsEnsLoading(false);
@@ -269,9 +287,9 @@ function DeployPanel(): JSX.Element {
269287
</Card.Header>
270288
<Collapse in={isPublishOpen}>
271289
<Card.Body>
272-
<Alert variant="info" className="small">
290+
<Alert variant="info">
273291
<i className="fas fa-info-circle me-2"></i>
274-
Deploy your DApp to IPFS using Remix's centralized gateway. No personal IPFS keys required.
292+
Deploy your DApp to IPFS using Remix's gateway. No personal IPFS keys required.
275293
</Alert>
276294

277295
<Button
@@ -288,13 +306,12 @@ function DeployPanel(): JSX.Element {
288306
</Button>
289307

290308
{deployResult.cid && (
291-
<Alert variant="success" className="mt-3 small" style={{ wordBreak: 'break-all' }}>
309+
<Alert variant="success" className="mt-3" style={{ wordBreak: 'break-all' }}>
292310
<div className="fw-bold">Deployed Successfully!</div>
293311
<div><strong>CID:</strong> {deployResult.cid}</div>
294-
<hr className="my-2" />
295-
<a href={deployResult.gatewayUrl} target="_blank" rel="noopener noreferrer">
296-
View DApp
297-
</a>
312+
<div className="mt-1">
313+
<strong>Domain:</strong> <a href={deployResult.gatewayUrl} target="_blank" rel="noopener noreferrer">View DApp</a>
314+
</div>
298315
</Alert>
299316
)}
300317
{deployResult.error && (
@@ -319,12 +336,11 @@ function DeployPanel(): JSX.Element {
319336
</Card.Header>
320337
<Collapse in={isEnsOpen}>
321338
<Card.Body>
322-
<Alert variant="info" className="small">
339+
<Alert variant="info">
323340
<i className="fas fa-gas-pump me-2"></i>
324341
Register a <strong>.remixdapp.eth</strong> subdomain on Arbitrum.
325342
Remix covers the gas fees!
326343
</Alert>
327-
328344
<Form.Group className="mb-2">
329345
<Form.Label className="text-uppercase mb-0">Subdomain Label</Form.Label>
330346
<div className="input-group">
@@ -333,15 +349,28 @@ function DeployPanel(): JSX.Element {
333349
placeholder="myapp"
334350
value={ensName}
335351
onChange={(e) => {
336-
setEnsName(e.target.value)
337-
if (ensResult.success) setEnsResult({ ...ensResult, success: '', txHash: '', domain: '' })
352+
const val = e.target.value.toLowerCase();
353+
setEnsName(val);
354+
const errorMsg = validateEnsName(val);
355+
setEnsError(errorMsg);
356+
if (ensResult.success || ensResult.error) {
357+
setEnsResult({ success: '', error: '', txHash: '', domain: '' });
358+
}
338359
}}
360+
isInvalid={!!ensError}
339361
/>
340362
<span className="input-group-text">.remixdapp.eth</span>
341363
</div>
342-
{!ensResult.success && (
343-
<Form.Text className="text-muted">
344-
Preview: <strong>https://{ensName || 'myapp'}.remixdapp.eth.limo</strong>
364+
{ensError && (
365+
<Form.Text className="text-danger">
366+
<i className="fas fa-exclamation-circle me-1"></i>
367+
{ensError}
368+
</Form.Text>
369+
)}
370+
{!ensError && ensName && !ensResult.success && (
371+
<Form.Text className="text-success">
372+
<i className="fas fa-check-circle me-1"></i>
373+
Valid name format
345374
</Form.Text>
346375
)}
347376
</Form.Group>
@@ -350,7 +379,7 @@ function DeployPanel(): JSX.Element {
350379
variant="secondary"
351380
className="w-100"
352381
onClick={handleEnsLink}
353-
disabled={isEnsLoading || !ensName}
382+
disabled={isEnsLoading || !ensName || !!ensError}
354383
>
355384
{isEnsLoading ? (
356385
<><i className="fas fa-spinner fa-spin me-1"></i> Registering...</>
@@ -360,8 +389,7 @@ function DeployPanel(): JSX.Element {
360389
</Button>
361390

362391
{ensResult.success && (
363-
<Alert variant="success" className="mt-3 small">
364-
<div className="fw-bold mb-1">Success!</div>
392+
<Alert variant="success" className="mt-3">
365393
<div>{ensResult.success}</div>
366394
<div className="mt-1">
367395
<strong>Domain:</strong> <a href={`https://${ensResult.domain}.limo`} target="_blank" rel="noreferrer">{ensResult.domain}</a>
@@ -380,14 +408,14 @@ function DeployPanel(): JSX.Element {
380408
<div className="mt-3">
381409
<Button
382410
size="sm"
383-
variant="outline-secondary"
411+
variant="secondary"
384412
onClick={() => { resetInstance(); handleRemoveLogo(); }}
385413
>
386414
<FormattedMessage id="quickDapp.resetFunctions" />
387415
</Button>
388416
<Button
389417
size="sm"
390-
variant="outline-danger"
418+
variant="danger"
391419
className="ms-3"
392420
onClick={() => { emptyInstance(); }}
393421
>

apps/quick-dapp-v2/src/components/EditHtmlTemplate/index.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,14 @@ function EditHtmlTemplate(): JSX.Element {
304304
return (
305305
<Row className="m-0 h-100">
306306
<Col xs={12} lg={8} className="pe-3 d-flex flex-column h-100">
307+
<Row>
308+
{/* Chat Section */}
309+
<div className="flex-grow-1 mb-3" style={{ minHeight: '30px' }}>
310+
<ChatBox
311+
onSendMessage={handleChatMessage}
312+
/>
313+
</div>
314+
</Row>
307315
{/* Preview Section */}
308316
<Row className="flex-grow-1 mb-3">
309317
<Col xs={12} className="d-flex flex-column h-100">
@@ -312,7 +320,7 @@ function EditHtmlTemplate(): JSX.Element {
312320
<FormattedMessage id="quickDapp.preview" defaultMessage="Preview" />
313321
</h5>
314322
<Button
315-
variant="outline-primary"
323+
variant="primary"
316324
size="sm"
317325
onClick={runBuild}
318326
disabled={isBuilding}
@@ -340,7 +348,7 @@ function EditHtmlTemplate(): JSX.Element {
340348
style={{
341349
width: '100%',
342350
height: '100%',
343-
minHeight: '400px',
351+
minHeight: '800px',
344352
border: 'none',
345353
backgroundColor: 'white',
346354
flex: '1'
@@ -369,14 +377,6 @@ function EditHtmlTemplate(): JSX.Element {
369377
</Card>
370378
</Col>
371379
</Row>
372-
<Row>
373-
{/* Chat Section */}
374-
<div className="flex-grow-1 mb-3" style={{ minHeight: '300px' }}>
375-
<ChatBox
376-
onSendMessage={handleChatMessage}
377-
/>
378-
</div>
379-
</Row>
380380
</Col>
381381

382382
{/* Second Column: Deploy Panel */}

apps/remix-ide/src/app.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import { RemixAIAssistant } from './app/plugins/remix-ai-assistant'
2626
import { SolidityUmlGen } from './app/plugins/solidity-umlgen'
2727
import { VyperCompilationDetailsPlugin } from './app/plugins/vyper-compilation-details'
2828
import { ContractFlattener } from './app/plugins/contractFlattener'
29-
import { IframeContent } from './app/plugins/iframe-content'
3029

3130
import { WalkthroughService } from './walkthroughService'
3231

@@ -320,9 +319,6 @@ class AppComponent {
320319
//---------------- Solidity UML Generator -------------------------
321320
const solidityumlgen = new SolidityUmlGen(appManager)
322321

323-
// ----------------- IframeContent Plugin -------------------------
324-
const iframeContent = new IframeContent(appManager)
325-
326322
// ----------------- Compilation Details ----------------------------
327323
const compilationDetails = new CompilationDetailsPlugin(appManager)
328324
const vyperCompilationDetails = new VyperCompilationDetailsPlugin(appManager)
@@ -456,7 +452,6 @@ class AppComponent {
456452
this.walkthroughService,
457453
search,
458454
solidityumlgen,
459-
iframeContent,
460455
compilationDetails,
461456
vyperCompilationDetails,
462457
remixGuide,

0 commit comments

Comments
 (0)