Giter Club home page Giter Club logo

nylo's Introduction

Nylo Banner

Latest Release Version GitHub GitHub stars

Nylo

Nylo is a micro-framework for Flutter which is designed to help simplify developing apps. Every project provides a simple boilerplate and MVC pattern to help you build apps easier.

This project is open source and MIT-licenced, we welcome any contributions. You can join as a backer/sponsor to fund future development for this project here


Features

Some core features available

Requirements

  • Dart >= 3.1.3

Getting Started

git clone https://github.com/nylo-core/nylo.git

Documentation

View our docs and visit nylo.dev

Changelog

Please see CHANGELOG for more information what has changed recently.

Social

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Contributors

Licence

The MIT License (MIT). Please view the License File for more information.

nylo's People

Contributors

abdulrasheed1729 avatar agordn52 avatar flutter-nylo avatar lepresk avatar lpdevit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nylo's Issues

Cant use fontweightBold()

Happening with latest version

 child: Text(
                    trans("auth.get_started"),
                  ).fontWeightBold(),

getting this

image

refreshToken function isn't invoked

First of all, Thank you @agordn52 for this great framework.

I'm following the docs, and what has been mentioned in the issues/discussions.

refreshToken function isn't being invoked at all.

  @override
  refreshToken(Dio dio) async {
    AuthTokens? tokens = await StorageKey.userToken.read<AuthTokens>();
    if (tokens?.refreshToken == null) {
      await Auth.logout();
      routeToInitial(navigationType: NavigationType.pushAndForgetAll);
      return;
    }
    dynamic response = (await dio.post(baseUrl + "/auth/refresh",
            options: Options(
                headers: {"Authorization": "Bearer ${tokens?.refreshToken}"})))
        .data();
    //  Save the new token
    await StorageKey.userToken.store(response);
  }

Noting that the approach was mentioned, I have to retry manually.

Did I miss anything?

If we refresh on request instead, would it be better? but what if I run parallel requests?


Update [29-01-2024]

This is the interceptor approach.

class BearerAuthInterceptor extends Interceptor {
  @override
  void onRequest(
      RequestOptions options, RequestInterceptorHandler handler) async {
    if (!options.path.contains("auth/refresh")) {
      await api<ApiService>((request) => request.refreshTokens());
    }
    AuthTokens? tokens = await StorageKey.userToken.read<AuthTokens>();
    String? token = options.path.contains("auth/refresh")
        ? tokens?.refreshToken
        : tokens?.accessToken;

    if (token != null) {
      options.headers.addAll({"Authorization": "Bearer $token"});
    }
    return super.onRequest(options, handler);
  }

the refreshTokens function checks if a refresh token is needed then proceed.
if condition to eliminate the recursion.

I had to skip the previous approach, but I still do not know how reactive this approach is. Especially with parallel requests scenario.

Suggestion: Add an env.dart file

import 'package:nylo_framework/nylo_framework.dart';

class Env {
  static String API_BASE_URL = getEnv('API_BASE_URL');
}

will help in ide autocomplete for env var

Router extend

Need the ability to get the previous route name
Something like this: NyRouter().getPreviousRouteName()

build fails in nylo 5.11.0

After updating nylo from 5.8.0 to 5.11.0, my ios build fails with this error
Error (Xcode): ../../.pub-cache/hosted/pub.dev/nylo_support-5.17.0/lib/helpers/extensions.dart:264:7: Error: Type 'TextScaler' not found.

any dependent package needs to be updated?

Use Provider instead of Controller

Hi! Great work.

Why not replace Controllers with providers? With providers, we can interact with the state from the logic which is impossible with the controller.

I mean creating a Stateful widget(page) just like it is done actually and binding a dedicated Provider to that page.

This is an example:

PS: In my example, the stateless widget is useful to create the stateful one because it is the only way I've found to wrap the stateful widget with the Provider. But you may have a better approachπŸ€—.

class SignUpPage extends StatelessWidget {
  SignUpPage();

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => SignUpProvider(), // The provider of the page
      child: _SignUpPage(),
    );
  }
}

class _SignUpPage extends StatefulWidget {
  _SignUpPage();

  @override
  _SignUpPageState createState() => new _SignUpPageState();
}

class _SignUpPageState extends State<_SignUpPage> {
  // The provider to work with
  late SignUpProvider _provider = context.watch<SignUpProvider>(); 

  @override
  void initState() {
    super.initState();
  }
  
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        onTap: () => _provider.signUp(), // Call a method from the provider,
        child: Container(
          child: _provider.loading ? Text('Signing up...') : Text("Show form :).") // Display depending on the state
        )
      ),
    );
  }
}

This is what the provider may look like.

class SignUpProvider extends ChangeNotifier {
  bool loading = false; // Could be private with a getter to expose, and a setter to apply state change with "notifyListeners".
  
  void signUp() {
     // Some validations that could change the state too...
     
     // Mark loading
     loading = true;
     notifyListeners(); // This change updates the UI state.
     
    // API CALL...
    
     loading = false;
     notifyListeners();
  }
}

It will be amazing. It can be coupled with NyState too and can be fully optional for developers.

--- A little further in simplicity

We can even imagine a setState helper in the provider class to make it more familiar to developers who are not used to the provider pattern.

void setState(VoidCallback fn) {
  assert(fn != null);
  
  final Object? result = fn() as dynamic;
  
  assert(() {
      if (result is Future) {
        throw FlutterError.fromParts(<DiagnosticsNode>[
          ErrorSummary('setState() callback argument returned a Future.'),
          ErrorDescription(
            'The setState() method on $this was called with a closure or method that '
            'returned a Future. Maybe it is marked as "async".',
          ),
          ErrorHint(
            'Instead of performing asynchronous work inside a call to setState(), first '
            'execute the work (without updating the widget state), and then synchronously '
            'update the state inside a call to setState().',
          ),
        ]);
      }
      // We ignore other types of return values so that you can do things like:
      //   setState(() => x = 3);
      return true;
    }());
  
  notifyListeners();
}

Thank youuu!,

localization is broken

i spend hours trying to make it work as expected but it has a lot of issues, especially in RTL languages
nylo localization restarting the whole app and even after restarting UI doesn't switch to RTL
I end up using https://pub.dev/packages/easy_localization however I wich those problems get a fix

what we need Localization should happen without restarting the app and rtl UI should refresh

context is null in controller

I'd like to run onTodo method below code in controller class.

class HomeController extends Controller {
  @override
  construct(BuildContext context) {
    super.construct(context);
  }

onTodo() {
   Navigator.pushNamed(context!, "/todo");
   print(context == null ? "context is null" : "context is not null");
  }
}

home_page.dart:

...
MaterialButton(
                          child: Text(
                            "todo".tr().capitalize(),
                            style: Theme.of(context)
                                .textTheme
                                .bodyText1!
                                .setColor(
                                    context, (color) => color.surfaceContent),
                          ),
                          onPressed: widget.homeController.onTodo,
...

but context object is null.
error message: Exception has occurred._CastError (Null check operator used on a null value)

Hidden Features and Recipes

Hello everyone !

There are very few recipes using the framework.

For example, how do I check the saved token on the device, and transfer it to the router when downloading.

Some methods are not described in the documentation. For example, there is "handleSuccess", but the "handleFailure" method is not described. It is not clear how List works? routeGuards in routes. There are a lot of questions. Tell me that the project is not abandoned please )

UPD:
I made dependencies on checking the token and confirming the number in this way. I'm not sure if it's right, but everything works.
image

onGenerateRoute + ResponsiveFramework

Hi,
I'm trying to use Nylo + ResponsiveFramework
I was looking at this example but I have a problem...
How can I use their "onGenerateRoute" with Nylo:

runApp(
    AppBuild(
      navigatorKey: NyNavigator.instance.router.navigatorKey,
      onGenerateRoute: nylo.router!.generator(), // THIS ROW!!!
      debugShowCheckedModeBanner: false,
      initialRoute: nylo.getInitialRoute(),
    ),
  );

Thank you for your help! If this is the wrong place to ask, I'm sorry and please tell me where I can get help

Build failed TextScaler not found error

./../../.pub-cache/hosted/pub.dev/nylo_support-5.18.0/lib/helpers/extensions.dart:264:7: Error: Type 'TextScaler' not found.
TextScaler? textScaler,
^^^^^^^^^^

flutter 3.13.9 β€’ channel stable β€’ https://github.com/flutter/flutter.git
Framework β€’ revision d211f42860 (5 weeks ago) β€’ 2023-10-25 13:42:25 -0700
Engine β€’ revision 0545f8705d
Tools β€’ Dart 3.1.5 β€’ DevTools 2.25.0

Checking auth token externally before visiting initial route

I am storing my user token (from my external api) in the NyStorage so that when I close the app and reopen it at a later time it can still be used without having to login again. Now the problem is that I want to set the HomePage as the initialRoute when Auth.loggedIn() returns true (in the AuthGuard) and after I have done a request to my external api to check the token. I tried to set LoginPage as the initialRoute and then in the AuthProvider I did the request and based on that result it either just goes on or redirects to the HomePage on a successful request. The problem with this is that it shows the LoginPage for a brief moment before redirecting to the HomePage. I would like to show my HomePage initially (after doing the external api call to check the token) or show the LoginPage (this can be done via a redirect) when the request is not successful. I also tried doing the request in the AuthGuard but this does not seem to be called when setting HomePage as my initialRoute and also setting routeGuards: [AuthGuard] on it. What would be the best way to do this?

Theme font

Really love the concept of this framework and I am testing it on a project. Thanks for the good stuff.

final TextStyle appThemeFont = GoogleFonts.montserrat();

How can I switch the google font to a TTF font available from my assets folder in the theme file?

Null safety

I am working with flutter sdk 2.12.0 and above.

is it a plan on your side to refactor the method Appbuild() in bootstrap/app.dart?
It is currently causing some type and null safety issue

Back gesture not working in nylo

Hello Sir @agordn52 ,
when I create a project in Flutter itself.
the back gesture is working fine.

But in Nylo I'm not able to back by using gesture(finger horizontal swipe)

new hidden bug

I found bug in NyStorage:
Sometime on old phones have an error

 NyStorage.read at line 200 within nylo_support
PlatformException(Exception encountered, read, javax.crypto.BadPaddingException: error:1e000065:Cipher functions:OPENSSL_internal:BAD_DECRYPT
	at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method)
	at com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER.doFinalInternal(OpenSSLCipher.java:596)
	at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:363)

I think better choice use try-catch in the core: in String? data = await StorageManager.storage.read(key: key);
Will wait new update

validation not working when extends NyPage

validation not working when extends NyPage

import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';

class DashboardPage extends NyPage {

  static String path = '/dashboard';

  @override
  init() async {
    // initialize the page
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Dashboard")
      ),
      body: SafeArea(
         child: Container(
             child: Text("Hello World") // Build your UI
         ),
      ),
    );
  }
}

State Management

Discussed in #37

Originally posted by AdemAygun December 17, 2022
Hi ,
I'm new to flutter. I've been reviewing nylo framework recently. Nylo is good job.
It caught my attention that no package related to state management was used. Nylo uses NyState and NyStatefulWidget instead of other state management packages. (In this link , he used MVC+S pattern like nylo with state management )

Do you consider to add a milestone about state management(provider, bloc flutter,or riverpod ) in nylo framework ?

Nylo future upgrades and maintenance

Since Flutter & Dart releasing frequently i would like to check if we have a way to upgrade Nylo with out braking existing functionality

For example :

  • Nylo 1.x to 2.x
  • Upgrade to dart v2.14.0
  • Any major upcoming releases from flutter

How to override Dio baseoptions?

I couldn't override connectTimeout value in BaseOptions of Dio in NyBaseApiService class. Could you assist me to do that correctly?

In that class baseoptions initialized in the init method

  void init() {
    baseOptions = BaseOptions(
      baseUrl: baseUrl,
      headers: {
        "Content-type": "application/json",
        "Accept": "application/json",
      },
      connectTimeout: Duration(seconds: 5),  <!-- here
    );

    _api = Dio(baseOptions);

    if (useInterceptors) {
      _addInterceptors();
    }
  }

BaseOptions override does not work for request timeout

In the constructor of my api service I try to set the timeout of my requests to 10 seconds but whenever the request is sent it is still on 5 seconds.

ApiService:

class ApiService extends NyApiService {
  ApiService({BuildContext? buildContext})
      : super(buildContext, decoders: modelDecoders) {
    baseOptions = BaseOptions(
      connectTimeout: Duration(seconds: 10),
      receiveTimeout: Duration(seconds: 10),
      sendTimeout: Duration(seconds: 10),
    );
  }
}

Method to retrieve user:

Future<dynamic> checkUser() async {
    return await network(
      request: (request) {
        return request.get("/auth/me");
      },
      handleFailure: (DioException exception) {
        throw exception;
      },
    );
  }

Log shows 5 seconds instead of 10 and throws and exception because of it

I/flutter ( 3511): β•”β•£ Request β•‘ POST 
I/flutter ( 3511): β•‘  https://my-site.com/api/v1/auth/me
I/flutter ( 3511): β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
I/flutter ( 3511): β•” Headers 
I/flutter ( 3511): β•Ÿ Content-type: application/json
I/flutter ( 3511): β•Ÿ Accept: application/json
I/flutter ( 3511): β•Ÿ contentType: application/json
I/flutter ( 3511): β•Ÿ responseType: ResponseType.json
I/flutter ( 3511): β•Ÿ followRedirects: true
I/flutter ( 3511): β•Ÿ connectTimeout: 0:00:05.000000
I/flutter ( 3511): β•Ÿ receiveTimeout: null
I/flutter ( 3511): β•”β•£ DioError β•‘ DioExceptionType.connectionTimeout
I/flutter ( 3511): β•‘  The request connection took longer than 0:00:05.000000 and it was aborted. To get rid of this exception, try raising the RequestOptions.connectTimeout above the duration of 0:00:05.000000 or improve the response time of the server.

network localhost refused

i tested my API using postman it work fine however when i call it from nylo it fail

  Future<String?> GetTest() async {
    return await network<String>(
      request: (request) => request.get("/test"),
    );
  }
I/flutter (16330): β•”β•£ Request β•‘ GET 
I/flutter (16330): β•‘  http://localhost:3000/test
I/flutter (16330): β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
D/EGL_emulation(16330): app_time_stats: avg=96.64ms min=2.39ms max=501.03ms count=12
I/flutter (16330): 
I/flutter (16330): β•”β•£ DioError β•‘ DioExceptionType.connectionError
I/flutter (16330): β•‘  The connection errored: Connection refused
I/flutter (16330): β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
I/flutter (16330): [2023-10-18 23:54:37] error DioException [connection error]: The connection errored: Connection refused
I/flutter (16330): Error: SocketException: Connection refused (OS Error: Connection refused, errno = 111), address = localhost, port = 47028

Validate error

nylo_framework: ^5.0.2
Example:

  validate(
        rules: {
          "name": "not_empty",
          "email": "email",
          "phone number": "regex:(^[+\(\d+\)]+)"
        },
        data: {
          "name": nameFieldValue,
          "email": emailFieldValue,
          "phone number": phoneFieldValue,
        },
        messages: {
          "Name": "Name failed",
          "Email address": "Email failed",
          "Phone number": "Correct phone number format: +(**)**********"
        },
        onSuccess: () {
        },
        onFailure: (Exception exception) {
          print('Validate error: ${exception.toString()}');
        },
        showAlert: true, 
        alertStyle: ToastNotificationStyleType.DANGER);
  }

Alert doesn't show correct messages.It works only for first field

rightToLeftJoined transition animation error

My routes

appRouter() => nyRoutes((router) {
      // Home page
      router.route(
          RouterPages.homePage, (context) => MyHomePage(title: "Hello World"));

      // Auth routes
      router.route(RouterPages.startPage, (context) => StartPage(),
          transition: PageTransitionType.fade);
      router.route(
        RouterPages.loginByEmailPage,
        (context) => LoginByEmailPage(),
        transition: PageTransitionType.rightToLeftJoined,
      );
    });

// ignore: avoid_classes_with_only_static_members
/// Class holding all the routes
class RouterPages {
  /// Home page
  static String homePage = "/";

  /// Start page shown before login screen
  static String startPage = "/auth/start";

  /// Login by email page
  static String loginByEmailPage = "/auth/login_by_email";
}

getting this error
image

NyTextField

am using NyTextField it works well however how could I know if all fields are correct when I press submit button
Thank you

NyText extension

A member named 'bodyMedium', 'bodyLarge' etc... is defined in extension 'NyText' and extension 'NyText', and none are more specific.
Questions: why? what to do if I have a project based on prev version?

widget.data() still have data

assume i have 3 screen
1 and 2 have relation between
example screen 1 is listing page
and 2 has view page
but if come 2 screen using 3rd screen
still widget.data() hold a value

Bug. Parameters are not passed to the view

As I have not tried - but the parameters are not transmitted. Not the routeTo helper("/order-view", data: "Hello world!"), nor Navigator.pushNamed(context, "/order-view",arguments: "Hello World");

=((((((

image

P.S.
Found the reason, did not specify:
final HomeController controller = HomeController()

I hope it saves time for those who are looking, the ticket can be closed)

Metro error(dart 3)

Flutter 3.11 +Tools β€’ Dart 3.1.0 (build 3.1.0-63.1.beta) β€’ DevTools 2.23.1
ERRORS:

  • alias metro:
    Deprecated. Use dart run instead.
  • metro commands run:
    Unhandled exception:
    Unsupported operation: Cannot remove from a fixed-length list
    #0 FixedLengthListMixin.removeAt (dart:_internal/list.dart:61:5)
    #1 commands (package:nylo_framework/metro/metro.dart:111:13)
    #2 main (file:///***/.pub-cache/hosted/pub.dev/nylo_framework-4.1.4/bin/main.dart:13:19)
    #3 _delayEntrypointInvocation. (dart:isolate-patch/isolate_patch.dart:294:33)
    #4 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:189:12)

Will wait Nylo 5.0 without errors)))

need more documentations/examples

  • need more documentation on complex scenarios like nested route, state management
  • is there any discord/slack server where devs can ask support questions?
  • is there any complex app examples ? chat app, e-commerce app, todo ?
  • how to contribute ?
  • what is future roadmap ?

Update readme

The readme requirements are different to the website's one:

Repo readme:
image

Website requirements page:
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.