cmdrootaccess / another-flushbar

A flexible widget for user notification. Customize your text, button, duration, animations and much more. For Android devs, it is made to replace Snackbars and Toasts.
https://pub.dev/packages/another_flushbar
MIT License
145 stars 89 forks source link

Swiping back while flushbar is dismissing freezes swiping animation #34

Open fevzican opened 3 years ago

fevzican commented 3 years ago

This is issue was marked as resolved, but bug is still going on:

7

pam3ec555 commented 3 years ago

This is issue was marked as resolved, but bug is still going on:

7

Hi. I have the same issue and I found a solution

Try to detect your ios back gesture by overriding method didStartUserGesture of RouteObserver

class LocalNotificationObserver extends RouteObserver {
  @override
  void didStartUserGesture(Route route, Route? previousRoute) {
    if (LocalNotification.hasActiveNotifications) {
      LocalNotification.dismissAll();
    }
    super.didStartUserGesture(route, previousRoute);
  }
}

And use this class LocalNotificationObserver in your MaterialApp like this

Widget _buildMaterialApp() {
    return GetMaterialApp(
      onGenerateTitle: (BuildContext context) {
        return 'Sueta';
      },
      navigatorObservers: [
        AnalyticsService.analyticsObserver,
        LocalNotificationObserver(), // Add this
      ],
      debugShowCheckedModeBanner: false,
      builder: (context, child) {
        return MediaQuery(
          data: MediaQuery.of(context).copyWith(textScaleFactor: 1),
          child: child,
        );
      },
      onGenerateRoute: _onMobileAppGeneretaRoute,
      initialRoute: Routes.initial,
      localizationsDelegates: _localizationDelegates,
      supportedLocales: S.delegate.supportedLocales,
      theme: appTheme,
    );
  }

This solution helps to prevent back gesture on Ios while I have an active flushbar.

Also, I prevent showing my flushbar when user's back gesture is active and invoke showing after he is done.

static Future<Flushbar> show({
    VoidCallback? onTap,
    required Widget message,
    required String title,
    Widget? icon,
  }) async {
    // Check whether gesture in progress
    if (Navigator.of(Get.context!).userGestureInProgress) {
      await Future.delayed(Duration(milliseconds: 500));
      // Trying to show it again after delay
      return await show(
        onTap: onTap,
        message: message,
        title: title,
        icon: icon,
      );
    }
    late Flushbar notification;
    notification = Flushbar(...);
    dismissAll(); // dissmis all my previous notifications
    _activeNotifications.add(notification); // add current to array of active notifications in order to control them
    notification.show(Get.context!);
    return notification;
  }

Here are others method from the class

static List<Flushbar> _activeNotifications = [];

static bool get hasActiveNotifications {
  return _activeNotifications.length > 0;
}

static void dismissAll() {
    _activeNotifications.forEach((notification) {
      notification.dismiss();
    });
}
thorgexyz commented 2 years ago

LocalNotification

where is LocalNotification implemented?

otopba commented 2 years ago

Same issue =/

szrbdk commented 2 years ago

This is issue was marked as resolved, but bug is still going on:

7

Hi. I have the same issue and I found a solution

Try to detect your ios back gesture by overriding method didStartUserGesture of RouteObserver

class LocalNotificationObserver extends RouteObserver {
  @override
  void didStartUserGesture(Route route, Route? previousRoute) {
    if (LocalNotification.hasActiveNotifications) {
      LocalNotification.dismissAll();
    }
    super.didStartUserGesture(route, previousRoute);
  }
}

And use this class LocalNotificationObserver in your MaterialApp like this

Widget _buildMaterialApp() {
    return GetMaterialApp(
      onGenerateTitle: (BuildContext context) {
        return 'Sueta';
      },
      navigatorObservers: [
        AnalyticsService.analyticsObserver,
        LocalNotificationObserver(), // Add this
      ],
      debugShowCheckedModeBanner: false,
      builder: (context, child) {
        return MediaQuery(
          data: MediaQuery.of(context).copyWith(textScaleFactor: 1),
          child: child,
        );
      },
      onGenerateRoute: _onMobileAppGeneretaRoute,
      initialRoute: Routes.initial,
      localizationsDelegates: _localizationDelegates,
      supportedLocales: S.delegate.supportedLocales,
      theme: appTheme,
    );
  }

This solution helps to prevent back gesture on Ios while I have an active flushbar.

Also, I prevent showing my flushbar when user's back gesture is active and invoke showing after he is done.

static Future<Flushbar> show({
    VoidCallback? onTap,
    required Widget message,
    required String title,
    Widget? icon,
  }) async {
    // Check whether gesture in progress
    if (Navigator.of(Get.context!).userGestureInProgress) {
      await Future.delayed(Duration(milliseconds: 500));
      // Trying to show it again after delay
      return await show(
        onTap: onTap,
        message: message,
        title: title,
        icon: icon,
      );
    }
    late Flushbar notification;
    notification = Flushbar(...);
    dismissAll(); // dissmis all my previous notifications
    _activeNotifications.add(notification); // add current to array of active notifications in order to control them
    notification.show(Get.context!);
    return notification;
  }

Here are others method from the class

static List<Flushbar> _activeNotifications = [];

static bool get hasActiveNotifications {
  return _activeNotifications.length > 0;
}

static void dismissAll() {
    _activeNotifications.forEach((notification) {
      notification.dismiss();
    });
}

I tried this. It's worked. Thank you.

szrbdk commented 2 years ago

This is issue was marked as resolved, but bug is still going on:

7

Hi. I have the same issue and I found a solution Try to detect your ios back gesture by overriding method didStartUserGesture of RouteObserver

class LocalNotificationObserver extends RouteObserver {
  @override
  void didStartUserGesture(Route route, Route? previousRoute) {
    if (LocalNotification.hasActiveNotifications) {
      LocalNotification.dismissAll();
    }
    super.didStartUserGesture(route, previousRoute);
  }
}

And use this class LocalNotificationObserver in your MaterialApp like this

Widget _buildMaterialApp() {
    return GetMaterialApp(
      onGenerateTitle: (BuildContext context) {
        return 'Sueta';
      },
      navigatorObservers: [
        AnalyticsService.analyticsObserver,
        LocalNotificationObserver(), // Add this
      ],
      debugShowCheckedModeBanner: false,
      builder: (context, child) {
        return MediaQuery(
          data: MediaQuery.of(context).copyWith(textScaleFactor: 1),
          child: child,
        );
      },
      onGenerateRoute: _onMobileAppGeneretaRoute,
      initialRoute: Routes.initial,
      localizationsDelegates: _localizationDelegates,
      supportedLocales: S.delegate.supportedLocales,
      theme: appTheme,
    );
  }

This solution helps to prevent back gesture on Ios while I have an active flushbar. Also, I prevent showing my flushbar when user's back gesture is active and invoke showing after he is done.

static Future<Flushbar> show({
    VoidCallback? onTap,
    required Widget message,
    required String title,
    Widget? icon,
  }) async {
    // Check whether gesture in progress
    if (Navigator.of(Get.context!).userGestureInProgress) {
      await Future.delayed(Duration(milliseconds: 500));
      // Trying to show it again after delay
      return await show(
        onTap: onTap,
        message: message,
        title: title,
        icon: icon,
      );
    }
    late Flushbar notification;
    notification = Flushbar(...);
    dismissAll(); // dissmis all my previous notifications
    _activeNotifications.add(notification); // add current to array of active notifications in order to control them
    notification.show(Get.context!);
    return notification;
  }

Here are others method from the class

static List<Flushbar> _activeNotifications = [];

static bool get hasActiveNotifications {
  return _activeNotifications.length > 0;
}

static void dismissAll() {
    _activeNotifications.forEach((notification) {
      notification.dismiss();
    });
}

I tried this. It's worked. Thank you.

UPDATE: LocalNotificationObserver is not required.

You can use blockBackgroundInteraction parameter of FlushBar instead of LocalNotificationObserver. Disable all interactions when FlushBar on screen.