// ignore_for_file: prefer_const_constructors, prefer_typing_uninitialized_variables, unrelated_type_equality_checks import 'dart:async'; import 'dart:io'; import 'dart:ui'; import 'package:animations/animations.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:get/get.dart'; import 'package:gsp_app/repository/response_data.dart'; import 'package:gsp_app/view_model/app_data_controller.dart'; import 'package:gsp_app/view_model/common_functions.dart'; import 'package:gsp_app/view_model/global_controller.dart'; import 'package:gsp_app/views/components/page_animation.dart'; import 'package:skeletons/skeletons.dart'; import '../../../modals/leaderboard_ranking_model.dart'; import '../../../repository/services/cj/leader_board_ranking.dart'; import '../../../view_model/my_ranking_controller.dart'; import '../../components/bottom_navigation.dart'; import '../../components/leaderboard_element.dart'; import '../../theme.dart'; import '../StepCount/HealthApp.dart'; import '../profile/pages/view_profile.dart'; import 'filter_elites_leaderboard.dart'; class MVPelitesBoard extends StatefulWidget { const MVPelitesBoard({Key? key}) : super(key: key); @override State createState() => _MVPelitesBoardState(); } class _MVPelitesBoardState extends State with SingleTickerProviderStateMixin { AppDataController appDataController = Get.find(); late AnimationController _animationController; late Timer _timer; var userIndexId; var up = 'assets/image/arrows/arrow_up.svg'; var down = 'assets/image/arrows/arrow_down.svg'; var still = 'assets/image/arrows/arrow_right.svg'; late String genderDefaultSelected; late String groupLevelDefaultSelected; final calculateStepsFromHealthApp stepscontroller = Get.put(calculateStepsFromHealthApp()); String timeAgo = ''; String timeAgoSelf = ''; // Timer? _timer; // Timer object to schedule periodic refresh void _startTimer() { _timer = Timer.periodic(Duration(seconds: 25), (Timer timer) async { if (Platform.isIOS) { await stepscontroller .fetchStepData() .then((value) => stepscontroller.storeStepsInDB()); } setState(() {}); }); } @override void initState() { super.initState(); _startTimer(); if (Platform.isIOS) { stepscontroller .fetchStepData() .then((value) => stepscontroller.storeStepsInDB()); } _animationController = AnimationController( value: 0.0, duration: const Duration(milliseconds: 600), reverseDuration: const Duration(milliseconds: 75), vsync: this, ); } @override void dispose() { _timer.cancel(); _animationController.dispose(); super.dispose(); } MyRankingController myRankingController = Get.put(MyRankingController()); @override Widget build(BuildContext context) { int index = -1; _animationController.forward(); final brightness = Get.theme.brightness; return Scaffold( // backgroundColor: ColorConstants.kBlack, appBar: AppBar( automaticallyImplyLeading: false, titleSpacing: 0, centerTitle: true, // backgroundColor: ColorConstants.kBlack, // elevation: 0, title: Text( 'Leaderboard', style: TextStyle( fontSize: 16, color: (brightness == Brightness.light) ? ColorConstants.kBlack : ColorConstants.kWhite, ), ), bottom: PreferredSize( preferredSize: const Size.fromHeight(50), child: Padding( padding: const EdgeInsets.only(bottom: 20.0), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ GestureDetector( onTap: () { // debugPrint("BackdropFilter, $genderDefaultSelected"); // debugPrint("BackdropFilter, $groupLevelDefaultSelected"); Get.dialog( BackdropFilter( filter: ImageFilter.blur(sigmaX: 8, sigmaY: 8), child: FilterLeaderboard( defaultGender: genderDefaultSelected, defaultGroupLevel: groupLevelDefaultSelected), ), ); }, child: Container( height: 36, padding: const EdgeInsets.symmetric(horizontal: 18), // decoration: ShapeDecoration( // color: Color(0xff333333), // shape: StadiumBorder(), // ), decoration: BoxDecoration( color: (brightness == Brightness.light) ? ColorConstants.kWhite : const Color(0xff333333), borderRadius: BorderRadius.circular(50), boxShadow: [ BoxShadow( color: ColorConstants.kBlack.withOpacity(0.12), spreadRadius: 2, blurRadius: 10, ) ]), child: Row(mainAxisSize: MainAxisSize.min, children: [ Text( "Filter", style: QuizTextStyles.heading.copyWith( color: (brightness == Brightness.light) ? ColorConstants.kBlack : ColorConstants.kWhite), ), SizedBox(width: 6), Icon( Icons.filter_alt, color: (brightness == Brightness.light) ? ColorConstants.kBlack : Colors.white, size: 20, ), ]), ), ), const SizedBox(width: 24), ], ), ), ), ), body: Obx(() { return AnimatedBuilder( child: FutureBuilder( future: RankingLeaderboard().getLeaderboardRanking( gender: myRankingController.gender.value, groupLevel: myRankingController.groupLevel.value, ), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return ListView( children: [ for (var i = 0; i < 12; i++) Padding( padding: const EdgeInsets.symmetric( horizontal: 4, vertical: 8), child: SkeletonAvatar( style: SkeletonAvatarStyle( padding: const EdgeInsets.symmetric(horizontal: 8), width: context.width, height: 56, borderRadius: BorderRadius.circular(100), ), ), ), ], ); } else if (snapshot.hasError) { return Center( child: Text('Something Went Wrong\n please try again later ☹️.'), ); } else { RnakingModel userRanking = snapshot.data!.data; // print('userRanking test ${userRanking.groupLevel}'); genderDefaultSelected = userRanking.gender; groupLevelDefaultSelected = userRanking.groupLevel; final userID = appDataController.id; List x = userRanking.userData as List; var selfData; // print('all x data ${userRanking.userData![0].totalScore}'); try { selfData = x.where((e) => e.userId == userID.value).first; } catch (e) { selfData = null; } for (var i = 0; i < userRanking.userData!.length; i++) { if (userRanking.userData![i].userId == userID.value) { userIndexId = i + 1; // print('userIndex without null'); break; // print('userIndexId $userIndexId'); } else { // print('userIndex with null'); userIndexId = null; } // print('userIndexId user id ${appDataController.id};'); } print('userIndexId $userIndexId'); void calculateTimeAgo(times) { // var yearsinDays = 365; DateTime now = DateTime.now(); DateTime timestamp = DateTime.parse(times); Duration difference = now.difference(timestamp); if (difference.inSeconds < 60) { timeAgo = '${difference.inSeconds} seconds ago'; } else if (difference.inMinutes < 60) { timeAgo = '${difference.inMinutes} minutes ago'; } else if (difference.inHours < 24) { timeAgo = '${difference.inHours} hours ago'; } else if (difference.inDays < 30) { timeAgo = '${difference.inDays} days ago'; } else if (difference.inDays < 365) { int months = (difference.inDays / 30).floor(); timeAgo = '$months months ago'; } else { int years = (difference.inDays / 365).floor(); timeAgo = '$years years ago'; } // return ''; } void calculateTimeAgoSelf(times) { // var yearsinDays = 365; DateTime now = DateTime.now(); DateTime timestamp = DateTime.parse(times); Duration difference = now.difference(timestamp); if (difference.inSeconds < 60) { timeAgoSelf = '${difference.inSeconds} seconds ago'; } else if (difference.inMinutes < 60) { timeAgoSelf = '${difference.inMinutes} minutes ago'; } else if (difference.inHours < 24) { timeAgoSelf = '${difference.inHours} hours ago'; } else if (difference.inDays < 30) { timeAgoSelf = '${difference.inDays} days ago'; } else if (difference.inDays < 365) { int months = (difference.inDays / 30).floor(); timeAgoSelf = '$months months ago'; } else { int years = (difference.inDays / 365).floor(); timeAgoSelf = '$years years ago'; } // return ''; } return (userRanking.userData!.isNotEmpty) ? ListView( children: [ SizedBox( height: 300, child: Center( child: ListView( scrollDirection: Axis.horizontal, shrinkWrap: true, physics: NeverScrollableScrollPhysics(), children: [ //index: 1 SizedBox( width: Get.size.width * 0.31, child: (userRanking.userData!.length >= 2 && userRanking.userData![1].user ?.fullName != null) ? OpenContainerWrappers( closeBuild: Padding( padding: const EdgeInsets.only( top: 110), child: WinnerUserElement( point: userRanking .userData![1].totalScore, rankIconPath: (userRanking .userData![1] .progressBar == '0') ? "assets/image/arrows/arrow_up.svg" : (userRanking.userData![1] .progressBar == '1') ? "assets/image/arrows/arrow_down.svg" : "assets/image/arrows/arrow_right.svg", imgUrl: userRanking .userData![1] .userData! .profilePicture ?? "", name: userRanking.userData![1] .user!.fullName, rank: 2, ), ), openBuild: ViewProfile( viewFrndProfileModels: userRanking.userData![1], groupLevel: userRanking.groupLevel, ), ) : SizedBox(), ), //index: 0 SizedBox( width: Get.size.width * 0.31, child: (userRanking.userData!.length >= 1 && userRanking.userData![0].user ?.fullName != null) ? OpenContainerWrappers( closeBuild: WinnerUserElement( point: userRanking .userData![0].totalScore, large: true, rankIconPath: "assets/image/crown.svg", imgUrl: userRanking .userData![0] .userData! .profilePicture ?? "", name: userRanking .userData![0].user!.fullName, rank: 1, ), openBuild: ViewProfile( viewFrndProfileModels: userRanking.userData![0], groupLevel: userRanking.groupLevel, ), ) : SizedBox(), ), //index: 2 SizedBox( width: Get.size.width * 0.31, child: (userRanking.userData!.length >= 3 && userRanking.userData![2].user ?.fullName != null) ? OpenContainerWrappers( closeBuild: Padding( padding: const EdgeInsets.only( top: 110), child: WinnerUserElement( point: userRanking .userData![2].totalScore, rankIconPath: (userRanking .userData![2] .progressBar == '0') ? "assets/image/arrows/arrow_up.svg" : (userRanking.userData![2] .progressBar == '1') ? "assets/image/arrows/arrow_down.svg" : "assets/image/arrows/arrow_right.svg", imgUrl: userRanking .userData![2] .userData! .profilePicture ?? "", name: userRanking.userData![2] .user!.fullName, rank: 3, ), ), openBuild: ViewProfile( viewFrndProfileModels: userRanking.userData![2], groupLevel: userRanking.groupLevel, ), ) : SizedBox(), ) ], ), ), ), // Self ranking counting userIndexId != null ? userIndexId > 5 ? Builder(builder: (context) { calculateTimeAgoSelf( selfData.updatatedTime); return OpenContainerWrappers( closeBuild: Padding( padding: const EdgeInsets.only( left: 8, right: 8, bottom: 16, ), child: Container( decoration: BoxDecoration( border: Border.all( color: ColorConstants .kPrimaryColor, width: 1, ), borderRadius: BorderRadius.circular(30)), child: LeaderboardElement( id: index, rank: userIndexId, points: selfData.totalScore, leaderboardArrowIconPath: (selfData .progressBar == '0') ? "assets/image/arrows/arrow_up.svg" : (selfData.progressBar == '1') ? "assets/image/arrows/arrow_down.svg" : "assets/image/arrows/arrow_right.svg", imgPath: selfData.userData ?.profilePicture ?? "", userName: 'You', lastUpdate: timeAgoSelf, ), ), ), openBuild: ViewProfile( viewFrndProfileModels: userRanking .userData![userIndexId - 1], groupLevel: userRanking.groupLevel, ), ); }) : SizedBox() : SizedBox(), (userRanking.userData!.length > 3) ? ListView.builder( itemCount: userRanking.userData!.length - 3, physics: BouncingScrollPhysics(), shrinkWrap: true, itemBuilder: (context, index) { List newLength = userRanking.userData!.sublist(3); calculateTimeAgo( newLength[index].updatatedTime); return OpenContainerWrappers( closeBuild: Padding( padding: const EdgeInsets.only( left: 8, right: 8, bottom: 16, ), child: LeaderboardElement( lastUpdate: '${timeAgo}', id: index, rank: index + 4, points: newLength[index].totalScore, leaderboardArrowIconPath: (newLength[ index] .progressBar == '0') ? "assets/image/arrows/arrow_up.svg" : (newLength[index].progressBar == '1') ? "assets/image/arrows/arrow_down.svg" : "assets/image/arrows/arrow_right.svg", imgPath: newLength[index] .userData ?.profilePicture ?? "", userName: newLength[index].user.fullName, ), ), openBuild: ViewProfile( viewFrndProfileModels: newLength[index], groupLevel: userRanking.groupLevel, ), ); }, ) : SizedBox(), ], ) : Center(child: Text('No User Found')); } }, ), animation: _animationController, builder: (context, child) => FadeScaleTransition( animation: _animationController, child: child, ), ); }), bottomNavigationBar: BottomNavigation( // three: BottomNavigationController.three, // four: BottomNavigationController.four, // five: BottomNavigationController.five, // six: BottomNavigationController.six, // seven: BottomNavigationController.seven, ), ); } } class WinnerUserElement extends StatelessWidget { const WinnerUserElement({ Key? key, required this.rankIconPath, required this.imgUrl, required this.name, required this.rank, required this.point, this.large = false, }) : super(key: key); final String rankIconPath; final String imgUrl; final String name; final int rank; final bool large; final int point; @override Widget build(BuildContext context) { // AppDataController appDataController = Get.find(); GlobalController globalController = Get.find(); return Column( mainAxisSize: MainAxisSize.min, children: [ //rank icon SvgPicture.asset( rankIconPath, width: large ? 65 : 24, ), const SizedBox(height: 8), //profile pic Stack( alignment: AlignmentDirectional.bottomCenter, clipBehavior: Clip.none, children: [ Container( width: large ? 118 : 84, height: large ? 118 : 84, decoration: BoxDecoration( color: const Color(0xff212121), border: Border.all( color: Colors.green, width: 2, ), shape: BoxShape.circle, ), child: imgUrl.isEmpty ? ClipRRect( borderRadius: BorderRadius.circular(100), child: Image.network( 'https://media.istockphoto.com/id/1327592449/vector/default-avatar-photo-placeholder-icon-grey-profile-picture-business-man.jpg?s=612x612&w=0&k=20&c=yqoos7g9jmufJhfkbQsk-mdhKEsih6Di4WZ66t_ib7I='), ) : CircleAvatar( // foregroundColor:!globalController.darkMode.value? Colors.transparent:Colors.transparent, backgroundImage: NetworkImage( correctImgUrl(imgUrl), ), backgroundColor: Colors.transparent, ), ), Positioned( bottom: -10, child: CircleAvatar( // foregroundColor:!globalController.darkMode.value?ColorConstants.kErroColor:Colors.transparent, backgroundColor: large ? ColorConstants.kPrimaryColor : ColorConstants.kWhite, maxRadius: large ? 16 : 12, child: Text( rank.toString(), style: TextStyle( fontWeight: FontWeight.bold, fontSize: large ? 18 : 14, color: ColorConstants.kBlack, ), ), ), ), ], ), SizedBox(height: 16), Text( name, style: TextStyle(fontSize: 16), textAlign: TextAlign.center, ), SizedBox(height: 2), Obx( () => Text( point.toString(), style: TextStyle( color: !globalController.darkMode.value ? ColorConstants.kBlack : ColorConstants.kPrimaryColor, ), ), ), ], ); } }