Skip to content

Commit c597ab4

Browse files
authored
Merge pull request #14 from nylo-core/master
Master
2 parents 920573a + 78ddf69 commit c597ab4

File tree

12 files changed

+206
-26
lines changed

12 files changed

+206
-26
lines changed

CHANGELOG.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
1+
## [3.0.0] - 2022-04-29
2+
3+
* New arguments for Nylo's `init` method: setup, setupFinished
4+
* Add init method for NyState class
5+
* New helpers: nyEvent, nyApi and Backpack
6+
* assert condition added to DefaultResponse class
7+
8+
## [2.8.0] - 2022-04-21
9+
10+
* Revert new init method in Nylo
11+
12+
## [2.7.0] - 2022-04-21
13+
14+
* Version bump
15+
16+
## [2.6.1] - 2022-04-21
17+
18+
* Fix Nylo init method with router param
19+
20+
## [2.6.0] - 2022-04-21
21+
22+
* Revert init change in NyState.
23+
* New Metro command to create events in Nylo.
24+
* bootApplication helper added.
25+
* Small refactor to folder names
26+
127
## [2.5.0] - 2022-04-19
228

329
* New Metro command to create Providers in Nylo.

lib/events/events.dart

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/// Base interface for Events
2+
abstract class NyEvent {
3+
final Map<Type, NyListener> listeners = {};
4+
}
5+
6+
/// Base class for listeners
7+
class NyListener {
8+
late NyEvent _event;
9+
10+
/// Set the [event] that the listener was called from
11+
setEvent(NyEvent event) {
12+
_event = event;
13+
}
14+
15+
/// Get the [NyEvent] that the listener was called from
16+
NyEvent getEvent() => _event;
17+
18+
/// Handle the payload from the event
19+
/// The [event] argument provides a Map of the data
20+
/// event<ChatCreated>({"chat": Chat()});
21+
/// E.g. [event] = {"chat":"Chat instance"}
22+
Future<dynamic> handle(Map? event) async {}
23+
}

lib/helpers/helper.dart

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
33
import 'package:flutter_dotenv/flutter_dotenv.dart';
44
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
55
import 'package:logger/logger.dart';
6+
import 'package:nylo_support/events/events.dart';
67
import 'package:nylo_support/localization/app_localization.dart';
78

89
/// Returns a value from the .env file
@@ -280,3 +281,71 @@ class NyLogger {
280281
/// lang translation will be returned for the app locale.
281282
String trans(String key, {Map<String, String>? arguments}) =>
282283
NyLocalization.instance.translate(key, arguments);
284+
285+
/// Event helper
286+
nyEvent<T>({
287+
Map? params,
288+
Map<Type, NyEvent> events = const {},
289+
}) async {
290+
assert(T.toString() != 'dynamic',
291+
'You must provide an Event type for this method.\nE.g. event<LoginEvent>({"User": "#1 User"});');
292+
293+
Map<Type, NyEvent> appEvents = events;
294+
295+
if (events.isEmpty) {
296+
appEvents = Backpack.instance.read('nylo').getEvents();
297+
}
298+
299+
NyEvent nyEvent = appEvents[T]!;
300+
assert(appEvents.containsKey(T),
301+
'Your config/events.dart is missing this class ${T.toString()}');
302+
Map<dynamic, NyListener> listeners = nyEvent.listeners;
303+
304+
if (listeners.isEmpty) {
305+
return;
306+
}
307+
for (NyListener listener in listeners.values.toList()) {
308+
listener.setEvent(nyEvent);
309+
dynamic result = await listener.handle(params);
310+
if (result != null && result == false) {
311+
break;
312+
}
313+
}
314+
}
315+
316+
/// API helper
317+
Future<void> nyApi<T>(
318+
{required dynamic Function(T) request,
319+
required Map<Type, dynamic> apiDecoders,
320+
BuildContext? context}) async {
321+
assert(apiDecoders.containsKey(T),
322+
'Your config/decoders.dart is missing this class ${T.toString()} in apiDecoders');
323+
324+
dynamic apiService = apiDecoders[T];
325+
if (context != null) {
326+
apiService.setContext(context);
327+
}
328+
329+
await request(apiService);
330+
}
331+
332+
/// Backpack class for storing data
333+
/// This class is not designed to store huge amounts of data.
334+
class Backpack {
335+
Map<String, dynamic> _values = {};
336+
337+
Backpack._privateConstructor();
338+
339+
static final Backpack instance = Backpack._privateConstructor();
340+
341+
T? read<T>(String key) {
342+
if (!_values.containsKey(key)) {
343+
return null;
344+
}
345+
return _values[key];
346+
}
347+
348+
set(String key, dynamic value) async {
349+
_values[key] = value;
350+
}
351+
}

lib/metro/constants/strings.dart

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@ const String themeDarkFlag = 'dark';
77
const String controllerFlag = 'controller';
88
const String isResourceFlag = 'resource';
99
const String modelFlag = 'model';
10+
const String urlFlag = 'url';
1011

1112
// folders
1213
const String yamlPath = 'pubspec.yaml';
13-
const String controllerFolder = 'lib/app/controllers';
14-
const String widgetFolder = 'lib/resources/widgets';
15-
const String pageFolder = 'lib/resources/pages';
16-
const String modelFolder = 'lib/app/models';
17-
const String themeFolder = 'lib/resources/themes';
14+
const String controllersFolder = 'lib/app/controllers';
15+
const String widgetsFolder = 'lib/resources/widgets';
16+
const String pagesFolder = 'lib/resources/pages';
17+
const String modelsFolder = 'lib/app/models';
18+
const String themesFolder = 'lib/resources/themes';
1819
const String providerFolder = 'lib/app/providers';
20+
const String eventsFolder = 'lib/app/events';
1921
const String networkingFolder = 'lib/app/networking';
2022
const String themeColorsFolder = 'lib/resources/themes/styles';

lib/metro/metro_service.dart

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import 'package:nylo_support/metro/metro_console.dart';
55
class MetroService {
66
/// Creates a new Controller.
77
static Future makeController(String className, String value,
8-
{String folderPath = controllerFolder, bool forceCreate = false}) async {
8+
{String folderPath = controllersFolder, bool forceCreate = false}) async {
99
String filePath = '$folderPath/${className.toLowerCase()}_controller.dart';
1010

1111
await _makeDirectory(folderPath);
@@ -15,7 +15,7 @@ class MetroService {
1515

1616
/// Creates a new Page.
1717
static makePage(String className, String value,
18-
{String folderPath = pageFolder, bool forceCreate = false}) async {
18+
{String folderPath = pagesFolder, bool forceCreate = false}) async {
1919
String filePath = '$folderPath/${className.toLowerCase()}_page.dart';
2020

2121
await _makeDirectory(folderPath);
@@ -25,7 +25,7 @@ class MetroService {
2525

2626
/// Creates a new Model.
2727
static makeModel(String className, String value,
28-
{String folderPath = modelFolder,
28+
{String folderPath = modelsFolder,
2929
bool storable = false,
3030
bool forceCreate = false}) async {
3131
String filePath = '$folderPath/${className.toLowerCase()}.dart';
@@ -37,7 +37,7 @@ class MetroService {
3737

3838
/// Creates a new Stateless Widget.
3939
static makeStatelessWidget(String className, String value,
40-
{String folderPath = widgetFolder, bool forceCreate = false}) async {
40+
{String folderPath = widgetsFolder, bool forceCreate = false}) async {
4141
String filePath = '$folderPath/${className.toLowerCase()}_widget.dart';
4242

4343
await _makeDirectory(folderPath);
@@ -47,7 +47,7 @@ class MetroService {
4747

4848
/// Creates a new Stateful Widget.
4949
static makeStatefulWidget(String className, String value,
50-
{String folderPath = widgetFolder, bool forceCreate = false}) async {
50+
{String folderPath = widgetsFolder, bool forceCreate = false}) async {
5151
String filePath = '$folderPath/${className.toLowerCase()}_widget.dart';
5252

5353
await _makeDirectory(folderPath);
@@ -57,7 +57,7 @@ class MetroService {
5757

5858
/// Creates a new Stateful Widget.
5959
static makeTheme(String className, String value,
60-
{String folderPath = themeFolder, bool forceCreate = false}) async {
60+
{String folderPath = themesFolder, bool forceCreate = false}) async {
6161
String filePath = '$folderPath/${className.toLowerCase()}_theme.dart';
6262

6363
await _makeDirectory(folderPath);
@@ -75,6 +75,16 @@ class MetroService {
7575
await _createNewFile(filePath, value);
7676
}
7777

78+
/// Creates a new Event.
79+
static makeEvent(String className, String value,
80+
{String folderPath = eventsFolder, bool forceCreate = false}) async {
81+
String filePath = '$folderPath/${className.toLowerCase()}_event.dart';
82+
83+
await _makeDirectory(folderPath);
84+
await _checkIfFileExists(filePath, shouldForceCreate: forceCreate);
85+
await _createNewFile(filePath, value);
86+
}
87+
7888
/// Creates a new API service.
7989
static makeApiService(String className, String value,
8090
{String folderPath = networkingFolder, bool forceCreate = false}) async {

lib/networking/default_response.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ class DefaultResponse<T> {
66

77
late final T data;
88

9-
DefaultResponse.fromJson(json, decoders, {required Type type}) {
9+
DefaultResponse.fromJson(json, Map<Type, dynamic> decoders,
10+
{required Type type}) {
11+
assert(decoders.containsKey(type),
12+
'Your config/decoders.dart file does not contain a decoder for the following class: ${type.toString()} in modelDecoders');
1013
data = decoders[type]!(json) as T;
1114
}
1215
}

lib/nylo.dart

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import 'package:flutter_dotenv/flutter_dotenv.dart';
2+
import 'package:nylo_support/events/events.dart';
23
import 'package:nylo_support/plugin/nylo_plugin.dart';
34
import 'package:nylo_support/router/router.dart';
45
export 'package:nylo_support/exceptions/validation_exception.dart';
56
export 'package:nylo_support/alerts/toast_enums.dart';
67

78
class Nylo {
89
late NyRouter? router;
10+
late Map<Type, NyEvent> _events = {};
911

1012
Nylo({this.router});
1113

@@ -18,6 +20,8 @@ class Nylo {
1820
router = NyRouter();
1921
}
2022
router!.setNyRoutes(plugin.routes());
23+
_events.addAll(plugin.events());
24+
NyNavigator.instance.router = this.router!;
2125
}
2226

2327
/// Allows you to add additional Router's to your project.
@@ -35,15 +39,29 @@ class Nylo {
3539
this.router = NyRouter();
3640
}
3741
this.router!.setRegisteredRoutes(router.getRegisteredRoutes());
42+
NyNavigator.instance.router = this.router!;
3843
}
3944

40-
/// Run to init Nylo
41-
static Future<Nylo> init({required router, Function? setup}) async {
45+
/// Add [events] to Nylo
46+
addEvents(Map<Type, NyEvent> events) async {
47+
_events.addAll(events);
48+
}
49+
50+
/// Return all the registered events
51+
Map<Type, NyEvent> getEvents() => _events;
52+
53+
/// Initialize Nylo
54+
static Future<Nylo> init({Function? setup, Function? setupFinished}) async {
4255
await dotenv.load(fileName: ".env");
4356

44-
if (setup != null) {
45-
await setup();
57+
if (setup == null) {
58+
return Nylo();
59+
}
60+
61+
Nylo nylo = await setup();
62+
if (setupFinished != null) {
63+
await setupFinished(nylo);
4664
}
47-
return Nylo(router: router);
65+
return nylo;
4866
}
4967
}

lib/plugin/nylo_plugin.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:nylo_support/events/events.dart';
12
import 'package:nylo_support/nylo.dart';
23
import 'package:nylo_support/router/router.dart';
34

@@ -6,6 +7,7 @@ abstract class NyAppPlugin {
67
initPackage(Nylo nylo) async {}
78
construct() async {}
89
routes() {}
10+
events() {}
911
}
1012

1113
/// [BasePlugin] class for NyPlugin.
@@ -24,6 +26,9 @@ class BasePlugin implements NyAppPlugin {
2426

2527
/// Add additional routes to a Nylo project via the [router].
2628
NyRouter routes() => nyRoutes((router) {});
29+
30+
/// Add events to a Nylo project.
31+
Map<Type, NyEvent> events() => {};
2732
}
2833

2934
class NyPlugin extends BasePlugin {
@@ -35,4 +40,7 @@ class NyPlugin extends BasePlugin {
3540
// Add your routes here
3641
// router.route("/new-page", (context) => NewPage());
3742
});
43+
44+
/// Add events to a Nylo project.
45+
Map<Type, NyEvent> events() => {};
3846
}

lib/providers/providers.dart

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
1+
import 'package:nylo_support/helpers/helper.dart';
2+
import 'package:nylo_support/nylo.dart';
3+
14
/// Base class for Providers.
2-
class NyProvider {
5+
abstract class NyProvider {
36
/// Boot method is used for initializing code in your application.
4-
boot() async {}
7+
Future<Nylo?> boot(Nylo nylo) async => null;
8+
}
9+
10+
/// Boots application providers.
11+
///
12+
/// See "config/providers" to add/modify providers
13+
Future<Nylo> bootApplication(Map<Type, NyProvider> providers) async {
14+
Nylo nylo = Nylo();
15+
for (var provider in providers.values) {
16+
Nylo? nyloObject = await provider.boot(nylo);
17+
if (nyloObject != null) {
18+
nylo = nyloObject;
19+
}
20+
}
21+
return nylo;
22+
}
23+
24+
/// Called with init Nylo finishes.
25+
Future<Nylo> bootFinished(Nylo nylo) async {
26+
Backpack.instance.set('nylo', nylo);
27+
return nylo;
528
}

lib/router/router.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ NyRouter nyRoutes(Function(NyRouter router) build) {
2929
NyRouter nyRouter = NyRouter();
3030
build(nyRouter);
3131

32-
NyNavigator.instance.router = nyRouter;
3332
return nyRouter;
3433
}
3534

@@ -144,13 +143,15 @@ class NyRouter {
144143
"'${route.name}' has already been registered before. Overriding it!");
145144
}
146145
_routeNameMappings[route.name] = route;
146+
NyNavigator.instance.router = this;
147147
}
148148

149149
/// Add a list of routes at once.
150150
void addRoutes(List<NyRouterRoute> routes) {
151151
if (routes.isNotEmpty) {
152152
routes.forEach((route) => this._addRoute(route));
153153
}
154+
NyNavigator.instance.router = this;
154155
}
155156

156157
/// Makes this a callable class. Delegates to [navigate].

0 commit comments

Comments
 (0)