Skip to content

Improve UX of editing with AI (drafted by Brian). #3235

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 60 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
f414a71
-
polina-c Apr 2, 2025
a9bf58d
-
polina-c Apr 2, 2025
89fb139
Update main.dart
polina-c Apr 2, 2025
bde6060
Update main.dart
polina-c Apr 2, 2025
e68d997
-
polina-c Apr 2, 2025
185f76c
Update main.dart
polina-c Apr 2, 2025
56909e1
attmanager
polina-c Apr 2, 2025
214a77b
-
polina-c Apr 3, 2025
e7bda57
Merge branch 'main' of github.com:dart-lang/dart-pad into edit_b
polina-c Apr 3, 2025
84599a8
assets
polina-c Apr 3, 2025
cf64287
fb
polina-c Apr 3, 2025
618c6e5
Update main.dart
polina-c Apr 3, 2025
af4162c
Update main.dart
polina-c Apr 3, 2025
eab3015
Update widgets.dart
polina-c Apr 3, 2025
4f083ad
-
polina-c Apr 3, 2025
91fc56a
Update widgets.dart
polina-c Apr 3, 2025
7dec550
Update model.dart
polina-c Apr 3, 2025
2ee12c3
Update model.dart
polina-c Apr 3, 2025
e858b5b
-
polina-c Apr 3, 2025
9209e14
-
polina-c Apr 3, 2025
1a86265
Update model.dart
polina-c Apr 3, 2025
8fc0831
-
polina-c Apr 3, 2025
58b108c
-
polina-c Apr 4, 2025
422f6b0
Update editor.dart
polina-c Apr 4, 2025
444b590
fb
polina-c Apr 4, 2025
c163346
Update .firebaserc
polina-c Apr 4, 2025
a30c194
Update firebase.json
polina-c Apr 4, 2025
73ded97
Update .firebaserc
polina-c Apr 4, 2025
92f101d
Update editor.dart
polina-c Apr 8, 2025
64f6c32
-
polina-c Apr 8, 2025
5d29629
Update widgets.dart
polina-c Apr 8, 2025
16478bb
Update main.dart
polina-c Apr 8, 2025
1676130
Update main.dart
polina-c Apr 8, 2025
5b26c86
-
polina-c Apr 8, 2025
d87a56f
Update edit_with_ai.dart
polina-c Apr 8, 2025
6c482c2
Update edit_with_ai.dart
polina-c Apr 8, 2025
075e66b
Update edit_with_ai.dart
polina-c Apr 8, 2025
8751ecb
-
polina-c Apr 9, 2025
d0e326e
-
polina-c Apr 9, 2025
cc59d79
Update model.dart
polina-c Apr 9, 2025
17d5109
-
polina-c Apr 9, 2025
95763f2
Merge branch 'main' of github.com:dart-lang/dart-pad into edit_b
polina-c Apr 9, 2025
da7ab75
Update pubspec.yaml
polina-c Apr 9, 2025
8a61a72
-
polina-c Apr 10, 2025
51ed8f6
Update main.dart
polina-c Apr 10, 2025
5f63f3b
-
polina-c Apr 10, 2025
2efc74f
Update model.dart
polina-c Apr 10, 2025
d44f3de
Update main.dart
polina-c Apr 10, 2025
e3670e6
Merge branch 'main' of github.com:dart-lang/dart-pad into edit_b
polina-c Apr 11, 2025
c7af32f
Update widgets.dart
polina-c Apr 11, 2025
1b0f260
-
polina-c Apr 11, 2025
63b286c
Update prompt_dialog.dart
polina-c Apr 11, 2025
87c7a54
Merge branch 'main' of github.com:dart-lang/dart-pad into edit_b
polina-c Apr 12, 2025
54c9e7e
-
polina-c Apr 12, 2025
28abe3d
Update suggest_fix.dart
polina-c Apr 12, 2025
4753fae
Update model.dart
polina-c Apr 12, 2025
1d7518e
-
polina-c Apr 12, 2025
c7863a0
Update main.dart
polina-c Apr 12, 2025
1f1a9c4
-
polina-c Apr 16, 2025
badd547
Merge branch 'main' of github.com:dart-lang/dart-pad into edit_b
polina-c Apr 16, 2025
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
14 changes: 14 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@
"--disable-web-security",
],
},
{
"name": "ui, beta channel",
"request": "launch",
"type": "dart",
"program": "pkgs/dartpad_ui/lib/main.dart",
"args": [
"--web-browser-flag",
"--disable-web-security",
"--web-port",
"8888",
"--web-launch-url",
"http://localhost:8888/?channel=beta",
],
},
{
"name": "ui, local backend",
"request": "launch",
Expand Down
10 changes: 5 additions & 5 deletions pkgs/dartpad_ui/.firebaserc
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
{
"projects": {
"default": "dart-pad"
"default": "dartpad-polina"
},
"targets": {
"dart-pad": {
"dartpad-polina": {
"hosting": {
"dartpad": [
"dart-pad-a3c64"
"dartpad-polina"
],
"preview": [
"sketch-pad-1cebb"
"dartpad-polina"
]
}
}
},
"etags": {}
}
}
6 changes: 2 additions & 4 deletions pkgs/dartpad_ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,9 @@ If you want to collaborate on an intermediate version, you can publish it to you
...
```

2. Run `firebase init`
2. Make sure your current Flutter channel is set to `stable`

3. Make sure your current Flutter channel is set to `stable`

4. Run the commands:
3. Run the commands:

```
cd pkgs/dartpad_ui
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 changes: 27 additions & 33 deletions pkgs/dartpad_ui/lib/editor/editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -622,19 +622,16 @@ class _ReadOnlyCodeWidgetState extends State<ReadOnlyCodeWidget> {
Widget build(BuildContext context) {
return Focus(
autofocus: true,
child: SizedBox(
height: 500,
child: TextField(
controller: _textController,
readOnly: true,
maxLines: null,
style: GoogleFonts.robotoMono(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Theme.of(context).textTheme.bodyMedium?.color,
),
decoration: const InputDecoration(border: InputBorder.none),
child: TextField(
controller: _textController,
readOnly: true,
maxLines: null,
style: GoogleFonts.robotoMono(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Theme.of(context).textTheme.bodyMedium?.color,
),
decoration: const InputDecoration(border: InputBorder.none),
),
);
}
Expand All @@ -656,27 +653,24 @@ class ReadOnlyDiffWidget extends StatelessWidget {
Widget build(BuildContext context) {
return Focus(
autofocus: true,
child: SizedBox(
height: 500,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: PrettyDiffText(
oldText: existingSource,
newText: newSource,
defaultTextStyle: GoogleFonts.robotoMono(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Theme.of(context).textTheme.bodyMedium?.color,
),
addedTextStyle: const TextStyle(
color: Colors.black,
backgroundColor: Color.fromARGB(255, 201, 255, 201),
),
deletedTextStyle: const TextStyle(
color: Colors.black,
backgroundColor: Color.fromARGB(255, 249, 199, 199),
decoration: TextDecoration.lineThrough,
),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: PrettyDiffText(
oldText: existingSource,
newText: newSource,
defaultTextStyle: GoogleFonts.robotoMono(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Theme.of(context).textTheme.bodyMedium?.color,
),
addedTextStyle: const TextStyle(
color: Colors.black,
backgroundColor: Color.fromARGB(255, 201, 255, 201),
),
deletedTextStyle: const TextStyle(
color: Colors.black,
backgroundColor: Color.fromARGB(255, 249, 199, 199),
decoration: TextDecoration.lineThrough,
),
),
),
Expand Down
128 changes: 128 additions & 0 deletions pkgs/dartpad_ui/lib/editor/generating_panel.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';

import 'package:flutter/material.dart';

import '../model.dart';
import '../simple_widgets.dart';
import '../theme.dart';
import '../utils.dart';
import 'editor.dart';

class GeneratingCodePanel extends StatefulWidget {
const GeneratingCodePanel({
required this.appModel,
required this.appServices,
super.key,
});

final AppModel appModel;
final AppServices appServices;

@override
State<GeneratingCodePanel> createState() => _GeneratingCodePanelState();
}

class _GeneratingCodePanelState extends State<GeneratingCodePanel> {
final _focusNode = FocusNode();
StreamSubscription<String>? _subscription;

@override
void initState() {
super.initState();

final genAiManager = widget.appModel.genAiManager;

final stream = genAiManager.stream;

_subscription = stream.value.listen(
(text) => setState(() {
genAiManager.writeToStreamBuffer(text);
}),
onDone: () {
setState(() {
final generatedCode = genAiManager.generatedCode().trim();
if (generatedCode.isEmpty) {
widget.appModel.editorStatus.showToast('Error generating code');
widget.appModel.appendError(
'There was an error generating your code, please try again.',
);
widget.appModel.genAiManager.enterStandby();
return;
}
genAiManager.setStreamBufferValue(generatedCode);
genAiManager.setStreamIsDone(true);
genAiManager.enterAwaitingAcceptReject();
_focusNode.requestFocus();
widget.appModel.sourceCodeController.textNoScroll = generatedCode;
widget.appServices.performCompileAndReloadOrRun();
});
},
);
}

@override
void dispose() {
_subscription?.cancel();
super.dispose();
}

@override
Widget build(BuildContext context) {
final genAiManager = widget.appModel.genAiManager;
return ValueListenableBuilder(
valueListenable: genAiManager.streamIsDone,
builder: (
BuildContext context,
bool genAiCodeStreamIsDone,
Widget? child,
) {
final resolvedSpinner =
genAiCodeStreamIsDone
? SizedBox(width: 0, height: 0)
: Positioned(
top: 10,
right: 10,
child: AnimatedContainer(
duration: animationDelay,
curve: animationCurve,
child: CircularProgressIndicator(),
),
);
return Stack(
children: [
resolvedSpinner,
MultiValueListenableBuilder(
listenables: [
genAiManager.streamBuffer,
widget.appModel.genAiManager.activeCuj,
genAiManager.preGenAiSourceCode,
],
builder: (_) {
final genAiCodeStreamBuffer =
genAiManager.streamBuffer.value.toString();

return Focus(
autofocus: true,
focusNode: _focusNode,
child:
widget.appModel.genAiManager.activeCuj.value ==
GenAiCuj.generateCode
? ReadOnlyCodeWidget(genAiCodeStreamBuffer)
: ReadOnlyDiffWidget(
existingSource:
genAiManager.preGenAiSourceCode.value,
newSource: genAiCodeStreamBuffer,
),
);
},
),
],
);
},
);
}
}
11 changes: 11 additions & 0 deletions pkgs/dartpad_ui/lib/extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

extension GoRouteHelpers on GoRouter {
Expand All @@ -21,3 +22,13 @@ extension GoRouteHelpers on GoRouter {
go(currentUri.replace(queryParameters: newQueryParameters).toString());
}
}

extension MenuControllerToggleMenu on MenuController {
void toggleMenuState() {
if (isOpen) {
close();
} else {
open();
}
}
}
Loading
Loading