Skip to content

Commit 6312da6

Browse files
committed
Payload is now optional when calling from Javascript. Renamed bottom modal to bottom sheet
1 parent 7121674 commit 6312da6

File tree

4 files changed

+42
-40
lines changed

4 files changed

+42
-40
lines changed

lib/action/action_invokable.dart

+6-1
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,23 @@ abstract class ActionInvokable with Invokable {
2424
ActionType.getPhoneContactPhoto,
2525
ActionType.showBottomModal,
2626
ActionType.dismissBottomModal,
27+
ActionType.showBottomSheet,
28+
ActionType.dismissBottomSheet,
2729
ActionType.showDialog,
2830
ActionType.navigateViewGroup,
31+
ActionType.showToast,
2932
]);
3033
}
3134

3235
Map<String, Function> _generateFromActionTypes(List<ActionType> actionTypes) {
3336
Map<String, Function> functions = {};
3437
for (ActionType actionType in actionTypes) {
35-
functions[actionType.name] = (payload) {
38+
functions[actionType.name] = ([dynamic payload]) {
39+
// payload is optional but must be a Map if specified
3640
if (payload != null && payload is! Map) {
3741
throw LanguageError("${actionType.name} has an invalid payload.");
3842
}
43+
3944
EnsembleAction? action =
4045
EnsembleAction.fromActionType(actionType, payload: payload);
4146
return action?.execute(buildContext, _getScopeManager(buildContext));

lib/action/bottom_modal_actions.dart renamed to lib/action/bottom_sheet_actions.dart

+24-21
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import 'package:ensemble_ts_interpreter/invokables/invokable.dart';
1111
import 'package:flutter/material.dart';
1212

1313
/// open a Modal Bottom Sheet
14-
class ShowBottomModalAction extends EnsembleAction {
15-
ShowBottomModalAction({
14+
class ShowBottomSheetAction extends EnsembleAction {
15+
ShowBottomSheetAction({
1616
super.initiator,
1717
super.inputs,
1818
required this.body,
@@ -26,13 +26,13 @@ class ShowBottomModalAction extends EnsembleAction {
2626
final dynamic body;
2727
final EnsembleAction? onDismiss;
2828

29-
factory ShowBottomModalAction.from({Invokable? initiator, Map? payload}) {
29+
factory ShowBottomSheetAction.from({Invokable? initiator, Map? payload}) {
3030
dynamic body = payload?['body'] ?? payload?['widget'];
3131
if (payload == null || body == null) {
3232
throw LanguageError(
33-
"${ActionType.showBottomModal.name} requires a body widget.");
33+
"${ActionType.showBottomSheet.name} requires a body widget.");
3434
}
35-
return ShowBottomModalAction(
35+
return ShowBottomSheetAction(
3636
initiator: initiator,
3737
inputs: Utils.getMap(payload['inputs']),
3838
body: body,
@@ -104,7 +104,7 @@ class ShowBottomModalAction extends EnsembleAction {
104104
bottom: MediaQuery.of(modalContext).viewInsets.bottom,
105105
),
106106
// have a bottom modal scope widget so we can close the modal
107-
child: BottomModalScopeWidget(
107+
child: BottomSheetScopeWidget(
108108
rootContext: modalContext,
109109
// create a new Data Scope since the bottom modal is placed in a different context tree (directly under MaterialApp)
110110
child: DataScopeWidget(
@@ -139,6 +139,9 @@ class ShowBottomModalAction extends EnsembleAction {
139139
initialViewport = (minViewport + maxViewport) / 2.0;
140140
}
141141

142+
// On platforms with a mouse (Web/desktop), there is no min/maxViewport due to platform consistency,
143+
// so the height will be fixed to initialViewport, and content will just scroll within it.
144+
// https://docs.flutter.dev/release/breaking-changes/default-scroll-behavior-drag
142145
return DraggableScrollableSheet(
143146
expand: false,
144147
minChildSize: minViewport,
@@ -168,8 +171,8 @@ class ShowBottomModalAction extends EnsembleAction {
168171
topLeft: defaultTopBorderRadius,
169172
topRight: defaultTopBorderRadius)),
170173
clipBehavior: Clip.antiAlias,
174+
// stretch width 100%. Note that Flutter's bottom sheet has a width constraint on Web/Desktop so it may not take 100% on wide screen
171175
width: double.infinity,
172-
// stretch width 100%
173176
child: useSafeArea(scopeManager) ? SafeArea(child: child) : child);
174177
if (showDragHandle(scopeManager)) {
175178
rootWidget = Stack(
@@ -194,43 +197,43 @@ class ShowBottomModalAction extends EnsembleAction {
194197
}
195198

196199
/// Dismiss the Bottom Modal (if the context is a descendant, no-op otherwise)
197-
class DismissBottomModalAction extends EnsembleAction {
198-
DismissBottomModalAction({this.payload});
200+
class DismissBottomSheetAction extends EnsembleAction {
201+
DismissBottomSheetAction({this.payload});
199202

200203
Map? payload;
201204

202-
factory DismissBottomModalAction.from({Map? payload}) =>
203-
DismissBottomModalAction(payload: payload?['payload']);
205+
factory DismissBottomSheetAction.from({Map? payload}) =>
206+
DismissBottomSheetAction(payload: payload?['payload']);
204207

205208
@override
206209
Future<dynamic> execute(BuildContext context, ScopeManager scopeManager,
207210
{DataContext? dataContext}) {
208-
BuildContext? bottomModalContext =
209-
BottomModalScopeWidget.getRootContext(context);
210-
if (bottomModalContext != null) {
211+
BuildContext? bottomSheetContext =
212+
BottomSheetScopeWidget.getRootContext(context);
213+
if (bottomSheetContext != null) {
211214
return Navigator.maybePop(
212-
bottomModalContext, scopeManager.dataContext.eval(payload));
215+
bottomSheetContext, scopeManager.dataContext.eval(payload));
213216
}
214217
return Navigator.maybePop(context, scopeManager.dataContext.eval(payload));
215218
}
216219
}
217220

218-
/// a wrapper InheritedWidget for its descendant to look up the root modal context to close it
219-
class BottomModalScopeWidget extends InheritedWidget {
220-
const BottomModalScopeWidget(
221+
/// a wrapper InheritedWidget for its descendant to look up the Sheet's root context to close it
222+
class BottomSheetScopeWidget extends InheritedWidget {
223+
const BottomSheetScopeWidget(
221224
{super.key, required super.child, required this.rootContext});
222225

223226
// this is the context root of the modal
224227
final BuildContext rootContext;
225228

226229
@override
227-
bool updateShouldNotify(covariant BottomModalScopeWidget oldWidget) {
230+
bool updateShouldNotify(covariant BottomSheetScopeWidget oldWidget) {
228231
return oldWidget.rootContext != rootContext;
229232
}
230233

231234
static BuildContext? getRootContext(BuildContext context) {
232-
BottomModalScopeWidget? wrapperWidget =
233-
context.dependOnInheritedWidgetOfExactType<BottomModalScopeWidget>();
235+
BottomSheetScopeWidget? wrapperWidget =
236+
context.dependOnInheritedWidgetOfExactType<BottomSheetScopeWidget>();
234237
return wrapperWidget?.rootContext;
235238
}
236239
}

lib/framework/action.dart

+11-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import 'package:app_settings/app_settings.dart';
22
import 'package:ensemble/action/audio_player.dart';
33
import 'package:ensemble/action/Log_event_action.dart';
44
import 'package:ensemble/action/badge_action.dart';
5-
import 'package:ensemble/action/bottom_modal_actions.dart';
5+
import 'package:ensemble/action/bottom_sheet_actions.dart';
66
import 'package:ensemble/action/deep_link_action.dart';
77
import 'package:ensemble/action/call_external_method.dart';
88
import 'package:ensemble/action/haptic_action.dart';
@@ -1085,7 +1085,11 @@ enum ActionType {
10851085
navigateViewGroup,
10861086
navigateExternalScreen,
10871087
navigateModalScreen,
1088+
showBottomSheet,
1089+
dismissBottomSheet,
1090+
@Deprecated("use showBottomSheet")
10881091
showBottomModal,
1092+
@Deprecated("use dismissBottomSheet")
10891093
dismissBottomModal,
10901094
showDialog,
10911095
startTimer,
@@ -1202,10 +1206,12 @@ abstract class EnsembleAction {
12021206
initiator: initiator, payload: payload);
12031207
} else if (actionType == ActionType.navigateBack) {
12041208
return NavigateBackAction.from(payload: payload);
1205-
} else if (actionType == ActionType.showBottomModal) {
1206-
return ShowBottomModalAction.from(payload: payload);
1207-
} else if (actionType == ActionType.dismissBottomModal) {
1208-
return DismissBottomModalAction.from(payload: payload);
1209+
} else if (actionType == ActionType.showBottomSheet ||
1210+
actionType == ActionType.showBottomModal) {
1211+
return ShowBottomSheetAction.from(payload: payload);
1212+
} else if (actionType == ActionType.dismissBottomSheet ||
1213+
actionType == ActionType.dismissBottomModal) {
1214+
return DismissBottomSheetAction.from(payload: payload);
12091215
} else if (actionType == ActionType.invokeAPI) {
12101216
return InvokeAPIAction.fromYaml(initiator: initiator, payload: payload);
12111217
} else if (actionType == ActionType.openCamera) {

lib/framework/data_context.dart

+1-13
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import 'dart:ui';
55
import 'package:ensemble/action/Log_event_action.dart';
66
import 'package:ensemble/action/action_invokable.dart';
77
import 'package:ensemble/action/audio_player.dart';
8-
import 'package:ensemble/action/bottom_modal_actions.dart';
8+
import 'package:ensemble/action/bottom_sheet_actions.dart';
99
import 'package:ensemble/action/haptic_action.dart';
1010
import 'package:ensemble/action/invoke_api_action.dart';
1111
import 'package:ensemble/action/misc_action.dart';
@@ -473,8 +473,6 @@ class NativeInvokable extends ActionInvokable {
473473
ActionType.stopTimer.name: stopTimer,
474474
ActionType.openCamera.name: showCamera,
475475
ActionType.navigateBack.name: navigateBack,
476-
ActionType.showToast.name: (inputs) => ScreenController()
477-
.executeAction(buildContext, ShowToastAction.fromMap(inputs)),
478476
ActionType.startTimer.name: (inputs) => ScreenController()
479477
.executeAction(buildContext, StartTimerAction.fromMap(inputs)),
480478
ActionType.uploadFiles.name: uploadFiles,
@@ -503,16 +501,6 @@ class NativeInvokable extends ActionInvokable {
503501
final scope = ScreenController().getScopeManager(buildContext);
504502
callNativeMethod(buildContext, scope, inputs);
505503
},
506-
ActionType.showBottomModal.name: (inputs) =>
507-
ScreenController().executeAction(
508-
buildContext,
509-
ShowBottomModalAction.from(payload: inputs),
510-
),
511-
ActionType.dismissBottomModal.name: (inputs) =>
512-
ScreenController().executeAction(
513-
buildContext,
514-
DismissBottomModalAction.from(payload: inputs),
515-
),
516504
ActionType.showDialog.name: (inputs) => ScreenController()
517505
.executeAction(buildContext, ShowDialogAction.from(payload: inputs)),
518506
ActionType.rateApp.name: (inputs) => ScreenController()

0 commit comments

Comments
 (0)