Skip to content

Commit fbd4aef

Browse files
authored
Merge branch 'main' into mentionable-input
2 parents 7875e4f + c3a9950 commit fbd4aef

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1928
-804
lines changed

CHANGELOG.md

+410
Large diffs are not rendered by default.

modules/auth/lib/signin/auth_manager.dart

+14-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:developer';
22
import 'dart:io';
3+
import 'package:collection/collection.dart';
34

45
import 'package:ensemble/action/invoke_api_action.dart';
56
import 'package:ensemble/ensemble.dart';
@@ -22,6 +23,7 @@ import 'package:firebase_auth/firebase_auth.dart';
2223
import 'package:flutter/cupertino.dart';
2324
import 'package:firebase_core/firebase_core.dart';
2425
import 'package:flutter/foundation.dart';
26+
import 'package:flutter/services.dart';
2527
import 'package:google_sign_in/google_sign_in.dart';
2628
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
2729

@@ -183,19 +185,28 @@ class AuthManager with UserAuthentication {
183185
}
184186

185187
Future<FirebaseApp> _initializeFirebaseSignIn() async {
188+
String? appId = await SignInUtils.getAppIdFromYaml();
189+
186190
FirebaseOptions? options;
191+
187192
if (kIsWeb) {
188193
options = Ensemble().getAccount()?.firebaseConfig?.webConfig;
189194
} else if (Platform.isIOS) {
190195
options = Ensemble().getAccount()?.firebaseConfig?.iOSConfig;
191196
} else if (Platform.isAndroid) {
192197
options = Ensemble().getAccount()?.firebaseConfig?.androidConfig;
193198
}
194-
if (options == null) {
199+
if (options == null || appId == null) {
195200
throw ConfigError('Firebase is not configured for this platform.');
196201
}
197-
return await Firebase.initializeApp(
198-
name: 'customFirebase', options: options);
202+
203+
// if the Firebase app is already initialized by other modules with same options, return it
204+
FirebaseApp? existingApp = Firebase.apps.firstWhereOrNull(
205+
(app) => SignInUtils.areFirebaseOptionsEqual(app.options, options!),
206+
);
207+
208+
return existingApp ??
209+
await Firebase.initializeApp(name: appId, options: options);
199210
}
200211

201212
/// enrich the passed in User with information from Firebase

modules/auth/lib/signin/signin_utils.dart

+16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import 'package:ensemble/framework/stub/auth_context_manager.dart';
2+
import 'package:firebase_core/firebase_core.dart';
3+
import 'package:flutter/services.dart';
24
import 'package:google_sign_in/google_sign_in.dart';
5+
import 'package:yaml/yaml.dart';
36

47
class SignInUtils {
58
/// convert a Google user account to our User
@@ -12,4 +15,17 @@ class SignInUtils {
1215
name: account.displayName,
1316
email: account.email,
1417
photo: account.photoUrl);
18+
19+
static Future<String?> getAppIdFromYaml() async {
20+
final yamlString = await rootBundle.loadString('ensemble/ensemble-config.yaml');
21+
final YamlMap yamlMap = loadYaml(yamlString);
22+
return yamlMap['definitions']?['ensemble']?['appId'];
23+
}
24+
25+
static bool areFirebaseOptionsEqual(FirebaseOptions a, FirebaseOptions b) {
26+
return a.apiKey == b.apiKey &&
27+
a.appId == b.appId &&
28+
a.messagingSenderId == b.messagingSenderId &&
29+
a.projectId == b.projectId;
30+
}
1531
}

modules/auth/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ dependencies:
2828
ensemble:
2929
git:
3030
url: https://github.com/EnsembleUI/ensemble.git
31-
ref: ensemble-v1.1.18
31+
ref: ensemble-v1.1.27
3232
path: modules/ensemble
3333

3434
ensemble_ts_interpreter:

modules/bracket/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ dependencies:
1414
ensemble:
1515
git:
1616
url: https://github.com/EnsembleUI/ensemble.git
17-
ref: ensemble-v1.1.18
17+
ref: ensemble-v1.1.27
1818
path: modules/ensemble
1919

2020
dev_dependencies:

modules/camera/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ dependencies:
1515
ensemble:
1616
git:
1717
url: https://github.com/EnsembleUI/ensemble.git
18-
ref: ensemble-v1.1.18
18+
ref: ensemble-v1.1.27
1919
path: modules/ensemble
2020
ensemble_ts_interpreter:
2121
git:

modules/chat/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ dependencies:
1313
ensemble:
1414
git:
1515
url: https://github.com/EnsembleUI/ensemble.git
16-
ref: ensemble-v1.1.18
16+
ref: ensemble-v1.1.27
1717
path: modules/ensemble
1818

1919
ensemble_ts_interpreter:

modules/connect/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ dependencies:
1313
ensemble:
1414
git:
1515
url: https://github.com/EnsembleUI/ensemble.git
16-
ref: ensemble-v1.1.18
16+
ref: ensemble-v1.1.27
1717
path: modules/ensemble
1818

1919
plaid_flutter: ^3.1.2

modules/contacts/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ dependencies:
1313
ensemble:
1414
git:
1515
url: https://github.com/EnsembleUI/ensemble.git
16-
ref: ensemble-v1.1.18
16+
ref: ensemble-v1.1.27
1717
path: modules/ensemble
1818

1919
flutter_contacts: ^1.1.7+1

modules/deeplink/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ dependencies:
1313
ensemble:
1414
git:
1515
url: https://github.com/EnsembleUI/ensemble.git
16-
ref: ensemble-v1.1.18
16+
ref: ensemble-v1.1.27
1717
path: modules/ensemble
1818

1919
flutter_branch_sdk: ^7.0.1

modules/ensemble/CHANGELOG.md

+32
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,35 @@
1+
## 1.1.27
2+
3+
- **FIX**: handle exceptions in getLocalAssetFullPath. ([8844d487](https://github.com/ensembleUI/ensemble/commit/8844d4874ddde3e7a3244e663c5cdcf0ee6520b7))
4+
5+
## 1.1.26
6+
7+
- **FIX**: ensure EnsembleConfigService is initialized before accessing config. ([1f8df899](https://github.com/ensembleUI/ensemble/commit/1f8df8997f7a9ab2dffae88ad96ac898cb49fa0a))
8+
9+
## 1.1.25
10+
11+
## 1.1.24
12+
13+
- Bump "ensemble" to `1.1.24`.
14+
15+
## 1.1.23
16+
17+
## 1.1.22
18+
19+
- **REFACTOR**: remove no internet widget. ([e03359b2](https://github.com/ensembleUI/ensemble/commit/e03359b2dd6b1290bea39c71c69e2a3d5ad27c13))
20+
- **REFACTOR**: replace offline widget with error screen for no internet connection. ([b0163a1b](https://github.com/ensembleUI/ensemble/commit/b0163a1ba20eb72c7a459afb3dfa59e1729cf9bf))
21+
- **FIX**: auto complete dropdown selected label. ([80b9c8f5](https://github.com/ensembleUI/ensemble/commit/80b9c8f54c753aca7884fd12ed449c5f019d981b))
22+
- **FEAT**: reinitialize app state when internet connectivity is restored. ([e914e337](https://github.com/ensembleUI/ensemble/commit/e914e337e54bbe539f08aa192b0a50b118708a00))
23+
- **FEAT**: implement internet connectivity check in runtime. ([30204d3b](https://github.com/ensembleUI/ensemble/commit/30204d3bb29324d9ae44380fc919b450cf30cfd0))
24+
25+
## 1.1.21
26+
27+
## 1.1.20
28+
29+
- Bump "ensemble" to `1.1.20`.
30+
31+
## 1.1.19
32+
133
## 1.1.18
234

335
## 1.1.17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import 'package:ensemble/ensemble.dart';
2+
import 'package:ensemble/framework/action.dart';
3+
import 'package:ensemble/framework/scope.dart';
4+
import 'package:ensemble/util/utils.dart';
5+
import 'package:ensemble_ts_interpreter/invokables/invokable.dart';
6+
import 'package:flutter/material.dart';
7+
8+
/// Action to open drawer in the current context
9+
/// Will open screen-level drawer if exists, otherwise app-level drawer
10+
class OpenDrawerAction extends EnsembleAction {
11+
OpenDrawerAction({super.initiator});
12+
13+
factory OpenDrawerAction.from({Invokable? initiator, Map? payload}) {
14+
return OpenDrawerAction(initiator: initiator);
15+
}
16+
17+
@override
18+
Future<void> execute(BuildContext context, ScopeManager scopeManager) {
19+
try {
20+
// Get nearest Scaffold
21+
ScaffoldState? scaffold = Scaffold.maybeOf(context);
22+
23+
// Check if scaffold exists and has drawer
24+
if (scaffold != null && scaffold.hasDrawer) {
25+
scaffold.openDrawer();
26+
}
27+
} catch (e) {
28+
debugPrint('Error opening drawer: $e');
29+
}
30+
return Future.value();
31+
}
32+
}
33+
34+
class CloseDrawerAction extends EnsembleAction {
35+
CloseDrawerAction({super.initiator});
36+
37+
factory CloseDrawerAction.from({Invokable? initiator, Map? payload}) {
38+
return CloseDrawerAction(initiator: initiator);
39+
}
40+
41+
@override
42+
Future execute(BuildContext context, ScopeManager scopeManager) async {
43+
try {
44+
// Get the current route
45+
final currentRoute = Ensemble().getCurrentRoute();
46+
final scaffold = Scaffold.maybeOf(context);
47+
48+
// Check if we're in a drawer route
49+
if (currentRoute != null &&
50+
currentRoute.isCurrent &&
51+
currentRoute.navigator != null &&
52+
currentRoute is MaterialPageRoute) {
53+
if(scaffold != null && !scaffold.hasDrawer) {
54+
currentRoute.navigator!.maybePop();
55+
return Future.value(true);
56+
}
57+
}
58+
return Future.value(false);
59+
} catch (e) {
60+
debugPrint('Error closing drawer: $e');
61+
return Future.value(false);
62+
}
63+
}
64+
}

modules/ensemble/lib/action/saveFile/save_file.dart

+25-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import 'dart:convert';
22
import 'dart:typed_data';
33

44
import 'package:ensemble/framework/action.dart';
5+
import 'package:ensemble/framework/event.dart';
56
import 'package:ensemble/framework/scope.dart';
7+
import 'package:ensemble/screen_controller.dart';
68
import 'package:flutter/material.dart';
79
import 'package:ensemble/framework/error_handling.dart';
810
import 'package:flutter/foundation.dart';
@@ -15,12 +17,16 @@ class SaveToFileSystemAction extends EnsembleAction {
1517
final dynamic blobData;
1618
final String? source; // Optional source for URL if blobData is not available
1719
final String? type; // file type
20+
final EnsembleAction? onComplete;
21+
final EnsembleAction? onError;
1822

1923
SaveToFileSystemAction({
2024
required this.fileName,
2125
this.blobData,
2226
this.source,
2327
this.type,
28+
this.onComplete,
29+
this.onError,
2430
});
2531

2632
factory SaveToFileSystemAction.from({Map? payload}) {
@@ -33,6 +39,8 @@ class SaveToFileSystemAction extends EnsembleAction {
3339
blobData: payload['blobData'],
3440
source: payload['source'],
3541
type: payload['type'],
42+
onComplete: EnsembleAction.from(payload['onComplete']),
43+
onError: EnsembleAction.from(payload['onError']),
3644
);
3745
}
3846

@@ -71,8 +79,24 @@ class SaveToFileSystemAction extends EnsembleAction {
7179

7280
// Save the file to the storage system
7381
await _saveFile(type!, fileName!, fileBytes);
82+
if (onComplete != null) {
83+
await ScreenController().executeAction(
84+
context,
85+
onComplete!,
86+
event: EnsembleEvent(initiator, data: {
87+
'fileBytes': fileBytes,
88+
'fileName': fileName,
89+
}),
90+
);
91+
}
7492
} catch (e) {
75-
throw Exception('Failed to save file: $e');
93+
if (onError != null) {
94+
await ScreenController().executeAction(
95+
context,
96+
onError!,
97+
event: EnsembleEvent(initiator, error: e.toString()),
98+
);
99+
}
76100
}
77101
}
78102

modules/ensemble/lib/ensemble.dart

+23-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import 'package:ensemble/framework/app_info.dart';
1616
import 'package:ensemble/framework/logging/console_log_provider.dart';
1717
import 'package:ensemble/framework/logging/log_manager.dart';
1818
import 'package:ensemble/framework/logging/log_provider.dart';
19+
import 'package:ensemble/framework/ensemble_config_service.dart';
1920
import 'package:ensemble/framework/route_observer.dart';
2021
import 'package:ensemble/framework/scope.dart';
2122
import 'package:ensemble/framework/secrets.dart';
@@ -139,10 +140,13 @@ class Ensemble extends WithEnsemble with EnsembleRouteObserver {
139140
if (_config != null) {
140141
return Future<EnsembleConfig>.value(_config);
141142
}
143+
// Initialize the config service to get `ensemble-config.yaml` file to access the configuration using static property as `EnsembleConfigService.config`
144+
if (!EnsembleConfigService.isInitialized) {
145+
await EnsembleConfigService.initialize();
146+
}
142147

143-
final yamlString =
144-
await rootBundle.loadString('ensemble/ensemble-config.yaml');
145-
final YamlMap yamlMap = loadYaml(yamlString);
148+
// get the config YAML
149+
final YamlMap yamlMap = EnsembleConfigService.config;
146150

147151
Account account = Account.fromYaml(yamlMap['accounts']);
148152
dynamic analyticsConfig = yamlMap['analytics'];
@@ -174,6 +178,20 @@ class Ensemble extends WithEnsemble with EnsembleRouteObserver {
174178
envOverrides = {};
175179
env.forEach((key, value) => envOverrides![key.toString()] = value);
176180
}
181+
// Read environmental variables from config/appConfig.json
182+
try {
183+
dynamic path = yamlMap["definitions"]?['local']?["path"];
184+
final configString = await rootBundle
185+
.loadString('${path}/config/appConfig.json');
186+
final Map<String, dynamic> configMap = json.decode(configString);
187+
// Loop through the envVariables from appConfig.json file and add them to the envOverrides
188+
configMap["envVariables"].forEach((key, value) {
189+
envOverrides![key] = value;
190+
});
191+
} catch(e) {
192+
debugPrint("appConfig.json file doesn't exist");
193+
}
194+
177195
DefinitionProvider definitionProvider = DefinitionProvider.from(yamlMap);
178196
_config = EnsembleConfig(
179197
definitionProvider: await definitionProvider.init(),
@@ -452,9 +470,11 @@ class EnsembleConfig {
452470
ThemeData getAppTheme() {
453471
return ThemeManager().getAppTheme(appBundle?.theme);
454472
}
473+
455474
bool hasLegacyCustomAppTheme() {
456475
return ThemeManager().hasLegacyCustomAppTheme(appBundle?.theme);
457476
}
477+
458478
/// retrieve the global widgets/codes/APIs
459479
Map? getResources() {
460480
return appBundle?.resources;

0 commit comments

Comments
 (0)