@@ -271,16 +271,19 @@ class _ContentInput extends StatelessWidget {
271
271
required this .controller,
272
272
required this .focusNode,
273
273
required this .hintText,
274
+ this .enabled = true ,
274
275
});
275
276
276
277
final Narrow narrow;
277
278
final ComposeContentController controller;
278
279
final FocusNode focusNode;
279
280
final String hintText;
281
+ final bool enabled;
280
282
281
283
@override
282
284
Widget build (BuildContext context) {
283
285
ColorScheme colorScheme = Theme .of (context).colorScheme;
286
+ if (! enabled) controller.clear ();
284
287
285
288
return InputDecorator (
286
289
decoration: const InputDecoration (),
@@ -303,6 +306,7 @@ class _ContentInput extends StatelessWidget {
303
306
decoration: InputDecoration .collapsed (hintText: hintText),
304
307
maxLines: null ,
305
308
textCapitalization: TextCapitalization .sentences,
309
+ enabled: enabled,
306
310
);
307
311
}),
308
312
));
@@ -377,31 +381,36 @@ class _FixedDestinationContentInput extends StatelessWidget {
377
381
required this .narrow,
378
382
required this .controller,
379
383
required this .focusNode,
384
+ required this .enabled,
380
385
});
381
386
382
387
final SendableNarrow narrow;
383
388
final ComposeContentController controller;
384
389
final FocusNode focusNode;
390
+ final bool enabled;
385
391
386
392
String _hintText (BuildContext context) {
387
393
final zulipLocalizations = ZulipLocalizations .of (context);
388
- switch (narrow) {
389
- case TopicNarrow (: final streamId, : final topic):
394
+ switch (( narrow, enabled) ) {
395
+ case ( TopicNarrow (: final streamId, : final topic), _ ):
390
396
final store = PerAccountStoreWidget .of (context);
391
397
final streamName = store.streams[streamId]? .name
392
398
?? zulipLocalizations.composeBoxUnknownChannelName;
393
399
return zulipLocalizations.composeBoxChannelContentHint (streamName, topic);
394
400
395
- case DmNarrow (otherRecipientIds: []): // The self-1:1 thread.
401
+ case ( DmNarrow (otherRecipientIds: []), _ ): // The self-1:1 thread.
396
402
return zulipLocalizations.composeBoxSelfDmContentHint;
397
403
398
- case DmNarrow (otherRecipientIds: [final otherUserId]):
404
+ case ( DmNarrow (otherRecipientIds: [final otherUserId]), true ):
399
405
final store = PerAccountStoreWidget .of (context);
400
406
final fullName = store.users[otherUserId]? .fullName;
401
407
if (fullName == null ) return zulipLocalizations.composeBoxGenericContentHint;
402
408
return zulipLocalizations.composeBoxDmContentHint (fullName);
403
409
404
- case DmNarrow (): // A group DM thread.
410
+ case (DmNarrow (: final otherRecipientIds), false ):
411
+ return zulipLocalizations.composeBoxDeactivatedDmContentHint (otherRecipientIds.length);
412
+
413
+ case (DmNarrow (), true ): // A group DM thread.
405
414
return zulipLocalizations.composeBoxGroupDmContentHint;
406
415
}
407
416
}
@@ -412,7 +421,8 @@ class _FixedDestinationContentInput extends StatelessWidget {
412
421
narrow: narrow,
413
422
controller: controller,
414
423
focusNode: focusNode,
415
- hintText: _hintText (context));
424
+ hintText: _hintText (context),
425
+ enabled: enabled);
416
426
}
417
427
}
418
428
@@ -492,10 +502,15 @@ Future<void> _uploadFiles({
492
502
}
493
503
494
504
abstract class _AttachUploadsButton extends StatelessWidget {
495
- const _AttachUploadsButton ({required this .contentController, required this .contentFocusNode});
505
+ const _AttachUploadsButton ({
506
+ required this .contentController,
507
+ required this .contentFocusNode,
508
+ required this .enabled,
509
+ });
496
510
497
511
final ComposeContentController contentController;
498
512
final FocusNode contentFocusNode;
513
+ final bool enabled;
499
514
500
515
IconData get icon;
501
516
String tooltip (ZulipLocalizations zulipLocalizations);
@@ -534,7 +549,7 @@ abstract class _AttachUploadsButton extends StatelessWidget {
534
549
return IconButton (
535
550
icon: Icon (icon),
536
551
tooltip: tooltip (zulipLocalizations),
537
- onPressed: () => _handlePress (context));
552
+ onPressed: enabled ? () => _handlePress (context) : null );
538
553
}
539
554
}
540
555
@@ -578,7 +593,11 @@ Future<Iterable<_File>> _getFilePickerFiles(BuildContext context, FileType type)
578
593
}
579
594
580
595
class _AttachFileButton extends _AttachUploadsButton {
581
- const _AttachFileButton ({required super .contentController, required super .contentFocusNode});
596
+ const _AttachFileButton ({
597
+ required super .contentController,
598
+ required super .contentFocusNode,
599
+ required super .enabled,
600
+ });
582
601
583
602
@override
584
603
IconData get icon => Icons .attach_file;
@@ -594,7 +613,11 @@ class _AttachFileButton extends _AttachUploadsButton {
594
613
}
595
614
596
615
class _AttachMediaButton extends _AttachUploadsButton {
597
- const _AttachMediaButton ({required super .contentController, required super .contentFocusNode});
616
+ const _AttachMediaButton ({
617
+ required super .contentController,
618
+ required super .contentFocusNode,
619
+ required super .enabled,
620
+ });
598
621
599
622
@override
600
623
IconData get icon => Icons .image;
@@ -611,7 +634,11 @@ class _AttachMediaButton extends _AttachUploadsButton {
611
634
}
612
635
613
636
class _AttachFromCameraButton extends _AttachUploadsButton {
614
- const _AttachFromCameraButton ({required super .contentController, required super .contentFocusNode});
637
+ const _AttachFromCameraButton ({
638
+ required super .contentController,
639
+ required super .contentFocusNode,
640
+ required super .enabled,
641
+ });
615
642
616
643
@override
617
644
IconData get icon => Icons .camera_alt;
@@ -667,11 +694,13 @@ class _SendButton extends StatefulWidget {
667
694
required this .topicController,
668
695
required this .contentController,
669
696
required this .getDestination,
697
+ this .enabled = true ,
670
698
});
671
699
672
700
final ComposeTopicController ? topicController;
673
701
final ComposeContentController contentController;
674
702
final MessageDestination Function () getDestination;
703
+ final bool enabled;
675
704
676
705
@override
677
706
State <_SendButton > createState () => _SendButtonState ();
@@ -776,7 +805,7 @@ class _SendButtonState extends State<_SendButton> {
776
805
),
777
806
color: foregroundColor,
778
807
icon: const Icon (Icons .send),
779
- onPressed: _send));
808
+ onPressed: widget.enabled ? _send : null ));
780
809
}
781
810
}
782
811
@@ -787,13 +816,15 @@ class _ComposeBoxLayout extends StatelessWidget {
787
816
required this .sendButton,
788
817
required this .contentController,
789
818
required this .contentFocusNode,
819
+ this .enabled = true ,
790
820
});
791
821
792
822
final Widget ? topicInput;
793
823
final Widget contentInput;
794
824
final Widget sendButton;
795
825
final ComposeContentController contentController;
796
826
final FocusNode contentFocusNode;
827
+ final bool enabled;
797
828
798
829
@override
799
830
Widget build (BuildContext context) {
@@ -837,9 +868,21 @@ class _ComposeBoxLayout extends StatelessWidget {
837
868
data: themeData.copyWith (
838
869
iconTheme: themeData.iconTheme.copyWith (color: colorScheme.onSurfaceVariant)),
839
870
child: Row (children: [
840
- _AttachFileButton (contentController: contentController, contentFocusNode: contentFocusNode),
841
- _AttachMediaButton (contentController: contentController, contentFocusNode: contentFocusNode),
842
- _AttachFromCameraButton (contentController: contentController, contentFocusNode: contentFocusNode),
871
+ _AttachFileButton (
872
+ contentController: contentController,
873
+ contentFocusNode: contentFocusNode,
874
+ enabled: enabled,
875
+ ),
876
+ _AttachMediaButton (
877
+ contentController: contentController,
878
+ contentFocusNode: contentFocusNode,
879
+ enabled: enabled,
880
+ ),
881
+ _AttachFromCameraButton (
882
+ contentController: contentController,
883
+ contentFocusNode: contentFocusNode,
884
+ enabled: enabled,
885
+ ),
843
886
])),
844
887
])))); }
845
888
}
@@ -937,19 +980,28 @@ class _FixedDestinationComposeBoxState extends State<_FixedDestinationComposeBox
937
980
938
981
@override
939
982
Widget build (BuildContext context) {
983
+ final store = PerAccountStoreWidget .of (context);
984
+ final bool enabled = switch (widget.narrow) {
985
+ DmNarrow (: final otherRecipientIds) => otherRecipientIds.every ((id) =>
986
+ store.users[id]? .isActive ?? true ),
987
+ TopicNarrow () => true ,
988
+ };
940
989
return _ComposeBoxLayout (
941
990
contentController: _contentController,
942
991
contentFocusNode: _contentFocusNode,
943
992
topicInput: null ,
993
+ enabled: enabled,
944
994
contentInput: _FixedDestinationContentInput (
945
995
narrow: widget.narrow,
946
996
controller: _contentController,
947
997
focusNode: _contentFocusNode,
998
+ enabled: enabled,
948
999
),
949
1000
sendButton: _SendButton (
950
1001
topicController: null ,
951
1002
contentController: _contentController,
952
1003
getDestination: () => widget.narrow.destination,
1004
+ enabled: enabled,
953
1005
));
954
1006
}
955
1007
}
0 commit comments