Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions modules/ensemble/lib/action/bottom_sheet_actions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class ShowBottomSheetAction extends EnsembleAction {
required this.body,
required this.payload,
this.onDismiss,
this.useRoot = true,
});

static const defaultTopBorderRadius = Radius.circular(16);
Expand All @@ -30,6 +31,7 @@ class ShowBottomSheetAction extends EnsembleAction {
final Map payload;
final dynamic body;
final EnsembleAction? onDismiss;
final bool useRoot;

factory ShowBottomSheetAction.from({Invokable? initiator, Map? payload}) {
dynamic body = payload?['body'] ?? payload?['widget'];
Expand All @@ -42,6 +44,7 @@ class ShowBottomSheetAction extends EnsembleAction {
inputs: Utils.getMap(payload['inputs']),
body: body,
onDismiss: EnsembleAction.from(payload['onDismiss']),
useRoot: Utils.getBool(payload['useRoot'], fallback: true),
payload: payload);
}

Expand Down Expand Up @@ -103,6 +106,7 @@ class ShowBottomSheetAction extends EnsembleAction {
if (body != null) {
final body = getBodyWidget(scopeManager, context);
showModalBottomSheet(
useRootNavigator: useRoot,
context: context,
// disable the default bottom sheet styling since we use our own
backgroundColor: Colors.transparent,
Expand Down
54 changes: 51 additions & 3 deletions modules/ensemble/lib/action/dialog_actions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import 'package:ensemble/framework/data_context.dart';
import 'package:ensemble/framework/error_handling.dart';
import 'package:ensemble/framework/event.dart';
import 'package:ensemble/framework/scope.dart';
import 'package:ensemble/framework/view/bottom_nav_page_group.dart';
import 'package:ensemble/framework/view/data_scope_widget.dart';
import 'package:ensemble/framework/view/page_group.dart';
import 'package:ensemble/screen_controller.dart';
import 'package:ensemble/util/ensemble_utils.dart';
import 'package:ensemble/util/utils.dart';
Expand All @@ -21,11 +23,13 @@ class ShowDialogAction extends EnsembleAction {
required this.dismissible,
this.options,
this.onDialogDismiss,
this.useRoot = true,
});

final dynamic body;
final bool dismissible;
final Map<String, dynamic>? options;
final bool useRoot;
final EnsembleAction? onDialogDismiss;

factory ShowDialogAction.from({Invokable? initiator, Map? payload}) {
Expand All @@ -40,6 +44,7 @@ class ShowDialogAction extends EnsembleAction {
Utils.maybeYamlMap(payload['widget']),
options: Utils.getMap(payload['options']),
dismissible: Utils.getBool(payload['dismissible'], fallback: true),
useRoot: Utils.getBool(payload['useRoot'], fallback: true),
onDialogDismiss: payload['onDialogDismiss'] == null
? null
: EnsembleAction.from(Utils.maybeYamlMap(payload['onDialogDismiss'])),
Expand All @@ -57,8 +62,11 @@ class ShowDialogAction extends EnsembleAction {
bool useDefaultStyle = dialogStyles['style'] != 'none';
BuildContext? dialogContext;

// Store the current tab observer provider for resubscription
final tabObserverProvider = TabRouteObserverProvider.of(context);

showGeneralDialog(
useRootNavigator: false,
useRootNavigator: useRoot, // use root navigator if specified
// use inner-most MaterialApp (our App) as root so theming is ours
context: context,
barrierDismissible: dismissible,
Expand All @@ -71,7 +79,8 @@ class ShowDialogAction extends EnsembleAction {
dialogContext = context;
scopeManager.openedDialogs.add(dialogContext!);

return Align(
// Wrap the dialog content with TabRouteObserverProvider to maintain tab context
Widget dialogWidget = Align(
alignment: Alignment(
Utils.getDouble(dialogStyles['horizontalOffset'],
min: -1, max: 1, fallback: 0),
Expand Down Expand Up @@ -113,6 +122,17 @@ class ShowDialogAction extends EnsembleAction {
child: scopeManager
.buildWidgetFromDefinition(body),
))))));

// If we have a tab observer provider, wrap the dialog to maintain tab context
if (tabObserverProvider != null) {
return TabRouteObserverProvider(
routeObserver: tabObserverProvider.routeObserver,
tabIndex: tabObserverProvider.tabIndex,
child: dialogWidget,
);
}

return dialogWidget;
}).then((payload) {
// remove the dialog context since we are closing them
scopeManager.openedDialogs.remove(dialogContext);
Expand All @@ -123,9 +143,37 @@ class ShowDialogAction extends EnsembleAction {
context, scopeManager, onDialogDismiss!,
event: EnsembleEvent(initiator, data: payload));
}

// Trigger resubscription to bottom nav navigator when dialog closes
_resubscribeToBottomNavNavigator(context, tabObserverProvider);
});
return Future.value(null);
}

// Helper method to resubscribe to bottom nav navigator after dialog closes
void _resubscribeToBottomNavNavigator(
BuildContext context, TabRouteObserverProvider? tabObserverProvider) {
if (tabObserverProvider != null) {
// Schedule the resubscription for the next frame to ensure the dialog is fully closed
WidgetsBinding.instance.addPostFrameCallback((_) {
try {
// Use the viewGroupNotifier's updatePage method to trigger a refresh
// This maintains the current page but forces a rebuild
int currentIndex = viewGroupNotifier.viewIndex;
viewGroupNotifier.updatePage(currentIndex, isReload: true);
} catch (e) {}
});
}
}

// Fallback method to trigger bottom nav rebuild
void _triggerBottomNavRebuild(BuildContext context) {
try {
// Use the viewGroupNotifier's public updatePage method
int currentIndex = viewGroupNotifier.viewIndex;
viewGroupNotifier.updatePage(currentIndex, isReload: true);
} catch (e) {}
}
}

/**
Expand Down Expand Up @@ -164,4 +212,4 @@ class CloseAllDialogsAction extends EnsembleAction {
scopeManager.openedDialogs.clear();
return Future.value(null);
}
}
}
Loading
Loading