otp_count_down_plus 2.2.0 copy "otp_count_down_plus: ^2.2.0" to clipboard
otp_count_down_plus: ^2.2.0 copied to clipboard

A fork of otp_count_down package. A new dart package for easy implementation of OTP Count Down.

otp_count_down_plus #

Easily implement a countdown timer in Flutter applications (Forked from otp_count_down by Hitesh Garg).

This package is a pure headless countdown utility supporting Dart 3 (SDK >=2.17.0 <4.0.0) that handles timer synchronization, app lifecycle states, and backoff mathematical models, while leaving 100% of the UI design to the developer.

Features #

  • Drift-Free Precision: Calculates remaining time based on absolute target timestamps, eliminating timer drift caused by event-loop delays.
  • Background Time Sync: Automatically synchronizes remaining time when the app returns from background using system time differentials and WidgetsBindingObserver.
  • Auto Persistence & Recovery: Seamlessly persist target end time (onSaveState, onClearState) and restore countdowns across app restarts via OTPCountDown.restoreOTPTimer().
  • Hours Support (HH:mm:ss): Automatically formats countdown to include hours when remaining time >= 1 hour (e.g., "01:15:30").
  • Cooldown Backoff: Support for exponential or custom backoff strategies when resending OTPs (e.g. attempt 1 is 30s, attempt 2 is 60s...).
  • Persistence Hook (onTick): A callback returning the exact remaining milliseconds on every tick.
  • Milestone Callbacks: Trigger events at specific countdown milestones (e.g. at 5 seconds remaining).
  • Streams support: Expose countDownStream and remainingTimeStream for reactive state management.
  • Timer Controls & Safe Disposal: Pause, resume, restart, and isDisposed status checking to avoid stream memory errors.
  • Custom Formatting & Tick Intervals: Provide a custom formatting function and change the tick duration (e.g. 500ms instead of 1 second).
  • Responsive Initialization: Emits initial formatted value immediately on initialization to avoid the typical 1-second delay.

Usage #

1. Initializing and Starting the Timer #

import 'package:otp_count_down_plus/otp_count_down_plus.dart';

late OTPCountDown _otpCountDown;
final int _otpTimeInMS = 1000 * 5 * 60; // 5 minutes

_otpCountDown = OTPCountDown.startOTPTimer(
    timeInMS: _otpTimeInMS,
    currentCountDown: (String countDown) {
        print("Count down : $countDown"); // e.g., "05:00"
    },
    onFinish: () {
        print("Count down finished!");
    },
);

2. Reactive UI (StreamBuilder) #

You can bind OTPCountDown streams directly to your own custom UI:

StreamBuilder<String>(
  stream: _otpCountDown.countDownStream,
  initialData: "05:00",
  builder: (context, snapshot) {
    final String formattedTime = snapshot.data ?? "00:00";
    final bool isTimeUp = _otpCountDown.remainingTimeInMS <= 0;

    return Column(
      children: [
        Text("Resend code in: $formattedTime"),
        ElevatedButton(
          onPressed: isTimeUp ? () {
            // Trigger resend & restart timer
            _otpCountDown.restart(1000 * 5 * 60);
          } : null,
          child: const Text("Resend OTP"),
        ),
      ],
    );
  },
)

3. Cooldown Backoff Strategy #

Multiply the cooldown duration automatically with each attempt:

// Restarts using a linear backoff strategy (1x, 2x, 3x duration)
_otpCountDown.restartWithBackoff(
  baseDuration: const Duration(seconds: 30),
);

4. Auto Persistence & State Recovery Across App Restarts #

Automatically persist target end time into SharedPreferences (or secure storage) and restore it seamlessly when the user re-opens the app:

// 1. Restore timer upon screen/controller initialization
_otpCountDown = OTPCountDown.restoreOTPTimer(
  savedTargetEndTimeEpochMs: prefs.getInt('otp_target_epoch'),
  defaultTimeInMS: 1000 * 60 * 5, // Default 5 mins if no valid saved state
  onSaveState: (int targetEpochMs) async {
    // Save target timestamp when timer starts or restarts
    await prefs.setInt('otp_target_epoch', targetEpochMs);
  },
  onClearState: () async {
    // Automatically purge saved state when timer finishes or expires
    await prefs.remove('otp_target_epoch');
  },
);

5. Persistence Hook & Milestones #

_otpCountDown = OTPCountDown.startOTPTimer(
    timeInMS: _otpTimeInMS,
    onTick: (int remainingTimeInMS) {
        // Save remaining time to SharedPreferences/local store
        saveRemainingTime(remainingTimeInMS);
    },
    milestones: {
        5000: () {
            // Triggered exactly once when 5 seconds remain
            print("Warning: Only 5 seconds remaining!");
        },
    },
);

6. Controls (Pause, Resume, Restart, Dispose) #

// Pause the timer (stops ticking and freezes remaining duration)
_otpCountDown.pause();

// Resume the timer (calculates new target end time)
_otpCountDown.resume();

// Restart timer with short or long duration (automatically formats as HH:mm:ss if >= 1h)
_otpCountDown.restart(1000 * 3600 * 2); // 2 hours -> "02:00:00"

// Check if active or disposed
print(_otpCountDown.isDisposed); // false

// Cancel timer, remove lifecycle observer, and close streams safely
_otpCountDown.dispose();

Getting Started #

For help getting started with Flutter, view our online documentation.

0
likes
160
points
50
downloads

Documentation

API reference

Publisher

verified publisherrizkyghofur.my.id

Weekly Downloads

A fork of otp_count_down package. A new dart package for easy implementation of OTP Count Down.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on otp_count_down_plus