Your best flutter coding friend. All in one; state management, navigation management(with dynamic routing), local storage, localization, dependency injection, cool extensions with best usages and with the support of best utilities!

Overview

okito

Your best flutter coding friend. All in one; state management, navigation management(with dynamic routing), local storage, dependency injection, localization, cool extensions with best usages and with the support of best utilities!

pub points likes popularity GitHub Repo stars pub version GitHub last commit

Click here to join our discord community channel!

 

Features

Contents

 

State Management

Create Controller

Q: What should I do to make it work?
A: Just create a regular class and extend OkitoController, if you want to change the state, call update() or setState()

Q: How does these methods notify the state?
A: They have a conversation between themselves, whenever you call these methods, the notifier checks all the builders, if they are watching, they will be re-built. So the scheme is;

Model -> Controller -> Model
View -> Controller -> View
The controller is the root of them.

class CounterController extends OkitoController {
  int count = 0;

  void increment() => setState(() => count++);

  void decrement() {
    count--;
    update();
  }
}

CounterController counterController = CounterController();

You can also use setStateAsync function to update data asynchronously.


Use Controller

// That simple!
OkitoBuilder(
      controller: counterController,
      builder: () => Text('${counterController.count}'),
    );

Update Controller

    main(){
        // You can change state from anywhere without context!
        counterController.increment();
    }

    // In Flutter
    ElevatedButton(
                  onPressed: counterController.increment,
                  child: const Text('Increment'),
                )
    // Or
     ElevatedButton(
                  onPressed: () => counterController
                      .setState(() => counterController.count--),
                  child: const Text('Decrement'),
                )

Rockitos

Rockitos are our way to use state management with dependency injection!
If you don't know what is dependency injection, read Dependency Injection Guide first.

// Rockito - My favorite vay to use Okito state.

Rockito<CounterController>(
  (controller) => Text('${controller.count}')
);
// Isn't it  simple ?
// To use _Rockito_, you should first inject the CounterController.

Okito.inject(CounterController);
// RockitoBuilder - Rockito but with more features and builder!
  RockitoBuilder<CounterController>(
    inject: CounterController(), // optionally, if you didn't inject it yet.
    builder: (controller) => Text('${controller.count}'),
    // You can use all of OkitoBuilder features here like otherControllers and etc.
  );

Watch Controller

    OkitoWatcher(
    watch: counterController,
    onChange: (CounterController controller) {
      // You can also update the state there.
      // onChange gives to you is the instance of controller.
      print(controller.count);
    },
  );
  counterController.increment();

  // OkitoWatcher also returns a function that stops watching which
  // reduces the memory usage, you can use it when your usage ends.

  final stopWatching = OkitoWatcher(/* code here */);
  // do what you want to do while watching, then:
  stopWatching();
// You can also watch with Rockitos.
RockitoWatcher<CounterController>(
  (controller) => print(controller.count))
// You have to inject the controller first.

State Methods

State methods are methods like the State class of Flutter.

class CounterController extends OkitoController{
  int count = 0;

  /// This will be called whenever your [OkitoBuilder] is mounted
  // to the widget tree.
  @override
  void initState() {
    count++;
  }
  /// This will be called whenever your [OkitoBuilder] is removed
  /// from the widget tree.
  @override
  void dispose() {
    count = 0;
  }
}

I personally use State Methods when I use controllers as StatefulWidget replacers.
Example:

class EditProductController extends OkitoController {
  // other nodes here
  final priceFocusNode = FocusNode();

  void submitForm(){
    // I use my inputControllers here to get their values.
    // then I use my Okito routing without context!
    Okito.pushNamed('/productUpdatedSuccessfully/31')
  }

  @override
  void dispose() {
    // other nodes here to [dispose].
    priceFocusNode.dispose();
  }
}

Utilities

Navigation and using widgets without context.

Firstly, we should wrap our app with Okito or provide Okito

// Basically, you should add *Okito* to the beginning of your app or provide key/observers manually.

OkitoMaterialApp(/*  Everything is same with [MaterialApp] */);

// Or
OkitoCupertinoApp(/*  Everything is same with [CupertinoApp] */);

// Or
Material/CupertinoApp(
    navigatorKey: Okito.navigatorKey,
    navigatorObservers: [OkitoObserver()]);

Then you can use all of Okito Benefits!

All of the properities has same usages with its long usage

For example: Okito.pushNamed('/secondPage') = Navigator.of(context).pushNamed('secondPage')

Okito.width;
Okito.height;
Okito.aspectRatio;
Okito.devicePixelRatio;
Okito.isLandscape;
Okito.isPortrait;
Okito.theme;

Okito.showSnackBar();
Okito.showToast(); // Snackbar without widget, usefull for simple usage.
Okito.showModal();
Okito.showDialog();

Okito.push();
Okito.pushReplacement();
Okito.pushNamed();
Okito.pushReplacementNamed();
Okito.pop();
Okito.arguments;
Okito.routeName;

Routing Management

Lets say that you want dynamic urls like

/posts/:id
/posts/23

And this id is a dynamic variable, right?
With Okito, you can do that easily!

// You don't need to add something like OkitoPage or etc.
// Okito lets you do your job without code changes.
OkitoMaterialApp(
      routes: {
        '/': (ctx) => FirstPage(),
        '/second/:id': (ctx) => SecondPage(),
      }
);

Now, whenever you try this:

ElevatedButton(
  onPressed: () => Okito.pushNamed(
    /// You can add any kind of arguments
    '/second/33?name=Rago&postId=123&isMaterial=true',
    arguments: 'This is an extra argument'),
    child: const Text('Go to second page'),
  )

It will push to second page with the argument [id] : [33]

Moreover, you will see your arguments like this:

print(Okito.arguments);
// result
{'id' : '33', 'name' : 'Rago', 'postId' : 123, 'isMaterial' : true, 'arguments': 'This is an extra argument'};
// Yes, you can even get extra arguments manually.

Check example/flutter_dynamic_routing/lib/main.dart for a live example.

Would you like to have more benefits? Of course!

Theme Management

// Firstly, the bottom method gives you the app controller, you can update anything manually.
Okito.app; /* or */ Okito.use<AppController>();

// Then you have all of its usages.

Okito.app.setThemeData();
Okito.app.setThemeMode();
Okito.app.setCupertinoThemeData();

Okito.app.locale;
Okito.app.setLocale();

Local Storage

OkitoStorage is a way to save variables to the local storage.

It works like SharedPereferences but it is synchronous like GetStorage.

OkitoStorage is blazingly fast because in read operations it uses memory to get data instead of reading from disk everytime!

// To use, you should init the storage, it is not required for web but required for all other platforms.

void main() async{
  // Only init is asynchronous, you can also call without await but it is not recommended.
  await OkitoStorage.init();


  // Usage
  final box = OkitoStorage; // For easier reference.

  box.write('count', 0);

  final int count = box.read<int>('count');
  // Simple as this!

  print('Count is $count');
  // Rest of your code will be here.
}

Other Usages

  box.watchKey('count', () =>
    print('This function will be called whenever the count changes.');
  );

  box.watchAll(() =>
    print('This function will be called whenever the storage changes.');
  );

  box.removeKey('count'); // Removes the key

  box.readAllKeys(); // returns all keys in storage

  box.readAllValues(); // returns all values in storage

  box.readAll(); // returns all of the storage

  box.clearStorage(); // removes everything from the storage but storage will still exists.

  box.deleteStorage(); // removes the storage from file system completely, after this operation, OkitoStorage won't be able to write or read.

Watch OkitoStorage With OkitoBuilder

// Check the example/flutter_okito_storage/lib/main.dart for more examples!

// It will run whenever key 'count' changes.
OkitoBuilder(
      controller: yourController,
      watchStorageKeys: ['count'],
      builder: () => Text('${box.read('count')}'),
    );

Benefits Of OkitoStorage

  • Really fast
  • You can watch the changes from anywhere, even in your builders.
  • It is synchronous, so you don't have to use 'await' keyword.
  • You can storage Strings, ints, Maps and even Lists.
  • Works on any device that flutter supports!

OkitoStorage is reliable but be careful when using it as database, because it is not created to be database. For complex works, you can try Hive!

Localization

For global apps, it might be hard to find a new library for localization or creating your own, then you will probably have another problems like updating the whole app after language change and etc. Why would you do that?

Okito provides localization solutions for your app.

// It is also so simple to have!
// Firstly create your translations like this:
const translations = {
  'en': {
    'hello': 'Hello from Okito!',
  },
  'tr': {
    'hello': "Okito'dan selamlar!",
  },
};
// You can have unlimited amount of locales and translations
// You can make it dynamic, seperate files and etc. It is just a dart map!
// After creating it, give it to the app.
OkitoMaterialApp /* or OkitoCupertinoApp */(
  translations: translations,
  /* Your code here without any change */);
// Using it? It is the simplest! Lets use it in a text widget.
Text('hello'.loc); // It will show 'Hello from Okito!'

// Lets change the language and see it again.
Okito.app.setLocale(Locale('tr','TR'));
// Now it says: 'Okito'dan selamlar!' as it is declared in translations.
// You can also set it like this;
Okito.localize('hello'); // returns the translation as String.

For better examples check example/flutter_localization/lib/main.dart

Extensions

// Context Extensions
context.width;
context.height;
context.aspectRatio;
context.devicePixelRatio;
context.isLandscape;
context.isPortrait;
context.theme;
context.arguments;
context.routeName;

Dependency Injection

Dependency injection is your way to inject variables to the Okito and use it anywhere in your app. With Okito, it is as simple as it can be!

// Example Variable
class Counter(){
  count = 0;
}

// Inject it
Okito.inject(Counter());


// Use it anywhere!
Okito.use<Counter>();

// Asign it with type support!
final counter = Okito.use<Counter>();

// Update however you want
counter.count++;
// or
Okito.use<Counter>().count++;

Soo, lets say that your job is done with that class, why would we let it to use memory?

// Counter will be gone forever!
Okito.eject<Counter>();

For more details, check the tests or examples about it!

Injection With Keys

It is useful when you want to storage with a String key instead of type which gives you advantage of multiple injects with same type.

// Example Variable
class Counter(){
  count = 0;
}

// Inject it
Okito.injectWithKey('firstCounter',Counter());
Okito.injectWithKey('secondCounter',Counter());


// Use it anywhere with type support!
final firstCounter = Okito.useWithKey<Counter>('firstCounter');
final secondCounter = Okito.useWithKey<Counter>('secondCounter');

// Update however you want
firstCounter.count++;
secondCounter.count++;

Soo, lets say that your job is done with that class, why would we let it to use memory?

// Second counter will be gone forever!
Okito.ejectWithKey('secondCounter');

Tips

Cleaner Widgets

// In your widgets folder or any other folder, declare builder.
OkitoBuilder CounterBuilder({
  required Widget Function() builder,
}) =>
    OkitoBuilder(
      controller: counterController,
      builder: () => builder(),
    );

// Usage
CounterBuilder(builder: () => Text('${counterController.count}'));

My Favorite Way

OkitoBuilder CounterBuilder({
  required Widget Function(CounterController state) builder,
}) =>
    OkitoBuilder(
      controller: counterController,
      builder: () => builder(counterController),
    );

// Usage
CounterBuilder(builder: (state) => Text('${state.count}'));

Update State

class CounterController extends OkitoController {
  int _count = 0;

  int get count => _count;

  set count(int count) {
    _count = count;
    // Now, whenever you change count like 'count++', it will update state.
    update();
  }
}

App Controller

It is the controller of app, you can wrap your widgets that you want to change on big updates like theme changes if the data you wrote is not coming from a controller.

Rockito<AppController>(
  (app) => // yourWidget
)

Tutorials

Examples

How to contribute okito

  • okito needs tests.
  • okito needs more examples.
  • okito needs a better readme file :D
  • okito needs reputition, likes and users!
  • okito needs test with Apple products, I tested on linux, android, web and Windows
You might also like...

Generates utilities to aid in serializing to/from JSON.

Provides Dart Build System builders for handling JSON. json_serializable Package: https://pub.dev/packages/json_serializable Source code The core pack

Jan 8, 2023

A CLI for syncing Dart dependency versions between pubspec.yaml and pubspec.lock files.

lockpick A CLI for syncing Dart dependency versions between pubspec.yaml and pubspec.lock files. 🔒 Usage # Activate lockpick pub global activate lock

Oct 17, 2022

Library for help you make userbot or bot telegram and support tdlib telegram database and only support nodejs dart and google-apps-script

To-Do telegram client dart ✅️ support multi token ( bot / userbot ) ✅️ support bot and userbot ✅️ support telegram-bot-api local server ✅️ support tel

Jan 7, 2023

Let's Encrypt support for the shelf package (free and automatic HTTPS certificate support).

shelf_letsencrypt shelf_letsencrypt brings support for Let's Encrypt to the shelf package. Usage To use the LetsEncrypt class import 'dart:io'; impor

Oct 31, 2022

Flutter Cool Random User Generate 🔥🔥

Flutter Cool Random User Generate 🔥🔥

Flutter Cool Random User Generate 🔥🔥

Sep 10, 2022

Flutter localization example

Flutter localization example

📌 Showcase 📌 Installation ✔️ 패키지 추가 & 디렉토리 선언 (pubspec.yaml) dependencies: easy_localization: ^3.0.0 # 현지화 flutter_phoenix: ^1.0.0 # 앱 재시작 flu

May 21, 2022

Doing cool stuff with Git VCS in dart programming language.

Git Assistant Assists you to use git and .git in easy and simple way with robust API Features Generates git commands in simple form Supports commands,

Mar 4, 2022

An example todo list back end project that uses gRPC for client-server communication and Firestore for data storage

An example todo list back end project that uses gRPC for client-server communication and Firestore for data storage

Apr 18, 2022

A flutter application , that create dynamic forms from json data

checktyper A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if th

Aug 23, 2022
Comments
  • Pattern with Stroage

    Pattern with Stroage

    https://github.com/ragokan/okito/blob/a0b41f1420baa5b09e4d7371f82da796059ebb46/lib/bin/okito_storage/modules/okito_io_storage.dart#L7

    öncelikle eline sağık bence çok tatlı olmuş tüm katmanlar kendin yazmış olman tüm patternleri nice to have. -Stroage işlemlerini bir strategy pattern yapsak yarın yeni bir alan gelse misal nosql sambas, realm vs hepsınde ne tarz methodlar yapacağımız belirli olsa rahatlıkla projeyi ona evirebilsek contr vs içinde çok iyi olabilir vexanadaki bu örneğe bakabilrisin.

    Eline sağık iyi çalışmalar

    opened by VB10 1
Releases(1.1.4)
  • 1.1.4(Apr 11, 2021)

    We are slowly going to be more stable, after these updates, probably there won't be any update that changes your code. We mostly aim new updates with bug fixes and performance improvements. Of course we will also have new features in future.

    • New routing functions including 'easy' usage.
    • New state methods: 'initState' and 'dispose' in controller.
    • New folder structure, thanks to @IsmailAlamKhan
    • Finally more bug fixes and better documentation, also some of updates actually increased the performance of the Okito!
    Source code(tar.gz)
    Source code(zip)
  • 1.0.8(Apr 6, 2021)

    • Dynamic routing, check examples/readme file.
    • Localization, details on examples and readme file.
    • Better optimization for code.
    • New utilities: setTheme and setLocale while running the app.
    • As usual, more examples, more tests, new extensions.
    • I also added documentation to most used app variables for OkitoMaterialApp/OkitoCupertinoApp
    • Now Okito provides more opportunities to adjust variables like Okito.app!
    Source code(tar.gz)
    Source code(zip)
  • 1.0.5(Apr 3, 2021)

    • The biggest update since initial release.
    • Okito now doesn't need any context for utilities.
    • New features with OkitoMaterialApp and OkitoCupertinoApp are here!
    • Now, Okito can use routing, and it will be done without context.
    • Snackbar, modal, dialog, they all will be available without context!
    • More examples, especially for new features.
    • More tests, especially for new features.
    • New features with OkitoStorage that lets you use local storage on any device!
    Source code(tar.gz)
    Source code(zip)
  • 1.0.4(Mar 31, 2021)

    • New feature: OkitoWatcher (Check test/okito_watcher_test.dart)
    • More examples
    • More tests
    • Document for OkitoWatcher
    • Document for all variables and parameters
    Source code(tar.gz)
    Source code(zip)
  • 1.0.2(Mar 29, 2021)

  • 1.0.0(Mar 27, 2021)

Owner
Okan YILDIRIM
I'm Okan, a Mobile/Web Developer. Check my website for further information and contact.
Okan YILDIRIM
Fluro is a Flutter routing library that adds flexible routing options like wildcards, named parameters and clear route definitions.

Fluro is a Flutter routing library that adds flexible routing options like wildcards, named parameters and clear route definitions.

Luke Pighetti 3.5k Jan 4, 2023
Dependency Injection is a great design pattern that allows us to eliminate rigid dependencies between elements and it makes the application more flexible

GetX lib DI pattern Dependency Injection is a great design pattern that allows us to eliminate rigid dependencies between elements and it makes the ap

Trương Việt Hoàng 4 Feb 1, 2022
library to help you create database on local memory, support json local database inspired by lowdb

Licensed Licensed under the MIT License <http://opensource.org/licenses/MIT>. SPDX-License-Identifier: MIT Copyright (c) 2021 Azkadev <http://github.c

Azka Full Snack Developer:) 35 Oct 17, 2022
A flutter plugin that provides external storage path and external public storage path

ext_storage ext_storage is minimal flutter plugin that provides external storage path and external public storage path

null 0 Nov 16, 2021
Easy to use session wrapper that adds support to session storage and management in flutter.

flutter_session_manager Adds an easy to use wrapper to session management in flutter. Allows for easy session storage and management. The session pers

Eduardo Migueis 2 Feb 15, 2022
Queen support for localization in flutter

Nations ?? Features translation without context ?? custom configuration value not found builder fallback locale supported locales fall back to base be

Ahmed Masoud 10 Jun 22, 2022
A package that lets you include a cool, nice looking and validated Password TextFormField in your app to enhance user experience. The package is fully & easily modifiable.

A package that lets you include a cool, nice looking and validated Password TextFormField in your app to enhance user experience. The package is fully

Muhammad Hamza 20 Jun 7, 2022
Provides Dart Build System builder for creating Injection pattern using annotations.

Provides Dart Build System builder for creating Injection pattern using annotations. Gate generator The core package providing generators using annoat

Apparence.io 17 Dec 20, 2022
Material color utilities

Material color utilities Algorithms and utilities that power the Material Design 3 (M3) color system, including choosing theme colors from images and

null 878 Jan 8, 2023
Utilities to make working with 'Duration's easier.

duration Utilities to make working with 'Duration's easier. NOTE: Use prettyDuration, prettySeconds, prettyMilliseconds instead of printDuration, prin

null 45 Sep 21, 2022