From 502e09cf8b1769c9418be445303e93af26014bdd Mon Sep 17 00:00:00 2001 From: babayaga2002 Date: Sat, 15 Oct 2022 00:19:07 +0530 Subject: [PATCH 01/82] Background notifications --- README.md | 17 ++- android/app/build.gradle | 6 + android/app/src/main/AndroidManifest.xml | 12 +- android/build.gradle | 1 + ios/Runner.xcodeproj/project.pbxproj | 18 +-- ios/Runner/AppDelegate.swift | 10 +- ios/Runner/Info.plist | 156 +++++++++++----------- lib/main.dart | 6 + lib/pages/barcode.dart | 163 ++++++++++++----------- pubspec.yaml | 3 + 10 files changed, 226 insertions(+), 166 deletions(-) diff --git a/README.md b/README.md index 3bbe4ba7..2e33083c 100644 --- a/README.md +++ b/README.md @@ -1 +1,16 @@ -![feature graphic](https://user-images.githubusercontent.com/75874394/192554328-370aece6-9697-4878-92b8-eb120d07e1b1.png) +# onestop_dev + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/android/app/build.gradle b/android/app/build.gradle index 9e6e40ee..cfaa7a92 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -34,6 +34,7 @@ if (project.hasProperty('dart-defines')) { apply plugin: 'com.android.application' +apply plugin: 'com.google.gms.google-services' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" @@ -67,6 +68,7 @@ android { versionCode flutterVersionCode.toInteger() versionName flutterVersionName manifestPlaceholders['GMAP_KEY'] = dartEnvironmentVariables.GMAP_KEY + multiDexEnabled true } signingConfigs { @@ -90,5 +92,9 @@ flutter { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + implementation "com.google.firebase:firebase-inappmessaging-display:19.1.5" + implementation platform('com.google.firebase:firebase-bom:31.0.0') + implementation 'com.google.firebase:firebase-analytics' + implementation "com.android.support:multidex:1.0.3" } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d68f0ebc..95f80087 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -17,7 +17,9 @@ android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" - android:windowSoftInputMode="adjustResize"> + android:windowSoftInputMode="adjustResize" + android:showWhenLocked="true" + android:turnScreenOn="true"> + + + diff --git a/android/build.gradle b/android/build.gradle index 83ae2200..99f1e0e1 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,6 +8,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:7.1.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.google.gms:google-services:4.3.13' } } diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 54679128..e5ab4074 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -372,8 +372,8 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 9LF97T55R7; ENABLE_BITCODE = NO; @@ -384,7 +384,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.swciitg.onestop2swc2022; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; + PROVISIONING_PROFILE_SPECIFIER = "OneStop AdHoc Profile"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -504,8 +504,8 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 9LF97T55R7; ENABLE_BITCODE = NO; @@ -516,7 +516,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.swciitg.onestop2swc2022; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; + PROVISIONING_PROFILE_SPECIFIER = "OneStop AdHoc Profile"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -530,8 +530,8 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 9LF97T55R7; ENABLE_BITCODE = NO; @@ -542,7 +542,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.swciitg.onestop2swc2022; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; + PROVISIONING_PROFILE_SPECIFIER = "OneStop AdHoc Profile"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 435706da..49f0aa96 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -6,8 +6,14 @@ import GoogleMaps @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any] ? ) -> Bool { + if #available(iOS 10.0, *) { + UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate + } + FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in + GeneratedPluginRegistrant.register(with: registry) + } let dartDefinesString = Bundle.main.infoDictionary!["DART_DEFINES"] as! String var dartDefinesDictionary = [String:String]() for definedValue in dartDefinesString.components(separatedBy: ",") { @@ -15,7 +21,7 @@ import GoogleMaps let values = decoded.components(separatedBy: "=") dartDefinesDictionary[values[0]] = values[1] } - GMSServices.provideAPIKey(dartDefinesDictionary["GMAP_KEY"] as? String ?? "") + GMSServices.provideAPIKey(Bundle.main.object(forInfoDictionaryKey: "GMAP_API_KEY") as? String ?? "") GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 4252dbbb..ff3fc635 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -1,81 +1,81 @@ - - CADisableMinimumFrameDurationOnPhone - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - OneStop - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - onestop_dev - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - DART_DEFINES - $(DART_DEFINES) - GMAP_API_KEY - $(GMAP_API_KEY) - LSApplicationQueriesSchemes - - comgooglemaps - baidumap - iosamap - waze - yandexmaps - yandexnavi - citymapper - mapswithme - osmandmaps - dgis - qqmap - here-location - tomtomgo - - LSRequiresIPhoneOS - - NSCalendarsUsageDescription - OneStop may add events to your device's calendar - NSCameraUsageDescription - This app requires Camera access for Lost/Found or Buy/Sell images - NSLocationAlwaysUsageDescription - This app needs access to location when open. - NSLocationUsageDescription - This app needs access to location when open. - NSLocationWhenInUseUsageDescription - This app needs access to location when open. - NSPhotoLibraryUsageDescription - This app requires Photo Library access for Lost/Found or Buy/Sell images - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiresFullScreen - - UIStatusBarHidden - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - - UIViewControllerBasedStatusBarAppearance - - - + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + OneStop + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + onestop_dev + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + GMAP_API_KEY + $(GMAP_API_KEY) + LSApplicationQueriesSchemes + + comgooglemaps + baidumap + iosamap + waze + yandexmaps + yandexnavi + citymapper + mapswithme + osmandmaps + dgis + qqmap + here-location + tomtomgo + + LSRequiresIPhoneOS + + NSCalendarsUsageDescription + OneStop may add events to your device's calendar + NSLocationWhenInUseUsageDescription + This app needs access to location when open. + NSLocationAlwaysUsageDescription + This app needs access to location when open. + NSLocationUsageDescription + This app needs access to location when open. + NSLocationAlwaysUsageDescription + This app needs access to location when open. + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + + UIViewControllerBasedStatusBarAppearance + + NSPhotoLibraryUsageDescription + This app requires Photo Library access for Lost/Found or Buy/Sell images + NSCameraUsageDescription + This app requires Camera access for Lost/Found or Buy/Sell images + DART_DEFINES + $(DART_DEFINES) + + \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index a4e54abe..12cc0141 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,8 +1,11 @@ +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:onestop_dev/functions/utility/check_last_updated.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/routes.dart'; +import 'package:onestop_dev/services/notifications_provider.dart'; import 'package:onestop_dev/stores/common_store.dart'; import 'package:onestop_dev/stores/login_store.dart'; import 'package:onestop_dev/stores/mapbox_store.dart'; @@ -12,11 +15,14 @@ import 'package:provider/provider.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp(); SystemChrome.setPreferredOrientations( [DeviceOrientation.portraitDown, DeviceOrientation.portraitUp]); SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom, SystemUiOverlay.top]); await checkLastUpdated(); + await checkForNotifications(); + FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); runApp(const MyApp()); } diff --git a/lib/pages/barcode.dart b/lib/pages/barcode.dart index cd282134..d05d25ca 100644 --- a/lib/pages/barcode.dart +++ b/lib/pages/barcode.dart @@ -6,6 +6,7 @@ import 'package:onestop_dev/stores/login_store.dart'; import 'package:onestop_dev/widgets/ui/appbar.dart'; import 'package:provider/provider.dart'; import 'package:barcode_widget/barcode_widget.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class QRPage extends StatefulWidget { static String id = "/qr"; @@ -17,89 +18,101 @@ class QRPage extends StatefulWidget { } class _QRPageState extends State { + @override Widget build(BuildContext context) { SizeConfig().init(context); + return Scaffold( appBar: appBar(context, displayIcon: false), body: SafeArea( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const SizedBox( - height: 16, - ), - Text( - "${context.read().userData['name']}", - textAlign: TextAlign.center, - style: MyFonts.w800.setColor(kWhite).size(20), - ), - Text( - '${context.read().userData['rollno']}', - textAlign: TextAlign.center, - style: MyFonts.w500.setColor(kWhite).size(20), - ), - const SizedBox( - height: 26, - ), - Stack( - children: [ - Container( - height: 300, - width: double.infinity, - color: kWhite, - ), - Positioned.fill( - child: Align( - alignment: Alignment.center, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: BarcodeWidget( - barcode: Barcode.code128(), - data: "${context.read().userData['rollno']}", - height: 150, - color: kBlack, - backgroundColor: kWhite, - drawText: false, - ), - ), - ), - ), - ], - ), - // Padding( - // padding: const EdgeInsets.only(top: 20), - // child: Center( - // child: Text( - // "Library issuing barcode", - // textAlign: TextAlign.center, - // style: MyFonts.w500.setColor(kWhite).size(18), + child: + // SingleChildScrollView( + // child: Padding( + // padding: const EdgeInsets.symmetric(horizontal: 16), + // child: + // Column( + // mainAxisAlignment: MainAxisAlignment.center, + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + FutureBuilder(future: SharedPreferences.getInstance(), builder: (context,snapshot) { + if(snapshot.hasData){ + return ListView.builder(itemCount: snapshot.data!.getStringList('notifications')!.length, itemBuilder: (context, index){ + return Text(snapshot.data!.getStringList('notifications')![index],style: TextStyle(color: Colors.white),); + }); + } + return CircularProgressIndicator(); + }), + // const SizedBox( + // height: 16, + // ), + // Text( + // "${context.read().userData['name']}", + // textAlign: TextAlign.center, + // style: MyFonts.w800.setColor(kWhite).size(20), + // ), + // Text( + // '${context.read().userData['rollno']}', + // textAlign: TextAlign.center, + // style: MyFonts.w500.setColor(kWhite).size(20), + // ), + // const SizedBox( + // height: 26, + // ), + // Stack( + // children: [ + // Container( + // height: 300, + // width: double.infinity, + // color: kWhite, + // ), + // Positioned.fill( + // child: Align( + // alignment: Alignment.center, + // child: Padding( + // padding: const EdgeInsets.symmetric(horizontal: 16), + // child: BarcodeWidget( + // barcode: Barcode.code128(), + // data: "${context.read().userData['rollno']}", + // height: 150, + // color: kBlack, + // backgroundColor: kWhite, + // drawText: false, + // ), + // ), + // ), // ), - // ), + // ], + // ), + // // Padding( + // // padding: const EdgeInsets.only(top: 20), + // // child: Center( + // // child: Text( + // // "Library issuing barcode", + // // textAlign: TextAlign.center, + // // style: MyFonts.w500.setColor(kWhite).size(18), + // // ), + // // ), + // // ), + // Padding( + // padding: const EdgeInsets.all(20.0), + // child: ElevatedButton( + // onPressed: () { + // context.read().logOut(() => + // Navigator.of(context).pushNamedAndRemoveUntil( + // '/', (Route route) => false)); + // }, + // style: ElevatedButton.styleFrom( + // elevation: 0, primary: kAppBarGrey), + // child: Text( + // 'Log Out', + // style: MyFonts.w500.setColor(kBlue), + // )), // ), - Padding( - padding: const EdgeInsets.all(20.0), - child: ElevatedButton( - onPressed: () { - context.read().logOut(() => - Navigator.of(context).pushNamedAndRemoveUntil( - '/', (Route route) => false)); - }, - style: ElevatedButton.styleFrom( - elevation: 0, primary: kAppBarGrey), - child: Text( - 'Log Out', - style: MyFonts.w500.setColor(kBlue), - )), - ), - ], - ), - ), - ), + // ], + // ), + // ), + // ), ), ); } diff --git a/pubspec.yaml b/pubspec.yaml index 304d9fac..7af8d981 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -63,6 +63,9 @@ dependencies: path_provider: ^2.0.11 path: ^1.8.0 infinite_scroll_pagination: ^3.2.0 + firebase_messaging: ^13.0.4 + flutter_local_notifications: ^11.0.1 + firebase_core: ^1.24.0 dev_dependencies: flutter_test: From 204f880191bfa7e0e21b9675c02ba23cb5b45a48 Mon Sep 17 00:00:00 2001 From: babayaga2002 Date: Mon, 17 Oct 2022 10:46:32 +0530 Subject: [PATCH 02/82] Background notifications --- android/app/google-services.json | 39 +++++++ lib/services/notifications_provider.dart | 131 +++++++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 android/app/google-services.json create mode 100644 lib/services/notifications_provider.dart diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 00000000..ac08b5bb --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,39 @@ +{ + "project_info": { + "project_number": "320514948737", + "project_id": "onestop-5ce62", + "storage_bucket": "onestop-5ce62.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:320514948737:android:066c4a2cabdaedf1df5780", + "android_client_info": { + "package_name": "com.swciitg.onestop2" + } + }, + "oauth_client": [ + { + "client_id": "320514948737-nkd52j89olp45n773ookls9guji7fsj3.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyAYT3YqfDbfrY539YK9rzu-C4I4atXWsZ0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "320514948737-nkd52j89olp45n773ookls9guji7fsj3.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart new file mode 100644 index 00000000..ef27eb60 --- /dev/null +++ b/lib/services/notifications_provider.dart @@ -0,0 +1,131 @@ +import 'package:firebase_core/firebase_core.dart'; +import "package:firebase_messaging/firebase_messaging.dart"; +import "package:flutter_local_notifications/flutter_local_notifications.dart"; +import 'package:shared_preferences/shared_preferences.dart'; + +Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { + await Firebase.initializeApp(); + print('A bg message just showed up : ${message.messageId}'); + FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = + FlutterLocalNotificationsPlugin(); + const AndroidNotificationChannel channel = AndroidNotificationChannel( + 'high_importance_channel', // id + 'High Importance Notifications', // title + description: + 'This channel is used for important notifications.', // description + importance: Importance.high, + playSound: true); + await flutterLocalNotificationsPlugin + .resolvePlatformSpecificImplementation< + AndroidFlutterLocalNotificationsPlugin>() + ?.createNotificationChannel(channel); + AndroidNotificationDetails androidNotificationDetails = + AndroidNotificationDetails(channel.id, channel.name, + channelDescription: channel.description, + importance: Importance.high, + playSound: true, + icon: '@mipmap/ic_launcher'); + DarwinNotificationDetails iosNotificationDetails= DarwinNotificationDetails(presentAlert: true,presentBadge: true,presentSound: true); + NotificationDetails notificationDetails = + NotificationDetails(android: androidNotificationDetails,iOS: iosNotificationDetails); + RemoteNotification? notification = message.notification; + await flutterLocalNotificationsPlugin.show(notification.hashCode, + "sid", notification!.body,notificationDetails); + savenotif(notification); +} + +void onDidReceiveNotificationResponse( + NotificationResponse notificationResponse) async { + final String? payload = notificationResponse.payload; + if (notificationResponse.payload != null) { + print('notification payload: $payload'); + } + // await Navigator.pushNamed(context, HomePage.id); +} + +Future checkForNotifications() async { + FirebaseMessaging messaging = FirebaseMessaging.instance; + SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); + String? token = sharedPreferences.getString("fcm-token"); + if (token == null) { + token = await messaging.getToken(); + sharedPreferences.setString("fcm-token", token!); + } + FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = + FlutterLocalNotificationsPlugin(); + flutterLocalNotificationsPlugin + .resolvePlatformSpecificImplementation< + AndroidFlutterLocalNotificationsPlugin>()! + .requestPermission(); + + const AndroidNotificationChannel channel = AndroidNotificationChannel( + 'high_importance_channel', // id + 'High Importance Notifications', // title + description: + 'This channel is used for important notifications.', // description + importance: Importance.high, + playSound: true); + await flutterLocalNotificationsPlugin + .resolvePlatformSpecificImplementation< + AndroidFlutterLocalNotificationsPlugin>() + ?.createNotificationChannel(channel); + const AndroidInitializationSettings initializationSettingsAndroid = + AndroidInitializationSettings('@mipmap/ic_launcher'); + final DarwinInitializationSettings initializationSettingsDarwin = + DarwinInitializationSettings( + requestSoundPermission: true, + requestBadgePermission: true, + requestAlertPermission: true, + ); + final InitializationSettings initializationSettings = InitializationSettings( + android: initializationSettingsAndroid, + iOS: initializationSettingsDarwin, + ); + await flutterLocalNotificationsPlugin.initialize(initializationSettings, + onDidReceiveNotificationResponse: onDidReceiveNotificationResponse, + onDidReceiveBackgroundNotificationResponse: + onDidReceiveNotificationResponse); + AndroidNotificationDetails androidNotificationDetails = + AndroidNotificationDetails(channel.id, channel.name, + channelDescription: channel.description, + importance: Importance.high, + playSound: true, + icon: '@mipmap/ic_launcher'); + DarwinNotificationDetails iosNotificationDetails= DarwinNotificationDetails(presentAlert: true,presentBadge: true,presentSound: true); + NotificationDetails notificationDetails = + NotificationDetails(android: androidNotificationDetails,iOS: iosNotificationDetails); + + // FOR IOS + // await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( + // alert: true, + // badge: true, + // sound: true, + // ); + FirebaseMessaging.onMessage.listen((RemoteMessage message) async { + RemoteNotification? notification = message.notification; + print("NOTIFICation : $notification"); + // AndroidNotification android = message.notification!.android!; + if (notification != null) { + await flutterLocalNotificationsPlugin.show(notification.hashCode, + "sid", notification.body, notificationDetails); + } + // savenotif(notification); + }); + return true; +} + +void savenotif(RemoteNotification notification) async { + final SharedPreferences preferences = await SharedPreferences.getInstance(); + String notif = notification.hashCode.toString() + + notification.title! + + notification.body!; + List? notifications = + preferences.getStringList('notifications') == null + ? [] + : preferences.getStringList('notifications'); + if (notifications!.length > 14) { + notifications.removeAt(0); + } + notifications.add(notif); + preferences.setStringList('notifications', notifications); +} From 42603987f7b5226d51c1fe17f8bdf18e16b75049 Mon Sep 17 00:00:00 2001 From: babayaga2002 Date: Mon, 17 Oct 2022 12:41:39 +0530 Subject: [PATCH 03/82] Notifications Settings --- lib/models/buy_sell/sell_model.g.dart | 44 +++--- lib/pages/Notifications/notifications.dart | 142 ++++++++++++++++++ lib/pages/Notifications/settings.dart | 84 +++++++++++ lib/pages/barcode.dart | 161 ++++++++++----------- lib/routes.dart | 4 + lib/services/notifications_provider.dart | 42 +++--- lib/widgets/ui/appbar.dart | 19 ++- pubspec.yaml | 2 + 8 files changed, 364 insertions(+), 134 deletions(-) create mode 100644 lib/pages/Notifications/notifications.dart create mode 100644 lib/pages/Notifications/settings.dart diff --git a/lib/models/buy_sell/sell_model.g.dart b/lib/models/buy_sell/sell_model.g.dart index fe26befe..6898ca18 100644 --- a/lib/models/buy_sell/sell_model.g.dart +++ b/lib/models/buy_sell/sell_model.g.dart @@ -7,27 +7,27 @@ part of 'sell_model.dart'; // ************************************************************************** SellModel _$SellModelFromJson(Map json) => SellModel( - title: json['title'] as String, - description: json['description'] as String, - imageURL: json['imageURL'] as String, - compressedImageURL: json['compressedImageURL'] as String, - date: DateTime.parse(json['date'] as String), - phonenumber: json['phonenumber'] as String, - price: json['price'] as String, - email: json['email'] as String, - id: json['_id'] as String, - username: json['username'] as String, -); + title: json['title'] as String, + description: json['description'] as String, + imageURL: json['imageURL'] as String, + compressedImageURL: json['compressedImageURL'] as String, + date: DateTime.parse(json['date'] as String), + phonenumber: json['phonenumber'] as String, + price: json['price'] as String, + email: json['email'] as String, + id: json['_id'] as String, + username: json['username'] as String, + ); Map _$SellModelToJson(SellModel instance) => { - 'title': instance.title, - 'description': instance.description, - 'imageURL': instance.imageURL, - 'compressedImageURL': instance.compressedImageURL, - 'phonenumber': instance.phonenumber, - 'price': instance.price, - 'date': instance.date.toIso8601String(), - 'username': instance.username, - 'email': instance.email, - '_id': instance.id, -}; + 'title': instance.title, + 'description': instance.description, + 'imageURL': instance.imageURL, + 'compressedImageURL': instance.compressedImageURL, + 'phonenumber': instance.phonenumber, + 'price': instance.price, + 'date': instance.date.toIso8601String(), + 'username': instance.username, + 'email': instance.email, + '_id': instance.id, + }; diff --git a/lib/pages/Notifications/notifications.dart b/lib/pages/Notifications/notifications.dart new file mode 100644 index 00000000..41f8a35e --- /dev/null +++ b/lib/pages/Notifications/notifications.dart @@ -0,0 +1,142 @@ +import 'package:flutter/material.dart'; +import 'package:onestop_dev/globals/my_colors.dart'; +import 'package:onestop_dev/globals/my_fonts.dart'; +import 'package:onestop_dev/pages/Notifications/settings.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:shimmer/shimmer.dart'; + +class NotifsModel { + String? hashcode; + String? title; + String? body; + + NotifsModel( + this.hashcode, + this.title, + this.body, + ); +} + +class Notif extends StatefulWidget { + static String id = "notifications"; + const Notif({Key? key}) : super(key: key); + + @override + State createState() => _NotifState(); +} + +class _NotifState extends State { + Widget _getLoadingIndicator() { + return Expanded( + child: Shimmer.fromColors( + period: const Duration(seconds: 1), + baseColor: kHomeTile, + highlightColor: lGrey, + child: SizedBox( + height: 400, + child: ListView.builder( + itemCount: 8, + itemBuilder: (_, __) => Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Column( + children: [ + Container( + height: 180, + decoration: BoxDecoration( + color: kBlack, + borderRadius: BorderRadius.circular(5)), + ), + // Divider( + // thickness: 1.5, + // color: kTabBar, + // ), + const SizedBox( + height: 8, + ), + ], + ), + ), + ), + )), + ); + } + + Future> getDetails() async { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + List result = prefs.getStringList('notifications')!; + return result; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: kAppBarGrey, + leading: IconButton( + onPressed: () { + Navigator.of(context).pop(); + }, + icon: const Icon(Icons.arrow_back)), + leadingWidth: 30, + title: Text( + 'Notifications', + style: MyFonts.w500, + ), + actions: [ + IconButton(onPressed: () { + Navigator.pushNamed(context, NotifSettings.id); + }, icon: const Icon(Icons.settings)), + ], + ), + body: FutureBuilder>( + future: getDetails(), + builder: (context, snapshot) { + if (snapshot.hasData && snapshot.data!.length > 0) { + return ListView.builder( + itemCount: snapshot.data!.length, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.all(20.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Icon(Icons.square,color: kBlue,), + SizedBox(width: 10,), + Text( + snapshot.data![index], + style: const TextStyle( + fontFamily: 'Montserrat', + fontSize: 18, + fontWeight: FontWeight.w700, + color: kWhite, + letterSpacing: 0.1, + height: 1.5, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ); + },); + } + return ListView.builder( + itemCount: 3, + itemBuilder: (BuildContext buildContext, int index) { + return Container( + padding: const EdgeInsets.fromLTRB(0, 5, 0, 16), + color: Colors.black.withOpacity(0.8), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + _getLoadingIndicator(), + ], + ), + ); + }, + ); + }), + ); + } +} diff --git a/lib/pages/Notifications/settings.dart b/lib/pages/Notifications/settings.dart new file mode 100644 index 00000000..d6651d03 --- /dev/null +++ b/lib/pages/Notifications/settings.dart @@ -0,0 +1,84 @@ +import 'package:flutter/material.dart'; +import 'package:onestop_dev/globals/my_colors.dart'; +import 'package:onestop_dev/globals/my_fonts.dart'; +import 'package:flutter_switch/flutter_switch.dart'; + +class NotifSettings extends StatefulWidget { + static String id = "notifications-settings"; + const NotifSettings({Key? key}) : super(key: key); + + @override + State createState() => _NotifSettingsState(); +} + +List Titles = [ + "Food", + "Lost and Food", + "TimeTable", + "Assignment", + "Ferry", + "Buses" +]; + +class _NotifSettingsState extends State { + List value = List.filled(Titles.length, false); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: kAppBarGrey, + leading: Container(), + leadingWidth: 10, + title: Text( + 'Settings', + style: MyFonts.w500, + ), + actions: [ + IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: const Icon(Icons.close), + ), + ], + ), + body: ListView.builder( + itemCount: Titles.length, + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: const EdgeInsets.all(20.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + Titles[index], + style: const TextStyle( + fontFamily: 'Montserrat', + fontSize: 18, + fontWeight: FontWeight.w700, + color: kWhite, + letterSpacing: 0.1, + height: 1.5, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + FlutterSwitch( + width: 40.0, + height: 25.0, + toggleSize: 18.0, + value: value[index], + onToggle: (val) { + setState(() { + value[index] = val; + }); + }, + ), + ], + ), + ); + }, + ), + ); + } +} diff --git a/lib/pages/barcode.dart b/lib/pages/barcode.dart index d05d25ca..082d9ae7 100644 --- a/lib/pages/barcode.dart +++ b/lib/pages/barcode.dart @@ -22,97 +22,88 @@ class _QRPageState extends State { @override Widget build(BuildContext context) { SizeConfig().init(context); - return Scaffold( appBar: appBar(context, displayIcon: false), body: SafeArea( child: - // SingleChildScrollView( - // child: Padding( - // padding: const EdgeInsets.symmetric(horizontal: 16), - // child: - // Column( - // mainAxisAlignment: MainAxisAlignment.center, - // crossAxisAlignment: CrossAxisAlignment.center, - // children: [ - FutureBuilder(future: SharedPreferences.getInstance(), builder: (context,snapshot) { - if(snapshot.hasData){ - return ListView.builder(itemCount: snapshot.data!.getStringList('notifications')!.length, itemBuilder: (context, index){ - return Text(snapshot.data!.getStringList('notifications')![index],style: TextStyle(color: Colors.white),); - }); - } - return CircularProgressIndicator(); - }), - // const SizedBox( - // height: 16, - // ), - // Text( - // "${context.read().userData['name']}", - // textAlign: TextAlign.center, - // style: MyFonts.w800.setColor(kWhite).size(20), - // ), - // Text( - // '${context.read().userData['rollno']}', - // textAlign: TextAlign.center, - // style: MyFonts.w500.setColor(kWhite).size(20), - // ), - // const SizedBox( - // height: 26, - // ), - // Stack( - // children: [ - // Container( - // height: 300, - // width: double.infinity, - // color: kWhite, - // ), - // Positioned.fill( - // child: Align( - // alignment: Alignment.center, - // child: Padding( - // padding: const EdgeInsets.symmetric(horizontal: 16), - // child: BarcodeWidget( - // barcode: Barcode.code128(), - // data: "${context.read().userData['rollno']}", - // height: 150, - // color: kBlack, - // backgroundColor: kWhite, - // drawText: false, - // ), - // ), - // ), - // ), - // ], - // ), - // // Padding( - // // padding: const EdgeInsets.only(top: 20), - // // child: Center( - // // child: Text( - // // "Library issuing barcode", - // // textAlign: TextAlign.center, - // // style: MyFonts.w500.setColor(kWhite).size(18), - // // ), - // // ), - // // ), + SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox( + height: 16, + ), + Text( + "${context.read().userData['name']}", + textAlign: TextAlign.center, + style: MyFonts.w800.setColor(kWhite).size(20), + ), + Text( + '${context.read().userData['rollno']}', + textAlign: TextAlign.center, + style: MyFonts.w500.setColor(kWhite).size(20), + ), + const SizedBox( + height: 26, + ), + Stack( + children: [ + Container( + height: 300, + width: double.infinity, + color: kWhite, + ), + Positioned.fill( + child: Align( + alignment: Alignment.center, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: BarcodeWidget( + barcode: Barcode.code128(), + data: "${context.read().userData['rollno']}", + height: 150, + color: kBlack, + backgroundColor: kWhite, + drawText: false, + ), + ), + ), + ), + ], + ), // Padding( - // padding: const EdgeInsets.all(20.0), - // child: ElevatedButton( - // onPressed: () { - // context.read().logOut(() => - // Navigator.of(context).pushNamedAndRemoveUntil( - // '/', (Route route) => false)); - // }, - // style: ElevatedButton.styleFrom( - // elevation: 0, primary: kAppBarGrey), - // child: Text( - // 'Log Out', - // style: MyFonts.w500.setColor(kBlue), - // )), + // padding: const EdgeInsets.only(top: 20), + // child: Center( + // child: Text( + // "Library issuing barcode", + // textAlign: TextAlign.center, + // style: MyFonts.w500.setColor(kWhite).size(18), + // ), + // ), // ), - // ], - // ), - // ), - // ), + Padding( + padding: const EdgeInsets.all(20.0), + child: ElevatedButton( + onPressed: () { + context.read().logOut(() => + Navigator.of(context).pushNamedAndRemoveUntil( + '/', (Route route) => false)); + }, + style: ElevatedButton.styleFrom( + elevation: 0, primary: kAppBarGrey), + child: Text( + 'Log Out', + style: MyFonts.w500.setColor(kBlue), + )), + ), + ], + ), + ), + ), ), ); } diff --git a/lib/routes.dart b/lib/routes.dart index 58bc6fda..23940d3a 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -1,3 +1,5 @@ +import 'package:onestop_dev/pages/Notifications/notifications.dart'; +import 'package:onestop_dev/pages/Notifications/settings.dart'; import 'package:onestop_dev/pages/quick_links/academic_calendar.dart'; import 'package:onestop_dev/pages/quick_links/academic_sso.dart'; import 'package:onestop_dev/pages/quick_links/blogs_page.dart'; @@ -26,4 +28,6 @@ final routes = { AcademicSSO.id: (context) => const AcademicSSO(), AcademicCalendar.id: (context) => const AcademicCalendar(), Complaints.id: (context) => const Complaints(), + Notif.id: (context) => const Notif(), + NotifSettings.id:(context) => const NotifSettings(), }; diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart index ef27eb60..2a3b34b5 100644 --- a/lib/services/notifications_provider.dart +++ b/lib/services/notifications_provider.dart @@ -7,30 +7,31 @@ Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { await Firebase.initializeApp(); print('A bg message just showed up : ${message.messageId}'); FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = - FlutterLocalNotificationsPlugin(); + FlutterLocalNotificationsPlugin(); const AndroidNotificationChannel channel = AndroidNotificationChannel( 'high_importance_channel', // id 'High Importance Notifications', // title description: - 'This channel is used for important notifications.', // description + 'This channel is used for important notifications.', // description importance: Importance.high, playSound: true); await flutterLocalNotificationsPlugin .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>() + AndroidFlutterLocalNotificationsPlugin>() ?.createNotificationChannel(channel); AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails(channel.id, channel.name, - channelDescription: channel.description, - importance: Importance.high, - playSound: true, - icon: '@mipmap/ic_launcher'); - DarwinNotificationDetails iosNotificationDetails= DarwinNotificationDetails(presentAlert: true,presentBadge: true,presentSound: true); - NotificationDetails notificationDetails = - NotificationDetails(android: androidNotificationDetails,iOS: iosNotificationDetails); + AndroidNotificationDetails(channel.id, channel.name, + channelDescription: channel.description, + importance: Importance.high, + playSound: true, + icon: '@mipmap/ic_launcher'); + DarwinNotificationDetails iosNotificationDetails = DarwinNotificationDetails( + presentAlert: true, presentBadge: true, presentSound: true); + NotificationDetails notificationDetails = NotificationDetails( + android: androidNotificationDetails, iOS: iosNotificationDetails); RemoteNotification? notification = message.notification; - await flutterLocalNotificationsPlugin.show(notification.hashCode, - "sid", notification!.body,notificationDetails); + await flutterLocalNotificationsPlugin.show( + notification.hashCode, "sid", notification!.body, notificationDetails); savenotif(notification); } @@ -91,9 +92,10 @@ Future checkForNotifications() async { importance: Importance.high, playSound: true, icon: '@mipmap/ic_launcher'); - DarwinNotificationDetails iosNotificationDetails= DarwinNotificationDetails(presentAlert: true,presentBadge: true,presentSound: true); - NotificationDetails notificationDetails = - NotificationDetails(android: androidNotificationDetails,iOS: iosNotificationDetails); + DarwinNotificationDetails iosNotificationDetails = DarwinNotificationDetails( + presentAlert: true, presentBadge: true, presentSound: true); + NotificationDetails notificationDetails = NotificationDetails( + android: androidNotificationDetails, iOS: iosNotificationDetails); // FOR IOS // await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( @@ -106,10 +108,10 @@ Future checkForNotifications() async { print("NOTIFICation : $notification"); // AndroidNotification android = message.notification!.android!; if (notification != null) { - await flutterLocalNotificationsPlugin.show(notification.hashCode, - "sid", notification.body, notificationDetails); + await flutterLocalNotificationsPlugin.show( + notification.hashCode, "sid", notification.body, notificationDetails); } - // savenotif(notification); + savenotif(notification!); }); return true; } @@ -117,7 +119,9 @@ Future checkForNotifications() async { void savenotif(RemoteNotification notification) async { final SharedPreferences preferences = await SharedPreferences.getInstance(); String notif = notification.hashCode.toString() + + '-' + notification.title! + + '-' + notification.body!; List? notifications = preferences.getStringList('notifications') == null diff --git a/lib/widgets/ui/appbar.dart b/lib/widgets/ui/appbar.dart index e6b9acb0..89853df4 100644 --- a/lib/widgets/ui/appbar.dart +++ b/lib/widgets/ui/appbar.dart @@ -2,6 +2,7 @@ import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; +import 'package:onestop_dev/pages/Notifications/notifications.dart'; import 'package:onestop_dev/pages/barcode.dart'; AppBar appBar(BuildContext context, {bool displayIcon = true}) { @@ -70,14 +71,16 @@ AppBar appBar(BuildContext context, {bool displayIcon = true}) { const SizedBox( width: 35, height: 35, - ) - // CircleAvatar( - // backgroundColor: kAppBarGrey, - // child: IconButton( - // onPressed: () {}, - // icon: Icon(Icons.notifications), - // color: lBlue2, - // )), + ), + CircleAvatar( + backgroundColor: kAppBarGrey, + child: IconButton( + onPressed: () { + Navigator.pushNamed(context, Notif.id); + }, + icon: Icon(Icons.notifications), + color: lBlue2, + )), ], ), elevation: 0.0, diff --git a/pubspec.yaml b/pubspec.yaml index 7af8d981..5129a9e7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -66,6 +66,7 @@ dependencies: firebase_messaging: ^13.0.4 flutter_local_notifications: ^11.0.1 firebase_core: ^1.24.0 + flutter_switch: ^0.3.2 dev_dependencies: flutter_test: @@ -79,6 +80,7 @@ dev_dependencies: dependency_validator: ^3.2.2 change_app_package_name: ^1.1.0 + flutter_icons: android: true ios: true From 248855e6a3f1d834a34d8e4a225d717891e6afe0 Mon Sep 17 00:00:00 2001 From: babayaga2002 Date: Tue, 18 Oct 2022 11:18:37 +0530 Subject: [PATCH 04/82] Notifications Settings Next --- lib/pages/Notifications/notifications.dart | 129 +++++++++++++-------- lib/pages/Notifications/settings.dart | 15 ++- lib/services/notifications_provider.dart | 44 +++++-- 3 files changed, 122 insertions(+), 66 deletions(-) diff --git a/lib/pages/Notifications/notifications.dart b/lib/pages/Notifications/notifications.dart index 41f8a35e..0bd17971 100644 --- a/lib/pages/Notifications/notifications.dart +++ b/lib/pages/Notifications/notifications.dart @@ -9,11 +9,13 @@ class NotifsModel { String? hashcode; String? title; String? body; + String? type; NotifsModel( this.hashcode, this.title, this.body, + this.type, ); } @@ -33,15 +35,16 @@ class _NotifState extends State { baseColor: kHomeTile, highlightColor: lGrey, child: SizedBox( - height: 400, + height: 200, child: ListView.builder( itemCount: 8, itemBuilder: (_, __) => Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), + padding: + const EdgeInsets.symmetric(horizontal: 10.0, vertical: 2), child: Column( children: [ Container( - height: 180, + height: 80, decoration: BoxDecoration( color: kBlack, borderRadius: BorderRadius.circular(5)), @@ -60,11 +63,32 @@ class _NotifState extends State { )), ); } - - Future> getDetails() async { + List n = []; + Future> getDetails() async { + n.clear(); final SharedPreferences prefs = await SharedPreferences.getInstance(); List result = prefs.getStringList('notifications')!; - return result; + for (String r in result) { + var parts = r.split(" "); + NotifsModel not = new NotifsModel("", "", "",""); + if (parts.length >= 1) not.hashcode = parts[0]; + if (parts.length >= 2) not.title = parts[1]; + if (parts.length >= 3) not.body = parts[2]; + if (parts.length >= 4) not.type = parts[3]; + n.add(not); + } + return n; + } + IconData getIcon(String? type){ + if(type==null) return Icons.circle; + else if(type=="Food" || type=="Lost and Found" || type=="TimeTable") return Icons.square; + else return Icons.eject; + } + + @override + void initState() { + getDetails(); + super.initState(); } @override @@ -83,58 +107,61 @@ class _NotifState extends State { style: MyFonts.w500, ), actions: [ - IconButton(onPressed: () { - Navigator.pushNamed(context, NotifSettings.id); - }, icon: const Icon(Icons.settings)), + IconButton( + onPressed: () { + Navigator.pushNamed(context, NotifSettings.id); + }, + icon: const Icon(Icons.settings)), ], ), - body: FutureBuilder>( + body: FutureBuilder>( future: getDetails(), builder: (context, snapshot) { - if (snapshot.hasData && snapshot.data!.length > 0) { + if (snapshot.hasData) { return ListView.builder( - itemCount: snapshot.data!.length, - itemBuilder: (context, index) { - return Padding( - padding: const EdgeInsets.all(20.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Icon(Icons.square,color: kBlue,), - SizedBox(width: 10,), - Text( - snapshot.data![index], - style: const TextStyle( - fontFamily: 'Montserrat', - fontSize: 18, - fontWeight: FontWeight.w700, - color: kWhite, - letterSpacing: 0.1, - height: 1.5, - ), - maxLines: 1, - overflow: TextOverflow.ellipsis, + itemCount: snapshot.data!.length, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.all(20.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Icon( + getIcon(snapshot.data![index].type), + color: kBlue, + ), + SizedBox( + width: 10, + ), + Text( + snapshot.data![index].title!, + style: const TextStyle( + fontFamily: 'Montserrat', + fontSize: 18, + fontWeight: FontWeight.w700, + color: kWhite, + letterSpacing: 0.1, + height: 1.5, ), - ], - ), - ); - },); + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ); + }, + ); } - return ListView.builder( - itemCount: 3, - itemBuilder: (BuildContext buildContext, int index) { - return Container( - padding: const EdgeInsets.fromLTRB(0, 5, 0, 16), - color: Colors.black.withOpacity(0.8), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - _getLoadingIndicator(), - ], - ), - ); - }, + return Container( + padding: const EdgeInsets.fromLTRB(0, 20, 0, 20), + color: Colors.black.withOpacity(0.8), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + _getLoadingIndicator(), + ], + ), ); }), ); diff --git a/lib/pages/Notifications/settings.dart b/lib/pages/Notifications/settings.dart index d6651d03..7f9d3eca 100644 --- a/lib/pages/Notifications/settings.dart +++ b/lib/pages/Notifications/settings.dart @@ -13,7 +13,7 @@ class NotifSettings extends StatefulWidget { List Titles = [ "Food", - "Lost and Food", + "Lost and Found", "TimeTable", "Assignment", "Ferry", @@ -21,7 +21,14 @@ List Titles = [ ]; class _NotifSettingsState extends State { - List value = List.filled(Titles.length, false); + Map value={ + "Food" : false, + "Lost and Food":false, + "TimeTable":false, + "Assignment":false, + "Ferry":false, + "Buses":false + }; @override Widget build(BuildContext context) { return Scaffold( @@ -67,10 +74,10 @@ class _NotifSettingsState extends State { width: 40.0, height: 25.0, toggleSize: 18.0, - value: value[index], + value: value[Titles[index]]!, onToggle: (val) { setState(() { - value[index] = val; + value[Titles[index]] = val; }); }, ), diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart index 2a3b34b5..a9d4ad4a 100644 --- a/lib/services/notifications_provider.dart +++ b/lib/services/notifications_provider.dart @@ -30,9 +30,13 @@ Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { NotificationDetails notificationDetails = NotificationDetails( android: androidNotificationDetails, iOS: iosNotificationDetails); RemoteNotification? notification = message.notification; - await flutterLocalNotificationsPlugin.show( - notification.hashCode, "sid", notification!.body, notificationDetails); - savenotif(notification); + String type = message.data['type']; + print("NOTIFICation : $notification"); + if (notification != null && checkIfUserWantsNotification(type)) { + await flutterLocalNotificationsPlugin.show( + notification.hashCode, notification.title, notification.body, notificationDetails); + } + savenotif(notification!,type); } void onDidReceiveNotificationResponse( @@ -43,7 +47,24 @@ void onDidReceiveNotificationResponse( } // await Navigator.pushNamed(context, HomePage.id); } - +Map value={ + "Food" : false, + "Lost and Food":false, + "TimeTable":false, + "Assignment":false, + "Ferry":false, + "Buses":false +}; +bool checkIfUserWantsNotification(String type){ + if(type=="Food") return value["Food"]!; + if(type=="Lost and Found") return value["Lost and Found"]!; + if(type=="TimeTable") return value["TimeTable"]!; + if(type=="Assignment") return value["Assignment"]!; + if(type=="Ferry") return value["Ferry"]!; + if(type=="Buses") return value["Buses"]!; + if(type=="all") return true; + return false; +} Future checkForNotifications() async { FirebaseMessaging messaging = FirebaseMessaging.instance; SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); @@ -105,24 +126,25 @@ Future checkForNotifications() async { // ); FirebaseMessaging.onMessage.listen((RemoteMessage message) async { RemoteNotification? notification = message.notification; + String type = message.data['type']; print("NOTIFICation : $notification"); // AndroidNotification android = message.notification!.android!; - if (notification != null) { + if (notification != null && checkIfUserWantsNotification(type)) { await flutterLocalNotificationsPlugin.show( - notification.hashCode, "sid", notification.body, notificationDetails); + notification.hashCode, notification.title, notification.body, notificationDetails); } - savenotif(notification!); + savenotif(notification!,type); }); return true; } -void savenotif(RemoteNotification notification) async { +void savenotif(RemoteNotification notification, String type) async { final SharedPreferences preferences = await SharedPreferences.getInstance(); String notif = notification.hashCode.toString() + - '-' + + ' ' + notification.title! + - '-' + - notification.body!; + ' ' + + notification.body!+' '+type; List? notifications = preferences.getStringList('notifications') == null ? [] From e6fcd00a1637baf35eafb57e4d9f0892ca0cb3d8 Mon Sep 17 00:00:00 2001 From: sidharthchoudhary Date: Wed, 7 Dec 2022 09:23:32 +0530 Subject: [PATCH 05/82] Notifications Settings Removed --- lib/pages/Notifications/notifications.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/pages/Notifications/notifications.dart b/lib/pages/Notifications/notifications.dart index 0bd17971..ff4ea834 100644 --- a/lib/pages/Notifications/notifications.dart +++ b/lib/pages/Notifications/notifications.dart @@ -107,11 +107,11 @@ class _NotifState extends State { style: MyFonts.w500, ), actions: [ - IconButton( - onPressed: () { - Navigator.pushNamed(context, NotifSettings.id); - }, - icon: const Icon(Icons.settings)), + // IconButton( + // onPressed: () { + // Navigator.pushNamed(context, NotifSettings.id); + // }, + // icon: const Icon(Icons.settings)), ], ), body: FutureBuilder>( From 83311a89394458288fb56115e41cca45749a1d6b Mon Sep 17 00:00:00 2001 From: Vignesh Rao Date: Wed, 7 Dec 2022 11:56:09 +0530 Subject: [PATCH 06/82] Merge with main --- lib/services/notifications_provider.dart | 59 +++++++++++++----------- pubspec.yaml | 4 +- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart index a9d4ad4a..9100f64f 100644 --- a/lib/services/notifications_provider.dart +++ b/lib/services/notifications_provider.dart @@ -33,12 +33,13 @@ Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { String type = message.data['type']; print("NOTIFICation : $notification"); if (notification != null && checkIfUserWantsNotification(type)) { - await flutterLocalNotificationsPlugin.show( - notification.hashCode, notification.title, notification.body, notificationDetails); + await flutterLocalNotificationsPlugin.show(notification.hashCode, + notification.title, notification.body, notificationDetails); } - savenotif(notification!,type); + savenotif(notification!, type); } +@pragma('vm:entry-point') void onDidReceiveNotificationResponse( NotificationResponse notificationResponse) async { final String? payload = notificationResponse.payload; @@ -47,24 +48,26 @@ void onDidReceiveNotificationResponse( } // await Navigator.pushNamed(context, HomePage.id); } -Map value={ - "Food" : false, - "Lost and Food":false, - "TimeTable":false, - "Assignment":false, - "Ferry":false, - "Buses":false + +Map value = { + "Food": false, + "Lost and Food": false, + "TimeTable": false, + "Assignment": false, + "Ferry": false, + "Buses": false }; -bool checkIfUserWantsNotification(String type){ - if(type=="Food") return value["Food"]!; - if(type=="Lost and Found") return value["Lost and Found"]!; - if(type=="TimeTable") return value["TimeTable"]!; - if(type=="Assignment") return value["Assignment"]!; - if(type=="Ferry") return value["Ferry"]!; - if(type=="Buses") return value["Buses"]!; - if(type=="all") return true; +bool checkIfUserWantsNotification(String type) { + if (type == "Food") return value["Food"]!; + if (type == "Lost and Found") return value["Lost and Found"]!; + if (type == "TimeTable") return value["TimeTable"]!; + if (type == "Assignment") return value["Assignment"]!; + if (type == "Ferry") return value["Ferry"]!; + if (type == "Buses") return value["Buses"]!; + if (type == "all") return true; return false; } + Future checkForNotifications() async { FirebaseMessaging messaging = FirebaseMessaging.instance; SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); @@ -103,10 +106,12 @@ Future checkForNotifications() async { android: initializationSettingsAndroid, iOS: initializationSettingsDarwin, ); - await flutterLocalNotificationsPlugin.initialize(initializationSettings, - onDidReceiveNotificationResponse: onDidReceiveNotificationResponse, - onDidReceiveBackgroundNotificationResponse: - onDidReceiveNotificationResponse); + await flutterLocalNotificationsPlugin.initialize( + initializationSettings, + // onDidReceiveNotificationResponse: onDidReceiveNotificationResponse, + // onDidReceiveBackgroundNotificationResponse: + // onDidReceiveNotificationResponse, + ); AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails(channel.id, channel.name, channelDescription: channel.description, @@ -130,10 +135,10 @@ Future checkForNotifications() async { print("NOTIFICation : $notification"); // AndroidNotification android = message.notification!.android!; if (notification != null && checkIfUserWantsNotification(type)) { - await flutterLocalNotificationsPlugin.show( - notification.hashCode, notification.title, notification.body, notificationDetails); + await flutterLocalNotificationsPlugin.show(notification.hashCode, + notification.title, notification.body, notificationDetails); } - savenotif(notification!,type); + savenotif(notification!, type); }); return true; } @@ -144,7 +149,9 @@ void savenotif(RemoteNotification notification, String type) async { ' ' + notification.title! + ' ' + - notification.body!+' '+type; + notification.body! + + ' ' + + type; List? notifications = preferences.getStringList('notifications') == null ? [] diff --git a/pubspec.yaml b/pubspec.yaml index bd4d58d4..057b07d5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -60,9 +60,9 @@ dependencies: path_provider: ^2.0.11 path: ^1.8.0 infinite_scroll_pagination: ^3.2.0 - firebase_messaging: ^13.0.4 + firebase_messaging: ^14.1.3 flutter_local_notifications: ^11.0.1 - firebase_core: ^1.24.0 + firebase_core: ^2.3.0 flutter_switch: ^0.3.2 dev_dependencies: From 71ca654b5292321151de5bc466d91970e1a39329 Mon Sep 17 00:00:00 2001 From: Vignesh Rao Date: Wed, 7 Dec 2022 21:02:22 +0530 Subject: [PATCH 07/82] Remove notification settings --- android/app/build.gradle | 3 - ios/Runner/AppDelegate.swift | 2 +- lib/main.dart | 2 + lib/pages/Notifications/settings.dart | 91 ------------------- .../notifications.dart | 8 -- lib/routes.dart | 4 +- lib/widgets/ui/appbar.dart | 2 +- pubspec.yaml | 1 - 8 files changed, 5 insertions(+), 108 deletions(-) delete mode 100644 lib/pages/Notifications/settings.dart rename lib/pages/{Notifications => notifications}/notifications.dart (94%) diff --git a/android/app/build.gradle b/android/app/build.gradle index cfaa7a92..7cbf5298 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -92,9 +92,6 @@ flutter { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - implementation "com.google.firebase:firebase-inappmessaging-display:19.1.5" - implementation platform('com.google.firebase:firebase-bom:31.0.0') - implementation 'com.google.firebase:firebase-analytics' implementation "com.android.support:multidex:1.0.3" } diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 49f0aa96..16614976 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -21,7 +21,7 @@ import GoogleMaps let values = decoded.components(separatedBy: "=") dartDefinesDictionary[values[0]] = values[1] } - GMSServices.provideAPIKey(Bundle.main.object(forInfoDictionaryKey: "GMAP_API_KEY") as? String ?? "") + GMSServices.provideAPIKey(dartDefinesDictionary["GMAP_KEY"] as? String ?? "") GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } diff --git a/lib/main.dart b/lib/main.dart index 5574a315..76673561 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -22,6 +22,8 @@ void main() async { overlays: [SystemUiOverlay.bottom, SystemUiOverlay.top]); await checkLastUpdated(); await checkForNotifications(); + final fcmToken = await FirebaseMessaging.instance.getToken(); + print("FCM TOken is $fcmToken"); FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); runApp(const MyApp()); } diff --git a/lib/pages/Notifications/settings.dart b/lib/pages/Notifications/settings.dart deleted file mode 100644 index 7f9d3eca..00000000 --- a/lib/pages/Notifications/settings.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:onestop_dev/globals/my_colors.dart'; -import 'package:onestop_dev/globals/my_fonts.dart'; -import 'package:flutter_switch/flutter_switch.dart'; - -class NotifSettings extends StatefulWidget { - static String id = "notifications-settings"; - const NotifSettings({Key? key}) : super(key: key); - - @override - State createState() => _NotifSettingsState(); -} - -List Titles = [ - "Food", - "Lost and Found", - "TimeTable", - "Assignment", - "Ferry", - "Buses" -]; - -class _NotifSettingsState extends State { - Map value={ - "Food" : false, - "Lost and Food":false, - "TimeTable":false, - "Assignment":false, - "Ferry":false, - "Buses":false - }; - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - backgroundColor: kAppBarGrey, - leading: Container(), - leadingWidth: 10, - title: Text( - 'Settings', - style: MyFonts.w500, - ), - actions: [ - IconButton( - onPressed: () { - Navigator.pop(context); - }, - icon: const Icon(Icons.close), - ), - ], - ), - body: ListView.builder( - itemCount: Titles.length, - itemBuilder: (BuildContext context, int index) { - return Padding( - padding: const EdgeInsets.all(20.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - Titles[index], - style: const TextStyle( - fontFamily: 'Montserrat', - fontSize: 18, - fontWeight: FontWeight.w700, - color: kWhite, - letterSpacing: 0.1, - height: 1.5, - ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - FlutterSwitch( - width: 40.0, - height: 25.0, - toggleSize: 18.0, - value: value[Titles[index]]!, - onToggle: (val) { - setState(() { - value[Titles[index]] = val; - }); - }, - ), - ], - ), - ); - }, - ), - ); - } -} diff --git a/lib/pages/Notifications/notifications.dart b/lib/pages/notifications/notifications.dart similarity index 94% rename from lib/pages/Notifications/notifications.dart rename to lib/pages/notifications/notifications.dart index ff4ea834..90afa001 100644 --- a/lib/pages/Notifications/notifications.dart +++ b/lib/pages/notifications/notifications.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; -import 'package:onestop_dev/pages/Notifications/settings.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:shimmer/shimmer.dart'; @@ -106,13 +105,6 @@ class _NotifState extends State { 'Notifications', style: MyFonts.w500, ), - actions: [ - // IconButton( - // onPressed: () { - // Navigator.pushNamed(context, NotifSettings.id); - // }, - // icon: const Icon(Icons.settings)), - ], ), body: FutureBuilder>( future: getDetails(), diff --git a/lib/routes.dart b/lib/routes.dart index 81541e81..1a53c671 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -1,5 +1,4 @@ -import 'package:onestop_dev/pages/Notifications/notifications.dart'; -import 'package:onestop_dev/pages/Notifications/settings.dart'; +import 'package:onestop_dev/pages/notifications/notifications.dart'; import 'package:onestop_dev/pages/quick_links/academic_calendar.dart'; import 'package:onestop_dev/pages/quick_links/academic_sso.dart'; import 'package:onestop_dev/pages/quick_links/news_page.dart'; @@ -29,5 +28,4 @@ final routes = { AcademicCalendar.id: (context) => const AcademicCalendar(), Complaints.id: (context) => const Complaints(), Notif.id: (context) => const Notif(), - NotifSettings.id:(context) => const NotifSettings(), }; diff --git a/lib/widgets/ui/appbar.dart b/lib/widgets/ui/appbar.dart index 5ed2e50a..345344d1 100644 --- a/lib/widgets/ui/appbar.dart +++ b/lib/widgets/ui/appbar.dart @@ -2,7 +2,7 @@ import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; -import 'package:onestop_dev/pages/Notifications/notifications.dart'; +import 'package:onestop_dev/pages/notifications/notifications.dart'; import 'package:onestop_dev/pages/profile.dart'; AppBar appBar(BuildContext context, {bool displayIcon = true}) { diff --git a/pubspec.yaml b/pubspec.yaml index 057b07d5..0924e59c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -63,7 +63,6 @@ dependencies: firebase_messaging: ^14.1.3 flutter_local_notifications: ^11.0.1 firebase_core: ^2.3.0 - flutter_switch: ^0.3.2 dev_dependencies: flutter_test: From b3a296bd752dd7f5228996c84c2a95907a1e25be Mon Sep 17 00:00:00 2001 From: Vignesh Rao Date: Wed, 7 Dec 2022 21:27:22 +0530 Subject: [PATCH 08/82] Correct app bar --- lib/services/notifications_provider.dart | 9 +++++++-- lib/widgets/ui/appbar.dart | 10 ---------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart index 9100f64f..bbd96515 100644 --- a/lib/services/notifications_provider.dart +++ b/lib/services/notifications_provider.dart @@ -50,7 +50,7 @@ void onDidReceiveNotificationResponse( } Map value = { - "Food": false, + "Food": true, "Lost and Food": false, "TimeTable": false, "Assignment": false, @@ -131,7 +131,12 @@ Future checkForNotifications() async { // ); FirebaseMessaging.onMessage.listen((RemoteMessage message) async { RemoteNotification? notification = message.notification; - String type = message.data['type']; + // try{ + // String type = message.data['type']; + // } catch(e){ + // print(e); + // } + String type = "Food"; print("NOTIFICation : $notification"); // AndroidNotification android = message.notification!.android!; if (notification != null && checkIfUserWantsNotification(type)) { diff --git a/lib/widgets/ui/appbar.dart b/lib/widgets/ui/appbar.dart index 345344d1..47f1d52c 100644 --- a/lib/widgets/ui/appbar.dart +++ b/lib/widgets/ui/appbar.dart @@ -65,16 +65,6 @@ AppBar appBar(BuildContext context, {bool displayIcon = true}) { ]), // textAlign: TextAlign.start, ), - // Expanded( - // child: Image.asset( - // 'assets/images/AppLogo.png', - // // scale: 4, - // ), - // ), - const SizedBox( - width: 35, - height: 35, - ), CircleAvatar( backgroundColor: kAppBarGrey, child: IconButton( From dffb1b1ef466b7e2b80e79b8ef68e76e2d4f30aa Mon Sep 17 00:00:00 2001 From: Vignesh Rao Date: Thu, 8 Dec 2022 01:08:43 +0530 Subject: [PATCH 09/82] Fix Notifications and App Bar --- lib/pages/notifications/notifications.dart | 118 ++++++++++++++------- lib/routes.dart | 2 +- lib/services/notifications_provider.dart | 44 ++++---- lib/widgets/ui/appbar.dart | 4 +- 4 files changed, 102 insertions(+), 66 deletions(-) diff --git a/lib/pages/notifications/notifications.dart b/lib/pages/notifications/notifications.dart index 90afa001..6058d202 100644 --- a/lib/pages/notifications/notifications.dart +++ b/lib/pages/notifications/notifications.dart @@ -1,3 +1,6 @@ +import 'dart:convert'; + +import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; @@ -8,25 +11,25 @@ class NotifsModel { String? hashcode; String? title; String? body; - String? type; + bool read; NotifsModel( this.hashcode, this.title, this.body, - this.type, + this.read, ); } -class Notif extends StatefulWidget { +class NotificationPage extends StatefulWidget { static String id = "notifications"; - const Notif({Key? key}) : super(key: key); + const NotificationPage({Key? key}) : super(key: key); @override - State createState() => _NotifState(); + State createState() => _NotificationPageState(); } -class _NotifState extends State { +class _NotificationPageState extends State { Widget _getLoadingIndicator() { return Expanded( child: Shimmer.fromColors( @@ -62,31 +65,37 @@ class _NotifState extends State { )), ); } + List n = []; Future> getDetails() async { + List newNotifList = []; n.clear(); final SharedPreferences prefs = await SharedPreferences.getInstance(); + await prefs.reload(); List result = prefs.getStringList('notifications')!; for (String r in result) { - var parts = r.split(" "); - NotifsModel not = new NotifsModel("", "", "",""); - if (parts.length >= 1) not.hashcode = parts[0]; - if (parts.length >= 2) not.title = parts[1]; - if (parts.length >= 3) not.body = parts[2]; - if (parts.length >= 4) not.type = parts[3]; - n.add(not); + Map notifData = jsonDecode(r); + print("Notif Data = $notifData"); + n.add(NotifsModel( + null, notifData['header'], notifData['body'], notifData['read'])); + // Set Read Recipient to True and then save to prefs + notifData['read'] = true; + newNotifList.add(jsonEncode(notifData)); } + + prefs.setStringList('notifications', newNotifList); return n; } - IconData getIcon(String? type){ - if(type==null) return Icons.circle; - else if(type=="Food" || type=="Lost and Found" || type=="TimeTable") return Icons.square; - else return Icons.eject; + + IconData getIcon(bool readNotif) { + if (!readNotif) { + return FluentIcons.circle_24_filled; + } + return Icons.brightness_1_outlined; } @override void initState() { - getDetails(); super.initState(); } @@ -95,12 +104,29 @@ class _NotifState extends State { return Scaffold( appBar: AppBar( backgroundColor: kAppBarGrey, + actions: [ + ElevatedButton.icon( + onPressed: () async { + final SharedPreferences prefs = + await SharedPreferences.getInstance(); + await prefs.reload(); + prefs.remove('notifications'); + setState(() {}); + }, + icon: const Icon(FluentIcons.delete_12_regular), + label: Text( + 'Clear All', + style: MyFonts.w300, + ), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.transparent, elevation: 0), + ) + ], leading: IconButton( onPressed: () { Navigator.of(context).pop(); }, - icon: const Icon(Icons.arrow_back)), - leadingWidth: 30, + icon: const Icon(FluentIcons.arrow_left_24_regular)), title: Text( 'Notifications', style: MyFonts.w500, @@ -115,29 +141,39 @@ class _NotifState extends State { itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.all(20.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Icon( - getIcon(snapshot.data![index].type), - color: kBlue, - ), - SizedBox( - width: 10, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Icon( + getIcon(snapshot.data![index].read), + color: kBlue, + ), + SizedBox( + width: 10, + ), + Text( + snapshot.data![index].title ?? " ", + style: MyFonts.w400.setColor(kWhite), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], ), - Text( - snapshot.data![index].title!, - style: const TextStyle( - fontFamily: 'Montserrat', - fontSize: 18, - fontWeight: FontWeight.w700, - color: kWhite, - letterSpacing: 0.1, - height: 1.5, + Row(children: [ + Icon( + getIcon(snapshot.data![index].read), + color: Colors.transparent, ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), + SizedBox( + width: 10, + ), + Text( + 'Description', + style: MyFonts.w300.setColor(kWhite), + ) + ]) ], ), ); diff --git a/lib/routes.dart b/lib/routes.dart index 1a53c671..e485d08c 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -27,5 +27,5 @@ final routes = { AcademicSSO.id: (context) => const AcademicSSO(), AcademicCalendar.id: (context) => const AcademicCalendar(), Complaints.id: (context) => const Complaints(), - Notif.id: (context) => const Notif(), + NotificationPage.id: (context) => const NotificationPage(), }; diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart index bbd96515..b6666b08 100644 --- a/lib/services/notifications_provider.dart +++ b/lib/services/notifications_provider.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:firebase_core/firebase_core.dart'; import "package:firebase_messaging/firebase_messaging.dart"; import "package:flutter_local_notifications/flutter_local_notifications.dart"; @@ -30,13 +32,14 @@ Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { NotificationDetails notificationDetails = NotificationDetails( android: androidNotificationDetails, iOS: iosNotificationDetails); RemoteNotification? notification = message.notification; - String type = message.data['type']; + // String type = message.data['type']; + String type = "Food"; print("NOTIFICation : $notification"); if (notification != null && checkIfUserWantsNotification(type)) { await flutterLocalNotificationsPlugin.show(notification.hashCode, notification.title, notification.body, notificationDetails); } - savenotif(notification!, type); + saveNotification(message.data, message.sentTime); } @pragma('vm:entry-point') @@ -123,12 +126,6 @@ Future checkForNotifications() async { NotificationDetails notificationDetails = NotificationDetails( android: androidNotificationDetails, iOS: iosNotificationDetails); - // FOR IOS - // await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( - // alert: true, - // badge: true, - // sound: true, - // ); FirebaseMessaging.onMessage.listen((RemoteMessage message) async { RemoteNotification? notification = message.notification; // try{ @@ -138,32 +135,35 @@ Future checkForNotifications() async { // } String type = "Food"; print("NOTIFICation : $notification"); + print("Message is ${message.category}"); // AndroidNotification android = message.notification!.android!; if (notification != null && checkIfUserWantsNotification(type)) { await flutterLocalNotificationsPlugin.show(notification.hashCode, notification.title, notification.body, notificationDetails); } - savenotif(notification!, type); + saveNotification(message.data, message.sentTime); }); return true; } -void savenotif(RemoteNotification notification, String type) async { +void saveNotification( + Map notificationData, DateTime? sentTime) async { final SharedPreferences preferences = await SharedPreferences.getInstance(); - String notif = notification.hashCode.toString() + - ' ' + - notification.title! + - ' ' + - notification.body! + - ' ' + - type; - List? notifications = - preferences.getStringList('notifications') == null - ? [] - : preferences.getStringList('notifications'); + notificationData['time'] = sentTime?.toString() ?? DateTime.now().toString(); + notificationData['read'] = false; + String notifJson = jsonEncode(notificationData); + print("data = $notificationData"); + // String notif = notification.hashCode.toString() + + // ' ' + + // notification.title! + + // ' ' + + // notification.body! + + // ' ' + + // type; + List notifications = preferences.getStringList('notifications') ?? []; if (notifications!.length > 14) { notifications.removeAt(0); } - notifications.add(notif); + notifications.add(notifJson); preferences.setStringList('notifications', notifications); } diff --git a/lib/widgets/ui/appbar.dart b/lib/widgets/ui/appbar.dart index 47f1d52c..427abf92 100644 --- a/lib/widgets/ui/appbar.dart +++ b/lib/widgets/ui/appbar.dart @@ -69,9 +69,9 @@ AppBar appBar(BuildContext context, {bool displayIcon = true}) { backgroundColor: kAppBarGrey, child: IconButton( onPressed: () { - Navigator.pushNamed(context, Notif.id); + Navigator.pushNamed(context, NotificationPage.id); }, - icon: Icon(Icons.notifications), + icon: const Icon(FluentIcons.alert_24_filled), color: lBlue2, )), ], From 90f764fe3d00688b8e096ffcd32340079580faf4 Mon Sep 17 00:00:00 2001 From: Vignesh Rao Date: Thu, 8 Dec 2022 01:15:21 +0530 Subject: [PATCH 10/82] App Bar colors --- lib/main.dart | 3 +- lib/services/notifications_provider.dart | 38 ++++++++---------------- lib/widgets/ui/appbar.dart | 2 +- 3 files changed, 15 insertions(+), 28 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 76673561..3b35b5c3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ // ignore_for_file: unused_import import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:onestop_dev/functions/utility/check_last_updated.dart'; @@ -23,7 +24,7 @@ void main() async { await checkLastUpdated(); await checkForNotifications(); final fcmToken = await FirebaseMessaging.instance.getToken(); - print("FCM TOken is $fcmToken"); + print("FCM Token is $fcmToken"); FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); runApp(const MyApp()); } diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart index b6666b08..63a70315 100644 --- a/lib/services/notifications_provider.dart +++ b/lib/services/notifications_provider.dart @@ -35,7 +35,7 @@ Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { // String type = message.data['type']; String type = "Food"; print("NOTIFICation : $notification"); - if (notification != null && checkIfUserWantsNotification(type)) { + if (notification != null && checkNotificationCategory(type)) { await flutterLocalNotificationsPlugin.show(notification.hashCode, notification.title, notification.body, notificationDetails); } @@ -52,22 +52,15 @@ void onDidReceiveNotificationResponse( // await Navigator.pushNamed(context, HomePage.id); } -Map value = { - "Food": true, - "Lost and Food": false, - "TimeTable": false, - "Assignment": false, - "Ferry": false, - "Buses": false -}; -bool checkIfUserWantsNotification(String type) { - if (type == "Food") return value["Food"]!; - if (type == "Lost and Found") return value["Lost and Found"]!; - if (type == "TimeTable") return value["TimeTable"]!; - if (type == "Assignment") return value["Assignment"]!; - if (type == "Ferry") return value["Ferry"]!; - if (type == "Buses") return value["Buses"]!; - if (type == "all") return true; + +bool checkNotificationCategory(String type) { + switch (type) { + case "Lost": + case "Found": + case "Buy": + case "Sell": + return true; + } return false; } @@ -137,7 +130,7 @@ Future checkForNotifications() async { print("NOTIFICation : $notification"); print("Message is ${message.category}"); // AndroidNotification android = message.notification!.android!; - if (notification != null && checkIfUserWantsNotification(type)) { + if (notification != null && checkNotificationCategory(type)) { await flutterLocalNotificationsPlugin.show(notification.hashCode, notification.title, notification.body, notificationDetails); } @@ -153,15 +146,8 @@ void saveNotification( notificationData['read'] = false; String notifJson = jsonEncode(notificationData); print("data = $notificationData"); - // String notif = notification.hashCode.toString() + - // ' ' + - // notification.title! + - // ' ' + - // notification.body! + - // ' ' + - // type; List notifications = preferences.getStringList('notifications') ?? []; - if (notifications!.length > 14) { + if (notifications.length > 15) { notifications.removeAt(0); } notifications.add(notifJson); diff --git a/lib/widgets/ui/appbar.dart b/lib/widgets/ui/appbar.dart index 427abf92..678862c6 100644 --- a/lib/widgets/ui/appbar.dart +++ b/lib/widgets/ui/appbar.dart @@ -71,7 +71,7 @@ AppBar appBar(BuildContext context, {bool displayIcon = true}) { onPressed: () { Navigator.pushNamed(context, NotificationPage.id); }, - icon: const Icon(FluentIcons.alert_24_filled), + icon: const Icon(FluentIcons.alert_24_filled,color: lBlue2,), color: lBlue2, )), ], From f0de64c00538ffa79c5f4b6a379516a9e0652799 Mon Sep 17 00:00:00 2001 From: Vignesh Rao Date: Thu, 8 Dec 2022 01:19:54 +0530 Subject: [PATCH 11/82] Correct README.md --- README.md | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/README.md b/README.md index 2e33083c..3c120f18 100644 --- a/README.md +++ b/README.md @@ -1,16 +1 @@ -# onestop_dev - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +![feature graphic](https://user-images.githubusercontent.com/75874394/192554328-370aece6-9697-4878-92b8-eb120d07e1b1.png) \ No newline at end of file From 832f76faf563080f0ac3d4039b4341cba6b35972 Mon Sep 17 00:00:00 2001 From: vrrao01 <75874394+vrrao01@users.noreply.github.com> Date: Thu, 8 Dec 2022 01:21:30 +0530 Subject: [PATCH 12/82] Restore README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3c120f18..3bbe4ba7 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -![feature graphic](https://user-images.githubusercontent.com/75874394/192554328-370aece6-9697-4878-92b8-eb120d07e1b1.png) \ No newline at end of file +![feature graphic](https://user-images.githubusercontent.com/75874394/192554328-370aece6-9697-4878-92b8-eb120d07e1b1.png) From 61902d1731531f84815437a891c72e498e8ffc34 Mon Sep 17 00:00:00 2001 From: Vignesh Rao Date: Thu, 8 Dec 2022 01:34:30 +0530 Subject: [PATCH 13/82] Reverse notification order --- lib/pages/notifications/notifications.dart | 2 +- lib/services/notifications_provider.dart | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/pages/notifications/notifications.dart b/lib/pages/notifications/notifications.dart index 6058d202..aeb0efb7 100644 --- a/lib/pages/notifications/notifications.dart +++ b/lib/pages/notifications/notifications.dart @@ -84,7 +84,7 @@ class _NotificationPageState extends State { } prefs.setStringList('notifications', newNotifList); - return n; + return n.reversed.toList(); } IconData getIcon(bool readNotif) { diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart index 63a70315..52cef8b9 100644 --- a/lib/services/notifications_provider.dart +++ b/lib/services/notifications_provider.dart @@ -126,11 +126,10 @@ Future checkForNotifications() async { // } catch(e){ // print(e); // } - String type = "Food"; print("NOTIFICation : $notification"); print("Message is ${message.category}"); // AndroidNotification android = message.notification!.android!; - if (notification != null && checkNotificationCategory(type)) { + if (notification != null && checkNotificationCategory(message.data['category'])) { await flutterLocalNotificationsPlugin.show(notification.hashCode, notification.title, notification.body, notificationDetails); } From ed4ba8ef9989c8685e73294e369d8143de58a9f8 Mon Sep 17 00:00:00 2001 From: Vignesh Rao Date: Thu, 8 Dec 2022 01:43:29 +0530 Subject: [PATCH 14/82] Dart analyze refactoring --- lib/main.dart | 1 - lib/pages/contact/contact.dart | 2 +- lib/pages/notifications/notifications.dart | 4 +- lib/pages/profile.dart | 4 +- lib/services/notifications_provider.dart | 52 +++++++++++++++------- lib/stores/mapbox_store.dart | 1 - lib/widgets/login/login_button.dart | 2 +- lib/widgets/ui/appbar.dart | 5 ++- 8 files changed, 46 insertions(+), 25 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 3b35b5c3..bb5215c4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,7 +1,6 @@ // ignore_for_file: unused_import import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:onestop_dev/functions/utility/check_last_updated.dart'; diff --git a/lib/pages/contact/contact.dart b/lib/pages/contact/contact.dart index ab9ca0dd..2beffc7d 100644 --- a/lib/pages/contact/contact.dart +++ b/lib/pages/contact/contact.dart @@ -153,7 +153,7 @@ class _ContactPageState extends State { } }); for (var e in alphabets) { - people["${e} ADONOTUSE"] = ContactModel( + people["$e ADONOTUSE"] = ContactModel( name: "Random", contacts: [], group: ""); } return AlphabetScrollView( diff --git a/lib/pages/notifications/notifications.dart b/lib/pages/notifications/notifications.dart index aeb0efb7..e64b87e6 100644 --- a/lib/pages/notifications/notifications.dart +++ b/lib/pages/notifications/notifications.dart @@ -150,7 +150,7 @@ class _NotificationPageState extends State { getIcon(snapshot.data![index].read), color: kBlue, ), - SizedBox( + const SizedBox( width: 10, ), Text( @@ -166,7 +166,7 @@ class _NotificationPageState extends State { getIcon(snapshot.data![index].read), color: Colors.transparent, ), - SizedBox( + const SizedBox( width: 10, ), Text( diff --git a/lib/pages/profile.dart b/lib/pages/profile.dart index f5b5c340..cbe05c1a 100644 --- a/lib/pages/profile.dart +++ b/lib/pages/profile.dart @@ -99,7 +99,9 @@ class _ProfilePageState extends State { '/', (Route route) => false)); }, style: ElevatedButton.styleFrom( - elevation: 0, primary: kAppBarGrey), + elevation: 0, + backgroundColor: kAppBarGrey, + ), child: Text( 'Log Out', style: MyFonts.w500.setColor(kBlue), diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart index 52cef8b9..3f36e259 100644 --- a/lib/services/notifications_provider.dart +++ b/lib/services/notifications_provider.dart @@ -27,17 +27,26 @@ Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { importance: Importance.high, playSound: true, icon: '@mipmap/ic_launcher'); - DarwinNotificationDetails iosNotificationDetails = DarwinNotificationDetails( - presentAlert: true, presentBadge: true, presentSound: true); + DarwinNotificationDetails iosNotificationDetails = + const DarwinNotificationDetails( + presentAlert: true, + presentBadge: true, + presentSound: true, + ); NotificationDetails notificationDetails = NotificationDetails( - android: androidNotificationDetails, iOS: iosNotificationDetails); + android: androidNotificationDetails, + iOS: iosNotificationDetails, + ); RemoteNotification? notification = message.notification; // String type = message.data['type']; - String type = "Food"; print("NOTIFICation : $notification"); - if (notification != null && checkNotificationCategory(type)) { - await flutterLocalNotificationsPlugin.show(notification.hashCode, - notification.title, notification.body, notificationDetails); + if (checkNotificationCategory(message.data['category'])) { + await flutterLocalNotificationsPlugin.show( + message.hashCode, + message.data['header'], + message.data['body'], + notificationDetails, + ); } saveNotification(message.data, message.sentTime); } @@ -52,7 +61,6 @@ void onDidReceiveNotificationResponse( // await Navigator.pushNamed(context, HomePage.id); } - bool checkNotificationCategory(String type) { switch (type) { case "Lost": @@ -92,13 +100,13 @@ Future checkForNotifications() async { ?.createNotificationChannel(channel); const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher'); - final DarwinInitializationSettings initializationSettingsDarwin = + const DarwinInitializationSettings initializationSettingsDarwin = DarwinInitializationSettings( requestSoundPermission: true, requestBadgePermission: true, requestAlertPermission: true, ); - final InitializationSettings initializationSettings = InitializationSettings( + const InitializationSettings initializationSettings = InitializationSettings( android: initializationSettingsAndroid, iOS: initializationSettingsDarwin, ); @@ -114,10 +122,16 @@ Future checkForNotifications() async { importance: Importance.high, playSound: true, icon: '@mipmap/ic_launcher'); - DarwinNotificationDetails iosNotificationDetails = DarwinNotificationDetails( - presentAlert: true, presentBadge: true, presentSound: true); + DarwinNotificationDetails iosNotificationDetails = + const DarwinNotificationDetails( + presentAlert: true, + presentBadge: true, + presentSound: true, + ); NotificationDetails notificationDetails = NotificationDetails( - android: androidNotificationDetails, iOS: iosNotificationDetails); + android: androidNotificationDetails, + iOS: iosNotificationDetails, + ); FirebaseMessaging.onMessage.listen((RemoteMessage message) async { RemoteNotification? notification = message.notification; @@ -128,10 +142,14 @@ Future checkForNotifications() async { // } print("NOTIFICation : $notification"); print("Message is ${message.category}"); - // AndroidNotification android = message.notification!.android!; - if (notification != null && checkNotificationCategory(message.data['category'])) { - await flutterLocalNotificationsPlugin.show(notification.hashCode, - notification.title, notification.body, notificationDetails); + if (notification != null && + checkNotificationCategory(message.data['category'])) { + await flutterLocalNotificationsPlugin.show( + message.hashCode, + message.data['header'], + message.data['body'], + notificationDetails, + ); } saveNotification(message.data, message.sentTime); }); diff --git a/lib/stores/mapbox_store.dart b/lib/stores/mapbox_store.dart index 60897cf5..72f27ce9 100644 --- a/lib/stores/mapbox_store.dart +++ b/lib/stores/mapbox_store.dart @@ -1,6 +1,5 @@ // ignore_for_file: library_private_types_in_public_api -import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; diff --git a/lib/widgets/login/login_button.dart b/lib/widgets/login/login_button.dart index 9ddf14c2..1aa1a203 100644 --- a/lib/widgets/login/login_button.dart +++ b/lib/widgets/login/login_button.dart @@ -28,7 +28,7 @@ class LoginButton extends StatelessWidget { flex: 2, child: ElevatedButton( style: ElevatedButton.styleFrom( - primary: kYellow, + backgroundColor: kYellow, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(18))), onPressed: () { diff --git a/lib/widgets/ui/appbar.dart b/lib/widgets/ui/appbar.dart index 678862c6..4f81f48a 100644 --- a/lib/widgets/ui/appbar.dart +++ b/lib/widgets/ui/appbar.dart @@ -71,7 +71,10 @@ AppBar appBar(BuildContext context, {bool displayIcon = true}) { onPressed: () { Navigator.pushNamed(context, NotificationPage.id); }, - icon: const Icon(FluentIcons.alert_24_filled,color: lBlue2,), + icon: const Icon( + FluentIcons.alert_24_filled, + color: lBlue2, + ), color: lBlue2, )), ], From 765ece29a316ea8d083fffe418e7645a77694b11 Mon Sep 17 00:00:00 2001 From: Vignesh Rao Date: Thu, 8 Dec 2022 23:46:21 +0530 Subject: [PATCH 15/82] Add notification icon --- .../main/res/drawable/notification_icon.png | Bin 0 -> 4053 bytes lib/pages/notifications/notifications.dart | 68 +++++---------- lib/services/notifications_provider.dart | 78 +++++++++--------- 3 files changed, 57 insertions(+), 89 deletions(-) create mode 100644 android/app/src/main/res/drawable/notification_icon.png diff --git a/android/app/src/main/res/drawable/notification_icon.png b/android/app/src/main/res/drawable/notification_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..766b161a048a4166a749358f3271fe9a4312ff57 GIT binary patch literal 4053 zcmV;`4=V79P)vlalpbE!BjwOfsi_V<2uY6<<(0=l+@`q7QF)w;qw5h#GUAfB zC>7^=Mb06mghF1Y)QOx@DK&GyRq7Tsv)7(AGvzn`-*4G#vevi0+510hecxK&T3eBl zLyis#MbZM}=K~RP zy1BUxJAC-?V#r!CsICC1H%iXV&Sr33w|FrUMa9gSGbftI<2@&#qa2+NjLFGnv#Gke zIu2xa5!9z8Jb~~iQK6xsR)K+mPbAci932#l$eEa!IMvqHHVm>Vg!O3?TrT$lq>`kh zq-l0`cE3xbO*v!_EOPqz_-I5%MxKMLmW1>X22J=uTonieiPNS{^8@=-1}exQP0%K1 za&q#w*4EZBl2nE!?7->D8w>dL*I&zIt&AL!11)kwZ?z3B4ieS{2Z}du-n?B}pXImkmOIf0l5;9?;iRhXe~ z-@cnb&q5Z9l_qOl@jq{qy1m(uAS+mAr)22OwWH(xD%9Eu?DDwMv%yHQ_UI0LllckkXveSQ55Q3WF+B6==fyf}fT+}&W)9%<`8va_>S85U6BCn1G}|SH`1ttV=H})ot3Aqe^V&T+>-s=QBgn?;k zBK;#oq&_sos7rlzJsadGid$Sx%$Qg!m=$?M@qwGQ$#;NFTHnMk0Soc8wi>QrNh8xHC{JUmRv zs`P(6efqQ-hD}o#25)0lT?>gQIk#-tqP=R>s$U?hL{Kc-(b4e+m@%`54I6fogg_v> zwu6I13e{-)k_IvbP5?FN5WrlyST-%l_AhPvKz<=J>X2tdc|-fr5X{Wp`mf>&6_u9&XDfP5*yGRt`Zw|Bmgz|j!y7h z=}vJ`F)=Z^;9RYdq*5ZF2oBv1H8r(y@7}#5D;WI)Ly9djMCH7o2R3rgZ6*nIDT3c6&2oauMaTLrCl`Ha075E1q1}hB*@~~vu6Q@hKA=b zs?2~SX>$GvDH75Rs&R$Ih-x%Ju!rZ5P#!sQxok{=p9k19C3M&`Bto$cf_&b(l3` z8j!@)&j$+&i!qlkU;a~6LGWhJ_vzDT@RTW2?oy5G*mUtdB%$QoxN+k_40-RM7aR>E z4^~jj!Gi}&)6&w0=jG+0d1g8@B~u|0CnpZDx~?w_f^OZq4FSWS_CuaJb!y$|)2C;^ z^*@@5O0v zz<>eipg;1^dWb4JY0@N5xX6s0k{Bv+AQNH&>cGZ4&9riQdir`(Q&ZaZC)lf6U=|d& z^?%R{Z=x#)hX2iU%L)VZzPt4G^#f@X9i*Y5LA`nNM(j43JZMQTjdfH+iBmZuA|eyW ziBkpjQf-nGFpRE{pr9ZkYxZZ)o=u=hPGoYR^9;oH+L@43Ry~(Y;pyp_B2IlCkM|0l zUV?#c;?6P$iV@8R~1`ZTVmuyQ~PSd3bw3cV`IZkPEMA(?dj;~h#L{qUeCh> zk_)_S8*K(IFIln#$LmKRV&~$3!{MNw{lDVMX(Hz{s&Vp|4p^$HswkfEfw+z1B0M~N zA!d~mq}o1o=n&bpIp)xiwE{FSm?A~aD_5>$Pna-)E;&)izYmMWS}AVhxB#2S4X3=T zt1C{RNM`}bU8|CUItd{Sz5V{6(y12O9!(0|bMz4>Xo7+ATO3=Z*d-rhGc@aupym%qj{9Xq|XNa=8PeMpb z&l~O48BVw2?AfzdN{gJ{-rjxTLT|6}M*x{=hn;mM?A*Dt>gS(-#;GDQfP^%_A<82m zrQKk@WE@s@r33;GiW2+<`opV%yX!Y3U9WF7UDt}73JMBW`FuWF6vdiL>)EsC zPnDIGI;yIw+X(3005MLuOW(S6YY{0uIwG{SwI37~7SbN&9335RX=-YYDk&)uo1n{< zEmPRBV+Uh7g6m3qC^qZkekaz)M2$<_rns6CC_ewkKEcS4sM^=)kFCgwJa%Z<4HUqR z9tYcV3Do}{Y&{EbMi{U9+uGU=N=!^l`cyZXsO!_Gj~COnI}3`6icm~#4kQzrRk{}! z7pG`xY1sfl8L#Yt6WnwA_U+dp#eylf0jI8-3dOFtq+Cu3+fUD;`Um^6N-N*9NB+dC zzw;RZmM>ra5XgxRTxYVKPAw-V=T==^-LuD!A3GQr7?jhk_~5|QL0c$R^C9<=# z7eJ39(S7tC1!-w%uIA?EIT%$20zq%X5C2VOBHYR?@`~S&ECn#$jBdhzwao9r&}m0Dh>dmWkOGiVlS`7#>W2k z^5x4c$fNEW-I#_6bx%*vF)&1-pjq01vqF$Kbm-7u2*~La7(ae|72IERmefRyYU*}& zc3CJGBrGg!8<)!!>L_tIoUSux&h+&1@%KC8aT&*V zP+01zlH4Xab8~YA;3*IJ@ZkfROcm$&6(rxn-QC?n3>kD#0yjzA^F%uxV3?hISibh~DV9Vysn@d-(UVT|up?Tj?o3Zy#@cCBl z+I28A3sO>2##mchXJU$#HvZJp)5Dse|56Ya7sm&3PNKvQvKU5T#E7VJXKQ<@ zto;Da599qjUn0P?i2w)XDr995Q?LabwD#jHSgac`v^(Mor9GEeQBi@0kR^V8e!F+> z+=+JA5!pt7iCkY_U-y0c_Q~Je)&}7DWH~xInkFP9oTBiTd>H}kUKcQ}gr1+e{~YUw zd3KoORA8UOp6HHW@aUyzoF3H1gn^9I)b{)(J54eh4E%FJjemc+Yt7PzuY-ozF58Pfgh4E%Jbl|Cq zipr5QXU-T{T3VtZ7VBtinkXGTdbCw$W@fpp-jLB*VPRpBpscK%@c#XKrZpB*cV2^vxslTC&=D0=fRr3h`pdXt^3B=k-SzTRCSy@@3y+rzMZf;!z0s=Tj zMn?1Cvw;|5uX4HELy3urm$S06h_;|FF6X}EwazjgtXbT8B1FCf4!iA4ZN{GHk zp#dzjTJ+L`b@7{&?7>NzO0fjsyRdF=kE`E(HIv`!{YU=;_^L>!gqORH00000NkvXX Hu0mjf*x{_r literal 0 HcmV?d00001 diff --git a/lib/pages/notifications/notifications.dart b/lib/pages/notifications/notifications.dart index e64b87e6..6ca1f4e7 100644 --- a/lib/pages/notifications/notifications.dart +++ b/lib/pages/notifications/notifications.dart @@ -4,8 +4,8 @@ import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; +import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:shimmer/shimmer.dart'; class NotifsModel { String? hashcode; @@ -30,44 +30,8 @@ class NotificationPage extends StatefulWidget { } class _NotificationPageState extends State { - Widget _getLoadingIndicator() { - return Expanded( - child: Shimmer.fromColors( - period: const Duration(seconds: 1), - baseColor: kHomeTile, - highlightColor: lGrey, - child: SizedBox( - height: 200, - child: ListView.builder( - itemCount: 8, - itemBuilder: (_, __) => Padding( - padding: - const EdgeInsets.symmetric(horizontal: 10.0, vertical: 2), - child: Column( - children: [ - Container( - height: 80, - decoration: BoxDecoration( - color: kBlack, - borderRadius: BorderRadius.circular(5)), - ), - // Divider( - // thickness: 1.5, - // color: kTabBar, - // ), - const SizedBox( - height: 8, - ), - ], - ), - ), - ), - )), - ); - } - - List n = []; Future> getDetails() async { + List n = []; List newNotifList = []; n.clear(); final SharedPreferences prefs = await SharedPreferences.getInstance(); @@ -136,6 +100,14 @@ class _NotificationPageState extends State { future: getDetails(), builder: (context, snapshot) { if (snapshot.hasData) { + if (snapshot.data!.isEmpty) { + return Center( + child: Text( + 'No notifications found', + style: MyFonts.w300.setColor(kWhite), + ), + ); + } return ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (context, index) { @@ -180,16 +152,16 @@ class _NotificationPageState extends State { }, ); } - return Container( - padding: const EdgeInsets.fromLTRB(0, 20, 0, 20), - color: Colors.black.withOpacity(0.8), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - _getLoadingIndicator(), - ], - ), + return Column( + children: [ + const SizedBox( + height: 10, + ), + Expanded( + child: ListShimmer( + count: 5, + )), + ], ); }), ); diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart index 3f36e259..44aa3bec 100644 --- a/lib/services/notifications_provider.dart +++ b/lib/services/notifications_provider.dart @@ -1,5 +1,5 @@ import 'dart:convert'; - +import 'dart:io' show Platform; import 'package:firebase_core/firebase_core.dart'; import "package:firebase_messaging/firebase_messaging.dart"; import "package:flutter_local_notifications/flutter_local_notifications.dart"; @@ -26,7 +26,7 @@ Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { channelDescription: channel.description, importance: Importance.high, playSound: true, - icon: '@mipmap/ic_launcher'); + icon: 'notification_icon'); DarwinNotificationDetails iosNotificationDetails = const DarwinNotificationDetails( presentAlert: true, @@ -38,8 +38,8 @@ Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { iOS: iosNotificationDetails, ); RemoteNotification? notification = message.notification; - // String type = message.data['type']; - print("NOTIFICation : $notification"); + + print("Notification : $notification"); if (checkNotificationCategory(message.data['category'])) { await flutterLocalNotificationsPlugin.show( message.hashCode, @@ -73,19 +73,15 @@ bool checkNotificationCategory(String type) { } Future checkForNotifications() async { - FirebaseMessaging messaging = FirebaseMessaging.instance; - SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); - String? token = sharedPreferences.getString("fcm-token"); - if (token == null) { - token = await messaging.getToken(); - sharedPreferences.setString("fcm-token", token!); - } FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); - flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>()! - .requestPermission(); + + if (Platform.isAndroid) { + await flutterLocalNotificationsPlugin + .resolvePlatformSpecificImplementation< + AndroidFlutterLocalNotificationsPlugin>() + ?.requestPermission(); + } const AndroidNotificationChannel channel = AndroidNotificationChannel( 'high_importance_channel', // id @@ -94,10 +90,12 @@ Future checkForNotifications() async { 'This channel is used for important notifications.', // description importance: Importance.high, playSound: true); + await flutterLocalNotificationsPlugin .resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin>() ?.createNotificationChannel(channel); + const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher'); const DarwinInitializationSettings initializationSettingsDarwin = @@ -116,34 +114,26 @@ Future checkForNotifications() async { // onDidReceiveBackgroundNotificationResponse: // onDidReceiveNotificationResponse, ); - AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails(channel.id, channel.name, - channelDescription: channel.description, - importance: Importance.high, - playSound: true, - icon: '@mipmap/ic_launcher'); - DarwinNotificationDetails iosNotificationDetails = - const DarwinNotificationDetails( - presentAlert: true, - presentBadge: true, - presentSound: true, - ); - NotificationDetails notificationDetails = NotificationDetails( - android: androidNotificationDetails, - iOS: iosNotificationDetails, - ); FirebaseMessaging.onMessage.listen((RemoteMessage message) async { - RemoteNotification? notification = message.notification; - // try{ - // String type = message.data['type']; - // } catch(e){ - // print(e); - // } - print("NOTIFICation : $notification"); - print("Message is ${message.category}"); - if (notification != null && - checkNotificationCategory(message.data['category'])) { + AndroidNotificationDetails androidNotificationDetails = + AndroidNotificationDetails(channel.id, channel.name, + channelDescription: channel.description, + importance: Importance.high, + playSound: true, + icon: 'notification_icon'); + DarwinNotificationDetails iosNotificationDetails = + const DarwinNotificationDetails( + presentAlert: true, + presentBadge: true, + presentSound: true, + ); + NotificationDetails notificationDetails = NotificationDetails( + android: androidNotificationDetails, + iOS: iosNotificationDetails, + ); + print("Message is ${message.data}"); + if (checkNotificationCategory(message.data['category'])) { await flutterLocalNotificationsPlugin.show( message.hashCode, message.data['header'], @@ -153,6 +143,12 @@ Future checkForNotifications() async { } saveNotification(message.data, message.sentTime); }); + + // Resave list of notifications in case it's initialized to null + final SharedPreferences preferences = await SharedPreferences.getInstance(); + await preferences.reload(); + List notifications = preferences.getStringList('notifications') ?? []; + preferences.setStringList('notifications', notifications); return true; } From 651bc26a9804b54138472e43673ed2599222f4e6 Mon Sep 17 00:00:00 2001 From: Hareesh-Nandigrama Date: Fri, 17 Mar 2023 02:05:16 +0530 Subject: [PATCH 16/82] Change Firebase project --- android/app/google-services.json | 21 ++++++--- ios/Runner.xcodeproj/project.pbxproj | 4 ++ ios/Runner/GoogleService-Info.plist | 34 ++++++++++++++ ios/firebase_app_id_file.json | 7 +++ lib/firebase_options.dart | 69 ++++++++++++++++++++++++++++ lib/main.dart | 6 ++- 6 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 ios/Runner/GoogleService-Info.plist create mode 100644 ios/firebase_app_id_file.json create mode 100644 lib/firebase_options.dart diff --git a/android/app/google-services.json b/android/app/google-services.json index ac08b5bb..a4410341 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -1,34 +1,41 @@ { "project_info": { - "project_number": "320514948737", - "project_id": "onestop-5ce62", - "storage_bucket": "onestop-5ce62.appspot.com" + "project_number": "755380116666", + "project_id": "onestopiitg-2", + "storage_bucket": "onestopiitg-2.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:320514948737:android:066c4a2cabdaedf1df5780", + "mobilesdk_app_id": "1:755380116666:android:2e30df4d32309c29e2f683", "android_client_info": { "package_name": "com.swciitg.onestop2" } }, "oauth_client": [ { - "client_id": "320514948737-nkd52j89olp45n773ookls9guji7fsj3.apps.googleusercontent.com", + "client_id": "755380116666-8eqlpn3rnrp3j4v1unhonm6qldqhek2c.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyAYT3YqfDbfrY539YK9rzu-C4I4atXWsZ0" + "current_key": "AIzaSyBsoG-Xp8P2FGth4pE38cUyT2ljSjrAfLE" } ], "services": { "appinvite_service": { "other_platform_oauth_client": [ { - "client_id": "320514948737-nkd52j89olp45n773ookls9guji7fsj3.apps.googleusercontent.com", + "client_id": "755380116666-8eqlpn3rnrp3j4v1unhonm6qldqhek2c.apps.googleusercontent.com", "client_type": 3 + }, + { + "client_id": "755380116666-7glnointr5aktgrk2rvsonjlfjvuoqpq.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.example.testNotification" + } } ] } diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 82df7711..531aff10 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 527F68B950AE27793D9F7B83 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 104966F04E7993D95EF62BBA /* GoogleService-Info.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; @@ -30,6 +31,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 104966F04E7993D95EF62BBA /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 189799FC0EE353C8F0A37CCE /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -98,6 +100,7 @@ 97C146EF1CF9000F007C117D /* Products */, 94BCE952F797F377FEC6B694 /* Pods */, 550921A1AB19070431638329 /* Frameworks */, + 104966F04E7993D95EF62BBA /* GoogleService-Info.plist */, ); sourceTree = ""; }; @@ -192,6 +195,7 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + 527F68B950AE27793D9F7B83 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/Runner/GoogleService-Info.plist b/ios/Runner/GoogleService-Info.plist new file mode 100644 index 00000000..56527424 --- /dev/null +++ b/ios/Runner/GoogleService-Info.plist @@ -0,0 +1,34 @@ + + + + + CLIENT_ID + 755380116666-if5jvrpuk5hja4qtlqoaa5eil2nlhmaa.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.755380116666-if5jvrpuk5hja4qtlqoaa5eil2nlhmaa + API_KEY + AIzaSyDwfpfZYu7h93Ze4XfU00EdYA-b2Tr39Kk + GCM_SENDER_ID + 755380116666 + PLIST_VERSION + 1 + BUNDLE_ID + com.swciitg.onestop2swc2022 + PROJECT_ID + onestopiitg-2 + STORAGE_BUCKET + onestopiitg-2.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:755380116666:ios:0d6918b3d64a7377e2f683 + + \ No newline at end of file diff --git a/ios/firebase_app_id_file.json b/ios/firebase_app_id_file.json new file mode 100644 index 00000000..7c1e22da --- /dev/null +++ b/ios/firebase_app_id_file.json @@ -0,0 +1,7 @@ +{ + "file_generated_by": "FlutterFire CLI", + "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", + "GOOGLE_APP_ID": "1:755380116666:ios:89e63889573262dfe2f683", + "FIREBASE_PROJECT_ID": "onestopiitg-2", + "GCM_SENDER_ID": "755380116666" +} \ No newline at end of file diff --git a/lib/firebase_options.dart b/lib/firebase_options.dart new file mode 100644 index 00000000..a3203394 --- /dev/null +++ b/lib/firebase_options.dart @@ -0,0 +1,69 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for web - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyBsoG-Xp8P2FGth4pE38cUyT2ljSjrAfLE', + appId: '1:755380116666:android:2e30df4d32309c29e2f683', + messagingSenderId: '755380116666', + projectId: 'onestopiitg-2', + storageBucket: 'onestopiitg-2.appspot.com', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'AIzaSyDwfpfZYu7h93Ze4XfU00EdYA-b2Tr39Kk', + appId: '1:755380116666:ios:89e63889573262dfe2f683', + messagingSenderId: '755380116666', + projectId: 'onestopiitg-2', + storageBucket: 'onestopiitg-2.appspot.com', + iosClientId: '755380116666-if5jvrpuk5hja4qtlqoaa5eil2nlhmaa.apps.googleusercontent.com', + iosBundleId: 'com.swciitg.onestop2swc2022', + ); +} diff --git a/lib/main.dart b/lib/main.dart index bb5215c4..f7bf2cec 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,6 +3,7 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:onestop_dev/firebase_options.dart'; import 'package:onestop_dev/functions/utility/check_last_updated.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/routes.dart'; @@ -15,7 +16,9 @@ import 'package:provider/provider.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp(); + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); SystemChrome.setPreferredOrientations( [DeviceOrientation.portraitDown, DeviceOrientation.portraitUp]); SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, @@ -24,7 +27,6 @@ void main() async { await checkForNotifications(); final fcmToken = await FirebaseMessaging.instance.getToken(); print("FCM Token is $fcmToken"); - FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); runApp(const MyApp()); } From 3c39f1e2fd7a8267d696be5711f1a41c6a85d072 Mon Sep 17 00:00:00 2001 From: Priyanshu Srivastava Date: Tue, 21 Mar 2023 00:58:55 +0530 Subject: [PATCH 17/82] notif --- android/app/google-services.json | 21 ++++++--- ios/Runner.xcodeproj/project.pbxproj | 4 ++ ios/Runner/GoogleService-Info.plist | 34 ++++++++++++++ ios/firebase_app_id_file.json | 7 +++ lib/firebase_options.dart | 69 ++++++++++++++++++++++++++++ 5 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 ios/Runner/GoogleService-Info.plist create mode 100644 ios/firebase_app_id_file.json create mode 100644 lib/firebase_options.dart diff --git a/android/app/google-services.json b/android/app/google-services.json index ac08b5bb..ab204a0f 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -1,34 +1,41 @@ { "project_info": { - "project_number": "320514948737", - "project_id": "onestop-5ce62", - "storage_bucket": "onestop-5ce62.appspot.com" + "project_number": "755380116666", + "project_id": "onestopiitg-2", + "storage_bucket": "onestopiitg-2.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:320514948737:android:066c4a2cabdaedf1df5780", + "mobilesdk_app_id": "1:755380116666:android:93baf948818388bfe2f683", "android_client_info": { "package_name": "com.swciitg.onestop2" } }, "oauth_client": [ { - "client_id": "320514948737-nkd52j89olp45n773ookls9guji7fsj3.apps.googleusercontent.com", + "client_id": "755380116666-8eqlpn3rnrp3j4v1unhonm6qldqhek2c.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyAYT3YqfDbfrY539YK9rzu-C4I4atXWsZ0" + "current_key": "AIzaSyBsoG-Xp8P2FGth4pE38cUyT2ljSjrAfLE" } ], "services": { "appinvite_service": { "other_platform_oauth_client": [ { - "client_id": "320514948737-nkd52j89olp45n773ookls9guji7fsj3.apps.googleusercontent.com", + "client_id": "755380116666-8eqlpn3rnrp3j4v1unhonm6qldqhek2c.apps.googleusercontent.com", "client_type": 3 + }, + { + "client_id": "755380116666-7glnointr5aktgrk2rvsonjlfjvuoqpq.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.example.testNotification" + } } ] } diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 82df7711..2b5de75b 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 797FFB145D937626B7EA4ADA /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9822E429D96AFE0F8D730785 /* GoogleService-Info.plist */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; @@ -46,6 +47,7 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9822E429D96AFE0F8D730785 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; C05463DD6012FC0ED5AB6BC0 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -98,6 +100,7 @@ 97C146EF1CF9000F007C117D /* Products */, 94BCE952F797F377FEC6B694 /* Pods */, 550921A1AB19070431638329 /* Frameworks */, + 9822E429D96AFE0F8D730785 /* GoogleService-Info.plist */, ); sourceTree = ""; }; @@ -192,6 +195,7 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + 797FFB145D937626B7EA4ADA /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/Runner/GoogleService-Info.plist b/ios/Runner/GoogleService-Info.plist new file mode 100644 index 00000000..4194fa6c --- /dev/null +++ b/ios/Runner/GoogleService-Info.plist @@ -0,0 +1,34 @@ + + + + + CLIENT_ID + 755380116666-if5jvrpuk5hja4qtlqoaa5eil2nlhmaa.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.755380116666-if5jvrpuk5hja4qtlqoaa5eil2nlhmaa + API_KEY + AIzaSyDwfpfZYu7h93Ze4XfU00EdYA-b2Tr39Kk + GCM_SENDER_ID + 755380116666 + PLIST_VERSION + 1 + BUNDLE_ID + com.swciitg.onestop2swc2022 + PROJECT_ID + onestopiitg-2 + STORAGE_BUCKET + onestopiitg-2.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:755380116666:ios:2fde1264d6300380e2f683 + + \ No newline at end of file diff --git a/ios/firebase_app_id_file.json b/ios/firebase_app_id_file.json new file mode 100644 index 00000000..afae3c1b --- /dev/null +++ b/ios/firebase_app_id_file.json @@ -0,0 +1,7 @@ +{ + "file_generated_by": "FlutterFire CLI", + "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", + "GOOGLE_APP_ID": "1:755380116666:ios:2fde1264d6300380e2f683", + "FIREBASE_PROJECT_ID": "onestopiitg-2", + "GCM_SENDER_ID": "755380116666" +} \ No newline at end of file diff --git a/lib/firebase_options.dart b/lib/firebase_options.dart new file mode 100644 index 00000000..02293bc0 --- /dev/null +++ b/lib/firebase_options.dart @@ -0,0 +1,69 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for web - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyBsoG-Xp8P2FGth4pE38cUyT2ljSjrAfLE', + appId: '1:755380116666:android:93baf948818388bfe2f683', + messagingSenderId: '755380116666', + projectId: 'onestopiitg-2', + storageBucket: 'onestopiitg-2.appspot.com', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'AIzaSyDwfpfZYu7h93Ze4XfU00EdYA-b2Tr39Kk', + appId: '1:755380116666:ios:2fde1264d6300380e2f683', + messagingSenderId: '755380116666', + projectId: 'onestopiitg-2', + storageBucket: 'onestopiitg-2.appspot.com', + iosClientId: '755380116666-if5jvrpuk5hja4qtlqoaa5eil2nlhmaa.apps.googleusercontent.com', + iosBundleId: 'com.swciitg.onestop2swc2022', + ); +} From 99edb00a758ad756b5ffef0d68c31ed3e78f3d76 Mon Sep 17 00:00:00 2001 From: Priyanshu Srivastava Date: Tue, 21 Mar 2023 23:57:57 +0530 Subject: [PATCH 18/82] notif --- lib/main.dart | 3 +++ lib/services/api.dart | 20 ++++++++++++++++++++ lib/services/notifications_provider.dart | 9 +++++---- pubspec.yaml | 8 ++++---- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index bb5215c4..37840929 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,6 +6,7 @@ import 'package:flutter/services.dart'; import 'package:onestop_dev/functions/utility/check_last_updated.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/routes.dart'; +import 'package:onestop_dev/services/api.dart'; import 'package:onestop_dev/services/notifications_provider.dart'; import 'package:onestop_dev/stores/common_store.dart'; import 'package:onestop_dev/stores/login_store.dart'; @@ -24,6 +25,8 @@ void main() async { await checkForNotifications(); final fcmToken = await FirebaseMessaging.instance.getToken(); print("FCM Token is $fcmToken"); + + await APIService.createUser(fcmToken ?? ''); FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); runApp(const MyApp()); } diff --git a/lib/services/api.dart b/lib/services/api.dart index a66d3494..1bcc8c2c 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -9,6 +9,7 @@ import 'package:onestop_dev/models/lostfound/lost_model.dart'; import 'package:onestop_dev/models/timetable/registered_courses.dart'; import 'package:onestop_dev/models/buy_sell/sell_model.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class APIService { static const String _restaurantURL = @@ -504,4 +505,23 @@ class APIService { return null; } } + + static Future createUser(String token) async { + final prefs = await SharedPreferences.getInstance(); + final res = await http.post( + Uri.parse('https://d248-14-139-196-16.in.ngrok.io/onestopapi/v2/onestop-user'), + body: jsonEncode( + { + "name": prefs.getString('name'), + "email": prefs.getString('email'), + "deviceToken": token + }, + ), + headers: { + 'Content-Type': 'application/json', + 'security-key': apiSecurityKey + }, + ); + + } } diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart index 44aa3bec..f1a04167 100644 --- a/lib/services/notifications_provider.dart +++ b/lib/services/notifications_provider.dart @@ -63,10 +63,11 @@ void onDidReceiveNotificationResponse( bool checkNotificationCategory(String type) { switch (type) { - case "Lost": - case "Found": - case "Buy": - case "Sell": + case "lost": + case "found": + case "buy": + case "sell": + case "travel": return true; } return false; diff --git a/pubspec.yaml b/pubspec.yaml index d8a1054c..e0105c80 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -61,7 +61,7 @@ dependencies: flutter_mobx: ^2.0.5 add_2_calendar: ^2.1.3 timeago: ^3.2.2 - get: 4.6.1 + get: ^4.6.5 map_launcher: ^2.3.0+1 json_annotation: ^4.7.0 sembast: ^3.2.0 @@ -72,10 +72,10 @@ dependencies: path_provider: ^2.0.11 path: ^1.8.0 infinite_scroll_pagination: ^3.2.0 - upgrader: ^5.1.0 + upgrader: ^6.2.0 badges: ^2.0.3 firebase_messaging: ^14.1.3 - flutter_local_notifications: ^11.0.1 + flutter_local_notifications: ^13.0.0 firebase_core: ^2.3.0 dev_dependencies: @@ -85,7 +85,7 @@ dev_dependencies: build_runner: ^2.1.10 mobx_codegen: ^2.0.5+2 json_serializable: ^6.2.0 - flutter_launcher_icons: ^0.10.0 + flutter_launcher_icons: ^0.12.0 flutter_lints: ^2.0.1 dependency_validator: ^3.2.2 change_app_package_name: ^1.1.0 From 1453b9d26a4e50cf65005959e5bffa4c830a7b09 Mon Sep 17 00:00:00 2001 From: Priyanshu Srivastava Date: Wed, 22 Mar 2023 00:22:50 +0530 Subject: [PATCH 19/82] notif --- lib/services/api.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/api.dart b/lib/services/api.dart index 1bcc8c2c..e480fd04 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -509,7 +509,7 @@ class APIService { static Future createUser(String token) async { final prefs = await SharedPreferences.getInstance(); final res = await http.post( - Uri.parse('https://d248-14-139-196-16.in.ngrok.io/onestopapi/v2/onestop-user'), + Uri.parse('https://swc.iitg.ac.in/onestopapi/v2/onestop-user'), body: jsonEncode( { "name": prefs.getString('name'), From 75ff89956c1d33eae5153666efe5a1452cce07f0 Mon Sep 17 00:00:00 2001 From: Vignesh Rao Date: Sat, 25 Mar 2023 00:31:52 +0530 Subject: [PATCH 20/82] Add notification tile --- lib/main.dart | 4 +- lib/pages/notifications/notifications.dart | 4 +- lib/services/notifications_provider.dart | 3 +- lib/widgets/ui/notification_tile.dart | 107 +++++++++++++++++++++ 4 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 lib/widgets/ui/notification_tile.dart diff --git a/lib/main.dart b/lib/main.dart index 37840929..baf23747 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -14,9 +14,11 @@ import 'package:onestop_dev/stores/mapbox_store.dart'; import 'package:onestop_dev/stores/restaurant_store.dart'; import 'package:provider/provider.dart'; +import 'firebase_options.dart'; + void main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp(); + await Firebase.initializeApp(options:DefaultFirebaseOptions.currentPlatform); SystemChrome.setPreferredOrientations( [DeviceOrientation.portraitDown, DeviceOrientation.portraitUp]); SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, diff --git a/lib/pages/notifications/notifications.dart b/lib/pages/notifications/notifications.dart index 6ca1f4e7..a89e8288 100644 --- a/lib/pages/notifications/notifications.dart +++ b/lib/pages/notifications/notifications.dart @@ -8,13 +8,11 @@ import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; import 'package:shared_preferences/shared_preferences.dart'; class NotifsModel { - String? hashcode; String? title; String? body; bool read; NotifsModel( - this.hashcode, this.title, this.body, this.read, @@ -41,7 +39,7 @@ class _NotificationPageState extends State { Map notifData = jsonDecode(r); print("Notif Data = $notifData"); n.add(NotifsModel( - null, notifData['header'], notifData['body'], notifData['read'])); + notifData['header'], notifData['body'], notifData['read'])); // Set Read Recipient to True and then save to prefs notifData['read'] = true; newNotifList.add(jsonEncode(notifData)); diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart index f1a04167..773fb472 100644 --- a/lib/services/notifications_provider.dart +++ b/lib/services/notifications_provider.dart @@ -62,7 +62,7 @@ void onDidReceiveNotificationResponse( } bool checkNotificationCategory(String type) { - switch (type) { + switch (type.toLowerCase()) { case "lost": case "found": case "buy": @@ -117,6 +117,7 @@ Future checkForNotifications() async { ); FirebaseMessaging.onMessage.listen((RemoteMessage message) async { + print("Here me"); AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails(channel.id, channel.name, channelDescription: channel.description, diff --git a/lib/widgets/ui/notification_tile.dart b/lib/widgets/ui/notification_tile.dart new file mode 100644 index 00000000..e7400bdc --- /dev/null +++ b/lib/widgets/ui/notification_tile.dart @@ -0,0 +1,107 @@ + +import 'package:fluentui_system_icons/fluentui_system_icons.dart'; +import 'package:flutter/material.dart'; +import 'package:onestop_dev/globals/my_colors.dart'; +import 'package:onestop_dev/globals/my_fonts.dart'; + +class NotificationTile extends StatelessWidget { + const NotificationTile({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: kTimetableGreen, + borderRadius: BorderRadius.circular(25), + // color: kTimetableGreen, + // border: showHighlight + // ? Border.all(color: Colors.blueAccent) + // : Border.all(color: Colors.transparent), + // ) + ), + child: Padding( + padding: const EdgeInsets.only( + top: 10.0, bottom: 10, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only( + left: 20.0, right: 20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + height: 50, + width: 50, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: kGreen, + ), + child: Icon( + FluentIcons.vehicle_car_24_filled, + color: kAppBarGrey, + size: 25, + ), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + // Text( + // 'Text1', + // style: + // MyFonts.w300.size(12).setColor(kWhite), + // ), + const SizedBox( + height: 5.0, + ), + Text( + 'Cab Sharing', + style: + MyFonts.w500.size(15).setColor(kWhite), + ), + const SizedBox( + height: 3.0, + ), + Text( + 'A new reply to your cab sharing post. Check it out now and book together', + style: + MyFonts.w400.size(13).setColor(lBlue), + ), + const SizedBox( + height: 3.0, + ), + ], + ), + ), + Expanded( + child: Container( + decoration: BoxDecoration( + color: lBlue2, + borderRadius: BorderRadius.circular(25), + // color: kTimetableGreen, + // border: showHighlight + // ? Border.all(color: Colors.blueAccent) + // : Border.all(color: Colors.transparent), + // ) + ), + padding: EdgeInsets.all(5), + // color: lBlue2, + child: Center(child: Text('12 new', style: MyFonts.w600.setColor(kAppBarGrey),)), + ), + ) + ], + ), + ), + ); + } +} From bb9177b88d45fb2841817d7f6f755298a12dcd75 Mon Sep 17 00:00:00 2001 From: Vignesh Rao Date: Sun, 26 Mar 2023 03:47:32 +0530 Subject: [PATCH 21/82] Modify notification UI --- lib/globals/my_colors.dart | 1 + lib/pages/notifications/notifications.dart | 76 +++++++---------- lib/services/notifications_provider.dart | 12 +-- lib/widgets/ui/notification_tile.dart | 98 ++++++++++++---------- 4 files changed, 94 insertions(+), 93 deletions(-) diff --git a/lib/globals/my_colors.dart b/lib/globals/my_colors.dart index 2d5e6c76..5aa20aa4 100644 --- a/lib/globals/my_colors.dart +++ b/lib/globals/my_colors.dart @@ -42,3 +42,4 @@ const Color kGrey14 = Color.fromRGBO(41, 45, 53, 1); const Color kGreen = Color.fromRGBO(124, 198, 154, 1); const Color kBadgeColor = Color.fromRGBO(255, 201, 7, 1); const Color kTimetableDisabled = Color.fromRGBO(120, 120, 120, 0.16); +const Color kGreenDisabled = Color.fromRGBO(124, 198, 154, 0.5); \ No newline at end of file diff --git a/lib/pages/notifications/notifications.dart b/lib/pages/notifications/notifications.dart index a89e8288..eaf88547 100644 --- a/lib/pages/notifications/notifications.dart +++ b/lib/pages/notifications/notifications.dart @@ -5,17 +5,24 @@ import 'package:flutter/material.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; +import 'package:onestop_dev/widgets/ui/notification_tile.dart'; import 'package:shared_preferences/shared_preferences.dart'; class NotifsModel { String? title; String? body; + String category; bool read; + DateTime time; + String messageId; NotifsModel( this.title, this.body, this.read, + this.category, + this.time, + this.messageId ); } @@ -38,8 +45,8 @@ class _NotificationPageState extends State { for (String r in result) { Map notifData = jsonDecode(r); print("Notif Data = $notifData"); - n.add(NotifsModel( - notifData['header'], notifData['body'], notifData['read'])); + n.add(NotifsModel(notifData['header'], notifData['body'], + notifData['read'], notifData['category'], DateTime.parse(notifData['time']), notifData['messageId'])); // Set Read Recipient to True and then save to prefs notifData['read'] = true; newNotifList.add(jsonEncode(notifData)); @@ -106,51 +113,23 @@ class _NotificationPageState extends State { ), ); } - return ListView.builder( - itemCount: snapshot.data!.length, - itemBuilder: (context, index) { - return Padding( - padding: const EdgeInsets.all(20.0), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Icon( - getIcon(snapshot.data![index].read), - color: kBlue, - ), - const SizedBox( - width: 10, - ), - Text( - snapshot.data![index].title ?? " ", - style: MyFonts.w400.setColor(kWhite), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ], - ), - Row(children: [ - Icon( - getIcon(snapshot.data![index].read), - color: Colors.transparent, - ), - const SizedBox( - width: 10, - ), - Text( - 'Description', - style: MyFonts.w300.setColor(kWhite), - ) - ]) - ], - ), - ); - }, + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: ListView.builder( + itemCount: snapshot.data!.length, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 4.0), + child: NotificationTile( + notifModel: snapshot.data![index], + ), + ); + }, + ), ); } - return Column( + if (snapshot.connectionState == ConnectionState.waiting) { + return Column( children: [ const SizedBox( height: 10, @@ -161,6 +140,13 @@ class _NotificationPageState extends State { )), ], ); + } + return Center( + child: Text( + 'No notifications found', + style: MyFonts.w300.setColor(kWhite), + ), + ); }), ); } diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart index 773fb472..92eb5818 100644 --- a/lib/services/notifications_provider.dart +++ b/lib/services/notifications_provider.dart @@ -48,7 +48,7 @@ Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { notificationDetails, ); } - saveNotification(message.data, message.sentTime); + saveNotification(message); } @pragma('vm:entry-point') @@ -143,7 +143,7 @@ Future checkForNotifications() async { notificationDetails, ); } - saveNotification(message.data, message.sentTime); + saveNotification(message); }); // Resave list of notifications in case it's initialized to null @@ -154,11 +154,13 @@ Future checkForNotifications() async { return true; } -void saveNotification( - Map notificationData, DateTime? sentTime) async { - final SharedPreferences preferences = await SharedPreferences.getInstance(); +void saveNotification(RemoteMessage message) async { + Map notificationData = message.data; + DateTime sentTime = message.sentTime ?? DateTime.now(); +final SharedPreferences preferences = await SharedPreferences.getInstance(); notificationData['time'] = sentTime?.toString() ?? DateTime.now().toString(); notificationData['read'] = false; + notificationData['messageId'] = message.messageId; String notifJson = jsonEncode(notificationData); print("data = $notificationData"); List notifications = preferences.getStringList('notifications') ?? []; diff --git a/lib/widgets/ui/notification_tile.dart b/lib/widgets/ui/notification_tile.dart index e7400bdc..fd27126e 100644 --- a/lib/widgets/ui/notification_tile.dart +++ b/lib/widgets/ui/notification_tile.dart @@ -1,47 +1,60 @@ - import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; +import 'package:onestop_dev/pages/notifications/notifications.dart'; class NotificationTile extends StatelessWidget { - const NotificationTile({ - Key? key, - }) : super(key: key); + const NotificationTile({Key? key, required this.notifModel}) + : super(key: key); + + final NotifsModel notifModel; + + IconData get notificationIcon { + switch (notifModel.category.toLowerCase()) { + case "lost": + case "found": + return FluentIcons.document_search_24_filled; + case "buy": + case "sell": + return FluentIcons.money_24_filled; + case "travel": + return FluentIcons.vehicle_car_24_filled; + } + return FluentIcons.checkbox_1_20_filled; + } @override Widget build(BuildContext context) { + var iconColor = notifModel.read ? kGreenDisabled : kGreen ; + var titleColor = notifModel.read ? kGrey2 : kWhite; + var bodyColor = notifModel.read ? kGrey2 : lBlue; + var tileBg = notifModel.read ? kTimetableDisabled : kTimetableGreen; return Container( decoration: BoxDecoration( - color: kTimetableGreen, + color: tileBg, borderRadius: BorderRadius.circular(25), - // color: kTimetableGreen, - // border: showHighlight - // ? Border.all(color: Colors.blueAccent) - // : Border.all(color: Colors.transparent), - // ) ), child: Padding( - padding: const EdgeInsets.only( - top: 10.0, bottom: 10, right: 10), + padding: const EdgeInsets.only(top: 10.0, bottom: 10, right: 10), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Padding( - padding: const EdgeInsets.only( - left: 20.0, right: 20.0), + padding: const EdgeInsets.only(left: 20.0, right: 20.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( height: 50, width: 50, - decoration: const BoxDecoration( + decoration: BoxDecoration( shape: BoxShape.circle, - color: kGreen, + color: iconColor, ), child: Icon( - FluentIcons.vehicle_car_24_filled, + notificationIcon, color: kAppBarGrey, size: 25, ), @@ -53,29 +66,21 @@ class NotificationTile extends StatelessWidget { flex: 3, child: Column( crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - // Text( - // 'Text1', - // style: - // MyFonts.w300.size(12).setColor(kWhite), - // ), const SizedBox( height: 5.0, ), Text( - 'Cab Sharing', - style: - MyFonts.w500.size(15).setColor(kWhite), + notifModel.title!, + style: MyFonts.w500.size(15).setColor(titleColor), ), const SizedBox( height: 3.0, ), Text( - 'A new reply to your cab sharing post. Check it out now and book together', - style: - MyFonts.w400.size(13).setColor(lBlue), + notifModel.body!, + style: MyFonts.w400.size(13).setColor(bodyColor), ), const SizedBox( height: 3.0, @@ -83,21 +88,28 @@ class NotificationTile extends StatelessWidget { ], ), ), + SizedBox( + width: 5, + ), Expanded( - child: Container( - decoration: BoxDecoration( - color: lBlue2, - borderRadius: BorderRadius.circular(25), - // color: kTimetableGreen, - // border: showHighlight - // ? Border.all(color: Colors.blueAccent) - // : Border.all(color: Colors.transparent), - // ) - ), - padding: EdgeInsets.all(5), - // color: lBlue2, - child: Center(child: Text('12 new', style: MyFonts.w600.setColor(kAppBarGrey),)), + child: Text( + DateFormat.MMMMd().format(notifModel.time), + style: MyFonts.w400.setColor(bodyColor), ), + // child: Container( + // decoration: BoxDecoration( + // color: lBlue2, + // borderRadius: BorderRadius.circular(25), + // // color: kTimetableGreen, + // // border: showHighlight + // // ? Border.all(color: Colors.blueAccent) + // // : Border.all(color: Colors.transparent), + // // ) + // ), + // padding: EdgeInsets.all(5), + // // color: lBlue2, + // child: Center(child: Text('12 new', style: MyFonts.w600.setColor(kAppBarGrey),)), + // ), ) ], ), From 1fe11078a0708efba4f5d9d8b68fcd9155d11ebc Mon Sep 17 00:00:00 2001 From: Hareesh-Nandigrama Date: Tue, 4 Apr 2023 02:25:57 +0530 Subject: [PATCH 22/82] fixed ios errors --- ios/Runner.xcodeproj/project.pbxproj | 23 ++++++++++++++--------- ios/Runner/AppDelegate.swift | 4 +++- ios/Runner/Info.plist | 9 +++++++-- ios/Runner/Runner.entitlements | 8 ++++++++ 4 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 ios/Runner/Runner.entitlements diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 2b5de75b..9379c594 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -49,6 +49,7 @@ 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 9822E429D96AFE0F8D730785 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; C05463DD6012FC0ED5AB6BC0 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + D800439E29DB5F970022C839 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -115,6 +116,7 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( + D800439E29DB5F970022C839 /* Runner.entitlements */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, @@ -378,8 +380,9 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 7T8XRG7HU9; ENABLE_BITCODE = NO; @@ -390,7 +393,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.swciitg.onestop2swc2022; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "OneStop AdHoc Profile"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -510,8 +513,9 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 7T8XRG7HU9; ENABLE_BITCODE = NO; @@ -522,7 +526,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.swciitg.onestop2swc2022; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "OneStop AdHoc Profile"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -536,8 +540,9 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 7T8XRG7HU9; ENABLE_BITCODE = NO; @@ -548,7 +553,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.swciitg.onestop2swc2022; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "OneStop AdHoc Profile"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 16614976..7473d1f9 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -1,12 +1,14 @@ import UIKit import Flutter import GoogleMaps +import flutter_local_notifications + @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any] ? + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { if #available(iOS 10.0, *) { UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 10967e83..d43565b1 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -58,6 +58,13 @@ This app needs access to location to show you the nearest bus stops, ferry ghats, restaurants etc. NSPhotoLibraryUsageDescription This app requires Photo Library access for Lost/Found or Buy/Sell images + UIApplicationSupportsIndirectInputEvents + + UIBackgroundModes + + fetch + remote-notification + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -77,7 +84,5 @@ UIViewControllerBasedStatusBarAppearance - UIApplicationSupportsIndirectInputEvents - diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements new file mode 100644 index 00000000..903def2a --- /dev/null +++ b/ios/Runner/Runner.entitlements @@ -0,0 +1,8 @@ + + + + + aps-environment + development + + From 6f757af8c16620d7d45d840d00d162f030be8886 Mon Sep 17 00:00:00 2001 From: Hareesh-Nandigrama Date: Tue, 4 Apr 2023 02:29:32 +0530 Subject: [PATCH 23/82] fixed ios errors --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 2bb9289e..f9452f32 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -47,7 +47,7 @@ dependencies: cookie_jar: 3.0.1 provider: ^6.0.2 http: ^0.13.4 - dio: ^4.0.6 + dio: ^5.0.3 file_picker: ^5.2.5 shared_preferences: ^2.0.12 barcode_widget: ^2.0.3 From dbb575ca887aa0d63c2c74fb11a3d3b942547810 Mon Sep 17 00:00:00 2001 From: Hareesh-Nandigrama Date: Tue, 4 Apr 2023 04:40:17 +0530 Subject: [PATCH 24/82] Update pubsoec version --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index f9452f32..55dcd80d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.3.3+25 +version: 1.4.0+26 environment: sdk: ">=2.15.1 <3.0.0" From 1f2512ea2121c3a90b0f0c61d83bd91e2bff20fe Mon Sep 17 00:00:00 2001 From: Vignesh Rao Date: Thu, 6 Apr 2023 00:55:34 +0530 Subject: [PATCH 25/82] Badge on notification in appbar --- .../notifications/get_notifications.dart | 27 ++++++++++++ lib/pages/notifications/notifications.dart | 23 +--------- lib/widgets/ui/appbar.dart | 43 +++++++++++++------ 3 files changed, 60 insertions(+), 33 deletions(-) create mode 100644 lib/functions/notifications/get_notifications.dart diff --git a/lib/functions/notifications/get_notifications.dart b/lib/functions/notifications/get_notifications.dart new file mode 100644 index 00000000..90d3caf6 --- /dev/null +++ b/lib/functions/notifications/get_notifications.dart @@ -0,0 +1,27 @@ +import 'dart:convert'; + +import 'package:onestop_dev/pages/notifications/notifications.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +Future> getSavedNotifications(bool changeReadStatus) async { + List n = []; + List newNotifList = []; + n.clear(); + final SharedPreferences prefs = await SharedPreferences.getInstance(); + await prefs.reload(); + List result = prefs.getStringList('notifications')!; + for (String r in result) { + Map notifData = jsonDecode(r); + print("Notif Data = $notifData"); + n.add(NotifsModel(notifData['header'], notifData['body'], + notifData['read'], notifData['category'], DateTime.parse(notifData['time']), notifData['messageId'])); + if (changeReadStatus) { + // Set Read Recipient to True and then save to prefs + notifData['read'] = true; + } + newNotifList.add(jsonEncode(notifData)); + } + + prefs.setStringList('notifications', newNotifList); + return n.reversed.toList(); +} diff --git a/lib/pages/notifications/notifications.dart b/lib/pages/notifications/notifications.dart index eaf88547..89a98d32 100644 --- a/lib/pages/notifications/notifications.dart +++ b/lib/pages/notifications/notifications.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; +import 'package:onestop_dev/functions/notifications/get_notifications.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; @@ -35,26 +36,6 @@ class NotificationPage extends StatefulWidget { } class _NotificationPageState extends State { - Future> getDetails() async { - List n = []; - List newNotifList = []; - n.clear(); - final SharedPreferences prefs = await SharedPreferences.getInstance(); - await prefs.reload(); - List result = prefs.getStringList('notifications')!; - for (String r in result) { - Map notifData = jsonDecode(r); - print("Notif Data = $notifData"); - n.add(NotifsModel(notifData['header'], notifData['body'], - notifData['read'], notifData['category'], DateTime.parse(notifData['time']), notifData['messageId'])); - // Set Read Recipient to True and then save to prefs - notifData['read'] = true; - newNotifList.add(jsonEncode(notifData)); - } - - prefs.setStringList('notifications', newNotifList); - return n.reversed.toList(); - } IconData getIcon(bool readNotif) { if (!readNotif) { @@ -102,7 +83,7 @@ class _NotificationPageState extends State { ), ), body: FutureBuilder>( - future: getDetails(), + future: getSavedNotifications(true), builder: (context, snapshot) { if (snapshot.hasData) { if (snapshot.data!.isEmpty) { diff --git a/lib/widgets/ui/appbar.dart b/lib/widgets/ui/appbar.dart index 4f81f48a..f3ea0b1b 100644 --- a/lib/widgets/ui/appbar.dart +++ b/lib/widgets/ui/appbar.dart @@ -1,9 +1,11 @@ import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; +import 'package:onestop_dev/functions/notifications/get_notifications.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/pages/notifications/notifications.dart'; import 'package:onestop_dev/pages/profile.dart'; +import 'package:badges/badges.dart' as badges; AppBar appBar(BuildContext context, {bool displayIcon = true}) { return AppBar( @@ -65,18 +67,35 @@ AppBar appBar(BuildContext context, {bool displayIcon = true}) { ]), // textAlign: TextAlign.start, ), - CircleAvatar( - backgroundColor: kAppBarGrey, - child: IconButton( - onPressed: () { - Navigator.pushNamed(context, NotificationPage.id); - }, - icon: const Icon( - FluentIcons.alert_24_filled, - color: lBlue2, - ), - color: lBlue2, - )), + FutureBuilder>( + future: getSavedNotifications(false), + builder: (context,snapshot) { + var badgeColor = Colors.transparent; + if (snapshot.hasData) { + int unread = snapshot.data!.where((element) => element.read == false).length; + if (unread > 0) { + badgeColor = kYellow; + } + } + return CircleAvatar( + backgroundColor: kAppBarGrey, + child: IconButton( + onPressed: () { + Navigator.pushNamed(context, NotificationPage.id); + }, + icon: badges.Badge( + badgeColor: badgeColor, + elevation: 0, + position: badges.BadgePosition.topStart(), + child: const Icon( + FluentIcons.alert_24_filled, + color: lBlue2, + ), + ), + color: lBlue2, + )); + } + ), ], ), elevation: 0.0, From 02643c96afb3c8800f88077bec67b0139307c09f Mon Sep 17 00:00:00 2001 From: Priyanshu Srivastava Date: Sat, 15 Apr 2023 18:49:38 +0530 Subject: [PATCH 26/82] added timings --- lib/globals/endpoints.dart | 39 +++ lib/models/timetable/bus_timing_model.dart | 37 +++ lib/models/timetable/ferry_timing_model.dart | 38 +++ lib/services/api.dart | 261 ++++++++----------- pubspec.yaml | 2 +- 5 files changed, 226 insertions(+), 151 deletions(-) create mode 100644 lib/globals/endpoints.dart create mode 100644 lib/models/timetable/bus_timing_model.dart create mode 100644 lib/models/timetable/ferry_timing_model.dart diff --git a/lib/globals/endpoints.dart b/lib/globals/endpoints.dart new file mode 100644 index 00000000..bd5413f1 --- /dev/null +++ b/lib/globals/endpoints.dart @@ -0,0 +1,39 @@ +class Endpoints { + static const baseUrl = 'https://swc.iitg.ac.in'; + static const String restaurantURL = "$baseUrl/onestopapi/v2/getAllOutlets"; + static const String lastUpdatedURL = "$baseUrl/onestopapi/v2/lastDataUpdate"; + static const String contactURL = "$baseUrl/onestopapi/v2/getContacts"; + static const String timetableURL = "$baseUrl/smartTimetable/get-my-courses"; + static const String ferryURL = '$baseUrl/onestopapi/v2/ferryTimings'; + static const String busURL = '$baseUrl/onestopapi/v2/busTimings'; + static const String busStops = '$baseUrl/onestopapi/v2/busstops'; + static const String messURL = "$baseUrl/onestopapi/v2/hostelsMessMenu"; + static const String buyURL = '$baseUrl/onestopapi/v2/buy'; + static const String sellURL = '$baseUrl/onestopapi/v2/sell'; + static const String sellPath = '/onestopapi/v2/sellPage'; + static const String buyPath = '/onestopapi/v2/buyPage'; + static const String bnsMyAdsURL = '$baseUrl/onestopapi/v2/bns/myads'; + static const String lnfMyAdsURL = '$baseUrl/onestopapi/v2/lnf/myads'; + static const String deleteBuyURL = "$baseUrl/onestopapi/v2/buy/remove"; + static const String deleteSellURL = "$baseUrl/onestopapi/v2/sell/remove"; + static const String deleteLostURL = "$baseUrl/onestopapi/v2/lost/remove"; + static const String deleteFoundURL = "$baseUrl/onestopapi/v2/found/remove"; + static const String lostURL = '$baseUrl/onestopapi/v2/lost'; + static const String lostPath = '/onestopapi/v2/lostPage'; + static const String foundPath = '/onestopapi/v2/foundPage'; + static const String foundURL = '$baseUrl/onestopapi/v2/found'; + static const String claimItemURL = "$baseUrl/onestopapi/v2/found/claim"; + static const String newsURL = "$baseUrl/onestopapi/v2/news"; + static const String githubIssueToken = + String.fromEnvironment('GITHUB_ISSUE_TOKEN'); + static const apiSecurityKey = String.fromEnvironment('SECURITY-KEY'); + static const feedback = + 'https://api.github.com/repos/vrrao01/onestop_dev/issues'; + static const String upspPost = '$baseUrl/onestopapi/v2/upsp/submit-request'; + static const String uploadFileUPSP = + "$baseUrl/onestopapi/v2/upsp/file-upload"; + + static getHeader() { + return {'Content-Type': 'application/json', 'security-key': apiSecurityKey}; + } +} diff --git a/lib/models/timetable/bus_timing_model.dart b/lib/models/timetable/bus_timing_model.dart new file mode 100644 index 00000000..0b80b4dc --- /dev/null +++ b/lib/models/timetable/bus_timing_model.dart @@ -0,0 +1,37 @@ +import 'dart:convert'; + +BusTiming busTimingFromJson(String str) => BusTiming.fromJson(json.decode(str)); + +String busTimingToJson(BusTiming data) => json.encode(data.toJson()); + +class BusTiming { + BusTiming({ + required this.busTiming, + required this.weekdaysCampusToCity, + required this.weekdaysCityToCampus, + required this.weekendCityToCampus, + required this.weekendCampusToCity, + }); + + String busTiming; + DateTime weekdaysCampusToCity; + DateTime weekdaysCityToCampus; + DateTime weekendCityToCampus; + DateTime weekendCampusToCity; + + factory BusTiming.fromJson(Map json) => BusTiming( + busTiming: json["busTiming"], + weekdaysCampusToCity: json["weekdays_campusToCity"], + weekdaysCityToCampus: json["weekdays_cityToCampus"], + weekendCityToCampus: json["weekend_cityToCampus"], + weekendCampusToCity: json["weekend_campusToCity"], + ); + + Map toJson() => { + "busTiming": busTiming, + "weekdays_campusToCity": weekdaysCampusToCity, + "weekdays_cityToCampus": weekdaysCityToCampus, + "weekend_cityToCampus": weekendCityToCampus, + "weekend_campusToCity": weekendCampusToCity, + }; +} diff --git a/lib/models/timetable/ferry_timing_model.dart b/lib/models/timetable/ferry_timing_model.dart new file mode 100644 index 00000000..9b5f5624 --- /dev/null +++ b/lib/models/timetable/ferry_timing_model.dart @@ -0,0 +1,38 @@ +import 'dart:convert'; + +FerryTiming ferryTimingFromJson(String str) => + FerryTiming.fromJson(json.decode(str)); + +String ferryTimingToJson(FerryTiming data) => json.encode(data.toJson()); + +class FerryTiming { + FerryTiming({ + required this.ferryGhat, + required this.weekdaysCampusToCity, + required this.weekdaysCityToCampus, + required this.weekendCityToCampus, + required this.weekendCampusToCity, + }); + + String ferryGhat; + DateTime weekdaysCampusToCity; + DateTime weekdaysCityToCampus; + DateTime weekendCityToCampus; + DateTime weekendCampusToCity; + + factory FerryTiming.fromJson(Map json) => FerryTiming( + ferryGhat: json["ferryGhat"], + weekdaysCampusToCity: json["weekdays_campusToCity"], + weekdaysCityToCampus: json["weekdays_cityToCampus"], + weekendCityToCampus: json["weekend_cityToCampus"], + weekendCampusToCity: json["weekend_campusToCity"], + ); + + Map toJson() => { + "ferryGhat": ferryGhat, + "weekdays_campusToCity": weekdaysCampusToCity, + "weekdays_cityToCampus": weekdaysCityToCampus, + "weekend_cityToCampus": weekendCityToCampus, + "weekend_campusToCity": weekendCampusToCity, + }; +} diff --git a/lib/services/api.dart b/lib/services/api.dart index a66d3494..126a5929 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -3,66 +3,22 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:http/http.dart' as http; +import 'package:onestop_dev/globals/endpoints.dart'; import 'package:onestop_dev/models/buy_sell/buy_model.dart'; import 'package:onestop_dev/models/lostfound/found_model.dart'; import 'package:onestop_dev/models/lostfound/lost_model.dart'; +import 'package:onestop_dev/models/timetable/bus_timing_model.dart'; +import 'package:onestop_dev/models/timetable/ferry_timing_model.dart'; import 'package:onestop_dev/models/timetable/registered_courses.dart'; import 'package:onestop_dev/models/buy_sell/sell_model.dart'; class APIService { - static const String _restaurantURL = - "https://swc.iitg.ac.in/onestopapi/v2/getAllOutlets"; - static const String _lastUpdatedURL = - "https://swc.iitg.ac.in/onestopapi/v2/lastDataUpdate"; - static const String _contactURL = - "https://swc.iitg.ac.in/onestopapi/v2/getContacts"; - static const String _timetableURL = - "https://swc.iitg.ac.in/smartTimetable/get-my-courses"; - static const String _ferryURL = - 'https://swc.iitg.ac.in/onestopapi/v2/ferryTimings'; - static const String _busURL = - 'https://swc.iitg.ac.in/onestopapi/v2/busTimings'; - static const String _messURL = - "https://swc.iitg.ac.in/onestopapi/v2/hostelsMessMenu"; - static const String _buyURL = 'https://swc.iitg.ac.in/onestopapi/v2/buy'; - static const String _sellURL = 'https://swc.iitg.ac.in/onestopapi/v2/sell'; - static const String _sellPath = '/onestopapi/v2/sellPage'; - static const String _buyPath = '/onestopapi/v2/buyPage'; - static const String _bnsMyAdsURL = - 'https://swc.iitg.ac.in/onestopapi/v2/bns/myads'; - static const String _lnfMyAdsURL = - 'https://swc.iitg.ac.in/onestopapi/v2/lnf/myads'; - static const String _deleteBuyURL = - "https://swc.iitg.ac.in/onestopapi/v2/buy/remove"; - static const String _deleteSellURL = - "https://swc.iitg.ac.in/onestopapi/v2/sell/remove"; - static const String _deleteLostURL = - "https://swc.iitg.ac.in/onestopapi/v2/lost/remove"; - static const String _deleteFoundURL = - "https://swc.iitg.ac.in/onestopapi/v2/found/remove"; - static const String _lostURL = 'https://swc.iitg.ac.in/onestopapi/v2/lost'; - static const String _lostPath = '/onestopapi/v2/lostPage'; - static const String _foundPath = '/onestopapi/v2/foundPage'; - static const String _foundURL = 'https://swc.iitg.ac.in/onestopapi/v2/found'; - static const String _claimItemURL = - "https://swc.iitg.ac.in/onestopapi/v2/found/claim"; - static const String _newsURL = "https://swc.iitg.ac.in/onestopapi/v2/news"; - static const String githubIssueToken = - String.fromEnvironment('GITHUB_ISSUE_TOKEN'); - static const apiSecurityKey = String.fromEnvironment('SECURITY-KEY'); - static const _feedback = - 'https://api.github.com/repos/vrrao01/onestop_dev/issues'; - static const String _upspPost = - 'https://swc.iitg.ac.in/onestopapi/v2/upsp/submit-request'; - static const String _uploadFileUPSP = - "https://swc.iitg.ac.in/onestopapi/v2/upsp/file-upload"; - static Future postFeedbackData(Map data) async { String tag = data['type'] == 'Issue Report' ? 'bug' : 'enhancement'; String newBody = "### Description :\n${data['body']}\n### Posted By :\n${data['user']}"; - var res = await http.post(Uri.parse(_feedback), + var res = await http.post(Uri.parse(Endpoints.feedback), body: jsonEncode({ 'title': data['title'], 'body': newBody, @@ -70,7 +26,7 @@ class APIService { }), headers: { 'Accept': 'application/vnd.github+json', - 'Authorization': 'Bearer $githubIssueToken' + 'Authorization': 'Bearer ${Endpoints.githubIssueToken}' }); if (res.statusCode == 201) { return true; @@ -79,7 +35,7 @@ class APIService { } static Future>> getRestaurantData() async { - http.Response response = await http.get(Uri.parse(_restaurantURL)); + http.Response response = await http.get(Uri.parse(Endpoints.restaurantURL)); var status = response.statusCode; var body = jsonDecode(response.body); if (status == 200) { @@ -94,7 +50,7 @@ class APIService { } static Future>> getNewsData() async { - http.Response response = await http.get(Uri.parse(_newsURL)); + http.Response response = await http.get(Uri.parse(Endpoints.newsURL)); var status = response.statusCode; var body = jsonDecode(response.body); if (status == 200) { @@ -110,65 +66,46 @@ class APIService { static Future claimFoundItem( {required String name, required String email, required String id}) async { - var res = await http.post(Uri.parse(_claimItemURL), - headers: { - 'Content-Type': 'application/json', - 'security-key': apiSecurityKey - }, + var res = await http.post(Uri.parse(Endpoints.claimItemURL), + headers: Endpoints.getHeader(), body: jsonEncode({"id": id, "claimerEmail": email, "claimerName": name})); return jsonDecode(res.body); } static Future deleteBnsMyAd(String id, String email) async { - await http.post(Uri.parse(_deleteBuyURL), - headers: { - 'Content-Type': 'application/json', - 'security-key': apiSecurityKey - }, + await http.post(Uri.parse(Endpoints.deleteBuyURL), + headers: Endpoints.getHeader(), body: jsonEncode({'id': id, 'email': email})); - await http.post(Uri.parse(_deleteSellURL), - headers: { - 'Content-Type': 'application/json', - 'security-key': apiSecurityKey - }, + await http.post(Uri.parse(Endpoints.deleteSellURL), + headers: Endpoints.getHeader(), body: jsonEncode({'id': id, 'email': email})); } static Future deleteLnfMyAd(String id, String email) async { - await http.post(Uri.parse(_deleteLostURL), - headers: { - 'Content-Type': 'application/json', - 'security-key': apiSecurityKey - }, + await http.post(Uri.parse(Endpoints.deleteLostURL), + headers: Endpoints.getHeader(), body: jsonEncode({'id': id, 'email': email})); - await http.post(Uri.parse(_deleteFoundURL), - headers: { - 'Content-Type': 'application/json', - 'security-key': apiSecurityKey - }, + await http.post(Uri.parse(Endpoints.deleteFoundURL), + headers: Endpoints.getHeader(), body: jsonEncode({'id': id, 'email': email})); } static Future getBuyItems() async { - var res = await http.get(Uri.parse(_buyURL)); + var res = await http.get(Uri.parse(Endpoints.buyURL)); var lostItemsDetails = jsonDecode(res.body); return lostItemsDetails["details"]; } static Future getSellItems() async { - var res = await http.get(Uri.parse(_sellURL)); + var res = await http.get(Uri.parse(Endpoints.sellURL)); var foundItemsDetails = jsonDecode(res.body); return foundItemsDetails["details"]; } static Future> getBnsMyItems(String mail) async { - var res = await http.post(Uri.parse(_bnsMyAdsURL), - headers: { - 'Content-Type': 'application/json', - 'security-key': apiSecurityKey - }, - body: jsonEncode({'email': mail})); + var res = await http.post(Uri.parse(Endpoints.bnsMyAdsURL), + headers: Endpoints.getHeader(), body: jsonEncode({'email': mail})); var myItemsDetails = jsonDecode(res.body); var sellList = (myItemsDetails["details"]["sellList"] as List) @@ -182,12 +119,8 @@ class APIService { } static Future> getLnfMyItems(String mail) async { - var res = await http.post(Uri.parse(_lnfMyAdsURL), - headers: { - 'Content-Type': 'application/json', - 'security-key': apiSecurityKey - }, - body: jsonEncode({'email': mail})); + var res = await http.post(Uri.parse(Endpoints.lnfMyAdsURL), + headers: Endpoints.getHeader(), body: jsonEncode({'email': mail})); var myItemsDetails = jsonDecode(res.body); var foundList = (myItemsDetails["details"]["foundList"] as List) @@ -201,7 +134,7 @@ class APIService { } static Future getLostItems() async { - var res = await http.get(Uri.parse(_lostURL)); + var res = await http.get(Uri.parse(Endpoints.lostURL)); var lostItemsDetails = jsonDecode(res.body); return lostItemsDetails["details"]; } @@ -210,7 +143,8 @@ class APIService { final queryParameters = { 'page': pageNumber.toString(), }; - final uri = Uri.https('swc.iitg.ac.in', _lostPath, queryParameters); + final uri = + Uri.https('swc.iitg.ac.in', Endpoints.lostPath, queryParameters); var response = await http.get(uri); var json = jsonDecode(response.body); List lostPage = (json['details'] as List) @@ -224,7 +158,8 @@ class APIService { final queryParameters = { 'page': pageNumber.toString(), }; - final uri = Uri.https('swc.iitg.ac.in', _foundPath, queryParameters); + final uri = + Uri.https('swc.iitg.ac.in', Endpoints.foundPath, queryParameters); var response = await http.get(uri); var json = jsonDecode(response.body); List lostPage = (json['details'] as List) @@ -238,7 +173,8 @@ class APIService { final queryParameters = { 'page': pageNumber.toString(), }; - final uri = Uri.https('swc.iitg.ac.in', _sellPath, queryParameters); + final uri = + Uri.https('swc.iitg.ac.in', Endpoints.sellPath, queryParameters); var response = await http.get(uri); var json = jsonDecode(response.body); List sellPage = (json['details'] as List) @@ -252,7 +188,7 @@ class APIService { final queryParameters = { 'page': pageNumber.toString(), }; - final uri = Uri.https('swc.iitg.ac.in', _buyPath, queryParameters); + final uri = Uri.https('swc.iitg.ac.in', Endpoints.buyPath, queryParameters); var response = await http.get(uri); var json = jsonDecode(response.body); List buyPage = (json['details'] as List) @@ -263,52 +199,50 @@ class APIService { } static Future getFoundItems() async { - var res = await http.get(Uri.parse(_foundURL)); + var res = await http.get(Uri.parse(Endpoints.foundURL)); var foundItemsDetails = jsonDecode(res.body); return foundItemsDetails["details"]; } static Future> postSellData( Map data) async { - var res = await http.post(Uri.parse(_sellURL), - body: jsonEncode({ - 'title': data['title'], - 'description': data['description'], - 'price': data['price'], - 'imageString': data['image'], - 'phonenumber': data['contact'], - 'email': data['email'], - 'username': data['name'] - }), - headers: { - 'Content-Type': 'application/json', - 'security-key': apiSecurityKey - }); + var res = await http.post( + Uri.parse(Endpoints.sellURL), + body: jsonEncode({ + 'title': data['title'], + 'description': data['description'], + 'price': data['price'], + 'imageString': data['image'], + 'phonenumber': data['contact'], + 'email': data['email'], + 'username': data['name'] + }), + headers: Endpoints.getHeader(), + ); return jsonDecode(res.body); } static Future> postBuyData( Map data) async { - var res = await http.post(Uri.parse(_buyURL), - body: jsonEncode({ - 'title': data['title'], - 'description': data['description'], - 'price': data['total_price'], - 'imageString': data['image'], - 'phonenumber': data['contact'], - 'email': data['email'], - 'username': data['name'] - }), - headers: { - 'Content-Type': 'application/json', - 'security-key': apiSecurityKey - }); + var res = await http.post( + Uri.parse(Endpoints.buyURL), + body: jsonEncode({ + 'title': data['title'], + 'description': data['description'], + 'price': data['total_price'], + 'imageString': data['image'], + 'phonenumber': data['contact'], + 'email': data['email'], + 'username': data['name'] + }), + headers: Endpoints.getHeader(), + ); return jsonDecode(res.body); } static Future> postLostData( Map data) async { - var res = await http.post(Uri.parse(_lostURL), + var res = await http.post(Uri.parse(Endpoints.lostURL), body: jsonEncode({ 'title': data['title'], 'description': data['description'], @@ -318,16 +252,13 @@ class APIService { 'email': data['email'], 'username': data['name'] }), - headers: { - 'Content-Type': 'application/json', - 'security-key': apiSecurityKey - }); + headers: Endpoints.getHeader()); return jsonDecode(res.body); } static Future> postFoundData( Map data) async { - var res = await http.post(Uri.parse(_foundURL), + var res = await http.post(Uri.parse(Endpoints.foundURL), body: jsonEncode({ 'title': data['title'], 'description': data['description'], @@ -337,15 +268,13 @@ class APIService { 'email': data['email'], 'username': data['name'] }), - headers: { - 'Content-Type': 'application/json', - 'security-key': apiSecurityKey - }); + headers: Endpoints.getHeader()); return jsonDecode(res.body); } static Future> getLastUpdated() async { - http.Response response = await http.get(Uri.parse(_lastUpdatedURL)); + http.Response response = + await http.get(Uri.parse(Endpoints.lastUpdatedURL)); var status = response.statusCode; var body = jsonDecode(response.body); if (status == 200) { @@ -357,7 +286,7 @@ class APIService { } static Future>> getContactData() async { - http.Response response = await http.get(Uri.parse(_contactURL)); + http.Response response = await http.get(Uri.parse(Endpoints.contactURL)); var status = response.statusCode; var body = jsonDecode(response.body); if (status == 200) { @@ -372,7 +301,7 @@ class APIService { } static Future>>> getBusData() async { - http.Response response = await http.get(Uri.parse(_busURL)); + http.Response response = await http.get(Uri.parse(Endpoints.busURL)); var status = response.statusCode; var json = jsonDecode(response.body); if (status == 200) { @@ -401,7 +330,7 @@ class APIService { } static Future>> getFerryData() async { - http.Response response = await http.get(Uri.parse(_ferryURL)); + http.Response response = await http.get(Uri.parse(Endpoints.ferryURL)); var status = response.statusCode; var json = jsonDecode(response.body); if (status == 200) { @@ -417,10 +346,10 @@ class APIService { static Future getTimeTable({required String roll}) async { final response = await http.post( - Uri.parse(_timetableURL), + Uri.parse(Endpoints.timetableURL), headers: { HttpHeaders.contentTypeHeader: 'application/json', - 'security-key': apiSecurityKey + 'security-key': Endpoints.apiSecurityKey }, body: jsonEncode({ "roll_number": roll, @@ -434,7 +363,7 @@ class APIService { } static Future>> getMessMenu() async { - http.Response response = await http.get(Uri.parse(_messURL)); + http.Response response = await http.get(Uri.parse(Endpoints.messURL)); var status = response.statusCode; var body = jsonDecode(response.body); if (status == 200) { @@ -471,12 +400,8 @@ class APIService { static Future> postUPSP( Map data) async { - var res = await http.post(Uri.parse(_upspPost), - body: jsonEncode(data), - headers: { - 'Content-Type': 'application/json', - 'security-key': apiSecurityKey - }); + var res = await http.post(Uri.parse(Endpoints.upspPost), + body: jsonEncode(data), headers: Endpoints.getHeader()); return jsonDecode(res.body); } @@ -487,10 +412,11 @@ class APIService { }); try { var response = await Dio().post( - _uploadFileUPSP, + Endpoints.uploadFileUPSP, options: Options( - contentType: 'multipart/form-data', - headers: {'security-key': apiSecurityKey}), + contentType: 'multipart/form-data', + headers: {'security-key': Endpoints.apiSecurityKey}, + ), data: formData, onSendProgress: (int send, int total) { // TODO: Show send/total percent as progress indicator @@ -504,4 +430,39 @@ class APIService { return null; } } + + static Future getBusTiming() async { + try { + final res = await http.get( + Uri.parse(Endpoints.busStops), + headers: Endpoints.getHeader(), + ); + + final busTiming = json.decode(res.body); + return BusTiming.fromJson(busTiming); + } catch (e) { + rethrow; + } + } + + static Future getFerryTiming() async { + try { + final res = await http.get( + Uri.parse(Endpoints.ferryURL), + headers: Endpoints.getHeader(), + ); + + final ferryTiming = json.decode(res.body); + return FerryTiming.fromJson(ferryTiming); + } catch (e) { + rethrow; + } + } + + + + + + + } diff --git a/pubspec.yaml b/pubspec.yaml index 8c543b34..4bad1a79 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -47,7 +47,7 @@ dependencies: cookie_jar: 3.0.1 provider: ^6.0.2 http: ^0.13.4 - dio: ^4.0.6 + dio: ^5.0.3 file_picker: ^5.2.5 shared_preferences: ^2.0.12 barcode_widget: ^2.0.3 From 82e06c0841931d647970422dbf7e5924cd63a09d Mon Sep 17 00:00:00 2001 From: Priyanshu Srivastava Date: Sat, 15 Apr 2023 19:29:55 +0530 Subject: [PATCH 27/82] minor fix --- lib/main.dart | 2 + lib/models/timetable/bus_timing_model.dart | 56 ++++++++++++-------- lib/models/timetable/ferry_timing_model.dart | 45 ++++++++++------ lib/services/api.dart | 31 ++++++----- 4 files changed, 84 insertions(+), 50 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index e1ce8cec..1b88c462 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -11,6 +11,7 @@ import 'package:onestop_dev/stores/mapbox_store.dart'; import 'package:onestop_dev/stores/restaurant_store.dart'; import 'package:onestop_dev/stores/timetable_store.dart'; import 'package:provider/provider.dart'; +import './services/api.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -59,3 +60,4 @@ class MyApp extends StatelessWidget { ); } } + diff --git a/lib/models/timetable/bus_timing_model.dart b/lib/models/timetable/bus_timing_model.dart index 0b80b4dc..37f7fcc4 100644 --- a/lib/models/timetable/bus_timing_model.dart +++ b/lib/models/timetable/bus_timing_model.dart @@ -1,37 +1,51 @@ import 'dart:convert'; -BusTiming busTimingFromJson(String str) => BusTiming.fromJson(json.decode(str)); +List busTimingFromJson(String str) => + List.from(json.decode(str).map((x) => BusTiming.fromJson(x))); -String busTimingToJson(BusTiming data) => json.encode(data.toJson()); +String busTimingToJson(List data) => + json.encode(List.from(data.map((x) => x.toJson()))); class BusTiming { BusTiming({ - required this.busTiming, + required this.weekendCampusToCity, + required this.id, + required this.busStop, required this.weekdaysCampusToCity, required this.weekdaysCityToCampus, required this.weekendCityToCampus, - required this.weekendCampusToCity, }); - String busTiming; - DateTime weekdaysCampusToCity; - DateTime weekdaysCityToCampus; - DateTime weekendCityToCampus; - DateTime weekendCampusToCity; + List weekendCampusToCity; + String id; + String busStop; + List weekdaysCampusToCity; + List weekdaysCityToCampus; + List weekendCityToCampus; - factory BusTiming.fromJson(Map json) => BusTiming( - busTiming: json["busTiming"], - weekdaysCampusToCity: json["weekdays_campusToCity"], - weekdaysCityToCampus: json["weekdays_cityToCampus"], - weekendCityToCampus: json["weekend_cityToCampus"], - weekendCampusToCity: json["weekend_campusToCity"], + factory BusTiming.fromJson(Map json) => BusTiming( + weekendCampusToCity: + List.from(json["weekend_campusToCity"].map((x) => x)), + id: json["_id"], + busStop: json[" busStop"], + weekdaysCampusToCity: List.from( + json["weekdays_campusToCity"].map((x) => DateTime.parse(x))), + weekdaysCityToCampus: List.from( + json["weekdays_cityToCampus"].map((x) => DateTime.parse(x))), + weekendCityToCampus: List.from( + json["weekend_cityToCampus"].map((x) => DateTime.parse(x))), ); - Map toJson() => { - "busTiming": busTiming, - "weekdays_campusToCity": weekdaysCampusToCity, - "weekdays_cityToCampus": weekdaysCityToCampus, - "weekend_cityToCampus": weekendCityToCampus, - "weekend_campusToCity": weekendCampusToCity, + Map toJson() => { + "weekend_campusToCity": + List.from(weekendCampusToCity.map((x) => x)), + "_id": id, + " busStop": busStop, + "weekdays_campusToCity": List.from( + weekdaysCampusToCity.map((x) => x.toIso8601String())), + "weekdays_cityToCampus": List.from( + weekdaysCityToCampus.map((x) => x.toIso8601String())), + "weekend_cityToCampus": List.from( + weekendCityToCampus.map((x) => x.toIso8601String())), }; } diff --git a/lib/models/timetable/ferry_timing_model.dart b/lib/models/timetable/ferry_timing_model.dart index 9b5f5624..54d553bf 100644 --- a/lib/models/timetable/ferry_timing_model.dart +++ b/lib/models/timetable/ferry_timing_model.dart @@ -1,38 +1,51 @@ import 'dart:convert'; -FerryTiming ferryTimingFromJson(String str) => - FerryTiming.fromJson(json.decode(str)); +List ferryTimingFromJson(String str) => List.from( + json.decode(str).map((x) => FerryTiming.fromJson(x))); -String ferryTimingToJson(FerryTiming data) => json.encode(data.toJson()); +String ferryTimingToJson(List data) => + json.encode(List.from(data.map((x) => x.toJson()))); class FerryTiming { FerryTiming({ + required this.weekendCampusToCity, + required this.id, required this.ferryGhat, required this.weekdaysCampusToCity, required this.weekdaysCityToCampus, required this.weekendCityToCampus, - required this.weekendCampusToCity, }); + List weekendCampusToCity; + String id; String ferryGhat; - DateTime weekdaysCampusToCity; - DateTime weekdaysCityToCampus; - DateTime weekendCityToCampus; - DateTime weekendCampusToCity; + List weekdaysCampusToCity; + List weekdaysCityToCampus; + List weekendCityToCampus; factory FerryTiming.fromJson(Map json) => FerryTiming( + weekendCampusToCity: + List.from(json["weekend_campusToCity"].map((x) => x)), + id: json["_id"], ferryGhat: json["ferryGhat"], - weekdaysCampusToCity: json["weekdays_campusToCity"], - weekdaysCityToCampus: json["weekdays_cityToCampus"], - weekendCityToCampus: json["weekend_cityToCampus"], - weekendCampusToCity: json["weekend_campusToCity"], + weekdaysCampusToCity: List.from( + json["weekdays_campusToCity"].map((x) => DateTime.parse(x))), + weekdaysCityToCampus: List.from( + json["weekdays_cityToCampus"].map((x) => DateTime.parse(x))), + weekendCityToCampus: List.from( + json["weekend_cityToCampus"].map((x) => DateTime.parse(x))), ); Map toJson() => { + "weekend_campusToCity": + List.from(weekendCampusToCity.map((x) => x)), + "_id": id, "ferryGhat": ferryGhat, - "weekdays_campusToCity": weekdaysCampusToCity, - "weekdays_cityToCampus": weekdaysCityToCampus, - "weekend_cityToCampus": weekendCityToCampus, - "weekend_campusToCity": weekendCampusToCity, + "weekdays_campusToCity": List.from( + weekdaysCampusToCity.map((x) => x.toIso8601String())), + "weekdays_cityToCampus": List.from( + weekdaysCityToCampus.map((x) => x.toIso8601String())), + "weekend_cityToCampus": List.from( + weekendCityToCampus.map((x) => x.toIso8601String())), }; } diff --git a/lib/services/api.dart b/lib/services/api.dart index 126a5929..1fe99823 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -431,38 +431,43 @@ class APIService { } } - static Future getBusTiming() async { + static Future> getBusTiming() async { try { final res = await http.get( Uri.parse(Endpoints.busStops), headers: Endpoints.getHeader(), ); - final busTiming = json.decode(res.body); - return BusTiming.fromJson(busTiming); + List busTiming = json.decode(res.body); + + List busTimings = []; + + for (var element in busTiming) { + busTimings.add(BusTiming.fromJson(element)); + } + return busTimings; } catch (e) { rethrow; } } - static Future getFerryTiming() async { + static Future> getFerryTiming() async { try { final res = await http.get( Uri.parse(Endpoints.ferryURL), headers: Endpoints.getHeader(), ); - final ferryTiming = json.decode(res.body); - return FerryTiming.fromJson(ferryTiming); + List ferryTiming = json.decode(res.body); + + List ferryTimings = []; + + for (var element in ferryTiming) { + ferryTimings.add(FerryTiming.fromJson(element)); + } + return ferryTimings; } catch (e) { rethrow; } } - - - - - - - } From 48c1c3a49161f93158e7f954754c916a772101bc Mon Sep 17 00:00:00 2001 From: Priyanshu Srivastava Date: Sat, 15 Apr 2023 21:05:59 +0530 Subject: [PATCH 28/82] added local storage feature --- lib/globals/endpoints.dart | 52 +++++++------- lib/main.dart | 3 +- lib/models/lostfound/lost_model.g.dart | 2 +- lib/models/timetable/bus_timing_model.dart | 67 +++++++------------ lib/models/timetable/bus_timing_model.g.dart | 37 ++++++++++ lib/models/timetable/ferry_timing_model.dart | 67 ++++++++----------- .../timetable/ferry_timing_model.g.dart | 46 +++++++++++++ lib/services/api.dart | 44 +++++++++--- 8 files changed, 198 insertions(+), 120 deletions(-) create mode 100644 lib/models/timetable/bus_timing_model.g.dart create mode 100644 lib/models/timetable/ferry_timing_model.g.dart diff --git a/lib/globals/endpoints.dart b/lib/globals/endpoints.dart index bd5413f1..14772de7 100644 --- a/lib/globals/endpoints.dart +++ b/lib/globals/endpoints.dart @@ -1,37 +1,37 @@ class Endpoints { - static const baseUrl = 'https://swc.iitg.ac.in'; - static const String restaurantURL = "$baseUrl/onestopapi/v2/getAllOutlets"; - static const String lastUpdatedURL = "$baseUrl/onestopapi/v2/lastDataUpdate"; - static const String contactURL = "$baseUrl/onestopapi/v2/getContacts"; + static const baseUrl = 'https://swc.iitg.ac.in/onestopapi/v2'; + static const String restaurantURL = "$baseUrl/getAllOutlets"; + static const String lastUpdatedURL = "$baseUrl/lastDataUpdate"; + static const String contactURL = "$baseUrl/getContacts"; static const String timetableURL = "$baseUrl/smartTimetable/get-my-courses"; - static const String ferryURL = '$baseUrl/onestopapi/v2/ferryTimings'; - static const String busURL = '$baseUrl/onestopapi/v2/busTimings'; - static const String busStops = '$baseUrl/onestopapi/v2/busstops'; - static const String messURL = "$baseUrl/onestopapi/v2/hostelsMessMenu"; - static const String buyURL = '$baseUrl/onestopapi/v2/buy'; - static const String sellURL = '$baseUrl/onestopapi/v2/sell'; - static const String sellPath = '/onestopapi/v2/sellPage'; - static const String buyPath = '/onestopapi/v2/buyPage'; - static const String bnsMyAdsURL = '$baseUrl/onestopapi/v2/bns/myads'; - static const String lnfMyAdsURL = '$baseUrl/onestopapi/v2/lnf/myads'; - static const String deleteBuyURL = "$baseUrl/onestopapi/v2/buy/remove"; - static const String deleteSellURL = "$baseUrl/onestopapi/v2/sell/remove"; - static const String deleteLostURL = "$baseUrl/onestopapi/v2/lost/remove"; - static const String deleteFoundURL = "$baseUrl/onestopapi/v2/found/remove"; - static const String lostURL = '$baseUrl/onestopapi/v2/lost'; - static const String lostPath = '/onestopapi/v2/lostPage'; - static const String foundPath = '/onestopapi/v2/foundPage'; - static const String foundURL = '$baseUrl/onestopapi/v2/found'; - static const String claimItemURL = "$baseUrl/onestopapi/v2/found/claim"; - static const String newsURL = "$baseUrl/onestopapi/v2/news"; + static const String ferryURL = '$baseUrl/ferryTimings'; + static const String busURL = '$baseUrl/busTimings'; + static const String busStops = '$baseUrl/busstops'; + static const String messURL = "$baseUrl/hostelsMessMenu"; + static const String buyURL = '$baseUrl/buy'; + static const String sellURL = '$baseUrl/sell'; + static const String sellPath = '/sellPage'; + static const String buyPath = '/buyPage'; + static const String bnsMyAdsURL = '$baseUrl/bns/myads'; + static const String lnfMyAdsURL = '$baseUrl/lnf/myads'; + static const String deleteBuyURL = "$baseUrl/buy/remove"; + static const String deleteSellURL = "$baseUrl/sell/remove"; + static const String deleteLostURL = "$baseUrl/lost/remove"; + static const String deleteFoundURL = "$baseUrl/found/remove"; + static const String lostURL = '$baseUrl/lost'; + static const String lostPath = '/lostPage'; + static const String foundPath = '/foundPage'; + static const String foundURL = '$baseUrl/found'; + static const String claimItemURL = "$baseUrl/found/claim"; + static const String newsURL = "$baseUrl/news"; static const String githubIssueToken = String.fromEnvironment('GITHUB_ISSUE_TOKEN'); static const apiSecurityKey = String.fromEnvironment('SECURITY-KEY'); static const feedback = 'https://api.github.com/repos/vrrao01/onestop_dev/issues'; - static const String upspPost = '$baseUrl/onestopapi/v2/upsp/submit-request'; + static const String upspPost = '$baseUrl/upsp/submit-request'; static const String uploadFileUPSP = - "$baseUrl/onestopapi/v2/upsp/file-upload"; + "$baseUrl/upsp/file-upload"; static getHeader() { return {'Content-Type': 'application/json', 'security-key': apiSecurityKey}; diff --git a/lib/main.dart b/lib/main.dart index 1b88c462..1d2977d5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,7 @@ // ignore_for_file: unused_import +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:onestop_dev/functions/utility/check_last_updated.dart'; @@ -60,4 +62,3 @@ class MyApp extends StatelessWidget { ); } } - diff --git a/lib/models/lostfound/lost_model.g.dart b/lib/models/lostfound/lost_model.g.dart index 068124b9..57159075 100644 --- a/lib/models/lostfound/lost_model.g.dart +++ b/lib/models/lostfound/lost_model.g.dart @@ -14,8 +14,8 @@ LostModel _$LostModelFromJson(Map json) => LostModel( email: json['email'] as String, compressedImageURL: json['compressedImageURL'] as String, date: DateTime.parse(json['date'] as String), - phonenumber: json['phonenumber'] as String, id: json['_id'] as String, + phonenumber: json['phonenumber'] as String, ); Map _$LostModelToJson(LostModel instance) => { diff --git a/lib/models/timetable/bus_timing_model.dart b/lib/models/timetable/bus_timing_model.dart index 37f7fcc4..15bf95d5 100644 --- a/lib/models/timetable/bus_timing_model.dart +++ b/lib/models/timetable/bus_timing_model.dart @@ -1,51 +1,34 @@ -import 'dart:convert'; +import 'package:json_annotation/json_annotation.dart'; -List busTimingFromJson(String str) => - List.from(json.decode(str).map((x) => BusTiming.fromJson(x))); - -String busTimingToJson(List data) => - json.encode(List.from(data.map((x) => x.toJson()))); +part 'bus_timing_model.g.dart'; +@JsonSerializable() class BusTiming { + final List? weekend_campusToCity; + @JsonKey(defaultValue: '') + final String id; + @JsonKey(defaultValue: '') + final String busStop; + + @JsonKey(defaultValue: []) + final List? weekdays_campusToCity; + + @JsonKey(defaultValue: []) + final List? weekdays_cityToCampus; + + @JsonKey(defaultValue: []) + final List? weekend_cityToCampus; + BusTiming({ - required this.weekendCampusToCity, + required this.weekend_campusToCity, required this.id, required this.busStop, - required this.weekdaysCampusToCity, - required this.weekdaysCityToCampus, - required this.weekendCityToCampus, + required this.weekdays_campusToCity, + required this.weekdays_cityToCampus, + required this.weekend_cityToCampus, }); + factory BusTiming.fromJson(Map json) => + _$BusTimingFromJson(json); - List weekendCampusToCity; - String id; - String busStop; - List weekdaysCampusToCity; - List weekdaysCityToCampus; - List weekendCityToCampus; - - factory BusTiming.fromJson(Map json) => BusTiming( - weekendCampusToCity: - List.from(json["weekend_campusToCity"].map((x) => x)), - id: json["_id"], - busStop: json[" busStop"], - weekdaysCampusToCity: List.from( - json["weekdays_campusToCity"].map((x) => DateTime.parse(x))), - weekdaysCityToCampus: List.from( - json["weekdays_cityToCampus"].map((x) => DateTime.parse(x))), - weekendCityToCampus: List.from( - json["weekend_cityToCampus"].map((x) => DateTime.parse(x))), - ); - - Map toJson() => { - "weekend_campusToCity": - List.from(weekendCampusToCity.map((x) => x)), - "_id": id, - " busStop": busStop, - "weekdays_campusToCity": List.from( - weekdaysCampusToCity.map((x) => x.toIso8601String())), - "weekdays_cityToCampus": List.from( - weekdaysCityToCampus.map((x) => x.toIso8601String())), - "weekend_cityToCampus": List.from( - weekendCityToCampus.map((x) => x.toIso8601String())), - }; + Map toJson() => _$BusTimingToJson(this); } diff --git a/lib/models/timetable/bus_timing_model.g.dart b/lib/models/timetable/bus_timing_model.g.dart new file mode 100644 index 00000000..f8a45211 --- /dev/null +++ b/lib/models/timetable/bus_timing_model.g.dart @@ -0,0 +1,37 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'bus_timing_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +BusTiming _$BusTimingFromJson(Map json) => BusTiming( + weekend_campusToCity: json['weekend_campusToCity'] as List?, + id: json['id'] as String, + busStop: json['busStop'] as String, + weekdays_campusToCity: (json['weekdays_campusToCity'] as List?) + ?.map((e) => DateTime.parse(e as String)) + .toList(), + weekdays_cityToCampus: (json['weekdays_cityToCampus'] as List?) + ?.map((e) => DateTime.parse(e as String)) + .toList(), + weekend_cityToCampus: (json['weekend_cityToCampus'] as List?) + ?.map((e) => DateTime.parse(e as String)) + .toList(), + ); + +Map _$BusTimingToJson(BusTiming instance) => { + 'weekend_campusToCity': instance.weekend_campusToCity, + 'id': instance.id, + 'busStop': instance.busStop, + 'weekdays_campusToCity': instance.weekdays_campusToCity + ?.map((e) => e.toIso8601String()) + .toList(), + 'weekdays_cityToCampus': instance.weekdays_cityToCampus + ?.map((e) => e.toIso8601String()) + .toList(), + 'weekend_cityToCampus': instance.weekend_cityToCampus + ?.map((e) => e.toIso8601String()) + .toList(), + }; diff --git a/lib/models/timetable/ferry_timing_model.dart b/lib/models/timetable/ferry_timing_model.dart index 54d553bf..a4446253 100644 --- a/lib/models/timetable/ferry_timing_model.dart +++ b/lib/models/timetable/ferry_timing_model.dart @@ -1,51 +1,38 @@ -import 'dart:convert'; +import 'package:json_annotation/json_annotation.dart'; -List ferryTimingFromJson(String str) => List.from( - json.decode(str).map((x) => FerryTiming.fromJson(x))); - -String ferryTimingToJson(List data) => - json.encode(List.from(data.map((x) => x.toJson()))); +part 'ferry_timing_model.g.dart'; +@JsonSerializable() class FerryTiming { FerryTiming({ - required this.weekendCampusToCity, + required this.weekend_campusToCity, required this.id, required this.ferryGhat, - required this.weekdaysCampusToCity, - required this.weekdaysCityToCampus, - required this.weekendCityToCampus, + required this.weekdays_campusToCity, + required this.weekdays_cityToCampus, + required this.weekend_cityToCampus, }); - List weekendCampusToCity; + @JsonKey(defaultValue: '') String id; + + @JsonKey(defaultValue: '') String ferryGhat; - List weekdaysCampusToCity; - List weekdaysCityToCampus; - List weekendCityToCampus; - - factory FerryTiming.fromJson(Map json) => FerryTiming( - weekendCampusToCity: - List.from(json["weekend_campusToCity"].map((x) => x)), - id: json["_id"], - ferryGhat: json["ferryGhat"], - weekdaysCampusToCity: List.from( - json["weekdays_campusToCity"].map((x) => DateTime.parse(x))), - weekdaysCityToCampus: List.from( - json["weekdays_cityToCampus"].map((x) => DateTime.parse(x))), - weekendCityToCampus: List.from( - json["weekend_cityToCampus"].map((x) => DateTime.parse(x))), - ); - - Map toJson() => { - "weekend_campusToCity": - List.from(weekendCampusToCity.map((x) => x)), - "_id": id, - "ferryGhat": ferryGhat, - "weekdays_campusToCity": List.from( - weekdaysCampusToCity.map((x) => x.toIso8601String())), - "weekdays_cityToCampus": List.from( - weekdaysCityToCampus.map((x) => x.toIso8601String())), - "weekend_cityToCampus": List.from( - weekendCityToCampus.map((x) => x.toIso8601String())), - }; + + @JsonKey(defaultValue: []) + List weekend_campusToCity; + + @JsonKey(defaultValue: []) + List weekdays_campusToCity; + + @JsonKey(defaultValue: []) + List weekdays_cityToCampus; + + @JsonKey(defaultValue: []) + List weekend_cityToCampus; + + factory FerryTiming.fromJson(Map json) => + _$FerryTimingFromJson(json); + + Map toJson() => _$FerryTimingToJson(this); } diff --git a/lib/models/timetable/ferry_timing_model.g.dart b/lib/models/timetable/ferry_timing_model.g.dart new file mode 100644 index 00000000..cca9eb65 --- /dev/null +++ b/lib/models/timetable/ferry_timing_model.g.dart @@ -0,0 +1,46 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'ferry_timing_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +FerryTiming _$FerryTimingFromJson(Map json) => FerryTiming( + weekend_campusToCity: (json['weekend_campusToCity'] as List?) + ?.map((e) => DateTime.parse(e as String)) + .toList() ?? + [], + id: json['id'] as String? ?? '', + ferryGhat: json['ferryGhat'] as String? ?? '', + weekdays_campusToCity: (json['weekdays_campusToCity'] as List?) + ?.map((e) => DateTime.parse(e as String)) + .toList() ?? + [], + weekdays_cityToCampus: (json['weekdays_cityToCampus'] as List?) + ?.map((e) => DateTime.parse(e as String)) + .toList() ?? + [], + weekend_cityToCampus: (json['weekend_cityToCampus'] as List?) + ?.map((e) => DateTime.parse(e as String)) + .toList() ?? + [], + ); + +Map _$FerryTimingToJson(FerryTiming instance) => + { + 'id': instance.id, + 'ferryGhat': instance.ferryGhat, + 'weekend_campusToCity': instance.weekend_campusToCity + .map((e) => e.toIso8601String()) + .toList(), + 'weekdays_campusToCity': instance.weekdays_campusToCity + .map((e) => e.toIso8601String()) + .toList(), + 'weekdays_cityToCampus': instance.weekdays_cityToCampus + .map((e) => e.toIso8601String()) + .toList(), + 'weekend_cityToCampus': instance.weekend_cityToCampus + .map((e) => e.toIso8601String()) + .toList(), + }; diff --git a/lib/services/api.dart b/lib/services/api.dart index 1fe99823..62b268fb 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -12,6 +12,7 @@ import 'package:onestop_dev/models/timetable/ferry_timing_model.dart'; import 'package:onestop_dev/models/timetable/registered_courses.dart'; import 'package:onestop_dev/models/buy_sell/sell_model.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class APIService { static Future postFeedbackData(Map data) async { @@ -433,12 +434,24 @@ class APIService { static Future> getBusTiming() async { try { - final res = await http.get( - Uri.parse(Endpoints.busStops), - headers: Endpoints.getHeader(), - ); + final prefs = await SharedPreferences.getInstance(); + + late String jsonData; + + if (prefs.getString('busTimings') != null) { + jsonData = prefs.getString('busTimings') ?? ''; + } else { + final res = await http.get( + Uri.parse(Endpoints.busStops), + headers: Endpoints.getHeader(), + ); + + prefs.setString('busTimings', res.body); + + jsonData = prefs.getString('busTimings') ?? ''; + } - List busTiming = json.decode(res.body); + List busTiming = json.decode(jsonData); List busTimings = []; @@ -453,12 +466,23 @@ class APIService { static Future> getFerryTiming() async { try { - final res = await http.get( - Uri.parse(Endpoints.ferryURL), - headers: Endpoints.getHeader(), - ); + final prefs = await SharedPreferences.getInstance(); + + late String jsonData; + + if (prefs.getString('ferryTimings') != null) { + jsonData = prefs.getString('ferryTimings') ?? ''; + } else { + final res = await http.get( + Uri.parse(Endpoints.ferryURL), + headers: Endpoints.getHeader(), + ); + prefs.setString('ferryTimings', res.body); + + jsonData = prefs.getString('ferryTimings') ?? ''; + } - List ferryTiming = json.decode(res.body); + List ferryTiming = json.decode(jsonData); List ferryTimings = []; From 35f189eba178fddccdae759894fcb487920954d3 Mon Sep 17 00:00:00 2001 From: Priyanshu Srivastava Date: Sat, 22 Apr 2023 09:39:29 +0530 Subject: [PATCH 29/82] added provision for sendToAll --- lib/services/notifications_provider.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart index 92eb5818..7b46cf9a 100644 --- a/lib/services/notifications_provider.dart +++ b/lib/services/notifications_provider.dart @@ -74,6 +74,7 @@ bool checkNotificationCategory(String type) { } Future checkForNotifications() async { + await FirebaseMessaging.instance.subscribeToTopic('all'); FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); @@ -155,9 +156,9 @@ Future checkForNotifications() async { } void saveNotification(RemoteMessage message) async { - Map notificationData = message.data; + Map notificationData = message.data; DateTime sentTime = message.sentTime ?? DateTime.now(); -final SharedPreferences preferences = await SharedPreferences.getInstance(); + final SharedPreferences preferences = await SharedPreferences.getInstance(); notificationData['time'] = sentTime?.toString() ?? DateTime.now().toString(); notificationData['read'] = false; notificationData['messageId'] = message.messageId; From ada5d7d9d3277359e92d61af3a4573c67b087b6c Mon Sep 17 00:00:00 2001 From: Ashutosh-777 Date: Sun, 21 May 2023 13:42:21 +0530 Subject: [PATCH 30/82] Travel and Mess --- android/build.gradle | 4 +- lib/functions/food/get_day.dart | 4 + lib/functions/travel/has_left.dart | 87 +++++------ lib/functions/travel/next_time.dart | 68 ++++++++- lib/models/food/mess_menu_model.dart | 104 ++++++++++--- lib/models/food/mess_menu_model.g.dart | 82 +++++++++-- lib/models/timetable/bus_timing_model.dart | 34 ----- lib/models/timetable/bus_timing_model.g.dart | 37 ----- lib/models/timetable/ferry_timing_model.dart | 38 ----- .../timetable/ferry_timing_model.g.dart | 46 ------ lib/models/travel/day_type_model.dart | 21 +++ lib/models/travel/day_type_model.g.dart | 22 +++ lib/models/travel/ferry_data_model.dart | 26 ---- lib/models/travel/ferry_data_model.g.dart | 35 ----- lib/models/travel/travel_timing_model.dart | 31 ++++ lib/models/travel/travel_timing_model.g.dart | 24 +++ lib/services/api.dart | 102 +++++++++---- lib/services/data_provider.dart | 32 ---- lib/stores/mess_store.dart | 83 ++++------- lib/stores/mess_store.g.dart | 57 +++---- lib/stores/travel_store.dart | 7 +- lib/stores/travel_store.g.dart | 26 ++-- lib/widgets/food/mess/mess_meal.dart | 13 +- lib/widgets/food/mess/mess_menu.dart | 72 ++++----- lib/widgets/mapbox/carousel_card.dart | 69 ++++++--- lib/widgets/mapbox/map_box.dart | 81 +++++----- lib/widgets/travel/bus_details.dart | 125 ++++++++-------- lib/widgets/travel/ferry_details.dart | 139 +++++++++++------- lib/widgets/travel/next_time_card.dart | 95 +++++++----- lib/widgets/travel/stops_bus_details.dart | 8 +- lib/widgets/travel/stops_list.dart | 69 ++++++--- lib/widgets/travel/timing_tile.dart | 12 +- pubspec.yaml | 2 +- 33 files changed, 885 insertions(+), 770 deletions(-) delete mode 100644 lib/models/timetable/bus_timing_model.dart delete mode 100644 lib/models/timetable/bus_timing_model.g.dart delete mode 100644 lib/models/timetable/ferry_timing_model.dart delete mode 100644 lib/models/timetable/ferry_timing_model.g.dart create mode 100644 lib/models/travel/day_type_model.dart create mode 100644 lib/models/travel/day_type_model.g.dart delete mode 100644 lib/models/travel/ferry_data_model.dart delete mode 100644 lib/models/travel/ferry_data_model.g.dart create mode 100644 lib/models/travel/travel_timing_model.dart create mode 100644 lib/models/travel/travel_timing_model.g.dart diff --git a/android/build.gradle b/android/build.gradle index 83ae2200..e06c40a4 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.6.10' + ext.kotlin_version = '1.8.0' repositories { google() mavenCentral() @@ -26,6 +26,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/lib/functions/food/get_day.dart b/lib/functions/food/get_day.dart index 141fd3ee..b38e2be8 100644 --- a/lib/functions/food/get_day.dart +++ b/lib/functions/food/get_day.dart @@ -4,3 +4,7 @@ String getFormattedDay() { DateTime now = DateTime.now(); return DateFormat("EEE").format(now); } +String getFormattedDayForMess() { + DateTime now = DateTime.now(); + return DateFormat("EEEE").format(now); +} diff --git a/lib/functions/travel/has_left.dart b/lib/functions/travel/has_left.dart index d5e96dc0..5b469322 100644 --- a/lib/functions/travel/has_left.dart +++ b/lib/functions/travel/has_left.dart @@ -1,44 +1,47 @@ import 'package:intl/intl.dart'; - -bool hasLeft(String inputTime) { - var currentTime = DateTime.now(); - List currentHour = - DateFormat.j().format(currentTime).toString().split(' '); - List inputHour = inputTime.split(' '); - - //Checking if both AM or both PM - if (inputHour[1] == currentHour[1]) { - List hm = inputHour[0].split(':'); - int a = int.parse(hm[0]); - int b = int.parse(currentHour[0]); - - if (a == 12) { - a = 0; - } - if (b == 12) { - b = 0; - } - - //Checking if both have same hour - if (a > b) { - return false; - } else if (a < b) { - return true; - } else { - //Checking if both have same minute - a = int.parse(hm[1]); - b = int.parse(DateFormat.m().format(currentTime)); - if (a > b) { - return false; - } else { - return true; - } - } - } else { - if (inputHour[1] == 'AM') { - return true; - } else { - return false; - } - } +bool hasLeft(DateTime s) { + DateTime x = DateTime.now(); + return x.isBefore(s); } +// bool hasLeft(String inputTime) { +// var currentTime = DateTime.now(); +// List currentHour = +// DateFormat.j().format(currentTime).toString().split(' '); +// List inputHour = inputTime.split(' '); +// +// //Checking if both AM or both PM +// if (inputHour[1] == currentHour[1]) { +// List hm = inputHour[0].split(':'); +// int a = int.parse(hm[0]); +// int b = int.parse(currentHour[0]); +// +// if (a == 12) { +// a = 0; +// } +// if (b == 12) { +// b = 0; +// } +// +// //Checking if both have same hour +// if (a > b) { +// return false; +// } else if (a < b) { +// return true; +// } else { +// //Checking if both have same minute +// a = int.parse(hm[1]); +// b = int.parse(DateFormat.m().format(currentTime)); +// if (a > b) { +// return false; +// } else { +// return true; +// } +// } +// } else { +// if (inputHour[1] == 'AM') { +// return true; +// } else { +// return false; +// } +// } +// } diff --git a/lib/functions/travel/next_time.dart b/lib/functions/travel/next_time.dart index f9d7784b..167b869d 100644 --- a/lib/functions/travel/next_time.dart +++ b/lib/functions/travel/next_time.dart @@ -1,23 +1,32 @@ import 'package:onestop_dev/functions/travel/has_left.dart'; - -String nextTime(List timings, {String firstTime = ''}) { - String answer = "Nothing"; - for (String time in timings) { +String nextTime(List timings, {String firstTime = ''}) { + DateTime answer = DateTime.now(); + bool changed = false; + for (var time in timings) { if (!hasLeft(time)) { answer = time; + changed = true; break; } } - if (answer == "Nothing") { + + if (!changed) { if (firstTime == '') { answer = timings[0]; } else { - answer = firstTime; + answer = DateTime.parse(firstTime); } } - return answer; + String a= formatTime(answer); + return a; +} +String formatTime(DateTime dateTime) { + var hour = dateTime.hour; + hour=hour>12?hour-12:hour; + final minute = dateTime.minute.toString().padLeft(2, '0'); + final period = dateTime.hour < 12 ? 'AM' : 'PM'; + return '$hour:$minute $period'; } - int parseTime(String time) { var components = time.split(RegExp('[: ]')); if (components.length != 3) { @@ -41,3 +50,46 @@ int parseTime(String time) { return hours * 100 + minutes; } + +// +// String nextTime(List timings, {String firstTime = ''}) { +// String answer = "Nothing"; +// for (String time in timings) { +// if (!hasLeft(time)) { +// answer = time; +// break; +// } +// } +// if (answer == "Nothing") { +// if (firstTime == '') { +// answer = timings[0]; +// } else { +// answer = firstTime; +// } +// } +// return answer; +// } +// +// int parseTime(String time) { +// var components = time.split(RegExp('[: ]')); +// if (components.length != 3) { +// throw FormatException('Time not in the expected format: $time'); +// } +// var hours = int.parse(components[0]); +// var minutes = int.parse(components[1]); +// var period = components[2].toUpperCase(); +// +// if (hours < 1 || hours > 12 || minutes < 0 || minutes > 59) { +// throw FormatException('Time not in the expected format: $time'); +// } +// +// if (hours == 12) { +// hours = 0; +// } +// +// if (period == 'PM') { +// hours += 12; +// } +// +// return hours * 100 + minutes; +// } diff --git a/lib/models/food/mess_menu_model.dart b/lib/models/food/mess_menu_model.dart index 679e0fbb..69fdb87a 100644 --- a/lib/models/food/mess_menu_model.dart +++ b/lib/models/food/mess_menu_model.dart @@ -1,33 +1,95 @@ import 'package:json_annotation/json_annotation.dart'; part 'mess_menu_model.g.dart'; - @JsonSerializable() -class MessMenuModel { - @JsonKey(defaultValue: "Untitled Hostel") - late String hostel; +class MessMenu { + final String id; + final String hostel; + final Day monday; + final Day tuesday; + final Day wednesday; + final Day thursday; + final Day friday; + final Day saturday; + final Day sunday; + final int v; + + MessMenu({ + required this.id, + required this.hostel, + required this.monday, + required this.tuesday, + required this.wednesday, + required this.thursday, + required this.friday, + required this.saturday, + required this.sunday, + required this.v, + }); + factory MessMenu.fromJson(Map json) => _$MessMenuFromJson(json); - @JsonKey(defaultValue: "Untitled Meal") - late String meal; + Map toJson() => _$MessMenuToJson(this); - @JsonKey(defaultValue: "Untitled Menu") - late String menu; +} +@JsonSerializable() +class Day { + final String id; + final MealType breakfast; + final MealType lunch; + final MealType dinner; - @JsonKey(defaultValue: "Untitled Timing") - late String timing; + Day({ + required this.id, + required this.breakfast, + required this.lunch, + required this.dinner, + }); + factory Day.fromJson(Map json) => _$DayFromJson(json); - @JsonKey(defaultValue: "Untitled Day") - late String day; + Map toJson() => _$DayToJson(this); +} +@JsonSerializable() +class MealType { + final String id; + final String mealDesription; + final String timing; - MessMenuModel( - {required this.hostel, - required this.meal, - required this.menu, - required this.day, - required this.timing}); + MealType({ + required this.id, + required this.mealDesription, + required this.timing, + }); + factory MealType.fromJson(Map json) => _$MealTypeFromJson(json); - factory MessMenuModel.fromJson(Map json) => - _$MessMenuModelFromJson(json); + Map toJson() => _$MealTypeToJson(this); - Map toJson() => _$MessMenuModelToJson(this); } +// @JsonSerializable() +// class MessMenuModel { +// @JsonKey(defaultValue: "Untitled Hostel") +// late String hostel; +// +// @JsonKey(defaultValue: "Untitled Meal") +// late String meal; +// +// @JsonKey(defaultValue: "Untitled Menu") +// late String menu; +// +// @JsonKey(defaultValue: "Untitled Timing") +// late String timing; +// +// @JsonKey(defaultValue: "Untitled Day") +// late String day; +// +// MessMenuModel( +// {required this.hostel, +// required this.meal, +// required this.menu, +// required this.day, +// required this.timing}); +// +// factory MessMenuModel.fromJson(Map json) => +// _$MessMenuModelFromJson(json); +// +// Map toJson() => _$MessMenuModelToJson(this); +//} diff --git a/lib/models/food/mess_menu_model.g.dart b/lib/models/food/mess_menu_model.g.dart index f1177fa0..63313aeb 100644 --- a/lib/models/food/mess_menu_model.g.dart +++ b/lib/models/food/mess_menu_model.g.dart @@ -6,20 +6,72 @@ part of 'mess_menu_model.dart'; // JsonSerializableGenerator // ************************************************************************** -MessMenuModel _$MessMenuModelFromJson(Map json) => - MessMenuModel( - hostel: json['hostel'] as String? ?? 'Untitled Hostel', - meal: json['meal'] as String? ?? 'Untitled Meal', - menu: json['menu'] as String? ?? 'Untitled Menu', - day: json['day'] as String? ?? 'Untitled Day', - timing: json['timing'] as String? ?? 'Untitled Timing', - ); - -Map _$MessMenuModelToJson(MessMenuModel instance) => - { +MessMenu _$MessMenuFromJson(Map json) => MessMenu( + id: json['_id'] as String, + hostel: json['hostel'] as String, + monday: Day.fromJson(json['monday'] as Map), + tuesday: Day.fromJson(json['tuesday'] as Map), + wednesday: Day.fromJson(json['wednesday'] as Map), + thursday: Day.fromJson(json['thursday'] as Map), + friday: Day.fromJson(json['friday'] as Map), + saturday: Day.fromJson(json['saturday'] as Map), + sunday: Day.fromJson(json['sunday'] as Map), + v: json['v'] as int, +); + +Map _$MessMenuToJson(MessMenu instance) => { + '_id': instance.id, 'hostel': instance.hostel, - 'meal': instance.meal, - 'menu': instance.menu, + 'monday': instance.monday, + 'tuesday': instance.tuesday, + 'wednesday': instance.wednesday, + 'thursday': instance.thursday, + 'friday': instance.friday, + 'saturday': instance.saturday, + 'sunday': instance.sunday, + 'v': instance.v, +}; + +Day _$DayFromJson(Map json) => Day( + id: json['_id'] as String, + breakfast: MealType.fromJson(json['breakfast'] as Map), + lunch: MealType.fromJson(json['lunch'] as Map), + dinner: MealType.fromJson(json['dinner'] as Map), +); + +Map _$DayToJson(Day instance) => { + '_id': instance.id, + 'breakfast': instance.breakfast, + 'lunch': instance.lunch, + 'dinner': instance.dinner, +}; + +MealType _$MealTypeFromJson(Map json) => MealType( + id: json['_id'] as String, + mealDesription: json['mealDesription'] as String, + timing: json['timing'] as String, +); + +Map _$MealTypeToJson(MealType instance) => { + '_id': instance.id, + 'mealDesription': instance.mealDesription, 'timing': instance.timing, - 'day': instance.day, - }; +}; + +// MessMenuModel _$MessMenuModelFromJson(Map json) => +// MessMenuModel( +// hostel: json['hostel'] as String? ?? 'Untitled Hostel', +// meal: json['meal'] as String? ?? 'Untitled Meal', +// menu: json['menu'] as String? ?? 'Untitled Menu', +// day: json['day'] as String? ?? 'Untitled Day', +// timing: json['timing'] as String? ?? 'Untitled Timing', +// ); +// +// Map _$MessMenuModelToJson(MessMenuModel instance) => +// { +// 'hostel': instance.hostel, +// 'meal': instance.meal, +// 'menu': instance.menu, +// 'timing': instance.timing, +// 'day': instance.day, +// }; diff --git a/lib/models/timetable/bus_timing_model.dart b/lib/models/timetable/bus_timing_model.dart deleted file mode 100644 index 15bf95d5..00000000 --- a/lib/models/timetable/bus_timing_model.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'bus_timing_model.g.dart'; - -@JsonSerializable() -class BusTiming { - final List? weekend_campusToCity; - @JsonKey(defaultValue: '') - final String id; - @JsonKey(defaultValue: '') - final String busStop; - - @JsonKey(defaultValue: []) - final List? weekdays_campusToCity; - - @JsonKey(defaultValue: []) - final List? weekdays_cityToCampus; - - @JsonKey(defaultValue: []) - final List? weekend_cityToCampus; - - BusTiming({ - required this.weekend_campusToCity, - required this.id, - required this.busStop, - required this.weekdays_campusToCity, - required this.weekdays_cityToCampus, - required this.weekend_cityToCampus, - }); - factory BusTiming.fromJson(Map json) => - _$BusTimingFromJson(json); - - Map toJson() => _$BusTimingToJson(this); -} diff --git a/lib/models/timetable/bus_timing_model.g.dart b/lib/models/timetable/bus_timing_model.g.dart deleted file mode 100644 index f8a45211..00000000 --- a/lib/models/timetable/bus_timing_model.g.dart +++ /dev/null @@ -1,37 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'bus_timing_model.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -BusTiming _$BusTimingFromJson(Map json) => BusTiming( - weekend_campusToCity: json['weekend_campusToCity'] as List?, - id: json['id'] as String, - busStop: json['busStop'] as String, - weekdays_campusToCity: (json['weekdays_campusToCity'] as List?) - ?.map((e) => DateTime.parse(e as String)) - .toList(), - weekdays_cityToCampus: (json['weekdays_cityToCampus'] as List?) - ?.map((e) => DateTime.parse(e as String)) - .toList(), - weekend_cityToCampus: (json['weekend_cityToCampus'] as List?) - ?.map((e) => DateTime.parse(e as String)) - .toList(), - ); - -Map _$BusTimingToJson(BusTiming instance) => { - 'weekend_campusToCity': instance.weekend_campusToCity, - 'id': instance.id, - 'busStop': instance.busStop, - 'weekdays_campusToCity': instance.weekdays_campusToCity - ?.map((e) => e.toIso8601String()) - .toList(), - 'weekdays_cityToCampus': instance.weekdays_cityToCampus - ?.map((e) => e.toIso8601String()) - .toList(), - 'weekend_cityToCampus': instance.weekend_cityToCampus - ?.map((e) => e.toIso8601String()) - .toList(), - }; diff --git a/lib/models/timetable/ferry_timing_model.dart b/lib/models/timetable/ferry_timing_model.dart deleted file mode 100644 index a4446253..00000000 --- a/lib/models/timetable/ferry_timing_model.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'ferry_timing_model.g.dart'; - -@JsonSerializable() -class FerryTiming { - FerryTiming({ - required this.weekend_campusToCity, - required this.id, - required this.ferryGhat, - required this.weekdays_campusToCity, - required this.weekdays_cityToCampus, - required this.weekend_cityToCampus, - }); - - @JsonKey(defaultValue: '') - String id; - - @JsonKey(defaultValue: '') - String ferryGhat; - - @JsonKey(defaultValue: []) - List weekend_campusToCity; - - @JsonKey(defaultValue: []) - List weekdays_campusToCity; - - @JsonKey(defaultValue: []) - List weekdays_cityToCampus; - - @JsonKey(defaultValue: []) - List weekend_cityToCampus; - - factory FerryTiming.fromJson(Map json) => - _$FerryTimingFromJson(json); - - Map toJson() => _$FerryTimingToJson(this); -} diff --git a/lib/models/timetable/ferry_timing_model.g.dart b/lib/models/timetable/ferry_timing_model.g.dart deleted file mode 100644 index cca9eb65..00000000 --- a/lib/models/timetable/ferry_timing_model.g.dart +++ /dev/null @@ -1,46 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'ferry_timing_model.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FerryTiming _$FerryTimingFromJson(Map json) => FerryTiming( - weekend_campusToCity: (json['weekend_campusToCity'] as List?) - ?.map((e) => DateTime.parse(e as String)) - .toList() ?? - [], - id: json['id'] as String? ?? '', - ferryGhat: json['ferryGhat'] as String? ?? '', - weekdays_campusToCity: (json['weekdays_campusToCity'] as List?) - ?.map((e) => DateTime.parse(e as String)) - .toList() ?? - [], - weekdays_cityToCampus: (json['weekdays_cityToCampus'] as List?) - ?.map((e) => DateTime.parse(e as String)) - .toList() ?? - [], - weekend_cityToCampus: (json['weekend_cityToCampus'] as List?) - ?.map((e) => DateTime.parse(e as String)) - .toList() ?? - [], - ); - -Map _$FerryTimingToJson(FerryTiming instance) => - { - 'id': instance.id, - 'ferryGhat': instance.ferryGhat, - 'weekend_campusToCity': instance.weekend_campusToCity - .map((e) => e.toIso8601String()) - .toList(), - 'weekdays_campusToCity': instance.weekdays_campusToCity - .map((e) => e.toIso8601String()) - .toList(), - 'weekdays_cityToCampus': instance.weekdays_cityToCampus - .map((e) => e.toIso8601String()) - .toList(), - 'weekend_cityToCampus': instance.weekend_cityToCampus - .map((e) => e.toIso8601String()) - .toList(), - }; diff --git a/lib/models/travel/day_type_model.dart b/lib/models/travel/day_type_model.dart new file mode 100644 index 00000000..235a162a --- /dev/null +++ b/lib/models/travel/day_type_model.dart @@ -0,0 +1,21 @@ +// ignore_for_file: non_constant_identifier_names + +import 'package:json_annotation/json_annotation.dart'; + +part 'day_type_model.g.dart'; + +@JsonSerializable() +class DayType { + final List fromCampus; + final List toCampus; + DayType( + { + required this.fromCampus, + required this.toCampus, + } + ); + factory DayType.fromJson(Map json) => + _$DayTypeFromJson(json); + + Map toJson() => _$DayTypeToJson(this); +} diff --git a/lib/models/travel/day_type_model.g.dart b/lib/models/travel/day_type_model.g.dart new file mode 100644 index 00000000..35e7fc69 --- /dev/null +++ b/lib/models/travel/day_type_model.g.dart @@ -0,0 +1,22 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'day_type_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +DayType _$DayTypeFromJson(Map json) => DayType( + fromCampus: (json['fromCampus'] as List) + .map((e) => DateTime.parse(e as String)) + .toList(), + toCampus: (json['toCampus'] as List) + .map((e) => DateTime.parse(e as String)) + .toList(), + ); + +Map _$DayTypeToJson(DayType instance) => { + 'fromCampus': + instance.fromCampus.map((e) => e.toIso8601String()).toList(), + 'toCampus': instance.toCampus.map((e) => e.toIso8601String()).toList(), + }; diff --git a/lib/models/travel/ferry_data_model.dart b/lib/models/travel/ferry_data_model.dart deleted file mode 100644 index 31e49b5d..00000000 --- a/lib/models/travel/ferry_data_model.dart +++ /dev/null @@ -1,26 +0,0 @@ -// ignore_for_file: non_constant_identifier_names - -import 'package:json_annotation/json_annotation.dart'; - -part 'ferry_data_model.g.dart'; - -@JsonSerializable() -class FerryTimeData { - final String name; - final List MonToFri_GuwahatiToNorthGuwahati; - final List MonToFri_NorthGuwahatiToGuwahati; - final List Sunday_GuwahatiToNorthGuwahati; - final List Sunday_NorthGuwahatiToGuwahati; - - FerryTimeData( - this.name, - this.MonToFri_GuwahatiToNorthGuwahati, - this.MonToFri_NorthGuwahatiToGuwahati, - this.Sunday_GuwahatiToNorthGuwahati, - this.Sunday_NorthGuwahatiToGuwahati); - - factory FerryTimeData.fromJson(Map json) => - _$FerryTimeDataFromJson(json); - - Map toJson() => _$FerryTimeDataToJson(this); -} diff --git a/lib/models/travel/ferry_data_model.g.dart b/lib/models/travel/ferry_data_model.g.dart deleted file mode 100644 index 83b4dfe4..00000000 --- a/lib/models/travel/ferry_data_model.g.dart +++ /dev/null @@ -1,35 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'ferry_data_model.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FerryTimeData _$FerryTimeDataFromJson(Map json) => - FerryTimeData( - json['name'] as String, - (json['MonToFri_GuwahatiToNorthGuwahati'] as List) - .map((e) => e as String) - .toList(), - (json['MonToFri_NorthGuwahatiToGuwahati'] as List) - .map((e) => e as String) - .toList(), - (json['Sunday_GuwahatiToNorthGuwahati'] as List) - .map((e) => e as String) - .toList(), - (json['Sunday_NorthGuwahatiToGuwahati'] as List) - .map((e) => e as String) - .toList(), - ); - -Map _$FerryTimeDataToJson(FerryTimeData instance) => - { - 'name': instance.name, - 'MonToFri_GuwahatiToNorthGuwahati': - instance.MonToFri_GuwahatiToNorthGuwahati, - 'MonToFri_NorthGuwahatiToGuwahati': - instance.MonToFri_NorthGuwahatiToGuwahati, - 'Sunday_GuwahatiToNorthGuwahati': instance.Sunday_GuwahatiToNorthGuwahati, - 'Sunday_NorthGuwahatiToGuwahati': instance.Sunday_NorthGuwahatiToGuwahati, - }; diff --git a/lib/models/travel/travel_timing_model.dart b/lib/models/travel/travel_timing_model.dart new file mode 100644 index 00000000..cdcd9569 --- /dev/null +++ b/lib/models/travel/travel_timing_model.dart @@ -0,0 +1,31 @@ +import 'package:json_annotation/json_annotation.dart'; + +import 'day_type_model.dart'; + +part 'travel_timing_model.g.dart'; + +@JsonSerializable() +class TravelTiming { + final String id; + @JsonKey(defaultValue: '') + final String type; + @JsonKey(defaultValue: '') + final String stop; + @JsonKey(defaultValue: []) + final DayType weekend; + @JsonKey(defaultValue: []) + final DayType weekdays; + + + TravelTiming({ + required this.type, + required this.id, + required this.stop, + required this.weekend, + required this.weekdays, + }); + factory TravelTiming.fromJson(Map json) => + _$TravelTimingFromJson(json); + + Map toJson() => _$TravelTimingToJson(this); +} diff --git a/lib/models/travel/travel_timing_model.g.dart b/lib/models/travel/travel_timing_model.g.dart new file mode 100644 index 00000000..b8829b4a --- /dev/null +++ b/lib/models/travel/travel_timing_model.g.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'travel_timing_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +TravelTiming _$TravelTimingFromJson(Map json) => TravelTiming( + type: json['type'] as String? ?? '', + id: json['_id'] as String, + stop: json['stop'] as String? ?? '', + weekend: DayType.fromJson(json['weekend'] as Map), + weekdays:DayType.fromJson(json['weekdays'] as Map), + ); + +Map _$TravelTimingToJson(TravelTiming instance) => + { + '_id': instance.id, + 'type': instance.type, + 'stop': instance.stop, + 'weekend': instance.weekend, + 'weekdays': instance.weekdays, + }; diff --git a/lib/services/api.dart b/lib/services/api.dart index 62b268fb..6ca4da36 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -7,13 +7,13 @@ import 'package:onestop_dev/globals/endpoints.dart'; import 'package:onestop_dev/models/buy_sell/buy_model.dart'; import 'package:onestop_dev/models/lostfound/found_model.dart'; import 'package:onestop_dev/models/lostfound/lost_model.dart'; -import 'package:onestop_dev/models/timetable/bus_timing_model.dart'; -import 'package:onestop_dev/models/timetable/ferry_timing_model.dart'; import 'package:onestop_dev/models/timetable/registered_courses.dart'; - import 'package:onestop_dev/models/buy_sell/sell_model.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import '../models/food/mess_menu_model.dart'; +import '../models/travel/travel_timing_model.dart'; + class APIService { static Future postFeedbackData(Map data) async { String tag = data['type'] == 'Issue Report' ? 'bug' : 'enhancement'; @@ -432,65 +432,103 @@ class APIService { } } - static Future> getBusTiming() async { + static Future> getFerryTiming() async { try { final prefs = await SharedPreferences.getInstance(); late String jsonData; - if (prefs.getString('busTimings') != null) { - jsonData = prefs.getString('busTimings') ?? ''; + if (prefs.getString('ferryTimings') != null) { + jsonData = prefs.getString('ferryTimings') ?? ''; } else { + final res = await http.get( - Uri.parse(Endpoints.busStops), + Uri.parse('https://swc.iitg.ac.in/test/onestopapi/v2/ferryTimings'), headers: Endpoints.getHeader(), ); - prefs.setString('busTimings', res.body); - - jsonData = prefs.getString('busTimings') ?? ''; + prefs.setString('ferryTimings', res.body); + jsonData = prefs.getString('ferryTimings') ?? ''; + jsonData=res.body; } + List ferryTiming = json.decode(jsonData)['data']; + List ferryTimings = []; - List busTiming = json.decode(jsonData); - - List busTimings = []; - - for (var element in busTiming) { - busTimings.add(BusTiming.fromJson(element)); + for (var element in ferryTiming) { + ferryTimings.add(TravelTiming.fromJson(element)); } - return busTimings; + return ferryTimings; + } catch (e) { rethrow; } } - - static Future> getFerryTiming() async { - try { + static Future getMealData(String hostel, String day, String mealType,) async { + try{ final prefs = await SharedPreferences.getInstance(); - late String jsonData; - - if (prefs.getString('ferryTimings') != null) { - jsonData = prefs.getString('ferryTimings') ?? ''; + if (prefs.getString('messMenu') != null) { + jsonData = prefs.getString('messMenu') ?? ''; } else { final res = await http.get( - Uri.parse(Endpoints.ferryURL), + Uri.parse('https://swc.iitg.ac.in/test/onestopapi/v2/hostelsMessMenu'), headers: Endpoints.getHeader(), ); - prefs.setString('ferryTimings', res.body); + prefs.setString('messMenu', res.body); - jsonData = prefs.getString('ferryTimings') ?? ''; + jsonData = prefs.getString('messMenu') ?? res.body; + } + List answer = json.decode(jsonData)['details']; + var meal = answer.firstWhere( + (m) => m['hostel'].toString().trim().toLowerCase() == + hostel.toString().toLowerCase(), + orElse: () => 'no data' + ); + if(meal=='no data'){ + return MealType( + id: '', + mealDesription: 'Not updated by HMC', + timing: 'Oh no!' + ); } + return MealType( + id: meal[day.trim().toLowerCase()][mealType.trim() + .toLowerCase()]['_id'], + mealDesription: meal[day.trim().toLowerCase()][mealType.trim() + .toLowerCase()]['mealDesription'], + timing: meal[day.trim().toLowerCase()][mealType.trim() + .toLowerCase()]['timing'] + ); + }catch(e){ + rethrow; + } - List ferryTiming = json.decode(jsonData); + } + static Future> getBusTiming() async { + try { + final prefs = await SharedPreferences.getInstance(); - List ferryTimings = []; + late String jsonData; - for (var element in ferryTiming) { - ferryTimings.add(FerryTiming.fromJson(element)); + if (prefs.getString('busTimings') != null) { + jsonData = prefs.getString('busTimings') ?? ''; + } else { + final res = await http.get( + Uri.parse('https://swc.iitg.ac.in/test/onestopapi/v2/busstops'), + headers: Endpoints.getHeader(), + ); + prefs.setString('busTimings', res.body); + jsonData=res.body; + jsonData = prefs.getString('busTimings') ?? ''; } - return ferryTimings; + List busTiming = json.decode(jsonData)['data']; + List busTimings = []; + for (var element in busTiming) { + busTimings.add(TravelTiming.fromJson(element)); + } + return busTimings; } catch (e) { + rethrow; } } diff --git a/lib/services/data_provider.dart b/lib/services/data_provider.dart index e311a2d2..e49c4d29 100644 --- a/lib/services/data_provider.dart +++ b/lib/services/data_provider.dart @@ -7,7 +7,6 @@ import 'package:onestop_dev/models/food/mess_menu_model.dart'; import 'package:onestop_dev/models/food/restaurant_model.dart'; import 'package:onestop_dev/models/news/news_model.dart'; import 'package:onestop_dev/models/timetable/registered_courses.dart'; -import 'package:onestop_dev/models/travel/ferry_data_model.dart'; import 'package:onestop_dev/services/api.dart'; import 'package:onestop_dev/services/local_storage.dart'; @@ -100,37 +99,6 @@ class DataProvider { return people; } - static Future> getMessMenu() async { - // return Future.delayed(Duration(seconds: 10),() => throw Exception("hello")); - var cachedData = await LocalStorage.instance.getRecord(DatabaseRecords.messMenu); - if (cachedData == null) { - List> messMenuData = await APIService.getMessMenu(); - List answer = - messMenuData.map((e) => MessMenuModel.fromJson(e)).toList(); - await LocalStorage.instance.storeData(messMenuData, DatabaseRecords.messMenu); - return answer; - } - List answer = cachedData - .map((e) => MessMenuModel.fromJson(e as Map)) - .toList(); - return answer; - } - static Future> getFerryTimings() async { - var cachedData = await LocalStorage.instance.getRecord(DatabaseRecords.ferryTimings); - if (cachedData == null) { - List> ferryData = await APIService.getFerryData(); - await LocalStorage.instance.storeData(ferryData, DatabaseRecords.ferryTimings); - List answer = - ferryData.map((e) => FerryTimeData.fromJson(e)).toList(); - return answer; - } - List answer = []; - for (var element in cachedData) { - var x = element as Map; - answer.add(FerryTimeData.fromJson(x)); - } - return answer; - } } diff --git a/lib/stores/mess_store.dart b/lib/stores/mess_store.dart index 40ef0b99..d2b821d1 100644 --- a/lib/stores/mess_store.dart +++ b/lib/stores/mess_store.dart @@ -1,23 +1,18 @@ // ignore_for_file: library_private_types_in_public_api - import 'package:mobx/mobx.dart'; import 'package:onestop_dev/functions/food/get_day.dart'; import 'package:onestop_dev/models/food/mess_menu_model.dart'; +import 'package:onestop_dev/services/api.dart'; import 'package:onestop_dev/services/data_provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; - part 'mess_store.g.dart'; - class MessStore = _MessStore with _$MessStore; - abstract class _MessStore with Store { _MessStore() { setupReactions(); } - @observable - String selectedDay = getFormattedDay(); - + String selectedDay = getFormattedDayForMess(); @observable String selectedMeal = getMeal(); @@ -32,68 +27,50 @@ abstract class _MessStore with Store { } return "Dinner"; } - @observable - ObservableFuture selectedHostel = ObservableFuture(getSavedHostel()); - + ObservableFuture selectedHostel = ObservableFuture(getSavedHostel()) ; + @observable + MealType mealData= MealType(id: 'id', mealDesription: 'mealDesription', timing: 'timing'); @computed bool get hostelLoaded => selectedHostel.status == FutureStatus.fulfilled; - - @observable - MessMenuModel? selectedMessModel; - - static Future getSavedHostel() async { - var prefs = await SharedPreferences.getInstance(); - if (prefs.containsKey('hostel')) { - return prefs.getString('hostel') ?? "Kameng"; - } - return "Kameng"; - } - - @observable - ObservableFuture> allMessData = - ObservableFuture(DataProvider.getMessMenu()); - @action void setDay(String s) { selectedDay = s; } - @action void setMeal(String s) { selectedMeal = s; } - @action - void setHostel(String s) { + void setHostel(String s) { selectedHostel = ObservableFuture.value(s); + print(selectedHostel.value); + print("___________________________________"); } - @action - void setSelectedMessModel(MessMenuModel m) { - selectedMessModel = m; + void setmealData(MealType m) { + mealData = m; } - - void setupReactions() { - autorun((_) { - if (allMessData.status == FutureStatus.fulfilled && - selectedHostel.status == FutureStatus.fulfilled) { - var requiredModel = allMessData.value!.firstWhere( - (element) => (element.day - .toLowerCase() - .contains(selectedDay.toLowerCase()) && - element.hostel - .toLowerCase() - .contains(selectedHostel.value!.toLowerCase()) && - element.meal.toLowerCase() == selectedMeal.toLowerCase()), - orElse: () => MessMenuModel( - hostel: "", - meal: "", - menu: "Not updated by HMC.", - day: "", - timing: "Oh no!")); - setSelectedMessModel(requiredModel); + void setupReactions() async { + autorun((_) async{ + if(selectedHostel.status == FutureStatus.fulfilled){ + MealType requiredModel = await APIService.getMealData(selectedHostel.value! , selectedDay, selectedMeal); + setmealData(requiredModel); + }else{ + MealType requiredModel = await APIService.getMealData('kameng' , 'Monday', 'Breakfast'); + setmealData(requiredModel); } }); } -} + + static Future getSavedHostel() async{ + var prefs = await SharedPreferences.getInstance(); + if (prefs.containsKey('hostel')) { + if(prefs.getString('hostel')=="Brahma"){ + return 'Brahmaputra'; + } + return prefs.getString('hostel') ?? "Kameng"; + } + return "Kameng"; + } +} \ No newline at end of file diff --git a/lib/stores/mess_store.g.dart b/lib/stores/mess_store.g.dart index bb7fa502..b472dedc 100644 --- a/lib/stores/mess_store.g.dart +++ b/lib/stores/mess_store.g.dart @@ -14,11 +14,11 @@ mixin _$MessStore on _MessStore, Store { @override bool get hostelLoaded => (_$hostelLoadedComputed ??= Computed(() => super.hostelLoaded, - name: '_MessStore.hostelLoaded')) + name: '_MessStore.hostelLoaded')) .value; late final _$selectedDayAtom = - Atom(name: '_MessStore.selectedDay', context: context); + Atom(name: '_MessStore.selectedDay', context: context); @override String get selectedDay { @@ -34,7 +34,7 @@ mixin _$MessStore on _MessStore, Store { } late final _$selectedMealAtom = - Atom(name: '_MessStore.selectedMeal', context: context); + Atom(name: '_MessStore.selectedMeal', context: context); @override String get selectedMeal { @@ -50,7 +50,7 @@ mixin _$MessStore on _MessStore, Store { } late final _$selectedHostelAtom = - Atom(name: '_MessStore.selectedHostel', context: context); + Atom(name: '_MessStore.selectedHostel', context: context); @override ObservableFuture get selectedHostel { @@ -65,45 +65,29 @@ mixin _$MessStore on _MessStore, Store { }); } - late final _$selectedMessModelAtom = - Atom(name: '_MessStore.selectedMessModel', context: context); + late final _$mealDataAtom = + Atom(name: '_MessStore.mealData', context: context); @override - MessMenuModel? get selectedMessModel { - _$selectedMessModelAtom.reportRead(); - return super.selectedMessModel; + MealType get mealData { + _$mealDataAtom.reportRead(); + return super.mealData; } @override - set selectedMessModel(MessMenuModel? value) { - _$selectedMessModelAtom.reportWrite(value, super.selectedMessModel, () { - super.selectedMessModel = value; - }); - } - - late final _$allMessDataAtom = - Atom(name: '_MessStore.allMessData', context: context); - - @override - ObservableFuture> get allMessData { - _$allMessDataAtom.reportRead(); - return super.allMessData; - } - - @override - set allMessData(ObservableFuture> value) { - _$allMessDataAtom.reportWrite(value, super.allMessData, () { - super.allMessData = value; + set mealData(MealType value) { + _$mealDataAtom.reportWrite(value, super.mealData, () { + super.mealData = value; }); } late final _$_MessStoreActionController = - ActionController(name: '_MessStore', context: context); + ActionController(name: '_MessStore', context: context); @override void setDay(String s) { final _$actionInfo = - _$_MessStoreActionController.startAction(name: '_MessStore.setDay'); + _$_MessStoreActionController.startAction(name: '_MessStore.setDay'); try { return super.setDay(s); } finally { @@ -114,7 +98,7 @@ mixin _$MessStore on _MessStore, Store { @override void setMeal(String s) { final _$actionInfo = - _$_MessStoreActionController.startAction(name: '_MessStore.setMeal'); + _$_MessStoreActionController.startAction(name: '_MessStore.setMeal'); try { return super.setMeal(s); } finally { @@ -125,7 +109,7 @@ mixin _$MessStore on _MessStore, Store { @override void setHostel(String s) { final _$actionInfo = - _$_MessStoreActionController.startAction(name: '_MessStore.setHostel'); + _$_MessStoreActionController.startAction(name: '_MessStore.setHostel'); try { return super.setHostel(s); } finally { @@ -134,11 +118,11 @@ mixin _$MessStore on _MessStore, Store { } @override - void setSelectedMessModel(MessMenuModel m) { + void setmealData(MealType m) { final _$actionInfo = _$_MessStoreActionController.startAction( - name: '_MessStore.setSelectedMessModel'); + name: '_MessStore.setmealData'); try { - return super.setSelectedMessModel(m); + return super.setmealData(m); } finally { _$_MessStoreActionController.endAction(_$actionInfo); } @@ -150,8 +134,7 @@ mixin _$MessStore on _MessStore, Store { selectedDay: ${selectedDay}, selectedMeal: ${selectedMeal}, selectedHostel: ${selectedHostel}, -selectedMessModel: ${selectedMessModel}, -allMessData: ${allMessData}, +mealData: ${mealData}, hostelLoaded: ${hostelLoaded} '''; } diff --git a/lib/stores/travel_store.dart b/lib/stores/travel_store.dart index 797fb50b..5f46cd6f 100644 --- a/lib/stores/travel_store.dart +++ b/lib/stores/travel_store.dart @@ -2,7 +2,8 @@ import 'package:flutter/material.dart'; import 'package:mobx/mobx.dart'; -import 'package:onestop_dev/models/travel/ferry_data_model.dart'; +import 'package:onestop_dev/models/travel/travel_timing_model.dart'; +import 'package:onestop_dev/services/api.dart'; import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/widgets/travel/bus_details.dart'; import 'package:onestop_dev/widgets/travel/stops_list.dart'; @@ -28,8 +29,8 @@ abstract class _TravelStore with Store { String selectedFerryGhat = "Mazgaon"; @observable - ObservableFuture> ferryTimings = - ObservableFuture(DataProvider.getFerryTimings()); + ObservableFuture> ferryTimings = + ObservableFuture(APIService.getFerryTiming()); @action void setFerryDayType(String s) { diff --git a/lib/stores/travel_store.g.dart b/lib/stores/travel_store.g.dart index 5c606896..1e120daf 100644 --- a/lib/stores/travel_store.g.dart +++ b/lib/stores/travel_store.g.dart @@ -14,31 +14,31 @@ mixin _$TravelStore on _TravelStore, Store { @override String get ferryDataIndex => (_$ferryDataIndexComputed ??= Computed(() => super.ferryDataIndex, - name: '_TravelStore.ferryDataIndex')) + name: '_TravelStore.ferryDataIndex')) .value; Computed? _$busDayTypeIndexComputed; @override int get busDayTypeIndex => (_$busDayTypeIndexComputed ??= Computed(() => super.busDayTypeIndex, - name: '_TravelStore.busDayTypeIndex')) + name: '_TravelStore.busDayTypeIndex')) .value; Computed? _$busPageComputed; @override Widget get busPage => (_$busPageComputed ??= - Computed(() => super.busPage, name: '_TravelStore.busPage')) + Computed(() => super.busPage, name: '_TravelStore.busPage')) .value; Computed? _$isBusSelectedComputed; @override bool get isBusSelected => (_$isBusSelectedComputed ??= Computed(() => super.isBusSelected, - name: '_TravelStore.isBusSelected')) + name: '_TravelStore.isBusSelected')) .value; late final _$selectBusesorStopsAtom = - Atom(name: '_TravelStore.selectBusesorStops', context: context); + Atom(name: '_TravelStore.selectBusesorStops', context: context); @override int get selectBusesorStops { @@ -54,7 +54,7 @@ mixin _$TravelStore on _TravelStore, Store { } late final _$busDayTypeAtom = - Atom(name: '_TravelStore.busDayType', context: context); + Atom(name: '_TravelStore.busDayType', context: context); @override String get busDayType { @@ -70,7 +70,7 @@ mixin _$TravelStore on _TravelStore, Store { } late final _$ferryDirectionAtom = - Atom(name: '_TravelStore.ferryDirection', context: context); + Atom(name: '_TravelStore.ferryDirection', context: context); @override String get ferryDirection { @@ -86,7 +86,7 @@ mixin _$TravelStore on _TravelStore, Store { } late final _$ferryDayTypeAtom = - Atom(name: '_TravelStore.ferryDayType', context: context); + Atom(name: '_TravelStore.ferryDayType', context: context); @override String get ferryDayType { @@ -102,7 +102,7 @@ mixin _$TravelStore on _TravelStore, Store { } late final _$selectedFerryGhatAtom = - Atom(name: '_TravelStore.selectedFerryGhat', context: context); + Atom(name: '_TravelStore.selectedFerryGhat', context: context); @override String get selectedFerryGhat { @@ -118,23 +118,23 @@ mixin _$TravelStore on _TravelStore, Store { } late final _$ferryTimingsAtom = - Atom(name: '_TravelStore.ferryTimings', context: context); + Atom(name: '_TravelStore.ferryTimings', context: context); @override - ObservableFuture> get ferryTimings { + ObservableFuture> get ferryTimings { _$ferryTimingsAtom.reportRead(); return super.ferryTimings; } @override - set ferryTimings(ObservableFuture> value) { + set ferryTimings(ObservableFuture> value) { _$ferryTimingsAtom.reportWrite(value, super.ferryTimings, () { super.ferryTimings = value; }); } late final _$_TravelStoreActionController = - ActionController(name: '_TravelStore', context: context); + ActionController(name: '_TravelStore', context: context); @override void setFerryDayType(String s) { diff --git a/lib/widgets/food/mess/mess_meal.dart b/lib/widgets/food/mess/mess_meal.dart index dcd2f477..1ddb14ab 100644 --- a/lib/widgets/food/mess/mess_meal.dart +++ b/lib/widgets/food/mess/mess_meal.dart @@ -4,15 +4,12 @@ import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/stores/mess_store.dart'; import 'package:provider/provider.dart'; - class MessMeal extends StatelessWidget { const MessMeal({ Key? key, required this.mealName, }) : super(key: key); - final String mealName; - @override Widget build(BuildContext context) { final screenWidth = MediaQuery.of(context).size.width; @@ -36,11 +33,11 @@ class MessMeal extends StatelessWidget { mealName, style: selected ? MyFonts.w500 - .size(screenWidth <= 380 ? 13 : 14) - .setColor(kBlueGrey) + .size(screenWidth <= 380 ? 13 : 14) + .setColor(kBlueGrey) : MyFonts.w500 - .size(screenWidth <= 380 ? 13 : 14) - .setColor(const Color.fromRGBO(91, 146, 227, 1)), + .size(screenWidth <= 380 ? 13 : 14) + .setColor(const Color.fromRGBO(91, 146, 227, 1)), ), ); }), @@ -48,4 +45,4 @@ class MessMeal extends StatelessWidget { ), ); } -} +} \ No newline at end of file diff --git a/lib/widgets/food/mess/mess_menu.dart b/lib/widgets/food/mess/mess_menu.dart index 632b60a5..0891ad90 100644 --- a/lib/widgets/food/mess/mess_menu.dart +++ b/lib/widgets/food/mess/mess_menu.dart @@ -12,12 +12,12 @@ class MessMenu extends StatelessWidget { Key? key, }) : super(key: key); - final List days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; + final List days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; final List hostels = [ "Kameng", "Barak", "Lohit", - "Brahma", + "Brahmaputra", "Disang", "Manas", "Dihing", @@ -44,17 +44,18 @@ class MessMenu extends StatelessWidget { child: Padding( padding: const EdgeInsets.all(16), child: Row(children: [ - Expanded( + const Expanded( flex: 1, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: const [ + children: [ MessMeal(mealName: "Breakfast"), MessMeal(mealName: "Lunch"), MessMeal(mealName: "Dinner") ], - )), + ) + ), const SizedBox( width: 16, ), @@ -73,7 +74,7 @@ class MessMenu extends StatelessWidget { Expanded( flex: 1, child: Text( - messStore.selectedMessModel?.timing ?? "", + messStore.mealData.timing, style: MyFonts.w500.size(12).setColor(kGrey12), ), ), @@ -81,7 +82,7 @@ class MessMenu extends StatelessWidget { flex: 4, child: SingleChildScrollView( child: Text( - messStore.selectedMessModel?.menu ?? "", + messStore.mealData.mealDesription, style: MyFonts.w400 .size(14) .setColor(kWhite)))), @@ -98,15 +99,15 @@ class MessMenu extends StatelessWidget { return days .map( (value) => PopupMenuItem( - onTap: () { - messStore.setDay(value); - }, - value: value, - child: Text(value, - style: MyFonts.w500 - .setColor(kWhite)), - ), - ) + onTap: () { + messStore.setDay(value); + }, + value: value, + child: Text(value.substring(0,3), + style: MyFonts.w500 + .setColor(kWhite)), + ), + ) .toList(); }, offset: const Offset(1, 40), @@ -119,15 +120,15 @@ class MessMenu extends StatelessWidget { Radius.circular(20))), child: Row( mainAxisAlignment: - MainAxisAlignment.spaceAround, + MainAxisAlignment.spaceAround, mainAxisSize: MainAxisSize.min, children: [ - Text(messStore.selectedDay, + Text(messStore.selectedDay.substring(0,3), style: MyFonts.w500 .setColor(lBlue) .size(screenWidth <= 380 - ? 10 - : 13)), + ? 10 + : 13)), Icon( FluentIcons.chevron_down_24_regular, color: lBlue, @@ -143,22 +144,23 @@ class MessMenu extends StatelessWidget { .copyWith(cardColor: kBlueGrey), child: PopupMenuButton( constraints: - const BoxConstraints(maxHeight: 320), + const BoxConstraints(maxHeight: 320), itemBuilder: (context) { return hostels .map( (value) => PopupMenuItem( - onTap: () { - messStore.setHostel(value); - }, - value: value, - child: Text( - value, - style: MyFonts.w500 - .setColor(kWhite), - ), - ), - ) + onTap: () { + messStore.setHostel(value); + + }, + value: value, + child: Text( + value, + style: MyFonts.w500 + .setColor(kWhite), + ), + ), + ) .toList(); }, offset: const Offset(1, 40), @@ -171,15 +173,15 @@ class MessMenu extends StatelessWidget { Radius.circular(20))), child: Row( mainAxisAlignment: - MainAxisAlignment.spaceAround, + MainAxisAlignment.spaceAround, mainAxisSize: MainAxisSize.min, children: [ Text(messStore.selectedHostel.value!, style: MyFonts.w500 .setColor(lBlue) .size(screenWidth <= 380 - ? 10 - : 13)), + ? 10 + : 13)), Icon( FluentIcons.chevron_down_24_regular, color: lBlue, diff --git a/lib/widgets/mapbox/carousel_card.dart b/lib/widgets/mapbox/carousel_card.dart index 71af3353..17d75319 100644 --- a/lib/widgets/mapbox/carousel_card.dart +++ b/lib/widgets/mapbox/carousel_card.dart @@ -5,6 +5,8 @@ import 'package:onestop_dev/functions/food/get_day.dart'; import 'package:onestop_dev/functions/travel/next_time.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; +import 'package:onestop_dev/models/travel/travel_timing_model.dart'; +import 'package:onestop_dev/services/api.dart'; import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/stores/mapbox_store.dart'; import 'package:provider/provider.dart'; @@ -18,39 +20,58 @@ class CarouselCard extends StatelessWidget { @override Widget build(BuildContext context) { - Future getNextTime() async { + Future getNextTime() async { String today = getFormattedDay(); if (context.read().indexBusesorFerry == 0) { - var allBusTimes = await DataProvider.getBusTimings(); - List> busTimes = [[], []]; - allBusTimes.forEach((key, list) { - for (String time in list[0]) { - busTimes[0].add(time); + List allBusTimes = await APIService.getBusTiming(); + List weekdaysTimes= []; + List weekendTimes=[]; + for(var xyz in allBusTimes){ + int n=xyz.weekdays.fromCampus.length; + for(int i=0;i a.compareTo(b)); + for(var xyz in allBusTimes){ + int n=xyz.weekend.fromCampus.length; + for(int i=0;i parseTime(a).compareTo(parseTime(b))); - busTimes[1].sort((a, b) => parseTime(a).compareTo(parseTime(b))); + } + weekendTimes.sort((a, b) => a.compareTo(b)); + if (today == 'Fri') { - return 'Next Bus at: ${nextTime(busTimes[1], firstTime: busTimes[0][0])}'; + return 'Next Bus at: ${nextTime(weekdaysTimes, firstTime: weekendTimes[0].toString())}'; } else if (today == 'Sun') { - return 'Next Bus at: ${nextTime(busTimes[0], firstTime: busTimes[1][0])}'; + return 'Next Bus at: ${nextTime(weekendTimes, firstTime: weekdaysTimes[0].toString())}'; } else if (today == 'Sat') { - return 'Next Bus at: ${nextTime(busTimes[0])}'; + return 'Next Bus at: ${nextTime(weekendTimes)}'; } - return 'Next Bus at: ${nextTime(busTimes[1])}'; + return 'Next Bus at: ${nextTime(weekdaysTimes)}'; } else { - var ferryTimes = await DataProvider.getFerryTimings(); - var requiredModel = - ferryTimes.firstWhere((element) => element.name == name); + List ferryTimings = await APIService.getFerryTiming(); + List weekdaysTimes= []; + List weekendTimes=[]; + TravelTiming requiredModel = + ferryTimings.firstWhere((element) => element.stop == name); + + int n=requiredModel.weekdays.fromCampus.length; + for(int i=0;i a.compareTo(b)); + int p=requiredModel.weekend.fromCampus.length; + for(int i=0;i a.compareTo(b)); if (today == 'Sat') { - return 'Next Ferry at: ${nextTime(requiredModel.MonToFri_NorthGuwahatiToGuwahati, firstTime: requiredModel.Sunday_NorthGuwahatiToGuwahati[0])}'; + return 'Next Ferry at: ${nextTime(weekdaysTimes, firstTime: weekendTimes[0].toString())}'; } else if (today == 'Sun') { - return 'Next Ferry at: ${nextTime(requiredModel.Sunday_NorthGuwahatiToGuwahati, firstTime: requiredModel.MonToFri_NorthGuwahatiToGuwahati[0])}'; + return 'Next Ferry at: ${nextTime(weekendTimes, firstTime: weekdaysTimes[0].toString())}'; } - return 'Next Ferry at: ${nextTime(requiredModel.MonToFri_NorthGuwahatiToGuwahati)}'; + return 'Next Ferry at: ${nextTime(weekdaysTimes)}'; } } @@ -63,9 +84,9 @@ class CarouselCard extends StatelessWidget { borderRadius: const BorderRadius.all(Radius.circular(20)), border: Border.all( color: - (context.read().selectedCarouselIndex == index) - ? lBlue5 - : kTileBackground), + (context.read().selectedCarouselIndex == index) + ? lBlue5 + : kTileBackground), ), child: Padding( padding: const EdgeInsets.all(10.0), diff --git a/lib/widgets/mapbox/map_box.dart b/lib/widgets/mapbox/map_box.dart index 86cad3b2..bd6c837e 100644 --- a/lib/widgets/mapbox/map_box.dart +++ b/lib/widgets/mapbox/map_box.dart @@ -26,7 +26,6 @@ class MapBox extends StatefulWidget { DateTime now = DateTime.now(); String formattedTime = DateFormat.jm().format(now); - class _MapBoxState extends State { String mapString = ''; late GoogleMapController controller; @@ -58,9 +57,9 @@ class _MapBoxState extends State { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text( - "Could not fetch your current location", - style: MyFonts.w500, - ))); + "Could not fetch your current location", + style: MyFonts.w500, + ))); return const LatLng(26.192613073419974, 91.69907177061708); } return coordinates; @@ -92,7 +91,7 @@ class _MapBoxState extends State { gestureRecognizers: < Factory>{ Factory( - () => EagerGestureRecognizer()) + () => EagerGestureRecognizer()) }, onMapCreated: (mapcontroller) { controller = mapcontroller; @@ -272,7 +271,7 @@ class _MapBoxState extends State { await availableMap.showDirections( originTitle: 'User Location', destinationTitle: - mapStore.selectedCarouselName, + mapStore.selectedCarouselName, directionsMode: DirectionsMode.walking, destination: Coords( mapStore @@ -285,10 +284,10 @@ class _MapBoxState extends State { if (!mounted) return; ScaffoldMessenger.of(context) .showSnackBar(SnackBar( - content: Text( - "Could not open map.", - style: MyFonts.w500, - ))); + content: Text( + "Could not open map.", + style: MyFonts.w500, + ))); } }, mini: true, @@ -319,37 +318,37 @@ class _MapBoxState extends State { ), (!mapStore.isTravelPage) ? Observer(builder: (context) { - return CarouselSlider( - items: mapStore.carouselCards - .map((e) => GestureDetector( - child: mapStore.selectedCarouselIndex == - (e as CarouselCard).index - ? e - : ColorFiltered( - colorFilter: ColorFilter.mode( - Colors.grey.shade600, - BlendMode.modulate), - child: e, - ), - onTap: () { - mapStore.selectedCarousel(e.index); - mapStore.zoomTwoMarkers( - mapStore.selectedCarouselLatLng, - LatLng(mapStore.userlat, - mapStore.userlong), - 120.0); - }, - )) - .toList(), - options: CarouselOptions( - height: 100, - viewportFraction: 0.7, - initialPage: 0, - enableInfiniteScroll: false, - scrollDirection: Axis.horizontal, - ), - ); - }) + return CarouselSlider( + items: mapStore.carouselCards + .map((e) => GestureDetector( + child: mapStore.selectedCarouselIndex == + (e as CarouselCard).index + ? e + : ColorFiltered( + colorFilter: ColorFilter.mode( + Colors.grey.shade600, + BlendMode.modulate), + child: e, + ), + onTap: () { + mapStore.selectedCarousel(e.index); + mapStore.zoomTwoMarkers( + mapStore.selectedCarouselLatLng, + LatLng(mapStore.userlat, + mapStore.userlong), + 120.0); + }, + )) + .toList(), + options: CarouselOptions( + height: 100, + viewportFraction: 0.7, + initialPage: 0, + enableInfiniteScroll: false, + scrollDirection: Axis.horizontal, + ), + ); + }) : const SizedBox(), ], ), diff --git a/lib/widgets/travel/bus_details.dart b/lib/widgets/travel/bus_details.dart index a4bcfb44..b0c38bb1 100644 --- a/lib/widgets/travel/bus_details.dart +++ b/lib/widgets/travel/bus_details.dart @@ -3,8 +3,13 @@ import 'package:flutter/material.dart'; import 'package:onestop_dev/functions/travel/has_left.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; +import 'package:onestop_dev/models/travel/travel_timing_model.dart'; +import 'package:onestop_dev/services/api.dart'; import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; +import 'package:provider/provider.dart'; +import '../../functions/travel/next_time.dart'; +import '../../stores/travel_store.dart'; import 'timing_tile.dart'; class BusDetails extends StatefulWidget { @@ -19,8 +24,7 @@ class BusDetails extends StatefulWidget { class _BusDetailsState extends State { bool isCity = false; bool isCampus = false; - Map>> busTime = {}; - + List? busTime = []; @override void initState() { super.initState(); @@ -28,11 +32,12 @@ class _BusDetailsState extends State { @override Widget build(BuildContext context) { - return FutureBuilder( - future: DataProvider.getBusTimings(), + var daytype = context.read().busDayType; + return FutureBuilder>( + future: APIService.getBusTiming(), builder: (context, snapshot) { if (snapshot.hasData) { - busTime = snapshot.data as Map>>; + busTime = snapshot.data; return Column( children: [ GestureDetector( @@ -60,36 +65,34 @@ class _BusDetailsState extends State { ), ), isCity - ? Column( - children: busTime.entries.map((entry) { - if ((busTime[entry.key]![widget.index].isEmpty)) { - return Container(); - } - return Column( - children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 5), - child: Text( - "To ${entry.key}", - style: MyFonts.w500.setColor(kWhite), - ), + ?Column( + children: [ + Padding( + padding: + const EdgeInsets.symmetric(vertical: 5), + child: Text( + "To ${busTime![0].stop}", + style: MyFonts.w500.setColor(kWhite), + ), + ), + ListView.builder( + shrinkWrap: true, + physics: const ClampingScrollPhysics(), + itemCount:daytype == 'Weekdays' ?busTime![0].weekdays.fromCampus.length:busTime![0].weekend.fromCampus.length, + itemBuilder:(BuildContext context, int index){ + return Padding( + padding: const EdgeInsets.symmetric(vertical: 5), + child: TimingTile( + time: daytype == 'Weekdays' ? formatTime(busTime![0].weekdays.fromCampus[index]):formatTime(busTime![0].weekend.fromCampus[index]), + isLeft: daytype=='Weekdays'? hasLeft(busTime![0].weekdays.fromCampus[index]):hasLeft(busTime![0].weekend.fromCampus[index]), + icon: FluentIcons.vehicle_bus_24_filled, + ), - Column( - children: - busTime[entry.key]![widget.index].map((e) { - return Padding( - padding: - const EdgeInsets.symmetric(vertical: 5), - child: TimingTile( - time: e, - isLeft: hasLeft(e.toString()), - icon: FluentIcons.vehicle_bus_24_filled, - ), - ); - }).toList()), - ], - ); - }).toList()) + ); + } + ), + ], + ) : Container(), GestureDetector( onTap: () { @@ -117,35 +120,33 @@ class _BusDetailsState extends State { ), isCampus ? Column( - children: busTime.entries.map((entry) { - if ((busTime[entry.key]![widget.index + 2].isEmpty)) { - return Container(); - } - return Column( - children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 5), - child: Text( - "From ${entry.key}", - style: MyFonts.w500.setColor(kWhite), - ), + children: [ + Padding( + padding: + const EdgeInsets.symmetric(vertical: 5), + child: Text( + "From ${busTime![0].stop}", + style: MyFonts.w500.setColor(kWhite), + ), + ), + ListView.builder( + shrinkWrap: true, + physics: const ClampingScrollPhysics(), + itemCount:daytype == 'Weekdays' ?busTime![0].weekdays.toCampus.length : busTime![0].weekend.toCampus.length, + itemBuilder:(BuildContext context, int index){ + return Padding( + padding: const EdgeInsets.symmetric(vertical: 5), + child: TimingTile( + time: daytype == 'Weekdays' ? formatTime(busTime![0].weekdays.toCampus[index]):formatTime(busTime![0].weekend.toCampus[index]), + isLeft: daytype=='Weekdays'?hasLeft(busTime![0].weekdays.toCampus[index]):hasLeft(busTime![0].weekend.toCampus[index]), + icon: FluentIcons.vehicle_bus_24_filled, + ), - Column( - children: busTime[entry.key]![widget.index + 2] - .map((e) { - return Padding( - padding: - const EdgeInsets.symmetric(vertical: 5), - child: TimingTile( - time: e, - isLeft: hasLeft(e.toString()), - icon: FluentIcons.vehicle_bus_24_filled, - ), - ); - }).toList()), - ], - ); - }).toList()) + ); + } + ), + ], + ) : Container(), ], ); diff --git a/lib/widgets/travel/ferry_details.dart b/lib/widgets/travel/ferry_details.dart index d5b9bca6..d9a6b2a8 100644 --- a/lib/widgets/travel/ferry_details.dart +++ b/lib/widgets/travel/ferry_details.dart @@ -6,6 +6,7 @@ import 'package:mobx/mobx.dart'; import 'package:onestop_dev/functions/travel/has_left.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; +import 'package:onestop_dev/models/travel/travel_timing_model.dart'; import 'package:onestop_dev/pages/travel/data.dart'; import 'package:onestop_dev/stores/mapbox_store.dart'; import 'package:onestop_dev/stores/travel_store.dart'; @@ -13,22 +14,24 @@ import 'package:onestop_dev/widgets/travel/timing_tile.dart'; import 'package:onestop_dev/widgets/travel/travel_drop_down.dart'; import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; import 'package:provider/provider.dart'; +import '../../functions/travel/next_time.dart'; class FerryDetails extends StatelessWidget { const FerryDetails({Key? key}) : super(key: key); - @override Widget build(BuildContext context) { return Observer(builder: (context) { + var direction = context.read().ferryDirection; + var daytype = context.read().ferryDayType; if (context.read().ferryTimings.status == FutureStatus.fulfilled) { - var ferryModel = context + TravelTiming ferryModel = context .read() .ferryTimings .value! .firstWhere((element) => - element.name == context.read().selectedFerryGhat); - var ferryMap = ferryModel.toJson(); + element.stop == context.read().selectedFerryGhat); + // var ferryMap = ferryModel.toJson(); return Column(children: [ SizedBox( height: 50, @@ -36,45 +39,45 @@ class FerryDetails extends StatelessWidget { scrollDirection: Axis.horizontal, children: ferryGhats .map((e) => TextButton( - onPressed: () { - context.read().setFerryGhat(e['name']); - var mapboxStore = context.read(); - int i = mapboxStore.allLocationData.indexWhere( - (element) => e['name'] == element['name']); - mapboxStore.selectedCarousel(i); - mapboxStore.zoomTwoMarkers( - mapboxStore.selectedCarouselLatLng, - LatLng(mapboxStore.userlat, mapboxStore.userlong), - 90.0); - }, - child: ClipRRect( - borderRadius: const BorderRadius.all( - Radius.circular(40), - ), - child: Container( - color: (context - .read() - .selectedFerryGhat == - e['name']) - ? lBlue2 - : kGrey2, - child: Center( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - e['name'], - style: (context - .read() - .selectedFerryGhat == - e['name']) - ? MyFonts.w500.setColor(kBlueGrey) - : MyFonts.w500.setColor(kWhite), - ), - ), - ), - ), + onPressed: () { + context.read().setFerryGhat(e['name']); + var mapboxStore = context.read(); + int i = mapboxStore.allLocationData.indexWhere( + (element) => e['name'] == element['name']); + mapboxStore.selectedCarousel(i); + mapboxStore.zoomTwoMarkers( + mapboxStore.selectedCarouselLatLng, + LatLng(mapboxStore.userlat, mapboxStore.userlong), + 90.0); + }, + child: ClipRRect( + borderRadius: const BorderRadius.all( + Radius.circular(40), + ), + child: Container( + color: (context + .read() + .selectedFerryGhat == + e['name']) + ? lBlue2 + : kGrey2, + child: Center( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + e['name'], + style: (context + .read() + .selectedFerryGhat == + e['name']) + ? MyFonts.w500.setColor(kBlueGrey) + : MyFonts.w500.setColor(kWhite), ), - )) + ), + ), + ), + ), + )) .toList(), ), ), @@ -94,23 +97,44 @@ class FerryDetails extends StatelessWidget { ], ), ), - Column( - children: (ferryMap[context.read().ferryDataIndex] - as List) - .map((e) { - return Padding( - padding: const EdgeInsets.fromLTRB(0, 5, 0, 5), - child: TimingTile( - time: e, - isLeft: hasLeft(e.toString()), - icon: FluentIcons.vehicle_ship_24_filled, - ), - ); - }).toList(), - ) + if (daytype=="Sunday") ...[ + ListView.builder( + shrinkWrap: true, + physics: const ClampingScrollPhysics(), + itemCount: direction=="Campus to City"? ferryModel.weekend.fromCampus.length:ferryModel.weekend.toCampus.length, + itemBuilder:(BuildContext context, int index){ + return Padding( + padding: const EdgeInsets.symmetric(vertical: 5), + child: TimingTile( + time: direction=="Campus to City" ? formatTime(ferryModel.weekend.fromCampus[index]):formatTime(ferryModel.weekend.toCampus[index]), + isLeft: direction=="Campus to City"? hasLeft(ferryModel.weekend.fromCampus[index]):hasLeft(ferryModel.weekend.toCampus[index]), + icon: FluentIcons.vehicle_bus_24_filled, + + ), + ); + } + + ), + ] else ...[ + ListView.builder( + shrinkWrap: true, + physics: const ClampingScrollPhysics(), + itemCount: direction=="Campus to City"? ferryModel.weekdays.fromCampus.length:ferryModel.weekdays.toCampus.length, + itemBuilder:(BuildContext context, int index){ + return Padding( + padding: const EdgeInsets.symmetric(vertical: 5), + child: TimingTile( + time: direction=="Campus to City" ? formatTime(ferryModel.weekdays.fromCampus[index]):formatTime(ferryModel.weekdays.toCampus[index]), + isLeft: direction=="Campus to City"? hasLeft(ferryModel.weekdays.fromCampus[index]):hasLeft(ferryModel.weekdays.toCampus[index]), + icon: FluentIcons.vehicle_bus_24_filled, + + ), + ); + } + ), + ] ]); } - return ListShimmer( count: 3, height: 50, @@ -118,3 +142,4 @@ class FerryDetails extends StatelessWidget { }); } } + diff --git a/lib/widgets/travel/next_time_card.dart b/lib/widgets/travel/next_time_card.dart index 38d1c887..1cc7913f 100644 --- a/lib/widgets/travel/next_time_card.dart +++ b/lib/widgets/travel/next_time_card.dart @@ -7,10 +7,13 @@ import 'package:onestop_dev/functions/travel/duration_left.dart'; import 'package:onestop_dev/functions/travel/next_time.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; +import 'package:onestop_dev/services/api.dart'; import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/stores/mapbox_store.dart'; import 'package:provider/provider.dart'; +import '../../models/travel/travel_timing_model.dart'; + class NextTimeCard extends StatefulWidget { const NextTimeCard({Key? key}) : super(key: key); @@ -25,39 +28,61 @@ class _NextTimeCardState extends State { Future getNextTime() async { String today = getFormattedDay(); if (mapStore.indexBusesorFerry == 0) { - var allBusTimes = await DataProvider.getBusTimings(); - List> busTimes = [[], []]; - allBusTimes.forEach((key, list) { - for (String time in list[0]) { - busTimes[0].add(time); + var allBusTimes = await APIService.getBusTiming(); + List weekdaysTimes= []; + List weekendTimes=[]; + for(var xyz in allBusTimes){ + int n=xyz.weekdays.fromCampus.length; + for(int i=0;i a.compareTo(b)); + for(var xyz in allBusTimes){ + int n=xyz.weekend.fromCampus.length; + for(int i=0;i parseTime(a).compareTo(parseTime(b))); - busTimes[1].sort((a, b) => parseTime(a).compareTo(parseTime(b))); + } + weekendTimes.sort((a, b) => a.compareTo(b)); + List> busTimes = [[], []]; if (today == 'Fri') { - return nextTime(busTimes[1], firstTime: busTimes[0][0]); + return nextTime(weekdaysTimes, firstTime: weekendTimes[0].toString()); } else if (today == 'Sun') { - return nextTime(busTimes[0], firstTime: busTimes[1][0]); + return nextTime(weekendTimes, firstTime:weekdaysTimes[0].toString()); } else if (today == 'Sat') { - return nextTime(busTimes[0]); + return nextTime(weekendTimes); } - return nextTime(busTimes[1]); + return nextTime(weekdaysTimes); } else { - var ferryTimes = await DataProvider.getFerryTimings(); - var requiredModel = ferryTimes.firstWhere((element) => - element.name == - mapStore.allLocationData[mapStore.selectedCarouselIndex]['name']); + List ferryTimings = await APIService.getFerryTiming(); + List weekdaysTimes= []; + List weekendTimes=[]; + TravelTiming requiredModel = + ferryTimings.firstWhere((element) => element.stop == mapStore.allLocationData[mapStore.selectedCarouselIndex]['name']); + + int n=requiredModel.weekdays.fromCampus.length; + for(int i=0;i a.compareTo(b)); + int p=requiredModel.weekend.fromCampus.length; + for(int i=0;i a.compareTo(b)); + // var ferryTimes = await DataProvider.getFerryTimings(); + // var requiredModel = ferryTimes.firstWhere((element) => + // element.name == + // mapStore.allLocationData[mapStore.selectedCarouselIndex]['name']); if (today == 'Sat') { - return nextTime(requiredModel.MonToFri_NorthGuwahatiToGuwahati, - firstTime: requiredModel.Sunday_NorthGuwahatiToGuwahati[0]); + return nextTime(weekdaysTimes, + firstTime: weekendTimes[0].toString()); } else if (today == 'Sun') { - return nextTime(requiredModel.Sunday_NorthGuwahatiToGuwahati, - firstTime: requiredModel.MonToFri_NorthGuwahatiToGuwahati[0]); + return nextTime(weekendTimes, + firstTime: weekdaysTimes[0].toString()); } - return nextTime(requiredModel.MonToFri_NorthGuwahatiToGuwahati); + return nextTime(weekdaysTimes); } } @@ -78,13 +103,13 @@ class _NextTimeCardState extends State { radius: 20, child: (context.read().indexBusesorFerry == 1) ? const Icon( - FluentIcons.vehicle_ship_24_filled, - color: kBlueGrey, - ) + FluentIcons.vehicle_ship_24_filled, + color: kBlueGrey, + ) : const Icon( - FluentIcons.vehicle_bus_24_filled, - color: kBlueGrey, - ), + FluentIcons.vehicle_bus_24_filled, + color: kBlueGrey, + ), ), title: Text( mapStore.allLocationData[mapStore.selectedCarouselIndex]['name'], @@ -101,13 +126,13 @@ class _NextTimeCardState extends State { width: 80, child: (mapStore.indexBusesorFerry == 0) ? Text( - 'Next Bus in ${durationLeft(snapshot.data.toString())}', - style: MyFonts.w500.setColor(lBlue2).size(14), - ) + 'Next Bus in ${durationLeft(snapshot.data.toString())}', + style: MyFonts.w500.setColor(lBlue2).size(14), + ) : Text( - 'Next Ferry in ${durationLeft(snapshot.data.toString())}', - style: MyFonts.w500.setColor(lBlue2).size(14), - )); + 'Next Ferry in ${durationLeft(snapshot.data.toString())}', + style: MyFonts.w500.setColor(lBlue2).size(14), + )); } return const CircularProgressIndicator(); }), diff --git a/lib/widgets/travel/stops_bus_details.dart b/lib/widgets/travel/stops_bus_details.dart index 818c8b2d..d0aa3795 100644 --- a/lib/widgets/travel/stops_bus_details.dart +++ b/lib/widgets/travel/stops_bus_details.dart @@ -71,10 +71,10 @@ class StopsBusDetails extends StatelessWidget { context.read().isBusSelected ? TravelDropDown( - value: context.read().busDayType, - onChange: context.read().setBusDayString, - items: const ['Weekdays', 'Weekends'], - ) + value: context.read().busDayType, + onChange: context.read().setBusDayString, + items: const ['Weekdays', 'Weekends'], + ) : GestureDetector( onTap: (){ showDialog(context: context, builder: (_) => const TrackingDailog()); diff --git a/lib/widgets/travel/stops_list.dart b/lib/widgets/travel/stops_list.dart index d9ec2013..e112a738 100644 --- a/lib/widgets/travel/stops_list.dart +++ b/lib/widgets/travel/stops_list.dart @@ -7,6 +7,8 @@ import 'package:onestop_dev/functions/travel/distance.dart'; import 'package:onestop_dev/functions/travel/next_time.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; +import 'package:onestop_dev/models/travel/travel_timing_model.dart'; +import 'package:onestop_dev/services/api.dart'; import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/stores/mapbox_store.dart'; import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; @@ -23,23 +25,44 @@ class BusStopList extends StatelessWidget { itemCount: context.read().allLocationData.length, itemBuilder: (BuildContext context, int index) { var mapStore = context.read(); - return FutureBuilder( - future: DataProvider.getBusTimings(), + return FutureBuilder>( + future: APIService.getBusTiming(), builder: (context, snapshot) { if (snapshot.hasData) { - var allBusTimes = - (snapshot.data as Map>>); - List> busTime = [[], []]; - allBusTimes.forEach((key, list) { - for (String time in list[0]) { - busTime[0].add(time); + List? busTime = snapshot.data ; + List weekdaysTimes=[]; + List weekendTimes=[]; + for(var xyz in busTime!){ + int n=xyz.weekdays.fromCampus.length; + for(int i=0;i a.compareTo(b)); + for(var xyz in busTime){ + int n=xyz.weekend.fromCampus.length; + for(int i=0;i parseTime(a).compareTo(parseTime(b))); - busTime[1].sort((a, b) => parseTime(a).compareTo(parseTime(b))); + } + weekendTimes.sort((a, b) => a.compareTo(b)); + // List allBusTimes = + // (snapshot.data as List); + // List> busTime = [[], []]; + // allBusTimes.forEach((key, list) { + // for (String time in list[0]) { + // busTime[0].add(time); + // } + // for (String time in list[1]) { + // busTime[1].add(time); + // } + // }); + // busTime.sort((a, b) { + // return parseTime(a).compareTo(parseTime(b)); + // }); + // busTime[1].sort((a, b) { + // return parseTime(a).compareTo(parseTime(b)); + // }); return Padding( padding: const EdgeInsets.only(top: 4.0, bottom: 4.0), child: GestureDetector( @@ -48,9 +71,9 @@ class BusStopList extends StatelessWidget { mapStore.zoomTwoMarkers( LatLng( mapStore.allLocationData[ - mapStore.selectedCarouselIndex]['lat'], + mapStore.selectedCarouselIndex]['lat'], mapStore.allLocationData[ - mapStore.selectedCarouselIndex]['long']), + mapStore.selectedCarouselIndex]['long']), LatLng(mapStore.userlat, mapStore.userlong), 100.0); }, @@ -60,7 +83,7 @@ class BusStopList extends StatelessWidget { decoration: BoxDecoration( color: kTileBackground, borderRadius: - const BorderRadius.all(Radius.circular(20)), + const BorderRadius.all(Radius.circular(20)), border: Border.all( color: (mapStore.selectedCarouselIndex == index) ? lBlue5 @@ -108,14 +131,14 @@ class BusStopList extends StatelessWidget { // trailing: Text( (getFormattedDay() == 'Fri') - ? nextTime(busTime[1], - firstTime: busTime[0][0]) + ? nextTime(weekendTimes, + firstTime: weekendTimes[0].toString()) : (getFormattedDay() == 'Sun') - ? nextTime(busTime[0], - firstTime: busTime[1][0]) - : (getFormattedDay() == 'Sat') - ? nextTime(busTime[0]) - : nextTime(busTime[1]), + ? nextTime(weekendTimes, + firstTime: weekdaysTimes[0].toString()) + : (getFormattedDay() == 'Sat') + ? nextTime(weekendTimes) + : nextTime(weekdaysTimes), style: MyFonts.w500.setColor(lBlue2), )), ); diff --git a/lib/widgets/travel/timing_tile.dart b/lib/widgets/travel/timing_tile.dart index db0764cd..3b982398 100644 --- a/lib/widgets/travel/timing_tile.dart +++ b/lib/widgets/travel/timing_tile.dart @@ -34,13 +34,13 @@ class TimingTile extends StatelessWidget { ), trailing: isLeft ? Text( - 'Left', - style: MyFonts.w500.setColor(kGrey11), - ) + 'Left', + style: MyFonts.w500.setColor(kGrey11), + ) : const SizedBox( - height: 0, - width: 0, - ), + height: 0, + width: 0, + ), ), ); } diff --git a/pubspec.yaml b/pubspec.yaml index 4bad1a79..44b65327 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -47,7 +47,7 @@ dependencies: cookie_jar: 3.0.1 provider: ^6.0.2 http: ^0.13.4 - dio: ^5.0.3 + dio: ^5.1.2 file_picker: ^5.2.5 shared_preferences: ^2.0.12 barcode_widget: ^2.0.3 From c2a02dc4a2da5b9abc794ab0241e27a656079f60 Mon Sep 17 00:00:00 2001 From: Ashutosh-777 Date: Sun, 21 May 2023 16:15:52 +0530 Subject: [PATCH 31/82] minor --- lib/services/api.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/services/api.dart b/lib/services/api.dart index 6ca4da36..6f626f4f 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -443,7 +443,7 @@ class APIService { } else { final res = await http.get( - Uri.parse('https://swc.iitg.ac.in/test/onestopapi/v2/ferryTimings'), + Uri.parse(Endpoints.ferryURL), headers: Endpoints.getHeader(), ); @@ -471,7 +471,7 @@ class APIService { jsonData = prefs.getString('messMenu') ?? ''; } else { final res = await http.get( - Uri.parse('https://swc.iitg.ac.in/test/onestopapi/v2/hostelsMessMenu'), + Uri.parse(Endpoints.messURL), headers: Endpoints.getHeader(), ); prefs.setString('messMenu', res.body); @@ -514,7 +514,7 @@ class APIService { jsonData = prefs.getString('busTimings') ?? ''; } else { final res = await http.get( - Uri.parse('https://swc.iitg.ac.in/test/onestopapi/v2/busstops'), + Uri.parse(Endpoints.busURL), headers: Endpoints.getHeader(), ); prefs.setString('busTimings', res.body); From eec3b0cfd176fa35433c0dadabb3f84c64193507 Mon Sep 17 00:00:00 2001 From: Ashutosh-777 Date: Sun, 21 May 2023 19:53:35 +0530 Subject: [PATCH 32/82] minor --- lib/models/food/mess_menu_model.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/models/food/mess_menu_model.dart b/lib/models/food/mess_menu_model.dart index 69fdb87a..d459052a 100644 --- a/lib/models/food/mess_menu_model.dart +++ b/lib/models/food/mess_menu_model.dart @@ -51,12 +51,12 @@ class Day { @JsonSerializable() class MealType { final String id; - final String mealDesription; + final String mealDescription; final String timing; MealType({ required this.id, - required this.mealDesription, + required this.mealDescription, required this.timing, }); factory MealType.fromJson(Map json) => _$MealTypeFromJson(json); From 4bb0075149696afc320ee737b416006924bb96f3 Mon Sep 17 00:00:00 2001 From: Ashutosh-777 Date: Sun, 21 May 2023 19:54:13 +0530 Subject: [PATCH 33/82] minor --- lib/models/food/mess_menu_model.g.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/models/food/mess_menu_model.g.dart b/lib/models/food/mess_menu_model.g.dart index 63313aeb..537b897c 100644 --- a/lib/models/food/mess_menu_model.g.dart +++ b/lib/models/food/mess_menu_model.g.dart @@ -48,13 +48,13 @@ Map _$DayToJson(Day instance) => { MealType _$MealTypeFromJson(Map json) => MealType( id: json['_id'] as String, - mealDesription: json['mealDesription'] as String, + mealDescription: json['mealDescription'] as String, timing: json['timing'] as String, ); Map _$MealTypeToJson(MealType instance) => { '_id': instance.id, - 'mealDesription': instance.mealDesription, + 'mealDescription': instance.mealDescription, 'timing': instance.timing, }; From 02e0fc29d5f2c283034515f107d5b32485b5acb1 Mon Sep 17 00:00:00 2001 From: Ashutosh-777 Date: Sun, 21 May 2023 19:54:51 +0530 Subject: [PATCH 34/82] minor --- lib/services/api.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/services/api.dart b/lib/services/api.dart index 6f626f4f..c4675bca 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -487,15 +487,15 @@ class APIService { if(meal=='no data'){ return MealType( id: '', - mealDesription: 'Not updated by HMC', + mealDescription: 'Not updated by HMC', timing: 'Oh no!' ); } return MealType( id: meal[day.trim().toLowerCase()][mealType.trim() .toLowerCase()]['_id'], - mealDesription: meal[day.trim().toLowerCase()][mealType.trim() - .toLowerCase()]['mealDesription'], + mealDescription: meal[day.trim().toLowerCase()][mealType.trim() + .toLowerCase()]['mealDescription'], timing: meal[day.trim().toLowerCase()][mealType.trim() .toLowerCase()]['timing'] ); From 48452c071d2810d5b866f024c3a5303638b17859 Mon Sep 17 00:00:00 2001 From: Ashutosh-777 Date: Sun, 21 May 2023 19:56:11 +0530 Subject: [PATCH 35/82] minor --- lib/stores/mess_store.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/stores/mess_store.dart b/lib/stores/mess_store.dart index d2b821d1..34866186 100644 --- a/lib/stores/mess_store.dart +++ b/lib/stores/mess_store.dart @@ -30,7 +30,7 @@ abstract class _MessStore with Store { @observable ObservableFuture selectedHostel = ObservableFuture(getSavedHostel()) ; @observable - MealType mealData= MealType(id: 'id', mealDesription: 'mealDesription', timing: 'timing'); + MealType mealData= MealType(id: 'id', mealDescription: 'mealDescription', timing: 'timing'); @computed bool get hostelLoaded => selectedHostel.status == FutureStatus.fulfilled; @action From 0c492a7698b7d411709669fe7c3689ee9d8c562c Mon Sep 17 00:00:00 2001 From: Ashutosh-777 Date: Sun, 21 May 2023 19:56:49 +0530 Subject: [PATCH 36/82] spell fix --- lib/widgets/food/mess/mess_menu.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/food/mess/mess_menu.dart b/lib/widgets/food/mess/mess_menu.dart index 0891ad90..15acd1d6 100644 --- a/lib/widgets/food/mess/mess_menu.dart +++ b/lib/widgets/food/mess/mess_menu.dart @@ -82,7 +82,7 @@ class MessMenu extends StatelessWidget { flex: 4, child: SingleChildScrollView( child: Text( - messStore.mealData.mealDesription, + messStore.mealData.mealDescription, style: MyFonts.w400 .size(14) .setColor(kWhite)))), From 0e35f4cee1f4e968313261bf0650e3329c8b371c Mon Sep 17 00:00:00 2001 From: Hareesh nandigrama <85237630+Hareesh-Nandigrama@users.noreply.github.com> Date: Tue, 23 May 2023 18:17:04 +0530 Subject: [PATCH 37/82] minor change --- lib/globals/endpoints.dart | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/globals/endpoints.dart b/lib/globals/endpoints.dart index 14772de7..b48186a1 100644 --- a/lib/globals/endpoints.dart +++ b/lib/globals/endpoints.dart @@ -1,5 +1,6 @@ class Endpoints { - static const baseUrl = 'https://swc.iitg.ac.in/onestopapi/v2'; + static const baseUrl = String.fromEnvironment('SECURITY-KEY'); + static const String restaurantURL = "$baseUrl/getAllOutlets"; static const String lastUpdatedURL = "$baseUrl/lastDataUpdate"; static const String contactURL = "$baseUrl/getContacts"; @@ -24,14 +25,11 @@ class Endpoints { static const String foundURL = '$baseUrl/found'; static const String claimItemURL = "$baseUrl/found/claim"; static const String newsURL = "$baseUrl/news"; - static const String githubIssueToken = - String.fromEnvironment('GITHUB_ISSUE_TOKEN'); + static const String githubIssueToken = String.fromEnvironment('GITHUB_ISSUE_TOKEN'); static const apiSecurityKey = String.fromEnvironment('SECURITY-KEY'); - static const feedback = - 'https://api.github.com/repos/vrrao01/onestop_dev/issues'; + static const feedback = 'https://api.github.com/repos/vrrao01/onestop_dev/issues'; static const String upspPost = '$baseUrl/upsp/submit-request'; - static const String uploadFileUPSP = - "$baseUrl/upsp/file-upload"; + static const String uploadFileUPSP = "$baseUrl/upsp/file-upload"; static getHeader() { return {'Content-Type': 'application/json', 'security-key': apiSecurityKey}; From 9b48e394e79e4f0a05a20868d31a0ecc0ebb51a7 Mon Sep 17 00:00:00 2001 From: Hareesh nandigrama <85237630+Hareesh-Nandigrama@users.noreply.github.com> Date: Tue, 23 May 2023 19:29:40 +0530 Subject: [PATCH 38/82] corrected feedback endpoint --- lib/globals/endpoints.dart | 2 +- test/widget_test.dart | 29 ----------------------------- 2 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 test/widget_test.dart diff --git a/lib/globals/endpoints.dart b/lib/globals/endpoints.dart index b48186a1..5258540b 100644 --- a/lib/globals/endpoints.dart +++ b/lib/globals/endpoints.dart @@ -27,7 +27,7 @@ class Endpoints { static const String newsURL = "$baseUrl/news"; static const String githubIssueToken = String.fromEnvironment('GITHUB_ISSUE_TOKEN'); static const apiSecurityKey = String.fromEnvironment('SECURITY-KEY'); - static const feedback = 'https://api.github.com/repos/vrrao01/onestop_dev/issues'; + static const feedback = 'https://api.github.com/repos/swciitg/onestop_flutter/issues'; static const String upspPost = '$baseUrl/upsp/submit-request'; static const String uploadFileUPSP = "$baseUrl/upsp/file-upload"; diff --git a/test/widget_test.dart b/test/widget_test.dart deleted file mode 100644 index ee2f29e6..00000000 --- a/test/widget_test.dart +++ /dev/null @@ -1,29 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:onestop_dev/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} From 88673f85975528cf4cfe573a17e113fa4f312fc1 Mon Sep 17 00:00:00 2001 From: Chanchal Yadav <84243956+chanchalyadav272@users.noreply.github.com> Date: Wed, 24 May 2023 03:59:41 +0530 Subject: [PATCH 39/82] profile --- android/build.gradle | 4 +- ios/Runner.xcodeproj/project.pbxproj | 1 + lib/functions/utility/validator.dart | 7 + lib/globals/my_colors.dart | 2 + lib/models/lostfound/lost_model.g.dart | 2 +- lib/models/profile/profile_model.dart | 30 ++ lib/models/profile/profile_model.g.dart | 33 +++ lib/pages/profile/edit_profile.dart | 304 ++++++++++++++++++++ lib/pages/profile/profile_page.dart | 95 ++++++ lib/widgets/profile/custom_date_picker.dart | 45 +++ lib/widgets/profile/custom_dropdown.dart | 98 +++++++ lib/widgets/profile/custom_text_field.dart | 94 ++++++ lib/widgets/profile/data_tile.dart | 41 +++ lib/widgets/ui/appbar.dart | 4 +- pubspec.yaml | 4 +- 15 files changed, 758 insertions(+), 6 deletions(-) create mode 100644 lib/functions/utility/validator.dart create mode 100644 lib/models/profile/profile_model.dart create mode 100644 lib/models/profile/profile_model.g.dart create mode 100644 lib/pages/profile/edit_profile.dart create mode 100644 lib/pages/profile/profile_page.dart create mode 100644 lib/widgets/profile/custom_date_picker.dart create mode 100644 lib/widgets/profile/custom_dropdown.dart create mode 100644 lib/widgets/profile/custom_text_field.dart create mode 100644 lib/widgets/profile/data_tile.dart diff --git a/android/build.gradle b/android/build.gradle index 83ae2200..0a40a986 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.6.10' + ext.kotlin_version = '1.8.21' repositories { google() mavenCentral() @@ -26,6 +26,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 52e10fba..a8f07f70 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -222,6 +222,7 @@ files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( diff --git a/lib/functions/utility/validator.dart b/lib/functions/utility/validator.dart new file mode 100644 index 00000000..d10481f1 --- /dev/null +++ b/lib/functions/utility/validator.dart @@ -0,0 +1,7 @@ +String? validatefield(String? value) { + + if (value == null || value.isEmpty) { + return 'Field cannot be empty'; + } + return null; +} \ No newline at end of file diff --git a/lib/globals/my_colors.dart b/lib/globals/my_colors.dart index 2d5e6c76..d2821779 100644 --- a/lib/globals/my_colors.dart +++ b/lib/globals/my_colors.dart @@ -42,3 +42,5 @@ const Color kGrey14 = Color.fromRGBO(41, 45, 53, 1); const Color kGreen = Color.fromRGBO(124, 198, 154, 1); const Color kBadgeColor = Color.fromRGBO(255, 201, 7, 1); const Color kTimetableDisabled = Color.fromRGBO(120, 120, 120, 0.16); +const Color kfocusColor = Color.fromRGBO(94, 94, 94, 1); +const Color kdatePickerSurfaceColor = Color.fromRGBO(43, 62, 92, 1); diff --git a/lib/models/lostfound/lost_model.g.dart b/lib/models/lostfound/lost_model.g.dart index 068124b9..57159075 100644 --- a/lib/models/lostfound/lost_model.g.dart +++ b/lib/models/lostfound/lost_model.g.dart @@ -14,8 +14,8 @@ LostModel _$LostModelFromJson(Map json) => LostModel( email: json['email'] as String, compressedImageURL: json['compressedImageURL'] as String, date: DateTime.parse(json['date'] as String), - phonenumber: json['phonenumber'] as String, id: json['_id'] as String, + phonenumber: json['phonenumber'] as String, ); Map _$LostModelToJson(LostModel instance) => { diff --git a/lib/models/profile/profile_model.dart b/lib/models/profile/profile_model.dart new file mode 100644 index 00000000..544d644c --- /dev/null +++ b/lib/models/profile/profile_model.dart @@ -0,0 +1,30 @@ +import 'package:json_annotation/json_annotation.dart'; +part 'profile_model.g.dart'; + +@JsonSerializable() +class ProfileModel { + final String username; + final String rollNumber; + final String outlook; + final String gmail; + final String contact; + final String emergencyContact; + final String hostel; + final String? linkedin; + final DateTime? date; + ProfileModel({ + required this.username, + required this.rollNumber, + required this.outlook, + required this.gmail, + required this.contact, + required this.emergencyContact, + required this.hostel, + this.linkedin, + this.date, + }); + + factory ProfileModel.fromJson(Map map) => _$ProfileModelFromJson(map); + + Map toJson() => _$ProfileModelToJson(this); +} diff --git a/lib/models/profile/profile_model.g.dart b/lib/models/profile/profile_model.g.dart new file mode 100644 index 00000000..0e953fef --- /dev/null +++ b/lib/models/profile/profile_model.g.dart @@ -0,0 +1,33 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'profile_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ProfileModel _$ProfileModelFromJson(Map json) => ProfileModel( + username: json['username'] as String, + rollNumber: json['rollNumber'] as String, + outlook: json['outlook'] as String, + gmail: json['gmail'] as String, + contact: json['contact'] as String, + emergencyContact: json['emergencyContact'] as String, + hostel: json['hostel'] as String, + linkedin: json['linkedin'] as String?, + date: + json['date'] == null ? null : DateTime.parse(json['date'] as String), + ); + +Map _$ProfileModelToJson(ProfileModel instance) => + { + 'username': instance.username, + 'rollNumber': instance.rollNumber, + 'outlook': instance.outlook, + 'gmail': instance.gmail, + 'contact': instance.contact, + 'emergencyContact': instance.emergencyContact, + 'hostel': instance.hostel, + 'linkedin': instance.linkedin, + 'date': instance.date?.toIso8601String(), + }; diff --git a/lib/pages/profile/edit_profile.dart b/lib/pages/profile/edit_profile.dart new file mode 100644 index 00000000..e7b1ff3a --- /dev/null +++ b/lib/pages/profile/edit_profile.dart @@ -0,0 +1,304 @@ +import 'package:flutter/material.dart'; +import 'package:get/get_connect/http/src/utils/utils.dart'; +import 'package:intl/intl.dart'; +import 'package:onestop_dev/globals/my_colors.dart'; +import 'package:onestop_dev/models/profile/profile_model.dart'; +import 'package:onestop_dev/pages/profile/profile_page.dart'; +import 'package:onestop_dev/widgets/profile/custom_dropdown.dart'; +import 'package:onestop_dev/widgets/profile/custom_text_field.dart'; +import 'package:onestop_dev/functions/utility/validator.dart'; +import 'package:provider/provider.dart'; +import '../../functions/utility/show_snackbar.dart'; +import '../../globals/my_fonts.dart'; +import '../../stores/login_store.dart'; +import '../../widgets/profile/custom_date_picker.dart'; + +class EditProfile extends StatefulWidget { + final ProfileModel? profileModel; + const EditProfile({Key? key, this.profileModel}) : super(key: key); + + @override + State createState() => _EditProfileState(); +} + +class _EditProfileState extends State { + final TextEditingController _usernameController = TextEditingController(); + final TextEditingController _outlookController = TextEditingController(); + final TextEditingController _rollController = TextEditingController(); + final TextEditingController _gmailController = TextEditingController(); + final TextEditingController _contactController = TextEditingController(); + final TextEditingController _emergencyController = TextEditingController(); + final TextEditingController _dateController = TextEditingController(); + final TextEditingController _linkedinController = TextEditingController(); + String? hostel; + DateTime? selectedDate; + final List hostels = [ + "Kameng", + "Barak", + "Lohit", + "Brahma", + "Disang", + "Manas", + "Dihing", + "Umiam", + "Siang", + "Kapili", + "Dhansiri", + "Subhansiri" + ]; + final _formKey = GlobalKey(); + + @override + void initState() { + super.initState(); + if (widget.profileModel != null) { + ProfileModel p = widget.profileModel!; + _usernameController.text = p.username; + _rollController.text = p.rollNumber; + _outlookController.text = p.outlook; + _gmailController.text = p.gmail; + _contactController.text = p.contact; + _emergencyController.text = p.emergencyContact; + _dateController.text = DateFormat('dd-MMM-yyyy').format(p.date!); + _linkedinController.text = p.linkedin!; + hostel = p.hostel; + selectedDate = p.date; + }else{ + _usernameController.text = "${context.read().userData['name']}"; + _rollController.text = "${context.read().userData['rollno']}"; + _outlookController.text = "${context.read().userData['email']}"; + } + } + + @override + Widget build(BuildContext context) { + Future onFormSubmit() async { + if (!_formKey.currentState!.validate()) { + showSnackBar('Please give all the inputs correctly'); + return; + } else { + DateTime date = DateTime( + selectedDate!.year, selectedDate!.month, selectedDate!.day); + var data = { + 'username': _usernameController.text, + 'rollNumber': _rollController.text, + 'outlook': _outlookController.text, + 'gmail': _gmailController.text, + 'contact': _contactController.text, + 'emergencyContact': _emergencyController.text, + 'hostel': hostel, + 'linkedin': _linkedinController.text, + 'date': date.toIso8601String(), + }; + + Navigator.of(context) + .pushAndRemoveUntil(MaterialPageRoute(builder: (context) => Profile(profileModel: ProfileModel.fromJson(data),)),((route) => false)); + } + } + + return Scaffold( + backgroundColor: kBackground, + appBar: AppBar( + backgroundColor: kAppBarGrey, + iconTheme: const IconThemeData(color: kAppBarGrey), + automaticallyImplyLeading: false, + centerTitle: false, + title: Text( + "Profile Setup", + textAlign: TextAlign.left, + style: MyFonts.w500.size(23).setColor(kWhite), + ), + ), + body: SafeArea( + child: SingleChildScrollView( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + children: [ + TextSpan( + text: 'Fields marked with', + style: MyFonts.w500.setColor(kWhite3).size(12)), + TextSpan( + text: ' * ', + style: MyFonts.w500.setColor(kRed).size(12)), + TextSpan( + text: 'are compulsory', + style: MyFonts.w500.setColor(kWhite3).size(12)), + ], + ), + ), + const SizedBox( + height: 24, + ), + Center( + child: Stack(alignment: Alignment.bottomRight, children: [ + Container( + height: 150, + width: 150, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(75)), + color: kWhite2), + child: Image.asset( + 'assets/images/class.png', + fit: BoxFit.fill, + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + height: 30, + width: 30, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(75)), + color: kWhite2), + child: Icon(Icons.edit_outlined), + ), + ), + ])), + const SizedBox( + height: 24, + ), + Text('Basic Information', + style: MyFonts.w600.size(16).setColor(kWhite)), + const SizedBox( + height: 18, + ), + Form( + key: _formKey, + child: Column( + children: [ + CustomTextField( + hintText: 'Username', + // validator: validatefield, + isNecessary: false, + controller: _usernameController, + ), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'Roll Number', + // validator: validatefield, + isNecessary: false, + controller: _rollController, + ), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'Outlook ID', + // validator: validatefield, + isNecessary: false, + controller: _outlookController, + ), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'Gmail', + validator: validatefield, + isNecessary: true, + controller: _gmailController, + ), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'Contact Number', + validator: validatefield, + isNecessary: true, + controller: _contactController, + ), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'Emergency Contact Number', + validator: validatefield, + isNecessary: true, + controller: _emergencyController, + ), + const SizedBox( + height: 12, + ), + CustomDropDown( + value: hostel, + items: hostels, + hintText: 'Hostel', + onChanged: (h) => hostel = h, + validator: validatefield), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'Date', + validator: validatefield, + controller: _dateController, + onTap: () async { + FocusScope.of(context).requestFocus(FocusNode()); + DateTime? pickedDate = await showDatePicker( + context: context, + initialDate: selectedDate ?? DateTime.now(), + firstDate: DateTime(2000), + //DateTime.now() - not to allow to choose before today. + lastDate: DateTime(2101), + builder: (context, child) => CustomDatePicker( + child: child, + )); + if (pickedDate != null) { + if (!mounted) return; + selectedDate = pickedDate; + String formattedDate = + DateFormat('dd-MMM-yyyy').format(pickedDate); + setState(() { + _dateController.text = + formattedDate; //set output date to TextField value. + }); + } + }, + isNecessary: true, + ), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'LinkedIn Profile', + // validator: validatefield, + isNecessary: false, + controller: _linkedinController, + ), + const SizedBox( + height: 24, + ), + ], + )), + GestureDetector( + onTap: onFormSubmit, + child: Container( + width: double.infinity, + height: 48, + alignment: Alignment.center, + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(4)), + color: lBlue2), + child: const Text( + 'Submit', + textAlign: TextAlign.center, + ), + ), + ), + const SizedBox( + height: 24, + ), + ], + ), + )), + ), + ); + } +} diff --git a/lib/pages/profile/profile_page.dart b/lib/pages/profile/profile_page.dart new file mode 100644 index 00000000..ea9ab311 --- /dev/null +++ b/lib/pages/profile/profile_page.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:onestop_dev/pages/profile/edit_profile.dart'; +import 'package:onestop_dev/widgets/profile/data_tile.dart'; + +import '../../globals/my_colors.dart'; +import '../../globals/my_fonts.dart'; +import '../../models/profile/profile_model.dart'; + +class Profile extends StatefulWidget { + final ProfileModel? profileModel; + const Profile({super.key, this.profileModel}); + + @override + State createState() => _ProfileState(); +} + +class _ProfileState extends State { + + @override + Widget build(BuildContext context) { + + return Scaffold( + backgroundColor: kBackground, + appBar: AppBar( + backgroundColor: kAppBarGrey, + iconTheme: const IconThemeData(color: kAppBarGrey), + automaticallyImplyLeading: false, + centerTitle: false, + title: Text( + "Profile", + textAlign: TextAlign.left, + style: MyFonts.w500.size(23).setColor(kWhite), + + ), + ), + body: SafeArea( + child: SingleChildScrollView( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 16,vertical: 8), + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 12,), + Center(child: Stack( + alignment: Alignment.bottomRight, + children: [ + Container( + height: 150, + width: 150, + decoration: const BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(75)),color: kWhite2), + child: Image.asset('assets/images/class.png',fit: BoxFit.fill,), + + ), + + ] + )), + const SizedBox(height: 24,), + Text('Basic Information', + style: MyFonts.w600.size(16).setColor(kWhite)), + const SizedBox( + height: 6, + ), + DataTile(title: 'Username',semiTitle: widget.profileModel?.username,), + DataTile(title: 'Roll Number',semiTitle: widget.profileModel?.rollNumber,), + DataTile(title: 'Outlook ID',semiTitle: widget.profileModel?.outlook,), + DataTile(title: 'Gmail',semiTitle: widget.profileModel?.gmail,), + DataTile(title: 'Contact Number',semiTitle: widget.profileModel?.contact,), + DataTile(title: 'Emergency Contact Number',semiTitle: widget.profileModel?.emergencyContact,), + DataTile(title: 'Hostel',semiTitle: widget.profileModel?.hostel,), + widget.profileModel==null?Container(): DataTile(title: 'Date of Birth',semiTitle: DateFormat('dd-MMM-yyyy') + .format(widget.profileModel!.date!),), + DataTile(title: 'LinkedIn Profile',semiTitle: widget.profileModel?.linkedin,), + SizedBox(height: 24,) + ], + ), + )), + ), + floatingActionButton: GestureDetector( + onTap: ((){ + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => EditProfile(profileModel: widget.profileModel,))); + }), + child: Container( + width: 48, + height: 48, + alignment: Alignment.center, + decoration: const BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(16)),color: lBlue2), + child: const Icon(Icons.edit_outlined), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/widgets/profile/custom_date_picker.dart b/lib/widgets/profile/custom_date_picker.dart new file mode 100644 index 00000000..6f320b45 --- /dev/null +++ b/lib/widgets/profile/custom_date_picker.dart @@ -0,0 +1,45 @@ + +import 'package:flutter/material.dart'; +import 'package:onestop_dev/globals/my_colors.dart'; +import 'package:onestop_dev/globals/my_fonts.dart'; + +class CustomDatePicker extends StatefulWidget { + final Widget? child; + const CustomDatePicker({super.key, this.child}); + + @override + State createState() => _CustomDatePickerState(); +} + +class _CustomDatePickerState extends State { + @override + Widget build(BuildContext context) { + return Theme( + data: Theme.of(context).copyWith( + textTheme: TextTheme( + headline4: MyFonts.w500, + headline5: MyFonts.w500, // Selected Date landscape + headline6: MyFonts.w500, // Selected Date portrait + overline: MyFonts.w500, // Title - SELECT DATE + bodyText1: MyFonts.w500, // year gridbview picker + subtitle1: MyFonts.w500, // input + subtitle2: MyFonts.w500, // month/year picker + caption: MyFonts.w500, // days + ), + colorScheme: const ColorScheme.dark( + primary: lBlue4, + surface: kdatePickerSurfaceColor, + ), + dialogBackgroundColor: kdatePickerSurfaceColor, + textButtonTheme: TextButtonThemeData( + style: TextButton.styleFrom( + backgroundColor: kdatePickerSurfaceColor, // button + foregroundColor: lBlue2, + elevation: 0, + textStyle: MyFonts.w500), + ), + ), + child: widget.child!, + ); + } +} diff --git a/lib/widgets/profile/custom_dropdown.dart b/lib/widgets/profile/custom_dropdown.dart new file mode 100644 index 00000000..1906638d --- /dev/null +++ b/lib/widgets/profile/custom_dropdown.dart @@ -0,0 +1,98 @@ + +import 'package:flutter/material.dart'; +import 'package:onestop_dev/globals/my_fonts.dart'; + +import '../../globals/my_colors.dart'; + +class CustomDropDown extends StatelessWidget { + final List items; + final String hintText; + final Function? onChanged; + final String? Function(String?)? validator; + final int? index; + final String? value; + + const CustomDropDown( + {super.key, + required this.items, + required this.hintText, + required this.onChanged, + this.index, + this.value, + required this.validator}); + + @override + Widget build(BuildContext context) { + return DropdownButtonFormField( + validator: validator, + menuMaxHeight: 400, + value: value, + isExpanded: true, + decoration: InputDecoration( + label: RichText( + text: TextSpan( + children: [ + TextSpan( + text: hintText, + style: MyFonts.w500.size(14).setColor(kTabText), + ), + TextSpan( + text: ' * ', + style: MyFonts.w500.size(16).setColor(kRed), + ), + ], + ), + ), + labelStyle: MyFonts.w500.size(14).setColor(kTabText), + errorStyle: MyFonts.w500, + contentPadding: + const EdgeInsets.symmetric(vertical: 16, horizontal: 16), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: kfocusColor, width: 1), + borderRadius: BorderRadius.all( + Radius.circular(4), + ), + ), + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: kfocusColor, width: 1), + borderRadius: BorderRadius.all( + Radius.circular(4), + ), + ), + errorBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.red, width: 1), + borderRadius: BorderRadius.all( + Radius.circular(4), + ), + ), + focusedErrorBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.red, width: 1), + borderRadius: BorderRadius.all( + Radius.circular(4), + ), + ), + ), + dropdownColor: kBackground, + isDense: true, + icon: const Icon( + Icons.arrow_drop_down, + size: 28, + ), + elevation: 16, + style: MyFonts.w500.size(14).setColor(kWhite), + onChanged: (String? value) { + if (index != null) { + onChanged!(value, index); + } else { + onChanged!(value); + } + }, + items: items.map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), + ); + } +} diff --git a/lib/widgets/profile/custom_text_field.dart b/lib/widgets/profile/custom_text_field.dart new file mode 100644 index 00000000..e58c78d6 --- /dev/null +++ b/lib/widgets/profile/custom_text_field.dart @@ -0,0 +1,94 @@ +import 'package:flutter/material.dart'; +import 'package:onestop_dev/globals/my_colors.dart'; +import 'package:onestop_dev/globals/my_fonts.dart'; + +class CustomTextField extends StatefulWidget { + final String hintText; + final TextInputType? inputType; + final String? Function(String?)? validator; + final String? value; + final void Function(String)? onChanged; + final bool isNecessary; + final TextEditingController? controller; + final void Function()? onTap; + final FocusNode? focusNode; + + const CustomTextField( + {super.key, + required this.hintText, + this.validator, + this.value, + this.onChanged, + required this.isNecessary, + this.inputType, + this.controller, + this.onTap, + this.focusNode}); + + @override + State createState() => _CustomTextFieldState(); +} + +class _CustomTextFieldState extends State { + @override + Widget build(BuildContext context) { + return TextFormField( + readOnly: widget.onTap != null, + style: MyFonts.w500.size(14).copyWith(color: Colors.white), + validator: widget.validator, + controller: widget.controller, + focusNode: widget.focusNode, + cursorColor: lBlue2, + onTap: widget.onTap, + onChanged: widget.onChanged, + initialValue: widget.value == 'null' ? '' : widget.value, + keyboardType: widget.inputType, + decoration: InputDecoration( + errorStyle: MyFonts.w500, + label: RichText( + text: TextSpan( + children: [ + TextSpan( + text: widget.hintText, + style: MyFonts.w500.size(14).setColor(kTabText), + ), + if (widget.isNecessary) + TextSpan( + text: ' * ', + style: MyFonts.w500.size(16).setColor(kRed), + ), + ], + ), + ), + labelStyle: MyFonts.w500.size(14).setColor(kTabText), + hintStyle: MyFonts.w500.size(14).setColor(kTabText), + contentPadding: + const EdgeInsets.symmetric(vertical: 20, horizontal: 16), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: kfocusColor, width: 1), + borderRadius: BorderRadius.all( + Radius.circular(4), + ), + ), + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: kfocusColor, width: 1), + borderRadius: BorderRadius.all( + Radius.circular(4), + ), + ), + errorBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.red, width: 1), + borderRadius: BorderRadius.all( + Radius.circular(4), + ), + ), + focusedErrorBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.red, width: 1), + borderRadius: BorderRadius.all( + Radius.circular(4), + ), + ), + ), + ); + } +} diff --git a/lib/widgets/profile/data_tile.dart b/lib/widgets/profile/data_tile.dart new file mode 100644 index 00000000..e547c833 --- /dev/null +++ b/lib/widgets/profile/data_tile.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; +import 'package:onestop_dev/globals/my_colors.dart'; +import 'package:onestop_dev/globals/my_fonts.dart'; + +class DataTile extends StatelessWidget { + final String title; + final String? semiTitle; + const DataTile({Key? key, required this.title, this.semiTitle}) + : super(key: key); + + @override + Widget build(BuildContext context) { + if (semiTitle != null && semiTitle!.length>0) { + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 12, + ), + Text( + title, + style: MyFonts.w600.size(12).setColor(kTabText), + ), + const SizedBox( + height: 10, + ), + Text( + semiTitle!, + style: MyFonts.w500.size(14).setColor(kWhite), + ), + const SizedBox( + height: 12, + ), + ], + ); + } + else {return Container(); + } + } +} diff --git a/lib/widgets/ui/appbar.dart b/lib/widgets/ui/appbar.dart index c0e4bba7..ace81885 100644 --- a/lib/widgets/ui/appbar.dart +++ b/lib/widgets/ui/appbar.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/pages/profile.dart'; +import 'package:onestop_dev/pages/profile/edit_profile.dart'; AppBar appBar(BuildContext context, {bool displayIcon = true}) { return AppBar( @@ -22,7 +23,8 @@ AppBar appBar(BuildContext context, {bool displayIcon = true}) { color: lBlue2, ), onPressed: () { - Navigator.pushNamed(context, ProfilePage.id); + // Navigator.pushNamed(context, ProfilePage.id); + Navigator.push(context, MaterialPageRoute(builder: (context)=>EditProfile())); }, ), ) diff --git a/pubspec.yaml b/pubspec.yaml index 8c543b34..d1e95a96 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,7 +18,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev version: 1.3.3+25 environment: - sdk: ">=2.15.1 <3.0.0" + sdk: ">=2.17.0 <3.0.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -47,7 +47,7 @@ dependencies: cookie_jar: 3.0.1 provider: ^6.0.2 http: ^0.13.4 - dio: ^4.0.6 + dio: ^5.0.3 file_picker: ^5.2.5 shared_preferences: ^2.0.12 barcode_widget: ^2.0.3 From 2baeb8c3e7f658552c076f216ff83eaac2d0802c Mon Sep 17 00:00:00 2001 From: Ashutosh-777 Date: Wed, 24 May 2023 12:36:42 +0530 Subject: [PATCH 40/82] baseurl fix --- lib/globals/endpoints.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/globals/endpoints.dart b/lib/globals/endpoints.dart index 5258540b..f64de3f3 100644 --- a/lib/globals/endpoints.dart +++ b/lib/globals/endpoints.dart @@ -1,6 +1,5 @@ class Endpoints { - static const baseUrl = String.fromEnvironment('SECURITY-KEY'); - + static const baseUrl = String.fromEnvironment('SERVER-URL'); static const String restaurantURL = "$baseUrl/getAllOutlets"; static const String lastUpdatedURL = "$baseUrl/lastDataUpdate"; static const String contactURL = "$baseUrl/getContacts"; From 87b7154640ffa460eceaeaea9486263e4ea33a44 Mon Sep 17 00:00:00 2001 From: Ashutosh-777 Date: Wed, 24 May 2023 12:39:10 +0530 Subject: [PATCH 41/82] baseurl --- lib/services/api.dart | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/services/api.dart b/lib/services/api.dart index c4675bca..bf62171f 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -500,6 +500,8 @@ class APIService { .toLowerCase()]['timing'] ); }catch(e){ + print(Endpoints.messURL); + print(e); rethrow; } @@ -514,7 +516,7 @@ class APIService { jsonData = prefs.getString('busTimings') ?? ''; } else { final res = await http.get( - Uri.parse(Endpoints.busURL), + Uri.parse(Endpoints.busStops), headers: Endpoints.getHeader(), ); prefs.setString('busTimings', res.body); @@ -528,7 +530,8 @@ class APIService { } return busTimings; } catch (e) { - + print("____________________________________________"); + print(e); rethrow; } } From bc988eed2c7ee1602cee27c9fb35a432bf479d98 Mon Sep 17 00:00:00 2001 From: Chanchal Yadav <84243956+chanchalyadav272@users.noreply.github.com> Date: Wed, 24 May 2023 14:27:30 +0530 Subject: [PATCH 42/82] profile pic and some minor changes --- assets/images/profile_placeholder.png | Bin 0 -> 3028 bytes lib/models/profile/profile_model.dart | 26 +-- lib/models/profile/profile_model.g.dart | 2 + lib/pages/profile/edit_profile.dart | 168 +++++++++++++++----- lib/pages/profile/profile_page.dart | 136 ++++++++++------ lib/widgets/profile/custom_date_picker.dart | 6 +- lib/widgets/profile/custom_dropdown.dart | 3 +- lib/widgets/profile/custom_text_field.dart | 15 +- lib/widgets/profile/data_tile.dart | 6 +- pubspec.yaml | 1 + 10 files changed, 259 insertions(+), 104 deletions(-) create mode 100644 assets/images/profile_placeholder.png diff --git a/assets/images/profile_placeholder.png b/assets/images/profile_placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..3fe205844384d858efaeb948442c628fe498b9fe GIT binary patch literal 3028 zcmd5-_g52Y5)Hj50V#q+sVksJ1Q9|rK`E;edJDZtRTNA}z#ySUx+q18G(kv2Kq)Fk zX+jWb5kw&L(4>ln9+LI>p6~5{usc7^J>U6e=H9vIjKvj0!|p=>fUUtLGaEAvspg;g zx4VE`meUAU1S`~BA;qxhNnxRkh!}SOFOTodX^aVAYwk(vwo3I1ZV=awZaY}dC=CKt zkKP)zow!3?fy`t?!ibQrYRFzbVx(Zxpi)(rzjq=me~0;m2BEpEtT*5K&Rh$76xPNJ zdYjYa3S&m8C$cX20V)OFG=obDcsCCHf5W%3uwxqXv>h_p6AaNxVj=X9lYz;+w*rR% zitoY7hlm8$`k0E3AZSZAlHbo+Yf|1K;!W!d7H8?ea3^D3k!ia9dY^tv(RRo}^^IsYwwTKL|^=D?n%TJqm96{l~WvwXG1dTUyan=w^tMx}%xxRtI)J^V}wNDOT9d|2Q7v;CiM7RplAxYtu%MHZ>ilU}1z zu=5C{kVVucqr44w-t^Ou@H8ZX#1VA5-r4=n;ogJK?$x*lM3Sv?eJ@-%H1VA$;M^vb+iyEAOrv?XqsqLueO!Lw;c$GD7 ztb;x*8~kP9_m6fq4vwu~M)RdkcZC{5-Yf%tmJ;gl-v85x3Vl%8U(0NSRbluHdRRKp z1;`$nG*KD-(yHfh;E1(Fmeux3tKGeeV;`g0ShNUjN#0i)0v=C_%`?XxLGz<(Cv=|! zY-1f=MJ>&^*(az!!O%~0{ATpK{9mj5Uqe_pfN?NtOH$=N#|ro-SWs*c^~pNPLM$Ew zaVGjc$TO7U{!xA?`9q_n+--Pl@OD*COyfO2B{nXm1Gu~{uS51dG9eV5l>%s;Vrxv zf@VM#HNrp}3+N zwCQ@QLlWrvi!9Kv_5Sh5d5~0#>UvbGX=d`gJ4s570E4Gn!R+AX64;tG^Ldx8Rg-)j z`iv`Pg7m6RRFDd=y8c-0p&aBIW8$zhJ<8gFJTy^MsfcyDN;cutr8+w8H#JvPzvq@o zFWs%jwJRSli+aVQUXl!c6|P^d0L%?VmYzCz9{*i*dD43{Y}BW=Hn2dKbtjJI?9AD= z+Ew&bRW{)$_`WN5gF_=V<*Fv!M^CsGK_V!dc)E>Vt2ORoCrL)S;xVbLqiIyoWuy$i z@`fF$y*}FKR6O02q2S);cY05nyg$O4$QwKmpFQK@J?%2YxL{JlrT)>rdpqRynK4;W z|CO_hQZW}C-=tCb_FEDDe$Eo;TBKA$coN9lpp6OH5_7|z7Fbj>g3hW?lyTZV5s(l2 zt0bZhHfzOIVYvGe26@;->Uga1D&5h^?vrXOYT5?vn@>8F0m{8HRljs>Y`K@dy49=# zmzUCf&b;_Yk^i~Qqu8>?1=W+O(_+@M6SdyWl403b!=FYdc=m`hfl2N{DUd5AhBrp~ zaNk;f3>magG9UP@8uS5E&d~!K76MS(lFJ9@^axrS;s7)dXMZ4gre;cbc7tcEoQxan zBd~~Qo18X&Mo>1(w6w}~s9yUDx9Mz_VUKdxlK!aLm;YVVj-&1x%|ENoGjO5ZC}YZe zeHSs~=LhI|_W((fAqi#@GEN{jeUcamyI<`LR zuZ7a6UkaCgr_}tkb7Ln}GN0)qS{HTkZokRVr=+>dc?Fbq@!WWs;MYX&Y++KZ&%ve+ zkE3}q-?0+_WSH99!C{AF$A+g;eL^65wk1?T;$TCmt38%n2Oef;h}oeYD$2ygl_%s~ z(;xjD{C*5?)T=`EB}kp`zKp3B8FZG3mYG}FF+5{l`6CUX$#0KKLBaeV6zJtP8RP=G_$FYxr(YBIaR1~?w{zl5$Glodp?&)O zIk*62N~N+f7^S!kO%L3S@!xYLx@3AwcsL3wtu_+<&GEh3Z1bMFs6avL299k|ZI*mu z|HxSb!Wz7Aw9Ne&d03lRw}CLp#OJWACzal?sCgZ>dQfmz#nZS1tbcf}k|EK-*L*RGLtgz0suToGK{U}^oMdLwPc{i1R7s@rEPKPz1a}5Jfat7Srl*fv9rTT#`pc*ASc(9E+E_o zU7X~#VWXwwmGzKRJx<|=F5+|kiH{9$?~zb$Iu57L8W@zp#A>S z23o<3g4s5SJmaFl#+I0Fg_3nrhvuzC4~hsOCQD1r`QLBOP0T%0RQEzH_x0>Ak2>W{ zEdlkoDMWL$3xQ%Tu~9nx^oKm6v>t#_l2!7R}M(a*9zfr&f5||b{BYpMV3^6>dgg2w_ zt6`xOB2*wV)N~hHCo&fgkZFgU)X>eFzS(n8ZWG%o@<_ZzFybbIn+&SidT6gbw~ahd-Eb(P)=0}Hws3N;mllTf=JD^=-6^^3k(t|4{53`F?!5`+%`G-x8k(bG zyRSUo_I~}kT-{>2J>S(%3ABm~U9AlEz0Uxu=PK z%<{fa@ap39#!>O3iX38igls=$$S`fogrweWGk;d!`Xp1{hCXoN$VkPLrIFV2Jxlpj ztHV4u4>K)O7n_5*!S&{5Uj56>sgjg?hETM)GP3{Ec{znW_Cm>yxCJr2Ro%rS1Te$Y z2QhM1TujSY)(4f8ziS&FXh&+8!iT%z3G_-igG`+Vdpm7N2GZIeSG={UfREMSc4;g0aE{*>p!yp086^Wvj6}9 literal 0 HcmV?d00001 diff --git a/lib/models/profile/profile_model.dart b/lib/models/profile/profile_model.dart index 544d644c..ee793614 100644 --- a/lib/models/profile/profile_model.dart +++ b/lib/models/profile/profile_model.dart @@ -12,19 +12,21 @@ class ProfileModel { final String hostel; final String? linkedin; final DateTime? date; - ProfileModel({ - required this.username, - required this.rollNumber, - required this.outlook, - required this.gmail, - required this.contact, - required this.emergencyContact, - required this.hostel, - this.linkedin, - this.date, - }); + final String? image; + ProfileModel( + {required this.username, + required this.rollNumber, + required this.outlook, + required this.gmail, + required this.contact, + required this.emergencyContact, + required this.hostel, + this.linkedin, + this.date, + this.image}); - factory ProfileModel.fromJson(Map map) => _$ProfileModelFromJson(map); + factory ProfileModel.fromJson(Map map) => + _$ProfileModelFromJson(map); Map toJson() => _$ProfileModelToJson(this); } diff --git a/lib/models/profile/profile_model.g.dart b/lib/models/profile/profile_model.g.dart index 0e953fef..8ad81dc0 100644 --- a/lib/models/profile/profile_model.g.dart +++ b/lib/models/profile/profile_model.g.dart @@ -17,6 +17,7 @@ ProfileModel _$ProfileModelFromJson(Map json) => ProfileModel( linkedin: json['linkedin'] as String?, date: json['date'] == null ? null : DateTime.parse(json['date'] as String), + image: json['image'] as String?, ); Map _$ProfileModelToJson(ProfileModel instance) => @@ -30,4 +31,5 @@ Map _$ProfileModelToJson(ProfileModel instance) => 'hostel': instance.hostel, 'linkedin': instance.linkedin, 'date': instance.date?.toIso8601String(), + 'image': instance.image, }; diff --git a/lib/pages/profile/edit_profile.dart b/lib/pages/profile/edit_profile.dart index e7b1ff3a..73377034 100644 --- a/lib/pages/profile/edit_profile.dart +++ b/lib/pages/profile/edit_profile.dart @@ -1,17 +1,21 @@ +import 'dart:convert'; +import 'dart:io'; + import 'package:flutter/material.dart'; -import 'package:get/get_connect/http/src/utils/utils.dart'; +import 'package:image_picker/image_picker.dart'; import 'package:intl/intl.dart'; -import 'package:onestop_dev/globals/my_colors.dart'; -import 'package:onestop_dev/models/profile/profile_model.dart'; -import 'package:onestop_dev/pages/profile/profile_page.dart'; -import 'package:onestop_dev/widgets/profile/custom_dropdown.dart'; -import 'package:onestop_dev/widgets/profile/custom_text_field.dart'; -import 'package:onestop_dev/functions/utility/validator.dart'; import 'package:provider/provider.dart'; + import '../../functions/utility/show_snackbar.dart'; +import '../../functions/utility/validator.dart'; +import '../../globals/my_colors.dart'; import '../../globals/my_fonts.dart'; +import '../../models/profile/profile_model.dart'; import '../../stores/login_store.dart'; import '../../widgets/profile/custom_date_picker.dart'; +import '../../widgets/profile/custom_dropdown.dart'; +import '../../widgets/profile/custom_text_field.dart'; +import 'profile_page.dart'; class EditProfile extends StatefulWidget { final ProfileModel? profileModel; @@ -32,6 +36,7 @@ class _EditProfileState extends State { final TextEditingController _linkedinController = TextEditingController(); String? hostel; DateTime? selectedDate; + String? imageString; final List hostels = [ "Kameng", "Barak", @@ -63,10 +68,13 @@ class _EditProfileState extends State { _linkedinController.text = p.linkedin!; hostel = p.hostel; selectedDate = p.date; - }else{ - _usernameController.text = "${context.read().userData['name']}"; + imageString = p.image; + } else { + _usernameController.text = + "${context.read().userData['name']}"; _rollController.text = "${context.read().userData['rollno']}"; - _outlookController.text = "${context.read().userData['email']}"; + _outlookController.text = + "${context.read().userData['email']}"; } } @@ -81,18 +89,23 @@ class _EditProfileState extends State { selectedDate!.year, selectedDate!.month, selectedDate!.day); var data = { 'username': _usernameController.text, - 'rollNumber': _rollController.text, - 'outlook': _outlookController.text, - 'gmail': _gmailController.text, - 'contact': _contactController.text, - 'emergencyContact': _emergencyController.text, - 'hostel': hostel, - 'linkedin': _linkedinController.text, - 'date': date.toIso8601String(), + 'rollNumber': _rollController.text, + 'outlook': _outlookController.text, + 'gmail': _gmailController.text, + 'contact': _contactController.text, + 'emergencyContact': _emergencyController.text, + 'hostel': hostel, + 'linkedin': _linkedinController.text, + 'date': date.toIso8601String(), + 'image': imageString, }; - Navigator.of(context) - .pushAndRemoveUntil(MaterialPageRoute(builder: (context) => Profile(profileModel: ProfileModel.fromJson(data),)),((route) => false)); + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute( + builder: (context) => Profile( + profileModel: ProfileModel.fromJson(data), + )), + ((route) => false)); } } @@ -137,26 +150,99 @@ class _EditProfileState extends State { ), Center( child: Stack(alignment: Alignment.bottomRight, children: [ - Container( - height: 150, - width: 150, - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(75)), - color: kWhite2), - child: Image.asset( - 'assets/images/class.png', - fit: BoxFit.fill, - ), - ), + + ClipRRect( + borderRadius: BorderRadius.circular(75.0), + + child: Image( + image: imageString==null?const ResizeImage(AssetImage('assets/images/profile_placeholder.png'),width: 150,height: 150): ResizeImage( + MemoryImage(base64Decode(imageString!)) + ,width: 150, + height: 150,), + fit: BoxFit.fill, + ) + ), Padding( padding: const EdgeInsets.all(8.0), - child: Container( - height: 30, - width: 30, - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(75)), - color: kWhite2), - child: Icon(Icons.edit_outlined), + child: GestureDetector( + onTap: () async { + XFile? xFile; + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(28)), + backgroundColor: kBlueGrey, + title: Text( + "Do you want to change your profile photo?",style: MyFonts.w500.size(16).setColor(kWhite2),), + content: SingleChildScrollView( + child: ListBody( + children: [ + GestureDetector( + child: Text("Take Photo",style: MyFonts.w500.size(14).setColor(kWhite),), + onTap: () async { + xFile = await ImagePicker().pickImage( + source: ImageSource.camera); + if (!mounted) return; + Navigator.of(context).pop(); + }, + ), + const Padding( + padding: EdgeInsets.all(8.0)), + GestureDetector( + child: Text("Choose Photo",style: MyFonts.w500.size(14).setColor(kWhite),), + onTap: () async { + xFile = await ImagePicker().pickImage( + source: ImageSource.gallery); + if (!mounted) return; + Navigator.of(context).pop(); + }, + ), + const Padding( + padding: EdgeInsets.all(8.0)), + + GestureDetector( + child: Text("Remove Photo",style: MyFonts.w500.size(14).setColor(kRed),), + onTap: () async { + setState(() { + imageString=null; + }); + return + Navigator.of(context).pop(); + }, + ), + ], + ), + )); + }); + + if (!mounted) return; + if (xFile != null) { + var bytes = File(xFile!.path).readAsBytesSync(); + var imageSize = (bytes.lengthInBytes / + (1048576)); // dividing by 1024*1024 + if (imageSize > 2.5) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: Text( + "Maximum image size can be 2.5 MB", + style: MyFonts.w500, + ))); + return; + } + setState(() { + imageString = base64Encode(bytes); + }); + return; + } + }, + child: Container( + height: 30, + width: 30, + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(75)), + color: kWhite), + child: const Icon(Icons.edit_outlined), + ), ), ), ])), @@ -177,6 +263,7 @@ class _EditProfileState extends State { // validator: validatefield, isNecessary: false, controller: _usernameController, + isEnabled: false, ), const SizedBox( height: 12, @@ -191,6 +278,7 @@ class _EditProfileState extends State { height: 12, ), CustomTextField( + isEnabled: false, hintText: 'Outlook ID', // validator: validatefield, isNecessary: false, @@ -227,7 +315,7 @@ class _EditProfileState extends State { height: 12, ), CustomDropDown( - value: hostel, + value: hostel, items: hostels, hintText: 'Hostel', onChanged: (h) => hostel = h, @@ -236,7 +324,7 @@ class _EditProfileState extends State { height: 12, ), CustomTextField( - hintText: 'Date', + hintText: 'Date of Birth', validator: validatefield, controller: _dateController, onTap: () async { diff --git a/lib/pages/profile/profile_page.dart b/lib/pages/profile/profile_page.dart index ea9ab311..460c4fba 100644 --- a/lib/pages/profile/profile_page.dart +++ b/lib/pages/profile/profile_page.dart @@ -1,11 +1,14 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; -import 'package:onestop_dev/pages/profile/edit_profile.dart'; -import 'package:onestop_dev/widgets/profile/data_tile.dart'; + import '../../globals/my_colors.dart'; import '../../globals/my_fonts.dart'; import '../../models/profile/profile_model.dart'; +import '../../widgets/profile/data_tile.dart'; +import 'edit_profile.dart'; class Profile extends StatefulWidget { final ProfileModel? profileModel; @@ -16,10 +19,8 @@ class Profile extends StatefulWidget { } class _ProfileState extends State { - @override Widget build(BuildContext context) { - return Scaffold( backgroundColor: kBackground, appBar: AppBar( @@ -31,65 +32,110 @@ class _ProfileState extends State { "Profile", textAlign: TextAlign.left, style: MyFonts.w500.size(23).setColor(kWhite), - ), ), body: SafeArea( child: SingleChildScrollView( child: Container( - padding: const EdgeInsets.symmetric(horizontal: 16,vertical: 8), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), width: double.infinity, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const SizedBox(height: 12,), - Center(child: Stack( - alignment: Alignment.bottomRight, - children: [ - Container( - height: 150, - width: 150, - decoration: const BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(75)),color: kWhite2), - child: Image.asset('assets/images/class.png',fit: BoxFit.fill,), - - ), - - ] - )), - const SizedBox(height: 24,), + const SizedBox( + height: 12, + ), + Center( + child: Stack(alignment: Alignment.bottomRight, children: [ + ClipRRect( + borderRadius: BorderRadius.circular(75.0), + child: Image( + image: widget.profileModel?.image == null + ? const ResizeImage( + AssetImage( + 'assets/images/profile_placeholder.png'), + width: 150, + height: 150) + : ResizeImage( + MemoryImage( + base64Decode(widget.profileModel!.image!)), + width: 150, + height: 150, + ), + fit: BoxFit.fill, + )), + ])), + const SizedBox( + height: 24, + ), Text('Basic Information', style: MyFonts.w600.size(16).setColor(kWhite)), const SizedBox( height: 6, ), - DataTile(title: 'Username',semiTitle: widget.profileModel?.username,), - DataTile(title: 'Roll Number',semiTitle: widget.profileModel?.rollNumber,), - DataTile(title: 'Outlook ID',semiTitle: widget.profileModel?.outlook,), - DataTile(title: 'Gmail',semiTitle: widget.profileModel?.gmail,), - DataTile(title: 'Contact Number',semiTitle: widget.profileModel?.contact,), - DataTile(title: 'Emergency Contact Number',semiTitle: widget.profileModel?.emergencyContact,), - DataTile(title: 'Hostel',semiTitle: widget.profileModel?.hostel,), - widget.profileModel==null?Container(): DataTile(title: 'Date of Birth',semiTitle: DateFormat('dd-MMM-yyyy') - .format(widget.profileModel!.date!),), - DataTile(title: 'LinkedIn Profile',semiTitle: widget.profileModel?.linkedin,), - SizedBox(height: 24,) + DataTile( + title: 'Username', + semiTitle: widget.profileModel?.username, + ), + DataTile( + title: 'Roll Number', + semiTitle: widget.profileModel?.rollNumber, + ), + DataTile( + title: 'Outlook ID', + semiTitle: widget.profileModel?.outlook, + ), + DataTile( + title: 'Gmail', + semiTitle: widget.profileModel?.gmail, + ), + DataTile( + title: 'Contact Number', + semiTitle: widget.profileModel?.contact, + ), + DataTile( + title: 'Emergency Contact Number', + semiTitle: widget.profileModel?.emergencyContact, + ), + DataTile( + title: 'Hostel', + semiTitle: widget.profileModel?.hostel, + ), + widget.profileModel == null + ? Container() + : DataTile( + title: 'Date of Birth', + semiTitle: DateFormat('dd-MMM-yyyy') + .format(widget.profileModel!.date!), + ), + DataTile( + title: 'LinkedIn Profile', + semiTitle: widget.profileModel?.linkedin, + ), + const SizedBox( + height: 24, + ) ], ), )), ), floatingActionButton: GestureDetector( - onTap: ((){ - Navigator.of(context).push(MaterialPageRoute( - builder: (context) => EditProfile(profileModel: widget.profileModel,))); - }), - child: Container( - width: 48, - height: 48, - alignment: Alignment.center, - decoration: const BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(16)),color: lBlue2), - child: const Icon(Icons.edit_outlined), - ), - ), + onTap: (() { + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => EditProfile( + profileModel: widget.profileModel, + ))); + }), + child: Container( + width: 48, + height: 48, + alignment: Alignment.center, + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(16)), + color: lBlue2), + child: const Icon(Icons.edit_outlined), + ), + ), ); } -} \ No newline at end of file +} diff --git a/lib/widgets/profile/custom_date_picker.dart b/lib/widgets/profile/custom_date_picker.dart index 6f320b45..fc3ec247 100644 --- a/lib/widgets/profile/custom_date_picker.dart +++ b/lib/widgets/profile/custom_date_picker.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:onestop_dev/globals/my_colors.dart'; -import 'package:onestop_dev/globals/my_fonts.dart'; + +import '../../globals/my_colors.dart'; +import '../../globals/my_fonts.dart'; + class CustomDatePicker extends StatefulWidget { final Widget? child; diff --git a/lib/widgets/profile/custom_dropdown.dart b/lib/widgets/profile/custom_dropdown.dart index 1906638d..fa99659b 100644 --- a/lib/widgets/profile/custom_dropdown.dart +++ b/lib/widgets/profile/custom_dropdown.dart @@ -1,8 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:onestop_dev/globals/my_fonts.dart'; + import '../../globals/my_colors.dart'; +import '../../globals/my_fonts.dart'; class CustomDropDown extends StatelessWidget { final List items; diff --git a/lib/widgets/profile/custom_text_field.dart b/lib/widgets/profile/custom_text_field.dart index e58c78d6..8000cd36 100644 --- a/lib/widgets/profile/custom_text_field.dart +++ b/lib/widgets/profile/custom_text_field.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:onestop_dev/globals/my_colors.dart'; -import 'package:onestop_dev/globals/my_fonts.dart'; + +import '../../globals/my_colors.dart'; +import '../../globals/my_fonts.dart'; + class CustomTextField extends StatefulWidget { final String hintText; @@ -12,6 +14,7 @@ class CustomTextField extends StatefulWidget { final TextEditingController? controller; final void Function()? onTap; final FocusNode? focusNode; + final bool? isEnabled; const CustomTextField( {super.key, @@ -23,6 +26,7 @@ class CustomTextField extends StatefulWidget { this.inputType, this.controller, this.onTap, + this.isEnabled, this.focusNode}); @override @@ -33,6 +37,7 @@ class _CustomTextFieldState extends State { @override Widget build(BuildContext context) { return TextFormField( + enabled: widget.isEnabled ?? true, readOnly: widget.onTap != null, style: MyFonts.w500.size(14).copyWith(color: Colors.white), validator: widget.validator, @@ -76,6 +81,12 @@ class _CustomTextFieldState extends State { Radius.circular(4), ), ), + disabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: kfocusColor, width: 1), + borderRadius: BorderRadius.all( + Radius.circular(4), + ), + ), errorBorder: const OutlineInputBorder( borderSide: BorderSide(color: Colors.red, width: 1), borderRadius: BorderRadius.all( diff --git a/lib/widgets/profile/data_tile.dart b/lib/widgets/profile/data_tile.dart index e547c833..61b1d650 100644 --- a/lib/widgets/profile/data_tile.dart +++ b/lib/widgets/profile/data_tile.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:onestop_dev/globals/my_colors.dart'; -import 'package:onestop_dev/globals/my_fonts.dart'; + +import '../../globals/my_colors.dart'; +import '../../globals/my_fonts.dart'; + class DataTile extends StatelessWidget { final String title; diff --git a/pubspec.yaml b/pubspec.yaml index d1e95a96..b3928642 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -74,6 +74,7 @@ dependencies: infinite_scroll_pagination: ^3.2.0 upgrader: ^5.1.0 badges: ^2.0.3 + image: ^3.3.0 dev_dependencies: From 45dc056364332dce14a58fdd56e0ad94c1c1b945 Mon Sep 17 00:00:00 2001 From: Chanchal Yadav <84243956+chanchalyadav272@users.noreply.github.com> Date: Wed, 24 May 2023 14:28:29 +0530 Subject: [PATCH 43/82] removed warning --- lib/widgets/profile/data_tile.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/profile/data_tile.dart b/lib/widgets/profile/data_tile.dart index 61b1d650..12a61a93 100644 --- a/lib/widgets/profile/data_tile.dart +++ b/lib/widgets/profile/data_tile.dart @@ -12,7 +12,7 @@ class DataTile extends StatelessWidget { @override Widget build(BuildContext context) { - if (semiTitle != null && semiTitle!.length>0) { + if (semiTitle != null && semiTitle!.isNotEmpty) { return Column( crossAxisAlignment: CrossAxisAlignment.start, From 4dfc6cb7fba713764fcefadb6aeab1b93c5b8773 Mon Sep 17 00:00:00 2001 From: Chanchal Yadav <84243956+chanchalyadav272@users.noreply.github.com> Date: Wed, 24 May 2023 22:08:54 +0530 Subject: [PATCH 44/82] added bug report and logout in profile page --- lib/pages/profile/profile_page.dart | 38 +++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/lib/pages/profile/profile_page.dart b/lib/pages/profile/profile_page.dart index 460c4fba..7c70148b 100644 --- a/lib/pages/profile/profile_page.dart +++ b/lib/pages/profile/profile_page.dart @@ -2,12 +2,14 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; - +import 'package:provider/provider.dart'; import '../../globals/my_colors.dart'; import '../../globals/my_fonts.dart'; import '../../models/profile/profile_model.dart'; +import '../../stores/login_store.dart'; import '../../widgets/profile/data_tile.dart'; +import '../../widgets/profile/feedback.dart'; import 'edit_profile.dart'; class Profile extends StatefulWidget { @@ -33,6 +35,38 @@ class _ProfileState extends State { textAlign: TextAlign.left, style: MyFonts.w500.size(23).setColor(kWhite), ), + actions: [ + if (!context.read().isGuestUser) + IconButton( + onPressed: (() { + showModalBottomSheet( + context: context, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(20), + ), + ), + clipBehavior: Clip.antiAliasWithSaveLayer, + isScrollControlled: true, + builder: (BuildContext context) { + return const FeedBack(); + }); + }), + icon: const Icon( + Icons.bug_report_outlined, + color: kWhite, + )), + IconButton( + onPressed: (() { + context.read().logOut(() => Navigator.of(context) + .pushNamedAndRemoveUntil( + '/', (Route route) => false)); + }), + icon: const Icon( + Icons.logout_outlined, + color: kWhite, + )) + ], ), body: SafeArea( child: SingleChildScrollView( @@ -114,7 +148,7 @@ class _ProfileState extends State { ), const SizedBox( height: 24, - ) + ), ], ), )), From ce9c7ced9a4cae8777ddea57e0740d7f1bd9f936 Mon Sep 17 00:00:00 2001 From: Kunalpal215 Date: Sat, 10 Jun 2023 12:17:00 +0530 Subject: [PATCH 45/82] migrated to dio and token auth --- lib/functions/buysell/get_items.dart | 16 +- lib/functions/travel/has_left.dart | 1 - lib/functions/utility/auth_user_helper.dart | 24 + lib/functions/utility/check_last_updated.dart | 3 +- lib/functions/utility/pick_file.dart | 2 +- lib/functions/utility/show_snackbar.dart | 13 + lib/globals/database_strings.dart | 6 + lib/globals/endpoints.dart | 52 ++- lib/main.dart | 59 +-- lib/models/food/mess_menu_model.g.dart | 42 +- lib/models/travel/day_type_model.g.dart | 22 +- lib/models/travel/travel_timing_model.dart | 2 +- lib/models/travel/travel_timing_model.g.dart | 14 +- lib/pages/buy_sell/bns_home.dart | 17 +- lib/pages/buy_sell/buy_form.dart | 8 +- lib/pages/home/home_tab.dart | 10 +- lib/pages/lost_found/lnf_home.dart | 15 +- lib/pages/quick_links/cab_share.dart | 1 + lib/pages/upsp/details_upsp.dart | 11 +- lib/pages/upsp/upsp.dart | 3 +- lib/services/api.dart | 412 ++++++++++-------- lib/services/data_provider.dart | 14 +- lib/stores/login_store.dart | 53 ++- lib/stores/mapbox_store.dart | 4 +- lib/stores/mapbox_store.g.dart | 4 +- lib/stores/mess_store.dart | 5 +- lib/stores/mess_store.g.dart | 18 +- lib/stores/restaurant_store.dart | 1 - lib/stores/timetable_store.dart | 2 +- lib/stores/timetable_store.g.dart | 5 +- lib/stores/travel_store.dart | 3 +- lib/stores/travel_store.g.dart | 22 +- lib/widgets/food/mess/mess_menu.dart | 2 +- lib/widgets/home/date_course.dart | 1 + lib/widgets/login/login_button.dart | 1 + lib/widgets/login/login_webview.dart | 21 +- lib/widgets/lostfound/ads_tile.dart | 11 +- lib/widgets/lostfound/claim_call_button.dart | 2 +- lib/widgets/mapbox/carousel_card.dart | 5 +- lib/widgets/profile/feedback.dart | 2 +- lib/widgets/travel/bus_details.dart | 3 +- lib/widgets/travel/next_time_card.dart | 7 +- lib/widgets/travel/stops_list.dart | 3 +- lib/widgets/ui/appbar.dart | 1 - pubspec.yaml | 2 +- 45 files changed, 518 insertions(+), 407 deletions(-) create mode 100644 lib/functions/utility/auth_user_helper.dart diff --git a/lib/functions/buysell/get_items.dart b/lib/functions/buysell/get_items.dart index 426daa32..8304f443 100644 --- a/lib/functions/buysell/get_items.dart +++ b/lib/functions/buysell/get_items.dart @@ -1,8 +1,8 @@ -import 'package:onestop_dev/services/api.dart'; - -Future getBuySellItems(mail) async { - var list1 = await APIService.getBuyItems(); - var list2 = await APIService.getSellItems(); - var list3 = await APIService.getBnsMyItems(mail); - return [list1, list2, list3]; -} +// import 'package:onestop_dev/services/api.dart'; +// +// Future getBuySellItems(mail) async { +// var list1 = await APIService().getBuyItems(); +// var list2 = await APIService.getSellItems(); +// var list3 = await APIService.getBnsMyItems(mail); +// return [list1, list2, list3]; +// } diff --git a/lib/functions/travel/has_left.dart b/lib/functions/travel/has_left.dart index 5b469322..68a94c81 100644 --- a/lib/functions/travel/has_left.dart +++ b/lib/functions/travel/has_left.dart @@ -1,4 +1,3 @@ -import 'package:intl/intl.dart'; bool hasLeft(DateTime s) { DateTime x = DateTime.now(); return x.isBefore(s); diff --git a/lib/functions/utility/auth_user_helper.dart b/lib/functions/utility/auth_user_helper.dart new file mode 100644 index 00000000..11044e9d --- /dev/null +++ b/lib/functions/utility/auth_user_helper.dart @@ -0,0 +1,24 @@ +import 'package:onestop_dev/globals/database_strings.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class AuthUserHelpers{ + static Future getAccessToken() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + return prefs.getString(BackendHelper.accesstoken) ?? " "; + } + + static Future setAccessToken(String value) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + await prefs.setString(BackendHelper.accesstoken, value); + } + + static Future getRefreshToken() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + return prefs.getString(BackendHelper.refreshtoken) ?? " "; + } + + static Future setRefreshToken(String value) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + await prefs.setString(BackendHelper.refreshtoken, value); + } +} \ No newline at end of file diff --git a/lib/functions/utility/check_last_updated.dart b/lib/functions/utility/check_last_updated.dart index f31677d6..d1ea844c 100644 --- a/lib/functions/utility/check_last_updated.dart +++ b/lib/functions/utility/check_last_updated.dart @@ -1,4 +1,5 @@ import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:onestop_dev/globals/database_strings.dart'; import 'package:onestop_dev/services/api.dart'; import 'package:onestop_dev/services/data_provider.dart'; @@ -15,7 +16,7 @@ Future checkLastUpdated() async { Map? lastUpdated = await DataProvider.getLastUpdated(); try { - Map last = await APIService.getLastUpdated(); + Map last = await APIService().getLastUpdated(); if (lastUpdated == null) { await LocalStorage.instance.deleteAllRecord(); diff --git a/lib/functions/utility/pick_file.dart b/lib/functions/utility/pick_file.dart index 4c269817..fee03e94 100644 --- a/lib/functions/utility/pick_file.dart +++ b/lib/functions/utility/pick_file.dart @@ -18,7 +18,7 @@ Future uploadFile( if (result != null) { File file = File(result.files.single.path!); uploadCallback(); - String? responseFilename = await APIService.uploadFileToServer(file); + String? responseFilename = await APIService().uploadFileToServer(file); if (responseFilename == null) { showSnackBar("There was an error uploading your file"); } diff --git a/lib/functions/utility/show_snackbar.dart b/lib/functions/utility/show_snackbar.dart index b21e4505..24dd8795 100644 --- a/lib/functions/utility/show_snackbar.dart +++ b/lib/functions/utility/show_snackbar.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; +import 'package:dio/dio.dart'; import 'package:onestop_dev/main.dart'; void showSnackBar(String message) { @@ -9,3 +10,15 @@ void showSnackBar(String message) { ), ); } + +void showErrorSnackBar(DioException err) { + rootScaffoldMessengerKey.currentState?.showSnackBar(SnackBar( + content: Text( + (err.response != null) + ? err.response!.data['message'] + : "Some error occurred. try again", + style: MyFonts.w500, + ), + duration: const Duration(seconds: 5), + )); +} diff --git a/lib/globals/database_strings.dart b/lib/globals/database_strings.dart index e7ee39c2..b7407ef5 100644 --- a/lib/globals/database_strings.dart +++ b/lib/globals/database_strings.dart @@ -7,4 +7,10 @@ abstract class DatabaseRecords { static const messMenu = "MessMenu"; static const ferryTimings = "FerryTimings"; static const busTimings = "BusTimings"; +} + +class BackendHelper { + static const refreshtoken = "refreshToken"; + static const accesstoken = "accessToken"; + static const authorization = "authorization"; } \ No newline at end of file diff --git a/lib/globals/endpoints.dart b/lib/globals/endpoints.dart index f64de3f3..a2b5ccbe 100644 --- a/lib/globals/endpoints.dart +++ b/lib/globals/endpoints.dart @@ -1,36 +1,40 @@ +import 'package:onestop_dev/globals/database_strings.dart'; + +import '../functions/utility/auth_user_helper.dart'; + class Endpoints { static const baseUrl = String.fromEnvironment('SERVER-URL'); - static const String restaurantURL = "$baseUrl/getAllOutlets"; - static const String lastUpdatedURL = "$baseUrl/lastDataUpdate"; - static const String contactURL = "$baseUrl/getContacts"; - static const String timetableURL = "$baseUrl/smartTimetable/get-my-courses"; - static const String ferryURL = '$baseUrl/ferryTimings'; - static const String busURL = '$baseUrl/busTimings'; - static const String busStops = '$baseUrl/busstops'; - static const String messURL = "$baseUrl/hostelsMessMenu"; - static const String buyURL = '$baseUrl/buy'; - static const String sellURL = '$baseUrl/sell'; + static const String restaurantURL = "/getAllOutlets"; + static const String lastUpdatedURL = "/lastDataUpdate"; + static const String contactURL = "/getContacts"; + static const String timetableURL = "/smartTimetable/get-my-courses"; + static const String ferryURL = '/ferryTimings'; + static const String busURL = '/busTimings'; + static const String busStops = '/busstops'; + static const String messURL = "/hostelsMessMenu"; + static const String buyURL = '/buy'; + static const String sellURL = '/sell'; static const String sellPath = '/sellPage'; static const String buyPath = '/buyPage'; - static const String bnsMyAdsURL = '$baseUrl/bns/myads'; - static const String lnfMyAdsURL = '$baseUrl/lnf/myads'; - static const String deleteBuyURL = "$baseUrl/buy/remove"; - static const String deleteSellURL = "$baseUrl/sell/remove"; - static const String deleteLostURL = "$baseUrl/lost/remove"; - static const String deleteFoundURL = "$baseUrl/found/remove"; - static const String lostURL = '$baseUrl/lost'; + static const String bnsMyAdsURL = '/bns/myads'; + static const String lnfMyAdsURL = '/lnf/myads'; + static const String deleteBuyURL = "/buy/remove"; + static const String deleteSellURL = "/sell/remove"; + static const String deleteLostURL = "/lost/remove"; + static const String deleteFoundURL = "/found/remove"; + static const String lostURL = '/lost'; static const String lostPath = '/lostPage'; static const String foundPath = '/foundPage'; - static const String foundURL = '$baseUrl/found'; - static const String claimItemURL = "$baseUrl/found/claim"; - static const String newsURL = "$baseUrl/news"; + static const String foundURL = '/found'; + static const String claimItemURL = "/found/claim"; + static const String newsURL = "/news"; static const String githubIssueToken = String.fromEnvironment('GITHUB_ISSUE_TOKEN'); static const apiSecurityKey = String.fromEnvironment('SECURITY-KEY'); static const feedback = 'https://api.github.com/repos/swciitg/onestop_flutter/issues'; - static const String upspPost = '$baseUrl/upsp/submit-request'; - static const String uploadFileUPSP = "$baseUrl/upsp/file-upload"; - + static const String upspPost = '/upsp/submit-request'; + static const String uploadFileUPSP = "/upsp/file-upload"; + static const String guestLogin = "/user/guest/login"; static getHeader() { - return {'Content-Type': 'application/json', 'security-key': apiSecurityKey}; + return {'Content-Type': 'application/json', 'security-key': Endpoints.apiSecurityKey}; } } diff --git a/lib/main.dart b/lib/main.dart index 1d2977d5..907fa114 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -21,7 +21,7 @@ void main() async { [DeviceOrientation.portraitDown, DeviceOrientation.portraitUp]); SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom, SystemUiOverlay.top]); - await checkLastUpdated(); + // await checkLastUpdated(); runApp(const MyApp()); } @@ -35,30 +35,37 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { debugInvertOversizedImages = true; - return MultiProvider( - providers: [ - Provider( - create: (_) => LoginStore(), - ), - Provider( - create: (_) => RestaurantStore(), - ), - Provider( - create: (_) => MapBoxStore(), - ), - Provider( - create: (_) => CommonStore(), - ) - ], - child: MaterialApp( - scaffoldMessengerKey: rootScaffoldMessengerKey, - debugShowCheckedModeBanner: false, - theme: ThemeData( - scaffoldBackgroundColor: kBackground, - splashColor: Colors.transparent), - title: 'OneStop 2.0', - routes: routes, - ), - ); + return FutureBuilder( + future: checkLastUpdated(), + builder: (buildContext,snapshot){ + if(snapshot.hasData){ + return MultiProvider( + providers: [ + Provider( + create: (_) => LoginStore(), + ), + Provider( + create: (_) => RestaurantStore(), + ), + Provider( + create: (_) => MapBoxStore(), + ), + Provider( + create: (_) => CommonStore(), + ) + ], + child: MaterialApp( + scaffoldMessengerKey: rootScaffoldMessengerKey, + debugShowCheckedModeBanner: false, + theme: ThemeData( + scaffoldBackgroundColor: kBackground, + splashColor: Colors.transparent), + title: 'OneStop 2.0', + routes: routes, + ), + ); + } + return Container(); + }); } } diff --git a/lib/models/food/mess_menu_model.g.dart b/lib/models/food/mess_menu_model.g.dart index 537b897c..af289c6b 100644 --- a/lib/models/food/mess_menu_model.g.dart +++ b/lib/models/food/mess_menu_model.g.dart @@ -7,7 +7,7 @@ part of 'mess_menu_model.dart'; // ************************************************************************** MessMenu _$MessMenuFromJson(Map json) => MessMenu( - id: json['_id'] as String, + id: json['id'] as String, hostel: json['hostel'] as String, monday: Day.fromJson(json['monday'] as Map), tuesday: Day.fromJson(json['tuesday'] as Map), @@ -17,10 +17,10 @@ MessMenu _$MessMenuFromJson(Map json) => MessMenu( saturday: Day.fromJson(json['saturday'] as Map), sunday: Day.fromJson(json['sunday'] as Map), v: json['v'] as int, -); + ); Map _$MessMenuToJson(MessMenu instance) => { - '_id': instance.id, + 'id': instance.id, 'hostel': instance.hostel, 'monday': instance.monday, 'tuesday': instance.tuesday, @@ -30,48 +30,30 @@ Map _$MessMenuToJson(MessMenu instance) => { 'saturday': instance.saturday, 'sunday': instance.sunday, 'v': instance.v, -}; + }; Day _$DayFromJson(Map json) => Day( - id: json['_id'] as String, + id: json['id'] as String, breakfast: MealType.fromJson(json['breakfast'] as Map), lunch: MealType.fromJson(json['lunch'] as Map), dinner: MealType.fromJson(json['dinner'] as Map), -); + ); Map _$DayToJson(Day instance) => { - '_id': instance.id, + 'id': instance.id, 'breakfast': instance.breakfast, 'lunch': instance.lunch, 'dinner': instance.dinner, -}; + }; MealType _$MealTypeFromJson(Map json) => MealType( - id: json['_id'] as String, + id: json['id'] as String, mealDescription: json['mealDescription'] as String, timing: json['timing'] as String, -); + ); Map _$MealTypeToJson(MealType instance) => { - '_id': instance.id, + 'id': instance.id, 'mealDescription': instance.mealDescription, 'timing': instance.timing, -}; - -// MessMenuModel _$MessMenuModelFromJson(Map json) => -// MessMenuModel( -// hostel: json['hostel'] as String? ?? 'Untitled Hostel', -// meal: json['meal'] as String? ?? 'Untitled Meal', -// menu: json['menu'] as String? ?? 'Untitled Menu', -// day: json['day'] as String? ?? 'Untitled Day', -// timing: json['timing'] as String? ?? 'Untitled Timing', -// ); -// -// Map _$MessMenuModelToJson(MessMenuModel instance) => -// { -// 'hostel': instance.hostel, -// 'meal': instance.meal, -// 'menu': instance.menu, -// 'timing': instance.timing, -// 'day': instance.day, -// }; + }; diff --git a/lib/models/travel/day_type_model.g.dart b/lib/models/travel/day_type_model.g.dart index 35e7fc69..81cd0773 100644 --- a/lib/models/travel/day_type_model.g.dart +++ b/lib/models/travel/day_type_model.g.dart @@ -7,16 +7,16 @@ part of 'day_type_model.dart'; // ************************************************************************** DayType _$DayTypeFromJson(Map json) => DayType( - fromCampus: (json['fromCampus'] as List) - .map((e) => DateTime.parse(e as String)) - .toList(), - toCampus: (json['toCampus'] as List) - .map((e) => DateTime.parse(e as String)) - .toList(), - ); + fromCampus: (json['fromCampus'] as List) + .map((e) => DateTime.parse(e as String)) + .toList(), + toCampus: (json['toCampus'] as List) + .map((e) => DateTime.parse(e as String)) + .toList(), +); Map _$DayTypeToJson(DayType instance) => { - 'fromCampus': - instance.fromCampus.map((e) => e.toIso8601String()).toList(), - 'toCampus': instance.toCampus.map((e) => e.toIso8601String()).toList(), - }; + 'fromCampus': + instance.fromCampus.map((e) => e.toIso8601String()).toList(), + 'toCampus': instance.toCampus.map((e) => e.toIso8601String()).toList(), +}; \ No newline at end of file diff --git a/lib/models/travel/travel_timing_model.dart b/lib/models/travel/travel_timing_model.dart index cdcd9569..17e29263 100644 --- a/lib/models/travel/travel_timing_model.dart +++ b/lib/models/travel/travel_timing_model.dart @@ -1,6 +1,6 @@ import 'package:json_annotation/json_annotation.dart'; -import 'day_type_model.dart'; +import './day_type_model.dart'; part 'travel_timing_model.g.dart'; diff --git a/lib/models/travel/travel_timing_model.g.dart b/lib/models/travel/travel_timing_model.g.dart index b8829b4a..c93183ec 100644 --- a/lib/models/travel/travel_timing_model.g.dart +++ b/lib/models/travel/travel_timing_model.g.dart @@ -12,13 +12,13 @@ TravelTiming _$TravelTimingFromJson(Map json) => TravelTiming( stop: json['stop'] as String? ?? '', weekend: DayType.fromJson(json['weekend'] as Map), weekdays:DayType.fromJson(json['weekdays'] as Map), - ); +); Map _$TravelTimingToJson(TravelTiming instance) => { - '_id': instance.id, - 'type': instance.type, - 'stop': instance.stop, - 'weekend': instance.weekend, - 'weekdays': instance.weekdays, - }; + '_id': instance.id, + 'type': instance.type, + 'stop': instance.stop, + 'weekend': instance.weekend, + 'weekdays': instance.weekdays, + }; \ No newline at end of file diff --git a/lib/pages/buy_sell/bns_home.dart b/lib/pages/buy_sell/bns_home.dart index ced85633..972b280d 100644 --- a/lib/pages/buy_sell/bns_home.dart +++ b/lib/pages/buy_sell/bns_home.dart @@ -35,10 +35,10 @@ class _BuySellHomeState extends State { void initState() { super.initState(); _sellController.addPageRequestListener((pageKey) async { - await listener(_sellController, APIService.getSellPage, pageKey); + await listener(_sellController, APIService().getSellPage, pageKey); }); _buyController.addPageRequestListener((pageKey) async { - await listener(_buyController, APIService.getBuyPage, pageKey); + await listener(_buyController, APIService().getBuyPage, pageKey); }); } @@ -65,6 +65,8 @@ class _BuySellHomeState extends State { @override Widget build(BuildContext context) { var commonStore = context.read(); + + return Observer( builder: (BuildContext context) { return Scaffold( @@ -166,9 +168,12 @@ class _BuySellHomeState extends State { ) else Expanded( - child: FutureBuilder( - future: APIService.getBnsMyItems( - context.read().userData['email'] ?? ""), + child: context.read().isGuestUser ? const PaginationText( + text: + "Not Available in guest mode") + : FutureBuilder( + future: APIService().getBnsMyItems( + context.read().userData['email']!), builder: (context, snapshot) { if (snapshot.hasData) { List models = @@ -199,7 +204,7 @@ class _BuySellHomeState extends State { ), floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, - floatingActionButton: AddItemButton( + floatingActionButton: context.read().isGuestUser ? Container() : AddItemButton( type: commonStore.bnsIndex, ), ); diff --git a/lib/pages/buy_sell/buy_form.dart b/lib/pages/buy_sell/buy_form.dart index a3da796d..2496908d 100644 --- a/lib/pages/buy_sell/buy_form.dart +++ b/lib/pages/buy_sell/buy_form.dart @@ -161,16 +161,16 @@ class _BuySellFormState extends State { try { if (widget.category == "Sell") { - res = await APIService.postSellData(data); + res = await APIService().postSellData(data); } if (widget.category == "Buy") { - res = await APIService.postBuyData(data); + res = await APIService().postBuyData(data); } if (widget.category == "Lost") { - res = await APIService.postLostData(data); + res = await APIService().postLostData(data); } if (widget.category == "Found") { - res = await APIService.postFoundData(data); + res = await APIService().postFoundData(data); } // ignore: empty_catches } catch (e) { diff --git a/lib/pages/home/home_tab.dart b/lib/pages/home/home_tab.dart index 1dee8775..7d5119d0 100644 --- a/lib/pages/home/home_tab.dart +++ b/lib/pages/home/home_tab.dart @@ -26,7 +26,7 @@ class _HomeTabState extends State { void initState() { super.initState(); context.read().setTimetable( - context.read().userData["rollno"] ?? "190101109"); + context.read().userData["rollno"] ?? "190101109",context); } @override @@ -45,10 +45,10 @@ class _HomeTabState extends State { const SizedBox( height: 10, ), - const DateCourse(), - const SizedBox( - height: 10, - ), + context.read().isGuest ? Container() : const Column(mainAxisSize: MainAxisSize.min,children: [const DateCourse(), + SizedBox( + height: 10, + )],), HomeLinks(title: 'Services', links: serviceLinks), const SizedBox( height: 10, diff --git a/lib/pages/lost_found/lnf_home.dart b/lib/pages/lost_found/lnf_home.dart index 718cc03f..33c2fcc4 100644 --- a/lib/pages/lost_found/lnf_home.dart +++ b/lib/pages/lost_found/lnf_home.dart @@ -34,10 +34,10 @@ class _LostFoundHomeState extends State { void initState() { super.initState(); _lostController.addPageRequestListener((pageKey) async { - await listener(_lostController, APIService.getLostPage, pageKey); + await listener(_lostController, APIService().getLostPage, pageKey); }); _foundController.addPageRequestListener((pageKey) async { - await listener(_foundController, APIService.getFoundPage, pageKey); + await listener(_foundController, APIService().getFoundPage, pageKey); }); } @@ -64,6 +64,8 @@ class _LostFoundHomeState extends State { @override Widget build(BuildContext context) { var commonStore = context.read(); + + return Observer(builder: (context) { return Scaffold( appBar: AppBar( @@ -169,8 +171,11 @@ class _LostFoundHomeState extends State { ) else Expanded( - child: FutureBuilder( - future: APIService.getLnfMyItems( + child: context.read().isGuestUser ? const PaginationText( + text: + "Not Available in guest mode") + : FutureBuilder( + future: APIService().getLnfMyItems( context.read().userData['email'] ?? ""), builder: (context, snapshot) { if (snapshot.hasData) { @@ -200,7 +205,7 @@ class _LostFoundHomeState extends State { ], ), floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, - floatingActionButton: AddItemButton( + floatingActionButton: context.read().isGuestUser ? Container() : AddItemButton( type: commonStore.lnfIndex, ), ); diff --git a/lib/pages/quick_links/cab_share.dart b/lib/pages/quick_links/cab_share.dart index 33733419..f9468248 100644 --- a/lib/pages/quick_links/cab_share.dart +++ b/lib/pages/quick_links/cab_share.dart @@ -9,6 +9,7 @@ class CabShare extends StatelessWidget { @override Widget build(BuildContext context) { + print(context.read().userData); return CabSharingScreen(userData: { 'name': context.read().userData["name"]!, 'email': context.read().userData["email"]!, diff --git a/lib/pages/upsp/details_upsp.dart b/lib/pages/upsp/details_upsp.dart index b4d692ee..8020d766 100644 --- a/lib/pages/upsp/details_upsp.dart +++ b/lib/pages/upsp/details_upsp.dart @@ -240,23 +240,20 @@ class _DetailsUpspState extends State { data['roll_number'] = roll; data['email'] = email; try { - var response = await APIService.postUPSP(data); + var response = await APIService().postUPSP(data); if (!mounted) return; if (response['success']) { - showSnackBar( - "Your problem has been successfully sent to respective authorities."); + showSnackBar("Your problem has been successfully sent to respective authorities."); Navigator.popUntil( context, ModalRoute.withName(HomePage.id)); } else { - showSnackBar( - "Some error occurred. Try again later"); + showSnackBar("Some error occurred. Try again later"); setState(() { submitted = false; }); } } catch (err) { - showSnackBar( - "Please check you internet connection and try again"); + showSnackBar("Please check you internet connection and try again"); setState(() { submitted = false; }); diff --git a/lib/pages/upsp/upsp.dart b/lib/pages/upsp/upsp.dart index ef080a9f..f483315f 100644 --- a/lib/pages/upsp/upsp.dart +++ b/lib/pages/upsp/upsp.dart @@ -196,8 +196,7 @@ class _UpspState extends State { GestureDetector( onTap: () { if (problem.value.text.isEmpty) { - showSnackBar( - "Problem description cannot be empty"); + showSnackBar("Problem description cannot be empty"); } else { Map data = { 'problem': problem.text, diff --git a/lib/services/api.dart b/lib/services/api.dart index bf62171f..ad3d3704 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -1,8 +1,10 @@ import 'dart:convert'; import 'dart:io'; import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:http/http.dart' as http; +import 'package:onestop_dev/globals/database_strings.dart'; import 'package:onestop_dev/globals/endpoints.dart'; import 'package:onestop_dev/models/buy_sell/buy_model.dart'; import 'package:onestop_dev/models/lostfound/found_model.dart'; @@ -11,34 +13,123 @@ import 'package:onestop_dev/models/timetable/registered_courses.dart'; import 'package:onestop_dev/models/buy_sell/sell_model.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import '../functions/utility/show_snackbar.dart'; import '../models/food/mess_menu_model.dart'; import '../models/travel/travel_timing_model.dart'; +import '../functions/utility/auth_user_helper.dart'; class APIService { - static Future postFeedbackData(Map data) async { + + final dio = Dio(BaseOptions( + baseUrl: Endpoints.baseUrl, + connectTimeout: const Duration(seconds: 15), + receiveTimeout: const Duration(seconds: 15), + headers: Endpoints.getHeader())); + + APIService() { + + dio.interceptors + .add(InterceptorsWrapper(onRequest: (options, handler) async { + print("THIS IS TOKEN"); + print(await AuthUserHelpers.getAccessToken()); + options.headers["Authorization"] = + "Bearer ${await AuthUserHelpers.getAccessToken()}"; + handler.next(options); + }, onError: (error, handler) async { + var response = error.response; + if (response != null && response.statusCode == 401) { + bool couldRegenerate = await regenerateAccessToken(); + // ignore: use_build_context_synchronously + if (couldRegenerate) { + // retry + return handler.resolve(await retryRequest(response)); + } else { + showSnackBar("Your session has expired!! Login again."); + } + } + else if(response != null && response.statusCode == 403){ + showSnackBar("Access not allowed in guest mode"); + } + // admin user with expired tokens + return handler.next(error); + })); + } + + Future> retryRequest(Response response) async { + RequestOptions requestOptions = response.requestOptions; + response.requestOptions.headers[BackendHelper.authorization] = + "Bearer ${await AuthUserHelpers.getAccessToken()}"; + final options = Options(method: requestOptions.method, headers: requestOptions.headers); + Dio retryDio = Dio(BaseOptions( + baseUrl: Endpoints.baseUrl, + connectTimeout: const Duration(seconds: 5), + receiveTimeout: const Duration(seconds: 5), + headers: { + 'Security-Key': Endpoints.apiSecurityKey + })); + if (requestOptions.method == "GET") { + return retryDio.request(requestOptions.path, + queryParameters: requestOptions.queryParameters, options: options); + } else { + return retryDio.request(requestOptions.path, + queryParameters: requestOptions.queryParameters, + data: requestOptions.data, + options: options); + } + } + + Future regenerateAccessToken() async { + String refreshToken = await AuthUserHelpers.getRefreshToken(); + try { + Dio regenDio = Dio(BaseOptions( + baseUrl: Endpoints.baseUrl, + connectTimeout: const Duration(seconds: 5), + receiveTimeout: const Duration(seconds: 5), + headers: { + 'Security-Key': Endpoints.apiSecurityKey + })); + Response> resp = await regenDio.post( + "/user/accesstoken", + options: Options(headers: {"authorization": "Bearer $refreshToken"})); + var data = resp.data!; + await AuthUserHelpers.setAccessToken(data["token"]); + return true; + } catch (err) { + return false; + } + } + + + Future postFeedbackData(Map data) async { String tag = data['type'] == 'Issue Report' ? 'bug' : 'enhancement'; String newBody = "### Description :\n${data['body']}\n### Posted By :\n${data['user']}"; - var res = await http.post(Uri.parse(Endpoints.feedback), - body: jsonEncode({ + + var res = await dio.post(Endpoints.feedback, + data: { 'title': data['title'], 'body': newBody, 'labels': [tag] - }), - headers: { + }, + options: Options(headers: { 'Accept': 'application/vnd.github+json', 'Authorization': 'Bearer ${Endpoints.githubIssueToken}' - }); + })); if (res.statusCode == 201) { return true; } return false; } - static Future>> getRestaurantData() async { - http.Response response = await http.get(Uri.parse(Endpoints.restaurantURL)); + Future guestUserLogin() async { + var response = await dio.post(Endpoints.guestLogin); + return response; + } + + Future>> getRestaurantData() async { + var response = await dio.get(Endpoints.restaurantURL); var status = response.statusCode; - var body = jsonDecode(response.body); + var body = response.data; if (status == 200) { List> data = []; for (var json in body) { @@ -50,10 +141,10 @@ class APIService { } } - static Future>> getNewsData() async { - http.Response response = await http.get(Uri.parse(Endpoints.newsURL)); + Future>> getNewsData() async { + var response = await dio.get(Endpoints.newsURL); var status = response.statusCode; - var body = jsonDecode(response.body); + var body = response.data; if (status == 200) { List> data = []; for (var json in body) { @@ -65,50 +156,45 @@ class APIService { } } - static Future claimFoundItem( + Future claimFoundItem( {required String name, required String email, required String id}) async { - var res = await http.post(Uri.parse(Endpoints.claimItemURL), - headers: Endpoints.getHeader(), - body: - jsonEncode({"id": id, "claimerEmail": email, "claimerName": name})); - return jsonDecode(res.body); - } - - static Future deleteBnsMyAd(String id, String email) async { - await http.post(Uri.parse(Endpoints.deleteBuyURL), - headers: Endpoints.getHeader(), - body: jsonEncode({'id': id, 'email': email})); - await http.post(Uri.parse(Endpoints.deleteSellURL), - headers: Endpoints.getHeader(), - body: jsonEncode({'id': id, 'email': email})); - } - - static Future deleteLnfMyAd(String id, String email) async { - await http.post(Uri.parse(Endpoints.deleteLostURL), - headers: Endpoints.getHeader(), - body: jsonEncode({'id': id, 'email': email})); - await http.post(Uri.parse(Endpoints.deleteFoundURL), - headers: Endpoints.getHeader(), - body: jsonEncode({'id': id, 'email': email})); - } - - static Future getBuyItems() async { - var res = await http.get(Uri.parse(Endpoints.buyURL)); - var lostItemsDetails = jsonDecode(res.body); - return lostItemsDetails["details"]; + var res = await dio.post(Endpoints.claimItemURL,data: {"id": id, "claimerEmail": email, "claimerName": name}); + return res.data; } - static Future getSellItems() async { - var res = await http.get(Uri.parse(Endpoints.sellURL)); - var foundItemsDetails = jsonDecode(res.body); - return foundItemsDetails["details"]; + Future deleteBnsMyAd(String id, String email) async { + await dio.post(Endpoints.deleteBuyURL, + data: {'id': id, 'email': email}); + await dio.post(Endpoints.deleteSellURL, + data: {'id': id, 'email': email}); + } + + Future deleteLnfMyAd(String id, String email) async { + await dio.post(Endpoints.deleteLostURL, + data: {'id': id, 'email': email}); + await dio.post(Endpoints.deleteFoundURL, + data: {'id': id, 'email': email}); + } + + Future getBuyItems() async { + //var res = await http.get(Uri.parse(Endpoints.buyURL)); + var response = await dio.get(Endpoints.buyURL); + // var lostItemsDetails = jsonDecode(res.body); + // return lostItemsDetails["details"]; + print(response.data); + return response.data.details; } - static Future> getBnsMyItems(String mail) async { - var res = await http.post(Uri.parse(Endpoints.bnsMyAdsURL), - headers: Endpoints.getHeader(), body: jsonEncode({'email': mail})); + Future getSellItems() async { + var res = await dio.get(Endpoints.sellURL); + return res.data.details; + } - var myItemsDetails = jsonDecode(res.body); + Future> getBnsMyItems(String mail) async { + print("here in function"); + var res = await dio.post(Endpoints.bnsMyAdsURL,data: {'email': mail}); + print(res.data); + var myItemsDetails = res.data; var sellList = (myItemsDetails["details"]["sellList"] as List) .map((e) => BuyModel.fromJson(e)) .toList(); @@ -119,11 +205,11 @@ class APIService { return [...sellList, ...buyList]; } - static Future> getLnfMyItems(String mail) async { - var res = await http.post(Uri.parse(Endpoints.lnfMyAdsURL), - headers: Endpoints.getHeader(), body: jsonEncode({'email': mail})); - - var myItemsDetails = jsonDecode(res.body); + Future> getLnfMyItems(String mail) async { + print("here"); + var res = await dio.post(Endpoints.lnfMyAdsURL,data: {'email': mail}); + print(res); + var myItemsDetails = res.data; var foundList = (myItemsDetails["details"]["foundList"] as List) .map((e) => FoundModel.fromJson(e)) .toList(); @@ -134,20 +220,23 @@ class APIService { return [...foundList, ...lostList]; } - static Future getLostItems() async { - var res = await http.get(Uri.parse(Endpoints.lostURL)); - var lostItemsDetails = jsonDecode(res.body); + Future getLostItems() async { + var res = await dio.get(Endpoints.lostURL); + var lostItemsDetails = res.data; return lostItemsDetails["details"]; } - static Future> getLostPage(int pageNumber) async { + Future> getLostPage(int pageNumber) async { + print("hre"); final queryParameters = { 'page': pageNumber.toString(), }; - final uri = - Uri.https('swc.iitg.ac.in', Endpoints.lostPath, queryParameters); - var response = await http.get(uri); - var json = jsonDecode(response.body); + // final uri = + // Uri.https('swc.iitg.ac.in', Endpoints.lostPath, queryParameters); + var response = await dio.get(Endpoints.lostPath,queryParameters: queryParameters); + print(response); + var json = response.data; + print(json); List lostPage = (json['details'] as List) .map((e) => LostModel.fromJson(e)) .toList(); @@ -155,14 +244,14 @@ class APIService { return lostPage; } - static Future> getFoundPage(int pageNumber) async { + Future> getFoundPage(int pageNumber) async { final queryParameters = { 'page': pageNumber.toString(), }; - final uri = - Uri.https('swc.iitg.ac.in', Endpoints.foundPath, queryParameters); - var response = await http.get(uri); - var json = jsonDecode(response.body); + // final uri = + // Uri.https('swc.iitg.ac.in', Endpoints.foundPath, queryParameters); + var response = await dio.get(Endpoints.foundPath,queryParameters: queryParameters); + var json = response.data; List lostPage = (json['details'] as List) .map((e) => FoundModel.fromJson(e)) .toList(); @@ -170,14 +259,14 @@ class APIService { return lostPage; } - static Future> getSellPage(int pageNumber) async { + Future> getSellPage(int pageNumber) async { final queryParameters = { 'page': pageNumber.toString(), }; - final uri = - Uri.https('swc.iitg.ac.in', Endpoints.sellPath, queryParameters); - var response = await http.get(uri); - var json = jsonDecode(response.body); + // final uri = + // Uri.https('swc.iitg.ac.in', Endpoints.sellPath, queryParameters); + var response = await dio.get(Endpoints.sellPath,queryParameters: queryParameters); + var json = response.data; List sellPage = (json['details'] as List) .map((e) => BuyModel.fromJson(e)) .toList(); @@ -185,13 +274,15 @@ class APIService { return sellPage; } - static Future> getBuyPage(int pageNumber) async { + Future> getBuyPage(int pageNumber) async { + print(pageNumber); final queryParameters = { 'page': pageNumber.toString(), }; - final uri = Uri.https('swc.iitg.ac.in', Endpoints.buyPath, queryParameters); - var response = await http.get(uri); - var json = jsonDecode(response.body); + //final uri = Uri.https('swc.iitg.ac.in', Endpoints.buyPath, queryParameters); + var response = await dio.get(Endpoints.sellPath,queryParameters: queryParameters); + print(response); + var json = response.data; List buyPage = (json['details'] as List) .map((e) => SellModel.fromJson(e)) .toList(); @@ -199,17 +290,17 @@ class APIService { return buyPage; } - static Future getFoundItems() async { - var res = await http.get(Uri.parse(Endpoints.foundURL)); - var foundItemsDetails = jsonDecode(res.body); + Future getFoundItems() async { + var res = await dio.get(Endpoints.foundURL); + var foundItemsDetails = res.data; return foundItemsDetails["details"]; } - static Future> postSellData( + Future> postSellData( Map data) async { - var res = await http.post( - Uri.parse(Endpoints.sellURL), - body: jsonEncode({ + var res = await dio.post( + Endpoints.sellURL, + data: { 'title': data['title'], 'description': data['description'], 'price': data['price'], @@ -217,17 +308,16 @@ class APIService { 'phonenumber': data['contact'], 'email': data['email'], 'username': data['name'] - }), - headers: Endpoints.getHeader(), + } ); - return jsonDecode(res.body); + return res.data; } - static Future> postBuyData( + Future> postBuyData( Map data) async { - var res = await http.post( - Uri.parse(Endpoints.buyURL), - body: jsonEncode({ + var res = await dio.post( + Endpoints.buyURL, + data: { 'title': data['title'], 'description': data['description'], 'price': data['total_price'], @@ -235,16 +325,15 @@ class APIService { 'phonenumber': data['contact'], 'email': data['email'], 'username': data['name'] - }), - headers: Endpoints.getHeader(), + } ); - return jsonDecode(res.body); + return res.data; } - static Future> postLostData( + Future> postLostData( Map data) async { - var res = await http.post(Uri.parse(Endpoints.lostURL), - body: jsonEncode({ + var res = await dio.post(Endpoints.lostURL, + data: { 'title': data['title'], 'description': data['description'], 'location': data['location'], @@ -252,15 +341,14 @@ class APIService { 'phonenumber': data['contact'], 'email': data['email'], 'username': data['name'] - }), - headers: Endpoints.getHeader()); - return jsonDecode(res.body); + }); + return res.data; } - static Future> postFoundData( + Future> postFoundData( Map data) async { - var res = await http.post(Uri.parse(Endpoints.foundURL), - body: jsonEncode({ + var res = await dio.post(Endpoints.foundURL, + data: { 'title': data['title'], 'description': data['description'], 'location': data['location'], @@ -268,16 +356,15 @@ class APIService { 'submittedat': data['submittedAt'], 'email': data['email'], 'username': data['name'] - }), - headers: Endpoints.getHeader()); - return jsonDecode(res.body); + }); + return res.data; } - static Future> getLastUpdated() async { - http.Response response = - await http.get(Uri.parse(Endpoints.lastUpdatedURL)); + Future> getLastUpdated() async { + var response = + await dio.get(Endpoints.lastUpdatedURL); var status = response.statusCode; - var body = jsonDecode(response.body); + var body = response.data; if (status == 200) { Map data = body; return data; @@ -286,10 +373,10 @@ class APIService { } } - static Future>> getContactData() async { - http.Response response = await http.get(Uri.parse(Endpoints.contactURL)); + Future>> getContactData() async { + var response = await dio.get(Endpoints.contactURL); var status = response.statusCode; - var body = jsonDecode(response.body); + var body = response.data; if (status == 200) { List> data = []; for (var json in body) { @@ -301,10 +388,10 @@ class APIService { } } - static Future>>> getBusData() async { - http.Response response = await http.get(Uri.parse(Endpoints.busURL)); + Future>>> getBusData() async { + var response = await dio.get(Endpoints.busURL); var status = response.statusCode; - var json = jsonDecode(response.body); + var json = response.data; if (status == 200) { Map>> answer = {}; for (String stop in json.keys) { @@ -330,10 +417,10 @@ class APIService { } } - static Future>> getFerryData() async { - http.Response response = await http.get(Uri.parse(Endpoints.ferryURL)); + Future>> getFerryData() async { + var response = await dio.get(Endpoints.ferryURL); var status = response.statusCode; - var json = jsonDecode(response.body); + var json = response.data; if (status == 200) { List> answer = []; for (var temp in json) { @@ -345,28 +432,23 @@ class APIService { } } - static Future getTimeTable({required String roll}) async { - final response = await http.post( - Uri.parse(Endpoints.timetableURL), - headers: { - HttpHeaders.contentTypeHeader: 'application/json', - 'security-key': Endpoints.apiSecurityKey - }, - body: jsonEncode({ + Future getTimeTable({required String roll}) async { + final response = await dio.post(Endpoints.timetableURL, + data: { "roll_number": roll, - }), + }, ); if (response.statusCode == 200) { - return RegisteredCourses.fromJson(jsonDecode(response.body)); + return RegisteredCourses.fromJson(response.data); } else { throw Exception(response.statusCode); } } - static Future>> getMessMenu() async { - http.Response response = await http.get(Uri.parse(Endpoints.messURL)); + Future>> getMessMenu() async { + var response = await dio.get(Endpoints.messURL); var status = response.statusCode; - var body = jsonDecode(response.body); + var body = response.data; if (status == 200) { List> data = []; for (var json in body) { @@ -378,45 +460,40 @@ class APIService { } } - static Future> getPolyline( + Future> getPolyline( {required LatLng source, required LatLng dest}) async { - final response = await http.get( - Uri.parse( - 'https://api.openrouteservice.org/v2/directions/driving-car?api_key=5b3ce3597851110001cf6248b144cc92443247b7b9e0bd5df85012f2&start=8.681495,49.41461&end=8.687872,49.420318'), - headers: { - HttpHeaders.contentTypeHeader: 'application/json', - }, + final response = await dio.get( + 'https://api.openrouteservice.org/v2/directions/driving-car?api_key=5b3ce3597851110001cf6248b144cc92443247b7b9e0bd5df85012f2&start=8.681495,49.41461&end=8.687872,49.420318', ); if (response.statusCode == 200) { - var body = jsonDecode(response.body); + var body = response.data; List res = []; for (var r in body['features'][0]['geometry']['coordinates']) { res.add(LatLng(r[0], r[1])); } return res; } else { - throw Exception(response.body); + throw Exception(response.data); } } - static Future> postUPSP( + Future> postUPSP( Map data) async { - var res = await http.post(Uri.parse(Endpoints.upspPost), - body: jsonEncode(data), headers: Endpoints.getHeader()); - return jsonDecode(res.body); + var res = await dio.post(Endpoints.upspPost, + data: data); + return res.data; } - static Future uploadFileToServer(File file) async { + Future uploadFileToServer(File file) async { var fileName = file.path.split('/').last; var formData = FormData.fromMap({ 'file': await MultipartFile.fromFile(file.path, filename: fileName), }); try { - var response = await Dio().post( + var response = await dio.post( Endpoints.uploadFileUPSP, options: Options( - contentType: 'multipart/form-data', - headers: {'security-key': Endpoints.apiSecurityKey}, + contentType: 'multipart/form-data' ), data: formData, onSendProgress: (int send, int total) { @@ -427,12 +504,12 @@ class APIService { return response.data['filename']; } return null; - } on DioError { + } on DioException { return null; } } - static Future> getFerryTiming() async { + Future> getFerryTiming() async { try { final prefs = await SharedPreferences.getInstance(); @@ -442,14 +519,11 @@ class APIService { jsonData = prefs.getString('ferryTimings') ?? ''; } else { - final res = await http.get( - Uri.parse(Endpoints.ferryURL), - headers: Endpoints.getHeader(), - ); + final res = await dio.get(Endpoints.ferryURL); - prefs.setString('ferryTimings', res.body); + prefs.setString('ferryTimings', res.data); jsonData = prefs.getString('ferryTimings') ?? ''; - jsonData=res.body; + jsonData=res.data; } List ferryTiming = json.decode(jsonData)['data']; List ferryTimings = []; @@ -463,20 +537,18 @@ class APIService { rethrow; } } - static Future getMealData(String hostel, String day, String mealType,) async { + + Future getMealData(String hostel, String day, String mealType,) async { try{ final prefs = await SharedPreferences.getInstance(); late String jsonData; if (prefs.getString('messMenu') != null) { jsonData = prefs.getString('messMenu') ?? ''; } else { - final res = await http.get( - Uri.parse(Endpoints.messURL), - headers: Endpoints.getHeader(), - ); - prefs.setString('messMenu', res.body); + final res = await dio.get(Endpoints.messURL); + prefs.setString('messMenu', res.data); - jsonData = prefs.getString('messMenu') ?? res.body; + jsonData = prefs.getString('messMenu') ?? res.data; } List answer = json.decode(jsonData)['details']; var meal = answer.firstWhere( @@ -504,9 +576,8 @@ class APIService { print(e); rethrow; } - } - static Future> getBusTiming() async { + Future> getBusTiming() async { try { final prefs = await SharedPreferences.getInstance(); @@ -515,12 +586,9 @@ class APIService { if (prefs.getString('busTimings') != null) { jsonData = prefs.getString('busTimings') ?? ''; } else { - final res = await http.get( - Uri.parse(Endpoints.busStops), - headers: Endpoints.getHeader(), - ); - prefs.setString('busTimings', res.body); - jsonData=res.body; + final res = await dio.get(Endpoints.busStops); + prefs.setString('busTimings', res.data); + jsonData=res.data; jsonData = prefs.getString('busTimings') ?? ''; } List busTiming = json.decode(jsonData)['data']; diff --git a/lib/services/data_provider.dart b/lib/services/data_provider.dart index e49c4d29..ba57c9d3 100644 --- a/lib/services/data_provider.dart +++ b/lib/services/data_provider.dart @@ -1,9 +1,9 @@ import 'dart:async'; import 'dart:collection'; +import 'package:flutter/material.dart'; import 'package:onestop_dev/globals/database_strings.dart'; import 'package:onestop_dev/models/contacts/contact_model.dart'; -import 'package:onestop_dev/models/food/mess_menu_model.dart'; import 'package:onestop_dev/models/food/restaurant_model.dart'; import 'package:onestop_dev/models/news/news_model.dart'; import 'package:onestop_dev/models/timetable/registered_courses.dart'; @@ -22,7 +22,7 @@ class DataProvider { static Future>>> getBusTimings() async { var cachedData = await LocalStorage.instance.getBusRecord(DatabaseRecords.busTimings); if (cachedData == null) { - Map>> busTime = await APIService.getBusData(); + Map>> busTime = await APIService().getBusData(); await LocalStorage.instance.storeBusData(busTime, DatabaseRecords.busTimings); return busTime; } @@ -41,7 +41,7 @@ class DataProvider { if (cachedData == null) { List> restaurantData = - await APIService.getRestaurantData(); + await APIService().getRestaurantData(); List restaurants = restaurantData.map((e) => RestaurantModel.fromJson(e)).toList(); @@ -57,7 +57,7 @@ class DataProvider { } static Future> getNews() async { - List> newsData = await APIService.getNewsData(); + List> newsData = await APIService().getNewsData(); List news = newsData.map((e) => NewsModel.fromJson(e)).toList(); return news; } @@ -66,7 +66,7 @@ class DataProvider { var cachedData = (await LocalStorage.instance.getRecord(DatabaseRecords.timetable))?[0]; if (cachedData == null) { RegisteredCourses timetableData = - await APIService.getTimeTable(roll: roll); + await APIService().getTimeTable(roll: roll); await LocalStorage.instance .storeData([timetableData.toJson()], DatabaseRecords.timetable); return timetableData; @@ -76,7 +76,7 @@ class DataProvider { if (DateTime.now().isBefore(semEnd)) { return RegisteredCourses.fromJson(cachedData as Map); } - return (await APIService.getTimeTable(roll: roll)); + return (await APIService().getTimeTable(roll: roll)); } static Future> getContacts() async { @@ -85,7 +85,7 @@ class DataProvider { if (cachedData == null) { List> contactData = - await APIService.getContactData(); + await APIService().getContactData(); for (var element in contactData) { people[element['name']] = ContactModel.fromJson(element); } diff --git a/lib/stores/login_store.dart b/lib/stores/login_store.dart index 3b14bbb3..ce331365 100644 --- a/lib/stores/login_store.dart +++ b/lib/stores/login_store.dart @@ -1,13 +1,16 @@ // import 'package:aad_oauth/aad_oauth.dart'; // import 'package:aad_oauth/model/config.dart'; +import 'package:onestop_dev/globals/database_strings.dart'; +import 'package:onestop_dev/globals/endpoints.dart'; +import 'package:onestop_dev/services/api.dart'; import 'package:onestop_dev/services/local_storage.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:webview_cookie_manager/webview_cookie_manager.dart'; - +import 'package:dio/dio.dart'; class LoginStore { Map userData = {}; final cookieManager = WebviewCookieManager(); - final String guestEmail = 'guest_user'; + bool isGuest = false; // static final Config config = Config( // tenant: '850aa78d-94e1-4bc6-9cf3-8c11b530701c', // clientId: '81f3e9f0-b0fd-48e0-9d36-e6058e5c6d4f', @@ -45,42 +48,48 @@ class LoginStore { Future isAlreadyAuthenticated() async { SharedPreferences user = await SharedPreferences.getInstance(); - if (user.containsKey("name")) { - saveToUserData(user); + if (user.containsKey(BackendHelper.refreshtoken)) { + saveToUserInfo(user); return true; } return false; } bool get isGuestUser { - if (userData['email'] == guestEmail) { - return true; - } - return false; + return isGuest; } Future signInAsGuest() async { + APIService().getBuyPage(1); + print("GUEST SIGN IN"); + isGuest=true; var sharedPrefs = await SharedPreferences.getInstance(); - saveToPreferences(sharedPrefs, { - 'displayName': 'Guest User', - 'mail': guestEmail, - 'surname': ' ', - 'id': '' - }); + print(Endpoints.guestLogin); + print(Endpoints.getHeader()); + final response = await APIService().guestUserLogin(); + print(response.data); + saveToPreferences(sharedPrefs, response.data); + saveToUserInfo(sharedPrefs); + sharedPrefs.setBool("isGuest", true); // guest sign in } void saveToPreferences(SharedPreferences instance, dynamic data) { - instance.setString("name", data["displayName"]); - instance.setString("email", data["mail"]); - instance.setString("rollno", data["surname"]); - instance.setString("id", data["id"]); + print(data); + instance.setString(BackendHelper.accesstoken, data[BackendHelper.accesstoken]); + instance.setString(BackendHelper.refreshtoken, data[BackendHelper.refreshtoken]); + instance.setString("name", data["name"]); + instance.setString("email", data["email"]); + instance.setBool("isGuest", false); // general case } - void saveToUserData(SharedPreferences instance) { + void saveToUserInfo(SharedPreferences instance) { + print("here"); + print(instance.getString("name")); + print(instance.getString("email")); userData["name"] = instance.getString("name") ?? " "; userData["email"] = instance.getString("email") ?? " "; - userData["rollno"] = instance.getString("rollno") ?? " "; - userData["id"] = instance.getString("id") ?? " "; + isGuest = instance.getBool("isGuest")!; + print(userData); } void logOut(Function navigationPopCallBack) async { @@ -88,7 +97,9 @@ class LoginStore { SharedPreferences user = await SharedPreferences.getInstance(); user.clear(); userData.clear(); + isGuest=false; await LocalStorage.instance.deleteRecordsLogOut(); navigationPopCallBack(); } + } diff --git a/lib/stores/mapbox_store.dart b/lib/stores/mapbox_store.dart index 72f27ce9..9f42c6d3 100644 --- a/lib/stores/mapbox_store.dart +++ b/lib/stores/mapbox_store.dart @@ -137,8 +137,8 @@ abstract class _MapBoxStore with Store { } @action - Future getPolylines(int i) async { - loadOperation = APIService.getPolyline( + Future getPolylines(int i,BuildContext context) async { + loadOperation = APIService().getPolyline( source: LatLng(userlat, userlong), dest: const LatLng(26.2027, 91.7004)) .asObservable(); diff --git a/lib/stores/mapbox_store.g.dart b/lib/stores/mapbox_store.g.dart index cb948698..6e21b216 100644 --- a/lib/stores/mapbox_store.g.dart +++ b/lib/stores/mapbox_store.g.dart @@ -194,8 +194,8 @@ mixin _$MapBoxStore on _MapBoxStore, Store { AsyncAction('_MapBoxStore.getPolylines', context: context); @override - Future getPolylines(int i) { - return _$getPolylinesAsyncAction.run(() => super.getPolylines(i)); + Future getPolylines(int i, BuildContext context) { + return _$getPolylinesAsyncAction.run(() => super.getPolylines(i, context)); } late final _$_MapBoxStoreActionController = diff --git a/lib/stores/mess_store.dart b/lib/stores/mess_store.dart index 34866186..c57abe73 100644 --- a/lib/stores/mess_store.dart +++ b/lib/stores/mess_store.dart @@ -3,7 +3,6 @@ import 'package:mobx/mobx.dart'; import 'package:onestop_dev/functions/food/get_day.dart'; import 'package:onestop_dev/models/food/mess_menu_model.dart'; import 'package:onestop_dev/services/api.dart'; -import 'package:onestop_dev/services/data_provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; part 'mess_store.g.dart'; class MessStore = _MessStore with _$MessStore; @@ -54,10 +53,10 @@ abstract class _MessStore with Store { void setupReactions() async { autorun((_) async{ if(selectedHostel.status == FutureStatus.fulfilled){ - MealType requiredModel = await APIService.getMealData(selectedHostel.value! , selectedDay, selectedMeal); + MealType requiredModel = await APIService().getMealData(selectedHostel.value! , selectedDay, selectedMeal); setmealData(requiredModel); }else{ - MealType requiredModel = await APIService.getMealData('kameng' , 'Monday', 'Breakfast'); + MealType requiredModel = await APIService().getMealData('kameng' , 'Monday', 'Breakfast'); setmealData(requiredModel); } }); diff --git a/lib/stores/mess_store.g.dart b/lib/stores/mess_store.g.dart index b472dedc..a42f81fe 100644 --- a/lib/stores/mess_store.g.dart +++ b/lib/stores/mess_store.g.dart @@ -14,11 +14,11 @@ mixin _$MessStore on _MessStore, Store { @override bool get hostelLoaded => (_$hostelLoadedComputed ??= Computed(() => super.hostelLoaded, - name: '_MessStore.hostelLoaded')) + name: '_MessStore.hostelLoaded')) .value; late final _$selectedDayAtom = - Atom(name: '_MessStore.selectedDay', context: context); + Atom(name: '_MessStore.selectedDay', context: context); @override String get selectedDay { @@ -34,7 +34,7 @@ mixin _$MessStore on _MessStore, Store { } late final _$selectedMealAtom = - Atom(name: '_MessStore.selectedMeal', context: context); + Atom(name: '_MessStore.selectedMeal', context: context); @override String get selectedMeal { @@ -50,7 +50,7 @@ mixin _$MessStore on _MessStore, Store { } late final _$selectedHostelAtom = - Atom(name: '_MessStore.selectedHostel', context: context); + Atom(name: '_MessStore.selectedHostel', context: context); @override ObservableFuture get selectedHostel { @@ -66,7 +66,7 @@ mixin _$MessStore on _MessStore, Store { } late final _$mealDataAtom = - Atom(name: '_MessStore.mealData', context: context); + Atom(name: '_MessStore.mealData', context: context); @override MealType get mealData { @@ -82,12 +82,12 @@ mixin _$MessStore on _MessStore, Store { } late final _$_MessStoreActionController = - ActionController(name: '_MessStore', context: context); + ActionController(name: '_MessStore', context: context); @override void setDay(String s) { final _$actionInfo = - _$_MessStoreActionController.startAction(name: '_MessStore.setDay'); + _$_MessStoreActionController.startAction(name: '_MessStore.setDay'); try { return super.setDay(s); } finally { @@ -98,7 +98,7 @@ mixin _$MessStore on _MessStore, Store { @override void setMeal(String s) { final _$actionInfo = - _$_MessStoreActionController.startAction(name: '_MessStore.setMeal'); + _$_MessStoreActionController.startAction(name: '_MessStore.setMeal'); try { return super.setMeal(s); } finally { @@ -109,7 +109,7 @@ mixin _$MessStore on _MessStore, Store { @override void setHostel(String s) { final _$actionInfo = - _$_MessStoreActionController.startAction(name: '_MessStore.setHostel'); + _$_MessStoreActionController.startAction(name: '_MessStore.setHostel'); try { return super.setHostel(s); } finally { diff --git a/lib/stores/restaurant_store.dart b/lib/stores/restaurant_store.dart index d66e94ec..e065281b 100644 --- a/lib/stores/restaurant_store.dart +++ b/lib/stores/restaurant_store.dart @@ -1,5 +1,4 @@ // ignore_for_file: library_private_types_in_public_api - import 'package:fuzzy/fuzzy.dart'; import 'package:mobx/mobx.dart'; import 'package:onestop_dev/models/food/restaurant_model.dart'; diff --git a/lib/stores/timetable_store.dart b/lib/stores/timetable_store.dart index 2df05264..94aed2c7 100644 --- a/lib/stores/timetable_store.dart +++ b/lib/stores/timetable_store.dart @@ -58,7 +58,7 @@ abstract class _TimetableStore with Store { bool showDropDown = false; @action - Future setTimetable(String rollNumber) async { + Future setTimetable(String rollNumber,BuildContext context) async { if (loadOperation.value == null) { loadOperation = DataProvider.getTimeTable(roll: rollNumber).asObservable(); diff --git a/lib/stores/timetable_store.g.dart b/lib/stores/timetable_store.g.dart index 4d469d14..c51f733e 100644 --- a/lib/stores/timetable_store.g.dart +++ b/lib/stores/timetable_store.g.dart @@ -90,8 +90,9 @@ mixin _$TimetableStore on _TimetableStore, Store { AsyncAction('_TimetableStore.setTimetable', context: context); @override - Future setTimetable(String rollNumber) { - return _$setTimetableAsyncAction.run(() => super.setTimetable(rollNumber)); + Future setTimetable(String rollNumber, BuildContext context) { + return _$setTimetableAsyncAction + .run(() => super.setTimetable(rollNumber, context)); } late final _$_TimetableStoreActionController = diff --git a/lib/stores/travel_store.dart b/lib/stores/travel_store.dart index 5f46cd6f..474a83e0 100644 --- a/lib/stores/travel_store.dart +++ b/lib/stores/travel_store.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import 'package:mobx/mobx.dart'; import 'package:onestop_dev/models/travel/travel_timing_model.dart'; import 'package:onestop_dev/services/api.dart'; -import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/widgets/travel/bus_details.dart'; import 'package:onestop_dev/widgets/travel/stops_list.dart'; @@ -30,7 +29,7 @@ abstract class _TravelStore with Store { @observable ObservableFuture> ferryTimings = - ObservableFuture(APIService.getFerryTiming()); + ObservableFuture(APIService().getFerryTiming()); @action void setFerryDayType(String s) { diff --git a/lib/stores/travel_store.g.dart b/lib/stores/travel_store.g.dart index 1e120daf..e93f4fdd 100644 --- a/lib/stores/travel_store.g.dart +++ b/lib/stores/travel_store.g.dart @@ -14,31 +14,31 @@ mixin _$TravelStore on _TravelStore, Store { @override String get ferryDataIndex => (_$ferryDataIndexComputed ??= Computed(() => super.ferryDataIndex, - name: '_TravelStore.ferryDataIndex')) + name: '_TravelStore.ferryDataIndex')) .value; Computed? _$busDayTypeIndexComputed; @override int get busDayTypeIndex => (_$busDayTypeIndexComputed ??= Computed(() => super.busDayTypeIndex, - name: '_TravelStore.busDayTypeIndex')) + name: '_TravelStore.busDayTypeIndex')) .value; Computed? _$busPageComputed; @override Widget get busPage => (_$busPageComputed ??= - Computed(() => super.busPage, name: '_TravelStore.busPage')) + Computed(() => super.busPage, name: '_TravelStore.busPage')) .value; Computed? _$isBusSelectedComputed; @override bool get isBusSelected => (_$isBusSelectedComputed ??= Computed(() => super.isBusSelected, - name: '_TravelStore.isBusSelected')) + name: '_TravelStore.isBusSelected')) .value; late final _$selectBusesorStopsAtom = - Atom(name: '_TravelStore.selectBusesorStops', context: context); + Atom(name: '_TravelStore.selectBusesorStops', context: context); @override int get selectBusesorStops { @@ -54,7 +54,7 @@ mixin _$TravelStore on _TravelStore, Store { } late final _$busDayTypeAtom = - Atom(name: '_TravelStore.busDayType', context: context); + Atom(name: '_TravelStore.busDayType', context: context); @override String get busDayType { @@ -70,7 +70,7 @@ mixin _$TravelStore on _TravelStore, Store { } late final _$ferryDirectionAtom = - Atom(name: '_TravelStore.ferryDirection', context: context); + Atom(name: '_TravelStore.ferryDirection', context: context); @override String get ferryDirection { @@ -86,7 +86,7 @@ mixin _$TravelStore on _TravelStore, Store { } late final _$ferryDayTypeAtom = - Atom(name: '_TravelStore.ferryDayType', context: context); + Atom(name: '_TravelStore.ferryDayType', context: context); @override String get ferryDayType { @@ -102,7 +102,7 @@ mixin _$TravelStore on _TravelStore, Store { } late final _$selectedFerryGhatAtom = - Atom(name: '_TravelStore.selectedFerryGhat', context: context); + Atom(name: '_TravelStore.selectedFerryGhat', context: context); @override String get selectedFerryGhat { @@ -118,7 +118,7 @@ mixin _$TravelStore on _TravelStore, Store { } late final _$ferryTimingsAtom = - Atom(name: '_TravelStore.ferryTimings', context: context); + Atom(name: '_TravelStore.ferryTimings', context: context); @override ObservableFuture> get ferryTimings { @@ -134,7 +134,7 @@ mixin _$TravelStore on _TravelStore, Store { } late final _$_TravelStoreActionController = - ActionController(name: '_TravelStore', context: context); + ActionController(name: '_TravelStore', context: context); @override void setFerryDayType(String s) { diff --git a/lib/widgets/food/mess/mess_menu.dart b/lib/widgets/food/mess/mess_menu.dart index 15acd1d6..4a701fe0 100644 --- a/lib/widgets/food/mess/mess_menu.dart +++ b/lib/widgets/food/mess/mess_menu.dart @@ -44,7 +44,7 @@ class MessMenu extends StatelessWidget { child: Padding( padding: const EdgeInsets.all(16), child: Row(children: [ - const Expanded( + Expanded( flex: 1, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, diff --git a/lib/widgets/home/date_course.dart b/lib/widgets/home/date_course.dart index f602b170..d952fdd1 100644 --- a/lib/widgets/home/date_course.dart +++ b/lib/widgets/home/date_course.dart @@ -3,6 +3,7 @@ import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:onestop_dev/globals/days.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; +import 'package:onestop_dev/stores/login_store.dart'; import 'package:onestop_dev/stores/timetable_store.dart'; import 'package:onestop_dev/widgets/timetable/dropdown_arrow.dart'; import 'package:onestop_dev/widgets/timetable/home_shimmer.dart'; diff --git a/lib/widgets/login/login_button.dart b/lib/widgets/login/login_button.dart index 1aa1a203..45306afa 100644 --- a/lib/widgets/login/login_button.dart +++ b/lib/widgets/login/login_button.dart @@ -59,6 +59,7 @@ class LoginButton extends StatelessWidget { ..onTap = () async { await context.read().signInAsGuest(); // TODO: Next version of Flutter will have context.mounted. Use that instead to escape the lint + print("completed sign in"); Navigator.of(context).pushNamedAndRemoveUntil( '/', (Route route) => false); }, diff --git a/lib/widgets/login/login_webview.dart b/lib/widgets/login/login_webview.dart index 0c19a8f5..0e747f97 100644 --- a/lib/widgets/login/login_webview.dart +++ b/lib/widgets/login/login_webview.dart @@ -1,5 +1,7 @@ import 'dart:async'; +import 'dart:convert'; import 'package:flutter/material.dart'; +import 'package:onestop_dev/globals/endpoints.dart'; import 'package:onestop_dev/stores/login_store.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -23,7 +25,7 @@ class _LoginWebViewState extends State { @override Widget build(BuildContext context) { return WebView( - initialUrl: "https://swc.iitg.ac.in/onestopapi/v2/auth/microsoft", + initialUrl: "${Endpoints.baseUrl}/auth/microsoft", javascriptMode: JavascriptMode.unrestricted, onWebViewCreated: (controller) { widget._controller.complete(controller); @@ -31,21 +33,16 @@ class _LoginWebViewState extends State { onWebResourceError: (context) {}, onPageFinished: (url) async { if (url.startsWith( - "https://swc.iitg.ac.in/onestopapi/v2/auth/microsoft/redirect?code")) { + "${Endpoints.baseUrl}/auth/microsoft/redirect?code")) { WebViewController controller = await widget._controller.future; - var userInfoString = await controller.runJavascriptReturningResult("document.querySelector('#userInfo').innerText"); - var userInfo = {}; - List values = userInfoString.replaceAll('"', '').split("/"); - if (!values[0].toLowerCase().contains("error")) { - userInfo["displayName"] = values[0]; - userInfo["mail"] = values[1]; - userInfo["surname"] = values[2]; - userInfo["id"] = values[3]; + var userTokensString = await controller.runJavascriptReturningResult("document.querySelector('#userTokens').innerText"); + print(userTokensString); + if (userTokensString!="ERROR OCCURED") { SharedPreferences user = await SharedPreferences.getInstance(); if (!mounted) return; - context.read().saveToPreferences(user, userInfo); - context.read().saveToUserData(user); + context.read().saveToPreferences(user, jsonDecode(userTokensString)); + context.read().saveToUserInfo(user); await WebviewCookieManager().clearCookies(); Navigator.of(context) .pushNamedAndRemoveUntil('/', (Route route) => false); diff --git a/lib/widgets/lostfound/ads_tile.dart b/lib/widgets/lostfound/ads_tile.dart index cd60b37e..856340f9 100644 --- a/lib/widgets/lostfound/ads_tile.dart +++ b/lib/widgets/lostfound/ads_tile.dart @@ -1,6 +1,7 @@ import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; import 'package:onestop_dev/functions/food/rest_frame_builder.dart'; +import 'package:onestop_dev/functions/utility/show_snackbar.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/models/lostfound/found_model.dart'; @@ -169,20 +170,16 @@ class _MyAdsTileState extends State { ), onPressed: () async { if (isLnf) { - await APIService.deleteLnfMyAd( + await APIService().deleteLnfMyAd( widget.model.id, widget.model.email); } else { - await APIService.deleteBnsMyAd( + await APIService().deleteBnsMyAd( widget.model.id, widget.model.email); } if (!mounted) return; Navigator.of(context).pop(); - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text( - "Deleted your post successfully", - style: MyFonts.w500, - ))); + showSnackBar("Deleted your post successfully"); }, ), ), diff --git a/lib/widgets/lostfound/claim_call_button.dart b/lib/widgets/lostfound/claim_call_button.dart index decd5ca2..be9e82b3 100644 --- a/lib/widgets/lostfound/claim_call_button.dart +++ b/lib/widgets/lostfound/claim_call_button.dart @@ -51,7 +51,7 @@ class _ClaimCallButtonState extends State { context.read().userData['name']; var email = context.read().userData['email']; - var body = await APIService.claimFoundItem( + var body = await APIService().claimFoundItem( name: name!, email: email!, id: widget.model.id); diff --git a/lib/widgets/mapbox/carousel_card.dart b/lib/widgets/mapbox/carousel_card.dart index 17d75319..bd907738 100644 --- a/lib/widgets/mapbox/carousel_card.dart +++ b/lib/widgets/mapbox/carousel_card.dart @@ -7,7 +7,6 @@ import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/models/travel/travel_timing_model.dart'; import 'package:onestop_dev/services/api.dart'; -import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/stores/mapbox_store.dart'; import 'package:provider/provider.dart'; @@ -23,7 +22,7 @@ class CarouselCard extends StatelessWidget { Future getNextTime() async { String today = getFormattedDay(); if (context.read().indexBusesorFerry == 0) { - List allBusTimes = await APIService.getBusTiming(); + List allBusTimes = await APIService().getBusTiming(); List weekdaysTimes= []; List weekendTimes=[]; for(var xyz in allBusTimes){ @@ -50,7 +49,7 @@ class CarouselCard extends StatelessWidget { } return 'Next Bus at: ${nextTime(weekdaysTimes)}'; } else { - List ferryTimings = await APIService.getFerryTiming(); + List ferryTimings = await APIService().getFerryTiming(); List weekdaysTimes= []; List weekendTimes=[]; TravelTiming requiredModel = diff --git a/lib/widgets/profile/feedback.dart b/lib/widgets/profile/feedback.dart index 7d92bc75..e90dfd67 100644 --- a/lib/widgets/profile/feedback.dart +++ b/lib/widgets/profile/feedback.dart @@ -200,7 +200,7 @@ class _FeedBackState extends State { }; setState(() => enableSubmitButton = false); bool success = - await APIService.postFeedbackData(data); + await APIService().postFeedbackData(data); String snackBar = "There was an error while sending your feedback.\nPlease try again later or reach out to any member using the Contacts section."; if (success) { diff --git a/lib/widgets/travel/bus_details.dart b/lib/widgets/travel/bus_details.dart index b0c38bb1..d68fd1f0 100644 --- a/lib/widgets/travel/bus_details.dart +++ b/lib/widgets/travel/bus_details.dart @@ -5,7 +5,6 @@ import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/models/travel/travel_timing_model.dart'; import 'package:onestop_dev/services/api.dart'; -import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; import 'package:provider/provider.dart'; import '../../functions/travel/next_time.dart'; @@ -34,7 +33,7 @@ class _BusDetailsState extends State { Widget build(BuildContext context) { var daytype = context.read().busDayType; return FutureBuilder>( - future: APIService.getBusTiming(), + future: APIService().getBusTiming(), builder: (context, snapshot) { if (snapshot.hasData) { busTime = snapshot.data; diff --git a/lib/widgets/travel/next_time_card.dart b/lib/widgets/travel/next_time_card.dart index 1cc7913f..22fd4a3f 100644 --- a/lib/widgets/travel/next_time_card.dart +++ b/lib/widgets/travel/next_time_card.dart @@ -8,7 +8,6 @@ import 'package:onestop_dev/functions/travel/next_time.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/services/api.dart'; -import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/stores/mapbox_store.dart'; import 'package:provider/provider.dart'; @@ -28,7 +27,7 @@ class _NextTimeCardState extends State { Future getNextTime() async { String today = getFormattedDay(); if (mapStore.indexBusesorFerry == 0) { - var allBusTimes = await APIService.getBusTiming(); + var allBusTimes = await APIService().getBusTiming(); List weekdaysTimes= []; List weekendTimes=[]; for(var xyz in allBusTimes){ @@ -45,7 +44,7 @@ class _NextTimeCardState extends State { } } weekendTimes.sort((a, b) => a.compareTo(b)); - List> busTimes = [[], []]; + //List> busTimes = [[], []]; if (today == 'Fri') { return nextTime(weekdaysTimes, firstTime: weekendTimes[0].toString()); } else if (today == 'Sun') { @@ -55,7 +54,7 @@ class _NextTimeCardState extends State { } return nextTime(weekdaysTimes); } else { - List ferryTimings = await APIService.getFerryTiming(); + List ferryTimings = await APIService().getFerryTiming(); List weekdaysTimes= []; List weekendTimes=[]; TravelTiming requiredModel = diff --git a/lib/widgets/travel/stops_list.dart b/lib/widgets/travel/stops_list.dart index e112a738..04d78ace 100644 --- a/lib/widgets/travel/stops_list.dart +++ b/lib/widgets/travel/stops_list.dart @@ -9,7 +9,6 @@ import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/models/travel/travel_timing_model.dart'; import 'package:onestop_dev/services/api.dart'; -import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/stores/mapbox_store.dart'; import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; import 'package:provider/provider.dart'; @@ -26,7 +25,7 @@ class BusStopList extends StatelessWidget { itemBuilder: (BuildContext context, int index) { var mapStore = context.read(); return FutureBuilder>( - future: APIService.getBusTiming(), + future: APIService().getBusTiming(), builder: (context, snapshot) { if (snapshot.hasData) { List? busTime = snapshot.data ; diff --git a/lib/widgets/ui/appbar.dart b/lib/widgets/ui/appbar.dart index ace81885..8335369f 100644 --- a/lib/widgets/ui/appbar.dart +++ b/lib/widgets/ui/appbar.dart @@ -2,7 +2,6 @@ import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; -import 'package:onestop_dev/pages/profile.dart'; import 'package:onestop_dev/pages/profile/edit_profile.dart'; AppBar appBar(BuildContext context, {bool displayIcon = true}) { diff --git a/pubspec.yaml b/pubspec.yaml index b3928642..83ff5038 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -63,7 +63,7 @@ dependencies: timeago: ^3.2.2 get: 4.6.1 map_launcher: ^2.3.0+1 - json_annotation: ^4.7.0 + json_annotation: ^4.8.1 sembast: ^3.2.0 shimmer: ^2.0.0 google_maps_flutter: ^2.1.10 From 1db072c04d394c1fcdcc789b27385dc567f9624c Mon Sep 17 00:00:00 2001 From: Priyanshu Srivastava Date: Sat, 10 Jun 2023 22:51:40 +0530 Subject: [PATCH 46/82] minor bug fix --- lib/services/api.dart | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/services/api.dart b/lib/services/api.dart index cff3c15b..a496a532 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -522,7 +522,7 @@ class APIService { ), headers: { 'Content-Type': 'application/json', - 'security-key': apiSecurityKey + 'security-key': Endpoints.apiSecurityKey }, ); diff --git a/pubspec.yaml b/pubspec.yaml index 64607ffb..be21a1a1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -74,7 +74,7 @@ dependencies: infinite_scroll_pagination: ^3.2.0 upgrader: ^6.2.0 badges: ^2.0.3 - image: ^3.3.0 + image: ^4.0.15 firebase_messaging: ^14.1.3 flutter_local_notifications: ^13.0.0 firebase_core: ^2.3.0 From fa72d974d816c6132909fd1d962efe7deac6601c Mon Sep 17 00:00:00 2001 From: Kunalpal215 Date: Sun, 11 Jun 2023 07:53:26 +0530 Subject: [PATCH 47/82] added profile page --- lib/functions/home/action_button.dart | 4 +- lib/globals/endpoints.dart | 1 + lib/main.dart | 59 ++- lib/models/profile/profile_model.dart | 38 +- lib/models/profile/profile_model.g.dart | 37 +- lib/pages/buy_sell/bns_home.dart | 7 +- lib/pages/buy_sell/buy_form.dart | 4 +- lib/pages/home/home_tab.dart | 21 +- lib/pages/lost_found/lnf_home.dart | 7 +- lib/pages/profile.dart | 6 +- lib/pages/profile/edit_profile.dart | 383 +++++++++++-------- lib/pages/profile/profile_page.dart | 73 ++-- lib/pages/quick_links/cab_share.dart | 6 +- lib/pages/quick_links/gc_scoreboard.dart | 2 +- lib/pages/timetable/timetable.dart | 5 +- lib/pages/upsp/details_upsp.dart | 5 +- lib/pages/upsp/upsp.dart | 5 +- lib/services/api.dart | 22 +- lib/stores/login_store.dart | 23 +- lib/widgets/login/login_webview.dart | 16 +- lib/widgets/lostfound/claim_call_button.dart | 10 +- lib/widgets/profile/data_tile.dart | 52 ++- lib/widgets/profile/feedback.dart | 4 +- lib/widgets/ui/appbar.dart | 7 +- lib/widgets/ui/guest_restrict.dart | 20 + 25 files changed, 472 insertions(+), 345 deletions(-) create mode 100644 lib/widgets/ui/guest_restrict.dart diff --git a/lib/functions/home/action_button.dart b/lib/functions/home/action_button.dart index 0b7ca7e6..38dbbbb4 100644 --- a/lib/functions/home/action_button.dart +++ b/lib/functions/home/action_button.dart @@ -2,9 +2,11 @@ import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; import 'package:onestop_dev/functions/timetable/show_dialog.dart'; import 'package:onestop_dev/globals/my_colors.dart'; +import 'package:onestop_dev/stores/login_store.dart'; +import 'package:provider/provider.dart'; Widget homeActionButton(BuildContext context, int index) { - return (index == 3) + return (index == 3 && !LoginStore.isGuest) ? FloatingActionButton( backgroundColor: lBlue2, shape: diff --git a/lib/globals/endpoints.dart b/lib/globals/endpoints.dart index a2b5ccbe..1b84d643 100644 --- a/lib/globals/endpoints.dart +++ b/lib/globals/endpoints.dart @@ -34,6 +34,7 @@ class Endpoints { static const String upspPost = '/upsp/submit-request'; static const String uploadFileUPSP = "/upsp/file-upload"; static const String guestLogin = "/user/guest/login"; + static const String userProfile = "/user"; static getHeader() { return {'Content-Type': 'application/json', 'security-key': Endpoints.apiSecurityKey}; } diff --git a/lib/main.dart b/lib/main.dart index 907fa114..1d2977d5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -21,7 +21,7 @@ void main() async { [DeviceOrientation.portraitDown, DeviceOrientation.portraitUp]); SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom, SystemUiOverlay.top]); - // await checkLastUpdated(); + await checkLastUpdated(); runApp(const MyApp()); } @@ -35,37 +35,30 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { debugInvertOversizedImages = true; - return FutureBuilder( - future: checkLastUpdated(), - builder: (buildContext,snapshot){ - if(snapshot.hasData){ - return MultiProvider( - providers: [ - Provider( - create: (_) => LoginStore(), - ), - Provider( - create: (_) => RestaurantStore(), - ), - Provider( - create: (_) => MapBoxStore(), - ), - Provider( - create: (_) => CommonStore(), - ) - ], - child: MaterialApp( - scaffoldMessengerKey: rootScaffoldMessengerKey, - debugShowCheckedModeBanner: false, - theme: ThemeData( - scaffoldBackgroundColor: kBackground, - splashColor: Colors.transparent), - title: 'OneStop 2.0', - routes: routes, - ), - ); - } - return Container(); - }); + return MultiProvider( + providers: [ + Provider( + create: (_) => LoginStore(), + ), + Provider( + create: (_) => RestaurantStore(), + ), + Provider( + create: (_) => MapBoxStore(), + ), + Provider( + create: (_) => CommonStore(), + ) + ], + child: MaterialApp( + scaffoldMessengerKey: rootScaffoldMessengerKey, + debugShowCheckedModeBanner: false, + theme: ThemeData( + scaffoldBackgroundColor: kBackground, + splashColor: Colors.transparent), + title: 'OneStop 2.0', + routes: routes, + ), + ); } } diff --git a/lib/models/profile/profile_model.dart b/lib/models/profile/profile_model.dart index ee793614..47bcbc4f 100644 --- a/lib/models/profile/profile_model.dart +++ b/lib/models/profile/profile_model.dart @@ -3,26 +3,32 @@ part 'profile_model.g.dart'; @JsonSerializable() class ProfileModel { - final String username; - final String rollNumber; - final String outlook; - final String gmail; - final String contact; - final String emergencyContact; - final String hostel; + final String name; + final String rollNo; + final String outlookEmail; + final String? altEmail; + final int? phoneNumber; + final int? emergencyPhoneNumber; + final String? gender; + final String? roomNo; + final String? homeAddress; + final String? dob; + final String? hostel; final String? linkedin; - final DateTime? date; final String? image; ProfileModel( - {required this.username, - required this.rollNumber, - required this.outlook, - required this.gmail, - required this.contact, - required this.emergencyContact, - required this.hostel, + {required this.name, + required this.rollNo, + required this.outlookEmail, + this.altEmail, + this.phoneNumber, + this.emergencyPhoneNumber, + this.gender, + this.roomNo, + this.homeAddress, + this.dob, + this.hostel, this.linkedin, - this.date, this.image}); factory ProfileModel.fromJson(Map map) => diff --git a/lib/models/profile/profile_model.g.dart b/lib/models/profile/profile_model.g.dart index 8ad81dc0..acd57101 100644 --- a/lib/models/profile/profile_model.g.dart +++ b/lib/models/profile/profile_model.g.dart @@ -7,29 +7,34 @@ part of 'profile_model.dart'; // ************************************************************************** ProfileModel _$ProfileModelFromJson(Map json) => ProfileModel( - username: json['username'] as String, - rollNumber: json['rollNumber'] as String, - outlook: json['outlook'] as String, - gmail: json['gmail'] as String, - contact: json['contact'] as String, - emergencyContact: json['emergencyContact'] as String, - hostel: json['hostel'] as String, + name: json['name'] as String, + rollNo: json['rollNo'] as String, + outlookEmail: json['outlookEmail'] as String, + altEmail: json['altEmail'] as String?, + phoneNumber: json['phoneNumber'] as int?, + emergencyPhoneNumber: json['emergencyPhoneNumber'] as int?, + gender: json['gender'] as String?, + roomNo: json['roomNo'] as String?, + homeAddress: json['homeAddress'] as String?, + dob: json['dob'] as String?, + hostel: json['hostel'] as String?, linkedin: json['linkedin'] as String?, - date: - json['date'] == null ? null : DateTime.parse(json['date'] as String), image: json['image'] as String?, ); Map _$ProfileModelToJson(ProfileModel instance) => { - 'username': instance.username, - 'rollNumber': instance.rollNumber, - 'outlook': instance.outlook, - 'gmail': instance.gmail, - 'contact': instance.contact, - 'emergencyContact': instance.emergencyContact, + 'name': instance.name, + 'rollNo': instance.rollNo, + 'outlookEmail': instance.outlookEmail, + 'altEmail': instance.altEmail, + 'phoneNumber': instance.phoneNumber, + 'emergencyPhoneNumber': instance.emergencyPhoneNumber, + 'gender': instance.gender, + 'roomNo': instance.roomNo, + 'homeAddress': instance.homeAddress, + 'dob': instance.dob, 'hostel': instance.hostel, 'linkedin': instance.linkedin, - 'date': instance.date?.toIso8601String(), 'image': instance.image, }; diff --git a/lib/pages/buy_sell/bns_home.dart b/lib/pages/buy_sell/bns_home.dart index 972b280d..009df795 100644 --- a/lib/pages/buy_sell/bns_home.dart +++ b/lib/pages/buy_sell/bns_home.dart @@ -14,6 +14,7 @@ import 'package:onestop_dev/widgets/buy_sell/buy_tile.dart'; import 'package:onestop_dev/widgets/buy_sell/item_type_bar.dart'; import 'package:onestop_dev/widgets/lostfound/add_item_button.dart'; import 'package:onestop_dev/widgets/lostfound/ads_tile.dart'; +import 'package:onestop_dev/widgets/ui/guest_restrict.dart'; import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; import 'package:provider/provider.dart'; @@ -168,12 +169,10 @@ class _BuySellHomeState extends State { ) else Expanded( - child: context.read().isGuestUser ? const PaginationText( - text: - "Not Available in guest mode") + child: context.read().isGuestUser ? const GuestRestrictAccess() : FutureBuilder( future: APIService().getBnsMyItems( - context.read().userData['email']!), + LoginStore.userData['email']!), builder: (context, snapshot) { if (snapshot.hasData) { List models = diff --git a/lib/pages/buy_sell/buy_form.dart b/lib/pages/buy_sell/buy_form.dart index 2496908d..e1d09d20 100644 --- a/lib/pages/buy_sell/buy_form.dart +++ b/lib/pages/buy_sell/buy_form.dart @@ -155,8 +155,8 @@ class _BuySellFormState extends State { data['location'] = _price.text.trim(); data['contact'] = _contactNumber.text.trim(); data['image'] = widget.imageString; - data['name'] = context.read().userData["name"]!; - data['email'] = context.read().userData["email"]!; + data['name'] = LoginStore.userData["name"]!; + data['email'] = LoginStore.userData["email"]!; data['total_price'] = "${_price.text}-${_price2.text}"; try { diff --git a/lib/pages/home/home_tab.dart b/lib/pages/home/home_tab.dart index 7d5119d0..83c55aca 100644 --- a/lib/pages/home/home_tab.dart +++ b/lib/pages/home/home_tab.dart @@ -25,8 +25,10 @@ class _HomeTabState extends State { @override void initState() { super.initState(); - context.read().setTimetable( - context.read().userData["rollno"] ?? "190101109",context); + if (!LoginStore.isGuest) { + context.read().setTimetable( + LoginStore.userData["rollNo"]!, context); + } } @override @@ -45,10 +47,17 @@ class _HomeTabState extends State { const SizedBox( height: 10, ), - context.read().isGuest ? Container() : const Column(mainAxisSize: MainAxisSize.min,children: [const DateCourse(), - SizedBox( - height: 10, - )],), + LoginStore.isGuest + ? Container() + : const Column( + mainAxisSize: MainAxisSize.min, + children: [ + const DateCourse(), + SizedBox( + height: 10, + ) + ], + ), HomeLinks(title: 'Services', links: serviceLinks), const SizedBox( height: 10, diff --git a/lib/pages/lost_found/lnf_home.dart b/lib/pages/lost_found/lnf_home.dart index 33c2fcc4..ba7fe2d2 100644 --- a/lib/pages/lost_found/lnf_home.dart +++ b/lib/pages/lost_found/lnf_home.dart @@ -13,6 +13,7 @@ import 'package:onestop_dev/widgets/lostfound/ads_tile.dart'; import 'package:onestop_dev/widgets/lostfound/lost_found_button.dart'; import 'package:onestop_dev/widgets/lostfound/add_item_button.dart'; import 'package:onestop_dev/widgets/lostfound/lost_found_tile.dart'; +import 'package:onestop_dev/widgets/ui/guest_restrict.dart'; import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; import 'package:provider/provider.dart'; @@ -171,12 +172,10 @@ class _LostFoundHomeState extends State { ) else Expanded( - child: context.read().isGuestUser ? const PaginationText( - text: - "Not Available in guest mode") + child: context.read().isGuestUser ? const GuestRestrictAccess() : FutureBuilder( future: APIService().getLnfMyItems( - context.read().userData['email'] ?? ""), + LoginStore.userData['email'] ?? ""), builder: (context, snapshot) { if (snapshot.hasData) { List models = snapshot.data! as List; diff --git a/lib/pages/profile.dart b/lib/pages/profile.dart index bbf3d8fb..47cd4ea8 100644 --- a/lib/pages/profile.dart +++ b/lib/pages/profile.dart @@ -42,12 +42,12 @@ class _ProfilePageState extends State { width: MediaQuery.of(context).size.width, ), Text( - "${context.read().userData['name']}", + "${LoginStore.userData['name']}", textAlign: TextAlign.center, style: MyFonts.w800.setColor(kWhite).size(20), ), Text( - '${context.read().userData['rollno']}', + '${LoginStore.userData['rollNo']}', textAlign: TextAlign.center, style: MyFonts.w500.setColor(kWhite).size(20), ), @@ -69,7 +69,7 @@ class _ProfilePageState extends State { // padding: const EdgeInsets.symmetric(horizontal: 16), // child: BarcodeWidget( // barcode: Barcode.code128(), - // data: "${context.read().userData['rollno']}", + // data: "${context.read().userData['rollNo']}", // height: 150, // color: kBlack, // backgroundColor: kWhite, diff --git a/lib/pages/profile/edit_profile.dart b/lib/pages/profile/edit_profile.dart index 73377034..5df99be2 100644 --- a/lib/pages/profile/edit_profile.dart +++ b/lib/pages/profile/edit_profile.dart @@ -4,7 +4,9 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'package:intl/intl.dart'; +import 'package:onestop_dev/services/api.dart'; import 'package:provider/provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import '../../functions/utility/show_snackbar.dart'; import '../../functions/utility/validator.dart'; @@ -18,25 +20,33 @@ import '../../widgets/profile/custom_text_field.dart'; import 'profile_page.dart'; class EditProfile extends StatefulWidget { - final ProfileModel? profileModel; - const EditProfile({Key? key, this.profileModel}) : super(key: key); + final ProfileModel profileModel; + const EditProfile({Key? key,required this.profileModel}) : super(key: key); @override State createState() => _EditProfileState(); } class _EditProfileState extends State { - final TextEditingController _usernameController = TextEditingController(); - final TextEditingController _outlookController = TextEditingController(); + final TextEditingController _nameController = TextEditingController(); + final TextEditingController _outlookEmailController = TextEditingController(); final TextEditingController _rollController = TextEditingController(); - final TextEditingController _gmailController = TextEditingController(); - final TextEditingController _contactController = TextEditingController(); + final TextEditingController _altEmailController = TextEditingController(); + final TextEditingController _phoneController = TextEditingController(); final TextEditingController _emergencyController = TextEditingController(); - final TextEditingController _dateController = TextEditingController(); + final TextEditingController _roomNoController = TextEditingController(); + final TextEditingController _homeAddressController = TextEditingController(); + final TextEditingController _dobController = TextEditingController(); final TextEditingController _linkedinController = TextEditingController(); String? hostel; - DateTime? selectedDate; - String? imageString; + String? gender; + DateTime? selectedDob; + // String? imageString; + final List genders = [ + "Male", + "Female", + "Others" + ]; final List hostels = [ "Kameng", "Barak", @@ -56,26 +66,21 @@ class _EditProfileState extends State { @override void initState() { super.initState(); - if (widget.profileModel != null) { - ProfileModel p = widget.profileModel!; - _usernameController.text = p.username; - _rollController.text = p.rollNumber; - _outlookController.text = p.outlook; - _gmailController.text = p.gmail; - _contactController.text = p.contact; - _emergencyController.text = p.emergencyContact; - _dateController.text = DateFormat('dd-MMM-yyyy').format(p.date!); - _linkedinController.text = p.linkedin!; - hostel = p.hostel; - selectedDate = p.date; - imageString = p.image; - } else { - _usernameController.text = - "${context.read().userData['name']}"; - _rollController.text = "${context.read().userData['rollno']}"; - _outlookController.text = - "${context.read().userData['email']}"; - } + ProfileModel p = widget.profileModel!; + _nameController.text = p.name; + _rollController.text = p.rollNo; + _outlookEmailController.text = p.outlookEmail; + _altEmailController.text = p.altEmail ?? ""; + _phoneController.text = p.phoneNumber.toString() ?? ""; + _emergencyController.text = p.emergencyPhoneNumber.toString() ?? ""; + _roomNoController.text = p.roomNo ?? ""; + _homeAddressController.text = p.homeAddress ?? ""; + _dobController.text = DateFormat('dd-MMM-yyyy').format(DateTime.parse(p.dob ?? DateTime.now().toIso8601String())); + _linkedinController.text = p.linkedin ?? ""; + hostel = p.hostel; + gender = p.gender; + selectedDob = p.dob!=null ? DateTime.parse(p.dob!) : DateTime.now(); + // imageString = p.image; } @override @@ -86,26 +91,38 @@ class _EditProfileState extends State { return; } else { DateTime date = DateTime( - selectedDate!.year, selectedDate!.month, selectedDate!.day); + selectedDob!.year, selectedDob!.month, selectedDob!.day); var data = { - 'username': _usernameController.text, - 'rollNumber': _rollController.text, - 'outlook': _outlookController.text, - 'gmail': _gmailController.text, - 'contact': _contactController.text, - 'emergencyContact': _emergencyController.text, + 'name': _nameController.text, + 'rollNo': _rollController.text, + 'outlookEmail_email': _outlookEmailController.text, + 'altEmail': _altEmailController.text, + 'dob': date.toIso8601String(), + 'gender': gender, + 'phoneNumber': _phoneController.text, + 'emergencyPhoneNumber': _emergencyController.text, 'hostel': hostel, - 'linkedin': _linkedinController.text, - 'date': date.toIso8601String(), - 'image': imageString, + 'roomNo': _roomNoController.text, + 'homeAddress': _homeAddressController.text, + 'linkedin': _linkedinController.text }; - Navigator.of(context).pushAndRemoveUntil( - MaterialPageRoute( - builder: (context) => Profile( - profileModel: ProfileModel.fromJson(data), - )), - ((route) => false)); + print(data); + + await APIService().updateUserProfile(data); + + Map userInfo = await APIService().getUserProfile(); + SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString("userInfo", jsonEncode(userInfo)); + context.read().saveToUserInfo(prefs); + Navigator.of(context) + .pushNamedAndRemoveUntil('/', (Route route) => false); + // Navigator.of(context).pushAndRemoveUntil( + // MaterialPageRoute( + // builder: (context) => Profile( + // profileModel: ProfileModel.fromJson(data), + // )), + // ((route) => false)); } } @@ -148,107 +165,108 @@ class _EditProfileState extends State { const SizedBox( height: 24, ), - Center( - child: Stack(alignment: Alignment.bottomRight, children: [ - - ClipRRect( - borderRadius: BorderRadius.circular(75.0), - - child: Image( - image: imageString==null?const ResizeImage(AssetImage('assets/images/profile_placeholder.png'),width: 150,height: 150): ResizeImage( - MemoryImage(base64Decode(imageString!)) - ,width: 150, - height: 150,), - fit: BoxFit.fill, - ) - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: GestureDetector( - onTap: () async { - XFile? xFile; - await showDialog( - context: context, - builder: (BuildContext context) { - return AlertDialog( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(28)), - backgroundColor: kBlueGrey, - title: Text( - "Do you want to change your profile photo?",style: MyFonts.w500.size(16).setColor(kWhite2),), - content: SingleChildScrollView( - child: ListBody( - children: [ - GestureDetector( - child: Text("Take Photo",style: MyFonts.w500.size(14).setColor(kWhite),), - onTap: () async { - xFile = await ImagePicker().pickImage( - source: ImageSource.camera); - if (!mounted) return; - Navigator.of(context).pop(); - }, - ), - const Padding( - padding: EdgeInsets.all(8.0)), - GestureDetector( - child: Text("Choose Photo",style: MyFonts.w500.size(14).setColor(kWhite),), - onTap: () async { - xFile = await ImagePicker().pickImage( - source: ImageSource.gallery); - if (!mounted) return; - Navigator.of(context).pop(); - }, - ), - const Padding( - padding: EdgeInsets.all(8.0)), - - GestureDetector( - child: Text("Remove Photo",style: MyFonts.w500.size(14).setColor(kRed),), - onTap: () async { - setState(() { - imageString=null; - }); - return - Navigator.of(context).pop(); - }, - ), - ], - ), - )); - }); - - if (!mounted) return; - if (xFile != null) { - var bytes = File(xFile!.path).readAsBytesSync(); - var imageSize = (bytes.lengthInBytes / - (1048576)); // dividing by 1024*1024 - if (imageSize > 2.5) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text( - "Maximum image size can be 2.5 MB", - style: MyFonts.w500, - ))); - return; - } - setState(() { - imageString = base64Encode(bytes); - }); - return; - } - }, - child: Container( - height: 30, - width: 30, - decoration: const BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(75)), - color: kWhite), - child: const Icon(Icons.edit_outlined), - ), - ), - ), - ])), - const SizedBox( - height: 24, - ), + // For now image will not be stored + // Center( + // child: Stack(alignment: Alignment.bottomRight, children: [ + // + // ClipRRect( + // borderRadius: BorderRadius.circular(75.0), + // + // child: Image( + // image: imageString==null?const ResizeImage(AssetImage('assets/images/profile_placeholder.png'),width: 150,height: 150): ResizeImage( + // MemoryImage(base64Decode(imageString!)) + // ,width: 150, + // height: 150,), + // fit: BoxFit.fill, + // ) + // ), + // Padding( + // padding: const EdgeInsets.all(8.0), + // child: GestureDetector( + // onTap: () async { + // XFile? xFile; + // await showDialog( + // context: context, + // builder: (BuildContext context) { + // return AlertDialog( + // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(28)), + // backgroundColor: kBlueGrey, + // title: Text( + // "Do you want to change your profile photo?",style: MyFonts.w500.size(16).setColor(kWhite2),), + // content: SingleChildScrollView( + // child: ListBody( + // children: [ + // GestureDetector( + // child: Text("Take Photo",style: MyFonts.w500.size(14).setColor(kWhite),), + // onTap: () async { + // xFile = await ImagePicker().pickImage( + // source: ImageSource.camera); + // if (!mounted) return; + // Navigator.of(context).pop(); + // }, + // ), + // const Padding( + // padding: EdgeInsets.all(8.0)), + // GestureDetector( + // child: Text("Choose Photo",style: MyFonts.w500.size(14).setColor(kWhite),), + // onTap: () async { + // xFile = await ImagePicker().pickImage( + // source: ImageSource.gallery); + // if (!mounted) return; + // Navigator.of(context).pop(); + // }, + // ), + // const Padding( + // padding: EdgeInsets.all(8.0)), + // + // GestureDetector( + // child: Text("Remove Photo",style: MyFonts.w500.size(14).setColor(kRed),), + // onTap: () async { + // setState(() { + // imageString=null; + // }); + // return + // Navigator.of(context).pop(); + // }, + // ), + // ], + // ), + // )); + // }); + // + // if (!mounted) return; + // if (xFile != null) { + // var bytes = File(xFile!.path).readAsBytesSync(); + // var imageSize = (bytes.lengthInBytes / + // (1048576)); // dividing by 1024*1024 + // if (imageSize > 2.5) { + // ScaffoldMessenger.of(context).showSnackBar(SnackBar( + // content: Text( + // "Maximum image size can be 2.5 MB", + // style: MyFonts.w500, + // ))); + // return; + // } + // setState(() { + // imageString = base64Encode(bytes); + // }); + // return; + // } + // }, + // child: Container( + // height: 30, + // width: 30, + // decoration: const BoxDecoration( + // borderRadius: BorderRadius.all(Radius.circular(75)), + // color: kWhite), + // child: const Icon(Icons.edit_outlined), + // ), + // ), + // ), + // ])), + // const SizedBox( + // height: 24, + // ), Text('Basic Information', style: MyFonts.w600.size(16).setColor(kWhite)), const SizedBox( @@ -259,10 +277,10 @@ class _EditProfileState extends State { child: Column( children: [ CustomTextField( - hintText: 'Username', + hintText: 'name', // validator: validatefield, isNecessary: false, - controller: _usernameController, + controller: _nameController, isEnabled: false, ), const SizedBox( @@ -279,41 +297,68 @@ class _EditProfileState extends State { ), CustomTextField( isEnabled: false, - hintText: 'Outlook ID', + hintText: 'outlookEmail ID', // validator: validatefield, isNecessary: false, - controller: _outlookController, + controller: _outlookEmailController, ), const SizedBox( height: 12, ), CustomTextField( - hintText: 'Gmail', + hintText: 'Alt Email', validator: validatefield, isNecessary: true, - controller: _gmailController, + controller: _altEmailController, ), const SizedBox( height: 12, ), CustomTextField( - hintText: 'Contact Number', - validator: validatefield, + hintText: 'Phone Number', + validator: (String? value) { + if (value == null || value.isEmpty) { + return 'Field cannot be empty'; + } + else if(value.length!=10){ + return 'Enter valid 10 digit phone number'; + } + return null; + }, isNecessary: true, - controller: _contactController, + controller: _phoneController, + inputType: TextInputType.phone, ), const SizedBox( height: 12, ), CustomTextField( hintText: 'Emergency Contact Number', - validator: validatefield, + validator: (String? value) { + if (value == null || value.isEmpty) { + return 'Field cannot be empty'; + } + else if(value.length!=10){ + return 'Enter valid 10 digit phone number'; + } + return null; + }, isNecessary: true, controller: _emergencyController, + inputType: TextInputType.phone, ), const SizedBox( height: 12, ), + CustomDropDown( + value: gender, + items: genders, + hintText: 'Your Gender', + onChanged: (g) => gender = g, + validator: validatefield), + const SizedBox( + height: 12, + ), CustomDropDown( value: hostel, items: hostels, @@ -326,12 +371,12 @@ class _EditProfileState extends State { CustomTextField( hintText: 'Date of Birth', validator: validatefield, - controller: _dateController, + controller: _dobController, onTap: () async { FocusScope.of(context).requestFocus(FocusNode()); DateTime? pickedDate = await showDatePicker( context: context, - initialDate: selectedDate ?? DateTime.now(), + initialDate: selectedDob ?? DateTime.now(), firstDate: DateTime(2000), //DateTime.now() - not to allow to choose before today. lastDate: DateTime(2101), @@ -340,11 +385,11 @@ class _EditProfileState extends State { )); if (pickedDate != null) { if (!mounted) return; - selectedDate = pickedDate; + selectedDob = pickedDate; String formattedDate = DateFormat('dd-MMM-yyyy').format(pickedDate); setState(() { - _dateController.text = + _dobController.text = formattedDate; //set output date to TextField value. }); } @@ -354,6 +399,24 @@ class _EditProfileState extends State { const SizedBox( height: 12, ), + CustomTextField( + hintText: 'Hostel room no', + validator: validatefield, + isNecessary: true, + controller: _roomNoController + ), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'Home Address', + validator: validatefield, + isNecessary: true, + controller: _homeAddressController + ), + const SizedBox( + height: 12, + ), CustomTextField( hintText: 'LinkedIn Profile', // validator: validatefield, diff --git a/lib/pages/profile/profile_page.dart b/lib/pages/profile/profile_page.dart index 7c70148b..c6dc9ca5 100644 --- a/lib/pages/profile/profile_page.dart +++ b/lib/pages/profile/profile_page.dart @@ -13,8 +13,8 @@ import '../../widgets/profile/feedback.dart'; import 'edit_profile.dart'; class Profile extends StatefulWidget { - final ProfileModel? profileModel; - const Profile({super.key, this.profileModel}); + final ProfileModel profileModel; + const Profile({super.key, required this.profileModel}); @override State createState() => _ProfileState(); @@ -23,6 +23,7 @@ class Profile extends StatefulWidget { class _ProfileState extends State { @override Widget build(BuildContext context) { + print(widget.profileModel!.toJson()); return Scaffold( backgroundColor: kBackground, appBar: AppBar( @@ -79,29 +80,29 @@ class _ProfileState extends State { const SizedBox( height: 12, ), - Center( - child: Stack(alignment: Alignment.bottomRight, children: [ - ClipRRect( - borderRadius: BorderRadius.circular(75.0), - child: Image( - image: widget.profileModel?.image == null - ? const ResizeImage( - AssetImage( - 'assets/images/profile_placeholder.png'), - width: 150, - height: 150) - : ResizeImage( - MemoryImage( - base64Decode(widget.profileModel!.image!)), - width: 150, - height: 150, - ), - fit: BoxFit.fill, - )), - ])), - const SizedBox( - height: 24, - ), + // Center( + // child: Stack(alignment: Alignment.bottomRight, children: [ + // ClipRRect( + // borderRadius: BorderRadius.circular(75.0), + // child: Image( + // image: widget.profileModel?.image == null + // ? const ResizeImage( + // AssetImage( + // 'assets/images/profile_placeholder.png'), + // width: 150, + // height: 150) + // : ResizeImage( + // MemoryImage( + // base64Decode(widget.profileModel!.image!)), + // width: 150, + // height: 150, + // ), + // fit: BoxFit.fill, + // )), + // ])), + // const SizedBox( + // height: 24, + // ), Text('Basic Information', style: MyFonts.w600.size(16).setColor(kWhite)), const SizedBox( @@ -109,42 +110,42 @@ class _ProfileState extends State { ), DataTile( title: 'Username', - semiTitle: widget.profileModel?.username, + semiTitle: widget.profileModel.name, ), DataTile( title: 'Roll Number', - semiTitle: widget.profileModel?.rollNumber, + semiTitle: widget.profileModel.rollNo, ), DataTile( title: 'Outlook ID', - semiTitle: widget.profileModel?.outlook, + semiTitle: widget.profileModel.outlookEmail, ), DataTile( title: 'Gmail', - semiTitle: widget.profileModel?.gmail, + semiTitle: widget.profileModel.altEmail, ), DataTile( title: 'Contact Number', - semiTitle: widget.profileModel?.contact, + semiTitle: widget.profileModel.phoneNumber.toString(), ), DataTile( title: 'Emergency Contact Number', - semiTitle: widget.profileModel?.emergencyContact, + semiTitle: widget.profileModel.emergencyPhoneNumber.toString(), ), DataTile( title: 'Hostel', - semiTitle: widget.profileModel?.hostel, + semiTitle: widget.profileModel.hostel, ), - widget.profileModel == null + widget.profileModel.dob==null ? Container() : DataTile( title: 'Date of Birth', semiTitle: DateFormat('dd-MMM-yyyy') - .format(widget.profileModel!.date!), + .format(DateTime.parse(widget.profileModel.dob!)), ), DataTile( title: 'LinkedIn Profile', - semiTitle: widget.profileModel?.linkedin, + semiTitle: widget.profileModel.linkedin, ), const SizedBox( height: 24, @@ -153,7 +154,7 @@ class _ProfileState extends State { ), )), ), - floatingActionButton: GestureDetector( + floatingActionButton: LoginStore.isGuest ? Container() : GestureDetector( onTap: (() { Navigator.of(context).push(MaterialPageRoute( builder: (context) => EditProfile( diff --git a/lib/pages/quick_links/cab_share.dart b/lib/pages/quick_links/cab_share.dart index f9468248..0518b447 100644 --- a/lib/pages/quick_links/cab_share.dart +++ b/lib/pages/quick_links/cab_share.dart @@ -9,10 +9,10 @@ class CabShare extends StatelessWidget { @override Widget build(BuildContext context) { - print(context.read().userData); + print(LoginStore.userData); return CabSharingScreen(userData: { - 'name': context.read().userData["name"]!, - 'email': context.read().userData["email"]!, + 'name': LoginStore.userData["name"]!, + 'email': LoginStore.userData["email"]!, 'security-key': const String.fromEnvironment('SECURITY-KEY') }); } diff --git a/lib/pages/quick_links/gc_scoreboard.dart b/lib/pages/quick_links/gc_scoreboard.dart index 9d2785c6..04a8e371 100644 --- a/lib/pages/quick_links/gc_scoreboard.dart +++ b/lib/pages/quick_links/gc_scoreboard.dart @@ -9,6 +9,6 @@ class Scoreboard extends StatelessWidget { @override Widget build(BuildContext context) { - return GCScoreBoard(userInfo: context.read().userData); + return GCScoreBoard(userInfo: {"name": LoginStore.userData["name"],"rollno": LoginStore.userData["rollNo"],"email" : LoginStore.userData["email"]}); } } diff --git a/lib/pages/timetable/timetable.dart b/lib/pages/timetable/timetable.dart index 88ffbad3..77466cab 100644 --- a/lib/pages/timetable/timetable.dart +++ b/lib/pages/timetable/timetable.dart @@ -1,9 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:onestop_dev/pages/lost_found/lnf_home.dart'; +import 'package:onestop_dev/stores/login_store.dart'; import 'package:onestop_dev/stores/timetable_store.dart'; import 'package:onestop_dev/widgets/timetable/date_slider.dart'; import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; import 'package:provider/provider.dart'; +import 'package:onestop_dev/widgets/ui/guest_restrict.dart'; class TimeTableTab extends StatefulWidget { static const String id = 'time'; @@ -16,7 +19,7 @@ class _TimeTableTabState extends State { List>>> data1 = []; @override Widget build(BuildContext context) { - return SingleChildScrollView( + return LoginStore.isGuest ? const GuestRestrictAccess() : SingleChildScrollView( child: Column( children: [ const SizedBox( diff --git a/lib/pages/upsp/details_upsp.dart b/lib/pages/upsp/details_upsp.dart index 8020d766..5ec3eb18 100644 --- a/lib/pages/upsp/details_upsp.dart +++ b/lib/pages/upsp/details_upsp.dart @@ -41,11 +41,10 @@ class _DetailsUpspState extends State { @override Widget build(BuildContext context) { - var userStore = context.read(); - var userData = userStore.userData; + var userData = LoginStore.userData; String email = userData['email']!; String name = userData['name']!; - String roll = userData['rollno']!; + String roll = userData['rollNo']!; return Scaffold( backgroundColor: kBackground, appBar: AppBar( diff --git a/lib/pages/upsp/upsp.dart b/lib/pages/upsp/upsp.dart index f483315f..a3dc593b 100644 --- a/lib/pages/upsp/upsp.dart +++ b/lib/pages/upsp/upsp.dart @@ -49,8 +49,7 @@ class _UpspState extends State { @override Widget build(BuildContext context) { - var userStore = context.read(); - var userData = userStore.userData; + var userData = LoginStore.userData; String email = userData['email']!; return Theme( @@ -68,7 +67,7 @@ class _UpspState extends State { style: MyFonts.w600.size(16).setColor(kWhite), ), ), - body: userStore.isGuestUser + body: LoginStore.isGuest ? Center( child: Text( 'Please sign in to use this feature', diff --git a/lib/services/api.dart b/lib/services/api.dart index ad3d3704..66b5c1be 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -38,6 +38,7 @@ class APIService { }, onError: (error, handler) async { var response = error.response; if (response != null && response.statusCode == 401) { + print(response.requestOptions.path); bool couldRegenerate = await regenerateAccessToken(); // ignore: use_build_context_synchronously if (couldRegenerate) { @@ -126,6 +127,17 @@ class APIService { return response; } + Future getUserProfile() async { + var response = await dio.get(Endpoints.userProfile); + return response.data; + } + + Future updateUserProfile(Map data) async { + print(data); + var response = await dio.patch(Endpoints.userProfile,data: data); + print(response); + } + Future>> getRestaurantData() async { var response = await dio.get(Endpoints.restaurantURL); var status = response.statusCode; @@ -365,6 +377,7 @@ class APIService { await dio.get(Endpoints.lastUpdatedURL); var status = response.statusCode; var body = response.data; + print(body); if (status == 200) { Map data = body; return data; @@ -512,18 +525,21 @@ class APIService { Future> getFerryTiming() async { try { final prefs = await SharedPreferences.getInstance(); - + print("FERRY TIMINGS"); late String jsonData; if (prefs.getString('ferryTimings') != null) { jsonData = prefs.getString('ferryTimings') ?? ''; + print(jsonData); } else { final res = await dio.get(Endpoints.ferryURL); prefs.setString('ferryTimings', res.data); jsonData = prefs.getString('ferryTimings') ?? ''; - jsonData=res.data; + print(res.data); + jsonData=res.data.toString(); + print(jsonData); } List ferryTiming = json.decode(jsonData)['data']; List ferryTimings = []; @@ -546,7 +562,7 @@ class APIService { jsonData = prefs.getString('messMenu') ?? ''; } else { final res = await dio.get(Endpoints.messURL); - prefs.setString('messMenu', res.data); + prefs.setString('messMenu', res.data.toString()); jsonData = prefs.getString('messMenu') ?? res.data; } diff --git a/lib/stores/login_store.dart b/lib/stores/login_store.dart index ce331365..af999f77 100644 --- a/lib/stores/login_store.dart +++ b/lib/stores/login_store.dart @@ -1,16 +1,20 @@ // import 'package:aad_oauth/aad_oauth.dart'; // import 'package:aad_oauth/model/config.dart'; +import 'dart:convert'; + import 'package:onestop_dev/globals/database_strings.dart'; import 'package:onestop_dev/globals/endpoints.dart'; +import 'package:onestop_dev/models/profile/profile_model.dart'; +import 'package:onestop_dev/pages/profile/profile_page.dart'; import 'package:onestop_dev/services/api.dart'; import 'package:onestop_dev/services/local_storage.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:webview_cookie_manager/webview_cookie_manager.dart'; import 'package:dio/dio.dart'; class LoginStore { - Map userData = {}; + static Map userData = {}; final cookieManager = WebviewCookieManager(); - bool isGuest = false; + static bool isGuest = false; // static final Config config = Config( // tenant: '850aa78d-94e1-4bc6-9cf3-8c11b530701c', // clientId: '81f3e9f0-b0fd-48e0-9d36-e6058e5c6d4f', @@ -73,21 +77,22 @@ class LoginStore { sharedPrefs.setBool("isGuest", true); // guest sign in } - void saveToPreferences(SharedPreferences instance, dynamic data) { + Future saveToPreferences(SharedPreferences instance, dynamic data) async { print(data); + print(data.runtimeType); + print(data[BackendHelper.accesstoken]); instance.setString(BackendHelper.accesstoken, data[BackendHelper.accesstoken]); instance.setString(BackendHelper.refreshtoken, data[BackendHelper.refreshtoken]); - instance.setString("name", data["name"]); - instance.setString("email", data["email"]); instance.setBool("isGuest", false); // general case + Map userInfo = await APIService().getUserProfile(); + print(userInfo); + print(jsonEncode(userInfo)); + instance.setString("userInfo", jsonEncode(userInfo)); } void saveToUserInfo(SharedPreferences instance) { print("here"); - print(instance.getString("name")); - print(instance.getString("email")); - userData["name"] = instance.getString("name") ?? " "; - userData["email"] = instance.getString("email") ?? " "; + userData = jsonDecode(instance.getString("userInfo")!); isGuest = instance.getBool("isGuest")!; print(userData); } diff --git a/lib/widgets/login/login_webview.dart b/lib/widgets/login/login_webview.dart index 0e747f97..25d3898d 100644 --- a/lib/widgets/login/login_webview.dart +++ b/lib/widgets/login/login_webview.dart @@ -1,7 +1,11 @@ import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; +import 'package:onestop_dev/globals/database_strings.dart'; import 'package:onestop_dev/globals/endpoints.dart'; +import 'package:onestop_dev/models/profile/profile_model.dart'; +import 'package:onestop_dev/pages/profile/edit_profile.dart'; +import 'package:onestop_dev/services/api.dart'; import 'package:onestop_dev/stores/login_store.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -37,15 +41,21 @@ class _LoginWebViewState extends State { WebViewController controller = await widget._controller.future; var userTokensString = await controller.runJavascriptReturningResult("document.querySelector('#userTokens').innerText"); + print("TOKENS STRING"); + userTokensString=userTokensString.replaceAll('"', ''); print(userTokensString); if (userTokensString!="ERROR OCCURED") { SharedPreferences user = await SharedPreferences.getInstance(); if (!mounted) return; - context.read().saveToPreferences(user, jsonDecode(userTokensString)); + Map userTokens = {BackendHelper.accesstoken: userTokensString.split('/')[0],BackendHelper.refreshtoken: userTokensString.split('/')[1]}; + print(userTokens); + await context.read().saveToPreferences(user, userTokens); context.read().saveToUserInfo(user); await WebviewCookieManager().clearCookies(); - Navigator.of(context) - .pushNamedAndRemoveUntil('/', (Route route) => false); + print("its here"); + Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => EditProfile(profileModel: ProfileModel.fromJson(LoginStore.userData),)), (route) => false); + // Navigator.of(context) + // .pushNamedAndRemoveUntil('/', (Route route) => false); } } }, diff --git a/lib/widgets/lostfound/claim_call_button.dart b/lib/widgets/lostfound/claim_call_button.dart index be9e82b3..b385305f 100644 --- a/lib/widgets/lostfound/claim_call_button.dart +++ b/lib/widgets/lostfound/claim_call_button.dart @@ -48,9 +48,9 @@ class _ClaimCallButtonState extends State { } buttonPressed = true; var name = - context.read().userData['name']; + LoginStore.userData['name']; var email = - context.read().userData['email']; + LoginStore.userData['email']; var body = await APIService().claimFoundItem( name: name!, email: email!, @@ -69,9 +69,7 @@ class _ClaimCallButtonState extends State { ModalRoute.withName(LostFoundHome.id)); } else { widget.model.claimed = true; - widget.model.claimerEmail = context - .read() - .userData["email"]!; + widget.model.claimerEmail = LoginStore.userData["email"]!; Navigator.popUntil(context, ModalRoute.withName(LostFoundHome.id)); ScaffoldMessenger.of(widget.parentContext) @@ -142,7 +140,7 @@ class _ClaimCallButtonState extends State { ) : Text( widget.model.claimerEmail == - context.read().userData["email"] + LoginStore.userData["email"] ? " You claimed" : " Already Claimed", style: MyFonts.w500.size(11).setColor(lBlue2), diff --git a/lib/widgets/profile/data_tile.dart b/lib/widgets/profile/data_tile.dart index 12a61a93..67864b51 100644 --- a/lib/widgets/profile/data_tile.dart +++ b/lib/widgets/profile/data_tile.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:onestop_dev/stores/login_store.dart'; import '../../globals/my_colors.dart'; import '../../globals/my_fonts.dart'; @@ -7,37 +8,32 @@ import '../../globals/my_fonts.dart'; class DataTile extends StatelessWidget { final String title; final String? semiTitle; - const DataTile({Key? key, required this.title, this.semiTitle}) + const DataTile({Key? key, required this.title, required this.semiTitle}) : super(key: key); @override Widget build(BuildContext context) { - if (semiTitle != null && semiTitle!.isNotEmpty) { - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 12, - ), - Text( - title, - style: MyFonts.w600.size(12).setColor(kTabText), - ), - const SizedBox( - height: 10, - ), - Text( - semiTitle!, - style: MyFonts.w500.size(14).setColor(kWhite), - ), - const SizedBox( - height: 12, - ), - ], - ); - } - else {return Container(); - } + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 12, + ), + Text( + title, + style: MyFonts.w600.size(12).setColor(kTabText), + ), + const SizedBox( + height: 10, + ), + Text( + semiTitle!=null && semiTitle!.isNotEmpty ? semiTitle! : (LoginStore.isGuest ? "Not set for guest user" : "Not set by you"), + style: MyFonts.w500.size(14).setColor(kWhite), + ), + const SizedBox( + height: 12, + ) + ], + ); } } diff --git a/lib/widgets/profile/feedback.dart b/lib/widgets/profile/feedback.dart index e90dfd67..a6ee95e8 100644 --- a/lib/widgets/profile/feedback.dart +++ b/lib/widgets/profile/feedback.dart @@ -193,9 +193,7 @@ class _FeedBackState extends State { 'title': title.text, 'body': body.text, 'type': selected, - 'user': context - .read() - .userData['email'] ?? + 'user': LoginStore.userData['email'] ?? "Unknown" }; setState(() => enableSubmitButton = false); diff --git a/lib/widgets/ui/appbar.dart b/lib/widgets/ui/appbar.dart index 8335369f..bbb1ad1a 100644 --- a/lib/widgets/ui/appbar.dart +++ b/lib/widgets/ui/appbar.dart @@ -2,7 +2,10 @@ import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; +import 'package:onestop_dev/models/profile/profile_model.dart'; import 'package:onestop_dev/pages/profile/edit_profile.dart'; +import 'package:onestop_dev/pages/profile/profile_page.dart'; +import 'package:onestop_dev/stores/login_store.dart'; AppBar appBar(BuildContext context, {bool displayIcon = true}) { return AppBar( @@ -23,7 +26,9 @@ AppBar appBar(BuildContext context, {bool displayIcon = true}) { ), onPressed: () { // Navigator.pushNamed(context, ProfilePage.id); - Navigator.push(context, MaterialPageRoute(builder: (context)=>EditProfile())); + print(ProfileModel.fromJson(LoginStore.userData)); + print(LoginStore.userData); + Navigator.push(context, MaterialPageRoute(builder: (buildContext) => Profile(profileModel: ProfileModel.fromJson(LoginStore.userData),))); }, ), ) diff --git a/lib/widgets/ui/guest_restrict.dart b/lib/widgets/ui/guest_restrict.dart new file mode 100644 index 00000000..833a1d71 --- /dev/null +++ b/lib/widgets/ui/guest_restrict.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; +import 'package:onestop_dev/globals/my_colors.dart'; +import 'package:onestop_dev/globals/my_fonts.dart'; + +class GuestRestrictAccess extends StatelessWidget { + const GuestRestrictAccess({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Center( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + "Not Accessible in Guest Mode", + style: MyFonts.w400.setColor(kWhite), + ), + ), + ); + } +} \ No newline at end of file From 4e41be25a355f4c9ae6a439d7991a5347ae2c28f Mon Sep 17 00:00:00 2001 From: Kunalpal215 Date: Sun, 11 Jun 2023 16:57:36 +0530 Subject: [PATCH 48/82] added notif setup --- lib/globals/endpoints.dart | 1 + lib/main.dart | 5 ++-- lib/pages/profile/edit_profile.dart | 4 +-- lib/services/api.dart | 17 +++++++++++-- lib/stores/login_store.dart | 39 ++++++++++++++++++++++------- 5 files changed, 49 insertions(+), 17 deletions(-) diff --git a/lib/globals/endpoints.dart b/lib/globals/endpoints.dart index 1b84d643..1a91405a 100644 --- a/lib/globals/endpoints.dart +++ b/lib/globals/endpoints.dart @@ -35,6 +35,7 @@ class Endpoints { static const String uploadFileUPSP = "/upsp/file-upload"; static const String guestLogin = "/user/guest/login"; static const String userProfile = "/user"; + static const String userDeviceTokens = "/user/device-tokens"; static getHeader() { return {'Content-Type': 'application/json', 'security-key': Endpoints.apiSecurityKey}; } diff --git a/lib/main.dart b/lib/main.dart index d64c186e..1c66e525 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -27,10 +27,9 @@ void main() async { overlays: [SystemUiOverlay.bottom, SystemUiOverlay.top]); await checkLastUpdated(); await checkForNotifications(); - final fcmToken = await FirebaseMessaging.instance.getToken(); + final fcmToken = await FirebaseMessaging.instance.getToken(); // ask for notification permission print("FCM Token is $fcmToken"); - - await APIService.createUser(fcmToken ?? ''); + // await APIService.createUser(fcmToken ?? ''); FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); runApp(const MyApp()); } diff --git a/lib/pages/profile/edit_profile.dart b/lib/pages/profile/edit_profile.dart index 5df99be2..b6610b2c 100644 --- a/lib/pages/profile/edit_profile.dart +++ b/lib/pages/profile/edit_profile.dart @@ -109,12 +109,10 @@ class _EditProfileState extends State { print(data); - await APIService().updateUserProfile(data); - Map userInfo = await APIService().getUserProfile(); SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setString("userInfo", jsonEncode(userInfo)); - context.read().saveToUserInfo(prefs); + context.read().saveToUserInfo(prefs); // automatically updates token & other user info Navigator.of(context) .pushNamedAndRemoveUntil('/', (Route route) => false); // Navigator.of(context).pushAndRemoveUntil( diff --git a/lib/services/api.dart b/lib/services/api.dart index 9d4e460c..252362e9 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -132,9 +132,22 @@ class APIService { return response.data; } - Future updateUserProfile(Map data) async { + Future updateUserProfile(Map data,String? deviceToken) async { print(data); - var response = await dio.patch(Endpoints.userProfile,data: data); + Map queryParameters={}; + if(deviceToken!=null) queryParameters["deviceToken"]=deviceToken; + var response = await dio.patch(Endpoints.userProfile,data: data,queryParameters: queryParameters); + print(response); + } + + Future postUserDeviceToken(String deviceToken) async { + var response = await dio.post(Endpoints.userDeviceTokens,data: {"deviceToken" : deviceToken}); + print(response); + } + + Future updateUserDeviceToken(Map data) async { + print(data); + var response = await dio.patch(Endpoints.userDeviceTokens,data: data); print(response); } diff --git a/lib/stores/login_store.dart b/lib/stores/login_store.dart index af999f77..404430d2 100644 --- a/lib/stores/login_store.dart +++ b/lib/stores/login_store.dart @@ -11,10 +11,13 @@ import 'package:onestop_dev/services/local_storage.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:webview_cookie_manager/webview_cookie_manager.dart'; import 'package:dio/dio.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; + class LoginStore { static Map userData = {}; final cookieManager = WebviewCookieManager(); static bool isGuest = false; + static String deviceToken = ''; // static final Config config = Config( // tenant: '850aa78d-94e1-4bc6-9cf3-8c11b530701c', // clientId: '81f3e9f0-b0fd-48e0-9d36-e6058e5c6d4f', @@ -52,8 +55,10 @@ class LoginStore { Future isAlreadyAuthenticated() async { SharedPreferences user = await SharedPreferences.getInstance(); + print("inside authentication check"); if (user.containsKey(BackendHelper.refreshtoken)) { - saveToUserInfo(user); + print("here"); + await saveToUserInfo(user); return true; } return false; @@ -66,7 +71,7 @@ class LoginStore { Future signInAsGuest() async { APIService().getBuyPage(1); print("GUEST SIGN IN"); - isGuest=true; + isGuest = true; var sharedPrefs = await SharedPreferences.getInstance(); print(Endpoints.guestLogin); print(Endpoints.getHeader()); @@ -77,24 +82,41 @@ class LoginStore { sharedPrefs.setBool("isGuest", true); // guest sign in } - Future saveToPreferences(SharedPreferences instance, dynamic data) async { + Future saveToPreferences( + SharedPreferences instance, dynamic data) async { print(data); print(data.runtimeType); print(data[BackendHelper.accesstoken]); - instance.setString(BackendHelper.accesstoken, data[BackendHelper.accesstoken]); - instance.setString(BackendHelper.refreshtoken, data[BackendHelper.refreshtoken]); + instance.setString( + BackendHelper.accesstoken, data[BackendHelper.accesstoken]); + instance.setString( + BackendHelper.refreshtoken, data[BackendHelper.refreshtoken]); instance.setBool("isGuest", false); // general case Map userInfo = await APIService().getUserProfile(); print(userInfo); print(jsonEncode(userInfo)); - instance.setString("userInfo", jsonEncode(userInfo)); + instance.setString("userInfo", jsonEncode(userInfo)); // save user profile } - void saveToUserInfo(SharedPreferences instance) { + Future saveToUserInfo(SharedPreferences instance) async { // only called after saving jwt tokens in local storage print("here"); userData = jsonDecode(instance.getString("userInfo")!); isGuest = instance.getBool("isGuest")!; print(userData); + var fcmToken = await FirebaseMessaging.instance.getToken(); + print("fcm token: ${fcmToken}"); + if (instance.getString("deviceToken") != null) { // already some token was stored + print("inside if"); + await APIService().updateUserDeviceToken({ + "oldToken": instance.getString("deviceToken"), // stored token + "newToken": fcmToken + }); + } + else{ + print("inside else"); + await APIService().postUserDeviceToken(fcmToken!); + } + instance.setString("deviceToken", fcmToken!); } void logOut(Function navigationPopCallBack) async { @@ -102,9 +124,8 @@ class LoginStore { SharedPreferences user = await SharedPreferences.getInstance(); user.clear(); userData.clear(); - isGuest=false; + isGuest = false; await LocalStorage.instance.deleteRecordsLogOut(); navigationPopCallBack(); } - } From 30ed5ce15ac27dbabae145f8fea226124c5b0dd4 Mon Sep 17 00:00:00 2001 From: Kunalpal215 Date: Sun, 11 Jun 2023 19:15:16 +0530 Subject: [PATCH 49/82] completed notif setup --- lib/globals/endpoints.dart | 1 + lib/main.dart | 2 +- lib/pages/buy_sell/buy_form.dart | 2 +- lib/pages/quick_links/cab_share.dart | 2 +- lib/pages/quick_links/gc_scoreboard.dart | 2 +- lib/services/api.dart | 6 ++++++ lib/stores/login_store.dart | 5 +++-- lib/widgets/lostfound/claim_call_button.dart | 4 ++-- 8 files changed, 16 insertions(+), 8 deletions(-) diff --git a/lib/globals/endpoints.dart b/lib/globals/endpoints.dart index 1a91405a..7044ab98 100644 --- a/lib/globals/endpoints.dart +++ b/lib/globals/endpoints.dart @@ -36,6 +36,7 @@ class Endpoints { static const String guestLogin = "/user/guest/login"; static const String userProfile = "/user"; static const String userDeviceTokens = "/user/device-tokens"; + static const String userLogout = "/user/logout"; static getHeader() { return {'Content-Type': 'application/json', 'security-key': Endpoints.apiSecurityKey}; } diff --git a/lib/main.dart b/lib/main.dart index 1c66e525..f3864fef 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -66,7 +66,7 @@ class MyApp extends StatelessWidget { scaffoldBackgroundColor: kBackground, splashColor: Colors.transparent), title: 'OneStop 2.0', - routes: routes, + routes: routes ), ); } diff --git a/lib/pages/buy_sell/buy_form.dart b/lib/pages/buy_sell/buy_form.dart index e1d09d20..278d717c 100644 --- a/lib/pages/buy_sell/buy_form.dart +++ b/lib/pages/buy_sell/buy_form.dart @@ -156,7 +156,7 @@ class _BuySellFormState extends State { data['contact'] = _contactNumber.text.trim(); data['image'] = widget.imageString; data['name'] = LoginStore.userData["name"]!; - data['email'] = LoginStore.userData["email"]!; + data['email'] = LoginStore.userData["outlookEmail"]!; data['total_price'] = "${_price.text}-${_price2.text}"; try { diff --git a/lib/pages/quick_links/cab_share.dart b/lib/pages/quick_links/cab_share.dart index 0518b447..a3cd6fe7 100644 --- a/lib/pages/quick_links/cab_share.dart +++ b/lib/pages/quick_links/cab_share.dart @@ -12,7 +12,7 @@ class CabShare extends StatelessWidget { print(LoginStore.userData); return CabSharingScreen(userData: { 'name': LoginStore.userData["name"]!, - 'email': LoginStore.userData["email"]!, + 'email': LoginStore.userData["outlookEmail"]!, 'security-key': const String.fromEnvironment('SECURITY-KEY') }); } diff --git a/lib/pages/quick_links/gc_scoreboard.dart b/lib/pages/quick_links/gc_scoreboard.dart index 04a8e371..27e7aa9c 100644 --- a/lib/pages/quick_links/gc_scoreboard.dart +++ b/lib/pages/quick_links/gc_scoreboard.dart @@ -9,6 +9,6 @@ class Scoreboard extends StatelessWidget { @override Widget build(BuildContext context) { - return GCScoreBoard(userInfo: {"name": LoginStore.userData["name"],"rollno": LoginStore.userData["rollNo"],"email" : LoginStore.userData["email"]}); + return GCScoreBoard(userInfo: {"name": LoginStore.userData["name"],"rollno": LoginStore.userData["rollNo"],"email" : LoginStore.userData["outlookEmail"]}); } } diff --git a/lib/services/api.dart b/lib/services/api.dart index 252362e9..b38f0ad1 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -151,6 +151,12 @@ class APIService { print(response); } + Future logoutUser(String deviceToken) async { + print(deviceToken); + var response = await dio.delete(Endpoints.userLogout,data: {"deviceToken" : deviceToken}); + print(response); + } + Future>> getRestaurantData() async { var response = await dio.get(Endpoints.restaurantURL); var status = response.statusCode; diff --git a/lib/stores/login_store.dart b/lib/stores/login_store.dart index 404430d2..f362fa35 100644 --- a/lib/stores/login_store.dart +++ b/lib/stores/login_store.dart @@ -17,7 +17,6 @@ class LoginStore { static Map userData = {}; final cookieManager = WebviewCookieManager(); static bool isGuest = false; - static String deviceToken = ''; // static final Config config = Config( // tenant: '850aa78d-94e1-4bc6-9cf3-8c11b530701c', // clientId: '81f3e9f0-b0fd-48e0-9d36-e6058e5c6d4f', @@ -116,12 +115,14 @@ class LoginStore { print("inside else"); await APIService().postUserDeviceToken(fcmToken!); } - instance.setString("deviceToken", fcmToken!); + instance.setString("deviceToken", fcmToken!); // set the returned fcToken } void logOut(Function navigationPopCallBack) async { await cookieManager.clearCookies(); SharedPreferences user = await SharedPreferences.getInstance(); + print(user.getString("deviceToken")!); + if(!isGuest) await APIService().logoutUser(user.getString("deviceToken")!); // remove token on logout if not guest user.clear(); userData.clear(); isGuest = false; diff --git a/lib/widgets/lostfound/claim_call_button.dart b/lib/widgets/lostfound/claim_call_button.dart index b385305f..762174ac 100644 --- a/lib/widgets/lostfound/claim_call_button.dart +++ b/lib/widgets/lostfound/claim_call_button.dart @@ -69,7 +69,7 @@ class _ClaimCallButtonState extends State { ModalRoute.withName(LostFoundHome.id)); } else { widget.model.claimed = true; - widget.model.claimerEmail = LoginStore.userData["email"]!; + widget.model.claimerEmail = LoginStore.userData["outlookEmail"]!; Navigator.popUntil(context, ModalRoute.withName(LostFoundHome.id)); ScaffoldMessenger.of(widget.parentContext) @@ -140,7 +140,7 @@ class _ClaimCallButtonState extends State { ) : Text( widget.model.claimerEmail == - LoginStore.userData["email"] + LoginStore.userData["outlookEmail"] ? " You claimed" : " Already Claimed", style: MyFonts.w500.size(11).setColor(lBlue2), From 9a35603c2a433ec02b9b6be4c29670e56b7647e3 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Mon, 12 Jun 2023 15:12:26 +0530 Subject: [PATCH 50/82] profile model and edit profile --- lib/models/profile/profile_model.dart | 4 ++-- lib/models/profile/profile_model.g.dart | 4 ++-- lib/models/travel/day_type_model.g.dart | 22 +++++++++++----------- lib/pages/profile/edit_profile.dart | 6 +++--- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/models/profile/profile_model.dart b/lib/models/profile/profile_model.dart index 47bcbc4f..75ea2c7e 100644 --- a/lib/models/profile/profile_model.dart +++ b/lib/models/profile/profile_model.dart @@ -7,8 +7,8 @@ class ProfileModel { final String rollNo; final String outlookEmail; final String? altEmail; - final int? phoneNumber; - final int? emergencyPhoneNumber; + final String? phoneNumber; + final String? emergencyPhoneNumber; final String? gender; final String? roomNo; final String? homeAddress; diff --git a/lib/models/profile/profile_model.g.dart b/lib/models/profile/profile_model.g.dart index acd57101..e5f6e292 100644 --- a/lib/models/profile/profile_model.g.dart +++ b/lib/models/profile/profile_model.g.dart @@ -11,8 +11,8 @@ ProfileModel _$ProfileModelFromJson(Map json) => ProfileModel( rollNo: json['rollNo'] as String, outlookEmail: json['outlookEmail'] as String, altEmail: json['altEmail'] as String?, - phoneNumber: json['phoneNumber'] as int?, - emergencyPhoneNumber: json['emergencyPhoneNumber'] as int?, + phoneNumber: json['phoneNumber'] as String?, + emergencyPhoneNumber: json['emergencyPhoneNumber'] as String?, gender: json['gender'] as String?, roomNo: json['roomNo'] as String?, homeAddress: json['homeAddress'] as String?, diff --git a/lib/models/travel/day_type_model.g.dart b/lib/models/travel/day_type_model.g.dart index 81cd0773..35e7fc69 100644 --- a/lib/models/travel/day_type_model.g.dart +++ b/lib/models/travel/day_type_model.g.dart @@ -7,16 +7,16 @@ part of 'day_type_model.dart'; // ************************************************************************** DayType _$DayTypeFromJson(Map json) => DayType( - fromCampus: (json['fromCampus'] as List) - .map((e) => DateTime.parse(e as String)) - .toList(), - toCampus: (json['toCampus'] as List) - .map((e) => DateTime.parse(e as String)) - .toList(), -); + fromCampus: (json['fromCampus'] as List) + .map((e) => DateTime.parse(e as String)) + .toList(), + toCampus: (json['toCampus'] as List) + .map((e) => DateTime.parse(e as String)) + .toList(), + ); Map _$DayTypeToJson(DayType instance) => { - 'fromCampus': - instance.fromCampus.map((e) => e.toIso8601String()).toList(), - 'toCampus': instance.toCampus.map((e) => e.toIso8601String()).toList(), -}; \ No newline at end of file + 'fromCampus': + instance.fromCampus.map((e) => e.toIso8601String()).toList(), + 'toCampus': instance.toCampus.map((e) => e.toIso8601String()).toList(), + }; diff --git a/lib/pages/profile/edit_profile.dart b/lib/pages/profile/edit_profile.dart index b6610b2c..9cceaa0b 100644 --- a/lib/pages/profile/edit_profile.dart +++ b/lib/pages/profile/edit_profile.dart @@ -71,8 +71,8 @@ class _EditProfileState extends State { _rollController.text = p.rollNo; _outlookEmailController.text = p.outlookEmail; _altEmailController.text = p.altEmail ?? ""; - _phoneController.text = p.phoneNumber.toString() ?? ""; - _emergencyController.text = p.emergencyPhoneNumber.toString() ?? ""; + _phoneController.text =p.phoneNumber==null?"": p.phoneNumber.toString(); + _emergencyController.text = p.emergencyPhoneNumber==null?"": p.emergencyPhoneNumber.toString(); _roomNoController.text = p.roomNo ?? ""; _homeAddressController.text = p.homeAddress ?? ""; _dobController.text = DateFormat('dd-MMM-yyyy').format(DateTime.parse(p.dob ?? DateTime.now().toIso8601String())); @@ -95,7 +95,7 @@ class _EditProfileState extends State { var data = { 'name': _nameController.text, 'rollNo': _rollController.text, - 'outlookEmail_email': _outlookEmailController.text, + 'outlookEmail': _outlookEmailController.text, 'altEmail': _altEmailController.text, 'dob': date.toIso8601String(), 'gender': gender, From 388302501921f4d731f8bdbc2e66785464c9fb55 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Mon, 12 Jun 2023 15:43:38 +0530 Subject: [PATCH 51/82] minor fix --- lib/models/profile/profile_model.dart | 4 ++-- lib/models/profile/profile_model.g.dart | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/models/profile/profile_model.dart b/lib/models/profile/profile_model.dart index 75ea2c7e..47bcbc4f 100644 --- a/lib/models/profile/profile_model.dart +++ b/lib/models/profile/profile_model.dart @@ -7,8 +7,8 @@ class ProfileModel { final String rollNo; final String outlookEmail; final String? altEmail; - final String? phoneNumber; - final String? emergencyPhoneNumber; + final int? phoneNumber; + final int? emergencyPhoneNumber; final String? gender; final String? roomNo; final String? homeAddress; diff --git a/lib/models/profile/profile_model.g.dart b/lib/models/profile/profile_model.g.dart index e5f6e292..acd57101 100644 --- a/lib/models/profile/profile_model.g.dart +++ b/lib/models/profile/profile_model.g.dart @@ -11,8 +11,8 @@ ProfileModel _$ProfileModelFromJson(Map json) => ProfileModel( rollNo: json['rollNo'] as String, outlookEmail: json['outlookEmail'] as String, altEmail: json['altEmail'] as String?, - phoneNumber: json['phoneNumber'] as String?, - emergencyPhoneNumber: json['emergencyPhoneNumber'] as String?, + phoneNumber: json['phoneNumber'] as int?, + emergencyPhoneNumber: json['emergencyPhoneNumber'] as int?, gender: json['gender'] as String?, roomNo: json['roomNo'] as String?, homeAddress: json['homeAddress'] as String?, From e923a89235f4479586b048cc2747cb88e95bd93a Mon Sep 17 00:00:00 2001 From: Kunalpal215 Date: Mon, 12 Jun 2023 21:27:48 +0530 Subject: [PATCH 52/82] fixed dio issue in travel --- lib/main.dart | 2 +- lib/models/travel/travel_timing_model.dart | 1 + lib/services/api.dart | 75 +++++++++++++--------- lib/services/data_provider.dart | 3 + lib/stores/login_store.dart | 4 +- lib/stores/travel_store.dart | 2 +- lib/widgets/login/login_webview.dart | 2 +- lib/widgets/travel/next_time_card.dart | 10 ++- 8 files changed, 63 insertions(+), 36 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index f3864fef..c559ca29 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -42,8 +42,8 @@ class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { + print("IN MY APP"); debugInvertOversizedImages = true; - return MultiProvider( providers: [ Provider( diff --git a/lib/models/travel/travel_timing_model.dart b/lib/models/travel/travel_timing_model.dart index 17e29263..aed06f7d 100644 --- a/lib/models/travel/travel_timing_model.dart +++ b/lib/models/travel/travel_timing_model.dart @@ -6,6 +6,7 @@ part 'travel_timing_model.g.dart'; @JsonSerializable() class TravelTiming { + @JsonKey(name: '_id') final String id; @JsonKey(defaultValue: '') final String type; diff --git a/lib/services/api.dart b/lib/services/api.dart index b38f0ad1..43c1bd92 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -6,11 +6,13 @@ import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:http/http.dart' as http; import 'package:onestop_dev/globals/database_strings.dart'; import 'package:onestop_dev/globals/endpoints.dart'; +import 'package:onestop_dev/main.dart'; import 'package:onestop_dev/models/buy_sell/buy_model.dart'; import 'package:onestop_dev/models/lostfound/found_model.dart'; import 'package:onestop_dev/models/lostfound/lost_model.dart'; import 'package:onestop_dev/models/timetable/registered_courses.dart'; import 'package:onestop_dev/models/buy_sell/sell_model.dart'; +import 'package:onestop_dev/pages/login/login.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../functions/utility/show_snackbar.dart'; @@ -38,14 +40,19 @@ class APIService { }, onError: (error, handler) async { var response = error.response; if (response != null && response.statusCode == 401) { - print(response.requestOptions.path); - bool couldRegenerate = await regenerateAccessToken(); - // ignore: use_build_context_synchronously - if (couldRegenerate) { - // retry - return handler.resolve(await retryRequest(response)); - } else { - showSnackBar("Your session has expired!! Login again."); + if((await AuthUserHelpers.getAccessToken()).isEmpty){ + showSnackBar("Login to continue!!"); + } + else{ + print(response.requestOptions.path); + bool couldRegenerate = await regenerateAccessToken(); + // ignore: use_build_context_synchronously + if (couldRegenerate) { + // retry + return handler.resolve(await retryRequest(response)); + } else { + showSnackBar("Your session has expired!! Login again."); + } } } else if(response != null && response.statusCode == 403){ @@ -421,9 +428,11 @@ class APIService { } Future>>> getBusData() async { + print("INSIDE BUS DATA"); var response = await dio.get(Endpoints.busURL); var status = response.statusCode; var json = response.data; + print(json); if (status == 200) { Map>> answer = {}; for (String stop in json.keys) { @@ -564,27 +573,26 @@ class APIService { try { final prefs = await SharedPreferences.getInstance(); print("FERRY TIMINGS"); - late String jsonData; - + Map jsonData; if (prefs.getString('ferryTimings') != null) { - jsonData = prefs.getString('ferryTimings') ?? ''; - print(jsonData); + print("FOUND CACHED TIMINGS"); + jsonData = jsonDecode(prefs.getString('ferryTimings')!); + print(jsonData.toString()); + print("AFTER HERE"); } else { - - final res = await dio.get(Endpoints.ferryURL); - - prefs.setString('ferryTimings', res.data); - jsonData = prefs.getString('ferryTimings') ?? ''; - print(res.data); - jsonData=res.data.toString(); - print(jsonData); + print("NOT FOUND CACHED TIMINGS"); + Response res = await dio.get(Endpoints.ferryURL); + prefs.setString('ferryTimings', jsonEncode(res.data)); + jsonData = res.data; } - List ferryTiming = json.decode(jsonData)['data']; List ferryTimings = []; - - for (var element in ferryTiming) { + List ferryData = jsonData['data']; + print(ferryData); + for (var element in ferryData) { ferryTimings.add(TravelTiming.fromJson(element)); + print(TravelTiming.fromJson(element).toJson()); } + print(ferryTimings.length); return ferryTimings; } catch (e) { @@ -635,21 +643,30 @@ class APIService { try { final prefs = await SharedPreferences.getInstance(); - late String jsonData; + Map jsonData; if (prefs.getString('busTimings') != null) { - jsonData = prefs.getString('busTimings') ?? ''; + print("FOUND BUS CACHED TIMINGS"); + print(prefs.getString('busTimings')!); + jsonData = jsonDecode(prefs.getString('busTimings')!); } else { + print("NOT BUS FOUND CACHED TIMINGS"); final res = await dio.get(Endpoints.busStops); - prefs.setString('busTimings', res.data); + print("BEFORE SET IN PREF"); + prefs.setString('busTimings', jsonEncode(res.data)); + print("SET IN PREF"); jsonData=res.data; - jsonData = prefs.getString('busTimings') ?? ''; } - List busTiming = json.decode(jsonData)['data']; + print("JSON DATA FOUND"); + List busData = jsonData['data']; + print(busData); List busTimings = []; - for (var element in busTiming) { + print("here before length"); + for (var element in busData) { busTimings.add(TravelTiming.fromJson(element)); } + print("here at length"); + print(busTimings.length); return busTimings; } catch (e) { print("____________________________________________"); diff --git a/lib/services/data_provider.dart b/lib/services/data_provider.dart index ba57c9d3..60c69e7e 100644 --- a/lib/services/data_provider.dart +++ b/lib/services/data_provider.dart @@ -22,10 +22,13 @@ class DataProvider { static Future>>> getBusTimings() async { var cachedData = await LocalStorage.instance.getBusRecord(DatabaseRecords.busTimings); if (cachedData == null) { + print("NO BUS CACHED DATA"); Map>> busTime = await APIService().getBusData(); + print(busTime); await LocalStorage.instance.storeBusData(busTime, DatabaseRecords.busTimings); return busTime; } + print("BUS CACHED DATA"); Map>> timings = {}; for (String key in cachedData.keys) { timings[key] = (cachedData[key] as List) diff --git a/lib/stores/login_store.dart b/lib/stores/login_store.dart index f362fa35..8b215bfb 100644 --- a/lib/stores/login_store.dart +++ b/lib/stores/login_store.dart @@ -104,7 +104,7 @@ class LoginStore { print(userData); var fcmToken = await FirebaseMessaging.instance.getToken(); print("fcm token: ${fcmToken}"); - if (instance.getString("deviceToken") != null) { // already some token was stored + if (instance.getString("deviceToken") != null && instance.getString("deviceToken")!=fcmToken) { // already some token was stored print("inside if"); await APIService().updateUserDeviceToken({ "oldToken": instance.getString("deviceToken"), // stored token @@ -113,9 +113,9 @@ class LoginStore { } else{ print("inside else"); + instance.setString("deviceToken", fcmToken!); // set the returned fcToken await APIService().postUserDeviceToken(fcmToken!); } - instance.setString("deviceToken", fcmToken!); // set the returned fcToken } void logOut(Function navigationPopCallBack) async { diff --git a/lib/stores/travel_store.dart b/lib/stores/travel_store.dart index 474a83e0..37426c98 100644 --- a/lib/stores/travel_store.dart +++ b/lib/stores/travel_store.dart @@ -101,4 +101,4 @@ abstract class _TravelStore with Store { void setFerryGhat(String s) { selectedFerryGhat = s; } -} +} \ No newline at end of file diff --git a/lib/widgets/login/login_webview.dart b/lib/widgets/login/login_webview.dart index 25d3898d..7fa7f25e 100644 --- a/lib/widgets/login/login_webview.dart +++ b/lib/widgets/login/login_webview.dart @@ -50,7 +50,7 @@ class _LoginWebViewState extends State { Map userTokens = {BackendHelper.accesstoken: userTokensString.split('/')[0],BackendHelper.refreshtoken: userTokensString.split('/')[1]}; print(userTokens); await context.read().saveToPreferences(user, userTokens); - context.read().saveToUserInfo(user); + await context.read().saveToUserInfo(user); await WebviewCookieManager().clearCookies(); print("its here"); Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => EditProfile(profileModel: ProfileModel.fromJson(LoginStore.userData),)), (route) => false); diff --git a/lib/widgets/travel/next_time_card.dart b/lib/widgets/travel/next_time_card.dart index 22fd4a3f..162a7bd0 100644 --- a/lib/widgets/travel/next_time_card.dart +++ b/lib/widgets/travel/next_time_card.dart @@ -25,13 +25,19 @@ class _NextTimeCardState extends State { Widget build(BuildContext context) { var mapStore = context.read(); Future getNextTime() async { + print("INSIDE NEXT TIME CARD"); String today = getFormattedDay(); + print(mapStore.indexBusesorFerry); if (mapStore.indexBusesorFerry == 0) { - var allBusTimes = await APIService().getBusTiming(); + print("hererereferf"); + List allBusTimes = await APIService().getBusTiming(); + //print(allBusTimes.toString()); + print("AFTER ALL BUS TIMES"); List weekdaysTimes= []; List weekendTimes=[]; for(var xyz in allBusTimes){ int n=xyz.weekdays.fromCampus.length; + print("n is : ${n}"); for(int i=0;i { List weekendTimes=[]; TravelTiming requiredModel = ferryTimings.firstWhere((element) => element.stop == mapStore.allLocationData[mapStore.selectedCarouselIndex]['name']); - + print(requiredModel.toJson()); int n=requiredModel.weekdays.fromCampus.length; for(int i=0;i Date: Mon, 12 Jun 2023 23:46:03 +0530 Subject: [PATCH 53/82] mess menu, text field counter --- lib/pages/profile/edit_profile.dart | 37 ++++++++++++++++++++-- lib/services/api.dart | 10 +++--- lib/widgets/profile/custom_text_field.dart | 17 +++++++++- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/lib/pages/profile/edit_profile.dart b/lib/pages/profile/edit_profile.dart index 9cceaa0b..94e492c3 100644 --- a/lib/pages/profile/edit_profile.dart +++ b/lib/pages/profile/edit_profile.dart @@ -85,6 +85,14 @@ class _EditProfileState extends State { @override Widget build(BuildContext context) { + Widget? counterBuilder(context, + {required currentLength, required isFocused, required maxLength}) { + if (currentLength == 0) { + return null; + } + return Text("$currentLength/$maxLength", + style: MyFonts.w500.size(12).setColor(kWhite)); + } Future onFormSubmit() async { if (!_formKey.currentState!.validate()) { showSnackBar('Please give all the inputs correctly'); @@ -289,6 +297,9 @@ class _EditProfileState extends State { // validator: validatefield, isNecessary: false, controller: _rollController, + maxLength: 9, + maxLines: 1, + counter: true, ), const SizedBox( height: 12, @@ -308,6 +319,9 @@ class _EditProfileState extends State { validator: validatefield, isNecessary: true, controller: _altEmailController, + maxLength: 50, + maxLines: 1, + counter: true, ), const SizedBox( height: 12, @@ -326,6 +340,9 @@ class _EditProfileState extends State { isNecessary: true, controller: _phoneController, inputType: TextInputType.phone, + maxLength: 10, + maxLines: 1, + counter: true, ), const SizedBox( height: 12, @@ -344,6 +361,9 @@ class _EditProfileState extends State { isNecessary: true, controller: _emergencyController, inputType: TextInputType.phone, + maxLength: 10, + maxLines: 1, + counter: true, ), const SizedBox( height: 12, @@ -362,7 +382,9 @@ class _EditProfileState extends State { items: hostels, hintText: 'Hostel', onChanged: (h) => hostel = h, - validator: validatefield), + validator: validatefield, + ), + const SizedBox( height: 12, ), @@ -401,7 +423,10 @@ class _EditProfileState extends State { hintText: 'Hostel room no', validator: validatefield, isNecessary: true, - controller: _roomNoController + controller: _roomNoController, + maxLength: 5, + maxLines: 1, + counter: true, ), const SizedBox( height: 12, @@ -410,7 +435,10 @@ class _EditProfileState extends State { hintText: 'Home Address', validator: validatefield, isNecessary: true, - controller: _homeAddressController + controller: _homeAddressController, + maxLength: 400, + // maxLines: 1, + counter: true, ), const SizedBox( height: 12, @@ -420,6 +448,9 @@ class _EditProfileState extends State { // validator: validatefield, isNecessary: false, controller: _linkedinController, + maxLength: 50, + maxLines: 1, + counter: true, ), const SizedBox( height: 24, diff --git a/lib/services/api.dart b/lib/services/api.dart index 43c1bd92..f601dd07 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -603,16 +603,16 @@ class APIService { Future getMealData(String hostel, String day, String mealType,) async { try{ final prefs = await SharedPreferences.getInstance(); - late String jsonData; + Map jsonData; if (prefs.getString('messMenu') != null) { - jsonData = prefs.getString('messMenu') ?? ''; + jsonData = jsonDecode(prefs.getString('messMenu')!); } else { final res = await dio.get(Endpoints.messURL); - prefs.setString('messMenu', res.data.toString()); + prefs.setString('messMenu', jsonEncode(res.data)); - jsonData = prefs.getString('messMenu') ?? res.data; + jsonData = res.data; } - List answer = json.decode(jsonData)['details']; + List answer = jsonData['details']; var meal = answer.firstWhere( (m) => m['hostel'].toString().trim().toLowerCase() == hostel.toString().toLowerCase(), diff --git a/lib/widgets/profile/custom_text_field.dart b/lib/widgets/profile/custom_text_field.dart index 8000cd36..cb3f718c 100644 --- a/lib/widgets/profile/custom_text_field.dart +++ b/lib/widgets/profile/custom_text_field.dart @@ -15,6 +15,10 @@ class CustomTextField extends StatefulWidget { final void Function()? onTap; final FocusNode? focusNode; final bool? isEnabled; + final int? maxLength; + final int? maxLines; + final bool? counter; + const CustomTextField( {super.key, @@ -27,7 +31,7 @@ class CustomTextField extends StatefulWidget { this.controller, this.onTap, this.isEnabled, - this.focusNode}); + this.focusNode, this.maxLength, this.maxLines, this.counter, }); @override State createState() => _CustomTextFieldState(); @@ -36,6 +40,14 @@ class CustomTextField extends StatefulWidget { class _CustomTextFieldState extends State { @override Widget build(BuildContext context) { + Widget? counterBuilder(context, + {required currentLength, required isFocused, required maxLength}) { + if (currentLength == 0) { + return null; + } + return Text("$currentLength/$maxLength", + style: MyFonts.w500.size(12).setColor(kWhite)); + } return TextFormField( enabled: widget.isEnabled ?? true, readOnly: widget.onTap != null, @@ -46,8 +58,11 @@ class _CustomTextFieldState extends State { cursorColor: lBlue2, onTap: widget.onTap, onChanged: widget.onChanged, + buildCounter:widget.counter==true?counterBuilder:null, initialValue: widget.value == 'null' ? '' : widget.value, keyboardType: widget.inputType, + maxLength: widget.maxLength, + maxLines: widget.maxLines, decoration: InputDecoration( errorStyle: MyFonts.w500, label: RichText( From 8c1c52179dcd6e5079d8a48ee35d3ac0a99f7ff4 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Tue, 13 Jun 2023 00:06:01 +0530 Subject: [PATCH 54/82] update user info --- lib/pages/profile/edit_profile.dart | 690 ++++++++++++++-------------- 1 file changed, 349 insertions(+), 341 deletions(-) diff --git a/lib/pages/profile/edit_profile.dart b/lib/pages/profile/edit_profile.dart index 94e492c3..c9d0701e 100644 --- a/lib/pages/profile/edit_profile.dart +++ b/lib/pages/profile/edit_profile.dart @@ -117,12 +117,15 @@ class _EditProfileState extends State { print(data); + await APIService().updateUserProfile(data,null); + Map userInfo = await APIService().getUserProfile(); SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setString("userInfo", jsonEncode(userInfo)); context.read().saveToUserInfo(prefs); // automatically updates token & other user info Navigator.of(context) .pushNamedAndRemoveUntil('/', (Route route) => false); + // Navigator.of(context).pushAndRemoveUntil( // MaterialPageRoute( // builder: (context) => Profile( @@ -132,352 +135,357 @@ class _EditProfileState extends State { } } - return Scaffold( - backgroundColor: kBackground, - appBar: AppBar( - backgroundColor: kAppBarGrey, - iconTheme: const IconThemeData(color: kAppBarGrey), - automaticallyImplyLeading: false, - centerTitle: false, - title: Text( - "Profile Setup", - textAlign: TextAlign.left, - style: MyFonts.w500.size(23).setColor(kWhite), + return GestureDetector( + onTap: () { + FocusScope.of(context).requestFocus(new FocusNode()); + }, + child: Scaffold( + backgroundColor: kBackground, + appBar: AppBar( + backgroundColor: kAppBarGrey, + iconTheme: const IconThemeData(color: kAppBarGrey), + automaticallyImplyLeading: false, + centerTitle: false, + title: Text( + "Profile Setup", + textAlign: TextAlign.left, + style: MyFonts.w500.size(23).setColor(kWhite), + ), ), - ), - body: SafeArea( - child: SingleChildScrollView( - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - width: double.infinity, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - RichText( - text: TextSpan( - children: [ - TextSpan( - text: 'Fields marked with', - style: MyFonts.w500.setColor(kWhite3).size(12)), - TextSpan( - text: ' * ', - style: MyFonts.w500.setColor(kRed).size(12)), - TextSpan( - text: 'are compulsory', - style: MyFonts.w500.setColor(kWhite3).size(12)), - ], - ), - ), - const SizedBox( - height: 24, - ), - // For now image will not be stored - // Center( - // child: Stack(alignment: Alignment.bottomRight, children: [ - // - // ClipRRect( - // borderRadius: BorderRadius.circular(75.0), - // - // child: Image( - // image: imageString==null?const ResizeImage(AssetImage('assets/images/profile_placeholder.png'),width: 150,height: 150): ResizeImage( - // MemoryImage(base64Decode(imageString!)) - // ,width: 150, - // height: 150,), - // fit: BoxFit.fill, - // ) - // ), - // Padding( - // padding: const EdgeInsets.all(8.0), - // child: GestureDetector( - // onTap: () async { - // XFile? xFile; - // await showDialog( - // context: context, - // builder: (BuildContext context) { - // return AlertDialog( - // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(28)), - // backgroundColor: kBlueGrey, - // title: Text( - // "Do you want to change your profile photo?",style: MyFonts.w500.size(16).setColor(kWhite2),), - // content: SingleChildScrollView( - // child: ListBody( - // children: [ - // GestureDetector( - // child: Text("Take Photo",style: MyFonts.w500.size(14).setColor(kWhite),), - // onTap: () async { - // xFile = await ImagePicker().pickImage( - // source: ImageSource.camera); - // if (!mounted) return; - // Navigator.of(context).pop(); - // }, - // ), - // const Padding( - // padding: EdgeInsets.all(8.0)), - // GestureDetector( - // child: Text("Choose Photo",style: MyFonts.w500.size(14).setColor(kWhite),), - // onTap: () async { - // xFile = await ImagePicker().pickImage( - // source: ImageSource.gallery); - // if (!mounted) return; - // Navigator.of(context).pop(); - // }, - // ), - // const Padding( - // padding: EdgeInsets.all(8.0)), - // - // GestureDetector( - // child: Text("Remove Photo",style: MyFonts.w500.size(14).setColor(kRed),), - // onTap: () async { - // setState(() { - // imageString=null; - // }); - // return - // Navigator.of(context).pop(); - // }, - // ), - // ], - // ), - // )); - // }); - // - // if (!mounted) return; - // if (xFile != null) { - // var bytes = File(xFile!.path).readAsBytesSync(); - // var imageSize = (bytes.lengthInBytes / - // (1048576)); // dividing by 1024*1024 - // if (imageSize > 2.5) { - // ScaffoldMessenger.of(context).showSnackBar(SnackBar( - // content: Text( - // "Maximum image size can be 2.5 MB", - // style: MyFonts.w500, - // ))); - // return; - // } - // setState(() { - // imageString = base64Encode(bytes); - // }); - // return; - // } - // }, - // child: Container( - // height: 30, - // width: 30, - // decoration: const BoxDecoration( - // borderRadius: BorderRadius.all(Radius.circular(75)), - // color: kWhite), - // child: const Icon(Icons.edit_outlined), - // ), - // ), - // ), - // ])), - // const SizedBox( - // height: 24, - // ), - Text('Basic Information', - style: MyFonts.w600.size(16).setColor(kWhite)), - const SizedBox( - height: 18, - ), - Form( - key: _formKey, - child: Column( + body: SafeArea( + child: SingleChildScrollView( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( children: [ - CustomTextField( - hintText: 'name', - // validator: validatefield, - isNecessary: false, - controller: _nameController, - isEnabled: false, - ), - const SizedBox( - height: 12, - ), - CustomTextField( - hintText: 'Roll Number', - // validator: validatefield, - isNecessary: false, - controller: _rollController, - maxLength: 9, - maxLines: 1, - counter: true, - ), - const SizedBox( - height: 12, - ), - CustomTextField( - isEnabled: false, - hintText: 'outlookEmail ID', - // validator: validatefield, - isNecessary: false, - controller: _outlookEmailController, - ), - const SizedBox( - height: 12, - ), - CustomTextField( - hintText: 'Alt Email', - validator: validatefield, - isNecessary: true, - controller: _altEmailController, - maxLength: 50, - maxLines: 1, - counter: true, - ), - const SizedBox( - height: 12, - ), - CustomTextField( - hintText: 'Phone Number', - validator: (String? value) { - if (value == null || value.isEmpty) { - return 'Field cannot be empty'; - } - else if(value.length!=10){ - return 'Enter valid 10 digit phone number'; - } - return null; - }, - isNecessary: true, - controller: _phoneController, - inputType: TextInputType.phone, - maxLength: 10, - maxLines: 1, - counter: true, - ), - const SizedBox( - height: 12, - ), - CustomTextField( - hintText: 'Emergency Contact Number', - validator: (String? value) { - if (value == null || value.isEmpty) { - return 'Field cannot be empty'; - } - else if(value.length!=10){ - return 'Enter valid 10 digit phone number'; - } - return null; - }, - isNecessary: true, - controller: _emergencyController, - inputType: TextInputType.phone, - maxLength: 10, - maxLines: 1, - counter: true, - ), - const SizedBox( - height: 12, - ), - CustomDropDown( - value: gender, - items: genders, - hintText: 'Your Gender', - onChanged: (g) => gender = g, - validator: validatefield), - const SizedBox( - height: 12, - ), - CustomDropDown( - value: hostel, - items: hostels, - hintText: 'Hostel', - onChanged: (h) => hostel = h, - validator: validatefield, - ), - - const SizedBox( - height: 12, - ), - CustomTextField( - hintText: 'Date of Birth', - validator: validatefield, - controller: _dobController, - onTap: () async { - FocusScope.of(context).requestFocus(FocusNode()); - DateTime? pickedDate = await showDatePicker( - context: context, - initialDate: selectedDob ?? DateTime.now(), - firstDate: DateTime(2000), - //DateTime.now() - not to allow to choose before today. - lastDate: DateTime(2101), - builder: (context, child) => CustomDatePicker( - child: child, - )); - if (pickedDate != null) { - if (!mounted) return; - selectedDob = pickedDate; - String formattedDate = - DateFormat('dd-MMM-yyyy').format(pickedDate); - setState(() { - _dobController.text = - formattedDate; //set output date to TextField value. - }); - } - }, - isNecessary: true, - ), - const SizedBox( - height: 12, - ), - CustomTextField( - hintText: 'Hostel room no', - validator: validatefield, - isNecessary: true, - controller: _roomNoController, - maxLength: 5, - maxLines: 1, - counter: true, - ), - const SizedBox( - height: 12, - ), - CustomTextField( - hintText: 'Home Address', - validator: validatefield, - isNecessary: true, - controller: _homeAddressController, - maxLength: 400, - // maxLines: 1, - counter: true, - ), - const SizedBox( - height: 12, - ), - CustomTextField( - hintText: 'LinkedIn Profile', - // validator: validatefield, - isNecessary: false, - controller: _linkedinController, - maxLength: 50, - maxLines: 1, - counter: true, - ), - const SizedBox( - height: 24, - ), + TextSpan( + text: 'Fields marked with', + style: MyFonts.w500.setColor(kWhite3).size(12)), + TextSpan( + text: ' * ', + style: MyFonts.w500.setColor(kRed).size(12)), + TextSpan( + text: 'are compulsory', + style: MyFonts.w500.setColor(kWhite3).size(12)), ], - )), - GestureDetector( - onTap: onFormSubmit, - child: Container( - width: double.infinity, - height: 48, - alignment: Alignment.center, - decoration: const BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(4)), - color: lBlue2), - child: const Text( - 'Submit', - textAlign: TextAlign.center, ), ), - ), - const SizedBox( - height: 24, - ), - ], - ), - )), + const SizedBox( + height: 24, + ), + // For now image will not be stored + // Center( + // child: Stack(alignment: Alignment.bottomRight, children: [ + // + // ClipRRect( + // borderRadius: BorderRadius.circular(75.0), + // + // child: Image( + // image: imageString==null?const ResizeImage(AssetImage('assets/images/profile_placeholder.png'),width: 150,height: 150): ResizeImage( + // MemoryImage(base64Decode(imageString!)) + // ,width: 150, + // height: 150,), + // fit: BoxFit.fill, + // ) + // ), + // Padding( + // padding: const EdgeInsets.all(8.0), + // child: GestureDetector( + // onTap: () async { + // XFile? xFile; + // await showDialog( + // context: context, + // builder: (BuildContext context) { + // return AlertDialog( + // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(28)), + // backgroundColor: kBlueGrey, + // title: Text( + // "Do you want to change your profile photo?",style: MyFonts.w500.size(16).setColor(kWhite2),), + // content: SingleChildScrollView( + // child: ListBody( + // children: [ + // GestureDetector( + // child: Text("Take Photo",style: MyFonts.w500.size(14).setColor(kWhite),), + // onTap: () async { + // xFile = await ImagePicker().pickImage( + // source: ImageSource.camera); + // if (!mounted) return; + // Navigator.of(context).pop(); + // }, + // ), + // const Padding( + // padding: EdgeInsets.all(8.0)), + // GestureDetector( + // child: Text("Choose Photo",style: MyFonts.w500.size(14).setColor(kWhite),), + // onTap: () async { + // xFile = await ImagePicker().pickImage( + // source: ImageSource.gallery); + // if (!mounted) return; + // Navigator.of(context).pop(); + // }, + // ), + // const Padding( + // padding: EdgeInsets.all(8.0)), + // + // GestureDetector( + // child: Text("Remove Photo",style: MyFonts.w500.size(14).setColor(kRed),), + // onTap: () async { + // setState(() { + // imageString=null; + // }); + // return + // Navigator.of(context).pop(); + // }, + // ), + // ], + // ), + // )); + // }); + // + // if (!mounted) return; + // if (xFile != null) { + // var bytes = File(xFile!.path).readAsBytesSync(); + // var imageSize = (bytes.lengthInBytes / + // (1048576)); // dividing by 1024*1024 + // if (imageSize > 2.5) { + // ScaffoldMessenger.of(context).showSnackBar(SnackBar( + // content: Text( + // "Maximum image size can be 2.5 MB", + // style: MyFonts.w500, + // ))); + // return; + // } + // setState(() { + // imageString = base64Encode(bytes); + // }); + // return; + // } + // }, + // child: Container( + // height: 30, + // width: 30, + // decoration: const BoxDecoration( + // borderRadius: BorderRadius.all(Radius.circular(75)), + // color: kWhite), + // child: const Icon(Icons.edit_outlined), + // ), + // ), + // ), + // ])), + // const SizedBox( + // height: 24, + // ), + Text('Basic Information', + style: MyFonts.w600.size(16).setColor(kWhite)), + const SizedBox( + height: 18, + ), + Form( + key: _formKey, + child: Column( + children: [ + CustomTextField( + hintText: 'name', + // validator: validatefield, + isNecessary: false, + controller: _nameController, + isEnabled: false, + ), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'Roll Number', + // validator: validatefield, + isNecessary: false, + controller: _rollController, + maxLength: 9, + maxLines: 1, + counter: true, + ), + const SizedBox( + height: 12, + ), + CustomTextField( + isEnabled: false, + hintText: 'outlookEmail ID', + // validator: validatefield, + isNecessary: false, + controller: _outlookEmailController, + ), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'Alt Email', + validator: validatefield, + isNecessary: true, + controller: _altEmailController, + maxLength: 50, + maxLines: 1, + counter: true, + ), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'Phone Number', + validator: (String? value) { + if (value == null || value.isEmpty) { + return 'Field cannot be empty'; + } + else if(value.length!=10){ + return 'Enter valid 10 digit phone number'; + } + return null; + }, + isNecessary: true, + controller: _phoneController, + inputType: TextInputType.phone, + maxLength: 10, + maxLines: 1, + counter: true, + ), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'Emergency Contact Number', + validator: (String? value) { + if (value == null || value.isEmpty) { + return 'Field cannot be empty'; + } + else if(value.length!=10){ + return 'Enter valid 10 digit phone number'; + } + return null; + }, + isNecessary: true, + controller: _emergencyController, + inputType: TextInputType.phone, + maxLength: 10, + maxLines: 1, + counter: true, + ), + const SizedBox( + height: 12, + ), + CustomDropDown( + value: gender, + items: genders, + hintText: 'Your Gender', + onChanged: (g) => gender = g, + validator: validatefield), + const SizedBox( + height: 12, + ), + CustomDropDown( + value: hostel, + items: hostels, + hintText: 'Hostel', + onChanged: (h) => hostel = h, + validator: validatefield, + ), + + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'Date of Birth', + validator: validatefield, + controller: _dobController, + onTap: () async { + FocusScope.of(context).requestFocus(FocusNode()); + DateTime? pickedDate = await showDatePicker( + context: context, + initialDate: selectedDob ?? DateTime.now(), + firstDate: DateTime(1990), + //DateTime.now() - not to allow to choose before today. + lastDate: DateTime(2101), + builder: (context, child) => CustomDatePicker( + child: child, + )); + if (pickedDate != null) { + if (!mounted) return; + selectedDob = pickedDate; + String formattedDate = + DateFormat('dd-MMM-yyyy').format(pickedDate); + setState(() { + _dobController.text = + formattedDate; //set output date to TextField value. + }); + } + }, + isNecessary: true, + ), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'Hostel room no', + validator: validatefield, + isNecessary: true, + controller: _roomNoController, + maxLength: 5, + maxLines: 1, + counter: true, + ), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'Home Address', + validator: validatefield, + isNecessary: true, + controller: _homeAddressController, + maxLength: 400, + // maxLines: 1, + counter: true, + ), + const SizedBox( + height: 12, + ), + CustomTextField( + hintText: 'LinkedIn Profile', + // validator: validatefield, + isNecessary: false, + controller: _linkedinController, + maxLength: 50, + maxLines: 1, + counter: true, + ), + const SizedBox( + height: 24, + ), + ], + )), + GestureDetector( + onTap: onFormSubmit, + child: Container( + width: double.infinity, + height: 48, + alignment: Alignment.center, + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(4)), + color: lBlue2), + child: const Text( + 'Submit', + textAlign: TextAlign.center, + ), + ), + ), + const SizedBox( + height: 24, + ), + ], + ), + )), + ), ), ); } From a3391f43cbee60b766471125477604dd8e984124 Mon Sep 17 00:00:00 2001 From: Chanchal Yadav <84243956+chanchalyadav272@users.noreply.github.com> Date: Fri, 16 Jun 2023 02:54:36 +0530 Subject: [PATCH 55/82] appbar on webview --- lib/pages/login/login.dart | 72 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index 1d9d3c05..c7cb5ff5 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -1,12 +1,16 @@ import 'dart:async'; import 'dart:io'; +import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; import 'package:onestop_dev/globals/size_config.dart'; import 'package:onestop_dev/pages/login/welcome.dart'; import 'package:onestop_dev/widgets/login/login_webview.dart'; import 'package:webview_flutter/webview_flutter.dart'; +import '../../globals/my_colors.dart'; +import '../../globals/my_fonts.dart'; + class LoginPage extends StatefulWidget { static String id = "/login"; @@ -30,6 +34,74 @@ class _LoginPageState extends State { Widget build(BuildContext context) { SizeConfig().init(context); return Scaffold( + appBar: loading + ? AppBar( + backgroundColor: kBackground, + iconTheme: const IconThemeData(color: kAppBarGrey), + automaticallyImplyLeading: false, + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CircleAvatar( + backgroundColor: kAppBarGrey, + child: IconButton( + icon: const Icon( + FluentIcons.arrow_left_24_regular, + color: lBlue2, + ), + onPressed: () { + Navigator.of(context) + .pushNamedAndRemoveUntil('/login', (Route route) => false); + }, + ), + ), + RichText( + text: TextSpan(children: [ + WidgetSpan( + child: Row( + children: [ + Text( + "One", + textAlign: TextAlign.center, + style: MyFonts.w600 + .size(23) + .letterSpace(1.0) + .setColor(lBlue2), + ), + Text( + ".", + textAlign: TextAlign.center, + style: MyFonts.w500.size(23).setColor(kYellow), + ), + ], + ), + ), + ]), + ), + Opacity( + opacity: 0, + child: CircleAvatar( + backgroundColor: kAppBarGrey, + child: IconButton( + icon: const Icon( + FluentIcons.arrow_left_24_regular, + color: lBlue2, + ), + onPressed: () { + // setState(() { + // loading=false; + // }); + }, + ), + ), + ), + + ], + ), + elevation: 0.0, + ) + : null, body: loading ? SafeArea(child: LoginWebView(controller: _controller)) : WelcomePage(setLoading: () { From a7b94f52ff6043bc81722659926827197b7ac44b Mon Sep 17 00:00:00 2001 From: Chanchal Yadav <84243956+chanchalyadav272@users.noreply.github.com> Date: Fri, 16 Jun 2023 05:16:47 +0530 Subject: [PATCH 56/82] changed routes for login --- lib/pages/login/login.dart | 88 ++++------------------------- lib/pages/login/welcome.dart | 60 ++++++++++++-------- lib/pages/splash.dart | 2 +- lib/routes.dart | 3 + lib/widgets/login/login_button.dart | 9 ++- 5 files changed, 58 insertions(+), 104 deletions(-) diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index c7cb5ff5..45b98795 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -20,7 +20,7 @@ class LoginPage extends StatefulWidget { } class _LoginPageState extends State { - bool loading = false; + // bool loading = false; final Completer _controller = Completer(); @@ -34,80 +34,16 @@ class _LoginPageState extends State { Widget build(BuildContext context) { SizeConfig().init(context); return Scaffold( - appBar: loading - ? AppBar( - backgroundColor: kBackground, - iconTheme: const IconThemeData(color: kAppBarGrey), - automaticallyImplyLeading: false, - title: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - CircleAvatar( - backgroundColor: kAppBarGrey, - child: IconButton( - icon: const Icon( - FluentIcons.arrow_left_24_regular, - color: lBlue2, - ), - onPressed: () { - Navigator.of(context) - .pushNamedAndRemoveUntil('/login', (Route route) => false); - }, - ), - ), - RichText( - text: TextSpan(children: [ - WidgetSpan( - child: Row( - children: [ - Text( - "One", - textAlign: TextAlign.center, - style: MyFonts.w600 - .size(23) - .letterSpace(1.0) - .setColor(lBlue2), - ), - Text( - ".", - textAlign: TextAlign.center, - style: MyFonts.w500.size(23).setColor(kYellow), - ), - ], - ), - ), - ]), - ), - Opacity( - opacity: 0, - child: CircleAvatar( - backgroundColor: kAppBarGrey, - child: IconButton( - icon: const Icon( - FluentIcons.arrow_left_24_regular, - color: lBlue2, - ), - onPressed: () { - // setState(() { - // loading=false; - // }); - }, - ), - ), - ), - - ], - ), - elevation: 0.0, - ) - : null, - body: loading - ? SafeArea(child: LoginWebView(controller: _controller)) - : WelcomePage(setLoading: () { - setState(() { - loading = true; - }); - })); + body: + // loading + // ? + SafeArea(child: LoginWebView(controller: _controller)) + // : WelcomePage(setLoading: () { + // setState(() { + // loading = true; + // }); + // }) + + ); } } diff --git a/lib/pages/login/welcome.dart b/lib/pages/login/welcome.dart index e61e7d2e..e509fac6 100644 --- a/lib/pages/login/welcome.dart +++ b/lib/pages/login/welcome.dart @@ -3,35 +3,47 @@ import 'package:onestop_dev/globals/my_spaces.dart'; import 'package:onestop_dev/widgets/login/login_button.dart'; import 'package:onestop_dev/widgets/login/welcome_header.dart'; +import '../../globals/size_config.dart'; + class WelcomePage extends StatelessWidget { - final Function setLoading; - const WelcomePage({Key? key, required this.setLoading}) : super(key: key); + static String id = "/login2"; + // final Function setLoading; + const WelcomePage({Key? key, + // required this.setLoading + }) : super(key: key); @override Widget build(BuildContext context) { - return Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - flex: 4, - child: Container( - decoration: const BoxDecoration( - image: DecorationImage( - image: AssetImage('assets/images/bg_triangle.png'), - fit: BoxFit.fill, - )), - child: const WelcomeHeader(), - ), - ), - Expanded( - flex: 1, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: MySpaces.horizontalScreenPadding), - child: LoginButton(setLoading: setLoading), - ), + SizeConfig().init(context); + return Scaffold( + body: + SafeArea( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + flex: 4, + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/bg_triangle.png'), + fit: BoxFit.fill, + )), + child: const WelcomeHeader(), + ), + ), + Expanded( + flex: 1, + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: MySpaces.horizontalScreenPadding + ), + child: const LoginButton(), + ), + ), + ], ), - ], + ), ); } } diff --git a/lib/pages/splash.dart b/lib/pages/splash.dart index 82bcd613..5fc61dd0 100644 --- a/lib/pages/splash.dart +++ b/lib/pages/splash.dart @@ -23,7 +23,7 @@ class _SplashPageState extends State { .pushNamedAndRemoveUntil('/home2', (Route route) => false); } else { Navigator.of(context) - .pushNamedAndRemoveUntil('/login', (Route route) => false); + .pushNamedAndRemoveUntil('/login2', (Route route) => false); } }); } diff --git a/lib/routes.dart b/lib/routes.dart index f8b5cfb3..e5fbf284 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -1,3 +1,4 @@ +import 'package:onestop_dev/pages/login/welcome.dart'; import 'package:onestop_dev/pages/notifications/notifications.dart'; import 'package:onestop_dev/pages/quick_links/academic_calendar.dart'; import 'package:onestop_dev/pages/quick_links/academic_sso.dart'; @@ -17,6 +18,7 @@ import 'package:onestop_dev/pages/profile.dart'; import 'package:onestop_dev/pages/splash.dart'; import 'package:onestop_dev/pages/upsp/upsp.dart'; + final routes = { SplashPage.id: (context) => const SplashPage(), ProfilePage.id: (context) => const ProfilePage(), @@ -36,4 +38,5 @@ final routes = { Scoreboard.id: (context) => const Scoreboard(), Upsp.id: (context) => const Upsp(), GuestHouse.id: (context) => const GuestHouse(), + WelcomePage.id:(context)=> const WelcomePage(), }; diff --git a/lib/widgets/login/login_button.dart b/lib/widgets/login/login_button.dart index 45306afa..86e55702 100644 --- a/lib/widgets/login/login_button.dart +++ b/lib/widgets/login/login_button.dart @@ -9,10 +9,10 @@ import 'package:provider/provider.dart'; class LoginButton extends StatelessWidget { const LoginButton({ Key? key, - required this.setLoading, + // required this.setLoading, }) : super(key: key); - final Function setLoading; + // final Function setLoading; @override Widget build(BuildContext context) { @@ -32,7 +32,10 @@ class LoginButton extends StatelessWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(18))), onPressed: () { - setLoading(); + // setLoading(); + Navigator.of(context).pushNamed( + '/login', + ); }, child: FittedBox( fit: BoxFit.fitWidth, From 7997527c934db5aeefd1a65e641a4c57970449b5 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Tue, 20 Jun 2023 03:14:16 +0530 Subject: [PATCH 57/82] minor fix --- lib/widgets/travel/ferry_details.dart | 134 +++++++++++++--------- lib/widgets/travel/stops_bus_details.dart | 40 +++++-- 2 files changed, 106 insertions(+), 68 deletions(-) diff --git a/lib/widgets/travel/ferry_details.dart b/lib/widgets/travel/ferry_details.dart index d9a6b2a8..ad532d76 100644 --- a/lib/widgets/travel/ferry_details.dart +++ b/lib/widgets/travel/ferry_details.dart @@ -16,8 +16,22 @@ import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; import 'package:provider/provider.dart'; import '../../functions/travel/next_time.dart'; -class FerryDetails extends StatelessWidget { +class FerryDetails extends StatefulWidget { const FerryDetails({Key? key}) : super(key: key); + + @override + State createState() => _FerryDetailsState(); +} + +class _FerryDetailsState extends State { + @override + void initState() { + super.initState(); + if (DateTime.now().weekday == DateTime.sunday) { + context.read().setFerryDayType("Sunday"); + } + } + @override Widget build(BuildContext context) { return Observer(builder: (context) { @@ -30,7 +44,7 @@ class FerryDetails extends StatelessWidget { .ferryTimings .value! .firstWhere((element) => - element.stop == context.read().selectedFerryGhat); + element.stop == context.read().selectedFerryGhat); // var ferryMap = ferryModel.toJson(); return Column(children: [ SizedBox( @@ -39,45 +53,45 @@ class FerryDetails extends StatelessWidget { scrollDirection: Axis.horizontal, children: ferryGhats .map((e) => TextButton( - onPressed: () { - context.read().setFerryGhat(e['name']); - var mapboxStore = context.read(); - int i = mapboxStore.allLocationData.indexWhere( - (element) => e['name'] == element['name']); - mapboxStore.selectedCarousel(i); - mapboxStore.zoomTwoMarkers( - mapboxStore.selectedCarouselLatLng, - LatLng(mapboxStore.userlat, mapboxStore.userlong), - 90.0); - }, - child: ClipRRect( - borderRadius: const BorderRadius.all( - Radius.circular(40), - ), - child: Container( - color: (context - .read() - .selectedFerryGhat == - e['name']) - ? lBlue2 - : kGrey2, - child: Center( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - e['name'], - style: (context - .read() - .selectedFerryGhat == - e['name']) - ? MyFonts.w500.setColor(kBlueGrey) - : MyFonts.w500.setColor(kWhite), + onPressed: () { + context.read().setFerryGhat(e['name']); + var mapboxStore = context.read(); + int i = mapboxStore.allLocationData.indexWhere( + (element) => e['name'] == element['name']); + mapboxStore.selectedCarousel(i); + mapboxStore.zoomTwoMarkers( + mapboxStore.selectedCarouselLatLng, + LatLng(mapboxStore.userlat, mapboxStore.userlong), + 90.0); + }, + child: ClipRRect( + borderRadius: const BorderRadius.all( + Radius.circular(40), + ), + child: Container( + color: (context + .read() + .selectedFerryGhat == + e['name']) + ? lBlue2 + : kGrey2, + child: Center( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + e['name'], + style: (context + .read() + .selectedFerryGhat == + e['name']) + ? MyFonts.w500.setColor(kBlueGrey) + : MyFonts.w500.setColor(kWhite), + ), + ), + ), + ), ), - ), - ), - ), - ), - )) + )) .toList(), ), ), @@ -97,41 +111,48 @@ class FerryDetails extends StatelessWidget { ], ), ), - if (daytype=="Sunday") ...[ + if (daytype == "Sunday") ...[ ListView.builder( shrinkWrap: true, physics: const ClampingScrollPhysics(), - itemCount: direction=="Campus to City"? ferryModel.weekend.fromCampus.length:ferryModel.weekend.toCampus.length, - itemBuilder:(BuildContext context, int index){ + itemCount: direction == "Campus to City" + ? ferryModel.weekend.fromCampus.length + : ferryModel.weekend.toCampus.length, + itemBuilder: (BuildContext context, int index) { return Padding( padding: const EdgeInsets.symmetric(vertical: 5), child: TimingTile( - time: direction=="Campus to City" ? formatTime(ferryModel.weekend.fromCampus[index]):formatTime(ferryModel.weekend.toCampus[index]), - isLeft: direction=="Campus to City"? hasLeft(ferryModel.weekend.fromCampus[index]):hasLeft(ferryModel.weekend.toCampus[index]), + time: direction == "Campus to City" + ? formatTime(ferryModel.weekend.fromCampus[index]) + : formatTime(ferryModel.weekend.toCampus[index]), + isLeft: direction == "Campus to City" + ? hasLeft(ferryModel.weekend.fromCampus[index]) + : hasLeft(ferryModel.weekend.toCampus[index]), icon: FluentIcons.vehicle_bus_24_filled, - ), ); - } - - ), + }), ] else ...[ ListView.builder( shrinkWrap: true, physics: const ClampingScrollPhysics(), - itemCount: direction=="Campus to City"? ferryModel.weekdays.fromCampus.length:ferryModel.weekdays.toCampus.length, - itemBuilder:(BuildContext context, int index){ + itemCount: direction == "Campus to City" + ? ferryModel.weekdays.fromCampus.length + : ferryModel.weekdays.toCampus.length, + itemBuilder: (BuildContext context, int index) { return Padding( padding: const EdgeInsets.symmetric(vertical: 5), child: TimingTile( - time: direction=="Campus to City" ? formatTime(ferryModel.weekdays.fromCampus[index]):formatTime(ferryModel.weekdays.toCampus[index]), - isLeft: direction=="Campus to City"? hasLeft(ferryModel.weekdays.fromCampus[index]):hasLeft(ferryModel.weekdays.toCampus[index]), + time: direction == "Campus to City" + ? formatTime(ferryModel.weekdays.fromCampus[index]) + : formatTime(ferryModel.weekdays.toCampus[index]), + isLeft: direction == "Campus to City" + ? hasLeft(ferryModel.weekdays.fromCampus[index]) + : hasLeft(ferryModel.weekdays.toCampus[index]), icon: FluentIcons.vehicle_bus_24_filled, - ), ); - } - ), + }), ] ]); } @@ -142,4 +163,3 @@ class FerryDetails extends StatelessWidget { }); } } - diff --git a/lib/widgets/travel/stops_bus_details.dart b/lib/widgets/travel/stops_bus_details.dart index d0aa3795..a5702014 100644 --- a/lib/widgets/travel/stops_bus_details.dart +++ b/lib/widgets/travel/stops_bus_details.dart @@ -7,9 +7,23 @@ import 'package:onestop_dev/widgets/travel/tracking_dailog.dart'; import 'package:onestop_dev/widgets/travel/travel_drop_down.dart'; import 'package:provider/provider.dart'; -class StopsBusDetails extends StatelessWidget { +class StopsBusDetails extends StatefulWidget { const StopsBusDetails({Key? key}) : super(key: key); + @override + State createState() => _StopsBusDetailsState(); +} + +class _StopsBusDetailsState extends State { + @override + void initState() { + super.initState(); + if (DateTime.now().weekday == DateTime.sunday || + DateTime.now().weekday == DateTime.saturday) { + context.read().setBusDayString("Weekends"); + } + } + @override Widget build(BuildContext context) { return Observer(builder: (context) { @@ -68,19 +82,23 @@ class StopsBusDetails extends StatelessWidget { Expanded( child: Container(), ), - context.read().isBusSelected ? TravelDropDown( - value: context.read().busDayType, - onChange: context.read().setBusDayString, - items: const ['Weekdays', 'Weekends'], - ) + value: context.read().busDayType, + onChange: context.read().setBusDayString, + items: const ['Weekdays', 'Weekends'], + ) : GestureDetector( - onTap: (){ - showDialog(context: context, builder: (_) => const TrackingDailog()); - }, - child: Text("Track Bus", style: MyFonts.w500.setColor(kWhite),), - ) + onTap: () { + showDialog( + context: context, + builder: (_) => const TrackingDailog()); + }, + child: Text( + "Track Bus", + style: MyFonts.w500.setColor(kWhite), + ), + ) ], ), context.read().busPage From c44e3dd31a172aac4e9db31c4c777fd883a78088 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Tue, 27 Jun 2023 02:46:32 +0530 Subject: [PATCH 58/82] input formatter in custom text field --- lib/pages/profile/edit_profile.dart | 4 ++++ lib/widgets/profile/custom_text_field.dart | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/pages/profile/edit_profile.dart b/lib/pages/profile/edit_profile.dart index c9d0701e..7d9362b6 100644 --- a/lib/pages/profile/edit_profile.dart +++ b/lib/pages/profile/edit_profile.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:image_picker/image_picker.dart'; import 'package:intl/intl.dart'; import 'package:onestop_dev/services/api.dart'; @@ -302,6 +303,7 @@ class _EditProfileState extends State { CustomTextField( hintText: 'Roll Number', // validator: validatefield, + inputFormatters: [FilteringTextInputFormatter.digitsOnly,], isNecessary: false, controller: _rollController, maxLength: 9, @@ -347,6 +349,7 @@ class _EditProfileState extends State { isNecessary: true, controller: _phoneController, inputType: TextInputType.phone, + inputFormatters: [FilteringTextInputFormatter.digitsOnly,], maxLength: 10, maxLines: 1, counter: true, @@ -365,6 +368,7 @@ class _EditProfileState extends State { } return null; }, + inputFormatters: [FilteringTextInputFormatter.digitsOnly,], isNecessary: true, controller: _emergencyController, inputType: TextInputType.phone, diff --git a/lib/widgets/profile/custom_text_field.dart b/lib/widgets/profile/custom_text_field.dart index cb3f718c..a5620073 100644 --- a/lib/widgets/profile/custom_text_field.dart +++ b/lib/widgets/profile/custom_text_field.dart @@ -1,10 +1,12 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import '../../globals/my_colors.dart'; import '../../globals/my_fonts.dart'; class CustomTextField extends StatefulWidget { + final List? inputFormatters; final String hintText; final TextInputType? inputType; final String? Function(String?)? validator; @@ -31,7 +33,7 @@ class CustomTextField extends StatefulWidget { this.controller, this.onTap, this.isEnabled, - this.focusNode, this.maxLength, this.maxLines, this.counter, }); + this.focusNode, this.maxLength, this.maxLines, this.counter, this.inputFormatters, }); @override State createState() => _CustomTextFieldState(); @@ -49,6 +51,7 @@ class _CustomTextFieldState extends State { style: MyFonts.w500.size(12).setColor(kWhite)); } return TextFormField( + inputFormatters:widget.inputFormatters, enabled: widget.isEnabled ?? true, readOnly: widget.onTap != null, style: MyFonts.w500.size(14).copyWith(color: Colors.white), From 7733d19bed26b1e71f4267a8192c02adc8e69114 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Tue, 27 Jun 2023 03:47:37 +0530 Subject: [PATCH 59/82] minor fix --- lib/pages/profile/edit_profile.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pages/profile/edit_profile.dart b/lib/pages/profile/edit_profile.dart index 7d9362b6..06bc1c49 100644 --- a/lib/pages/profile/edit_profile.dart +++ b/lib/pages/profile/edit_profile.dart @@ -122,6 +122,7 @@ class _EditProfileState extends State { Map userInfo = await APIService().getUserProfile(); SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString('hostel', hostel??""); prefs.setString("userInfo", jsonEncode(userInfo)); context.read().saveToUserInfo(prefs); // automatically updates token & other user info Navigator.of(context) From 2c58971f3bd73010868787ac1856121304b5b08a Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Tue, 27 Jun 2023 03:57:07 +0530 Subject: [PATCH 60/82] upsp fix --- lib/pages/upsp/details_upsp.dart | 5 ++++- lib/pages/upsp/upsp.dart | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/pages/upsp/details_upsp.dart b/lib/pages/upsp/details_upsp.dart index 5ec3eb18..85b218c6 100644 --- a/lib/pages/upsp/details_upsp.dart +++ b/lib/pages/upsp/details_upsp.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:fluentui_system_icons/fluentui_system_icons.dart'; +import 'package:flutter/services.dart'; import 'package:onestop_dev/functions/utility/show_snackbar.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; @@ -42,7 +43,7 @@ class _DetailsUpspState extends State { @override Widget build(BuildContext context) { var userData = LoginStore.userData; - String email = userData['email']!; + String email = userData['outlookEmail']!; String name = userData['name']!; String roll = userData['rollNo']!; return Scaffold( @@ -95,6 +96,7 @@ class _DetailsUpspState extends State { } return null; }, + inputFormatters: [FilteringTextInputFormatter.digitsOnly], keyboardType: TextInputType.number, style: MyFonts.w500.size(16).setColor(kWhite), decoration: InputDecoration( @@ -137,6 +139,7 @@ class _DetailsUpspState extends State { return null; }, keyboardType: TextInputType.number, + inputFormatters: [FilteringTextInputFormatter.digitsOnly], controller: contact, maxLength: 10, style: MyFonts.w500.size(16).setColor(kWhite), diff --git a/lib/pages/upsp/upsp.dart b/lib/pages/upsp/upsp.dart index a3dc593b..96aefbe1 100644 --- a/lib/pages/upsp/upsp.dart +++ b/lib/pages/upsp/upsp.dart @@ -50,7 +50,7 @@ class _UpspState extends State { @override Widget build(BuildContext context) { var userData = LoginStore.userData; - String email = userData['email']!; + String email = userData['outlookEmail']!; return Theme( data: Theme.of(context).copyWith( From 6a5988c07c7405ce98f846f16c99258e5d2a1b8a Mon Sep 17 00:00:00 2001 From: Kunalpal216 Date: Tue, 27 Jun 2023 15:13:26 +0530 Subject: [PATCH 61/82] fixed guest issue --- android/build.gradle | 2 +- lib/pages/profile/profile_page.dart | 4 +-- lib/services/api.dart | 3 ++ lib/stores/login_store.dart | 49 ++++++++++++++++------------- 4 files changed, 33 insertions(+), 25 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index e7e99f05..35e8b225 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.8.21' + ext.kotlin_version = '1.8.22' repositories { google() diff --git a/lib/pages/profile/profile_page.dart b/lib/pages/profile/profile_page.dart index c6dc9ca5..f8625ce5 100644 --- a/lib/pages/profile/profile_page.dart +++ b/lib/pages/profile/profile_page.dart @@ -126,11 +126,11 @@ class _ProfileState extends State { ), DataTile( title: 'Contact Number', - semiTitle: widget.profileModel.phoneNumber.toString(), + semiTitle: widget.profileModel.phoneNumber!=null ? widget.profileModel.phoneNumber.toString() : null, ), DataTile( title: 'Emergency Contact Number', - semiTitle: widget.profileModel.emergencyPhoneNumber.toString(), + semiTitle: widget.profileModel.emergencyPhoneNumber!=null ? widget.profileModel.emergencyPhoneNumber.toString() : null, ), DataTile( title: 'Hostel', diff --git a/lib/services/api.dart b/lib/services/api.dart index f601dd07..df70e16f 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -34,6 +34,7 @@ class APIService { .add(InterceptorsWrapper(onRequest: (options, handler) async { print("THIS IS TOKEN"); print(await AuthUserHelpers.getAccessToken()); + print(options.path); options.headers["Authorization"] = "Bearer ${await AuthUserHelpers.getAccessToken()}"; handler.next(options); @@ -135,7 +136,9 @@ class APIService { } Future getUserProfile() async { + print("Inside GET USER PROFILE"); var response = await dio.get(Endpoints.userProfile); + print(response.data); return response.data; } diff --git a/lib/stores/login_store.dart b/lib/stores/login_store.dart index 8b215bfb..3c9026fc 100644 --- a/lib/stores/login_store.dart +++ b/lib/stores/login_store.dart @@ -57,6 +57,7 @@ class LoginStore { print("inside authentication check"); if (user.containsKey(BackendHelper.refreshtoken)) { print("here"); + print(await user.containsKey("userInfo")); await saveToUserInfo(user); return true; } @@ -76,9 +77,8 @@ class LoginStore { print(Endpoints.getHeader()); final response = await APIService().guestUserLogin(); print(response.data); - saveToPreferences(sharedPrefs, response.data); - saveToUserInfo(sharedPrefs); - sharedPrefs.setBool("isGuest", true); // guest sign in + await saveToPreferences(sharedPrefs, response.data); + await saveToUserInfo(sharedPrefs); } Future saveToPreferences( @@ -86,44 +86,49 @@ class LoginStore { print(data); print(data.runtimeType); print(data[BackendHelper.accesstoken]); - instance.setString( + await instance.setString( BackendHelper.accesstoken, data[BackendHelper.accesstoken]); - instance.setString( + await instance.setString( BackendHelper.refreshtoken, data[BackendHelper.refreshtoken]); - instance.setBool("isGuest", false); // general case + await instance.setBool("isGuest", isGuest); // handle guest or user Map userInfo = await APIService().getUserProfile(); print(userInfo); print(jsonEncode(userInfo)); - instance.setString("userInfo", jsonEncode(userInfo)); // save user profile + await instance.setString("userInfo", jsonEncode(userInfo)); // save user profile } Future saveToUserInfo(SharedPreferences instance) async { // only called after saving jwt tokens in local storage print("here"); userData = jsonDecode(instance.getString("userInfo")!); - isGuest = instance.getBool("isGuest")!; print(userData); var fcmToken = await FirebaseMessaging.instance.getToken(); print("fcm token: ${fcmToken}"); - if (instance.getString("deviceToken") != null && instance.getString("deviceToken")!=fcmToken) { // already some token was stored - print("inside if"); - await APIService().updateUserDeviceToken({ - "oldToken": instance.getString("deviceToken"), // stored token - "newToken": fcmToken - }); - } - else{ - print("inside else"); - instance.setString("deviceToken", fcmToken!); // set the returned fcToken - await APIService().postUserDeviceToken(fcmToken!); + print(isGuest); + if(!isGuest){ + if (instance.getString("deviceToken") != null && instance.getString("deviceToken")!=fcmToken) { // already some token was stored + print("inside if"); + await APIService().updateUserDeviceToken({ + "oldToken": instance.getString("deviceToken"), // stored token + "newToken": fcmToken + }); + } + else{ + print("inside else"); + instance.setString("deviceToken", fcmToken!); // set the returned fcToken + await APIService().postUserDeviceToken(fcmToken!); + } } } void logOut(Function navigationPopCallBack) async { + print("INSIDE LOGOUT"); await cookieManager.clearCookies(); SharedPreferences user = await SharedPreferences.getInstance(); - print(user.getString("deviceToken")!); - if(!isGuest) await APIService().logoutUser(user.getString("deviceToken")!); // remove token on logout if not guest - user.clear(); + if(!isGuest){ + print(user.getString("deviceToken")!); + await APIService().logoutUser(user.getString("deviceToken")!); // remove token on logout if not guest + } + await user.clear(); userData.clear(); isGuest = false; await LocalStorage.instance.deleteRecordsLogOut(); From 408c7e20121917a5b851599a5ca33f995a780867 Mon Sep 17 00:00:00 2001 From: Kunalpal216 Date: Tue, 27 Jun 2023 19:18:54 +0530 Subject: [PATCH 62/82] fixed session expired --- lib/globals/endpoints.dart | 2 +- lib/services/api.dart | 3 ++- lib/stores/login_store.dart | 6 ++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/globals/endpoints.dart b/lib/globals/endpoints.dart index 7044ab98..04c502f1 100644 --- a/lib/globals/endpoints.dart +++ b/lib/globals/endpoints.dart @@ -14,8 +14,8 @@ class Endpoints { static const String messURL = "/hostelsMessMenu"; static const String buyURL = '/buy'; static const String sellURL = '/sell'; - static const String sellPath = '/sellPage'; static const String buyPath = '/buyPage'; + static const String sellPath = '/sellPage'; static const String bnsMyAdsURL = '/bns/myads'; static const String lnfMyAdsURL = '/lnf/myads'; static const String deleteBuyURL = "/buy/remove"; diff --git a/lib/services/api.dart b/lib/services/api.dart index df70e16f..420b5bf4 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -49,6 +49,7 @@ class APIService { bool couldRegenerate = await regenerateAccessToken(); // ignore: use_build_context_synchronously if (couldRegenerate) { + print("COULD REGENRATE TOKEN"); // retry return handler.resolve(await retryRequest(response)); } else { @@ -321,7 +322,7 @@ class APIService { 'page': pageNumber.toString(), }; //final uri = Uri.https('swc.iitg.ac.in', Endpoints.buyPath, queryParameters); - var response = await dio.get(Endpoints.sellPath,queryParameters: queryParameters); + var response = await dio.get(Endpoints.buyPath,queryParameters: queryParameters); print(response); var json = response.data; List buyPage = (json['details'] as List) diff --git a/lib/stores/login_store.dart b/lib/stores/login_store.dart index 3c9026fc..692c0d17 100644 --- a/lib/stores/login_store.dart +++ b/lib/stores/login_store.dart @@ -69,7 +69,6 @@ class LoginStore { } Future signInAsGuest() async { - APIService().getBuyPage(1); print("GUEST SIGN IN"); isGuest = true; var sharedPrefs = await SharedPreferences.getInstance(); @@ -104,7 +103,7 @@ class LoginStore { var fcmToken = await FirebaseMessaging.instance.getToken(); print("fcm token: ${fcmToken}"); print(isGuest); - if(!isGuest){ + if(instance.getBool("isGuest")==false){ if (instance.getString("deviceToken") != null && instance.getString("deviceToken")!=fcmToken) { // already some token was stored print("inside if"); await APIService().updateUserDeviceToken({ @@ -118,6 +117,9 @@ class LoginStore { await APIService().postUserDeviceToken(fcmToken!); } } + else{ + isGuest=true; + } } void logOut(Function navigationPopCallBack) async { From a504611ca0bbf8aa3399916e23c0736b600715f0 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Tue, 27 Jun 2023 19:42:30 +0530 Subject: [PATCH 63/82] fixed ui and null check issues --- lib/pages/buy_sell/bns_home.dart | 2 +- lib/pages/buy_sell/buy_form.dart | 2 +- lib/pages/lost_found/lnf_home.dart | 2 +- lib/widgets/lostfound/claim_call_button.dart | 2 +- lib/widgets/profile/feedback.dart | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/pages/buy_sell/bns_home.dart b/lib/pages/buy_sell/bns_home.dart index 009df795..10210a9e 100644 --- a/lib/pages/buy_sell/bns_home.dart +++ b/lib/pages/buy_sell/bns_home.dart @@ -172,7 +172,7 @@ class _BuySellHomeState extends State { child: context.read().isGuestUser ? const GuestRestrictAccess() : FutureBuilder( future: APIService().getBnsMyItems( - LoginStore.userData['email']!), + LoginStore.userData['outlookEmail']!), builder: (context, snapshot) { if (snapshot.hasData) { List models = diff --git a/lib/pages/buy_sell/buy_form.dart b/lib/pages/buy_sell/buy_form.dart index 278d717c..9cae3b5b 100644 --- a/lib/pages/buy_sell/buy_form.dart +++ b/lib/pages/buy_sell/buy_form.dart @@ -67,7 +67,7 @@ class _BuySellFormState extends State { children: [ isLoading ? const LinearProgressIndicator() - : const ProgressBar(blue: 2, grey: 0), + : widget.category == "Found" ? const ProgressBar(blue: 3, grey: 0): const ProgressBar(blue: 2, grey: 0), Container( margin: const EdgeInsets.only( top: 40, left: 15, right: 5, bottom: 15), diff --git a/lib/pages/lost_found/lnf_home.dart b/lib/pages/lost_found/lnf_home.dart index ba7fe2d2..1a7da6e5 100644 --- a/lib/pages/lost_found/lnf_home.dart +++ b/lib/pages/lost_found/lnf_home.dart @@ -175,7 +175,7 @@ class _LostFoundHomeState extends State { child: context.read().isGuestUser ? const GuestRestrictAccess() : FutureBuilder( future: APIService().getLnfMyItems( - LoginStore.userData['email'] ?? ""), + LoginStore.userData['outlookEmail'] ?? ""), builder: (context, snapshot) { if (snapshot.hasData) { List models = snapshot.data! as List; diff --git a/lib/widgets/lostfound/claim_call_button.dart b/lib/widgets/lostfound/claim_call_button.dart index 762174ac..67585c4a 100644 --- a/lib/widgets/lostfound/claim_call_button.dart +++ b/lib/widgets/lostfound/claim_call_button.dart @@ -50,7 +50,7 @@ class _ClaimCallButtonState extends State { var name = LoginStore.userData['name']; var email = - LoginStore.userData['email']; + LoginStore.userData['outlookEmail']; var body = await APIService().claimFoundItem( name: name!, email: email!, diff --git a/lib/widgets/profile/feedback.dart b/lib/widgets/profile/feedback.dart index a6ee95e8..442886c8 100644 --- a/lib/widgets/profile/feedback.dart +++ b/lib/widgets/profile/feedback.dart @@ -193,7 +193,7 @@ class _FeedBackState extends State { 'title': title.text, 'body': body.text, 'type': selected, - 'user': LoginStore.userData['email'] ?? + 'user': LoginStore.userData['outlookEmail'] ?? "Unknown" }; setState(() => enableSubmitButton = false); From a3e7fec994e42e2137fa8e2bc8bcff82b66ac212 Mon Sep 17 00:00:00 2001 From: Kunalpal216 Date: Wed, 28 Jun 2023 00:20:10 +0530 Subject: [PATCH 64/82] completed cab sharing --- lib/pages/quick_links/cab_share.dart | 6 +----- lib/services/notifications_provider.dart | 1 + lib/stores/login_store.dart | 3 ++- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/pages/quick_links/cab_share.dart b/lib/pages/quick_links/cab_share.dart index a3cd6fe7..0ac2437b 100644 --- a/lib/pages/quick_links/cab_share.dart +++ b/lib/pages/quick_links/cab_share.dart @@ -10,10 +10,6 @@ class CabShare extends StatelessWidget { @override Widget build(BuildContext context) { print(LoginStore.userData); - return CabSharingScreen(userData: { - 'name': LoginStore.userData["name"]!, - 'email': LoginStore.userData["outlookEmail"]!, - 'security-key': const String.fromEnvironment('SECURITY-KEY') - }); + return CabSharingSplashScreen(); } } diff --git a/lib/services/notifications_provider.dart b/lib/services/notifications_provider.dart index 7b46cf9a..a9630851 100644 --- a/lib/services/notifications_provider.dart +++ b/lib/services/notifications_provider.dart @@ -68,6 +68,7 @@ bool checkNotificationCategory(String type) { case "buy": case "sell": case "travel": + case "cab sharing": return true; } return false; diff --git a/lib/stores/login_store.dart b/lib/stores/login_store.dart index 692c0d17..641934f6 100644 --- a/lib/stores/login_store.dart +++ b/lib/stores/login_store.dart @@ -104,6 +104,7 @@ class LoginStore { print("fcm token: ${fcmToken}"); print(isGuest); if(instance.getBool("isGuest")==false){ + print(instance.getString("deviceToken")); if (instance.getString("deviceToken") != null && instance.getString("deviceToken")!=fcmToken) { // already some token was stored print("inside if"); await APIService().updateUserDeviceToken({ @@ -111,7 +112,7 @@ class LoginStore { "newToken": fcmToken }); } - else{ + else if(instance.getString("deviceToken")==null){ print("inside else"); instance.setString("deviceToken", fcmToken!); // set the returned fcToken await APIService().postUserDeviceToken(fcmToken!); From 090b12b6b2c03ef9a55ee7b2155cfa7e9a8e2caf Mon Sep 17 00:00:00 2001 From: Kunalpal216 Date: Wed, 28 Jun 2023 22:16:36 +0530 Subject: [PATCH 65/82] fixed all issues --- lib/models/contacts/contact_model.dart | 8 +-- lib/models/contacts/contact_model.g.dart | 6 +- lib/models/food/dish_model.dart | 32 ++------- lib/models/food/dish_model.g.dart | 18 ++--- lib/models/food/restaurant_model.dart | 28 ++++---- lib/models/food/restaurant_model.g.dart | 25 ++++--- lib/models/travel/day_type_model.dart | 2 +- lib/models/travel/travel_timing_model.dart | 2 - lib/models/travel/travel_timing_model.g.dart | 18 ++--- lib/pages/contact/contact.dart | 2 +- lib/pages/contact/contact_detail.dart | 18 ++--- lib/services/data_provider.dart | 23 ++++--- lib/stores/restaurant_store.dart | 13 ++-- lib/widgets/contact/contact_page_button.dart | 13 ++-- lib/widgets/food/restaurant/food_tile.dart | 66 +++++++++---------- .../food/restaurant/restaurant_header.dart | 14 ++-- .../food/restaurant/restaurant_tile.dart | 19 ++---- 17 files changed, 131 insertions(+), 176 deletions(-) diff --git a/lib/models/contacts/contact_model.dart b/lib/models/contacts/contact_model.dart index aa71aac7..537b665d 100644 --- a/lib/models/contacts/contact_model.dart +++ b/lib/models/contacts/contact_model.dart @@ -6,15 +6,13 @@ part 'contact_model.g.dart'; @JsonSerializable(explicitToJson: true) class ContactModel { @JsonKey(defaultValue: "Untitled") - late String name; + late String sectionName; @JsonKey(defaultValue: []) late List contacts; - @JsonKey(defaultValue: "") - late String group; //Constructor ContactModel( - {required this.name, required this.contacts, required this.group}); + {required this.sectionName, required this.contacts}); factory ContactModel.fromJson(Map json) => _$ContactModelFromJson(json); @@ -22,7 +20,7 @@ class ContactModel { Map toJson() => _$ContactModelToJson(this); //This constructor also does the work of initialising the variables // ContactModel.fromJson(Map json) { - // name = json['name']; + // sectionName = json['sectionName']; // parent = 'Campus'; // contacts = []; // List.from(json['contacts']).forEach((element) { diff --git a/lib/models/contacts/contact_model.g.dart b/lib/models/contacts/contact_model.g.dart index 5e910cba..708d4bf1 100644 --- a/lib/models/contacts/contact_model.g.dart +++ b/lib/models/contacts/contact_model.g.dart @@ -7,18 +7,16 @@ part of 'contact_model.dart'; // ************************************************************************** ContactModel _$ContactModelFromJson(Map json) => ContactModel( - name: json['name'] as String? ?? 'Untitled', + sectionName: json['sectionName'] as String? ?? 'Untitled', contacts: (json['contacts'] as List?) ?.map((e) => ContactDetailsModel.fromJson(e as Map)) .toList() ?? [], - group: json['group'] as String? ?? '', ); Map _$ContactModelToJson(ContactModel instance) => { - 'name': instance.name, + 'sectionName': instance.sectionName, 'contacts': instance.contacts.map((e) => e.toJson()).toList(), - 'group': instance.group, }; diff --git a/lib/models/food/dish_model.dart b/lib/models/food/dish_model.dart index b1d4ae82..b8cae8ca 100644 --- a/lib/models/food/dish_model.dart +++ b/lib/models/food/dish_model.dart @@ -6,28 +6,15 @@ part 'dish_model.g.dart'; @JsonSerializable() class DishModel { @JsonKey(defaultValue: "Unnamed") - late String name; - @JsonKey(defaultValue: false) - late bool veg; - @JsonKey( - defaultValue: " ", - fromJson: ingredientsFromJson, - toJson: ingredientsToJson) - late String ingredients; + late String itemName; @JsonKey(defaultValue: 2) - late int waiting_time; - @JsonKey(defaultValue: 150) late int price; - - String image; + String imageURL; DishModel( - {required this.name, - required this.veg, - required this.ingredients, - required this.waiting_time, + {required this.itemName, required this.price, - this.image = + this.imageURL = "https://d4t7t8y8xqo0t.cloudfront.net/resized/750X436/eazytrendz%2F3070%2Ftrend20210218124824.jpg"}); factory DishModel.fromJson(Map json) => @@ -42,13 +29,4 @@ class DishModel { // waiting_time = json['waiting_time'] ?? "Not Known"; // price = json['price'] ?? "Not Known"; // } -} - -String ingredientsFromJson(List ing) { - return ing.toString(); -} - -List ingredientsToJson(String ing) { - ing = ing.substring(1, ing.length - 1); - return ing.split(',').toList(); -} +} \ No newline at end of file diff --git a/lib/models/food/dish_model.g.dart b/lib/models/food/dish_model.g.dart index 252ae72d..c4047200 100644 --- a/lib/models/food/dish_model.g.dart +++ b/lib/models/food/dish_model.g.dart @@ -7,22 +7,14 @@ part of 'dish_model.dart'; // ************************************************************************** DishModel _$DishModelFromJson(Map json) => DishModel( - name: json['name'] as String? ?? 'Unnamed', - veg: json['veg'] as bool? ?? false, - ingredients: json['ingredients'] == null - ? ' ' - : ingredientsFromJson(json['ingredients'] as List), - waiting_time: json['waiting_time'] as int? ?? 2, - price: json['price'] as int? ?? 150, - image: json['image'] as String? ?? + itemName: json['itemName'] as String? ?? 'Unnamed', + price: json['price'] as int? ?? 2, + imageURL: json['imageURL'] as String? ?? "https://d4t7t8y8xqo0t.cloudfront.net/resized/750X436/eazytrendz%2F3070%2Ftrend20210218124824.jpg", ); Map _$DishModelToJson(DishModel instance) => { - 'name': instance.name, - 'veg': instance.veg, - 'ingredients': ingredientsToJson(instance.ingredients), - 'waiting_time': instance.waiting_time, + 'itemName': instance.itemName, 'price': instance.price, - 'image': instance.image, + 'imageURL': instance.imageURL, }; diff --git a/lib/models/food/restaurant_model.dart b/lib/models/food/restaurant_model.dart index e2869697..70f53e1c 100644 --- a/lib/models/food/restaurant_model.dart +++ b/lib/models/food/restaurant_model.dart @@ -8,19 +8,19 @@ part 'restaurant_model.g.dart'; @JsonSerializable(explicitToJson: true) class RestaurantModel { @JsonKey(defaultValue: "Untitled Restaurant") - late String name; + late String outletName; @JsonKey(defaultValue: " ") late String caption; @JsonKey(defaultValue: "10:00 PM") - late String closing_time; + late String closingTime; - @JsonKey(defaultValue: "2 hrs") - late String waiting_time; + @JsonKey(defaultValue: "IIT Guwahati") + late String location; @JsonKey(defaultValue: " ", fromJson: fromJsonPhone, toJson: toJsonPhone) - late String phone_number; + late String phoneNumber; @JsonKey(defaultValue: 26.19247153449412) late double latitude; @@ -28,29 +28,25 @@ class RestaurantModel { @JsonKey(defaultValue: 91.6993500129393) late double longitude; - @JsonKey(defaultValue: " ") - late String address; - @JsonKey(defaultValue: []) late List tags; @JsonKey(defaultValue: []) late List menu; - @JsonKey(name: "imageURL") - late String image; + @JsonKey(defaultValue: "https://dw7n6pv5zdng0.cloudfront.net/modules/0001/04/thumb_3251_modules_big.jpeg") + late String imageURL; RestaurantModel( - {required this.name, + {required this.outletName, required this.caption, - required this.closing_time, - required this.waiting_time, - required this.phone_number, + required this.closingTime, + required this.phoneNumber, required this.latitude, required this.longitude, - required this.address, + required this.location, required this.tags, - required this.image}); + required this.imageURL}); // RestaurantModel.fromJson(Map json) { // name = json['name'] ?? "Unnamed";= "https://live.staticflickr.com/3281/5813689894_a558bb341f_b.jpg" diff --git a/lib/models/food/restaurant_model.g.dart b/lib/models/food/restaurant_model.g.dart index fded6ec6..51c0f233 100644 --- a/lib/models/food/restaurant_model.g.dart +++ b/lib/models/food/restaurant_model.g.dart @@ -8,20 +8,20 @@ part of 'restaurant_model.dart'; RestaurantModel _$RestaurantModelFromJson(Map json) => RestaurantModel( - name: json['name'] as String? ?? 'Untitled Restaurant', + outletName: json['outletName'] as String? ?? 'Untitled Restaurant', caption: json['caption'] as String? ?? ' ', - closing_time: json['closing_time'] as String? ?? '10:00 PM', - waiting_time: json['waiting_time'] as String? ?? '2 hrs', - phone_number: json['phone_number'] == null + closingTime: json['closingTime'] as String? ?? '10:00 PM', + phoneNumber: json['phoneNumber'] == null ? ' ' - : fromJsonPhone(json['phone_number'] as int), + : fromJsonPhone(json['phoneNumber'] as int), latitude: (json['latitude'] as num?)?.toDouble() ?? 26.19247153449412, longitude: (json['longitude'] as num?)?.toDouble() ?? 91.6993500129393, - address: json['address'] as String? ?? ' ', + location: json['location'] as String? ?? 'IIT Guwahati', tags: (json['tags'] as List?)?.map((e) => e as String).toList() ?? [], - image: json['imageURL'] as String, + imageURL: json['imageURL'] as String? ?? + 'https://dw7n6pv5zdng0.cloudfront.net/modules/0001/04/thumb_3251_modules_big.jpeg', )..menu = (json['menu'] as List?) ?.map((e) => DishModel.fromJson(e as Map)) .toList() ?? @@ -29,15 +29,14 @@ RestaurantModel _$RestaurantModelFromJson(Map json) => Map _$RestaurantModelToJson(RestaurantModel instance) => { - 'name': instance.name, + 'outletName': instance.outletName, 'caption': instance.caption, - 'closing_time': instance.closing_time, - 'waiting_time': instance.waiting_time, - 'phone_number': toJsonPhone(instance.phone_number), + 'closingTime': instance.closingTime, + 'location': instance.location, + 'phoneNumber': toJsonPhone(instance.phoneNumber), 'latitude': instance.latitude, 'longitude': instance.longitude, - 'address': instance.address, 'tags': instance.tags, 'menu': instance.menu.map((e) => e.toJson()).toList(), - 'imageURL': instance.image, + 'imageURL': instance.imageURL, }; diff --git a/lib/models/travel/day_type_model.dart b/lib/models/travel/day_type_model.dart index 235a162a..ca40f4af 100644 --- a/lib/models/travel/day_type_model.dart +++ b/lib/models/travel/day_type_model.dart @@ -8,7 +8,7 @@ part 'day_type_model.g.dart'; class DayType { final List fromCampus; final List toCampus; - DayType( + const DayType( { required this.fromCampus, required this.toCampus, diff --git a/lib/models/travel/travel_timing_model.dart b/lib/models/travel/travel_timing_model.dart index aed06f7d..84447297 100644 --- a/lib/models/travel/travel_timing_model.dart +++ b/lib/models/travel/travel_timing_model.dart @@ -12,9 +12,7 @@ class TravelTiming { final String type; @JsonKey(defaultValue: '') final String stop; - @JsonKey(defaultValue: []) final DayType weekend; - @JsonKey(defaultValue: []) final DayType weekdays; diff --git a/lib/models/travel/travel_timing_model.g.dart b/lib/models/travel/travel_timing_model.g.dart index c93183ec..0ec3fcb3 100644 --- a/lib/models/travel/travel_timing_model.g.dart +++ b/lib/models/travel/travel_timing_model.g.dart @@ -10,15 +10,15 @@ TravelTiming _$TravelTimingFromJson(Map json) => TravelTiming( type: json['type'] as String? ?? '', id: json['_id'] as String, stop: json['stop'] as String? ?? '', - weekend: DayType.fromJson(json['weekend'] as Map), - weekdays:DayType.fromJson(json['weekdays'] as Map), -); + weekend: DayType.fromJson(json['weekend'] as Map), + weekdays: DayType.fromJson(json['weekdays'] as Map), + ); Map _$TravelTimingToJson(TravelTiming instance) => { - '_id': instance.id, - 'type': instance.type, - 'stop': instance.stop, - 'weekend': instance.weekend, - 'weekdays': instance.weekdays, - }; \ No newline at end of file + '_id': instance.id, + 'type': instance.type, + 'stop': instance.stop, + 'weekend': instance.weekend, + 'weekdays': instance.weekdays, + }; diff --git a/lib/pages/contact/contact.dart b/lib/pages/contact/contact.dart index 01ea0264..5ea38e57 100644 --- a/lib/pages/contact/contact.dart +++ b/lib/pages/contact/contact.dart @@ -154,7 +154,7 @@ class _ContactPageState extends State { }); for (var e in alphabets) { people["$e ADONOTUSE"] = ContactModel( - name: "Random", contacts: [], group: ""); + sectionName: "Random", contacts: []); } return AlphabetScrollView( list: people.keys.map((e) => AlphaModel(e)).toList(), diff --git a/lib/pages/contact/contact_detail.dart b/lib/pages/contact/contact_detail.dart index 0fde93f0..2c60dc89 100644 --- a/lib/pages/contact/contact_detail.dart +++ b/lib/pages/contact/contact_detail.dart @@ -51,18 +51,18 @@ class _ContactDetailsPageState extends State { Padding( padding: const EdgeInsets.only(left: 8.0), child: Text( - widget.contact!.name, + widget.contact!.sectionName, style: MyFonts.w600.size(16).setColor(kWhite), ), ), - const Expanded(child: SizedBox()), - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: Text( - widget.contact!.group, - style: MyFonts.w400.size(14).setColor(kGrey2), - ), - ) + // const Expanded(child: SizedBox()), + // Padding( + // padding: const EdgeInsets.only(right: 8.0), + // child: Text( + // widget.contact!.group, + // style: MyFonts.w400.size(14).setColor(kGrey2), + // ), + // ) ], ), Row( diff --git a/lib/services/data_provider.dart b/lib/services/data_provider.dart index 60c69e7e..872dd50a 100644 --- a/lib/services/data_provider.dart +++ b/lib/services/data_provider.dart @@ -43,9 +43,10 @@ class DataProvider { var cachedData = await LocalStorage.instance.getRecord(DatabaseRecords.restaurant); if (cachedData == null) { + print("INSIDE RESTRAURENTS GET"); List> restaurantData = await APIService().getRestaurantData(); - + print(restaurantData); List restaurants = restaurantData.map((e) => RestaurantModel.fromJson(e)).toList(); @@ -53,7 +54,6 @@ class DataProvider { return restaurants; } - return cachedData .map((e) => RestaurantModel.fromJson(e as Map)) .toList(); @@ -85,21 +85,24 @@ class DataProvider { static Future> getContacts() async { var cachedData = await LocalStorage.instance.getRecord(DatabaseRecords.contacts); SplayTreeMap people = SplayTreeMap(); - if (cachedData == null) { - List> contactData = - await APIService().getContactData(); + List> contactData = await APIService().getContactData(); + print("GET CONTACT DATA"); + print(contactData); for (var element in contactData) { - people[element['name']] = ContactModel.fromJson(element); + people[element['sectionName']] = ContactModel.fromJson(element); + print("HERE NFJ"); } await LocalStorage.instance.storeData(contactData, DatabaseRecords.contacts); return people; } - for (var element in cachedData) { - var x = element as Map; - people[x['name']] = ContactModel.fromJson(x); + else { + for (var element in cachedData) { + var x = element as Map; + people[x['name']] = ContactModel.fromJson(x); + } + return people; } - return people; } diff --git a/lib/stores/restaurant_store.dart b/lib/stores/restaurant_store.dart index e065281b..da9ea05f 100644 --- a/lib/stores/restaurant_store.dart +++ b/lib/stores/restaurant_store.dart @@ -10,16 +10,15 @@ class RestaurantStore = _RestaurantStore with _$RestaurantStore; abstract class _RestaurantStore with Store { RestaurantModel _selectedRestaurant = RestaurantModel( - name: "NA", + outletName: "NA", caption: "NA", - closing_time: "NA", - waiting_time: "NA", - phone_number: "NA", + closingTime: "NA", + phoneNumber: "NA", latitude: 0, longitude: 0, - address: "NA", + location: "NA", tags: [], - image: ""); + imageURL: ""); @observable String _searchString = ""; @@ -59,7 +58,7 @@ abstract class _RestaurantStore with Store { for (var element in allRestaurants) { List searchFields = element.tags; for (var dish in element.menu) { - searchFields.add(dish.name); + searchFields.add(dish.itemName); } final fuse = Fuzzy( searchFields, diff --git a/lib/widgets/contact/contact_page_button.dart b/lib/widgets/contact/contact_page_button.dart index 832bea10..3614e8ca 100644 --- a/lib/widgets/contact/contact_page_button.dart +++ b/lib/widgets/contact/contact_page_button.dart @@ -47,11 +47,14 @@ class _ContactPageButtonState extends State { flex: 106, child: GestureDetector( onTap: () { - var contact = people['Gymkhana']; - if (widget.label == "Emergency") { - contact = people['Emergency']; - } else if (widget.label == 'Transport') { - contact = people['Transport']; + ContactModel contact = ContactModel(sectionName: widget.label, contacts: []); //case when section is not in db + if(widget.label=="Gymkhana" && people['Gymkhana']!=null){ + contact=people['Gymkhana']!; + } + else if (widget.label == "Emergency" && people['Emergency']!=null) { + contact = people['Emergency']!; + } else if (widget.label == 'Transport' && people['Transport']!=null) { + contact = people['Transport']!; } Navigator.push(context, MaterialPageRoute(builder: (context) { return Provider.value( diff --git a/lib/widgets/food/restaurant/food_tile.dart b/lib/widgets/food/restaurant/food_tile.dart index 6594d925..09580af3 100644 --- a/lib/widgets/food/restaurant/food_tile.dart +++ b/lib/widgets/food/restaurant/food_tile.dart @@ -47,42 +47,42 @@ class FoodTile extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - Row( - children: [ - Expanded( - flex: 4, - child: Text( - dish.name, - style: MyFonts.w600.size(16).setColor(kWhite), - ), - ), - Expanded( - flex: 1, - child: Stack( - alignment: Alignment.center, - children: [ - Icon( - Icons.crop_square_sharp, - color: getIconColor(dish.veg), - size: 14, - ), - Icon( - Icons.circle, - color: getIconColor(dish.veg), - size: 5, - ), - ], - ), - ), - ], + Text( + dish.itemName, + style: MyFonts.w600.size(16).setColor(kWhite), ), + // Row( + // children: [ + // Expanded( + // flex: 4, + // child: Text( + // dish.itemName, + // style: MyFonts.w600.size(16).setColor(kWhite), + // ), + // ), + // Expanded( + // flex: 1, + // child: Stack( + // alignment: Alignment.center, + // children: [ + // Icon( + // Icons.crop_square_sharp, + // color: getIconColor(dish.veg), + // size: 14, + // ), + // Icon( + // Icons.circle, + // color: getIconColor(dish.veg), + // size: 5, + // ), + // ], + // ), + // ), + // ], + // ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - getIngredients(dish.ingredients), - style: MyFonts.w400.size(14).setColor(kGrey6), - ), const SizedBox( height: 8, ), @@ -106,7 +106,7 @@ class FoodTile extends StatelessWidget { aspectRatio: 1, child: CachedNetworkImage( maxHeightDiskCache: 200, - imageUrl: dish.image, + imageUrl: dish.imageURL, imageBuilder: (context, imageProvider) => Image( image: imageProvider, fit: BoxFit.cover, diff --git a/lib/widgets/food/restaurant/restaurant_header.dart b/lib/widgets/food/restaurant/restaurant_header.dart index 2ab4fecf..d314c789 100644 --- a/lib/widgets/food/restaurant/restaurant_header.dart +++ b/lib/widgets/food/restaurant/restaurant_header.dart @@ -29,7 +29,7 @@ class RestaurantHeader extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - restaurant.name, + restaurant.outletName, style: MyFonts.w600.size(22).setColor(kWhite), ), Text( @@ -40,7 +40,7 @@ class RestaurantHeader extends StatelessWidget { padding: const EdgeInsets.only(top: 10.0, bottom: 8.0), child: RichText( text: TextSpan( - text: restaurant.address, + text: restaurant.location, style: MyFonts.w500.size(13).setColor(kGrey), children: [ TextSpan( @@ -68,10 +68,6 @@ class RestaurantHeader extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ - Text( - 'Waiting time: ${restaurant.waiting_time}', - style: MyFonts.w300.size(12).setColor(kWhite), - ), const Padding( padding: EdgeInsets.symmetric(horizontal: 5.0), child: Icon(FluentIcons.circle_12_filled, @@ -86,7 +82,7 @@ class RestaurantHeader extends StatelessWidget { width: 4, ), Text( - 'Closing time: ${restaurant.closing_time}', + 'Closing time: ${restaurant.closingTime}', style: MyFonts.w300.size(12).setColor(lRed2), ), ], @@ -112,7 +108,7 @@ class RestaurantHeader extends StatelessWidget { callMap: 'Call', icon: FluentIcons.call_24_regular, callback: () { - launchPhoneURL(restaurant.phone_number); + launchPhoneURL(restaurant.phoneNumber); }, ), ), @@ -126,7 +122,7 @@ class RestaurantHeader extends StatelessWidget { icon: FluentIcons.location_24_regular, callback: () { openMap(restaurant.latitude, restaurant.longitude, - context, restaurant.name); + context, restaurant.outletName); }, ), ), diff --git a/lib/widgets/food/restaurant/restaurant_tile.dart b/lib/widgets/food/restaurant/restaurant_tile.dart index 6d9289c9..17418bc3 100644 --- a/lib/widgets/food/restaurant/restaurant_tile.dart +++ b/lib/widgets/food/restaurant/restaurant_tile.dart @@ -22,6 +22,7 @@ class RestaurantTile extends StatelessWidget { @override Widget build(BuildContext context) { + print(restaurantModel.imageURL); return TextButton( onPressed: () { context.read().setSelectedRestaurant(restaurantModel); @@ -50,7 +51,7 @@ class RestaurantTile extends StatelessWidget { aspectRatio: 1, child: CachedNetworkImage( maxHeightDiskCache: 200, - imageUrl: restaurantModel.image, + imageUrl: restaurantModel.imageURL, imageBuilder: (context, imageProvider) => Image( image: imageProvider, fit: BoxFit.cover, @@ -71,7 +72,7 @@ class RestaurantTile extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - restaurantModel.name, + restaurantModel.outletName, textAlign: TextAlign.left, style: MyFonts.w600.size(16).setColor(kWhite), ), @@ -83,14 +84,7 @@ class RestaurantTile extends StatelessWidget { height: 8, ), Text( - 'Waiting time: ${restaurantModel.waiting_time}', - style: MyFonts.w500.size(11).setColor(kTabText), - ), - const SizedBox( - height: 1, - ), - Text( - 'Closes at ${restaurantModel.closing_time}', + 'Closes at ${restaurantModel.closingTime}', style: MyFonts.w500.size(11).setColor(lRed2), ), const SizedBox( @@ -102,7 +96,7 @@ class RestaurantTile extends StatelessWidget { callMap: 'Call', icon: FluentIcons.call_20_regular, callback: () { - launchPhoneURL(restaurantModel.phone_number); + launchPhoneURL(restaurantModel.phoneNumber); }, ), const SizedBox( @@ -116,13 +110,14 @@ class RestaurantTile extends StatelessWidget { restaurantModel.latitude, restaurantModel.longitude, context, - restaurantModel.name); + restaurantModel.outletName); }, ), Expanded(child: Container()), Text( getRestaurantDistance(context, restaurantModel), style: MyFonts.w500.size(11).setColor(kWhite), + overflow:TextOverflow.fade ), Expanded(child: Container()), ], From 68023e0dc2c67a4ed9f269ba544e5d6c77ca5e0b Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Wed, 28 Jun 2023 23:22:09 +0530 Subject: [PATCH 66/82] fixed overflow --- lib/widgets/food/mess/mess_menu.dart | 9 +++++---- lib/widgets/food/restaurant/restaurant_tile.dart | 13 +++++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/widgets/food/mess/mess_menu.dart b/lib/widgets/food/mess/mess_menu.dart index 4a701fe0..d769a71d 100644 --- a/lib/widgets/food/mess/mess_menu.dart +++ b/lib/widgets/food/mess/mess_menu.dart @@ -126,13 +126,13 @@ class MessMenu extends StatelessWidget { Text(messStore.selectedDay.substring(0,3), style: MyFonts.w500 .setColor(lBlue) - .size(screenWidth <= 380 + .size(screenWidth <= 390 ? 10 : 13)), Icon( FluentIcons.chevron_down_24_regular, color: lBlue, - size: screenWidth <= 380 ? 15 : 20, + size: screenWidth <= 390 ? 15 : 20, ), ], ), @@ -177,15 +177,16 @@ class MessMenu extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Text(messStore.selectedHostel.value!, + overflow: TextOverflow.fade, style: MyFonts.w500 .setColor(lBlue) - .size(screenWidth <= 380 + .size(screenWidth <= 390 ? 10 : 13)), Icon( FluentIcons.chevron_down_24_regular, color: lBlue, - size: screenWidth <= 380 ? 15 : 20, + size: screenWidth <= 390 ? 15 : 20, ), ], ), diff --git a/lib/widgets/food/restaurant/restaurant_tile.dart b/lib/widgets/food/restaurant/restaurant_tile.dart index 17418bc3..328dc5c1 100644 --- a/lib/widgets/food/restaurant/restaurant_tile.dart +++ b/lib/widgets/food/restaurant/restaurant_tile.dart @@ -7,6 +7,7 @@ import 'package:onestop_dev/functions/utility/open_map.dart'; import 'package:onestop_dev/functions/utility/phone_email.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; +import 'package:onestop_dev/globals/size_config.dart'; import 'package:onestop_dev/models/food/restaurant_model.dart'; import 'package:onestop_dev/pages/food/restaurant_page.dart'; import 'package:onestop_dev/stores/restaurant_store.dart'; @@ -114,10 +115,14 @@ class RestaurantTile extends StatelessWidget { }, ), Expanded(child: Container()), - Text( - getRestaurantDistance(context, restaurantModel), - style: MyFonts.w500.size(11).setColor(kWhite), - overflow:TextOverflow.fade + ConstrainedBox( + constraints: BoxConstraints(maxWidth: SizeConfig.screenWidth!<=380? 55:70), + child: Text( + getRestaurantDistance(context, restaurantModel), + textAlign: TextAlign.center, + style: MyFonts.w500.size(11).setColor(kWhite), + overflow:TextOverflow.fade + ), ), Expanded(child: Container()), ], From 713bc1b5017cfa0ad25fa6a4a821319317509af3 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Thu, 29 Jun 2023 01:02:54 +0530 Subject: [PATCH 67/82] fixed feedback and tt api --- lib/globals/endpoints.dart | 2 +- lib/pages/timetable/timetable.dart | 2 +- lib/services/api.dart | 13 +++++++++++-- lib/services/data_provider.dart | 1 + lib/widgets/profile/feedback.dart | 1 + 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/globals/endpoints.dart b/lib/globals/endpoints.dart index 04c502f1..3064e72b 100644 --- a/lib/globals/endpoints.dart +++ b/lib/globals/endpoints.dart @@ -7,7 +7,7 @@ class Endpoints { static const String restaurantURL = "/getAllOutlets"; static const String lastUpdatedURL = "/lastDataUpdate"; static const String contactURL = "/getContacts"; - static const String timetableURL = "/smartTimetable/get-my-courses"; + static const String timetableURL = "https://swc.iitg.ac.in/smartTimetable/get-my-courses"; static const String ferryURL = '/ferryTimings'; static const String busURL = '/busTimings'; static const String busStops = '/busstops'; diff --git a/lib/pages/timetable/timetable.dart b/lib/pages/timetable/timetable.dart index 77466cab..e9c0c98b 100644 --- a/lib/pages/timetable/timetable.dart +++ b/lib/pages/timetable/timetable.dart @@ -9,7 +9,7 @@ import 'package:provider/provider.dart'; import 'package:onestop_dev/widgets/ui/guest_restrict.dart'; class TimeTableTab extends StatefulWidget { - static const String id = 'time'; + static const String id = '/time'; const TimeTableTab({Key? key}) : super(key: key); @override State createState() => _TimeTableTabState(); diff --git a/lib/services/api.dart b/lib/services/api.dart index 420b5bf4..822fa493 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -28,6 +28,12 @@ class APIService { receiveTimeout: const Duration(seconds: 15), headers: Endpoints.getHeader())); +final dio2 = Dio(BaseOptions( + connectTimeout: const Duration(seconds: 15), + receiveTimeout: const Duration(seconds: 15), + headers: Endpoints.getHeader())); + + APIService() { dio.interceptors @@ -114,8 +120,9 @@ class APIService { String tag = data['type'] == 'Issue Report' ? 'bug' : 'enhancement'; String newBody = "### Description :\n${data['body']}\n### Posted By :\n${data['user']}"; + print(Endpoints.githubIssueToken); - var res = await dio.post(Endpoints.feedback, + var res = await dio2.post(Endpoints.feedback, data: { 'title': data['title'], 'body': newBody, @@ -478,11 +485,13 @@ class APIService { } Future getTimeTable({required String roll}) async { - final response = await dio.post(Endpoints.timetableURL, + print(roll); + final response = await dio2.post(Endpoints.timetableURL, data: { "roll_number": roll, }, ); + print(response); if (response.statusCode == 200) { return RegisteredCourses.fromJson(response.data); } else { diff --git a/lib/services/data_provider.dart b/lib/services/data_provider.dart index 872dd50a..0d4dff2e 100644 --- a/lib/services/data_provider.dart +++ b/lib/services/data_provider.dart @@ -68,6 +68,7 @@ class DataProvider { static Future getTimeTable({required String roll}) async { var cachedData = (await LocalStorage.instance.getRecord(DatabaseRecords.timetable))?[0]; if (cachedData == null) { + print(roll); RegisteredCourses timetableData = await APIService().getTimeTable(roll: roll); await LocalStorage.instance diff --git a/lib/widgets/profile/feedback.dart b/lib/widgets/profile/feedback.dart index 442886c8..a147a79a 100644 --- a/lib/widgets/profile/feedback.dart +++ b/lib/widgets/profile/feedback.dart @@ -185,6 +185,7 @@ class _FeedBackState extends State { onTap: !enableSubmitButton ? null : () async { + print("inside feedback submit"); bool isValid = formKey.currentState!.validate(); if (!isValid) { return; From a0ffa0d61377bc8125a2dd8f759eccc6c21e48c2 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Thu, 29 Jun 2023 03:15:55 +0530 Subject: [PATCH 68/82] fixed time table --- lib/stores/timetable_store.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/stores/timetable_store.dart b/lib/stores/timetable_store.dart index 94aed2c7..7cc68330 100644 --- a/lib/stores/timetable_store.dart +++ b/lib/stores/timetable_store.dart @@ -449,8 +449,8 @@ abstract class _TimetableStore with Store { } } } - timetableCourses[i].morning.sort(); - timetableCourses[i].afternoon.sort(); + timetableCourses[i].morning.sort(((a, b) => a.timing.compareTo(b.timing))); + timetableCourses[i].afternoon.sort((a,b)=> a.timing.compareTo(b.timing)); } allTimetableCourses = timetableCourses; } From 305f98b3a14342532f8a05a2a124962a599bcd1f Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Thu, 29 Jun 2023 03:38:33 +0530 Subject: [PATCH 69/82] sem end date update --- lib/services/data_provider.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/data_provider.dart b/lib/services/data_provider.dart index 0d4dff2e..96afb184 100644 --- a/lib/services/data_provider.dart +++ b/lib/services/data_provider.dart @@ -76,7 +76,7 @@ class DataProvider { return timetableData; } // TODO: Change this later, for now cache till the end of Monsoon sem - DateTime semEnd = DateTime.parse("2022-12-23"); + DateTime semEnd = DateTime.parse("2023-12-23"); if (DateTime.now().isBefore(semEnd)) { return RegisteredCourses.fromJson(cachedData as Map); } From 17b3bb7a7bbf5ae3d6d2fa6dbcdb93b81d43fdbe Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Thu, 29 Jun 2023 18:27:36 +0530 Subject: [PATCH 70/82] validator for roll number --- lib/pages/profile/edit_profile.dart | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/pages/profile/edit_profile.dart b/lib/pages/profile/edit_profile.dart index 06bc1c49..42fa8cbc 100644 --- a/lib/pages/profile/edit_profile.dart +++ b/lib/pages/profile/edit_profile.dart @@ -303,9 +303,17 @@ class _EditProfileState extends State { ), CustomTextField( hintText: 'Roll Number', - // validator: validatefield, + validator: (String? value) { + if (value == null || value.isEmpty) { + return 'Field cannot be empty'; + } + else if(value.length!=9){ + return 'Enter valid roll number'; + } + return null; + }, inputFormatters: [FilteringTextInputFormatter.digitsOnly,], - isNecessary: false, + isNecessary: true, controller: _rollController, maxLength: 9, maxLines: 1, From 2e7fd511595a0f6db090ed0c3c824c05ce6a9a15 Mon Sep 17 00:00:00 2001 From: Hareesh nandigrama <85237630+Hareesh-Nandigrama@users.noreply.github.com> Date: Thu, 29 Jun 2023 23:12:23 +0530 Subject: [PATCH 71/82] updated timetable store --- lib/stores/timetable_store.dart | 275 +++++++++++++++++-------- lib/stores/timetable_store.g.dart | 34 +-- lib/widgets/timetable/date_slider.dart | 1 - 3 files changed, 201 insertions(+), 109 deletions(-) diff --git a/lib/stores/timetable_store.dart b/lib/stores/timetable_store.dart index 7cc68330..5cddf623 100644 --- a/lib/stores/timetable_store.dart +++ b/lib/stores/timetable_store.dart @@ -22,6 +22,18 @@ abstract class _TimetableStore with Store { initialiseDates(); } + void setupReactions() { + autorun((_) { + if (loadOperation.value != null) { + processTimetable(); + } + }); + } + + //List of dates to show in the date slider + List dates = List.filled(5, DateTime.now()); + + //Initialising the dates void initialiseDates() { dates = List.filled(5, DateTime.now()); if (dates[0].weekday == 6 || dates[0].weekday == 7) { @@ -37,15 +49,7 @@ abstract class _TimetableStore with Store { } } - List dates = List.filled(5, DateTime.now()); - - List allTimetableCourses = - List.generate(5, (index) => TimetableDay()); - - @observable - ObservableFuture loadOperation = - ObservableFuture.value(null); - + //index of date slider item @observable int selectedDate = 0; @@ -54,17 +58,10 @@ abstract class _TimetableStore with Store { selectedDate = i; } + //Dropdown state of tt on home @observable bool showDropDown = false; - @action - Future setTimetable(String rollNumber,BuildContext context) async { - if (loadOperation.value == null) { - loadOperation = - DataProvider.getTimeTable(roll: rollNumber).asObservable(); - } - } - @action void toggleDropDown() { showDropDown = !showDropDown; @@ -75,6 +72,64 @@ abstract class _TimetableStore with Store { showDropDown = b; } + List get homeTimeTable { + DateTime current = DateTime.now(); + if (current.weekday == 6 || current.weekday == 7) { + CourseModel noClass = CourseModel(); + noClass.instructor = ''; + noClass.course = 'Happy Weekend !'; + noClass.timing = ''; + return List.filled(1, TimetableTile(course: noClass)); + } + current = dates[0]; + DateFormat dateFormat = DateFormat("hh:00 - hh:55 a"); + List l = [ + ...allTimetableCourses[current.weekday - 1] + .morning + .where((e) => dateFormat.parse(e.timing).hour >= DateTime.now().hour) + .toList() + .map((e) => TimetableTile( + course: e, + inHomePage: true, + )) + .toList(), + ...allTimetableCourses[current.weekday - 1] + .afternoon + .where((e) => dateFormat.parse(e.timing).hour >= DateTime.now().hour) + .toList() + .map((e) => TimetableTile( + course: e, + inHomePage: true, + )) + .toList() + ]; + if (l.isEmpty) { + CourseModel noClass = CourseModel(); + noClass.instructor = ''; + noClass.course = 'No upcoming classes'; + noClass.timing = ''; + l.add(TimetableTile(course: noClass)); + } + return l; + } + + //List of time table of each day of the week + List allTimetableCourses = List.generate(5, (index) => TimetableDay()); + + + + @observable + ObservableFuture loadOperation = ObservableFuture.value(null); + + @action + Future setTimetable(String rollNumber,BuildContext context) async { + if (loadOperation.value == null) { + loadOperation = + DataProvider.getTimeTable(roll: rollNumber).asObservable(); + } + } + + @computed bool get coursesLoaded => loadOperation.value != null; @@ -115,58 +170,13 @@ abstract class _TimetableStore with Store { return l; } - List get homeTimeTable { - DateTime current = DateTime.now(); - if (current.weekday == 6 || current.weekday == 7) { - CourseModel noClass = CourseModel(); - noClass.instructor = ''; - noClass.course = 'Happy Weekend !'; - noClass.timing = ''; - return List.filled(1, TimetableTile(course: noClass)); - } - current = dates[0]; - DateFormat dateFormat = DateFormat("hh:00 - hh:55 a"); - List l = [ - ...allTimetableCourses[current.weekday - 1] - .morning - .where((e) => dateFormat.parse(e.timing).hour >= DateTime.now().hour) - .toList() - .map((e) => TimetableTile( - course: e, - inHomePage: true, - )) - .toList(), - ...allTimetableCourses[current.weekday - 1] - .afternoon - .where((e) => dateFormat.parse(e.timing).hour >= DateTime.now().hour) - .toList() - .map((e) => TimetableTile( - course: e, - inHomePage: true, - )) - .toList() - ]; - if (l.isEmpty) { - CourseModel noClass = CourseModel(); - noClass.instructor = ''; - noClass.course = 'No upcoming classes'; - noClass.timing = ''; - l.add(TimetableTile(course: noClass)); - } - return l; - } + void processTimetable() { - void setupReactions() { - autorun((_) { - if (loadOperation.value != null) { - processTimetable(); - } - }); - } + //A list of timetable of each day, with index 0 to 4 signifying mon to fri + List timetableCourses = List.generate(5, (index) => TimetableDay()); + + //Lets fill the above now - void processTimetable() { - List timetableCourses = - List.generate(5, (index) => TimetableDay()); var courseList = loadOperation.value!; for (int i = 0; i <= 4; i++) { for (var v in courseList.courses!) { @@ -175,53 +185,95 @@ abstract class _TimetableStore with Store { if (slot == 'A') { switch (i) { case 0: + copyCourse.timing = '08:00 - 08:55 AM'; + timetableCourses[i].addMorning(copyCourse); + break; case 1: - case 2: copyCourse.timing = '09:00 - 09:55 AM'; timetableCourses[i].addMorning(copyCourse); break; + case 2: + copyCourse.timing = '10:00 - 10:55 AM'; + timetableCourses[i].addMorning(copyCourse); + break; + case 3: + copyCourse.timing = '11:00 - 11:55 AM'; + timetableCourses[i].addMorning(copyCourse); + break; } } if (slot == 'B') { switch (i) { - case 3: - case 4: + case 0: copyCourse.timing = '09:00 - 09:55 AM'; timetableCourses[i].addMorning(copyCourse); break; - case 0: + case 1: copyCourse.timing = '10:00 - 10:55 AM'; timetableCourses[i].addMorning(copyCourse); break; + case 2: + copyCourse.timing = '11:00 - 11:55 AM'; + timetableCourses[i].addMorning(copyCourse); + break; + case 4: + copyCourse.timing = '08:00 - 08:55 AM'; + timetableCourses[i].addMorning(copyCourse); + break; } } if (slot == 'C') { switch (i) { + case 4: + copyCourse.timing = '09:00 - 09:55 AM'; + timetableCourses[i].addMorning(copyCourse); + break; + case 0: + copyCourse.timing = '10:00 - 10:55 AM'; + timetableCourses[i].addMorning(copyCourse); + break; case 1: - case 2: + copyCourse.timing = '11:00 - 11:55 AM'; + timetableCourses[i].addMorning(copyCourse); + break; case 3: - copyCourse.timing = '10:00 - 10:55 AM'; + copyCourse.timing = '08:00 - 08:55 AM'; timetableCourses[i].addMorning(copyCourse); break; } } if (slot == 'D') { switch (i) { + case 3: + copyCourse.timing = '09:00 - 09:55 AM'; + timetableCourses[i].addMorning(copyCourse); + break; case 4: copyCourse.timing = '10:00 - 10:55 AM'; timetableCourses[i].addMorning(copyCourse); break; case 0: - case 1: copyCourse.timing = '11:00 - 11:55 AM'; timetableCourses[i].addMorning(copyCourse); + break; + case 2: + copyCourse.timing = '08:00 - 08:55 AM'; + timetableCourses[i].addMorning(copyCourse); + break; } } if (slot == 'E') { switch (i) { case 2: + copyCourse.timing = '09:00 - 09:55 AM'; + timetableCourses[i].addMorning(copyCourse); + break; case 3: - copyCourse.timing = '11:00 - 11:55 AM'; + copyCourse.timing = '10:00 - 10:55 AM'; + timetableCourses[i].addMorning(copyCourse); + break; + case 1: + copyCourse.timing = '08:00 - 08:55 AM'; timetableCourses[i].addMorning(copyCourse); break; } @@ -237,11 +289,12 @@ abstract class _TimetableStore with Store { copyCourse.timing = '11:00 - 11:55 AM'; timetableCourses[i].addMorning(copyCourse); break; + } } if (slot == 'G') { switch (i) { - case 2: + case 5: case 3: case 4: copyCourse.timing = '12:00 - 12:55 PM'; @@ -252,8 +305,18 @@ abstract class _TimetableStore with Store { if (slot == 'A1') { switch (i) { case 0: + copyCourse.timing = '05:00 - 05:55 PM'; + timetableCourses[i].addAfternoon(copyCourse); + break; case 1: + copyCourse.timing = '04:00 - 04:55 PM'; + timetableCourses[i].addAfternoon(copyCourse); + break; case 2: + copyCourse.timing = '03:00 - 03:55 PM'; + timetableCourses[i].addAfternoon(copyCourse); + break; + case 3: copyCourse.timing = '02:00 - 02:55 PM'; timetableCourses[i].addAfternoon(copyCourse); break; @@ -261,58 +324,89 @@ abstract class _TimetableStore with Store { } if (slot == 'B1') { switch (i) { - case 3: case 4: - copyCourse.timing = '02:00 - 02:55 PM'; + copyCourse.timing = '05:00 - 05:55 PM'; timetableCourses[i].addAfternoon(copyCourse); break; case 0: + copyCourse.timing = '04:00 - 04:55 PM'; + timetableCourses[i].addAfternoon(copyCourse); + break; + case 1: copyCourse.timing = '03:00 - 03:55 PM'; timetableCourses[i].addAfternoon(copyCourse); break; + case 2: + copyCourse.timing = '02:00 - 02:55 PM'; + timetableCourses[i].addAfternoon(copyCourse); + break; } } if (slot == 'C1') { switch (i) { - case 1: - case 2: case 3: + copyCourse.timing = '05:00 - 05:55 PM'; + timetableCourses[i].addAfternoon(copyCourse); + break; + case 4: + copyCourse.timing = '04:00 - 04:55 PM'; + timetableCourses[i].addAfternoon(copyCourse); + break; + case 0: copyCourse.timing = '03:00 - 03:55 PM'; timetableCourses[i].addAfternoon(copyCourse); break; + case 1: + copyCourse.timing = '02:00 - 02:55 PM'; + timetableCourses[i].addAfternoon(copyCourse); + break; } } if (slot == 'D1') { switch (i) { + case 2: + copyCourse.timing = '05:00 - 05:55 PM'; + timetableCourses[i].addAfternoon(copyCourse); + break; + case 3: + copyCourse.timing = '04:00 - 04:55 PM'; + timetableCourses[i].addAfternoon(copyCourse); + break; case 4: copyCourse.timing = '03:00 - 03:55 PM'; timetableCourses[i].addAfternoon(copyCourse); break; case 0: - case 1: - copyCourse.timing = '04:00 - 04:55 PM'; + copyCourse.timing = '02:00 - 02:55 PM'; timetableCourses[i].addAfternoon(copyCourse); break; } } if (slot == 'E1') { switch (i) { + case 1: + copyCourse.timing = '05:00 - 05:55 PM'; + timetableCourses[i].addAfternoon(copyCourse); + break; case 2: - case 3: copyCourse.timing = '04:00 - 04:55 PM'; timetableCourses[i].addAfternoon(copyCourse); break; + case 3: + copyCourse.timing = '03:00 - 03:55 PM'; + timetableCourses[i].addAfternoon(copyCourse); + break; } } if (slot == 'F1') { switch (i) { case 0: case 1: - copyCourse.timing = '05:00 - 05:55 PM'; + copyCourse.timing = '01:00 - 01:55 PM'; timetableCourses[i].addAfternoon(copyCourse); break; case 4: - copyCourse.timing = '04:00 - 04:55 PM'; + copyCourse.timing = '02:00 - 02:55 PM'; timetableCourses[i].addAfternoon(copyCourse); break; } @@ -322,14 +416,14 @@ abstract class _TimetableStore with Store { case 2: case 3: case 4: - copyCourse.timing = '05:00 - 05:55 PM'; + copyCourse.timing = '01:00 - 01:55 PM'; timetableCourses[i].addAfternoon(copyCourse); break; } } if (slot == 'c') { switch (i) { - case 0: + case 3: copyCourse.timing = '08:00 - 08:55 AM'; timetableCourses[i].addMorning(copyCourse); break; @@ -345,7 +439,7 @@ abstract class _TimetableStore with Store { } if (slot == 'b') { switch (i) { - case 2: + case 4: copyCourse.timing = '08:00 - 08:55 AM'; timetableCourses[i].addMorning(copyCourse); break; @@ -353,7 +447,7 @@ abstract class _TimetableStore with Store { } if (slot == 'd') { switch (i) { - case 3: + case 2: copyCourse.timing = '08:00 - 08:55 AM'; timetableCourses[i].addMorning(copyCourse); break; @@ -361,7 +455,7 @@ abstract class _TimetableStore with Store { } if (slot == 'a') { switch (i) { - case 4: + case 0: copyCourse.timing = '08:00 - 08:55 AM'; timetableCourses[i].addMorning(copyCourse); break; @@ -391,7 +485,6 @@ abstract class _TimetableStore with Store { break; } } - if (slot == 'ML4') { switch (i) { case 3: diff --git a/lib/stores/timetable_store.g.dart b/lib/stores/timetable_store.g.dart index c51f733e..8aaf0d68 100644 --- a/lib/stores/timetable_store.g.dart +++ b/lib/stores/timetable_store.g.dart @@ -38,22 +38,6 @@ mixin _$TimetableStore on _TimetableStore, Store { name: '_TimetableStore.todayTimeTable')) .value; - late final _$loadOperationAtom = - Atom(name: '_TimetableStore.loadOperation', context: context); - - @override - ObservableFuture get loadOperation { - _$loadOperationAtom.reportRead(); - return super.loadOperation; - } - - @override - set loadOperation(ObservableFuture value) { - _$loadOperationAtom.reportWrite(value, super.loadOperation, () { - super.loadOperation = value; - }); - } - late final _$selectedDateAtom = Atom(name: '_TimetableStore.selectedDate', context: context); @@ -86,6 +70,22 @@ mixin _$TimetableStore on _TimetableStore, Store { }); } + late final _$loadOperationAtom = + Atom(name: '_TimetableStore.loadOperation', context: context); + + @override + ObservableFuture get loadOperation { + _$loadOperationAtom.reportRead(); + return super.loadOperation; + } + + @override + set loadOperation(ObservableFuture value) { + _$loadOperationAtom.reportWrite(value, super.loadOperation, () { + super.loadOperation = value; + }); + } + late final _$setTimetableAsyncAction = AsyncAction('_TimetableStore.setTimetable', context: context); @@ -134,9 +134,9 @@ mixin _$TimetableStore on _TimetableStore, Store { @override String toString() { return ''' -loadOperation: ${loadOperation}, selectedDate: ${selectedDate}, showDropDown: ${showDropDown}, +loadOperation: ${loadOperation}, coursesLoaded: ${coursesLoaded}, coursesLoading: ${coursesLoading}, coursesError: ${coursesError}, diff --git a/lib/widgets/timetable/date_slider.dart b/lib/widgets/timetable/date_slider.dart index 7ea1cd46..20318fb2 100644 --- a/lib/widgets/timetable/date_slider.dart +++ b/lib/widgets/timetable/date_slider.dart @@ -36,7 +36,6 @@ class _DateSliderState extends State { tStyle = MyFonts.w500.size(14).setColor(kGrey7); } return Container( - // height: 125, decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color: selected ? kTimetableGreen : Colors.transparent, From 204f474036edf6559984803b93d47318f1b04d88 Mon Sep 17 00:00:00 2001 From: Kunalpal216 Date: Fri, 30 Jun 2023 13:44:51 +0530 Subject: [PATCH 72/82] fixed timings in restraurent --- .gitignore | 3 ++ android/app/src/main/AndroidManifest.xml | 6 +++ .../ic_stat_notification_icon.png | Bin 0 -> 708 bytes .../ic_stat_notification_icon.png | Bin 0 -> 415 bytes .../ic_stat_notification_icon.png | Bin 0 -> 957 bytes .../ic_stat_notification_icon.png | Bin 0 -> 1584 bytes .../ic_stat_notification_icon.png | Bin 0 -> 1991 bytes android/app/src/main/res/values/colors.xml | 3 +- lib/functions/utility/check_last_updated.dart | 6 +-- lib/globals/endpoints.dart | 2 +- lib/models/food/mess_menu_model.dart | 6 ++- lib/models/food/mess_menu_model.g.dart | 6 ++- lib/pages/profile/edit_profile.dart | 11 +++--- lib/pages/profile/profile_page.dart | 2 +- lib/pages/splash.dart | 5 ++- lib/services/api.dart | 35 ++++++++++-------- lib/services/data_provider.dart | 2 +- lib/stores/login_store.dart | 20 +++++++--- lib/stores/mess_store.dart | 2 +- lib/widgets/food/mess/mess_menu.dart | 3 +- .../food/restaurant/restaurant_tile.dart | 5 +-- 21 files changed, 73 insertions(+), 44 deletions(-) create mode 100644 android/app/src/main/res/drawable-hdpi/ic_stat_notification_icon.png create mode 100644 android/app/src/main/res/drawable-mdpi/ic_stat_notification_icon.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_stat_notification_icon.png create mode 100644 android/app/src/main/res/drawable-xxhdpi/ic_stat_notification_icon.png create mode 100644 android/app/src/main/res/drawable-xxxhdpi/ic_stat_notification_icon.png diff --git a/.gitignore b/.gitignore index a7b2b06b..fe1246bb 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,9 @@ app.*.symbols # Obfuscation related app.*.map.json +# Keystore file path when building apk on windows +/android/app/onestop-keystore.jks + # Android Studio will place build artifacts here /android/app/debug /android/app/profile diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 95f80087..89c795cf 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -37,6 +37,12 @@ + + Px%en~_@R9Hvt)=S8za})>g&(}4S1`#WlLRq-fU}2*u*|2eolu*phM2$2vxfRMK zJ3E(&g@l-t%|tE>B)4Lkl*lC!Lb)HEx8FNnZ|`{2lwS2b^O}s*b}(oH2^{V=&&W-<0IdT>dwSJhFtbO`fE>@|YCg(s3Uh;Gdq zJc*A-ix(DVRh@_H@N$yPRkaV!#`$Qb`@Q$u8)N5n{4F>rN!#a3{^XKh-5=LU`2T^! q%+M6cGea{&Qw&VmXAS-D82S?*h0rClPx$SxH1eR7gwh)4xksQ5eVZ*QXy+84-jPkwF+Vw6^pQG>9|^hDJpYK?TuJTU$g0 zK}(Q>x%?U|OtQQcu!J2+E^Go+T{W-;R5g>0zK?i{qqvCs&3D)EKFN!%fIGO3 z$M}SOxQeqF#Wa2-xz#BBg6H^+dyTHDWf;{)1rH^eZ518IU7WyL?FNUN;5V4TdXi41 zrIZhNi4{D+chsQ|R7DN^OpPx&cS%G+RA@u(m|LjMX%xnPk1;W5qGYCVswt7kAqI^w2{ltl+&Rt2g$t3~j5#P5 zBQ={Fa^aYg5=t|sTsUon)TG8xnvsZ2LLw$)X??9f|NZUn(BAJZv+Ms}?QgyBIy~!n z-t~U_6CHf1gV#?1;C(Y#Fi3w=gk4!9ZdI zlie#aU}kO~1xy5nL+NYxYv3}_DCtsi=5`9u0)Ux)0&D;#)yQ!YSS{&cJJr$VFwFp% zSzq7?@Nq7p7x@C{0`v?veESwKThgO8XKx3`w*btn6L0_+8F8Ni%O#!4@|f8y;Afy$ z*#49>*Z(%N-oW&*9}mFefIh%~fXmL$yA+$P@cjZ90DJ)41ujauSr20#z+_-oIC#g0 zR!Pz_&4xg2@ zpqitZtpygv{xL~Q%K(%}0iH!iyXInTl(acm8y&3sM`!5{@Dgw-_XwYLl6F_CB@e(4 zWfyn7q-`|-ECs%g{i~9`sQ_S^q@z*j9N^bD|4`DHu)D1MzB$ZS0@bQEdNI z15UlqWiPrv&^coX_&S@_tz{qpd<*;(@v^t#HsEiHUvz&n#(ERY>|jpft`NUhEq_`J z5H6+9Yv}U|uu9UkT*q3?K!8~34`!8j;FXVSN$1RLKQJ!?E9s+(03xW%X(})i7#uIJ zk2t6N58#v}5B`oSGY7mT44WkVUACW1wdeT>75O}e50D}8b>%_iIwZ*-KbNmdYG*Wd zt)#Px)>PbXFRCr$Pn0LsRRTRfR-}c_oE?OiRZNj8MLW3x>B8rG66fGMztZZOLnMGD) zNo9jjnn)pG5JlsULLw}P$i$XSiskz`;N-Y%@@|1Jfie8d#w&-)UL~omg`Wa22pa zKV6$uj{=WL`nsQc2i)>y0E!5w&q=^&V58cJ{{bBIFTkI`2EaBc?ee9Iffs-~CH*kq zqVC6mS^>0=0|R!i`S}jG33wMU0A`B!uMOM*98p_uZ5jhimE^TVgxA_{rD2ODeVCqY z0_+TIn*90_K9clXukl2LFVy}w237~W_cLE=b%tJjRqK`lC?eJZMgSLOjvU-fNvC#l z9uXDm9B5_Mq!T24l|V26(}8u;0)uFMI}bPuSii+Po&X*J=CukkBGv!~0cR)Xw>swg zz<6Mmq~H4kQXQbJfTw{SGbf)IFiD?w0m$sQG6h>P#9PKnn%o8;3;7J-*e-{j35={) z$i&DK(}lXicCtULi@;<_zPO&O4$$GrNwwJlJOtb;$@~2Zirc|~7m)t=OYO#qIo z^}kCmZ43G9n`8-R7K*Gq0{*c3>}JT?goR3v%`n z)BhfK#=VGIMC_JCy)UJb&6PB)9Y9t3wYhosNUZ>}wzyr`uGfoev2K{8x!v~H0opcE zaqDd3d%$H?FVoIp8c)o=OH%V#EuA3gz7-5mD+aye#Kjjh8zjxnZfco6r~yEJpL?#nrSQeQ4Y;WMlx9B5hWjAv;~T)uRYx8X&XoIW z0zOBQ8P#X)K6jW2rvt8Po^|?bu0EqAEu{%7l0k_@djWU17_9x+rQ9P=-X@sIQ-Iq% z8AQbOz^&Qv{2wUN5?nfcFtc-iNxY>tI&=cdY30Gv!n`EMR|bO;Kt8_*ReyaL+`}!- z18y|KoMsVmW|9F<|CP;`v_(e-= z5#ceygR6C`x~;?71r`w=WL-Ea8!gFcvXn)H19XexRPyH%`!{nuKbkd`1`pky=ls9V zB4RUNCg3*2F}X1wA?cN#0qWsaR_P_Zd}m&z0q7Q70jLW?1)u^@w^bi!Ql?$=D-ImWU9>zGQ4kW*UZgyXGRgC_^P%mMKCmUTF~7 zmr(hVTgoKcxRb0|t}RMwx@CC1f5ZDc?+@pk=Q%%|bACH1uFfQJ(SxD@0C788t5ds5 z`7bbgcKLl?w9&3W5vNF&pr-$qB>;pI?5r%vm(G4T9n|Y*En)hih9{PYb2xXTerA7c zSb`N=F6H1LWeaa3po(MB)_-anNa^wtyA+}<4pUOlO7*l-MGZBzug2l;FK6;6RwtwR zmsfo65kCt4S?lMl9W!ZcY|Lb+r-HPY=)W1TXc(-Dh^VETQ~C0cvpE$d+QG-{+Dfjx zCnTn%t4u=onkih!?8Zn%tz)NAQZ^-Zv6(=%Lx(NchVM4v7!T8+N=sf2?&QR zls6h4cmfP`J+|!oG;C`&8NM1H<$Zg%&iO{rvsayHMtF|%(D`m@S&a$$%LcrYY!k zsqOtr0+WD2)h?x>(uElp0-y+64gKbyh{OBZe?oeayU!Dfm*R*->_-bq_49FIb7Ztj zB!629sV8(U8oKRni*}N379_27l=4+rL$WzNm`hTKC)DRJ#A}@DuU+v_x5G+r@Q=P6 z_LcZ3%iJ83+Go1m3D@m^sX$Z9e>=$CBa7<&0iAK&;9K0j-zcLw0kW_xBsTQ{+0}mw)s(%F(Bg~w37S>6d zvu^%GgbHQy-o$~~lQ*jKKcFa4iV<<p|)>gz>& zIBTf7FiJ)zYrNs}&V%fV#mcmyk|AnSLNHwzJklz8ck{hedhSv9;OB?=H>;w8aaX6v zFnG5D8>0ojdo*n+)XF^v>}V;jvMK|(xe`If+a?asIWiF zUB<&LOJq$tyTP05;&(Q*?dcyvyb0@#q1^8iR6Jbps^Ou#!$47;zYwyLE%LzOJGt3} z#s`-tA2+7S*>A*D zhsQpdSGF+v#zhX^PT4c-KyXSvx9*z8DQOd+F_qUw+3KsdDovAF9<>(n!W* z86I==nzV(I(tTa?m9KPRDf>HC>8}ZuUNxiV=s`k8#8RC<<_h~;@mL)pqzs8mnpDZe z)`f7>hx^4}Vg?HGbQ;}99;c=cDhC;|VoshVoIFIi0BZLvlx?^#)tMBJc2pY-aH7zR zUx2=xM@zp-<@N~XdL?^^nCAiVu`EZv%Luhupm^80ka>GZz{YxLlDMn(j zD=MyhMV6@J2x}ls@`C5;ZP%(t8ESSHT}-e8w-e1&+I-f>e%P3=Q;5C}`}F{sq-olW z#hr@b#pjpFugL}SP+vf+88Edg;)Z2#`4Ql_>}mJSUdi@IHm+N|gFGGPFR%^W%k+!c z=Z7=b_;dhVBE_q(mwV*k6%RhDHISLa{9QeUo8sBNEC@SD>)dY{+jor_g{70GTt ze~kbdM&!-cA6nT(dSvUAE8`!59aYbgb*N-&P7rGhJDVHRee?^N)eN>=1U#hM_h1GU zaGf}jCz+Mu<0-DHs9Cu5ypS2mX$Ucbd}bUC7f@xiT#siWy`n+wx~ht}#_EI4=AK5w zH;+L}d4XI8+|Zr>D@Vlk#o?+X$t>yqNZS9cVjEWJNsBMd)i}5N%)rjt*{a5plK3Be C+ - + #001B3E + #76ACFF \ No newline at end of file diff --git a/lib/functions/utility/check_last_updated.dart b/lib/functions/utility/check_last_updated.dart index d1ea844c..32b2201f 100644 --- a/lib/functions/utility/check_last_updated.dart +++ b/lib/functions/utility/check_last_updated.dart @@ -6,9 +6,9 @@ import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/services/local_storage.dart'; Map> recordNames = { - "food": [DatabaseRecords.restaurant], - "travel": [DatabaseRecords.busTimings, DatabaseRecords.ferryTimings], - "menu": [DatabaseRecords.messMenu], + "foodOutlet": [DatabaseRecords.restaurant], + "timing": [DatabaseRecords.busTimings, DatabaseRecords.ferryTimings], + "messMenu": [DatabaseRecords.messMenu], "contact": [DatabaseRecords.contacts] }; diff --git a/lib/globals/endpoints.dart b/lib/globals/endpoints.dart index 3064e72b..92040a7c 100644 --- a/lib/globals/endpoints.dart +++ b/lib/globals/endpoints.dart @@ -36,7 +36,7 @@ class Endpoints { static const String guestLogin = "/user/guest/login"; static const String userProfile = "/user"; static const String userDeviceTokens = "/user/device-tokens"; - static const String userLogout = "/user/logout"; + //static const String userLogout = "/user/logout"; static getHeader() { return {'Content-Type': 'application/json', 'security-key': Endpoints.apiSecurityKey}; } diff --git a/lib/models/food/mess_menu_model.dart b/lib/models/food/mess_menu_model.dart index d459052a..4e9cfa29 100644 --- a/lib/models/food/mess_menu_model.dart +++ b/lib/models/food/mess_menu_model.dart @@ -52,12 +52,14 @@ class Day { class MealType { final String id; final String mealDescription; - final String timing; + final DateTime startTiming; + final DateTime endTiming; MealType({ required this.id, required this.mealDescription, - required this.timing, + required this.startTiming, + required this.endTiming, }); factory MealType.fromJson(Map json) => _$MealTypeFromJson(json); diff --git a/lib/models/food/mess_menu_model.g.dart b/lib/models/food/mess_menu_model.g.dart index af289c6b..ecc92e23 100644 --- a/lib/models/food/mess_menu_model.g.dart +++ b/lib/models/food/mess_menu_model.g.dart @@ -49,11 +49,13 @@ Map _$DayToJson(Day instance) => { MealType _$MealTypeFromJson(Map json) => MealType( id: json['id'] as String, mealDescription: json['mealDescription'] as String, - timing: json['timing'] as String, + startTiming: DateTime.parse(json['startTiming'] as String), + endTiming: DateTime.parse(json['endTiming'] as String), ); Map _$MealTypeToJson(MealType instance) => { 'id': instance.id, 'mealDescription': instance.mealDescription, - 'timing': instance.timing, + 'startTiming': instance.startTiming.toIso8601String(), + 'endTiming': instance.endTiming.toIso8601String(), }; diff --git a/lib/pages/profile/edit_profile.dart b/lib/pages/profile/edit_profile.dart index 06bc1c49..cba59399 100644 --- a/lib/pages/profile/edit_profile.dart +++ b/lib/pages/profile/edit_profile.dart @@ -115,16 +115,15 @@ class _EditProfileState extends State { 'homeAddress': _homeAddressController.text, 'linkedin': _linkedinController.text }; - print(data); - await APIService().updateUserProfile(data,null); - Map userInfo = await APIService().getUserProfile(); SharedPreferences prefs = await SharedPreferences.getInstance(); - prefs.setString('hostel', hostel??""); - prefs.setString("userInfo", jsonEncode(userInfo)); - context.read().saveToUserInfo(prefs); // automatically updates token & other user info + await prefs.setString('hostel', hostel??""); + await prefs.setString("userInfo", jsonEncode(userInfo)); + await context.read().saveToUserInfo(prefs); // automatically updates token & other user info + await prefs.setBool("isProfileComplete", true); // profile is complete + print("PROFILE COMPLETED"); Navigator.of(context) .pushNamedAndRemoveUntil('/', (Route route) => false); diff --git a/lib/pages/profile/profile_page.dart b/lib/pages/profile/profile_page.dart index f8625ce5..2ab56a4c 100644 --- a/lib/pages/profile/profile_page.dart +++ b/lib/pages/profile/profile_page.dart @@ -121,7 +121,7 @@ class _ProfileState extends State { semiTitle: widget.profileModel.outlookEmail, ), DataTile( - title: 'Gmail', + title: 'Alt Email', semiTitle: widget.profileModel.altEmail, ), DataTile( diff --git a/lib/pages/splash.dart b/lib/pages/splash.dart index 5fc61dd0..048d075d 100644 --- a/lib/pages/splash.dart +++ b/lib/pages/splash.dart @@ -1,4 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:onestop_dev/functions/utility/show_snackbar.dart'; +import 'package:onestop_dev/models/profile/profile_model.dart'; +import 'package:onestop_dev/pages/profile/edit_profile.dart'; import 'package:onestop_dev/stores/login_store.dart'; import 'package:provider/provider.dart'; @@ -18,7 +21,7 @@ class _SplashPageState extends State { Provider.of(context, listen: false) .isAlreadyAuthenticated() .then((result) { - if (result) { + if (result && LoginStore.isProfileComplete){ Navigator.of(context) .pushNamedAndRemoveUntil('/home2', (Route route) => false); } else { diff --git a/lib/services/api.dart b/lib/services/api.dart index 822fa493..6f3a3e68 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -35,7 +35,6 @@ final dio2 = Dio(BaseOptions( APIService() { - dio.interceptors .add(InterceptorsWrapper(onRequest: (options, handler) async { print("THIS IS TOKEN"); @@ -66,6 +65,9 @@ final dio2 = Dio(BaseOptions( else if(response != null && response.statusCode == 403){ showSnackBar("Access not allowed in guest mode"); } + else if(response != null && response.statusCode == 400){ + showSnackBar(response.data["message"]); + } // admin user with expired tokens return handler.next(error); })); @@ -100,15 +102,13 @@ final dio2 = Dio(BaseOptions( Dio regenDio = Dio(BaseOptions( baseUrl: Endpoints.baseUrl, connectTimeout: const Duration(seconds: 5), - receiveTimeout: const Duration(seconds: 5), - headers: { - 'Security-Key': Endpoints.apiSecurityKey - })); + receiveTimeout: const Duration(seconds: 5))); Response> resp = await regenDio.post( "/user/accesstoken", - options: Options(headers: {"authorization": "Bearer $refreshToken"})); + options: Options(headers: {'Security-Key': Endpoints.apiSecurityKey,"authorization": "Bearer $refreshToken"})); var data = resp.data!; - await AuthUserHelpers.setAccessToken(data["token"]); + print("REGENRATED ACCESS TOKEN"); + await AuthUserHelpers.setAccessToken(data[BackendHelper.accesstoken]); return true; } catch (err) { return false; @@ -169,11 +169,11 @@ final dio2 = Dio(BaseOptions( print(response); } - Future logoutUser(String deviceToken) async { - print(deviceToken); - var response = await dio.delete(Endpoints.userLogout,data: {"deviceToken" : deviceToken}); - print(response); - } + // Future logoutUser(String deviceToken) async { + // print(deviceToken); + // var response = await dio.delete(Endpoints.userLogout,data: {"deviceToken" : deviceToken}); + // print(response); + // } Future>> getRestaurantData() async { var response = await dio.get(Endpoints.restaurantURL); @@ -634,8 +634,9 @@ final dio2 = Dio(BaseOptions( if(meal=='no data'){ return MealType( id: '', - mealDescription: 'Not updated by HMC', - timing: 'Oh no!' + mealDescription: "Not updated by ${hostel}'s HMC. Kindly Contact ask them to update", + startTiming: DateTime.now(), + endTiming: DateTime.now() ); } return MealType( @@ -643,8 +644,10 @@ final dio2 = Dio(BaseOptions( .toLowerCase()]['_id'], mealDescription: meal[day.trim().toLowerCase()][mealType.trim() .toLowerCase()]['mealDescription'], - timing: meal[day.trim().toLowerCase()][mealType.trim() - .toLowerCase()]['timing'] + startTiming: meal[day.trim().toLowerCase()][mealType.trim() + .toLowerCase()]['startTiming'], + endTiming: meal[day.trim().toLowerCase()][mealType.trim() + .toLowerCase()]['endTiming'], ); }catch(e){ print(Endpoints.messURL); diff --git a/lib/services/data_provider.dart b/lib/services/data_provider.dart index 96afb184..4b20eea3 100644 --- a/lib/services/data_provider.dart +++ b/lib/services/data_provider.dart @@ -100,7 +100,7 @@ class DataProvider { else { for (var element in cachedData) { var x = element as Map; - people[x['name']] = ContactModel.fromJson(x); + people[x['sectionName']] = ContactModel.fromJson(x); } return people; } diff --git a/lib/stores/login_store.dart b/lib/stores/login_store.dart index 641934f6..ab550787 100644 --- a/lib/stores/login_store.dart +++ b/lib/stores/login_store.dart @@ -17,6 +17,7 @@ class LoginStore { static Map userData = {}; final cookieManager = WebviewCookieManager(); static bool isGuest = false; + static bool isProfileComplete=false; // static final Config config = Config( // tenant: '850aa78d-94e1-4bc6-9cf3-8c11b530701c', // clientId: '81f3e9f0-b0fd-48e0-9d36-e6058e5c6d4f', @@ -55,8 +56,15 @@ class LoginStore { Future isAlreadyAuthenticated() async { SharedPreferences user = await SharedPreferences.getInstance(); print("inside authentication check"); - if (user.containsKey(BackendHelper.refreshtoken)) { + if (user.containsKey("userInfo")) { print("here"); + if(user.containsKey("isProfileComplete")){ + print("PROFILE IS COMPLETE"); + isProfileComplete=true; + } + else{ + print("PROFILE IS INCOMPLETE"); + } print(await user.containsKey("userInfo")); await saveToUserInfo(user); return true; @@ -78,6 +86,7 @@ class LoginStore { print(response.data); await saveToPreferences(sharedPrefs, response.data); await saveToUserInfo(sharedPrefs); + await sharedPrefs.setBool("isProfileComplete", true); // profile is complete for guest } Future saveToPreferences( @@ -127,13 +136,14 @@ class LoginStore { print("INSIDE LOGOUT"); await cookieManager.clearCookies(); SharedPreferences user = await SharedPreferences.getInstance(); - if(!isGuest){ - print(user.getString("deviceToken")!); - await APIService().logoutUser(user.getString("deviceToken")!); // remove token on logout if not guest - } + // if(!isGuest){ + // print(user.getString("deviceToken")!); + // await APIService().logoutUser(user.getString("deviceToken")!); // remove token on logout if not guest + // } await user.clear(); userData.clear(); isGuest = false; + isProfileComplete=false; await LocalStorage.instance.deleteRecordsLogOut(); navigationPopCallBack(); } diff --git a/lib/stores/mess_store.dart b/lib/stores/mess_store.dart index c57abe73..bddfbc54 100644 --- a/lib/stores/mess_store.dart +++ b/lib/stores/mess_store.dart @@ -29,7 +29,7 @@ abstract class _MessStore with Store { @observable ObservableFuture selectedHostel = ObservableFuture(getSavedHostel()) ; @observable - MealType mealData= MealType(id: 'id', mealDescription: 'mealDescription', timing: 'timing'); + MealType mealData= MealType(id: 'id', mealDescription: 'mealDescription', startTiming: DateTime.now(), endTiming: DateTime.now()); @computed bool get hostelLoaded => selectedHostel.status == FutureStatus.fulfilled; @action diff --git a/lib/widgets/food/mess/mess_menu.dart b/lib/widgets/food/mess/mess_menu.dart index d769a71d..2acf8987 100644 --- a/lib/widgets/food/mess/mess_menu.dart +++ b/lib/widgets/food/mess/mess_menu.dart @@ -1,6 +1,7 @@ import 'package:fluentui_system_icons/fluentui_system_icons.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:intl/intl.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/stores/mess_store.dart'; @@ -74,7 +75,7 @@ class MessMenu extends StatelessWidget { Expanded( flex: 1, child: Text( - messStore.mealData.timing, + messStore.mealData.id.isEmpty ? "Not Specified" : "${DateFormat.jm().format(messStore.mealData.startTiming)} - ${DateFormat.jm().format(messStore.mealData.endTiming)}", // id empty means not updated by HMC style: MyFonts.w500.size(12).setColor(kGrey12), ), ), diff --git a/lib/widgets/food/restaurant/restaurant_tile.dart b/lib/widgets/food/restaurant/restaurant_tile.dart index 328dc5c1..76638b19 100644 --- a/lib/widgets/food/restaurant/restaurant_tile.dart +++ b/lib/widgets/food/restaurant/restaurant_tile.dart @@ -116,12 +116,11 @@ class RestaurantTile extends StatelessWidget { ), Expanded(child: Container()), ConstrainedBox( - constraints: BoxConstraints(maxWidth: SizeConfig.screenWidth!<=380? 55:70), + constraints: const BoxConstraints(maxWidth: 55), child: Text( getRestaurantDistance(context, restaurantModel), textAlign: TextAlign.center, - style: MyFonts.w500.size(11).setColor(kWhite), - overflow:TextOverflow.fade + style: MyFonts.w500.size(11).setColor(kWhite) ), ), Expanded(child: Container()), From 1c9f49be812adc5e77a369e6a68bff229cc937f0 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Sat, 1 Jul 2023 01:03:42 +0530 Subject: [PATCH 73/82] update details upsp --- lib/pages/upsp/details_upsp.dart | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/pages/upsp/details_upsp.dart b/lib/pages/upsp/details_upsp.dart index 85b218c6..c754b8c7 100644 --- a/lib/pages/upsp/details_upsp.dart +++ b/lib/pages/upsp/details_upsp.dart @@ -20,9 +20,9 @@ class DetailsUpsp extends StatefulWidget { } class _DetailsUpspState extends State { - String selectedDropdown = 'Kameng'; bool submitted = false; TextEditingController contact = TextEditingController(); + TextEditingController rollNo = TextEditingController(); List hostels = [ "Kameng", "Barak", @@ -45,7 +45,10 @@ class _DetailsUpspState extends State { var userData = LoginStore.userData; String email = userData['outlookEmail']!; String name = userData['name']!; - String roll = userData['rollNo']!; + rollNo.text = userData['rollNo']!.toString(); + String selectedDropdown = userData['hostel']!; + contact.text=userData['phoneNumber']!.toString(); + return Scaffold( backgroundColor: kBackground, appBar: AppBar( @@ -89,7 +92,7 @@ class _DetailsUpspState extends State { padding: const EdgeInsets.symmetric( horizontal: 20, vertical: 10), child: TextFormField( - initialValue: roll, + controller: rollNo, validator: (val) { if (val == null || val.isEmpty) { return "Please fill your roll number"; @@ -106,7 +109,6 @@ class _DetailsUpspState extends State { hintText: 'Your Answer', hintStyle: const TextStyle(color: kGrey8), ), - onChanged: (r) => roll = r, ))), ), Padding( @@ -166,6 +168,7 @@ class _DetailsUpspState extends State { padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 5), child: DropdownButtonFormField( + value: selectedDropdown, validator: (val) { if (val == null) { return "Hostel can not be empty"; @@ -239,13 +242,13 @@ class _DetailsUpspState extends State { data['phone'] = contact.text; data['hostel'] = selectedDropdown; data['name'] = name; - data['roll_number'] = roll; + data['roll_number'] = rollNo.text; data['email'] = email; try { var response = await APIService().postUPSP(data); if (!mounted) return; if (response['success']) { - showSnackBar("Your problem has been successfully sent to respective authorities."); + showSnackBar("Your problem has been successfully sent to respective au1thorities."); Navigator.popUntil( context, ModalRoute.withName(HomePage.id)); } else { From 3083d7cf5e0db4a6677d91bfa9672fe030921dd0 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Sat, 1 Jul 2023 01:13:45 +0530 Subject: [PATCH 74/82] fixed mess menu --- lib/functions/utility/check_last_updated.dart | 8 +++++++- lib/services/api.dart | 8 ++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/functions/utility/check_last_updated.dart b/lib/functions/utility/check_last_updated.dart index 32b2201f..b53cdd64 100644 --- a/lib/functions/utility/check_last_updated.dart +++ b/lib/functions/utility/check_last_updated.dart @@ -4,6 +4,7 @@ import 'package:onestop_dev/globals/database_strings.dart'; import 'package:onestop_dev/services/api.dart'; import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/services/local_storage.dart'; +import 'package:shared_preferences/shared_preferences.dart'; Map> recordNames = { "foodOutlet": [DatabaseRecords.restaurant], @@ -20,11 +21,16 @@ Future checkLastUpdated() async { if (lastUpdated == null) { await LocalStorage.instance.deleteAllRecord(); - await LocalStorage.instance.storeData([last], DatabaseRecords.lastUpdated); + await LocalStorage.instance + .storeData([last], DatabaseRecords.lastUpdated); return true; } for (var key in lastUpdated.keys) { if (lastUpdated[key] != last[key]) { + if (key.toLowerCase() == "messmenu") { + final prefs = await SharedPreferences.getInstance(); + prefs.remove('messMenu'); + } recordNames[key]?.forEach((element) async { await LocalStorage.instance.deleteRecord(element); }); diff --git a/lib/services/api.dart b/lib/services/api.dart index 6f3a3e68..0e70de7a 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -644,10 +644,10 @@ final dio2 = Dio(BaseOptions( .toLowerCase()]['_id'], mealDescription: meal[day.trim().toLowerCase()][mealType.trim() .toLowerCase()]['mealDescription'], - startTiming: meal[day.trim().toLowerCase()][mealType.trim() - .toLowerCase()]['startTiming'], - endTiming: meal[day.trim().toLowerCase()][mealType.trim() - .toLowerCase()]['endTiming'], + startTiming: DateTime.parse( meal[day.trim().toLowerCase()][mealType.trim() + .toLowerCase()]['startTiming']).add(const Duration(hours: 5,minutes: 30)), + endTiming: DateTime.parse( meal[day.trim().toLowerCase()][mealType.trim() + .toLowerCase()]['endTiming']).add(const Duration(hours: 5,minutes: 30)), ); }catch(e){ print(Endpoints.messURL); From 3993b9a0e0387686ef124a33613f21b544b3d23b Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Sat, 1 Jul 2023 01:37:13 +0530 Subject: [PATCH 75/82] fixed restaurant seachbar --- lib/stores/restaurant_store.dart | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/lib/stores/restaurant_store.dart b/lib/stores/restaurant_store.dart index da9ea05f..e4bc6e30 100644 --- a/lib/stores/restaurant_store.dart +++ b/lib/stores/restaurant_store.dart @@ -1,5 +1,4 @@ // ignore_for_file: library_private_types_in_public_api -import 'package:fuzzy/fuzzy.dart'; import 'package:mobx/mobx.dart'; import 'package:onestop_dev/models/food/restaurant_model.dart'; import 'package:onestop_dev/services/data_provider.dart'; @@ -43,7 +42,7 @@ abstract class _RestaurantStore with Store { @action void setSearchString(String str) { _searchString = str; - searchResults = ObservableFuture(executeFuzzySearch()); + searchResults = ObservableFuture(executeSearch()); _searchPageHeader = "Showing results for $str"; } @@ -52,26 +51,18 @@ abstract class _RestaurantStore with Store { _searchPageHeader = str; } - Future> executeFuzzySearch() async { + Future> executeSearch() async { List allRestaurants = await DataProvider.getRestaurants(); List searchResults = []; - for (var element in allRestaurants) { - List searchFields = element.tags; - for (var dish in element.menu) { - searchFields.add(dish.itemName); - } - final fuse = Fuzzy( - searchFields, - options: FuzzyOptions( - findAllMatches: false, - tokenize: false, - threshold: 0.4, - ), - ); - - final result = fuse.search(_searchString); - if (result.isNotEmpty) { - searchResults.add(element); + for (var restaurant in allRestaurants) { + if (restaurant.outletName.toLowerCase().contains(_searchString.toLowerCase())) { + searchResults.add(restaurant); + } else { + for (var dish in restaurant.menu) { + if (dish.itemName.toLowerCase().contains(_searchString.toLowerCase())) { + searchResults.add(restaurant); + } + } } } return searchResults; From bad1bec646b56356f7fa608440c2039747e0a968 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Sat, 1 Jul 2023 02:08:46 +0530 Subject: [PATCH 76/82] fixed timetable update issue --- lib/pages/profile/edit_profile.dart | 87 ++++++++++++++++------------- 1 file changed, 49 insertions(+), 38 deletions(-) diff --git a/lib/pages/profile/edit_profile.dart b/lib/pages/profile/edit_profile.dart index b2381d35..b0a33360 100644 --- a/lib/pages/profile/edit_profile.dart +++ b/lib/pages/profile/edit_profile.dart @@ -5,7 +5,9 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:image_picker/image_picker.dart'; import 'package:intl/intl.dart'; +import 'package:onestop_dev/globals/database_strings.dart'; import 'package:onestop_dev/services/api.dart'; +import 'package:onestop_dev/services/local_storage.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -22,7 +24,7 @@ import 'profile_page.dart'; class EditProfile extends StatefulWidget { final ProfileModel profileModel; - const EditProfile({Key? key,required this.profileModel}) : super(key: key); + const EditProfile({Key? key, required this.profileModel}) : super(key: key); @override State createState() => _EditProfileState(); @@ -43,11 +45,7 @@ class _EditProfileState extends State { String? gender; DateTime? selectedDob; // String? imageString; - final List genders = [ - "Male", - "Female", - "Others" - ]; + final List genders = ["Male", "Female", "Others"]; final List hostels = [ "Kameng", "Barak", @@ -72,35 +70,39 @@ class _EditProfileState extends State { _rollController.text = p.rollNo; _outlookEmailController.text = p.outlookEmail; _altEmailController.text = p.altEmail ?? ""; - _phoneController.text =p.phoneNumber==null?"": p.phoneNumber.toString(); - _emergencyController.text = p.emergencyPhoneNumber==null?"": p.emergencyPhoneNumber.toString(); + _phoneController.text = + p.phoneNumber == null ? "" : p.phoneNumber.toString(); + _emergencyController.text = + p.emergencyPhoneNumber == null ? "" : p.emergencyPhoneNumber.toString(); _roomNoController.text = p.roomNo ?? ""; _homeAddressController.text = p.homeAddress ?? ""; - _dobController.text = DateFormat('dd-MMM-yyyy').format(DateTime.parse(p.dob ?? DateTime.now().toIso8601String())); + _dobController.text = DateFormat('dd-MMM-yyyy') + .format(DateTime.parse(p.dob ?? DateTime.now().toIso8601String())); _linkedinController.text = p.linkedin ?? ""; hostel = p.hostel; gender = p.gender; - selectedDob = p.dob!=null ? DateTime.parse(p.dob!) : DateTime.now(); + selectedDob = p.dob != null ? DateTime.parse(p.dob!) : DateTime.now(); // imageString = p.image; } @override Widget build(BuildContext context) { Widget? counterBuilder(context, - {required currentLength, required isFocused, required maxLength}) { - if (currentLength == 0) { - return null; + {required currentLength, required isFocused, required maxLength}) { + if (currentLength == 0) { + return null; + } + return Text("$currentLength/$maxLength", + style: MyFonts.w500.size(12).setColor(kWhite)); } - return Text("$currentLength/$maxLength", - style: MyFonts.w500.size(12).setColor(kWhite)); - } + Future onFormSubmit() async { if (!_formKey.currentState!.validate()) { showSnackBar('Please give all the inputs correctly'); return; } else { - DateTime date = DateTime( - selectedDob!.year, selectedDob!.month, selectedDob!.day); + DateTime date = + DateTime(selectedDob!.year, selectedDob!.month, selectedDob!.day); var data = { 'name': _nameController.text, 'rollNo': _rollController.text, @@ -116,17 +118,24 @@ class _EditProfileState extends State { 'linkedin': _linkedinController.text }; print(data); - await APIService().updateUserProfile(data,null); + try { + await APIService().updateUserProfile(data, null); + } catch (e) { + showSnackBar(e.toString()); + return; + } Map userInfo = await APIService().getUserProfile(); SharedPreferences prefs = await SharedPreferences.getInstance(); - await prefs.setString('hostel', hostel??""); + await prefs.setString('hostel', hostel ?? ""); await prefs.setString("userInfo", jsonEncode(userInfo)); - await context.read().saveToUserInfo(prefs); // automatically updates token & other user info + await context.read().saveToUserInfo( + prefs); // automatically updates token & other user info await prefs.setBool("isProfileComplete", true); // profile is complete + await LocalStorage.instance.deleteRecord(DatabaseRecords.timetable); print("PROFILE COMPLETED"); Navigator.of(context) .pushNamedAndRemoveUntil('/', (Route route) => false); - + // Navigator.of(context).pushAndRemoveUntil( // MaterialPageRoute( // builder: (context) => Profile( @@ -305,13 +314,14 @@ class _EditProfileState extends State { validator: (String? value) { if (value == null || value.isEmpty) { return 'Field cannot be empty'; - } - else if(value.length!=9){ + } else if (value.length != 9) { return 'Enter valid roll number'; } return null; }, - inputFormatters: [FilteringTextInputFormatter.digitsOnly,], + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], isNecessary: true, controller: _rollController, maxLength: 9, @@ -348,8 +358,7 @@ class _EditProfileState extends State { validator: (String? value) { if (value == null || value.isEmpty) { return 'Field cannot be empty'; - } - else if(value.length!=10){ + } else if (value.length != 10) { return 'Enter valid 10 digit phone number'; } return null; @@ -357,7 +366,9 @@ class _EditProfileState extends State { isNecessary: true, controller: _phoneController, inputType: TextInputType.phone, - inputFormatters: [FilteringTextInputFormatter.digitsOnly,], + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], maxLength: 10, maxLines: 1, counter: true, @@ -370,13 +381,14 @@ class _EditProfileState extends State { validator: (String? value) { if (value == null || value.isEmpty) { return 'Field cannot be empty'; - } - else if(value.length!=10){ + } else if (value.length != 10) { return 'Enter valid 10 digit phone number'; } return null; }, - inputFormatters: [FilteringTextInputFormatter.digitsOnly,], + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], isNecessary: true, controller: _emergencyController, inputType: TextInputType.phone, @@ -397,13 +409,12 @@ class _EditProfileState extends State { height: 12, ), CustomDropDown( - value: hostel, - items: hostels, - hintText: 'Hostel', - onChanged: (h) => hostel = h, - validator: validatefield, - ), - + value: hostel, + items: hostels, + hintText: 'Hostel', + onChanged: (h) => hostel = h, + validator: validatefield, + ), const SizedBox( height: 12, ), From 019016ad36daf34e041c970d406ea83ed033d8b4 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Sat, 1 Jul 2023 02:42:56 +0530 Subject: [PATCH 77/82] fixed update timing --- lib/functions/utility/check_last_updated.dart | 6 ++++++ lib/services/api.dart | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/lib/functions/utility/check_last_updated.dart b/lib/functions/utility/check_last_updated.dart index b53cdd64..bb86108c 100644 --- a/lib/functions/utility/check_last_updated.dart +++ b/lib/functions/utility/check_last_updated.dart @@ -31,6 +31,12 @@ Future checkLastUpdated() async { final prefs = await SharedPreferences.getInstance(); prefs.remove('messMenu'); } + if (key.toLowerCase() == "timing") { + final prefs = await SharedPreferences.getInstance(); + prefs.remove('busTimings'); + prefs.remove('ferryTimings'); + } + recordNames[key]?.forEach((element) async { await LocalStorage.instance.deleteRecord(element); }); diff --git a/lib/services/api.dart b/lib/services/api.dart index 0e70de7a..6885a7f2 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -681,6 +681,22 @@ final dio2 = Dio(BaseOptions( for (var element in busData) { busTimings.add(TravelTiming.fromJson(element)); } + // for(int i=0;i Date: Sun, 2 Jul 2023 20:35:19 +0530 Subject: [PATCH 78/82] data provider fro mess menu --- lib/functions/utility/check_last_updated.dart | 4 - lib/services/api.dart | 36 +-------- lib/services/data_provider.dart | 77 +++++++++++++++---- lib/stores/mess_store.dart | 12 ++- 4 files changed, 75 insertions(+), 54 deletions(-) diff --git a/lib/functions/utility/check_last_updated.dart b/lib/functions/utility/check_last_updated.dart index bb86108c..78728c7c 100644 --- a/lib/functions/utility/check_last_updated.dart +++ b/lib/functions/utility/check_last_updated.dart @@ -27,10 +27,6 @@ Future checkLastUpdated() async { } for (var key in lastUpdated.keys) { if (lastUpdated[key] != last[key]) { - if (key.toLowerCase() == "messmenu") { - final prefs = await SharedPreferences.getInstance(); - prefs.remove('messMenu'); - } if (key.toLowerCase() == "timing") { final prefs = await SharedPreferences.getInstance(); prefs.remove('busTimings'); diff --git a/lib/services/api.dart b/lib/services/api.dart index 6885a7f2..6305e77d 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -613,42 +613,10 @@ final dio2 = Dio(BaseOptions( } } - Future getMealData(String hostel, String day, String mealType,) async { + Future> getMealData() async { try{ - final prefs = await SharedPreferences.getInstance(); - Map jsonData; - if (prefs.getString('messMenu') != null) { - jsonData = jsonDecode(prefs.getString('messMenu')!); - } else { final res = await dio.get(Endpoints.messURL); - prefs.setString('messMenu', jsonEncode(res.data)); - - jsonData = res.data; - } - List answer = jsonData['details']; - var meal = answer.firstWhere( - (m) => m['hostel'].toString().trim().toLowerCase() == - hostel.toString().toLowerCase(), - orElse: () => 'no data' - ); - if(meal=='no data'){ - return MealType( - id: '', - mealDescription: "Not updated by ${hostel}'s HMC. Kindly Contact ask them to update", - startTiming: DateTime.now(), - endTiming: DateTime.now() - ); - } - return MealType( - id: meal[day.trim().toLowerCase()][mealType.trim() - .toLowerCase()]['_id'], - mealDescription: meal[day.trim().toLowerCase()][mealType.trim() - .toLowerCase()]['mealDescription'], - startTiming: DateTime.parse( meal[day.trim().toLowerCase()][mealType.trim() - .toLowerCase()]['startTiming']).add(const Duration(hours: 5,minutes: 30)), - endTiming: DateTime.parse( meal[day.trim().toLowerCase()][mealType.trim() - .toLowerCase()]['endTiming']).add(const Duration(hours: 5,minutes: 30)), - ); + return res.data; }catch(e){ print(Endpoints.messURL); print(e); diff --git a/lib/services/data_provider.dart b/lib/services/data_provider.dart index 4b20eea3..4bf8cd2a 100644 --- a/lib/services/data_provider.dart +++ b/lib/services/data_provider.dart @@ -4,6 +4,7 @@ import 'dart:collection'; import 'package:flutter/material.dart'; import 'package:onestop_dev/globals/database_strings.dart'; import 'package:onestop_dev/models/contacts/contact_model.dart'; +import 'package:onestop_dev/models/food/mess_menu_model.dart'; import 'package:onestop_dev/models/food/restaurant_model.dart'; import 'package:onestop_dev/models/news/news_model.dart'; import 'package:onestop_dev/models/timetable/registered_courses.dart'; @@ -12,7 +13,8 @@ import 'package:onestop_dev/services/local_storage.dart'; class DataProvider { static Future?> getLastUpdated() async { - var cachedData = await LocalStorage.instance.getRecord(DatabaseRecords.lastUpdated); + var cachedData = + await LocalStorage.instance.getRecord(DatabaseRecords.lastUpdated); if (cachedData == null) { return null; } @@ -20,12 +22,14 @@ class DataProvider { } static Future>>> getBusTimings() async { - var cachedData = await LocalStorage.instance.getBusRecord(DatabaseRecords.busTimings); + var cachedData = + await LocalStorage.instance.getBusRecord(DatabaseRecords.busTimings); if (cachedData == null) { print("NO BUS CACHED DATA"); Map>> busTime = await APIService().getBusData(); print(busTime); - await LocalStorage.instance.storeBusData(busTime, DatabaseRecords.busTimings); + await LocalStorage.instance + .storeBusData(busTime, DatabaseRecords.busTimings); return busTime; } print("BUS CACHED DATA"); @@ -40,7 +44,8 @@ class DataProvider { } static Future> getRestaurants() async { - var cachedData = await LocalStorage.instance.getRecord(DatabaseRecords.restaurant); + var cachedData = + await LocalStorage.instance.getRecord(DatabaseRecords.restaurant); if (cachedData == null) { print("INSIDE RESTRAURENTS GET"); @@ -50,7 +55,8 @@ class DataProvider { List restaurants = restaurantData.map((e) => RestaurantModel.fromJson(e)).toList(); - await LocalStorage.instance.storeData(restaurantData, DatabaseRecords.restaurant); + await LocalStorage.instance + .storeData(restaurantData, DatabaseRecords.restaurant); return restaurants; } @@ -66,7 +72,8 @@ class DataProvider { } static Future getTimeTable({required String roll}) async { - var cachedData = (await LocalStorage.instance.getRecord(DatabaseRecords.timetable))?[0]; + var cachedData = + (await LocalStorage.instance.getRecord(DatabaseRecords.timetable))?[0]; if (cachedData == null) { print(roll); RegisteredCourses timetableData = @@ -83,21 +90,66 @@ class DataProvider { return (await APIService().getTimeTable(roll: roll)); } + static Future getMealData({ + required String hostel, + required String day, + required String mealType, + }) async { + var cachedData = + (await LocalStorage.instance.getRecord(DatabaseRecords.messMenu))?[0]; + Map? jsonData; + + if (cachedData == null) { + jsonData = await APIService().getMealData(); + LocalStorage.instance.storeData([jsonData], DatabaseRecords.messMenu); + } else { + jsonData = cachedData as Map; + } + + List answer = jsonData['details']!; + var meal = answer.firstWhere( + (m) => + m['hostel'].toString().trim().toLowerCase() == + hostel.toString().toLowerCase(), + orElse: () => 'no data'); + if (meal == 'no data') { + return MealType( + id: '', + mealDescription: + "Not updated by ${hostel}'s HMC. Kindly Contact ask them to update", + startTiming: DateTime.now(), + endTiming: DateTime.now()); + } + return MealType( + id: meal[day.trim().toLowerCase()][mealType.trim().toLowerCase()]['_id'], + mealDescription: meal[day.trim().toLowerCase()] + [mealType.trim().toLowerCase()]['mealDescription'], + startTiming: DateTime.parse(meal[day.trim().toLowerCase()] + [mealType.trim().toLowerCase()]['startTiming']) + .add(const Duration(hours: 5, minutes: 30)), + endTiming: DateTime.parse(meal[day.trim().toLowerCase()] + [mealType.trim().toLowerCase()]['endTiming']) + .add(const Duration(hours: 5, minutes: 30)), + ); + } + static Future> getContacts() async { - var cachedData = await LocalStorage.instance.getRecord(DatabaseRecords.contacts); + var cachedData = + await LocalStorage.instance.getRecord(DatabaseRecords.contacts); SplayTreeMap people = SplayTreeMap(); if (cachedData == null) { - List> contactData = await APIService().getContactData(); + List> contactData = + await APIService().getContactData(); print("GET CONTACT DATA"); print(contactData); for (var element in contactData) { people[element['sectionName']] = ContactModel.fromJson(element); print("HERE NFJ"); } - await LocalStorage.instance.storeData(contactData, DatabaseRecords.contacts); + await LocalStorage.instance + .storeData(contactData, DatabaseRecords.contacts); return people; - } - else { + } else { for (var element in cachedData) { var x = element as Map; people[x['sectionName']] = ContactModel.fromJson(x); @@ -105,7 +157,4 @@ class DataProvider { return people; } } - - - } diff --git a/lib/stores/mess_store.dart b/lib/stores/mess_store.dart index bddfbc54..2e131c65 100644 --- a/lib/stores/mess_store.dart +++ b/lib/stores/mess_store.dart @@ -3,6 +3,7 @@ import 'package:mobx/mobx.dart'; import 'package:onestop_dev/functions/food/get_day.dart'; import 'package:onestop_dev/models/food/mess_menu_model.dart'; import 'package:onestop_dev/services/api.dart'; +import 'package:onestop_dev/services/data_provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; part 'mess_store.g.dart'; class MessStore = _MessStore with _$MessStore; @@ -53,10 +54,17 @@ abstract class _MessStore with Store { void setupReactions() async { autorun((_) async{ if(selectedHostel.status == FutureStatus.fulfilled){ - MealType requiredModel = await APIService().getMealData(selectedHostel.value! , selectedDay, selectedMeal); + print("selected hostel"); + print(selectedHostel.value); + // MealType requiredModel = await APIService().getMealData(selectedHostel.value! , selectedDay, selectedMeal); + MealType requiredModel = await DataProvider.getMealData(hostel:selectedHostel.value!, day: selectedDay,mealType: selectedMeal ); + print(requiredModel.toJson()); setmealData(requiredModel); }else{ - MealType requiredModel = await APIService().getMealData('kameng' , 'Monday', 'Breakfast'); + print("else selected hostel"); + // MealType requiredModel = await APIService().getMealData('kameng' , 'Monday', 'Breakfast'); + MealType requiredModel = await DataProvider.getMealData(hostel:'kameng', day: 'monday',mealType: 'breakfast' ); + print(requiredModel.toJson()); setmealData(requiredModel); } }); From 6356c6a0d3b1796e027f5caaad09a105304c13dc Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Sun, 2 Jul 2023 22:48:21 +0530 Subject: [PATCH 79/82] data provider for ferrry timings --- lib/functions/utility/check_last_updated.dart | 1 - lib/services/api.dart | 26 ++----------------- lib/services/data_provider.dart | 25 ++++++++++++++++++ lib/stores/travel_store.dart | 6 ++++- lib/widgets/mapbox/carousel_card.dart | 4 ++- lib/widgets/travel/next_time_card.dart | 4 ++- 6 files changed, 38 insertions(+), 28 deletions(-) diff --git a/lib/functions/utility/check_last_updated.dart b/lib/functions/utility/check_last_updated.dart index 78728c7c..60005ba7 100644 --- a/lib/functions/utility/check_last_updated.dart +++ b/lib/functions/utility/check_last_updated.dart @@ -30,7 +30,6 @@ Future checkLastUpdated() async { if (key.toLowerCase() == "timing") { final prefs = await SharedPreferences.getInstance(); prefs.remove('busTimings'); - prefs.remove('ferryTimings'); } recordNames[key]?.forEach((element) async { diff --git a/lib/services/api.dart b/lib/services/api.dart index 6305e77d..b58ae8ff 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -582,32 +582,10 @@ final dio2 = Dio(BaseOptions( } - Future> getFerryTiming() async { + Future> getFerryTiming() async { try { - final prefs = await SharedPreferences.getInstance(); - print("FERRY TIMINGS"); - Map jsonData; - if (prefs.getString('ferryTimings') != null) { - print("FOUND CACHED TIMINGS"); - jsonData = jsonDecode(prefs.getString('ferryTimings')!); - print(jsonData.toString()); - print("AFTER HERE"); - } else { - print("NOT FOUND CACHED TIMINGS"); Response res = await dio.get(Endpoints.ferryURL); - prefs.setString('ferryTimings', jsonEncode(res.data)); - jsonData = res.data; - } - List ferryTimings = []; - List ferryData = jsonData['data']; - print(ferryData); - for (var element in ferryData) { - ferryTimings.add(TravelTiming.fromJson(element)); - print(TravelTiming.fromJson(element).toJson()); - } - print(ferryTimings.length); - return ferryTimings; - + return res.data; } catch (e) { rethrow; } diff --git a/lib/services/data_provider.dart b/lib/services/data_provider.dart index 4bf8cd2a..53a69fad 100644 --- a/lib/services/data_provider.dart +++ b/lib/services/data_provider.dart @@ -11,6 +11,8 @@ import 'package:onestop_dev/models/timetable/registered_courses.dart'; import 'package:onestop_dev/services/api.dart'; import 'package:onestop_dev/services/local_storage.dart'; +import '../models/travel/travel_timing_model.dart'; + class DataProvider { static Future?> getLastUpdated() async { var cachedData = @@ -157,4 +159,27 @@ class DataProvider { return people; } } + + static Future> getFerryTiming() async { + var cachedData = await LocalStorage.instance.getRecord(DatabaseRecords.ferryTimings); + print("FERRY TIMINGS"); + Map jsonData; + if (cachedData == null) { + jsonData = await APIService().getFerryTiming(); + await LocalStorage.instance.storeData([jsonData], DatabaseRecords.ferryTimings); + } else { + jsonData = cachedData[0] as Map; + } + + List ferryTimings = []; + List ferryData = jsonData['data']; + print(ferryData); + for (var element in ferryData) { + ferryTimings.add(TravelTiming.fromJson(element)); + print(TravelTiming.fromJson(element).toJson()); + } + print(ferryTimings.length); + return ferryTimings; + + } } diff --git a/lib/stores/travel_store.dart b/lib/stores/travel_store.dart index 37426c98..870731d6 100644 --- a/lib/stores/travel_store.dart +++ b/lib/stores/travel_store.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:mobx/mobx.dart'; import 'package:onestop_dev/models/travel/travel_timing_model.dart'; import 'package:onestop_dev/services/api.dart'; +import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/widgets/travel/bus_details.dart'; import 'package:onestop_dev/widgets/travel/stops_list.dart'; @@ -29,7 +30,10 @@ abstract class _TravelStore with Store { @observable ObservableFuture> ferryTimings = - ObservableFuture(APIService().getFerryTiming()); + // ObservableFuture(APIService().getFerryTiming()); + ObservableFuture(DataProvider.getFerryTiming()); + + @action void setFerryDayType(String s) { diff --git a/lib/widgets/mapbox/carousel_card.dart b/lib/widgets/mapbox/carousel_card.dart index bd907738..83e901e8 100644 --- a/lib/widgets/mapbox/carousel_card.dart +++ b/lib/widgets/mapbox/carousel_card.dart @@ -7,6 +7,7 @@ import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/models/travel/travel_timing_model.dart'; import 'package:onestop_dev/services/api.dart'; +import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/stores/mapbox_store.dart'; import 'package:provider/provider.dart'; @@ -49,7 +50,8 @@ class CarouselCard extends StatelessWidget { } return 'Next Bus at: ${nextTime(weekdaysTimes)}'; } else { - List ferryTimings = await APIService().getFerryTiming(); + // List ferryTimings = await APIService().getFerryTiming(); + List ferryTimings = await DataProvider.getFerryTiming(); List weekdaysTimes= []; List weekendTimes=[]; TravelTiming requiredModel = diff --git a/lib/widgets/travel/next_time_card.dart b/lib/widgets/travel/next_time_card.dart index 162a7bd0..ec2a703e 100644 --- a/lib/widgets/travel/next_time_card.dart +++ b/lib/widgets/travel/next_time_card.dart @@ -8,6 +8,7 @@ import 'package:onestop_dev/functions/travel/next_time.dart'; import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/services/api.dart'; +import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/stores/mapbox_store.dart'; import 'package:provider/provider.dart'; @@ -60,7 +61,8 @@ class _NextTimeCardState extends State { } return nextTime(weekdaysTimes); } else { - List ferryTimings = await APIService().getFerryTiming(); + // List ferryTimings = await APIService().getFerryTiming(); + List ferryTimings = await DataProvider.getFerryTiming(); List weekdaysTimes= []; List weekendTimes=[]; TravelTiming requiredModel = From fb5d162e1826d948c9baa5522c2aecc7bd353288 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Sun, 2 Jul 2023 22:58:48 +0530 Subject: [PATCH 80/82] data provider for bus timing --- lib/functions/utility/check_last_updated.dart | 5 --- lib/services/api.dart | 45 +------------------ lib/services/data_provider.dart | 41 ++++++++--------- lib/widgets/mapbox/carousel_card.dart | 3 +- lib/widgets/travel/bus_details.dart | 4 +- lib/widgets/travel/next_time_card.dart | 3 +- lib/widgets/travel/stops_list.dart | 4 +- 7 files changed, 33 insertions(+), 72 deletions(-) diff --git a/lib/functions/utility/check_last_updated.dart b/lib/functions/utility/check_last_updated.dart index 60005ba7..46de44d6 100644 --- a/lib/functions/utility/check_last_updated.dart +++ b/lib/functions/utility/check_last_updated.dart @@ -27,11 +27,6 @@ Future checkLastUpdated() async { } for (var key in lastUpdated.keys) { if (lastUpdated[key] != last[key]) { - if (key.toLowerCase() == "timing") { - final prefs = await SharedPreferences.getInstance(); - prefs.remove('busTimings'); - } - recordNames[key]?.forEach((element) async { await LocalStorage.instance.deleteRecord(element); }); diff --git a/lib/services/api.dart b/lib/services/api.dart index b58ae8ff..ce75762d 100644 --- a/lib/services/api.dart +++ b/lib/services/api.dart @@ -601,51 +601,10 @@ final dio2 = Dio(BaseOptions( rethrow; } } - Future> getBusTiming() async { + Future> getBusTiming() async { try { - final prefs = await SharedPreferences.getInstance(); - - Map jsonData; - - if (prefs.getString('busTimings') != null) { - print("FOUND BUS CACHED TIMINGS"); - print(prefs.getString('busTimings')!); - jsonData = jsonDecode(prefs.getString('busTimings')!); - } else { - print("NOT BUS FOUND CACHED TIMINGS"); final res = await dio.get(Endpoints.busStops); - print("BEFORE SET IN PREF"); - prefs.setString('busTimings', jsonEncode(res.data)); - print("SET IN PREF"); - jsonData=res.data; - } - print("JSON DATA FOUND"); - List busData = jsonData['data']; - print(busData); - List busTimings = []; - print("here before length"); - for (var element in busData) { - busTimings.add(TravelTiming.fromJson(element)); - } - // for(int i=0;i; } - static Future>>> getBusTimings() async { - var cachedData = - await LocalStorage.instance.getBusRecord(DatabaseRecords.busTimings); - if (cachedData == null) { - print("NO BUS CACHED DATA"); - Map>> busTime = await APIService().getBusData(); - print(busTime); - await LocalStorage.instance - .storeBusData(busTime, DatabaseRecords.busTimings); - return busTime; - } - print("BUS CACHED DATA"); - Map>> timings = {}; - for (String key in cachedData.keys) { - timings[key] = (cachedData[key] as List) - .map((e) => - (e as List).map((e) => (e as String).trim()).toList()) - .toList(); - } - return timings; + static Future> getBusTiming() async { + var cachedData = await LocalStorage.instance.getRecord(DatabaseRecords.busTimings); + print("BUS TIMINGS"); + Map jsonData; + if (cachedData == null) { + jsonData = await APIService().getBusTiming(); + await LocalStorage.instance.storeData([jsonData], DatabaseRecords.busTimings); + } else { + jsonData = cachedData[0] as Map; + } + List busData = jsonData['data']; + print(busData); + List busTimings = []; + print("here before length"); + for (var element in busData) { + busTimings.add(TravelTiming.fromJson(element)); + } + print("here at length"); + print(busTimings.length); + return busTimings; + } static Future> getRestaurants() async { diff --git a/lib/widgets/mapbox/carousel_card.dart b/lib/widgets/mapbox/carousel_card.dart index 83e901e8..656a9310 100644 --- a/lib/widgets/mapbox/carousel_card.dart +++ b/lib/widgets/mapbox/carousel_card.dart @@ -23,7 +23,8 @@ class CarouselCard extends StatelessWidget { Future getNextTime() async { String today = getFormattedDay(); if (context.read().indexBusesorFerry == 0) { - List allBusTimes = await APIService().getBusTiming(); + // List allBusTimes = await APIService().getBusTiming(); + List allBusTimes = await DataProvider.getBusTiming(); List weekdaysTimes= []; List weekendTimes=[]; for(var xyz in allBusTimes){ diff --git a/lib/widgets/travel/bus_details.dart b/lib/widgets/travel/bus_details.dart index d68fd1f0..761e6786 100644 --- a/lib/widgets/travel/bus_details.dart +++ b/lib/widgets/travel/bus_details.dart @@ -5,6 +5,7 @@ import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/models/travel/travel_timing_model.dart'; import 'package:onestop_dev/services/api.dart'; +import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; import 'package:provider/provider.dart'; import '../../functions/travel/next_time.dart'; @@ -33,7 +34,8 @@ class _BusDetailsState extends State { Widget build(BuildContext context) { var daytype = context.read().busDayType; return FutureBuilder>( - future: APIService().getBusTiming(), + // future: APIService().getBusTiming(), + future: DataProvider.getBusTiming(), builder: (context, snapshot) { if (snapshot.hasData) { busTime = snapshot.data; diff --git a/lib/widgets/travel/next_time_card.dart b/lib/widgets/travel/next_time_card.dart index ec2a703e..cd364883 100644 --- a/lib/widgets/travel/next_time_card.dart +++ b/lib/widgets/travel/next_time_card.dart @@ -31,7 +31,8 @@ class _NextTimeCardState extends State { print(mapStore.indexBusesorFerry); if (mapStore.indexBusesorFerry == 0) { print("hererereferf"); - List allBusTimes = await APIService().getBusTiming(); + // List allBusTimes = await APIService().getBusTiming(); + List allBusTimes = await DataProvider.getBusTiming(); //print(allBusTimes.toString()); print("AFTER ALL BUS TIMES"); List weekdaysTimes= []; diff --git a/lib/widgets/travel/stops_list.dart b/lib/widgets/travel/stops_list.dart index 04d78ace..c840ec81 100644 --- a/lib/widgets/travel/stops_list.dart +++ b/lib/widgets/travel/stops_list.dart @@ -9,6 +9,7 @@ import 'package:onestop_dev/globals/my_colors.dart'; import 'package:onestop_dev/globals/my_fonts.dart'; import 'package:onestop_dev/models/travel/travel_timing_model.dart'; import 'package:onestop_dev/services/api.dart'; +import 'package:onestop_dev/services/data_provider.dart'; import 'package:onestop_dev/stores/mapbox_store.dart'; import 'package:onestop_dev/widgets/ui/list_shimmer.dart'; import 'package:provider/provider.dart'; @@ -25,7 +26,8 @@ class BusStopList extends StatelessWidget { itemBuilder: (BuildContext context, int index) { var mapStore = context.read(); return FutureBuilder>( - future: APIService().getBusTiming(), + // future: APIService().getBusTiming(), + future: DataProvider.getBusTiming(), builder: (context, snapshot) { if (snapshot.hasData) { List? busTime = snapshot.data ; From 1906c3ea5cfa41f9728bd4358da4ee48077ead49 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Sun, 2 Jul 2023 23:15:48 +0530 Subject: [PATCH 81/82] update version and build number --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index be21a1a1..65d560f4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.4.0+26 +version: 2.0.0+27 environment: sdk: ">=2.17.0 <3.0.0" From 6386cbfea39b805b07ae071e92356ea51eb44a29 Mon Sep 17 00:00:00 2001 From: chanchalyadav272 Date: Sun, 2 Jul 2023 23:17:09 +0530 Subject: [PATCH 82/82] removed gc scoreboard --- lib/widgets/home/service_links.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/widgets/home/service_links.dart b/lib/widgets/home/service_links.dart index da1f0976..8f6d09ca 100644 --- a/lib/widgets/home/service_links.dart +++ b/lib/widgets/home/service_links.dart @@ -33,11 +33,11 @@ List serviceLinks = [ label: "Cab Sharing", icon: FluentIcons.vehicle_bus_24_regular, routeId: CabShare.id), - const HomeTabTile( - label: "GC Score Board", - icon: FluentIcons.trophy_20_regular, - routeId: Scoreboard.id, - ), + // const HomeTabTile( + // label: "GC Score Board", + // icon: FluentIcons.trophy_20_regular, + // routeId: Scoreboard.id, + // ), const HomeTabTile( label: "UPSP", icon: FluentIcons.chat_warning_16_regular,