@@ -101,7 +101,10 @@ class _MobileChatDemoState extends State<MobileChatDemo> {
101
101
102
102
@override
103
103
Widget build (BuildContext context) {
104
- return KeyboardScaffoldSafeArea (
104
+ return KeyboardScaffoldSafeAreaScope (
105
+ // ^ Share keyboard inset info throughout all subtrees. The insets will
106
+ // be reported by the subtree with the editor. Those insets might then
107
+ // be used by the subtree with page content, etc.
105
108
child: DefaultTabController (
106
109
length: 2 ,
107
110
child: Scaffold (
@@ -140,54 +143,67 @@ class _MobileChatDemoState extends State<MobileChatDemo> {
140
143
}
141
144
142
145
Widget _buildChatPage () {
143
- return Stack (
146
+ return Column (
144
147
children: [
145
- Positioned .fill (
146
- child: GestureDetector (
147
- onTap: () {
148
- _screenFocusNode.requestFocus ();
149
- _keyboardPanelController.closeKeyboardAndPanel ();
150
- },
151
- child: Focus (
152
- focusNode: _screenFocusNode,
153
- child: ColoredBox (
154
- color: Colors .white,
155
- child: KeyboardScaffoldSafeArea (
156
- child: ListView .builder (
157
- // TODO: we need a solution to ensure this chat list has bottom
158
- // padding large enough to account for the (dynamic) height
159
- // of the editor.
160
- itemCount: 10 ,
161
- itemBuilder: (context, index) {
162
- return Container (
163
- height: 150 ,
164
- margin: EdgeInsets .all (16 ),
165
- decoration: BoxDecoration (
166
- color: Colors .white,
167
- borderRadius: BorderRadius .circular (16 ),
168
- border: Border .all (color: Colors .grey.shade200),
169
- boxShadow: [
170
- BoxShadow (
171
- color: Colors .black.withValues (alpha: 0.2 ),
172
- blurRadius: 16 ,
173
- offset: Offset (0 , 8 ),
174
- ),
175
- ],
148
+ Expanded (
149
+ child: Stack (
150
+ children: [
151
+ Positioned .fill (
152
+ child: GestureDetector (
153
+ onTap: () {
154
+ _screenFocusNode.requestFocus ();
155
+ _keyboardPanelController.closeKeyboardAndPanel ();
156
+ },
157
+ child: Focus (
158
+ focusNode: _screenFocusNode,
159
+ child: ColoredBox (
160
+ color: Colors .white,
161
+ child: KeyboardScaffoldSafeArea (
162
+ child: ListView .builder (
163
+ // TODO: we need a solution to ensure this chat list has bottom
164
+ // padding large enough to account for the (dynamic) height
165
+ // of the editor.
166
+ itemCount: 10 ,
167
+ itemBuilder: (context, index) {
168
+ return Container (
169
+ height: 150 ,
170
+ margin: EdgeInsets .all (16 ),
171
+ decoration: BoxDecoration (
172
+ color: Colors .white,
173
+ borderRadius: BorderRadius .circular (16 ),
174
+ border: Border .all (color: Colors .grey.shade200),
175
+ boxShadow: [
176
+ BoxShadow (
177
+ color: Colors .black.withValues (alpha: 0.2 ),
178
+ blurRadius: 16 ,
179
+ offset: Offset (0 , 8 ),
180
+ ),
181
+ ],
182
+ ),
183
+ );
184
+ },
176
185
),
177
- );
178
- } ,
186
+ ),
187
+ ) ,
179
188
),
180
189
),
181
190
),
182
- ),
191
+ Positioned (
192
+ left: 0 ,
193
+ right: 0 ,
194
+ bottom: 0 ,
195
+ child: KeyboardScaffoldSafeArea (
196
+ child: _buildCommentEditor (),
197
+ ),
198
+ ),
199
+ ],
183
200
),
184
201
),
185
- Positioned (
186
- left: 0 ,
187
- right: 0 ,
188
- bottom: 0 ,
189
- child: _buildCommentEditor (),
190
- ),
202
+ // We build a small status area to ensure that things work correctly
203
+ // when the chat editor isn't at the absolute bottom of the screen.
204
+ // Our earlier bottom inset logic didn't account for this, and broke
205
+ // in a client app, where that app had persistent bottom tabs.
206
+ _buildChatStatus (context),
191
207
],
192
208
);
193
209
}
@@ -250,7 +266,7 @@ class _MobileChatDemoState extends State<MobileChatDemo> {
250
266
slivers: [
251
267
SliverPadding (
252
268
padding: EdgeInsets .only (
253
- bottom: KeyboardScaffoldSafeArea .of (context).geometry.bottomPadding,
269
+ bottom: KeyboardScaffoldSafeAreaScope .of (context).geometry.bottomPadding,
254
270
// ^ Push the editor up above the OS bottom notch.
255
271
),
256
272
sliver: SuperEditor (
@@ -346,6 +362,32 @@ class _MobileChatDemoState extends State<MobileChatDemo> {
346
362
);
347
363
}
348
364
365
+ Widget _buildChatStatus (BuildContext context) {
366
+ return DefaultTextStyle (
367
+ style: DefaultTextStyle .of (context).style.copyWith (
368
+ color: Colors .white.withValues (alpha: 0.5 ),
369
+ ),
370
+ child: Container (
371
+ width: double .infinity,
372
+ color: const Color (0xFF222222 ),
373
+ child: SafeArea (
374
+ top: false ,
375
+ left: false ,
376
+ right: false ,
377
+ child: Padding (
378
+ padding: const EdgeInsets .symmetric (vertical: 8 , horizontal: 12 ),
379
+ child: Text (
380
+ "There are 3 people online in this chat." ,
381
+ textAlign: TextAlign .center,
382
+ maxLines: 1 ,
383
+ overflow: TextOverflow .ellipsis,
384
+ ),
385
+ ),
386
+ ),
387
+ ),
388
+ );
389
+ }
390
+
349
391
Widget _buildAccountPage () {
350
392
return ColoredBox (
351
393
color: Colors .grey.shade100,
0 commit comments