Skip to content

Commit a0e0897

Browse files
Fix: Make KeyboardScaffoldSafeArea work when not at bottom of screen (Resolves #2489) (#2490)
1 parent 66f8fcd commit a0e0897

File tree

3 files changed

+540
-163
lines changed

3 files changed

+540
-163
lines changed

super_editor/example/lib/demos/mobile_chat/demo_mobile_chat.dart

Lines changed: 85 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,10 @@ class _MobileChatDemoState extends State<MobileChatDemo> {
101101

102102
@override
103103
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.
105108
child: DefaultTabController(
106109
length: 2,
107110
child: Scaffold(
@@ -140,54 +143,67 @@ class _MobileChatDemoState extends State<MobileChatDemo> {
140143
}
141144

142145
Widget _buildChatPage() {
143-
return Stack(
146+
return Column(
144147
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+
},
176185
),
177-
);
178-
},
186+
),
187+
),
179188
),
180189
),
181190
),
182-
),
191+
Positioned(
192+
left: 0,
193+
right: 0,
194+
bottom: 0,
195+
child: KeyboardScaffoldSafeArea(
196+
child: _buildCommentEditor(),
197+
),
198+
),
199+
],
183200
),
184201
),
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),
191207
],
192208
);
193209
}
@@ -250,7 +266,7 @@ class _MobileChatDemoState extends State<MobileChatDemo> {
250266
slivers: [
251267
SliverPadding(
252268
padding: EdgeInsets.only(
253-
bottom: KeyboardScaffoldSafeArea.of(context).geometry.bottomPadding,
269+
bottom: KeyboardScaffoldSafeAreaScope.of(context).geometry.bottomPadding,
254270
// ^ Push the editor up above the OS bottom notch.
255271
),
256272
sliver: SuperEditor(
@@ -346,6 +362,32 @@ class _MobileChatDemoState extends State<MobileChatDemo> {
346362
);
347363
}
348364

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+
349391
Widget _buildAccountPage() {
350392
return ColoredBox(
351393
color: Colors.grey.shade100,

0 commit comments

Comments
 (0)