Browse Source

Moved focus node to LinkInput to avoid lifycycle issues, fixed tests

Anatoly Pulyaevskiy 6 years ago
parent
commit
53c1de6a44

+ 24
- 29
packages/zefyr/lib/src/widgets/buttons.dart View File

300
 }
300
 }
301
 
301
 
302
 class _LinkButtonState extends State<LinkButton> {
302
 class _LinkButtonState extends State<LinkButton> {
303
-  final FocusNode _focusNode = FocusNode();
304
   final TextEditingController _inputController = TextEditingController();
303
   final TextEditingController _inputController = TextEditingController();
305
   Key _inputKey;
304
   Key _inputKey;
306
   bool _formatError = false;
305
   bool _formatError = false;
308
 
307
 
309
   bool get isEditing => _inputKey != null;
308
   bool get isEditing => _inputKey != null;
310
 
309
 
311
-  @override
312
-  void dispose() {
313
-    _focusNode.dispose();
314
-    super.dispose();
315
-  }
316
-
317
-  @override
318
-  void didChangeDependencies() {
319
-    super.didChangeDependencies();
320
-    final toolbar = ZefyrToolbar.of(context);
321
-    if (_editor != toolbar.editor) {
322
-      _editor?.setToolbarFocusNode(null);
323
-      _editor = toolbar.editor;
324
-      _editor.setToolbarFocusNode(_focusNode);
325
-    }
326
-  }
327
-
328
   @override
310
   @override
329
   Widget build(BuildContext context) {
311
   Widget build(BuildContext context) {
330
     final toolbar = ZefyrToolbar.of(context);
312
     final toolbar = ZefyrToolbar.of(context);
457
         : _LinkInput(
439
         : _LinkInput(
458
             key: _inputKey,
440
             key: _inputKey,
459
             controller: _inputController,
441
             controller: _inputController,
460
-            focusNode: _focusNode,
461
             formatError: _formatError,
442
             formatError: _formatError,
462
           );
443
           );
463
     final items = <Widget>[Expanded(child: body)];
444
     final items = <Widget>[Expanded(child: body)];
494
 }
475
 }
495
 
476
 
496
 class _LinkInput extends StatefulWidget {
477
 class _LinkInput extends StatefulWidget {
497
-  final FocusNode focusNode;
498
   final TextEditingController controller;
478
   final TextEditingController controller;
499
   final bool formatError;
479
   final bool formatError;
500
 
480
 
501
-  const _LinkInput({
502
-    Key key,
503
-    @required this.focusNode,
504
-    @required this.controller,
505
-    this.formatError: false,
506
-  }) : super(key: key);
481
+  const _LinkInput(
482
+      {Key key, @required this.controller, this.formatError: false})
483
+      : super(key: key);
484
+
507
   @override
485
   @override
508
   _LinkInputState createState() {
486
   _LinkInputState createState() {
509
     return new _LinkInputState();
487
     return new _LinkInputState();
511
 }
489
 }
512
 
490
 
513
 class _LinkInputState extends State<_LinkInput> {
491
 class _LinkInputState extends State<_LinkInput> {
492
+  final FocusNode _focusNode = FocusNode();
493
+
514
   bool _didAutoFocus = false;
494
   bool _didAutoFocus = false;
495
+  ZefyrEditorScope _editor;
515
 
496
 
516
   @override
497
   @override
517
   void didChangeDependencies() {
498
   void didChangeDependencies() {
518
     super.didChangeDependencies();
499
     super.didChangeDependencies();
500
+    final toolbar = ZefyrToolbar.of(context);
519
     if (!_didAutoFocus) {
501
     if (!_didAutoFocus) {
520
-      FocusScope.of(context).requestFocus(widget.focusNode);
502
+      FocusScope.of(context).requestFocus(_focusNode);
521
       _didAutoFocus = true;
503
       _didAutoFocus = true;
522
     }
504
     }
505
+
506
+    if (_editor != toolbar.editor) {
507
+      _editor?.setToolbarFocusNode(null);
508
+      _editor = toolbar.editor;
509
+      _editor.setToolbarFocusNode(_focusNode);
510
+    }
511
+  }
512
+
513
+  @override
514
+  void dispose() {
515
+    _focusNode.dispose();
516
+    _editor = null;
517
+    super.dispose();
523
   }
518
   }
524
 
519
 
525
   @override
520
   @override
526
   Widget build(BuildContext context) {
521
   Widget build(BuildContext context) {
527
-    FocusScope.of(context).reparentIfNeeded(widget.focusNode);
522
+    FocusScope.of(context).reparentIfNeeded(_focusNode);
528
 
523
 
529
     final theme = Theme.of(context);
524
     final theme = Theme.of(context);
530
     final toolbarTheme = ZefyrTheme.of(context).toolbarTheme;
525
     final toolbarTheme = ZefyrTheme.of(context).toolbarTheme;
534
     return TextField(
529
     return TextField(
535
       style: style,
530
       style: style,
536
       keyboardType: TextInputType.url,
531
       keyboardType: TextInputType.url,
537
-      focusNode: widget.focusNode,
532
+      focusNode: _focusNode,
538
       controller: widget.controller,
533
       controller: widget.controller,
539
 //      autofocus: true,
534
 //      autofocus: true,
540
       decoration: new InputDecoration(
535
       decoration: new InputDecoration(

+ 2
- 1
packages/zefyr/lib/src/widgets/editor.dart View File

108
       _toolbarFocusNode?.removeListener(_handleFocusChange);
108
       _toolbarFocusNode?.removeListener(_handleFocusChange);
109
       _toolbarFocusNode = node;
109
       _toolbarFocusNode = node;
110
       _toolbarFocusNode.addListener(_handleFocusChange);
110
       _toolbarFocusNode.addListener(_handleFocusChange);
111
-      notifyListeners();
111
+      // We do not notify listeners here because it will happen when
112
+      // focus state changes.
112
     }
113
     }
113
   }
114
   }
114
 
115
 

+ 1
- 0
packages/zefyr/lib/src/widgets/toolbar.dart View File

191
     _delegate = widget.delegate ?? new _DefaultZefyrToolbarDelegate();
191
     _delegate = widget.delegate ?? new _DefaultZefyrToolbarDelegate();
192
     _overlayAnimation = new AnimationController(
192
     _overlayAnimation = new AnimationController(
193
         vsync: this, duration: Duration(milliseconds: 100));
193
         vsync: this, duration: Duration(milliseconds: 100));
194
+    _selection = editor.selection;
194
   }
195
   }
195
 
196
 
196
   @override
197
   @override

+ 2
- 1
packages/zefyr/test/widgets/buttons_test.dart View File

119
           .tap(find.widgetWithText(GestureDetector, 'Tap to edit link'));
119
           .tap(find.widgetWithText(GestureDetector, 'Tap to edit link'));
120
       await tester.pumpAndSettle();
120
       await tester.pumpAndSettle();
121
       // TODO: figure out why below finder finds 2 instances of TextField
121
       // TODO: figure out why below finder finds 2 instances of TextField
122
-      expect(find.widgetWithText(TextField, 'https://'), findsWidgets);
122
+      expect(find.byType(TextField), findsOneWidget);
123
+
123
       await tester.enterText(find.widgetWithText(TextField, 'https://').first,
124
       await tester.enterText(find.widgetWithText(TextField, 'https://').first,
124
           'https://github.com');
125
           'https://github.com');
125
       await tester.pumpAndSettle();
126
       await tester.pumpAndSettle();