diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f3918d9 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "dart.flutterSdkPath": "/Users/hans/.puro/envs/stable/flutter", + "dart.sdkPath": "/Users/hans/.puro/envs/stable/flutter/bin/cache/dart-sdk" +} \ No newline at end of file diff --git a/example/.vscode/launch.json b/example/.vscode/launch.json new file mode 100644 index 0000000..08658c9 --- /dev/null +++ b/example/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "example", + "request": "launch", + "type": "dart" + }, + { + "name": "example (profile mode)", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "example (release mode)", + "request": "launch", + "type": "dart", + "flutterMode": "release" + } + ] +} \ No newline at end of file diff --git a/example/lib/interfaces/debug_auth_interface.dart b/example/lib/interfaces/debug_auth_interface.dart index 5c99873..ec9f2d9 100644 --- a/example/lib/interfaces/debug_auth_interface.dart +++ b/example/lib/interfaces/debug_auth_interface.dart @@ -32,19 +32,19 @@ class DebugAuthInterface _isSignedIn = false; - return Result.ok(null); + return const Result.ok(null); } @override - Future> login({ - Credentials? input, + Future> login({ + T? input, Future Function()? onLoggedIn, }) async { final bool alreadyLoggedIn = await isSignedIn; - if (alreadyLoggedIn) return Result.ok(null); + if (alreadyLoggedIn) return const Result.ok(null); - final credentials = input as ({String email, String password}); + final credentials = input as Credentials; final String email = credentials.email; final String password = credentials.password; @@ -53,7 +53,7 @@ class DebugAuthInterface _isSignedIn = true; - return Result.ok(null); + return const Result.ok(null); } @override @@ -61,15 +61,15 @@ class DebugAuthInterface T? input, }) async { Arcane.log("Re-sending verification code to $input"); - return Result.ok("Code sent"); + return const Result.ok("Code sent"); } @override - Future> register({ - Credentials? input, + Future> register({ + T? input, }) async { if (input != null) { - final credentials = input as ({String email, String password}); + final credentials = input as Credentials; final String email = credentials.email; final String password = credentials.password; @@ -77,7 +77,7 @@ class DebugAuthInterface Arcane.log("Creating account for $email with password $password"); } - return Result.ok(SignUpStep.confirmSignUp); + return const Result.ok(SignUpStep.confirmSignUp); } @override @@ -88,7 +88,7 @@ class DebugAuthInterface Arcane.log( "Confirming registration for $username with code $confirmationCode", ); - return Result.ok(true); + return const Result.ok(true); } @override @@ -98,7 +98,7 @@ class DebugAuthInterface String? code, }) async { Arcane.log("Resetting password for $email"); - return Result.ok(true); + return const Result.ok(true); } @override diff --git a/lib/src/services/authentication/authentication_service.dart b/lib/src/services/authentication/authentication_service.dart index c2bdda3..499fe00 100644 --- a/lib/src/services/authentication/authentication_service.dart +++ b/lib/src/services/authentication/authentication_service.dart @@ -164,10 +164,10 @@ class ArcaneAuthenticationService extends ArcaneService { Future Function()? onLoggedOut, }) async { if (_authInterface == null) { - return Result.error("No ArcaneAuthInterface has been registered"); + return const Result.error("No ArcaneAuthInterface has been registered"); } - if (!isAuthenticated) Result.error("User is not authenticated."); + if (!isAuthenticated) const Result.error("User is not authenticated."); final Result loggedOut = await authInterface!.logout( onLoggedOut: onLoggedOut, @@ -188,7 +188,7 @@ class ArcaneAuthenticationService extends ArcaneService { Future Function()? onLoggedIn, }) async { if (_authInterface == null) { - return Result.error("No ArcaneAuthInterface has been registered"); + return const Result.error("No ArcaneAuthInterface has been registered"); } final Result result = await authInterface!.login( @@ -210,11 +210,11 @@ class ArcaneAuthenticationService extends ArcaneService { T? input, }) async { if (_authInterface == null) { - return Result.error("No ArcaneAuthInterface has been registered"); + return const Result.error("No ArcaneAuthInterface has been registered"); } if (authInterface is! ArcaneAuthAccountRegistration) { - return Result.error( + return const Result.error( "The provided ArcaneAuthInterface does not support account registration.", ); } @@ -226,7 +226,7 @@ class ArcaneAuthenticationService extends ArcaneService { ); if (result == null) { - return Result.error( + return const Result.error( "Registered ArcaneAuthInterface returned a null value.", ); } @@ -241,11 +241,11 @@ class ArcaneAuthenticationService extends ArcaneService { required String confirmationCode, }) async { if (_authInterface == null) { - return Result.error("No ArcaneAuthInterface has been registered"); + return const Result.error("No ArcaneAuthInterface has been registered"); } if (authInterface is! ArcaneAuthAccountRegistration) { - return Result.error( + return const Result.error( "The provided ArcaneAuthInterface does not support account registration.", ); } @@ -258,7 +258,7 @@ class ArcaneAuthenticationService extends ArcaneService { ); if (result == null) { - return Result.error( + return const Result.error( "Registered ArcaneAuthInterface returned a null value.", ); } @@ -270,11 +270,11 @@ class ArcaneAuthenticationService extends ArcaneService { /// registration. Future> resendVerificationCode(String email) async { if (_authInterface == null) { - return Result.error("No ArcaneAuthInterface has been registered"); + return const Result.error("No ArcaneAuthInterface has been registered"); } if (authInterface is! ArcaneAuthAccountRegistration) { - return Result.error( + return const Result.error( "The provided ArcaneAuthInterface does not support account registration.", ); } @@ -285,7 +285,7 @@ class ArcaneAuthenticationService extends ArcaneService { auth.resendVerificationCode(input: email); if (result == null) { - return Result.error( + return const Result.error( "Registered ArcaneAuthInterface returned a null value.", ); } @@ -305,11 +305,11 @@ class ArcaneAuthenticationService extends ArcaneService { String? confirmationCode, }) async { if (_authInterface == null) { - return Result.error("No ArcaneAuthInterface has been registered"); + return const Result.error("No ArcaneAuthInterface has been registered"); } if (authInterface is! ArcaneAuthPasswordManagement) { - return Result.error( + return const Result.error( "The provided ArcaneAuthInterface does not support password management.", ); } @@ -323,7 +323,7 @@ class ArcaneAuthenticationService extends ArcaneService { ); if (result == null) { - return Result.error( + return const Result.error( "Registered ArcaneAuthInterface returned a null value.", ); } diff --git a/lib/src/services/reactive_theme/arcane_theme.dart b/lib/src/services/reactive_theme/arcane_theme.dart new file mode 100644 index 0000000..d91ea3d --- /dev/null +++ b/lib/src/services/reactive_theme/arcane_theme.dart @@ -0,0 +1,26 @@ +import "package:flutter/material.dart"; + +class ArcaneTheme extends InheritedWidget { + final ThemeMode themeMode; + final bool followSystem; + final ThemeData? theme; + + const ArcaneTheme({ + required super.child, + this.themeMode = ThemeMode.light, + this.followSystem = false, + this.theme, + super.key, + }); + + static ArcaneTheme? of(BuildContext context) { + return context.dependOnInheritedWidgetOfExactType(); + } + + @override + bool updateShouldNotify(ArcaneTheme oldWidget) { + return themeMode != oldWidget.themeMode || + followSystem != oldWidget.followSystem || + theme != oldWidget.theme; + } +} diff --git a/pubspec.yaml b/pubspec.yaml index d778a15..92f88e7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,6 @@ name: arcane_framework -description: "Agnostic Reusable Component Architecture for New Ecosystems: a modern framework for bootstrapping new applications" +description: "Agnostic Reusable Component Architecture for New Ecosystems: a + modern framework for bootstrapping new applications" version: 2.0.0-dev repository: https://github.com/hanskokx/arcane_framework issue_tracker: https://github.com/hanskokx/arcane_framework/issues @@ -16,7 +17,7 @@ dependencies: collection: ^1.19.0 flutter: sdk: flutter - result_monad: ^2.3.2 + result_monad: ^4.0.0 dev_dependencies: arcane_analysis: ^1.0.3 diff --git a/test/services/authentication/authentication_service_test.dart b/test/services/authentication/authentication_service_test.dart index 52eef3b..e6d88b9 100644 --- a/test/services/authentication/authentication_service_test.dart +++ b/test/services/authentication/authentication_service_test.dart @@ -23,10 +23,10 @@ void main() { // Set up default mock behaviors when(mockInterface.login(input: anyNamed("input"))).thenAnswer( - (_) async => Result.ok(null), + (_) async => const Result.ok(null), ); when(mockInterface.logout()).thenAnswer( - (_) async => Result.ok(null), + (_) async => const Result.ok(null), ); when(mockInterface.init()).thenAnswer( (_) async {}, @@ -61,7 +61,7 @@ void main() { testWidgets("login with failure", (WidgetTester tester) async { // Reset the mock behavior for this specific test when(mockInterface.login(input: anyNamed("input"))) - .thenAnswer((_) async => Result.error("error")); + .thenAnswer((_) async => const Result.error("error")); final result = await ArcaneAuthenticationService.I .login(input: {"username": "test"});