basecraft

A reusable project setup package for Flutter applications β€” includes core utilities, networking layer, base configurations, and helper functions to streamline app development.

✨ Features

  • πŸ“¦ Easy integration into any Flutter app
  • 🌐 Pre-configured network layer (Dio, interceptors)
  • πŸ“ Path and file helpers (path_provider)
  • 🧱 Modular architecture ready for scaling
  • πŸ”§ Utility functions for common tasks

πŸš€ Getting Started

Add this package to your pubspec.yaml:

dependencies:
  basecraft: ^2.0.1

Then run:

flutter pub get

ApiClient (Dart)

A powerful, customizable, and easy-to-use API client built for Dart and Flutter. This singleton class provides support for common HTTP methods (GET, POST, PUT, PATCH, DELETE), file downloading, error handling, and connectivity checks.

✨ Features

  • βœ… Singleton design for easy global access
  • πŸ”— Base URL and custom headers configuration
  • ⏱ Configurable timeouts for requests
  • πŸͺ΅ Built-in logging interceptor for request/response logs
  • 🌐 Internet connectivity checker
  • πŸ“₯ File download support
  • 🧠 Automatic error handling with meaningful messages

πŸš€ Getting Started

Initialization

ApiClient.instance.init(
baseUrl: "https://api.example.com",
connectTimeout: Duration(seconds: 10),
receiveTimeout: Duration(seconds: 10),
);

πŸ§ͺ Usage Examples

GET Request

final response = await ApiClient.instance.get("/users", query: {"page": 1});

POST Request

final response = await ApiClient.instance.post("/login", {
"email": "test@example.com",
"password": "123456",
});

PUT Request

final response = await ApiClient.instance.put("/users/1", {
"name": "Updated Name",
});

PATCH Request

final response = await ApiClient.instance.patch("/users/1", {
"email": "updated@example.com",
});

DELETE Request

final response = await ApiClient.instance.delete("/users/1");

DOWNLOAD Request

final file = await ApiClient.instance.download("https://example.com/file.pdf");

INTERNET CONNECTIVITY CHECK

bool isOnline = await ApiClient.instance.isConnected();

SqfLiteService (Dart/Flutter)

A singleton service for managing SQLite database operations using the sqflite package in Flutter. This service provides a structured and reusable interface for common CRUD operations with customizable database configuration through an abstract DbHelper.

✨ Features

  • πŸ”„ Singleton pattern to ensure a single instance of the database

  • 🧱 Abstract DbHelper for customizable DB/table configuration

  • πŸ“ Support for basic CRUD operations:

    • get()
    • add()
    • update()
    • delete()
  • ⚠️ Error handling with descriptive messages

  • 🧩 Hooks for upgrade/downgrade callbacks

πŸ§ͺ Example Usage

1. Create a DbHelper Implementation

class MyDbHelper extends DbHelper {
  @override
  String get databaseName => 'my_database.db';

  @override
  int get version => 1;

  @override
  String get tableName => 'users';

  @override
  String get createTable => '''
    CREATE TABLE users (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT,
      email TEXT
    )
  ''';

  @override
  Function(Database, int, int)? get onUpgrade => (db, oldVersion, newVersion) {
    // Handle upgrade logic
  };

  @override
  Function(Database, int, int)? get onDowngrade => (db, oldVersion, newVersion) {
    // Handle downgrade logic
  };
}

2. Initialize the Database

await SqfLiteService.instance.init(MyDbHelper());

3. Perform CRUD Operations

ADD

await SqfLiteService.instance.add({
'name': 'John Doe',
'email': 'john@example.com',
});

GET

final data = await SqfLiteService.instance.get(orderBy: 'name ASC');

UPDATE

await SqfLiteService.instance.update(
{'email': 'newemail@example.com'},
'id = ?',
[1],
);

DELETE

await SqfLiteService.instance.delete(where: 'id = ?', whereArgs: [1]);

AppStorage (Dart/Flutter)

A lightweight singleton wrapper around get_storage for simple key-value storage in Flutter. Ideal for saving user preferences, flags, tokens, and other small pieces of persistent data.

✨ Features

  • βœ… Singleton pattern for global access

  • 🧠 In-memory + persistent key-value storage

  • πŸ“‚ Customizable storage container name

  • πŸ— Simple read/write/delete interface

  • 🧹 Supports clearing entire storage

πŸš€ Usage

1. Initialize Storage

⚠️ You must initialize the storage before using it.

await AppStorage.instance.init(); // Optionally: init(containerName: 'MyBox')

2. Set a Value

AppStorage.instance.setValueFor('isLoggedIn', true);

3. Get a Value

var isLoggedIn = AppStorage.instance.valueFor('isLoggedIn');

4. Remove a Value

AppStorage.instance.removeKey('isLoggedIn');

5. Clear All Stored Data

AppStorage.instance.clear();

πŸ§ͺ Example

void main() async {
  await AppStorage.instance.init();

  AppStorage.instance.setValueFor('theme', 'dark');
  var theme = AppStorage.instance.valueFor('theme');
  print('Current theme: $theme'); // Output: dark

  AppStorage.instance.removeKey('theme');
  AppStorage.instance.clear(); // Removes everything
}

CacheStorage (Dart/Flutter)

A static utility class for basic local file operations in Dart/Flutter. It provides an easy-to-use API for saving, reading, and deleting both text and binary files in a specified directory.

πŸ“¦ Features

  • πŸ“„ Save and read text files (.txt)
  • 🧱 Save and read binary files (Uint8List)
  • 🧹 Delete files from disk
  • πŸ“ Automatically creates target directories if they don’t exist
  • πŸͺΆ Lightweight and dependency-free (uses dart:io)

πŸš€ Getting Started

1. Save a Text File

await CacheStorage.saveTextFile('/path/to/folder', 'example', 'Hello, World!');

2. Read a Text File

String? contents = await CacheStorage.readTextFile('/path/to/folder', 'example');
print(contents); // "Hello, World!"

3. Save a Binary File

Uint8List bytes = await getSomeBinaryData();
await CacheStorage.saveFile('/path/to/folder', 'image.png', bytes);

4. Read a Binary File

Uint8List? bytes = await CacheStorage.readFile('/path/to/folder', 'image.png');
if (bytes != null) {
// Do something with the binary data
}

5. Delete a File

await CacheStorage.delete('/path/to/folder', 'example.txt');

πŸ“ File Location Tips

You can use the path_provider package to get platform-specific directories:

import 'package:path_provider/path_provider.dart';

final directory = await getApplicationDocumentsDirectory();
await CacheStorage.saveTextFile(directory.path, 'myfile', 'Hello');

Glass Widget

A simple Flutter widget that adds a glassmorphism effect.

πŸ”§ Constructor

Glass({
  double blurX = 0,
  double blurY = 0,
  BorderRadiusGeometry? borderRadius,
  Widget? child,
})

πŸ“š PaginationController & PagingListView

A lightweight, flexible solution for paginated list views in Flutter with pull-to-refresh and infinite scroll support.

πŸ“˜ How to Use PaginationController & PagingListView

1. Create a Controller

final controller = PaginationController<MyItem>(
  limit: 20,
  fetchPage: (page, size) => myApi.getItems(page, size),
);

2. Use with PagingListView

PagingListView<MyItem>(
  controller: controller,
  itemBuilder: (context, item, index) {
    return ListTile(title: Text(item.title));
  },
  separatorWidget: Divider(),
  emptyListWidget: Text('No items found'),
  loadingWidget: Center(child: CircularProgressIndicator()),
);

3. Refresh Manually (Optional)

ElevatedButton(
  onPressed: () {
    controller.refresh();
  },
  child: Text("Reload"),
)

✍️ SignaturePage

The SignaturePage widget provides a canvas for users to draw their signature using touch input. It allows users to clear the canvas or save the signature as an image file.

πŸš€ Usage

Get.to(() => SignaturePage())?.then((value) {
  if (value != null) {
    // Here, you get the path of saved signature.
  }
});

🎞️ Animation Widgets

The animation widgets like FadeIn, FadeOut, Flip, Rotate, Slide, ZoomIn, ZoomOut, and Pulse from the basecraft package allow you to easily add repeatable animations to any widget.

These animations can be customized and reused across your UI to create smooth, eye-catching effects.

πŸš€ Usage

Wrap any widget with an animation widget:

FadeIn(
  repeat: true,
  child: YourWidget(),
);

Rotate(
  repeat: true,
  child: Container(color: Colors.green),
);

Flip(
  axis: FlipAxis.Y,
  repeat: true,
  child: Text("Flip Me"),
);

πŸ“‘ Websocket Utility

It manages WebSocket connections with simplified APIs for initializing, listening, emitting, and closing connections.

βœ… Features

  • Singleton access: Websocket.instance
  • Auto-connect to WebSocket URL with ping and SSL options
  • Customizable connection lifecycle callbacks
  • Message handling, event listening, and emitting
  • Graceful close support

πŸ”§ Usage

Initialized
Websocket.instance.init(
  url: 'ws://yourserver.com',
  onOpen: () => print('βœ… WebSocket connected!'),
  onClose: (close) => print('❌ WebSocket closed: $close'),
  onError: (error) => print('⚠️ WebSocket error: $error'),
);
Perform operation on message receive
Websocket.instance.onMessage((msg) {
  print("πŸ“© Message received: $msg");
});
Listen to Events
Websocket.instance.listenTo("chat", (data) {
  print("πŸ’¬ Chat event: $data");
});
Sent Message to Specific Event
Websocket.instance.sentTo(event: "join", data: {"room": "flutter"});
Send Message
Websocket.instance.send("Simple string message");
Close Connection
Websocket.instance.close(reason: "App exit");

🌐 CheckInternet Utility

A lightweight Dart singleton class for monitoring internet connectivity status in real-time.
It checks for connectivity by resolving google.com periodically and updates the status accordingly.

πŸ“¦ Features

  • Singleton access via CheckInternet.instance
  • Periodic internet status checks (defaults to every 5 seconds)
  • Uses native Dart dart:io (no extra dependencies)
  • Enum-based connection status: online, offline, unknown
  • Ability to stop checks manually with .stop()

πŸš€ Usage

Start monitoring

CheckInternet.instance.init(duration: Duration(seconds: 10));

Access current connection status

var status = CheckInternet.instance.status;

Stop monitoring when done

CheckInternet.instance.stop();

πŸ” PermissionHandler Utility

A Flutter singleton utility for managing and checking runtime permissions across multiple platforms.
This class simplifies permission handling by abstracting platform-specific logic behind a clean Dart interface.

πŸ“¦ Features

  • Singleton access via PermissionHandler.instance
  • Supports checking and requesting:
    • Camera
    • Microphone
    • Bluetooth
    • Storage
    • Contacts
    • Location
    • Notification
    • Biometric
    • Calendar
    • Motion Sensors
  • Provides individual permission getters for easier UI/state logic
  • Uses a unified platform interface for calling native platform code

πŸš€ Usage

βœ… Initialize with Specific Permissions

await PermissionHandler.instance.init([
  Permission.camera,
  Permission.microphone,
  Permission.location,
]);

πŸ” Check Current Permission Status

bool isCameraGranted = PermissionHandler.instance.isCameraPermissionGranted;
bool isLocationGranted = PermissionHandler.instance.isLocationPermissionGranted;

πŸ“€ Request a Specific Permission

bool granted = await PermissionHandler.instance.requestPermission(Permission.camera);

βš™οΈ Open App Setting

PermissionHandler.instance.openSettings();

πŸ”„ Shimmer Widget

Easily add shimmer loading placeholders with basecraft.

βœ… Basic Usage

Shimmer(
  isLoading: true,
  child: YourActualWidget(),
)

🎨 With Custom Shimmer Layout

Shimmer(
  isLoading: true,
  shimmerWidget: YourShimmerPlaceholder(),
  child: YourActualWidget(),
)

βš™οΈ Parameters

Property Type Description
isLoading bool Toggle shimmer effect
child Widget Content to show when not loading
shimmerWidget Widget? Optional custom shimmer layout
linearGradient LinearGradient? Customize shimmer animation gradient

πŸ“ƒ License

This project is licensed under the MIT License.


πŸ’¬ Author

Made️ by ⚑️ Rugved Apraj