Skip to content

Commit

Permalink
Merge branch 'main' into image_cache
Browse files Browse the repository at this point in the history
  • Loading branch information
vusters authored Dec 13, 2023
2 parents 172ad73 + c76fbd8 commit 84c9d9b
Show file tree
Hide file tree
Showing 33 changed files with 1,299 additions and 873 deletions.
2 changes: 1 addition & 1 deletion .android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
org.gradle.jvmargs=-Xmx1536M
org.gradle.jvmargs=-Xmx4G
android.useAndroidX=true
android.enableJetifier=true
61 changes: 44 additions & 17 deletions assets/schema/ensemble_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@
"type": "boolean",
"description": "Specify if the content of this screen is scrollable with a global scrollbar. Using this also allow you to customize the scrolling experience of the header."
},
"unfocus": {
"type": "boolean",
"description": "Specify if the keyboard should dismissed automatically when tapping in the non interactive widgets. Default (false)"
},
"showNavigationIcon": {
"type": "boolean",
"description": "For a screen with header, the App will automatically show the Menu, Back, or Close icon (for modal screen) before the title. On modal screen without the header, the Close icon will be shown. Set this flag to false if you wish to hide the icons and handle the navigation yourself."
Expand Down Expand Up @@ -460,7 +464,7 @@
},
"cssStyles": {
"type": "array",
"oneOf": [
"items": [
{
"type": "object",
"properties": {
Expand Down Expand Up @@ -1562,6 +1566,10 @@
"type": "boolean",
"description": "enable the toggling between plain and obscure text."
},
"toolbarDone": {
"type": "boolean",
"description": "enable the toolbar with done button in the TextInput. (defaults to False)"
},
"enableClearText": {
"type": "boolean",
"description": "It enables the default suffix clear icon button for the text input field to clear the values. Default (false)"
Expand Down Expand Up @@ -2649,6 +2657,10 @@
"type": "string",
"description": "A unique identifier for this widget"
},
"scrollController": {
"type": "string",
"description": "For setting the scrollbehaviour"
},
"onItemTap": {
"$ref": "#/$defs/Action-payload",
"description": "Call Ensemble's built-in functions or execute code when tapping on an item in the list."
Expand Down Expand Up @@ -3062,6 +3074,10 @@
"type": "string",
"description": "A unique identifier for this widget"
},
"controller" :{
"type": "string",
"description": "For setting the scrollbehaviour"
},
"children": {
"$ref": "#/$defs/Widgets"
},
Expand Down Expand Up @@ -5076,6 +5092,10 @@
"type": "boolean",
"description": "Mark this item as a floating icon"
},
"switchScreen": {
"type": "boolean",
"description": "Disable the screen switching when clicking the bottom nav bar item. Default (True)"
},
"floatingMargin": {
"$ref": "#/$defs/Margin-payload",
"description": "The margin around the floating."
Expand Down Expand Up @@ -5887,13 +5907,13 @@
}
},
{
"title": "Youtube",
"title": "YouTube",
"required": [
"Youtube"
"YouTube"
],
"properties": {
"Youtube" : {
"$ref" : "#/$defs/Youtube-payload"
"YouTube" : {
"$ref" : "#/$defs/YouTube-payload"
}
}
},
Expand Down Expand Up @@ -6546,60 +6566,67 @@
}
}
},
"Youtube-payload":{
"YouTube-payload":{
"type" : "object",
"properties" : {
"id" : {
"type" : "string",
"description": "The unique identifier for this widget"
},
"styles": {
"$ref": "#/$defs/boxStyles"
},
"url" : {
"type": "string",
"description": "The URL source to the youtube video"
"description": "The URL source to the youTube video"
},
"aspectRatio" : {
"type": "double",
"type": "number",
"description" : "Video aspect ratio"
},
"autoplay": {
"type" : "bool",
"type" : "boolean",
"description" : "Automatically start the video when player is loaded. (default False)"
},
"videoList" : {
"type" : "array",
"type" : "object",
"description" : "List of videos to be played within a single player."
},
"startSeconds": {
"type" : "double",
"type" : "number",
"description" : "specifies the time from which the first video in the list(or single video) should start playing"
},
"endSeconds": {
"type": "double",
"type": "number",
"description": "Ends the video after the certain number of seconds (works with Single video)"
},
"showAnnotations" : {
"type" : "bool",
"type" : "boolean",
"description" : "Showing the annotations of the video"
},
"playbackRate" : {
"type": "double",
"type": "number",
"description": "For changing the speed at which the video is displayed"
},
"showControls": {
"type" : "bool",
"type" : "boolean",
"description" : "For showing the controls on the video within the player(Like in youtube)"
},
"showFullScreenButton": {
"type" : "bool",
"type" : "boolean",
"description" : "To show the fullscreen button of the video"
},
"enableCaptions" : {
"type": "bool",
"type": "boolean",
"description" : "To enable any captions in the video(default language of caption is English)"
},
"volume": {
"type": "integer",
"description" : "Changes the volume. (max = 100, min = 0)"
},
"videoPosition": {
"type": "boolean",
"description": "To add an indicator for the amount of video that is completed"
}
}
},
Expand Down
4 changes: 3 additions & 1 deletion lib/action/action_invokable.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'package:ensemble/action/call_external_method.dart';
import 'package:ensemble/framework/action.dart';
import 'package:ensemble/framework/error_handling.dart';
import 'package:ensemble/framework/scope.dart';
Expand All @@ -22,6 +21,9 @@ abstract class ActionInvokable with Invokable {
ActionType.copyToClipboard,
ActionType.getDeviceToken,
ActionType.getPhoneContacts,
ActionType.showBottomModal,
ActionType.dismissBottomModal,
ActionType.showDialog,
]);
}

Expand Down
28 changes: 14 additions & 14 deletions lib/action/bottom_modal_action.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import 'dart:ui';

import 'package:ensemble/framework/action.dart';
import 'package:ensemble/framework/data_context.dart';
import 'package:ensemble/framework/error_handling.dart';
Expand All @@ -9,9 +7,7 @@ import 'package:ensemble/framework/view/context_scope_widget.dart';
import 'package:ensemble/screen_controller.dart';
import 'package:ensemble/util/utils.dart';
import 'package:ensemble_ts_interpreter/invokables/invokable.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:yaml/yaml.dart';

/// open a Modal Bottom Sheet
class ShowBottomModalAction extends EnsembleAction {
Expand Down Expand Up @@ -68,15 +64,19 @@ class ShowBottomModalAction extends EnsembleAction {

if (widget != null) {
showModalBottomSheet(
context: context,
backgroundColor: _backgroundColor(scopeManager),
barrierColor: _barrierColor(scopeManager),
isScrollControlled: true,
enableDrag: _enableDrag(scopeManager),
showDragHandle: _enableDragHandler(scopeManager),
builder: (modalContext) =>
ContextScopeWidget(rootContext: modalContext, child: widget!))
.then((payload) {
context: context,
backgroundColor: _backgroundColor(scopeManager),
barrierColor: _barrierColor(scopeManager),
isScrollControlled: true,
enableDrag: _enableDrag(scopeManager),
showDragHandle: _enableDragHandler(scopeManager),
builder: (context) => Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: ContextScopeWidget(rootContext: context, child: widget!),
),
).then((payload) {
if (onDismiss != null) {
return ScreenController().executeActionWithScope(
context, scopeManager, onDismiss!,
Expand Down Expand Up @@ -106,6 +106,6 @@ class DismissBottomModalAction extends EnsembleAction {
return Navigator.maybePop(
bottomModalContext, scopeManager.dataContext.eval(payload));
}
return Future.value(null);
return Navigator.maybePop(context, scopeManager.dataContext.eval(payload));
}
}
21 changes: 0 additions & 21 deletions lib/ensemble_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -117,33 +117,12 @@ class EnsembleAppState extends State<EnsembleApp> with WidgetsBindingObserver {
Workmanager().initialize(callbackDispatcher, isInDebugMode: false);
initDeepLink(AppLifecycleState.resumed);
}

WidgetsBinding.instance.addPostFrameCallback((_) async {
executeCallbacks();
});
}

@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
super.didChangeAppLifecycleState(state);
initDeepLink(state);
if (state == AppLifecycleState.resumed) {
executeCallbacks();
}
}

Future<void> executeCallbacks() async {
final callbacks = List.from(Ensemble().getCallbacksAfterInitialization());

callbacks.asMap().forEach((index, function) async {
// Removing a method and getting the function with index to execute it
Ensemble().getCallbacksAfterInitialization().remove(function);
try {
await Function.apply(function, null);
} catch (e) {
print('Failed to execute a method: $e');
}
});
}

void initDeepLink(AppLifecycleState state) {
Expand Down
18 changes: 10 additions & 8 deletions lib/framework/action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import 'package:ensemble/framework/extensions.dart';
import 'package:ensemble/framework/keychain_manager.dart';
import 'package:ensemble/framework/permissions_manager.dart';
import 'package:ensemble/framework/scope.dart';
import 'package:ensemble/framework/view/bottom_nav_page_group.dart';
import 'package:ensemble/framework/view/page_group.dart';
import 'package:ensemble/framework/widget/view_util.dart';
import 'package:ensemble/receive_intent_manager.dart';
Expand Down Expand Up @@ -67,17 +66,20 @@ class ShowDialogAction extends EnsembleAction {
final Map<String, dynamic>? options;
final EnsembleAction? onDialogDismiss;

factory ShowDialogAction.fromYaml({Invokable? initiator, Map? payload}) {
factory ShowDialogAction.from({Invokable? initiator, Map? payload}) {
if (payload == null || payload['widget'] == null) {
throw LanguageError(
"${ActionType.showDialog.name} requires the 'widget' for the Dialog's content.");
}
return ShowDialogAction(
initiator: initiator,
widget: payload['widget'],
//inputs: Utils.getMap(payload["inputs"]),
options: Utils.getMap(payload['options']),
onDialogDismiss: EnsembleAction.fromYaml(payload['onDialogDismiss']));
initiator: initiator,
widget: payload['widget'],
//inputs: Utils.getMap(payload["inputs"]),
options: Utils.getMap(payload['options']),
onDialogDismiss: payload['onDialogDismiss'] == null
? null
: EnsembleAction.fromYaml(payload['onDialogDismiss']),
);
}
}

Expand Down Expand Up @@ -1006,7 +1008,7 @@ abstract class EnsembleAction {
} else if (actionType == ActionType.openCamera) {
return ShowCameraAction.fromYaml(initiator: initiator, payload: payload);
} else if (actionType == ActionType.showDialog) {
return ShowDialogAction.fromYaml(initiator: initiator, payload: payload);
return ShowDialogAction.from(initiator: initiator, payload: payload);
} else if (actionType == ActionType.closeAllDialogs) {
return CloseAllDialogsAction();
} else if (actionType == ActionType.startTimer) {
Expand Down
21 changes: 16 additions & 5 deletions lib/framework/data_context.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io' as io;
import 'dart:ui';
import 'package:ensemble/action/action_invokable.dart';
import 'package:ensemble/action/call_external_method.dart';
import 'package:ensemble/action/bottom_modal_action.dart';
import 'package:ensemble/action/haptic_action.dart';
import 'package:ensemble/action/invoke_api_action.dart';
import 'package:ensemble/action/misc_action.dart';
import 'package:ensemble/action/navigation_action.dart';
import 'package:ensemble/ensemble.dart';
import 'package:ensemble/ensemble_app.dart';
import 'package:ensemble/framework/all_countries.dart';
import 'package:ensemble/framework/bindings.dart';
import 'package:ensemble/framework/config.dart';
import 'package:ensemble/framework/device.dart';
import 'package:ensemble/framework/error_handling.dart';
Expand Down Expand Up @@ -365,6 +362,20 @@ class NativeInvokable extends ActionInvokable {
final scope = ScreenController().getScopeManager(buildContext);
callNativeMethod(buildContext, scope, inputs);
},
ActionType.showBottomModal.name: (inputs) =>
ScreenController().executeAction(
buildContext,
ShowBottomModalAction.from(payload: inputs),
),
ActionType.dismissBottomModal.name: (inputs) =>
ScreenController().executeAction(
buildContext,
DismissBottomModalAction.from(payload: inputs),
),
ActionType.showDialog.name: (inputs) => ScreenController()
.executeAction(buildContext, ShowDialogAction.from(payload: inputs)),
ActionType.rateApp.name: (inputs) => ScreenController()
.executeAction(buildContext, RateAppAction.from(payload: inputs)),
'connectSocket': (String socketName, Map<dynamic, dynamic>? inputs) {
connectSocket(buildContext, socketName, inputs: inputs);
},
Expand Down
3 changes: 3 additions & 0 deletions lib/framework/menu.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ abstract class Menu {
floatingAlignment:
Utils.optionalString(item['floatingAlignment']) ?? 'center',
floatingMargin: Utils.optionalInt(item['floatingMargin']),
switchScreen: Utils.getBool(item['switchScreen'], fallback: true),
onTap: item['onTap'],
onTapHaptic: Utils.optionalString(item['onTapHaptic']),
isExternal: Utils.getBool(item['isExternal'], fallback: false),
Expand Down Expand Up @@ -207,6 +208,7 @@ class MenuItem {
this.iconLibrary,
this.selected,
this.floating = false,
this.switchScreen = true,
this.floatingAlignment = 'center',
this.floatingMargin,
this.onTap,
Expand All @@ -223,6 +225,7 @@ class MenuItem {
final String? iconLibrary;
final dynamic selected;
final bool floating;
final bool switchScreen;
final String floatingAlignment;
final int? floatingMargin;
final dynamic onTap;
Expand Down
Loading

0 comments on commit 84c9d9b

Please sign in to comment.