Mindinventory / animated_notch_bottom_bar

Tabbar component for Flutter
MIT License
104 stars 32 forks source link

AnimationController.stop() called after AnimationController.dispose() #20

Closed FilyMSakine closed 6 months ago

FilyMSakine commented 8 months ago

I'm getting this error whenever I try to change items

The following assertion was thrown while dispatching notifications for NotchBottomBarController:
AnimationController.stop() called after AnimationController.dispose()
AnimationController methods should not be used after calling dispose.
'package:flutter/src/animation/animation_controller.dart':
Failed assertion: line 772 pos 7: '_ticker != null'

My code logic is:

I have done so much research about this problem but was unable to find any clue thats why I came here to open a new issue

FilyMSakine commented 8 months ago

I almost forget, I'm using go router for routes and navigation stuff

FilyMSakine commented 8 months ago

Full log

══╡ EXCEPTION CAUGHT BY FOUNDATION LIBRARY ╞════════════════════════════════════════════════════════
The following assertion was thrown while dispatching notifications for NotchBottomBarController:
AnimationController.stop() called after AnimationController.dispose()
AnimationController methods should not be used after calling dispose.
'package:flutter/src/animation/animation_controller.dart':
Failed assertion: line 772 pos 7: '_ticker != null'

Either the assertion indicates an error in the framework itself, or we should provide substantially
more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=2_bug.yml

When the exception was thrown, this was the stack:
#2      AnimationController.stop (package:flutter/src/animation/animation_controller.dart:772:7)
#3      AnimationController.value= (package:flutter/src/animation/animation_controller.dart:361:5)
#4      AnimationController.reset (package:flutter/src/animation/animation_controller.dart:382:5)
#5      _AnimatedNotchBottomBarState.initState.<anonymous closure> (package:animated_notch_bottom_bar/src/notch_bottom_bar.dart:106:28)
#6      ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:403:24)
#7      NotchBottomBarController.jumpTo (package:animated_notch_bottom_bar/src/notch_bottom_bar_controller.dart:12:5)
#8      _AnimatedNotchBottomBarState.build.<anonymous closure>.<anonymous closure> (package:animated_notch_bottom_bar/src/notch_bottom_bar.dart:218:38)
#9      BottomBarInActiveItem.build.<anonymous closure> (package:animated_notch_bottom_bar/src/bottom_bar_inactive_item.dart:35:25)
#10     GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:275:24)
#11     TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:654:11)
#12     BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:311:5)
#13     BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:244:7)
#14     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:630:9)
#15     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
#16     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
#17     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:625:13)
#18     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
#19     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
#20     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:488:19)
#21     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:468:22)
#22     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:333:11)
#23     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:413:7)
#24     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:376:5)
#25     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:323:7)
#26     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:292:9)
#27     _invoke1 (dart:ui/hooks.dart:186:13)
#28     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:424:7)
#29     _dispatchPointerDataPacket (dart:ui/hooks.dart:119:31)
(elided 2 frames from class _AssertionError)

The NotchBottomBarController sending notification was:
  Instance of 'NotchBottomBarController'
═══════════════════════════════════════════════════════════════════════════════════════════════════
mi-raj04 commented 7 months ago
import 'dart:developer';

import 'package:animated_notch_bottom_bar/animated_notch_bottom_bar/animated_notch_bottom_bar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key);

  final GoRouter _router = GoRouter(
    routes: <RouteBase>[
      GoRoute(
        path: '/',
        builder: (BuildContext context, GoRouterState state) {
          return const MyHomePage();
        },
      ),
    ],
  );
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: _router,
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  /// Controller to handle PageView and also handles initial page
  final List<Widget> _items = const <Widget>[
    Page2(),
    Page3(),
    Page1(),
  ];

  late PageController _pageController;
  late NotchBottomBarController _notchBottomBarController;

  @override
  void initState() {
    _pageController = PageController();
    _notchBottomBarController = NotchBottomBarController();
    super.initState();
  }

  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        scrollDirection: Axis.vertical,
        controller: _pageController,
        physics: const NeverScrollableScrollPhysics(),
        children: List<Widget>.generate(
          _items.length,
          (int index) => Container(
            margin: const EdgeInsets.only(),
            child: _items[index],
          ),
        ),
      ),
      extendBody: true,
      bottomNavigationBar: AnimatedNotchBottomBar(
        durationInMilliSeconds: 400,
        notchBottomBarController: _notchBottomBarController,
        showLabel: false,
        bottomBarItems: <BottomBarItem>[
          const BottomBarItem(
            inActiveItem: Icon(
              Icons.home_filled,
              color: Colors.blueGrey,
            ),
            activeItem: Icon(
              Icons.home_filled,
              color: Colors.blueAccent,
            ),
            itemLabel: 'Page 1',
          ),
          const BottomBarItem(
            inActiveItem: Icon(
              Icons.star,
              color: Colors.blueGrey,
            ),
            activeItem: Icon(
              Icons.star,
              color: Colors.blueAccent,
            ),
            itemLabel: 'Page 2',
          ),

          ///svg example
          BottomBarItem(
            inActiveItem: SvgPicture.asset(
              'assets/search_icon.svg',
              color: Colors.blueGrey,
            ),
            activeItem: SvgPicture.asset(
              'assets/search_icon.svg',
              color: Colors.white,
            ),
            itemLabel: 'Page 3',
          ),
        ],
        onTap: (index) {
          /// perform action on tab change and to update pages you can update pages without pages
          log('current selected index $index');
          _pageController.jumpToPage(index);
        },
      ),
    );

    Future<void> _changeBottomBarItem(int index) async {
      _pageController.animateToPage(index, duration: const Duration(milliseconds: 400), curve: Curves.easeInOut);
    }
  }
}

class Page1 extends StatelessWidget {
  const Page1({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(color: Colors.yellow, child: const Center(child: Text('Page 1')));
  }
}

class Page2 extends StatelessWidget {
  const Page2({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(color: Colors.green, child: const Center(child: Text('Page 2')));
  }
}

class Page3 extends StatelessWidget {
  const Page3({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(color: Colors.red, child: const Center(child: Text('Page 3')));
  }
}

// class Page4 extends StatelessWidget {
//   const Page4({Key? key}) : super(key: key);
//
//   @override
//   Widget build(BuildContext context) {
//     return Container(color: Colors.blue, child: const Center(child: Text('Page 4')));
//   }
// }
//
// class Page5 extends StatelessWidget {
//   const Page5({Key? key}) : super(key: key);
//
//   @override
//   Widget build(BuildContext context) {
//     return Container(color: Colors.lightGreenAccent, child: const Center(child: Text('Page 5')));
//   }
// }

@FilyMSakine using your code i create demo and its work fine you can try above code and if found any issue please give me more details so i can regenerate that issues and find solutions for you

FilyMSakine commented 7 months ago

@mi-raj04 alright

// my custom go_router

import ...

class CustomGoRouter {
  static bool redirected = false;

  static GoRouter configuration() => GoRouter(
        routes: <RouteBase>[...],
        redirect: (context, state) {
          if (getIt<SharedPreferencesClient>()
                      .restoreUserAuthenticationFields() !=
                  null &&
              !redirected) {
            redirected = true;
            return RouterPath.rootLocation;
          }
          return state.fullPath;
        },
      );

  static void go(BuildContext context, String routerPath) {
    GoRouter.of(context).go(routerPath);
  }

  static Future<void> push(BuildContext context, String routerPath) async {
    GoRouter.of(context).push(routerPath);
  }

  static void pop(BuildContext context) {
    GoRouter.of(context).pop();
  }
}

My material page definition


import ...

class App extends StatefulWidget {
  const App({super.key});

  @override
  State<StatefulWidget> createState() => _AppState();
}

class _AppState extends State<App> {
  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Sizer(
      builder: (BuildContext context, Orientation orientation,
              DeviceType deviceType) =>
          MaterialApp.router(
        routerConfig: CustomGoRouter.configuration(),
        theme: ThemeData(...),
        localizationsDelegates: const <LocalizationsDelegate<dynamic>>[...],
        supportedLocales: const <Locale>[...],
        debugShowCheckedModeBanner: false,
      ),
    );
  }
}
FilyMSakine commented 7 months ago

@mi-raj04 I have the same pageview definition and I'm using jumpToPage(index) method on onTap event Also I have updated my flutter SDK and the package but I'm still getting the same issue

Flutter log

Flutter 3.16.7 • channel stable • https://github.com/flutter/flutter.git
Framework • revision ef1af02aea (12 days ago) • 2024-01-11 15:19:26 -0600
Engine • revision 4a585b7929
Tools • Dart 3.2.4 • DevTools 2.28.5

Packager animated_notch_bottom_bar: ^1.0.1

pratikkansaramind commented 6 months ago

@FilyMSakine Thank you for expressing your confidence in our team. Unfortunately, after thorough investigation, we were unable to reproduce the issue you mentioned. We explored various approaches to address the issue but encountered no success. Your assistance in providing further details regarding the issue would be greatly appreciated. Additionally, we welcome any contributions or insights you may have to improve our package.

chandanraneso commented 1 day ago

****== Exception caught by foundation library ==================================================== The following assertion was thrown while dispatching notifications for NotchBottomBarController: AnimationController.stop() called after AnimationController.dispose() AnimationController methods should not be used after calling dispose. 'package:flutter/src/animation/animation_controller.dart': Failed assertion: line 795 pos 7: '_ticker != null'

Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause. In either case, please report this assertion by filing a bug on GitHub: https://github.com/flutter/flutter/issues/new?template=2_bug.yml

When the exception was thrown, this was the stack:

2 AnimationController.stop (package:flutter/src/animation/animation_controller.dart:795:7)

3 AnimationController.value= (package:flutter/src/animation/animation_controller.dart:393:5)

4 AnimationController.reset (package:flutter/src/animation/animation_controller.dart:414:5)

5 _AnimatedNotchBottomBarState.initState. (package:animated_notch_bottom_bar/src/notch_bottom_bar.dart:170:28)

6 ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:433:24)

7 NotchBottomBarController.jumpTo (package:animated_notch_bottom_bar/src/notch_bottom_bar_controller.dart:12:5)

8 _AnimatedNotchBottomBarState.build.. (package:animated_notch_bottom_bar/src/notch_bottom_bar.dart:270:65)

9 BottomBarInActiveItem.build. (package:animated_notch_bottom_bar/src/bottom_bar_inactive_item.dart:61:25)

10 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:344:24)

11 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:652:11)

12 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:309:5)

13 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:242:7)

14 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:696:9)

15 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)

16 PointerRouter._dispatchEventToRoutes. (package:flutter/src/gestures/pointer_router.dart:143:9)

17 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:633:13)

18 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)

19 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)

20 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:495:19)

21 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:475:22)

22 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:425:11)

23 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:420:7)

24 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:383:5)

25 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:330:7)

26 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:299:9)

27 _invoke1 (dart:ui/hooks.dart:328:13)

28 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:442:7)

29 _dispatchPointerDataPacket (dart:ui/hooks.dart:262:31)

(elided 2 frames from class _AssertionError) The NotchBottomBarController sending notification was: Instance of 'NotchBottomBarController'

======== Exception caught by foundation library ==================================================== The following assertion was thrown while dispatching notifications for NotchBottomBarController: AnimationController.stop() called after AnimationController.dispose() AnimationController methods should not be used after calling dispose. 'package:flutter/src/animation/animation_controller.dart': Failed assertion: line 795 pos 7: '_ticker != null'

Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause. In either case, please report this assertion by filing a bug on GitHub: https://github.com/flutter/flutter/issues/new?template=2_bug.yml

When the exception was thrown, this was the stack:

2 AnimationController.stop (package:flutter/src/animation/animation_controller.dart:795:7)

3 AnimationController.value= (package:flutter/src/animation/animation_controller.dart:393:5)

4 AnimationController.reset (package:flutter/src/animation/animation_controller.dart:414:5)

5 _AnimatedNotchBottomBarState.initState. (package:animated_notch_bottom_bar/src/notch_bottom_bar.dart:170:28)

6 ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:433:24)

7 NotchBottomBarController.jumpTo (package:animated_notch_bottom_bar/src/notch_bottom_bar_controller.dart:12:5)

8 _DashboardState.build.. (package:vits_rename/vits_mobile/views/screens/dashboard/Dashboard.dart:1152:45)

9 State.setState (package:flutter/src/widgets/framework.dart:1203:30)

10 _DashboardState.build. (package:vits_rename/vits_mobile/views/screens/dashboard/Dashboard.dart:1149:29)

11 _AnimatedNotchBottomBarState.build.. (package:animated_notch_bottom_bar/src/notch_bottom_bar.dart:271:46)

12 BottomBarInActiveItem.build. (package:animated_notch_bottom_bar/src/bottom_bar_inactive_item.dart:61:25)

13 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:344:24)

14 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:652:11)

15 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:309:5)

16 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:242:7)

17 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:696:9)

18 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)

19 PointerRouter._dispatchEventToRoutes. (package:flutter/src/gestures/pointer_router.dart:143:9)

20 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:633:13)

21 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)

22 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)

23 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:495:19)

24 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:475:22)

25 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:425:11)

26 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:420:7)

27 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:383:5)

28 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:330:7)

29 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:299:9)

30 _invoke1 (dart:ui/hooks.dart:328:13)

31 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:442:7)

32 _dispatchPointerDataPacket (dart:ui/hooks.dart:262:31)

(elided 2 frames from class _AssertionError) The NotchBottomBarController sending notification was: Instance of 'NotchBottomBarController'

How to fix my issue

chandanraneso commented 1 day ago

I have three tab VesselDetail,chatScreen and TicketScreen when i switch one tab to another i got above issue and page screen will completely blank how to fix that issue

chandanraneso commented 1 day ago

My code logic is import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import '../../../customWidgets/custom_loader.dart'; import '../../../provider/auth_provider.dart'; import '../../../provider/data_provider.dart'; import '../../../routes_networking/app_routes.dart'; import '../../../routes_networking/router.dart'; import '../../../util/app.dart'; import '../../../util/app_constants.dart'; import 'package:provider/provider.dart'; import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:web_socket_channel/io.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; import '../../../data/model/response/base/notification_model.dart' as nm; import '../../../util/localimages.dart'; import '../authentication/login/login.dart'; import '../chat/chats_screen.dart'; import '../clients/screens/vessels.dart'; import '../ticket/ticket.dart'; import 'package:audioplayers/audioplayers.dart'; import 'package:animated_notch_bottom_bar/animated_notch_bottom_bar/animated_notch_bottom_bar.dart';

class Dashboard extends StatefulWidget { Dashboard({Key? key, NotchBottomBarController? controller}) : super(key: key);

@override State createState() => _DashboardState(); }

class _DashboardState extends State with SingleTickerProviderStateMixin{ late final WebSocketChannel _channel = IOWebSocketChannel.connect('${AppRoutes.WS_CHAT_URL}'); late List notifications = []; int _currentIndex = 0; bool _isLoading = false; List _screens = [ // const TicketsScreen(), // const ChatScreen(), // const VesselDetails(),

// const VesselDetails(),

];

// final _pageController = PageController(initialPage: 0); // late final NotchBottomBarController _controller = NotchBottomBarController(index: 0);

// int _selectedIndex = 0; late AnimationController _animationController;

late PageController _pageController; late NotchBottomBarController _controller; bool _isDisposed = false; bool _isControllerDisposed = false;

int maxCount = 3; bool showVesselTab = true; // Set this variable based on your condition // String _screenName = AppConstants.TICKET.toUpperCase(); String? _screenName;

// _onTabTapped(int index) async { // if (!mounted) return; // setState(() { // _currentIndex = index; // switch (_currentIndex) { // case 0: // _screenName = AppConstants.VESSEL.toUpperCase(); // break; // case 1: // _screenName = AppConstants.CHATS.toUpperCase(); // break; // case 2: // _screenName = AppConstants.TICKET.toUpperCase(); // // break; // default: // _screenName = "DASHBOARD"; // } // }); // if (mounted) { // await _pageController.animateToPage(index, // duration: Duration(milliseconds: 300), // curve: Curves.easeInOut // ); // if (!_isControllerDisposed && _controller != null) { // _controller.jumpTo(index); // Ensure NotchBottomBarController is updated // } // } // }

void _onTabTapped(int index) { if (!mounted) return;

setState(() {
  _currentIndex = index;
  if (!_isDisposed) {
    _pageController.jumpToPage(index); // or animateToPage if you want smooth animation
    if (!_isControllerDisposed) {
      _controller.jumpTo(index); // Ensure NotchBottomBarController is updated
    }
  }
});

}

bool isCollapse = false; int _previousNotificationCount = 0; // Track previous notification count int _notificationCount = 0; // Track the total number of notifications

int _counter = 0; TextEditingController _dashboardSearch = TextEditingController();

// String _string = "VESSELS"; String userType = '';

// WebSocketChannel? _channel;

@override void initState() { // TODO: implement initState super.initState(); changeuserType(); _updateScreens();

_pageController = PageController(initialPage:_currentIndex);
_controller = NotchBottomBarController(index: _currentIndex);
  _animationController = AnimationController(vsync: this);

// Post-frame callback to ensure the widget tree is built before using context
  // Check if the user is logged in
  if (Provider.of<AuthProvider>(context, listen: false).isLoggedIn()) {
     _loadData(context, true); // Load data when the user is logged in
  } else {
    // Navigate to login screen if not logged in
    Navigator.pushNamed(context, MyRouter.getLoginRoute());
  }
_initWebSocketNotification();

}

@override void dispose() { print('Disposing controller');

_isDisposed = true;
_isControllerDisposed = true;
print('Rock $_isControllerDisposed');
_pageController.dispose();
_controller?.dispose();
_animationController.dispose();
super.dispose();

}

void _jumpToIndex(int index) { if (!_isDisposed) { _controller.jumpTo(index); } }

@override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.paused) { if (!_isDisposed) { _animationController.stop(); } } }

List existingMessages = [];

_initWebSocketNotification() { late final WebSocketChannel channel = IOWebSocketChannel.connect('${AppRoutes.WS_NOTIFICATION}'); channel.stream.listen((data) async { try { String messageJson = data; nm.NotificationModel notificationModel = nm.notificationModelFromJson(messageJson);

    if (mounted) {
      setState(() {
        notifications = notificationModel.data.results;
      });
    }

    // Calculate the difference between the current and previous notification counts
    int newNotifications = notifications.length - _previousNotificationCount;

    if (newNotifications > 0) {
      _notificationCount += newNotifications; // Increment the notification count

      // Play audio notification
      try {
        await AudioPlayer().play(AssetSource("mp3/notification.mp3"));
      } catch (e) {
        print("Error playing audio: $e");
      }
    }

    // Update previous notification count to current count
    _previousNotificationCount = notifications.length;
  } catch (e) {
    print('Error processing WebSocket data: $e, Data: $data');
  }
});

}

_initWebSocketNotifications() { late final WebSocketChannel channel = IOWebSocketChannel.connect('${AppRoutes.WS_NOTIFICATION}'); channel?.stream.listen((data) async { try { String messageJson = data; nm.NotificationModel notificationModel = nm.notificationModelFromJson(messageJson);

    // // Filter out notifications from the logged-in user
    // List<nm.Result> filteredNotifications = notificationModel.data.results
    //     .where((notification) => notification.userId != loggedInUserID)
    //     .toList();
    //
    // setState(() {
    //   notifications = filteredNotifications;
    // });
    if (mounted) {
      setState(() {
        notifications = notificationModel.data.results;
      });
    }

    // Check if the new notification count is greater than the previous count
    if (notifications.length > _previousNotificationCount) {
      // Play audio notification
      try {
        await AudioPlayer().play(AssetSource("mp3/notification.mp3"));
      } catch (e) {
        print("Error playing audio: $e");
      }
    }
    // Update previous notification count
    _previousNotificationCount = notifications.length;
  } catch (e) {
    print('Error processing WebSocket data: $e, Data: $data');
  }
});

}

void changeuserType() { final type = Provider.of(context, listen: false) .authRepo .getUserType(); setState(() { userType = type; }); }

void _updateScreens() { List newScreens;

if (userType == '1' || userType == '2') {
  newScreens = [
    const VesselDetails(),
    const ChatScreen(),
    const TicketsScreen(),
  ];
  _screenName = AppConstants.VESSEL.toUpperCase();
} else {
  newScreens = [
     const TicketsScreen(),
    const ChatScreen(),

  ];

  _screenName = AppConstants.TICKET.toUpperCase();
}

// Update screens and set PageController's initial page
if (mounted) {
  setState(() {
    _screens
      ..clear()
      ..addAll(newScreens);

    _pageController = PageController(initialPage: 0);
  });
}

}

// void _updateScreens() { // if (userType == '1' || userType == '2') { // _screens.clear(); // _screens.addAll([ // const VesselDetails(), // const ChatScreen(), // const TicketsScreen(), // ]); // _pageController = PageController(initialPage: _currentIndex); // _screenName = AppConstants.VESSEL.toUpperCase(); // } else { // _screens.clear(); // _screens.addAll([ // const TicketsScreen(), // const ChatScreen(), // ]); // _pageController = PageController(initialPage: _currentIndex); // _screenName = AppConstants.TICKET.toUpperCase(); // } // }

Future _loadData(BuildContext context, bool reload) async { if (mounted) { await Future.wait([ Provider.of(context, listen: false).getUsersList(context, reload), Provider.of(context, listen: false).getUsersList(context, reload, params: "?s&page=1&usertype=client"), Provider.of(context, listen: false).getProfile(context), Provider.of(context, listen: false).getTicketList(context, reload, params: "?s=&sortType&sortColumn&page=&s=&isLoadingAll=true"), Provider.of(context, listen: false).getVesselsItemsList(context, reload, params: "?s=&sortType&sortColumn"), Provider.of(context, listen: false).getClientsVesselList(context, reload), Provider.of(context, listen: false).getChatTicketList(context, reload), ]); print('Data loaded'); } } // @override // Widget build(BuildContext context) { // DataProvider dataProvider = Provider.of(context); // changeuserType(); // _updateScreens(); // bool isLoading = dataProvider.isLoading; // var size = MediaQuery.of(context).size; // // double appBarHeight = 30; // // return (isLoading) // ? CustomLoader() // : SafeArea( // child: Scaffold( // resizeToAvoidBottomInset: false, // // backgroundColor: AppConfigs.TertiaryColor, // appBar: PreferredSize( // preferredSize: Size(size.width, 1000), // child: Container( // decoration: const BoxDecoration( // gradient: LinearGradient(colors: [ // AppConfigs.PrimaryColor, // AppConfigs.SixthColor, // ]), // ), // child: Padding( // padding: EdgeInsets.fromLTRB(0, 0, 0, 0), // child: Row( // mainAxisAlignment: MainAxisAlignment.end, // children: [ // SingleChildScrollView( // scrollDirection: Axis.horizontal, // child: Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, // children: [ // /// logout button // SizedBox( // height: appBarHeight, // child: InkWell( // onTap: () { // Provider.of(context, // listen: false) // .clearSharedData(); // Navigator.pushNamedAndRemoveUntil(context, // MyRouter.login, (route) => false, // arguments: const LoginScreen()); // }, // child: const Align( // alignment: Alignment.center, // child: Icon( // Icons.power_settings_new, // size: 20, // color: AppConfigs.FifthColor, // ), // )), // ), // // SizedBox( // width: size.width / 100, // ), // // /// notification bell // SizedBox( // height: appBarHeight, // // width: appBarHeight, // child: InkWell( // onTap: () { // Navigator.pushNamed( // context, MyRouter.notification); // }, // child: Stack( // children: [ // const Positioned( // child: Align( // alignment: Alignment.center, // child: Icon( // Icons.notifications, // size: 20, // color: AppConfigs.FifthColor, // ), // ), // ), // Positioned.fill( // child: Align( // alignment: Alignment.topRight, // child: notifications.isNotEmpty // ? Container( // width: 15, // height: 15, // decoration: BoxDecoration( // shape: BoxShape.circle, // color: const Color( // 0xffc32c37), // border: Border.all( // color: Colors.white, // width: 1), // ), // child: Padding( // padding: // const EdgeInsets.all( // 0.0), // child: Center( // child: Text( // notifications.length // .toString(), // Use notifications.length to get the count // style: // const TextStyle( // fontSize: 10, // color: Colors // .white), // ), // ), // ), // ) // : const SizedBox(), // This will render an empty container if there are no notifications // ), // ), // ], // )), // ), // // SizedBox( // width: size.width / 100, // ), // // // SizedBox( // // child: InkWell( // // onTap: (){ // // Navigator.pushNamed(context, MyRouter.chats); // // }, // // child: const Icon( // // Icons.chat, // // color: AppConfigs.FifthColor, // // size: AppConfigs.ICON_SMALL_SIZE, // // ), // // ), // // ), // // // // SizedBox( // // width: size.width / 50, // // ), // // /// Profile Name & Avatar // Row( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // InkWell( // onTap: () { // isDesktop(context) // ? Navigator.pushNamedAndRemoveUntil( // context, // MyRouter.profile, // (route) => false) // : Navigator.pushNamed( // context, MyRouter.profile, // arguments: notifications.length // .toString()); // }, // child: CircleAvatar( // backgroundColor: AppConfigs.TertiaryColor, // backgroundImage: Provider.of< // DataProvider>(context) // .profileModel != // null && // Provider.of(context) // .profileModel! // .profilePic != // "" // ? NetworkImage( // Provider.of(context) // .profileModel! // .profilePic) as ImageProvider< // Object>? // : AssetImage(LocalImages.profile_logo) // as ImageProvider?, // radius: 10, // ), // ), // SizedBox(width: isDesktop(context) ? 10 : 5), // Visibility( // visible: isDesktop(context), // child: Row( // children: [ // InkWell( // onTap: () { // isDesktop(context) // ? Navigator // .pushNamedAndRemoveUntil( // context, // MyRouter.profile, // (route) => false) // : Navigator.pushNamed( // context, MyRouter.profile, // arguments: notifications // .length // .toString()); // }, // child: Text( // Provider.of(context) // .profileModel != // null // ? Provider.of( // context) // .profileModel! // .name // : "", // style: // TextStyle(color: Colors.white), // ), // ), // SizedBox(width: 5), // Icon(Icons.arrow_drop_down, // color: Colors.white), // ], // ), // ), // ], // ), // ], // ), // ), // SizedBox(width: 5), // ], // ), // ), // ), // ), // // body: SidebarPage(isCollapse : isCollapse, callback: (val) => setState(() => _string = val)), // body: PageView( // controller: _pageController, // physics: const NeverScrollableScrollPhysics(), // reverse: true, // scrollDirection: Axis.horizontal, // children: // List.generate(_screens.length, (index) => _screens[index]), // // ), // extendBody: true, // // bottomNavigationBar: (_screens.length <= maxCount) // ? AnimatedNotchBottomBar( // notchBottomBarController: _controller, // // color: AppConfigs.TertiaryColor, // itemLabelStyle: const TextStyle( // color: AppConfigs.FifthColor, // fontSize: AppConfigs.TIMELINE_TEXT, // fontFamily: AppConfigs.font, // ), // showLabel: true, // shadowElevation: 0, // kBottomRadius: 0, //28.0, // // notchShader: const SweepGradient( // startAngle: 0, // endAngle: 2 / 2, // // colors: [Colors.lightBlueAccent, Colors.blue, Colors.blue], // colors: [ // AppConfigs.PrimaryColor, // AppConfigs.SixthColor], // tileMode: TileMode.mirror, // ).createShader(Rect.fromCircle(center: Offset.zero, radius: 8.0)), // notchColor: AppConfigs.TertiaryColor, // removeMargins: true, // bottomBarWidth: size.width, // showBlurBottomBar: false, // durationInMilliSeconds: 300, // bottomBarItems: [ // // // ///1 Ticket Tab // BottomBarItem( // inActiveItem: SizedBox( // width: 24.0, // height: 24.0, // child: Icon( // (userType == '1' || userType == '2') // ? Icons.directions_boat_filled_sharp // : Icons.add_card_rounded, // color: Colors.white, // Less opaque for inactive state // ), // ), // activeItem: SizedBox( // width: 24.0, // height: 24.0, // child: Icon( // (userType == '1' || userType == '2') // ? Icons.directions_boat_filled_sharp // : Icons.add_card_rounded, // color: Colors.white, // Less opaque for inactive state // ), // ), // itemLabel: (userType == '1' || userType == '2') // ? AppConstants.VESSEL.toUpperCase() // : AppConstants.TICKET.toUpperCase(), // ), // // ///2 chat Tab // BottomBarItem( // inActiveItem: const SizedBox( // width: 24.0, // height: 24.0, // child: Icon( // Icons.chat, // color: Colors.white, // Less opaque for inactive state // size: AppConfigs.ICON_SMALL_SIZE, // ), // ), // activeItem: const SizedBox( // width: 24.0, // height: 24.0, // child: Icon( // Icons.chat, // color: Colors.white, // Less opaque for inactive state // size: AppConfigs.ICON_SMALL_SIZE, // ), // ), // itemLabel: AppConstants.CHATS.toUpperCase(), // ), // // ///3 Vessel Tab // if ((userType == '1' || // userType == '2')) // BottomBarItem( // // inActiveItem: const Icon( // // Icons.directions_boat_filled_sharp, // // color: AppConfigs.FifthColor, // // size: AppConfigs.ICON_SMALL_SIZE, // // ), // // activeItem: const Icon( // // Icons.directions_boat_filled_sharp, // // color: AppConfigs.FifthColor, // // size: AppConfigs.ICON_SMALL_SIZE, // // ), // // inActiveItem: GestureDetector( // onTap: () { // // Handle tap action for inActiveItem // if (userType == '1' || // userType == '2') { // print(userType); // Navigator.pushNamed(context, '/vessel'); // } else { // ScaffoldMessenger.of(context).showSnackBar( // SnackBar( // content: Text( // "You don't have access to this feature.")), // ); // } // }, // child: const SizedBox( // width: 24.0, // height: 24.0, // child: Icon( // Icons.add_card_rounded, // color: Colors.white, // size: AppConfigs.ICON_SMALL_SIZE, // ), // ), // ), // activeItem: GestureDetector( // onTap: () { // if (userType == '1' || // userType == '2' ) { // print(userType); // // Navigator.pushNamed(context, '/vessel'); // } else { // ScaffoldMessenger.of(context).showSnackBar( // const SnackBar( // content: Text( // "You don't have access to this feature.")), // ); // } // }, // child: SizedBox( // width: 24.0, // height: 24.0, // child: Icon( // Icons.add_card_rounded, // color: Colors.white, // Less opaque for inactive state // size: AppConfigs.ICON_SMALL_SIZE, // // ), // ), // ), // // itemLabel: AppConstants.VESSEL.toUpperCase(), // itemLabel: AppConstants.TICKET.toUpperCase(), // // // onTap: () { // // if (userType == 1 || userType == 2 || userType == 3) { // // // If user type is allowed, navigate to the Vessel screen // // Navigator.pushNamed(context, '/vessel'); // // } else { // // // If user type is not allowed, show a message or perform other actions // // ScaffoldMessenger.of(context).showSnackBar( // // SnackBar( // // content: Text("You don't have access to this feature."), // // ), // // ); // // } // // }, // ), // // // ], // onTap: (index) { // /// perform action on tab change and to update pages you can update pages without pages // _pageController.animateToPage(index,duration: Duration(milliseconds: 300),curve: Curves.fastOutSlowIn); // if(mounted){ // _controller.jumpTo(index); // // } // // // if(!(userType == '1'|| userType=='2')) // // _onTabTapped(index); // }, // kIconSize: 24.0, // // ) // : null, // // ), // ); // } // old above

@override Widget build(BuildContext context) {

DataProvider dataProvider = Provider.of<DataProvider>(context);
 changeuserType();
 _updateScreens();
bool isLoading = dataProvider.isLoading;
var size = MediaQuery.of(context).size;
double appBarHeight = 30;

return isLoading
    ? CustomLoader()
    : SafeArea(
        child: Scaffold(
          resizeToAvoidBottomInset: false,
          appBar: PreferredSize(
            preferredSize:
                Size(size.width, 100.0), // Adjust preferredSize as needed
            child: Container(
              decoration: const BoxDecoration(
                gradient: LinearGradient(
                  colors: [
                    AppConfigs.PrimaryColor,
                    AppConfigs.SixthColor,
                  ],
                ),
              ),
              child: Padding(
                padding: EdgeInsets.all(0), // Adjust padding as needed
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    SingleChildScrollView(
                      scrollDirection: Axis.horizontal,
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          // Logout button
                          SizedBox(
                            height: appBarHeight,
                            child: InkWell(
                              onTap: () {
                                Provider.of<AuthProvider>(context,
                                        listen: false)
                                    .clearSharedData();
                                Navigator.pushNamedAndRemoveUntil(
                                  context,
                                  MyRouter.login,
                                  (route) => false,
                                  arguments: const LoginScreen(),
                                );
                              },
                              child: const Align(
                                alignment: Alignment.center,
                                child: Icon(
                                  Icons.power_settings_new,
                                  size: 20,
                                  color: AppConfigs.FifthColor,
                                ),
                              ),
                            ),
                          ),
                          SizedBox(width: size.width / 100),

                          // Notification bell
                          // SizedBox(
                          //   height: appBarHeight,
                          //   child: InkWell(
                          //     onTap: (_notificationCount ?? 0) > 0 ? ()  {
                          //       Navigator.pushNamed(context, MyRouter.notification);
                          //     }: null,
                          //     child: Stack(
                          //       children: [
                          //         const Positioned(
                          //           child: Align(
                          //             alignment: Alignment.center,
                          //             child: Icon(
                          //               Icons.notifications,
                          //               size: 20,
                          //               color: AppConfigs.FifthColor,
                          //             ),
                          //           ),
                          //         ),
                          //         if ((_notificationCount ?? 0) > 0)
                          //         Positioned.fill(
                          //           child: Align(
                          //             alignment: Alignment.topRight,
                          //             child:
                          //                 Container(
                          //                     width: 15,
                          //                     height: 15,
                          //                     decoration: BoxDecoration(
                          //                       shape: BoxShape.circle,
                          //                       color: (_notificationCount ?? 0) > 0?const Color(0xffc32c37): Colors.red,
                          //                       border: Border.all(
                          //                           color: Colors.white,
                          //                           width: 1),
                          //                     ),
                          //                     child: Center(
                          //                       child: Text(
                          //                         '${(_notificationCount ?? 0) > 30 ? '30+' : _notificationCount}',
                          //
                          //                         // notifications.length
                          //                         //     .toString(),
                          //                         style: const TextStyle(
                          //                             fontSize: 10,
                          //                             color: Colors.white),
                          //                       ),
                          //                     ),
                          //                   )
                          //                 // : const SizedBox(),
                          //           ),
                          //         ),
                          //       ],
                          //     ),
                          //   ),
                          // ),
                          SizedBox(
                            height: appBarHeight,
                            child: InkWell(
                              onTap:  notifications != null && notifications.isNotEmpty ? ()  {
                                Navigator.pushNamed(context, MyRouter.notification);
                              }: null,
                              child: Stack(
                                children: [
                                  const Positioned(
                                    child: Align(
                                      alignment: Alignment.center,
                                      child: Icon(
                                        Icons.notifications,
                                        size: 20,
                                        color: AppConfigs.FifthColor,
                                      ),
                                    ),
                                  ),
                                  Positioned.fill(
                                    child: Align(
                                      alignment: Alignment.topRight,
                                      child: Container(
                                        width: 15,
                                        height: 15,
                                        decoration: BoxDecoration(
                                          shape: BoxShape.circle,
                                          color: const Color(0xffc32c37),
                                          border: Border.all(color: Colors.white, width: 1),
                                        ),
                                        child: Padding(
                                          padding: const EdgeInsets.all(0.0),
                                          child: Center(
                                            child: Text(
                                              notifications != null && notifications.isNotEmpty
                                                  ? (notifications.length > 50 ? '50+' : notifications.length.toString())
                                                  : '0', // Show zero if there are no notifications
                                              style: const TextStyle(fontSize: 10, color: Colors.white),
                                            ),
                                          ),
                                        ),
                                      ),

                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                          SizedBox(width: size.width / 100),

                          // Profile Name & Avatar
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              InkWell(
                                onTap: () {
                                  isDesktop(context)
                                      ? Navigator.pushNamedAndRemoveUntil(
                                          context,
                                          MyRouter.profile,
                                          (route) => false)
                                      : Navigator.pushNamed(
                                          context,
                                          MyRouter.profile,
                                          arguments: notifications.length
                                              .toString(),
                                        );
                                },
                                child: CircleAvatar(
                                  backgroundColor: AppConfigs.TertiaryColor,
                                  backgroundImage: Provider.of<
                                                  DataProvider>(context)
                                              .profileModel
                                              ?.profilePic
                                              .isNotEmpty ==
                                          true
                                      ? NetworkImage(
                                          Provider.of<DataProvider>(context)
                                              .profileModel!
                                              .profilePic)
                                      : AssetImage(LocalImages.profile_logo)
                                          as ImageProvider<Object>?,
                                  radius: 10,
                                ),
                              ),
                              SizedBox(width: isDesktop(context) ? 10 : 5),
                              Visibility(
                                visible: isDesktop(context),
                                child: Row(
                                  children: [
                                    InkWell(
                                      onTap: () {
                                        isDesktop(context)
                                            ? Navigator
                                                .pushNamedAndRemoveUntil(
                                                    context,
                                                    MyRouter.profile,
                                                    (route) => false)
                                            : Navigator.pushNamed(
                                                context,
                                                MyRouter.profile,
                                                arguments: notifications
                                                    .length
                                                    .toString(),
                                              );
                                      },
                                      child: Text(
                                        dataProvider.profileModel?.name ??
                                            "",
                                        style: const TextStyle(
                                            color: Colors.white),
                                      ),
                                    ),
                                    const SizedBox(width: 5),
                                    const Icon(Icons.arrow_drop_down,
                                        color: Colors.white),
                                  ],
                                ),
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                    const SizedBox(width: 5),
                  ],
                ),
              ),
            ),
          ),
          body: PageView(
            controller: _pageController,
            physics: const NeverScrollableScrollPhysics(),
            reverse: true,
            scrollDirection: Axis.horizontal,
            // children: List.generate(_screens.length, (index) => _screens[index]),
            children: _screens,

            onPageChanged: (index) {

              if (!_isControllerDisposed) {
                  // _controller.jumpTo(index);
                setState(() {
                  _currentIndex = index;
                });
                  print('object $index');

              }
            },

          ),
          extendBody: true,
          bottomNavigationBar: (_screens.length <= maxCount)
              ? AnimatedNotchBottomBar(
                  notchBottomBarController: _controller,
                  color: AppConfigs.TertiaryColor,
                  itemLabelStyle: const TextStyle(
                    color: AppConfigs.FifthColor,
                    fontSize: AppConfigs.TIMELINE_TEXT,
                    fontFamily: AppConfigs.font,
                  ),
                  showLabel: true,
                  shadowElevation: 0,
                  kBottomRadius: 0,
                  notchShader: const SweepGradient(
                    startAngle: 0,
                    endAngle: 2/ 2,
                    colors: [
                      AppConfigs.PrimaryColor,
                      AppConfigs.SixthColor
                    ],
                    tileMode: TileMode.mirror,
                  ).createShader(
                    Rect.fromCircle(center: Offset.zero, radius: 8.0),
                  ),
                  notchColor: AppConfigs.TertiaryColor,
                  removeMargins: true,
                  bottomBarWidth: size.width,
                  showBlurBottomBar: false,
                  durationInMilliSeconds: 300,

                  bottomBarItems: [
                    BottomBarItem(
                      inActiveItem: Padding(
                        padding: const EdgeInsets.only(right: 5),
                        child:
                        Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            Icon(
                              (userType == '1' || userType == '2')
                                  ? Icons.directions_boat_filled_sharp
                                  : Icons.add_card_rounded,
                              color: Colors.white,
                               // size: AppConfigs.ICON_SMALL_SIZE,
                            ),
                          ],
                        ),
                      ),
                      activeItem: Padding(
                        padding: const EdgeInsets.only(right: 5),
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            Icon(
                              (userType == '1' || userType == '2')
                                  ? Icons.directions_boat_filled_sharp
                                  : Icons.add_card_rounded,
                              color: Colors.white,
                              // size: AppConfigs.ICON_SMALL_SIZE,
                            ),
                          ],
                        ),
                      ),
                      itemLabel: (userType == '1' || userType == '2')
                          ? AppConstants.VESSEL.toUpperCase()
                           : AppConstants.TICKET.toUpperCase(),
                    ),
                    BottomBarItem(
                      inActiveItem: const Padding(
                        padding:  EdgeInsets.only(right:5),
                        child: Center(
                          child:  Icon(
                            Icons.chat,
                            color: Colors.white,
                            // size: AppConfigs.ICON_SMALL_SIZE,
                          ),
                        ),
                      ),
                      activeItem:const Padding(
                        padding:  EdgeInsets.only(right: 5),
                        child: Center(
                          child:  Icon(
                            Icons.chat,
                            color: Colors.white,
                             // size: AppConfigs.ICON_SMALL_SIZE,
                          ),
                        ),
                      ),
                      itemLabel: AppConstants.CHATS.toUpperCase(),
                    ),
                     if (userType == '1' || userType == '2')
                      BottomBarItem(
                        inActiveItem:const Padding(
                          padding:  EdgeInsets.only(right: 5),
                          child:  Icon(
                            Icons.add_card_rounded,
                            color: Colors.white,
                             size: 24,
                          ),
                        ),
                        activeItem:const Padding(
                          padding:  EdgeInsets.only(right: 5),
                          child:  Icon(
                            Icons.add_card_rounded,
                            color: Colors.white,
                          size: 24,
                          ),
                        ),
                        itemLabel: AppConstants.TICKET.toUpperCase(),
                      ),
                  ],

                  onTap: (index)  {
                    if (!_isControllerDisposed) {
                      // Ensure the index is valid
                      if (index >= 0 && index < _screens.length) {
                        // Use animateToPage for smooth transitions
                        _pageController.jumpToPage(index);

                        // Update the bottom navigation bar's selected index
                        setState(() {
                          _currentIndex = index;
                          if (mounted && _controller != null && !_isControllerDisposed) {
                            _controller.jumpTo(index);
                          }
                        });

                        // Conditionally call _onTabTapped based on userType
                        bool shouldHandleTab =
                            userType != '1' && userType != '2';
                        if (shouldHandleTab) {
                          _onTabTapped(index);
                        }
                      }
                    }
                  },

                  kIconSize: 30,
                )
              : null,
        ),
      );

} }