1
- import 'package:flutter/cupertino.dart' ;
2
1
import 'package:flutter/material.dart' ;
3
2
import 'package:flutter/services.dart' ;
4
3
import 'package:flutter_hooks/flutter_hooks.dart' ;
@@ -7,15 +6,14 @@ import 'package:fvm/fvm.dart';
7
6
import 'package:hooks_riverpod/hooks_riverpod.dart' ;
8
7
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart' ;
9
8
10
- import '../../../components/atoms/typography.dart' ;
11
9
import '../../../modules/common/dto/release.dto.dart' ;
12
10
import '../../../modules/common/utils/notify.dart' ;
13
11
import '../sandbox.provider.dart' ;
14
12
15
13
/// Sandbox terminal
16
- class SandboxConsole extends HookWidget {
14
+ class SandboxTerminal extends HookWidget {
17
15
/// Constructor
18
- const SandboxConsole ({
16
+ const SandboxTerminal ({
19
17
this .project,
20
18
this .release,
21
19
Key key,
@@ -41,23 +39,21 @@ class SandboxConsole extends HookWidget {
41
39
42
40
final processing = terminalState.processing;
43
41
44
- void submitCmd (
42
+ void onSubmit (
45
43
String value,
46
- ) async {
44
+ ) {
47
45
try {
48
46
/// Don't do anything if its empty
49
47
if (value.isEmpty) return ;
50
48
// Reset command index
51
49
currentCmdIdx.value = 0 ;
52
50
// Add to the beginning of list
53
51
textController.clear ();
54
- await terminal.sendIsolate (
52
+ terminal.sendIsolate (
55
53
value,
56
54
release,
57
55
project,
58
56
);
59
- // Clear controller
60
- scrollController.jumpTo (0 );
61
57
} on Exception catch (e) {
62
58
notifyError (e.toString ());
63
59
}
@@ -79,6 +75,20 @@ class SandboxConsole extends HookWidget {
79
75
}
80
76
}, [processing]);
81
77
78
+ useEffect (() {
79
+ /// Scroll to bottom
80
+ if (scrollController.hasClients) {
81
+ WidgetsBinding .instance.addPostFrameCallback ((_) {
82
+ scrollController.animateTo (
83
+ scrollController.position.maxScrollExtent,
84
+ duration: Duration (milliseconds: 250 ),
85
+ curve: Curves .ease,
86
+ );
87
+ });
88
+ }
89
+ return ;
90
+ }, [terminalState.lines]);
91
+
82
92
void moveCmdIndex (int step) {
83
93
final cmds = terminalState.cmdHistory;
84
94
final currentIdx = currentCmdIdx.value;
@@ -108,7 +118,7 @@ class SandboxConsole extends HookWidget {
108
118
});
109
119
}
110
120
111
- void handleKey (RawKeyEvent key) {
121
+ void handlekeyDown (RawKeyEvent key) {
112
122
if (key.runtimeType.toString () == 'RawKeyDownEvent' ) {
113
123
if (key.data.logicalKey == LogicalKeyboardKey .arrowUp) {
114
124
if (terminalState.cmdHistory.length > currentCmdIdx.value) {
@@ -124,27 +134,26 @@ class SandboxConsole extends HookWidget {
124
134
}
125
135
126
136
return Column (
137
+ crossAxisAlignment: CrossAxisAlignment .stretch,
127
138
children: [
128
139
Expanded (
129
- child: CupertinoScrollbar (
130
- child: ListView .builder (
131
- controller: scrollController,
132
- reverse: true ,
133
- padding: const EdgeInsets .fromLTRB (20 , 10 , 20 , 10 ),
134
- itemCount: terminalState.lines.length,
135
- itemBuilder: (context, index) {
136
- final line = terminalState.lines[index];
137
- switch (line.type) {
138
- case OutputType .stderr:
139
- return ConsoleTextError (line.text);
140
- case OutputType .info:
141
- return ConsoleTextInfo (line.text);
142
- case OutputType .stdout:
143
- return ConsoleText (line.text);
144
- default :
145
- return Container ();
146
- }
147
- },
140
+ child: SingleChildScrollView (
141
+ primary: false ,
142
+ controller: scrollController,
143
+ child: Padding (
144
+ padding: const EdgeInsets .all (8.0 ),
145
+ child: SelectableText .rich (
146
+ TextSpan (
147
+ children: terminalState.lines
148
+ .map (
149
+ (e) => TextSpan (
150
+ text: '${e .text }\n ' ,
151
+ style: e.style,
152
+ ),
153
+ )
154
+ .toList (),
155
+ ),
156
+ ),
148
157
),
149
158
),
150
159
),
@@ -155,12 +164,12 @@ class SandboxConsole extends HookWidget {
155
164
Expanded (
156
165
child: RawKeyboardListener (
157
166
focusNode: keyListenerFocus,
158
- onKey: handleKey ,
167
+ onKey: handlekeyDown ,
159
168
child: TextField (
160
169
focusNode: focus,
161
170
enabled: ! terminalState.processing,
162
171
controller: textController,
163
- onSubmitted: submitCmd ,
172
+ onSubmitted: onSubmit ,
164
173
decoration: const InputDecoration (
165
174
icon: Icon (MdiIcons .chevronRight),
166
175
border: InputBorder .none,
0 commit comments