Skip to content

Commit af36660

Browse files
committed
compose: Prepare some leafward widgets to support a disabled state
In the upcoming edit-message feature, the edit-message compose box will have a "Preparing..." state after you tap "Edit message" in the action sheet, while we're fetching the raw message content. The edit-message compose box shouldn't be interactable in this state.
1 parent ec811ee commit af36660

File tree

1 file changed

+54
-10
lines changed

1 file changed

+54
-10
lines changed

lib/widgets/compose_box.dart

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -493,11 +493,13 @@ class _ContentInput extends StatelessWidget {
493493
required this.narrow,
494494
required this.controller,
495495
required this.hintText,
496+
this.enabled = true, // ignore: unused_element_parameter
496497
});
497498

498499
final Narrow narrow;
499500
final ComposeBoxController controller;
500501
final String hintText;
502+
final bool enabled;
501503

502504
static double maxHeight(BuildContext context) {
503505
final clampingTextScaler = MediaQuery.textScalerOf(context)
@@ -540,6 +542,7 @@ class _ContentInput extends StatelessWidget {
540542
top: _verticalPadding, bottom: _verticalPadding,
541543
color: designVariables.composeBoxBg,
542544
child: TextField(
545+
enabled: enabled,
543546
controller: controller.content,
544547
focusNode: controller.contentFocusNode,
545548
// Let the content show through the `contentPadding` so that
@@ -957,9 +960,10 @@ Future<void> _uploadFiles({
957960
}
958961

959962
abstract class _AttachUploadsButton extends StatelessWidget {
960-
const _AttachUploadsButton({required this.controller});
963+
const _AttachUploadsButton({required this.controller, required this.enabled});
961964

962965
final ComposeBoxController controller;
966+
final bool enabled;
963967

964968
IconData get icon;
965969
String tooltip(ZulipLocalizations zulipLocalizations);
@@ -1001,7 +1005,7 @@ abstract class _AttachUploadsButton extends StatelessWidget {
10011005
child: IconButton(
10021006
icon: Icon(icon, color: designVariables.foreground.withFadedAlpha(0.5)),
10031007
tooltip: tooltip(zulipLocalizations),
1004-
onPressed: () => _handlePress(context)));
1008+
onPressed: enabled ? () => _handlePress(context) : null));
10051009
}
10061010
}
10071011

@@ -1060,7 +1064,7 @@ Future<Iterable<_File>> _getFilePickerFiles(BuildContext context, FileType type)
10601064
}
10611065

10621066
class _AttachFileButton extends _AttachUploadsButton {
1063-
const _AttachFileButton({required super.controller});
1067+
const _AttachFileButton({required super.controller, required super.enabled});
10641068

10651069
@override
10661070
IconData get icon => ZulipIcons.attach_file;
@@ -1076,7 +1080,7 @@ class _AttachFileButton extends _AttachUploadsButton {
10761080
}
10771081

10781082
class _AttachMediaButton extends _AttachUploadsButton {
1079-
const _AttachMediaButton({required super.controller});
1083+
const _AttachMediaButton({required super.controller, required super.enabled});
10801084

10811085
@override
10821086
IconData get icon => ZulipIcons.image;
@@ -1093,7 +1097,7 @@ class _AttachMediaButton extends _AttachUploadsButton {
10931097
}
10941098

10951099
class _AttachFromCameraButton extends _AttachUploadsButton {
1096-
const _AttachFromCameraButton({required super.controller});
1100+
const _AttachFromCameraButton({required super.controller, required super.enabled});
10971101

10981102
@override
10991103
IconData get icon => ZulipIcons.camera;
@@ -1370,6 +1374,7 @@ abstract class _ComposeBoxBody extends StatelessWidget {
13701374

13711375
Widget? buildTopicInput();
13721376
Widget buildContentInput();
1377+
bool getComposeButtonsEnabled(BuildContext context);
13731378
Widget buildSendButton();
13741379

13751380
@override
@@ -1396,10 +1401,11 @@ abstract class _ComposeBoxBody extends StatelessWidget {
13961401
shape: const RoundedRectangleBorder(
13971402
borderRadius: BorderRadius.all(Radius.circular(4)))));
13981403

1404+
final composeButtonsEnabled = getComposeButtonsEnabled(context);
13991405
final composeButtons = [
1400-
_AttachFileButton(controller: controller),
1401-
_AttachMediaButton(controller: controller),
1402-
_AttachFromCameraButton(controller: controller),
1406+
_AttachFileButton(controller: controller, enabled: composeButtonsEnabled),
1407+
_AttachMediaButton(controller: controller, enabled: composeButtonsEnabled),
1408+
_AttachFromCameraButton(controller: controller, enabled: composeButtonsEnabled),
14031409
];
14041410

14051411
final topicInput = buildTopicInput();
@@ -1449,6 +1455,8 @@ class _StreamComposeBoxBody extends _ComposeBoxBody {
14491455
controller: controller,
14501456
);
14511457

1458+
@override bool getComposeButtonsEnabled(BuildContext context) => true;
1459+
14521460
@override Widget buildSendButton() => _SendButton(
14531461
controller: controller,
14541462
getDestination: () => StreamDestination(
@@ -1472,6 +1480,8 @@ class _FixedDestinationComposeBoxBody extends _ComposeBoxBody {
14721480
controller: controller,
14731481
);
14741482

1483+
@override bool getComposeButtonsEnabled(BuildContext context) => true;
1484+
14751485
@override Widget buildSendButton() => _SendButton(
14761486
controller: controller,
14771487
getDestination: () => narrow.destination,
@@ -1756,7 +1766,8 @@ class _ComposeBoxState extends State<ComposeBox> with PerAccountStoreAwareStateM
17561766

17571767
final errorBanner = _errorBannerComposingNotAllowed(context);
17581768
if (errorBanner != null) {
1759-
return _ComposeBoxContainer(body: null, banner: errorBanner);
1769+
return ComposeBoxInheritedWidget.fromComposeBoxState(this,
1770+
child: _ComposeBoxContainer(body: null, banner: errorBanner));
17601771
}
17611772

17621773
final controller = this.controller;
@@ -1777,6 +1788,39 @@ class _ComposeBoxState extends State<ComposeBox> with PerAccountStoreAwareStateM
17771788
// errorBanner = _ErrorBanner(label:
17781789
// ZulipLocalizations.of(context).errorSendMessageTimeout);
17791790
// }
1780-
return _ComposeBoxContainer(body: body, banner: null);
1791+
return ComposeBoxInheritedWidget.fromComposeBoxState(this,
1792+
child: _ComposeBoxContainer(body: body, banner: null));
1793+
}
1794+
}
1795+
1796+
/// An [InheritedWidget] to provide data to leafward [StatelessWidget]s,
1797+
/// such as flags that should cause the upload buttons to be disabled.
1798+
class ComposeBoxInheritedWidget extends InheritedWidget {
1799+
factory ComposeBoxInheritedWidget.fromComposeBoxState(
1800+
ComposeBoxState state, {
1801+
required Widget child,
1802+
}) {
1803+
return ComposeBoxInheritedWidget._(
1804+
// TODO add fields
1805+
child: child,
1806+
);
1807+
}
1808+
1809+
const ComposeBoxInheritedWidget._({
1810+
// TODO add fields
1811+
required super.child,
1812+
});
1813+
1814+
// TODO add fields
1815+
1816+
@override
1817+
bool updateShouldNotify(covariant ComposeBoxInheritedWidget oldWidget) =>
1818+
// TODO compare fields
1819+
false;
1820+
1821+
static ComposeBoxInheritedWidget of(BuildContext context) {
1822+
final widget = context.dependOnInheritedWidgetOfExactType<ComposeBoxInheritedWidget>();
1823+
assert(widget != null, 'No ComposeBoxInheritedWidget ancestor');
1824+
return widget!;
17811825
}
17821826
}

0 commit comments

Comments
 (0)