koukibadr / Cherry-Toast

https://pub.dev/packages/cherry_toast
MIT License
22 stars 16 forks source link

Feature Request: Notification Queue #51

Open jjcazau opened 1 year ago

jjcazau commented 1 year ago

Hi there,

Thanks for the quick MIT License update. I see you have also moved to using overlays instead of pushing a PageRouteBuilder. I was already experimenting with overlay changes in my fork by the time i noticed.

I'm not able to use your overlay method as it does not seem compatible with my queue system I made. Issues with using the right context that don't seem to work with your implementation so ill stick with mine: https://github.com/jjcazau/Cherry-Toast/blob/main/lib/cherry_toast.dart

Anyway... Feature Request, a notification queue would be nice so if multiple toasts get fired, then they are queued and displayed one after the other, similar to the way native snackbars work. Using my overlay implementation I was able to implement a queuing system with this code. Maybe it might be of use to you.

This may not be the best solution but it works for my purposes currently.

THE QUEUE

import 'dart:collection';

import 'package:cherry_toast/cherry_toast.dart';
import 'package:ember_map/EMNotification/EMNotification.dart';
import 'package:ember_map/main.dart';
import 'package:flutter/material.dart';

// Singleton Instance
class EMNotificationQueue {
  static EMNotificationQueue instance = EMNotificationQueue._internal();

  EMNotificationQueue._internal();

  final Queue<CherryToast> _queue = Queue<CherryToast>();
  bool _isDisplaying = false;

  add(CherryToast toast) {
    if (_isDisplaying) {
      _queue.add(toast);
    } else {
      _displayToast(toast);
    }
  }

  _displayToast(CherryToast toast) {
    _isDisplaying = true;
    toast.show(navigatorKey.currentContext!);
    Future.delayed(
        Duration(
            seconds: 1 +
                toast.toastDuration.inSeconds +
                toast.animationDuration.inSeconds), () {
      _isDisplaying = false;
      if (_queue.isNotEmpty) {
        _displayToast(_queue.removeFirst());
      }
    });
  }
}

My Custom Notification Manager

import 'package:cherry_toast/cherry_toast.dart';
import 'package:cherry_toast/cherry_toast_icon.dart';
import 'package:cherry_toast/resources/arrays.dart';
import 'package:ember_map/EMNotification/EMNotificationQueue.dart';
import 'package:flutter/material.dart';

class EMNotification {
  final String? title;
  final String? description;
  final Function? actionButtonCallback;
  final String? actionButtonText;
  final Duration duration;
  final bool autoDismiss;

  final bool displayCloseButton = false;
  final double borderRadius = 10;
  final bool displayIcon = true;
  final bool enableIconAnimation = true;
  final Position toastPosition = Position.top;
  final Duration animationDuration = const Duration(milliseconds: 450);
  final AnimationType animationType = AnimationType.fromTop;
  final Cubic animationCurve = Curves.ease;
  final ToastLayout layout = ToastLayout.ltr;

  // Queue

  // Default Colors
  final Color errorColor = const Color(0xffE43837);
  final Color successColor = const Color(0xFF2F9449);
  final Color infoColor = const Color(0xFF4E5CB9);
  final Color warningColor = const Color(0xffFC9F00);
  final Color defaultBackgroundColor = const Color(0xFFFFFFFF);
  final Color defaultShadowColor = const Color(0x7E9E9E9E);

  // Title Text Styles
  final TextStyle titleTextStyle = const TextStyle(
    fontSize: 16,
    fontWeight: FontWeight.w500,
    color: Colors.black,
  );

  // Description Text Styles
  final TextStyle descriptionTextStyle = const TextStyle(
    fontSize: 14.0,
    fontWeight: FontWeight.normal,
    color: Colors.black,
  );

  // Action Button Text Styles
  final TextStyle actionButtonTextStyle = const TextStyle(
    fontSize: 15,
    fontWeight: FontWeight.bold,
  );

  EMNotification({
    this.title,
    this.description,
    this.actionButtonCallback,
    this.actionButtonText,
    this.duration = const Duration(seconds: 4),
    this.autoDismiss = true,
  });

  showInfo(BuildContext context) {
    EMNotificationQueue.instance.add(
      CherryToast.info(
        title: Text(
          '$title',
          style: titleTextStyle,
        ),
        description: (description != null)
            ? Text('$description', style: descriptionTextStyle)
            : null,
        action: (actionButtonText != null)
            ? Text('$actionButtonText',
                style: actionButtonTextStyle.copyWith(color: infoColor))
            : null,
        actionHandler: actionButtonCallback,
        animationDuration: animationDuration,
        displayTitle: (title != null) ? true : false,
        autoDismiss: autoDismiss,
        backgroundColor: defaultBackgroundColor,
        toastPosition: toastPosition,
        toastDuration: duration,
        animationType: animationType,
        borderRadius: borderRadius,
        displayCloseButton: displayCloseButton,
        animationCurve: animationCurve,
        displayIcon: displayIcon,
        enableIconAnimation: enableIconAnimation,
        layout: layout,
      ),
    );
  }

  showWarning() {
    EMNotificationQueue.instance.add(CherryToast.warning(
      title: Text(
        '$title',
        style: titleTextStyle,
      ),
      description: (description != null)
          ? Text('$description', style: descriptionTextStyle)
          : null,
      action: Text('$actionButtonText',
          style: actionButtonTextStyle.copyWith(color: warningColor)),
      actionHandler: actionButtonCallback,
      animationDuration: animationDuration,
      displayTitle: (title != null) ? true : false,
      autoDismiss: autoDismiss,
      backgroundColor: defaultBackgroundColor,
      toastPosition: toastPosition,
      toastDuration: duration,
      animationType: animationType,
      borderRadius: borderRadius,
      displayCloseButton: displayCloseButton,
      animationCurve: animationCurve,
      displayIcon: displayIcon,
      enableIconAnimation: enableIconAnimation,
      layout: layout,
    ));
  }

  showSuccess() {
    EMNotificationQueue.instance.add(CherryToast.success(
      title: Text(
        '$title',
        style: titleTextStyle,
      ),
      description: (description != null)
          ? Text('$description', style: descriptionTextStyle)
          : null,
      action: Text('$actionButtonText',
          style: actionButtonTextStyle.copyWith(color: successColor)),
      actionHandler: actionButtonCallback,
      animationDuration: animationDuration,
      displayTitle: (title != null) ? true : false,
      autoDismiss: autoDismiss,
      backgroundColor: defaultBackgroundColor,
      toastPosition: toastPosition,
      toastDuration: duration,
      animationType: animationType,
      borderRadius: borderRadius,
      displayCloseButton: displayCloseButton,
      animationCurve: animationCurve,
      displayIcon: displayIcon,
      enableIconAnimation: enableIconAnimation,
      layout: layout,
    ));
  }

  showError() {
    EMNotificationQueue.instance.add(CherryToast.error(
      title: Text(
        '$title',
        style: titleTextStyle,
      ),
      description: (description != null)
          ? Text('$description', style: descriptionTextStyle)
          : null,
      action: Text('$actionButtonText',
          style: actionButtonTextStyle.copyWith(color: errorColor)),
      actionHandler: actionButtonCallback,
      animationDuration: animationDuration,
      displayTitle: (title != null) ? true : false,
      autoDismiss: autoDismiss,
      backgroundColor: defaultBackgroundColor,
      toastPosition: toastPosition,
      toastDuration: duration,
      animationType: animationType,
      borderRadius: borderRadius,
      displayCloseButton: displayCloseButton,
      animationCurve: animationCurve,
      displayIcon: displayIcon,
      enableIconAnimation: enableIconAnimation,
      layout: layout,
    ));
  }
}
koukibadr commented 1 year ago

Hello @jjcazau thanks a lot for this suggestion and the alternative solution I will work on it meanwhile send me your issues