@@ -394,96 +394,6 @@ class ComposeContentController extends ComposeController<ContentValidationError>
394
394
}
395
395
}
396
396
397
- class _ContentInput extends StatefulWidget {
398
- const _ContentInput ({
399
- required this .narrow,
400
- required this .controller,
401
- required this .hintText,
402
- });
403
-
404
- final Narrow narrow;
405
- final ComposeBoxController controller;
406
- final String hintText;
407
-
408
- @override
409
- State <StatefulWidget > createState () => _ContentInputState ();
410
- }
411
-
412
- class _ContentInputState <T extends _ContentInput > extends State <T > {
413
- static double maxHeight (BuildContext context) {
414
- final clampingTextScaler = MediaQuery .textScalerOf (context)
415
- .clamp (maxScaleFactor: 1.5 );
416
- final scaledLineHeight = clampingTextScaler.scale (_fontSize) * _lineHeightRatio;
417
-
418
- // Reserve space to fully show the first 7th lines and just partially
419
- // clip the 8th line, where the height matches the spec at
420
- // https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=3960-5147&node-type=text&m=dev
421
- // > Maximum size of the compose box is suggested to be 178px. Which
422
- // > has 7 fully visible lines of text
423
- //
424
- // The partial line hints that the content input is scrollable.
425
- //
426
- // Using the ambient TextScale means this works for different values of the
427
- // system text-size setting. We clamp to a max scale factor to limit
428
- // how tall the content input can get; that's to save room for the message
429
- // list. The user can still scroll the input to see everything.
430
- return _verticalPadding + 7.727 * scaledLineHeight;
431
- }
432
-
433
- static const _verticalPadding = 8.0 ;
434
- static const _fontSize = 17.0 ;
435
- static const _lineHeight = 22.0 ;
436
- static const _lineHeightRatio = _lineHeight / _fontSize;
437
-
438
- @override
439
- Widget build (BuildContext context) {
440
- final designVariables = DesignVariables .of (context);
441
-
442
- return ComposeAutocomplete (
443
- narrow: widget.narrow,
444
- controller: widget.controller.content,
445
- focusNode: widget.controller.contentFocusNode,
446
- fieldViewBuilder: (context) => ConstrainedBox (
447
- constraints: BoxConstraints (maxHeight: maxHeight (context)),
448
- // This [ClipRect] replaces the [TextField] clipping we disable below.
449
- child: ClipRect (
450
- child: InsetShadowBox (
451
- top: _verticalPadding, bottom: _verticalPadding,
452
- color: designVariables.composeBoxBg,
453
- child: TextField (
454
- controller: widget.controller.content,
455
- focusNode: widget.controller.contentFocusNode,
456
- // Let the content show through the `contentPadding` so that
457
- // our [InsetShadowBox] can fade it smoothly there.
458
- clipBehavior: Clip .none,
459
- style: TextStyle (
460
- fontSize: _fontSize,
461
- height: _lineHeightRatio,
462
- color: designVariables.textInput),
463
- // From the spec at
464
- // https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=3960-5147&node-type=text&m=dev
465
- // > Compose box has the height to fit 2 lines. This is [done] to
466
- // > have a bigger hit area for the user to start the input. […]
467
- minLines: 2 ,
468
- maxLines: null ,
469
- textCapitalization: TextCapitalization .sentences,
470
- decoration: InputDecoration (
471
- // This padding ensures that the user can always scroll long
472
- // content entirely out of the top or bottom shadow if desired.
473
- // With this and the `minLines: 2` above, an empty content input
474
- // gets 60px vertical distance (with no text-size scaling)
475
- // between the top of the top shadow and the bottom of the
476
- // bottom shadow. That's a bit more than the 54px given in the
477
- // Figma, and we can revisit if needed, but it's tricky to get
478
- // that 54px distance while also making the scrolling work like
479
- // this and offering two lines of touchable area.
480
- contentPadding: const EdgeInsets .symmetric (vertical: _verticalPadding),
481
- hintText: widget.hintText,
482
- hintStyle: TextStyle (
483
- color: designVariables.textInput.withFadedAlpha (0.5 ))))))));
484
- }
485
- }
486
-
487
397
class _TypingNotifier extends StatefulWidget {
488
398
const _TypingNotifier ({
489
399
required this .destination,
@@ -576,6 +486,96 @@ class _TypingNotifierState extends State<_TypingNotifier> with WidgetsBindingObs
576
486
Widget build (BuildContext context) => widget.child;
577
487
}
578
488
489
+ class _ContentInput extends StatefulWidget {
490
+ const _ContentInput ({
491
+ required this .narrow,
492
+ required this .controller,
493
+ required this .hintText,
494
+ });
495
+
496
+ final Narrow narrow;
497
+ final ComposeBoxController controller;
498
+ final String hintText;
499
+
500
+ @override
501
+ State <StatefulWidget > createState () => _ContentInputState ();
502
+ }
503
+
504
+ class _ContentInputState <T extends _ContentInput > extends State <T > {
505
+ static double maxHeight (BuildContext context) {
506
+ final clampingTextScaler = MediaQuery .textScalerOf (context)
507
+ .clamp (maxScaleFactor: 1.5 );
508
+ final scaledLineHeight = clampingTextScaler.scale (_fontSize) * _lineHeightRatio;
509
+
510
+ // Reserve space to fully show the first 7th lines and just partially
511
+ // clip the 8th line, where the height matches the spec at
512
+ // https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=3960-5147&node-type=text&m=dev
513
+ // > Maximum size of the compose box is suggested to be 178px. Which
514
+ // > has 7 fully visible lines of text
515
+ //
516
+ // The partial line hints that the content input is scrollable.
517
+ //
518
+ // Using the ambient TextScale means this works for different values of the
519
+ // system text-size setting. We clamp to a max scale factor to limit
520
+ // how tall the content input can get; that's to save room for the message
521
+ // list. The user can still scroll the input to see everything.
522
+ return _verticalPadding + 7.727 * scaledLineHeight;
523
+ }
524
+
525
+ static const _verticalPadding = 8.0 ;
526
+ static const _fontSize = 17.0 ;
527
+ static const _lineHeight = 22.0 ;
528
+ static const _lineHeightRatio = _lineHeight / _fontSize;
529
+
530
+ @override
531
+ Widget build (BuildContext context) {
532
+ final designVariables = DesignVariables .of (context);
533
+
534
+ return ComposeAutocomplete (
535
+ narrow: widget.narrow,
536
+ controller: widget.controller.content,
537
+ focusNode: widget.controller.contentFocusNode,
538
+ fieldViewBuilder: (context) => ConstrainedBox (
539
+ constraints: BoxConstraints (maxHeight: maxHeight (context)),
540
+ // This [ClipRect] replaces the [TextField] clipping we disable below.
541
+ child: ClipRect (
542
+ child: InsetShadowBox (
543
+ top: _verticalPadding, bottom: _verticalPadding,
544
+ color: designVariables.composeBoxBg,
545
+ child: TextField (
546
+ controller: widget.controller.content,
547
+ focusNode: widget.controller.contentFocusNode,
548
+ // Let the content show through the `contentPadding` so that
549
+ // our [InsetShadowBox] can fade it smoothly there.
550
+ clipBehavior: Clip .none,
551
+ style: TextStyle (
552
+ fontSize: _fontSize,
553
+ height: _lineHeightRatio,
554
+ color: designVariables.textInput),
555
+ // From the spec at
556
+ // https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=3960-5147&node-type=text&m=dev
557
+ // > Compose box has the height to fit 2 lines. This is [done] to
558
+ // > have a bigger hit area for the user to start the input. […]
559
+ minLines: 2 ,
560
+ maxLines: null ,
561
+ textCapitalization: TextCapitalization .sentences,
562
+ decoration: InputDecoration (
563
+ // This padding ensures that the user can always scroll long
564
+ // content entirely out of the top or bottom shadow if desired.
565
+ // With this and the `minLines: 2` above, an empty content input
566
+ // gets 60px vertical distance (with no text-size scaling)
567
+ // between the top of the top shadow and the bottom of the
568
+ // bottom shadow. That's a bit more than the 54px given in the
569
+ // Figma, and we can revisit if needed, but it's tricky to get
570
+ // that 54px distance while also making the scrolling work like
571
+ // this and offering two lines of touchable area.
572
+ contentPadding: const EdgeInsets .symmetric (vertical: _verticalPadding),
573
+ hintText: widget.hintText,
574
+ hintStyle: TextStyle (
575
+ color: designVariables.textInput.withFadedAlpha (0.5 ))))))));
576
+ }
577
+ }
578
+
579
579
/// The content input for _StreamComposeBox.
580
580
class _StreamContentInput extends StatefulWidget {
581
581
const _StreamContentInput ({required this .narrow, required this .controller});
0 commit comments