├── android ├── settings_aar.gradle ├── app │ ├── src │ │ ├── main │ │ │ ├── ic_launcher-web.png │ │ │ ├── res │ │ │ │ ├── drawable-hdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── drawable-mdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── drawable-xhdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── drawable │ │ │ │ │ ├── background.png │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── values │ │ │ │ │ ├── colors.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── drawable-v21 │ │ │ │ │ ├── background.png │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable-xxhdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── drawable-xxxhdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── launcher_icon.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── launcher_icon.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── launcher_icon.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── launcher_icon.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ ├── launcher_icon.png │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── xml │ │ │ │ │ └── network_security_config.xml │ │ │ │ └── values-night │ │ │ │ │ └── styles.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── uttu │ │ │ │ │ └── ipecstudentsapp │ │ │ │ │ └── MainActivity.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle └── build.gradle ├── ios ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── appstore.png │ │ ├── AppIcon.appiconset │ │ │ ├── 29.png │ │ │ ├── 40.png │ │ │ ├── 57.png │ │ │ ├── 58.png │ │ │ ├── 60.png │ │ │ ├── 80.png │ │ │ ├── 87.png │ │ │ ├── 1024.png │ │ │ ├── 114.png │ │ │ ├── 120.png │ │ │ ├── 180.png │ │ │ └── Contents.json │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── LaunchBackground.imageset │ │ │ ├── background.png │ │ │ └── Contents.json │ ├── Runner.entitlements │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── .gitignore └── Podfile ├── web ├── favicon.png ├── icons │ ├── Icon-192.png │ ├── Icon-512.png │ ├── Icon-maskable-192.png │ └── Icon-maskable-512.png ├── splash │ ├── img │ │ ├── dark-1x.png │ │ ├── dark-2x.png │ │ ├── dark-3x.png │ │ ├── dark-4x.png │ │ ├── light-1x.png │ │ ├── light-2x.png │ │ ├── light-3x.png │ │ └── light-4x.png │ └── style.css └── manifest.json ├── assets ├── icons │ ├── Bag.png │ ├── Atom.png │ ├── menu.png │ ├── sam1.png │ ├── sam2.png │ ├── skip.png │ ├── total.png │ ├── Compass.png │ ├── attended.png │ ├── chat-box.png │ ├── verified.png │ ├── Boy-Student.png │ └── conversation.png └── images │ ├── logo.png │ ├── me_2.png │ ├── me_pic.png │ ├── coworkers.png │ ├── main_top.png │ ├── ic_forward.png │ ├── login_bottom.png │ ├── main_bottom.png │ └── signup_top.png ├── macos ├── Runner │ ├── Configs │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ ├── Warnings.xcconfig │ │ └── AppInfo.xcconfig │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── app_icon_1024.png │ │ │ ├── app_icon_128.png │ │ │ ├── app_icon_16.png │ │ │ ├── app_icon_256.png │ │ │ ├── app_icon_32.png │ │ │ ├── app_icon_512.png │ │ │ ├── app_icon_64.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Release.entitlements │ ├── MainFlutterWindow.swift │ ├── DebugProfile.entitlements │ └── Info.plist ├── .gitignore ├── Flutter │ ├── Flutter-Debug.xcconfig │ ├── Flutter-Release.xcconfig │ └── GeneratedPluginRegistrant.swift ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme └── Podfile ├── fonts └── averta │ ├── Averta-Bold.ttf │ └── Averta-Regular.ttf ├── flutter_launcher_icons.yaml ├── lib ├── data │ ├── model │ │ ├── Cred.dart │ │ ├── GeneralResponse.dart │ │ ├── Notice.dart │ │ ├── TokensModel.dart │ │ ├── hangout │ │ │ ├── PollModel.dart │ │ │ ├── comment.dart │ │ │ ├── hangUser.dart │ │ │ └── post.dart │ │ ├── Attendance.dart │ │ └── User.dart │ ├── base_bloc │ │ ├── base_state.dart │ │ ├── base_event.dart │ │ ├── base_bloc_builder.dart │ │ ├── base_bloc.dart │ │ └── base_bloc_listener.dart │ ├── bad_hindi_words.dart │ ├── local │ │ └── shared_pref.dart │ └── repo │ │ └── auth.dart ├── util │ ├── string_cap.dart │ ├── msg_gen.dart │ ├── helper.dart │ ├── SugarParse.dart │ ├── svg_wrapper.dart │ └── SizeConfig.dart ├── screens │ ├── login │ │ └── login_screen.dart │ ├── splash │ │ ├── bloc │ │ │ ├── splash_event.dart │ │ │ ├── splash_state.dart │ │ │ └── splash_bloc.dart │ │ └── splash_screen.dart │ ├── loading │ │ ├── bloc │ │ │ ├── loading_event.dart │ │ │ ├── loading_state.dart │ │ │ └── loading_bloc.dart │ │ └── loading_screen.dart │ ├── hangout │ │ ├── widget │ │ │ ├── removeButton.dart │ │ │ ├── bottomCompose.dart │ │ │ ├── linked_widget.dart │ │ │ ├── pollsWidget.dart │ │ │ └── userStrip.dart │ │ ├── bloc │ │ │ ├── chatter │ │ │ │ ├── chatters_event.dart │ │ │ │ ├── chatters_state.dart │ │ │ │ └── chatters_bloc.dart │ │ │ ├── onboarding │ │ │ │ ├── onboarding_event.dart │ │ │ │ ├── onboarding_state.dart │ │ │ │ └── onboarding_bloc.dart │ │ │ └── hangout │ │ │ │ ├── hangout_event.dart │ │ │ │ ├── hangout_state.dart │ │ │ │ └── hangout_bloc.dart │ │ └── chatters.dart │ ├── dashboard │ │ └── attendance │ │ │ ├── bloc │ │ │ ├── attendance_state.dart │ │ │ ├── attendance_event.dart │ │ │ └── attendance_bloc.dart │ │ │ ├── attendance_page.dart │ │ │ ├── myLocalWebview.dart │ │ │ └── prediction_result_screen.dart │ ├── sessional │ │ ├── bloc │ │ │ ├── sessional_event.dart │ │ │ ├── sessional_state.dart │ │ │ └── sessional_bloc.dart │ │ └── sessional_screen.dart │ ├── notices │ │ ├── bloc │ │ │ ├── notice_event.dart │ │ │ └── notice_state.dart │ │ └── pdf_viewer.dart │ └── about │ │ └── about_widget.dart ├── main.dart ├── theme │ ├── colors.dart │ └── style.dart └── widgets │ ├── text_field_container.dart │ ├── loading_widget.dart │ ├── background.dart │ ├── rounded_button.dart │ ├── rounded_input_field.dart │ ├── rounded_password_field.dart │ ├── button.dart │ ├── simple_appbar.dart │ └── progress_dialog.dart ├── .metadata ├── .gitignore ├── INFO_BOARD.md ├── pubspec.yaml └── README.md /android/settings_aar.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/web/favicon.png -------------------------------------------------------------------------------- /assets/icons/Bag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/icons/Bag.png -------------------------------------------------------------------------------- /assets/icons/Atom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/icons/Atom.png -------------------------------------------------------------------------------- /assets/icons/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/icons/menu.png -------------------------------------------------------------------------------- /assets/icons/sam1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/icons/sam1.png -------------------------------------------------------------------------------- /assets/icons/sam2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/icons/sam2.png -------------------------------------------------------------------------------- /assets/icons/skip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/icons/skip.png -------------------------------------------------------------------------------- /assets/icons/total.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/icons/total.png -------------------------------------------------------------------------------- /assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/images/logo.png -------------------------------------------------------------------------------- /assets/images/me_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/images/me_2.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/web/icons/Icon-512.png -------------------------------------------------------------------------------- /assets/icons/Compass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/icons/Compass.png -------------------------------------------------------------------------------- /assets/icons/attended.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/icons/attended.png -------------------------------------------------------------------------------- /assets/icons/chat-box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/icons/chat-box.png -------------------------------------------------------------------------------- /assets/icons/verified.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/icons/verified.png -------------------------------------------------------------------------------- /assets/images/me_pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/images/me_pic.png -------------------------------------------------------------------------------- /assets/images/coworkers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/images/coworkers.png -------------------------------------------------------------------------------- /assets/images/main_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/images/main_top.png -------------------------------------------------------------------------------- /macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /web/splash/img/dark-1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/web/splash/img/dark-1x.png -------------------------------------------------------------------------------- /web/splash/img/dark-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/web/splash/img/dark-2x.png -------------------------------------------------------------------------------- /web/splash/img/dark-3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/web/splash/img/dark-3x.png -------------------------------------------------------------------------------- /web/splash/img/dark-4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/web/splash/img/dark-4x.png -------------------------------------------------------------------------------- /web/splash/img/light-1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/web/splash/img/light-1x.png -------------------------------------------------------------------------------- /web/splash/img/light-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/web/splash/img/light-2x.png -------------------------------------------------------------------------------- /web/splash/img/light-3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/web/splash/img/light-3x.png -------------------------------------------------------------------------------- /web/splash/img/light-4x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/web/splash/img/light-4x.png -------------------------------------------------------------------------------- /assets/icons/Boy-Student.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/icons/Boy-Student.png -------------------------------------------------------------------------------- /assets/icons/conversation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/icons/conversation.png -------------------------------------------------------------------------------- /assets/images/ic_forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/images/ic_forward.png -------------------------------------------------------------------------------- /assets/images/login_bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/images/login_bottom.png -------------------------------------------------------------------------------- /assets/images/main_bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/images/main_bottom.png -------------------------------------------------------------------------------- /assets/images/signup_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/assets/images/signup_top.png -------------------------------------------------------------------------------- /fonts/averta/Averta-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/fonts/averta/Averta-Bold.ttf -------------------------------------------------------------------------------- /macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /fonts/averta/Averta-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/fonts/averta/Averta-Regular.ttf -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /flutter_launcher_icons.yaml: -------------------------------------------------------------------------------- 1 | flutter_icons: 2 | android: "launcher_icon" 3 | ios: true 4 | image_path: "assets/images/logo.png" 5 | 6 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /lib/data/model/Cred.dart: -------------------------------------------------------------------------------- 1 | class Cred { 2 | String? username; 3 | String? password; 4 | Cred({this.username, this.password}); 5 | } 6 | -------------------------------------------------------------------------------- /android/app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | android.enableR8=true 5 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/appstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/appstore.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/drawable-hdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/drawable-mdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/drawable-xhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/drawable/background.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/drawable-v21/background.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/drawable-xxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/drawable-xxxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /lib/util/string_cap.dart: -------------------------------------------------------------------------------- 1 | extension StringExtension on String { 2 | String capitalize() { 3 | return "${this[0].toUpperCase()}${this.substring(1)}"; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-hdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-mdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uttufy/IPEC-Students-App-Flutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/uttu/ipecstudentsapp/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.uttu.ipecstudentsapp 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig" 3 | #include "Generated.xcconfig" 4 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Nov 27 17:47:49 IST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /ios/Runner/Runner.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | aps-environment 6 | development 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | secure.example.com 5 | 6 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 022b333a089afb81c471ec43d1f1f4f26305d876 8 | channel: beta 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /lib/data/model/GeneralResponse.dart: -------------------------------------------------------------------------------- 1 | class GeneralResponse { 2 | var data; 3 | bool status; 4 | String error; 5 | GeneralResponse( 6 | {this.data, this.error = "Something went wrong", this.status = false}); 7 | 8 | @override 9 | String toString() => 10 | 'GeneralResponse(data: $data, status: $status, error: $error)'; 11 | } 12 | -------------------------------------------------------------------------------- /lib/screens/login/login_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'components/body.dart'; 4 | 5 | class LoginScreen extends StatelessWidget { 6 | static const String ROUTE = "/Login"; 7 | @override 8 | Widget build(BuildContext context) { 9 | return Scaffold( 10 | body: Body(), 11 | ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/util/msg_gen.dart: -------------------------------------------------------------------------------- 1 | String genShareMessage(String? title, String? date, String url, String? credit) => 2 | """IPEC Notice 3 | ---- 4 | Title : $title 5 | Date : $date 6 | 7 | Link [PDF] : ${Uri.parse(url).toString()} 8 | ---- 9 | Contributed by : $credit 10 | on IPEC Student's app 11 | Android : http://bit.ly/ipecapp 12 | IOS : http://bit.ly/ipecappios 13 | """; 14 | -------------------------------------------------------------------------------- /lib/screens/splash/bloc/splash_event.dart: -------------------------------------------------------------------------------- 1 | import '../../../data/base_bloc/base_event.dart'; 2 | import '../../../data/repo/auth.dart'; 3 | 4 | class SplashScreenEvent extends BaseEvent { 5 | SplashScreenEvent([List props = const []]) : super(props); 6 | } 7 | 8 | class CheckUserAuth extends SplashScreenEvent { 9 | final Auth auth; 10 | CheckUserAuth(this.auth); 11 | } 12 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /lib/screens/loading/bloc/loading_event.dart: -------------------------------------------------------------------------------- 1 | import '../../../data/base_bloc/base_event.dart'; 2 | import '../../../data/repo/auth.dart'; 3 | 4 | class LoadingEvent extends BaseEvent { 5 | LoadingEvent([List props = const []]) : super(props); 6 | } 7 | 8 | class CheckCredentials extends LoadingEvent { 9 | final Auth auth; 10 | CheckCredentials(this.auth); 11 | } 12 | 13 | class ResetState extends LoadingEvent {} 14 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:adaptive_theme/adaptive_theme.dart'; 2 | import 'package:firebase_core/firebase_core.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | import 'routes.dart'; 6 | 7 | Future main() async { 8 | WidgetsFlutterBinding.ensureInitialized(); 9 | await Firebase.initializeApp(); 10 | final savedThemeMode = await AdaptiveTheme.getThemeMode(); 11 | new Routes(savedThemeMode); 12 | } 13 | -------------------------------------------------------------------------------- /macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.network.client 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /lib/screens/hangout/widget/removeButton.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | IconButton removeWidget(Function onTap) { 4 | return IconButton( 5 | color: Colors.red, 6 | icon: Padding( 7 | padding: const EdgeInsets.all(8.0), 8 | child: Icon( 9 | Icons.remove_circle, 10 | size: 30, 11 | ), 12 | ), 13 | onPressed: () { 14 | onTap(); 15 | }, 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /lib/screens/loading/bloc/loading_state.dart: -------------------------------------------------------------------------------- 1 | import '../../../data/base_bloc/base_state.dart'; 2 | 3 | class LoadingState extends BaseState { 4 | LoadingState([List props = const []]) : super(props); 5 | } 6 | 7 | class LoadingInitState extends LoadingState {} 8 | 9 | class CloseLoadingState extends LoadingState {} 10 | 11 | class LoginFailState extends LoadingState {} 12 | 13 | class AuthenticatedState extends LoadingState {} 14 | -------------------------------------------------------------------------------- /lib/screens/hangout/bloc/chatter/chatters_event.dart: -------------------------------------------------------------------------------- 1 | import '../../../../data/base_bloc/base_event.dart'; 2 | import '../../../../data/repo/pings.dart'; 3 | 4 | class ChattersEvent extends BaseEvent { 5 | ChattersEvent([List props = const []]) : super(props); 6 | } 7 | 8 | class LoadChattersEvent extends ChattersEvent { 9 | final String? postID; 10 | final Pings pings; 11 | 12 | LoadChattersEvent(this.postID, this.pings); 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "background.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/screens/hangout/bloc/chatter/chatters_state.dart: -------------------------------------------------------------------------------- 1 | import '../../../../data/base_bloc/base_state.dart'; 2 | 3 | class ChattersState extends BaseState { 4 | ChattersState([List props = const []]) : super(props); 5 | } 6 | 7 | class ChattersInitialState extends ChattersState {} 8 | 9 | class ChattersLoadingState extends ChattersState {} 10 | 11 | class ChattersLoadedState extends ChattersState {} 12 | 13 | class ChattersErrorState extends ChattersState {} 14 | -------------------------------------------------------------------------------- /lib/screens/dashboard/attendance/bloc/attendance_state.dart: -------------------------------------------------------------------------------- 1 | import '../../../../data/base_bloc/base_state.dart'; 2 | 3 | class AttendanceState extends BaseState { 4 | AttendanceState([List props = const []]) : super(props); 5 | } 6 | 7 | class AttendanceInitState extends AttendanceState {} 8 | 9 | class AttendanceLoading extends AttendanceState {} 10 | 11 | class AttendanceLoaded extends AttendanceState {} 12 | 13 | class AttendanceFailed extends AttendanceState {} 14 | -------------------------------------------------------------------------------- /lib/screens/dashboard/attendance/bloc/attendance_event.dart: -------------------------------------------------------------------------------- 1 | import '../../../../data/base_bloc/base_event.dart'; 2 | import '../../../../data/repo/auth.dart'; 3 | import '../../../../data/repo/session.dart'; 4 | 5 | class AttendanceEvent extends BaseEvent { 6 | AttendanceEvent([List props = const []]) : super(props); 7 | } 8 | 9 | class LoadAttendance extends AttendanceEvent { 10 | final Auth? auth; 11 | final Session session; 12 | LoadAttendance(this.auth, this.session); 13 | } 14 | -------------------------------------------------------------------------------- /macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.client 10 | 11 | com.apple.security.network.server 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | import Firebase 4 | 5 | @UIApplicationMain 6 | @objc class AppDelegate: FlutterAppDelegate { 7 | override func application( 8 | _ application: UIApplication, 9 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 10 | ) -> Bool { 11 | GeneratedPluginRegistrant.register(with: self) 12 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /lib/screens/splash/bloc/splash_state.dart: -------------------------------------------------------------------------------- 1 | import '../../../data/base_bloc/base_state.dart'; 2 | 3 | class SplashScreenState extends BaseState { 4 | SplashScreenState([List props = const []]) : super(props); 5 | } 6 | 7 | class SplashInitState extends SplashScreenState {} 8 | 9 | class SplashLoaderState extends SplashScreenState {} 10 | 11 | class OpenAuthenticationScreen extends SplashScreenState {} 12 | 13 | class OpenDashboardScreen extends SplashScreenState {} 14 | 15 | class NoZoneErrorState extends SplashScreenState {} 16 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "LaunchImage.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "LaunchImage@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "LaunchImage@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/screens/sessional/bloc/sessional_event.dart: -------------------------------------------------------------------------------- 1 | import '../../../data/base_bloc/base_event.dart'; 2 | import '../../../data/repo/auth.dart'; 3 | import '../../../data/repo/session.dart'; 4 | 5 | class SessionalEvent extends BaseEvent { 6 | SessionalEvent([List props = const []]) : super(props); 7 | } 8 | 9 | class SessionalLoadEvent extends SessionalEvent { 10 | final Session session; 11 | final Auth? auth; 12 | 13 | SessionalLoadEvent(this.session, this.auth); 14 | } 15 | 16 | class SessionalLoadingFinished extends SessionalEvent {} 17 | -------------------------------------------------------------------------------- /lib/util/helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_database/firebase_database.dart'; 2 | 3 | Future checkUserExist(String docID) async { 4 | DatabaseReference userRef = 5 | FirebaseDatabase.instance.reference().child('hangout').child('user'); 6 | Map res = Map(); 7 | try { 8 | await userRef.child("$docID").once().then((doc) { 9 | if (doc.value != null) { 10 | res['exists'] = true; 11 | res['data'] = doc.value; 12 | } else 13 | res['exists'] = false; 14 | }); 15 | return res; 16 | } catch (e) { 17 | res['exists'] = false; 18 | return res; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /lib/screens/hangout/bloc/onboarding/onboarding_event.dart: -------------------------------------------------------------------------------- 1 | import '../../../../data/base_bloc/base_event.dart'; 2 | import '../../../../data/model/hangout/hangUser.dart'; 3 | import '../../../../data/repo/auth.dart'; 4 | import '../../../../data/repo/session.dart'; 5 | 6 | class OnboardingEvent extends BaseEvent { 7 | OnboardingEvent([List props = const []]) : super(props); 8 | } 9 | 10 | class LoadStudentData extends OnboardingEvent { 11 | final Auth? auth; 12 | final Session session; 13 | LoadStudentData(this.auth, this.session); 14 | } 15 | 16 | class SaveStudentDataEvent extends OnboardingEvent { 17 | final Huser user; 18 | 19 | SaveStudentDataEvent(this.user); 20 | } 21 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = ipecstudentsapp 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.ipecstudentsapp 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2022 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /lib/screens/hangout/bloc/hangout/hangout_event.dart: -------------------------------------------------------------------------------- 1 | import '../../../../data/base_bloc/base_event.dart'; 2 | import '../../../../data/model/hangout/hangUser.dart'; 3 | import '../../../../data/repo/auth.dart'; 4 | import '../../../../data/repo/session.dart'; 5 | 6 | class HangoutEvent extends BaseEvent { 7 | HangoutEvent([List props = const []]) : super(props); 8 | } 9 | 10 | class LoadPingsEvent extends HangoutEvent {} 11 | 12 | class OnboardFinishEvent extends HangoutEvent { 13 | final Huser? huser; 14 | 15 | OnboardFinishEvent(this.huser); 16 | } 17 | 18 | class CheckUserEvent extends HangoutEvent { 19 | final Auth auth; 20 | 21 | final Session session; 22 | CheckUserEvent(this.auth, this.session); 23 | } 24 | -------------------------------------------------------------------------------- /lib/screens/hangout/bloc/onboarding/onboarding_state.dart: -------------------------------------------------------------------------------- 1 | import '../../../../data/base_bloc/base_state.dart'; 2 | import '../../../../data/model/hangout/hangUser.dart'; 3 | 4 | class OnboardingState extends BaseState { 5 | OnboardingState([List props = const []]) : super(props); 6 | } 7 | 8 | class OnboardingInitState extends OnboardingState {} 9 | 10 | class OnboardingLoading extends OnboardingState {} 11 | 12 | class OnboardingFailed extends OnboardingState {} 13 | 14 | class OnboardingLoaded extends OnboardingState { 15 | final Huser user; 16 | 17 | OnboardingLoaded(this.user); 18 | } 19 | 20 | class SavedUserState extends OnboardingState { 21 | final Huser user; 22 | 23 | SavedUserState(this.user); 24 | } 25 | -------------------------------------------------------------------------------- /lib/util/SugarParse.dart: -------------------------------------------------------------------------------- 1 | import 'package:html/parser.dart'; 2 | 3 | import '../data/const.dart'; 4 | import '../data/model/User.dart'; 5 | 6 | class SugarParser { 7 | User user(String? body, username) { 8 | var document = parse(body); 9 | var name = document.querySelector("#lblname")!.text; 10 | 11 | var userImage = 12 | document.querySelector("#UserImage")!.attributes.values.elementAt(1); 13 | if (name.length != 0) { 14 | if (userImage.length == 0) { 15 | userImage = kDefaultUserImage; 16 | } 17 | return User( 18 | id: username, name: name.toString().split(',')[0], img: userImage); 19 | } 20 | return User(id: username, name: "User", img: userImage); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/theme/colors.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const kPrimaryColor = Color(0xFF6F35A5); 4 | 5 | const kPrimaryLightColor = Color(0xFFF1E6FF); 6 | 7 | const kLightBg = Color(0xFFF3F3F3); 8 | 9 | const kLighterGrey = Color(0xFFF4F4F9); 10 | 11 | const kOffWhite = Color(0xFFF9F9F9); 12 | 13 | const kGrey = Color(0xFF444444); 14 | 15 | const kLightGrey = Colors.grey; 16 | 17 | const kDarkBg = Color(0xFF151515); 18 | 19 | const kOrange = Color(0xFFEE9E77); 20 | 21 | const kGreen = Color(0xFF82C890); 22 | 23 | const kPurple = Color(0xFFffbe0b); 24 | 25 | const kBlue = Color(0xFF81BEF5); 26 | 27 | const kYellow = Color(0xFFF7D58A); 28 | //medium grey #A6BCD0 29 | const Color mediumGreyColor1 = Color(0xFFA6BCD0); 30 | -------------------------------------------------------------------------------- /lib/widgets/text_field_container.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../theme/colors.dart'; 4 | 5 | class TextFieldContainer extends StatelessWidget { 6 | final Widget? child; 7 | const TextFieldContainer({ 8 | Key? key, 9 | this.child, 10 | }) : super(key: key); 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | Size size = MediaQuery.of(context).size; 15 | return Container( 16 | margin: EdgeInsets.symmetric(vertical: 10), 17 | padding: EdgeInsets.symmetric(horizontal: 20, vertical: 5), 18 | width: size.width * 0.8, 19 | decoration: BoxDecoration( 20 | color: kPrimaryLightColor, 21 | borderRadius: BorderRadius.circular(29), 22 | ), 23 | child: child, 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/widgets/loading_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:lottie/lottie.dart'; 3 | 4 | class LoadingWidget extends StatelessWidget { 5 | const LoadingWidget({ 6 | Key? key, 7 | this.text = "Loading", 8 | }) : super(key: key); 9 | 10 | final String text; 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return Stack( 15 | alignment: Alignment.center, 16 | children: [ 17 | Text( 18 | text, 19 | textAlign: TextAlign.center, 20 | style: Theme.of(context) 21 | .textTheme 22 | .headline5! 23 | .copyWith(fontWeight: FontWeight.w700), 24 | ), 25 | Lottie.asset('assets/anim/loading2.json'), 26 | ], 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.6.21' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.1.3' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | classpath 'com.google.gms:google-services:4.3.8' 12 | } 13 | } 14 | 15 | 16 | allprojects { 17 | repositories { 18 | google() 19 | jcenter() 20 | 21 | } 22 | } 23 | 24 | rootProject.buildDir = '../build' 25 | subprojects { 26 | project.buildDir = "${rootProject.buildDir}/${project.name}" 27 | } 28 | subprojects { 29 | project.evaluationDependsOn(':app') 30 | } 31 | 32 | task clean(type: Delete) { 33 | delete rootProject.buildDir 34 | } 35 | -------------------------------------------------------------------------------- /web/splash/style.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | margin:0; 3 | height:100%; 4 | background: #FFFFFF; 5 | 6 | background-size: 100% 100%; 7 | } 8 | 9 | .center { 10 | margin: 0; 11 | position: absolute; 12 | top: 50%; 13 | left: 50%; 14 | -ms-transform: translate(-50%, -50%); 15 | transform: translate(-50%, -50%); 16 | } 17 | 18 | .contain { 19 | display:block; 20 | width:100%; height:100%; 21 | object-fit: contain; 22 | } 23 | 24 | .stretch { 25 | display:block; 26 | width:100%; height:100%; 27 | } 28 | 29 | .cover { 30 | display:block; 31 | width:100%; height:100%; 32 | object-fit: cover; 33 | } 34 | 35 | @media (prefers-color-scheme: dark) { 36 | body { 37 | margin:0; 38 | height:100%; 39 | background: #FFFFFF; 40 | 41 | background-size: 100% 100%; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/screens/sessional/bloc/sessional_state.dart: -------------------------------------------------------------------------------- 1 | import '../../../data/base_bloc/base_state.dart'; 2 | 3 | class SessionalState extends BaseState { 4 | SessionalState([List props = const []]) : super(props); 5 | } 6 | 7 | class SessionalInitial extends SessionalState {} 8 | 9 | class SessionalLoadingState extends SessionalState {} 10 | 11 | class AllSessionalLoadedState extends SessionalState { 12 | final String data; 13 | AllSessionalLoadedState(this.data); 14 | } 15 | 16 | class SessionalErrorState extends SessionalState { 17 | final msg; 18 | 19 | SessionalErrorState(this.msg); 20 | } 21 | 22 | class SessionalOpenFailedState extends SessionalState { 23 | final msg; 24 | 25 | SessionalOpenFailedState(this.msg); 26 | } 27 | 28 | class SessionalOpeningLoading extends SessionalState {} 29 | 30 | class SessionalOpeningLoaded extends SessionalState {} 31 | -------------------------------------------------------------------------------- /lib/screens/hangout/bloc/hangout/hangout_state.dart: -------------------------------------------------------------------------------- 1 | import '../../../../data/base_bloc/base_state.dart'; 2 | import '../../../../data/model/hangout/hangUser.dart'; 3 | 4 | class HangoutState extends BaseState { 5 | HangoutState([List props = const []]) : super(props); 6 | } 7 | 8 | class HangoutInitState extends HangoutState {} 9 | 10 | class HangoutLoading extends HangoutState {} 11 | 12 | class HangoutLoaded extends HangoutState { 13 | final Huser user; 14 | 15 | HangoutLoaded(this.user); 16 | } 17 | 18 | class SavedUserState extends HangoutState { 19 | final Huser user; 20 | 21 | SavedUserState(this.user); 22 | } 23 | 24 | class UserExistState extends HangoutState { 25 | final Huser? huser; 26 | 27 | UserExistState(this.huser); 28 | } 29 | 30 | class UserNotExistState extends HangoutState {} 31 | 32 | class UserBannedState extends HangoutState {} 33 | -------------------------------------------------------------------------------- /lib/screens/notices/bloc/notice_event.dart: -------------------------------------------------------------------------------- 1 | import '../../../data/base_bloc/base_event.dart'; 2 | import '../../../data/model/Notice.dart'; 3 | import '../../../data/repo/auth.dart'; 4 | import '../../../data/repo/session.dart'; 5 | 6 | class NoticeEvent extends BaseEvent { 7 | NoticeEvent([List props = const []]) : super(props); 8 | } 9 | 10 | class NoticeLoadEvent extends NoticeEvent { 11 | final Session session; 12 | final Auth? auth; 13 | 14 | NoticeLoadEvent(this.session, this.auth); 15 | } 16 | 17 | class NoticeOpenEvent extends NoticeEvent { 18 | final Session session; 19 | final Auth? auth; 20 | final Notice notice; 21 | 22 | NoticeOpenEvent( 23 | this.session, 24 | this.auth, 25 | this.notice, 26 | ); 27 | } 28 | 29 | class NoticeScreenFinished extends NoticeEvent { 30 | final List notices; 31 | 32 | NoticeScreenFinished(this.notices); 33 | } 34 | -------------------------------------------------------------------------------- /lib/util/svg_wrapper.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_svg/flutter_svg.dart'; 3 | 4 | class SvgWrapper { 5 | final String rawSvg; 6 | 7 | SvgWrapper(this.rawSvg); 8 | 9 | Future generateLogo() async { 10 | try { 11 | return await svg.fromSvgString(rawSvg, rawSvg); 12 | } catch (e) { 13 | print(e); 14 | return null; 15 | } 16 | } 17 | } 18 | 19 | class MyPainter extends CustomPainter { 20 | MyPainter(this.svg, this.size); 21 | 22 | final DrawableRoot svg; 23 | final Size size; 24 | @override 25 | void paint(Canvas canvas, Size size) { 26 | svg.scaleCanvasToViewBox(canvas, Size(180.0, 180.0)); 27 | svg.clipCanvasToViewBox(canvas); 28 | svg.draw(canvas, Rect.zero); 29 | } 30 | 31 | @override 32 | bool shouldRepaint(covariant CustomPainter oldDelegate) { 33 | return true; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/data/model/Notice.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | class Notice { 4 | String? title; 5 | String? date; 6 | String? link; 7 | String? credit; 8 | bool? tp; 9 | Notice({ 10 | this.title, 11 | this.date, 12 | this.link, 13 | this.credit, 14 | this.tp, 15 | }); 16 | 17 | Map toMap() { 18 | return { 19 | 'title': title, 20 | 'date': date, 21 | 'link': link, 22 | 'credit': credit, 23 | 'tp': tp, 24 | }; 25 | } 26 | 27 | factory Notice.fromMap(Map? map) { 28 | if (map == null) throw "Something went wrong"; 29 | 30 | return Notice( 31 | title: map['title'], 32 | date: map['date'], 33 | link: map['link'], 34 | credit: map['credit'], 35 | tp: map['tp'], 36 | ); 37 | } 38 | 39 | String toJson() => json.encode(toMap()); 40 | 41 | factory Notice.fromJson(String source) => Notice.fromMap(json.decode(source)); 42 | } 43 | -------------------------------------------------------------------------------- /lib/data/model/TokensModel.dart: -------------------------------------------------------------------------------- 1 | class Tokens { 2 | String? _cookies; 3 | String? _viewState; 4 | String? _viewStateGenerator; 5 | String? _eventValidation; 6 | 7 | // ignore: unnecessary_getters_setters 8 | set cookies(String? c) { 9 | _cookies = c; 10 | } 11 | 12 | // ignore: unnecessary_getters_setters 13 | set viewState(String? c) { 14 | _viewState = c; 15 | } 16 | 17 | // ignore: unnecessary_getters_setters 18 | set viewStateGenerator(String? c) { 19 | _viewStateGenerator = c; 20 | } 21 | 22 | // ignore: unnecessary_getters_setters 23 | set eventValidation(String? c) { 24 | _eventValidation = c; 25 | } 26 | 27 | // ignore: unnecessary_getters_setters 28 | String? get cookies => _cookies; 29 | // ignore: unnecessary_getters_setters 30 | String? get viewState => _viewState; 31 | // ignore: unnecessary_getters_setters 32 | String? get viewStateGenerator => _viewStateGenerator; 33 | // ignore: unnecessary_getters_setters 34 | String? get eventValidation => _eventValidation; 35 | } 36 | -------------------------------------------------------------------------------- /lib/data/base_bloc/base_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | abstract class BaseState extends Equatable { 4 | final List props; 5 | BaseState([this.props = const []]); 6 | 7 | @override 8 | String toString() => "$runtimeType"; 9 | } 10 | 11 | class InitState extends BaseState {} 12 | 13 | class ShowSnackBarErrorState extends BaseState { 14 | final String error; 15 | ShowSnackBarErrorState(this.error) : super([error]); 16 | } 17 | 18 | class ShowDialogInfoState extends BaseState { 19 | final String title; 20 | final String message; 21 | ShowDialogInfoState(this.title, this.message) : super([title, message]); 22 | } 23 | 24 | class ShowDialogErrorState extends BaseState { 25 | final String error; 26 | ShowDialogErrorState(this.error) : super([error]); 27 | } 28 | 29 | class ShowProgressLoader extends BaseState { 30 | final String message; 31 | ShowProgressLoader(this.message) : super([message]); 32 | } 33 | 34 | class PlaceHolderState extends BaseState {} 35 | 36 | class LogoutState extends BaseState {} 37 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ipecstudentsapp", 3 | "short_name": "ipecstudentsapp", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /lib/screens/notices/bloc/notice_state.dart: -------------------------------------------------------------------------------- 1 | import '../../../data/base_bloc/base_state.dart'; 2 | import '../../../data/model/Notice.dart'; 3 | 4 | class NoticeState extends BaseState { 5 | NoticeState([List props = const []]) : super(props); 6 | } 7 | 8 | class NoticeInitial extends NoticeState {} 9 | 10 | class NoticeLoadingState extends NoticeState {} 11 | 12 | class NoticeLoadedState extends NoticeState { 13 | final List notices; 14 | NoticeLoadedState(this.notices); 15 | } 16 | 17 | class AllNoticeLoadedState extends NoticeState { 18 | final List notices; 19 | AllNoticeLoadedState(this.notices); 20 | } 21 | 22 | class NoticeErrorState extends NoticeState { 23 | final msg; 24 | 25 | NoticeErrorState(this.msg); 26 | } 27 | 28 | class NoticeOpenFailedState extends NoticeState { 29 | final msg; 30 | 31 | NoticeOpenFailedState(this.msg); 32 | } 33 | 34 | class NoticeOpeningLoading extends NoticeState {} 35 | 36 | class NoticeOpeningLoaded extends NoticeState { 37 | final String url; 38 | final Notice notice; 39 | NoticeOpeningLoaded(this.url, this.notice); 40 | } 41 | -------------------------------------------------------------------------------- /lib/widgets/background.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Background extends StatelessWidget { 4 | final Widget child; 5 | const Background({ 6 | Key? key, 7 | required this.child, 8 | }) : super(key: key); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | Size size = MediaQuery.of(context).size; 13 | return Container( 14 | width: double.infinity, 15 | height: size.height, 16 | child: Stack( 17 | alignment: Alignment.center, 18 | children: [ 19 | Positioned( 20 | top: 0, 21 | left: 0, 22 | child: Image.asset( 23 | "assets/images/main_top.png", 24 | width: size.width * 0.35, 25 | ), 26 | ), 27 | Positioned( 28 | bottom: 0, 29 | right: 0, 30 | child: Image.asset( 31 | "assets/images/login_bottom.png", 32 | width: size.width * 0.4, 33 | ), 34 | ), 35 | child, 36 | ], 37 | ), 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/screens/dashboard/attendance/attendance_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../../../util/SizeConfig.dart'; 4 | import 'attendance_screen.dart'; 5 | import 'myLocalWebview.dart'; 6 | 7 | class AttendancePage extends StatefulWidget { 8 | static const String ROUTE = "/AttendancePage"; 9 | @override 10 | _AttendancePageState createState() => _AttendancePageState(); 11 | } 12 | 13 | class _AttendancePageState extends State { 14 | @override 15 | Widget build(BuildContext context) { 16 | return Scaffold( 17 | body: Stack( 18 | children: [ 19 | Padding( 20 | padding: EdgeInsets.only(bottom: SizeConfig.heightMultiplier * 20), 21 | child: Scaffold(body: MyLocalWebView()), 22 | ), 23 | DraggableScrollableSheet( 24 | initialChildSize: 1, 25 | minChildSize: 0.15, 26 | builder: (context, scrollController) { 27 | return AttendanceScreen(scrollController: scrollController); 28 | }, 29 | ), 30 | ], 31 | ), 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Exceptions to above rules. 44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 45 | android/app/google-services.json 46 | ios/GoogleService-Info.plist 47 | android/keystore.jks 48 | ios/Runner/GoogleService-Info.plist 49 | pubspec.yaml 50 | macos/GoogleService-Info.plist 51 | lib/data/local/saver_keys.dart 52 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 16 | 19 | -------------------------------------------------------------------------------- /lib/widgets/rounded_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../theme/colors.dart'; 4 | 5 | class RoundedButton extends StatelessWidget { 6 | final String? text; 7 | final Function? press; 8 | final Color color, textColor; 9 | const RoundedButton({ 10 | Key? key, 11 | this.text, 12 | this.press, 13 | this.color = kPrimaryColor, 14 | this.textColor = Colors.white, 15 | }) : super(key: key); 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | Size size = MediaQuery.of(context).size; 20 | return Container( 21 | margin: EdgeInsets.symmetric(vertical: 10), 22 | width: size.width * 0.8, 23 | child: ClipRRect( 24 | borderRadius: BorderRadius.circular(29), 25 | // ignore: deprecated_member_use 26 | child: FlatButton( 27 | padding: EdgeInsets.symmetric(vertical: 30, horizontal: 30), 28 | color: color, 29 | onPressed: press as void Function()?, 30 | child: Text( 31 | text!, 32 | style: TextStyle(color: textColor), 33 | ), 34 | ), 35 | ), 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/widgets/rounded_input_field.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../theme/colors.dart'; 4 | import 'text_field_container.dart'; 5 | 6 | class RoundedInputField extends StatelessWidget { 7 | final String? hintText; 8 | final IconData icon; 9 | final ValueChanged? onChanged; 10 | 11 | const RoundedInputField({ 12 | Key? key, 13 | this.hintText, 14 | this.icon = Icons.person, 15 | this.onChanged, 16 | }) : super(key: key); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return TextFieldContainer( 21 | child: TextField( 22 | onChanged: onChanged, 23 | cursorColor: kPrimaryColor, 24 | style: TextStyle(color: Colors.black), 25 | decoration: InputDecoration( 26 | icon: Icon( 27 | icon, 28 | color: kPrimaryColor, 29 | ), 30 | hintText: hintText, 31 | hintStyle: Theme.of(context) 32 | .textTheme 33 | .bodyText1! 34 | .copyWith(color: Colors.black), 35 | border: InputBorder.none, 36 | ), 37 | ), 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/data/base_bloc/base_event.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | abstract class BaseEvent extends Equatable { 4 | final List props; 5 | BaseEvent([this.props = const []]); 6 | 7 | @override 8 | String toString() => "$runtimeType"; 9 | } 10 | 11 | class ShowSnackBarErrorEvent extends BaseEvent { 12 | final String error; 13 | 14 | ShowSnackBarErrorEvent(this.error) : super([error]); 15 | } 16 | class ShowProgressLoaderEvent extends BaseEvent { 17 | final String message; 18 | 19 | ShowProgressLoaderEvent(this.message) : super([message]); 20 | } 21 | 22 | class ShowDialogErrorEvent extends BaseEvent { 23 | final String error; 24 | 25 | ShowDialogErrorEvent(this.error) : super([error]); 26 | } 27 | 28 | class ShowDialogInfoEvent extends BaseEvent { 29 | 30 | final String title; 31 | final String message; 32 | 33 | ShowDialogInfoEvent( 34 | this.title, this.message) :super([title,message]); 35 | } 36 | 37 | class PlaceHolderEvent extends BaseEvent { 38 | } 39 | 40 | class ShowSessionOutDialogEvent extends BaseEvent { 41 | } 42 | 43 | class InitStateEvent extends BaseEvent { 44 | } 45 | 46 | class LogoutEvent extends BaseEvent { 47 | } 48 | -------------------------------------------------------------------------------- /lib/data/model/hangout/PollModel.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | class PollModel { 4 | final String? creator; 5 | Map? userWhoVoted; 6 | List numberOfVotes; 7 | List optionLabel; 8 | 9 | PollModel( 10 | {required this.creator, 11 | this.userWhoVoted = const {}, 12 | this.numberOfVotes = const [0.0, 0.0], 13 | required this.optionLabel}); 14 | 15 | Map toMap() { 16 | return { 17 | 'creator': creator, 18 | 'userWhoVoted': userWhoVoted, 19 | 'numberOfVotes': numberOfVotes, 20 | 'optionLabel': optionLabel, 21 | }; 22 | } 23 | 24 | factory PollModel.fromMap(Map map) { 25 | List temp = []; 26 | (map['numberOfVotes'] as List).forEach((element) { 27 | temp.add(element.toDouble()); 28 | }); 29 | return PollModel( 30 | creator: map['creator'], 31 | userWhoVoted: map['userWhoVoted'] as Map?, 32 | numberOfVotes: temp, 33 | optionLabel: List.from(map['optionLabel']), 34 | ); 35 | } 36 | 37 | String toJson() => json.encode(toMap()); 38 | 39 | factory PollModel.fromJson(String source) => 40 | PollModel.fromMap(json.decode(source)); 41 | } 42 | -------------------------------------------------------------------------------- /macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSApplicationCategoryType 24 | public.app-category.education 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | $(PRODUCT_COPYRIGHT) 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /INFO_BOARD.md: -------------------------------------------------------------------------------- 1 | # Information 2 | 3 | # Basic Markdown Demo 4 | --- 5 | The Basic Markdown Demo shows the effect of the four Markdown extension sets 6 | on formatting basic and extended Markdown tags. 7 | ## Overview 8 | The Dart [markdown](https://pub.dev/packages/markdown) package parses Markdown 9 | into HTML. The flutter_markdown package builds on this package using the 10 | abstract syntax tree generated by the parser to make a tree of widgets instead 11 | of HTML elements. 12 | The markdown package supports the basic block and inline Markdown syntax 13 | specified in the original Markdown implementation as well as a few Markdown 14 | extensions. The markdown package uses extension sets to make extension 15 | management easy. There are four pre-defined extension sets; none, Common Mark, 16 | GitHub Flavored, and GitHub Web. The default extension set used by the 17 | flutter_markdown package is GitHub Flavored. 18 | The Basic Markdown Demo shows the effect each of the pre-defined extension sets 19 | has on a test Markdown document with basic and extended Markdown tags. Use the 20 | Extension Set dropdown menu to select an extension set and view the Markdown 21 | widget's output. 22 | ## Comments 23 | Since GitHub Flavored is the default extension set, it is the initial setting 24 | for the formatted Markdown view in the demo. -------------------------------------------------------------------------------- /lib/screens/hangout/widget/bottomCompose.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../../../theme/colors.dart'; 4 | import '../../../theme/style.dart'; 5 | 6 | class BottomCompose extends StatelessWidget { 7 | final String? title; 8 | final IconData? icon; 9 | final VoidCallback? onPress; 10 | 11 | const BottomCompose({ 12 | Key? key, 13 | this.title, 14 | this.icon, 15 | this.onPress, 16 | }) : super(key: key); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return InkWell( 21 | onTap: () { 22 | onPress!(); 23 | }, 24 | borderRadius: BorderRadius.circular(20), 25 | child: Container( 26 | padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), 27 | margin: const EdgeInsets.all(5), 28 | decoration: BoxDecoration( 29 | color: kLighterGrey, 30 | borderRadius: BorderRadius.circular(20), 31 | ), 32 | child: Row( 33 | mainAxisSize: MainAxisSize.min, 34 | children: [ 35 | Icon( 36 | icon, 37 | color: Colors.black, 38 | ), 39 | kLowWidthPadding, 40 | Text( 41 | title!, 42 | style: TextStyle(color: Colors.black), 43 | ), 44 | ], 45 | ), 46 | ), 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/util/SizeConfig.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/rendering.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | class SizeConfig { 5 | static double? screenWidth; 6 | static late double screenHeight; 7 | static double _blockWidth = 0; 8 | static double _blockHeight = 0; 9 | 10 | static late double textMultiplier; 11 | static double? imageSizeMultiplier; 12 | static late double heightMultiplier; 13 | static late double widthMultiplier; 14 | static bool isPortrait = true; 15 | static bool isMobilePortrait = false; 16 | 17 | void init(BoxConstraints constraints, Orientation orientation) { 18 | if (orientation == Orientation.portrait) { 19 | screenWidth = constraints.maxWidth; 20 | screenHeight = constraints.maxHeight; 21 | isPortrait = true; 22 | if (screenWidth! < 450) { 23 | // print('mobile portrait is true'); 24 | isMobilePortrait = true; 25 | } 26 | } else { 27 | screenWidth = constraints.maxHeight; 28 | screenHeight = constraints.maxWidth; 29 | isPortrait = false; 30 | isMobilePortrait = false; 31 | } 32 | 33 | _blockWidth = screenWidth! / 100; 34 | _blockHeight = screenHeight / 100; 35 | 36 | textMultiplier = _blockHeight; 37 | imageSizeMultiplier = _blockWidth; 38 | heightMultiplier = _blockHeight; 39 | widthMultiplier = _blockWidth; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/screens/splash/bloc/splash_bloc.dart: -------------------------------------------------------------------------------- 1 | import '../../../data/base_bloc/base_bloc.dart'; 2 | import '../../../data/base_bloc/base_event.dart'; 3 | import '../../../data/base_bloc/base_state.dart'; 4 | import '../../../data/local/shared_pref.dart'; 5 | import '../../../data/model/Cred.dart'; 6 | import 'splash_event.dart'; 7 | import 'splash_state.dart'; 8 | 9 | class SplashScreenBloc extends BaseBloc { 10 | SplashScreenBloc(BaseState initialState) : super(initialState); 11 | 12 | @override 13 | BaseState get initialState => SplashInitState(); 14 | 15 | @override 16 | Stream mapBaseEventToBaseState(BaseEvent event) async* { 17 | LocalData _localData = LocalData(); 18 | if (event is CheckUserAuth) { 19 | await Future.delayed(Duration(seconds: 1)); 20 | bool? isLogin = await _localData.getLoginStatus(); 21 | 22 | if (isLogin != null && isLogin) { 23 | String? username = await _localData.getUsername(); 24 | String? password = await _localData.getPassword(); 25 | bool? loginStatus = await _localData.getLoginStatus(); 26 | 27 | if (username != null && password != null && loginStatus!) { 28 | // Username and Password Exist 29 | event.auth.cred = Cred(username: username, password: password); 30 | yield OpenDashboardScreen(); 31 | } else 32 | yield OpenAuthenticationScreen(); 33 | } else 34 | yield OpenAuthenticationScreen(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.12' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | end 35 | 36 | post_install do |installer| 37 | installer.pods_project.targets.each do |target| 38 | flutter_additional_macos_build_settings(target) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/screens/notices/pdf_viewer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:share/share.dart'; 3 | import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart'; 4 | 5 | import '../../data/model/Notice.dart'; 6 | import '../../util/msg_gen.dart'; 7 | 8 | class PdfScreen extends StatefulWidget { 9 | final String url; 10 | final Notice notice; 11 | 12 | const PdfScreen({Key? key, required this.url, required this.notice}) 13 | : super(key: key); 14 | @override 15 | _PdfScreenState createState() => _PdfScreenState(); 16 | } 17 | 18 | class _PdfScreenState extends State { 19 | @override 20 | Widget build(BuildContext context) { 21 | // final _size = MediaQuery.of(context).size; 22 | // Widgets 23 | return Scaffold( 24 | appBar: AppBar( 25 | title: Text(widget.notice.title!), 26 | elevation: 0, 27 | actions: [ 28 | Padding( 29 | padding: const EdgeInsets.all(20.0), 30 | child: GestureDetector( 31 | onTap: () { 32 | Share.share( 33 | genShareMessage(widget.notice.title, widget.notice.date, 34 | widget.url, widget.notice.credit), 35 | subject: 'IPEC Notice'); 36 | }, 37 | child: Icon(Icons.ios_share_sharp)), 38 | ), 39 | ], 40 | ), 41 | body: SfPdfViewer.network( 42 | widget.url, 43 | ), 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/screens/hangout/bloc/chatter/chatters_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'package:firebase_database/firebase_database.dart'; 3 | import '../../../../data/base_bloc/base_bloc.dart'; 4 | import '../../../../data/base_bloc/base_event.dart'; 5 | import '../../../../data/base_bloc/base_state.dart'; 6 | import '../../../../data/model/hangout/comment.dart'; 7 | import 'chatters_state.dart'; 8 | import 'chatters_event.dart'; 9 | 10 | class ChattersBloc extends BaseBloc { 11 | ChattersBloc(BaseState initialState) : super(initialState); 12 | 13 | @override 14 | BaseState get initialState => ChattersInitialState(); 15 | 16 | @override 17 | Stream mapBaseEventToBaseState(BaseEvent event) async* { 18 | final firebaseRef = 19 | FirebaseDatabase.instance.reference().child('hangout/comments'); 20 | if (event is LoadChattersEvent) { 21 | yield ChattersLoadingState(); 22 | 23 | try { 24 | final res = await firebaseRef.child(event.postID!).once(); 25 | 26 | List _list = []; 27 | if (res.value != null && res.value.keys != null) { 28 | var keys = res.value.keys; 29 | var data = res.value; 30 | for (var indivisualKey in keys) { 31 | _list.add(CommentModel.fromSnapshot(data, indivisualKey)); 32 | } 33 | } 34 | event.pings.comments[event.postID] = _list; 35 | yield ChattersLoadedState(); 36 | } catch (e) { 37 | yield ShowDialogErrorState(e.toString()); 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/widgets/rounded_password_field.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../theme/colors.dart'; 4 | import 'text_field_container.dart'; 5 | 6 | class RoundedPasswordField extends StatefulWidget { 7 | final ValueChanged? onChanged; 8 | 9 | const RoundedPasswordField({ 10 | Key? key, 11 | this.onChanged, 12 | }) : super(key: key); 13 | 14 | @override 15 | _RoundedPasswordFieldState createState() => _RoundedPasswordFieldState(); 16 | } 17 | 18 | class _RoundedPasswordFieldState extends State { 19 | bool show = false; 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | return TextFieldContainer( 24 | child: TextField( 25 | obscureText: !show, 26 | onChanged: widget.onChanged, 27 | cursorColor: kPrimaryColor, 28 | style: TextStyle(color: Colors.black), 29 | decoration: InputDecoration( 30 | hintText: "Password", 31 | icon: Icon( 32 | Icons.lock, 33 | color: kPrimaryColor, 34 | ), 35 | suffixIcon: GestureDetector( 36 | onTap: () => setState(() { 37 | show = !show; 38 | }), 39 | child: Icon( 40 | show ? Icons.visibility_off : Icons.visibility, 41 | color: kPrimaryColor, 42 | ), 43 | ), 44 | border: InputBorder.none, 45 | hintStyle: Theme.of(context) 46 | .textTheme 47 | .bodyText1! 48 | .copyWith(color: Colors.black), 49 | ), 50 | ), 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/widgets/button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../theme/colors.dart'; 4 | import '../theme/style.dart'; 5 | 6 | class BasicButton extends StatefulWidget { 7 | BasicButton( 8 | {this.onPress, 9 | required this.title, 10 | this.buttonColor = kOrange, 11 | this.textColor = Colors.white}); 12 | 13 | final String title; 14 | final VoidCallback? onPress; 15 | final Color buttonColor; 16 | final Color textColor; 17 | 18 | @override 19 | _BasicButtonState createState() => _BasicButtonState(); 20 | } 21 | 22 | class _BasicButtonState extends State { 23 | @override 24 | Widget build(BuildContext context) { 25 | return Material( 26 | borderRadius: BorderRadius.circular(kLowCircleRadius), 27 | child: InkWell( 28 | onTap: widget.onPress, 29 | child: Ink( 30 | width: double.maxFinite, 31 | padding: EdgeInsets.all(20), 32 | decoration: BoxDecoration( 33 | color: widget.buttonColor, 34 | borderRadius: BorderRadius.circular(kLowCircleRadius), 35 | ), 36 | child: Center( 37 | child: Text( 38 | widget.title, 39 | ), 40 | ), 41 | ), 42 | ), 43 | ); 44 | } 45 | } 46 | 47 | basicBackButton(context) => InkWell( 48 | onTap: () => Navigator.pop(context), 49 | borderRadius: BorderRadius.circular(kMedCircleRadius), 50 | child: Ink( 51 | padding: const EdgeInsets.all(10), 52 | child: Icon( 53 | Icons.arrow_back, 54 | color: Colors.black, 55 | ))); 56 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | {"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"}]} -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import firebase_auth 9 | import firebase_core 10 | import firebase_database 11 | import firebase_messaging 12 | import firebase_storage 13 | import in_app_review 14 | import package_info_plus_macos 15 | import path_provider_macos 16 | import shared_preferences_macos 17 | import sqflite 18 | import syncfusion_flutter_pdfviewer_macos 19 | import url_launcher_macos 20 | 21 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 22 | FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) 23 | FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) 24 | FLTFirebaseDatabasePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseDatabasePlugin")) 25 | FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) 26 | FLTFirebaseStoragePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseStoragePlugin")) 27 | InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin")) 28 | FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) 29 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) 30 | SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) 31 | SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) 32 | SyncfusionFlutterPdfViewerPlugin.register(with: registry.registrar(forPlugin: "SyncfusionFlutterPdfViewerPlugin")) 33 | UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) 34 | } 35 | -------------------------------------------------------------------------------- /lib/data/base_bloc/base_bloc_builder.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc/bloc.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | 5 | import 'base_bloc.dart'; 6 | import 'base_state.dart'; 7 | 8 | class BaseBlocBuilder extends BlocBuilderBase { 9 | /// The [Bloc] that the [BlocBuilder] will interact with. 10 | final BaseBloc bloc; 11 | 12 | /// The `builder` function which will be invoked on each widget build. 13 | /// The `builder` takes the [BuildContext] and current bloc state and 14 | /// must return a [Widget]. 15 | /// This is analogous to the `builder` function in [StreamBuilder]. 16 | final BlocWidgetBuilder builder; 17 | 18 | /// The `condition` function will be invoked on each bloc state change. 19 | /// The `condition` takes the previous state and current state and must return a `bool` 20 | /// which determines whether or not the `builder` function will be invoked. 21 | /// The previous state will be initialized to `currentState` when the `BlocBuilder` is initialized. 22 | /// `condition` is optional and if it isn't implemented, it will default to return `true`. 23 | final BlocBuilderCondition condition; 24 | 25 | const BaseBlocBuilder({ 26 | Key? key, 27 | required this.bloc, 28 | required this.builder, 29 | required this.condition, 30 | }) : super(key: key, bloc: bloc); 31 | 32 | @override 33 | Widget build(BuildContext context, BaseState state) { 34 | // print("${runtimeType} - ${state.toString()}"); 35 | return builder(context, state); 36 | } 37 | 38 | static bool isBaseState(BaseState state) { 39 | return (state is ShowDialogErrorState || 40 | state is ShowProgressLoader || 41 | state is PlaceHolderState || 42 | state is ShowSnackBarErrorState); 43 | } 44 | 45 | // @override 46 | // Widget build(BuildContext context, S state) => builder(context, state); 47 | } 48 | -------------------------------------------------------------------------------- /lib/screens/sessional/bloc/sessional_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:html/parser.dart'; 2 | 3 | import '../../../data/base_bloc/base_bloc.dart'; 4 | import '../../../data/base_bloc/base_event.dart'; 5 | import '../../../data/base_bloc/base_state.dart'; 6 | import '../../../data/model/GeneralResponse.dart'; 7 | import 'sessional_event.dart'; 8 | import 'sessional_state.dart'; 9 | 10 | class SessionalBloc extends BaseBloc { 11 | SessionalBloc(BaseState initialState) : super(initialState); 12 | 13 | @override 14 | BaseState get initialState => SessionalInitial(); 15 | 16 | @override 17 | Stream mapBaseEventToBaseState(BaseEvent event) async* { 18 | if (event is SessionalLoadEvent) { 19 | yield SessionalLoadingState(); 20 | GeneralResponse response = await event.session.webClientService 21 | .getSessional(event.auth!.token.cookies); 22 | if (response.status) { 23 | try { 24 | var document = parse(response.data); 25 | String? changedHtml = 26 | document.querySelector("#right > table")!.outerHtml; 27 | 28 | changedHtml = changedHtml.replaceAll('Black', '#f44336'); 29 | // changedHtml = changedHtml.replaceAll('White', '#1D2C4B'); 30 | // changedHtml = changedHtml.replaceAll('#333333', 'White'); 31 | // changedHtml = changedHtml.replaceAll('White', 'Black'); 32 | // changedHtml = changedHtml.replaceAll('#333333', 'White'); 33 | 34 | changedHtml = changedHtml.replaceAll('#006699', '#6F35A5'); 35 | changedHtml = changedHtml.replaceAll( 36 | '', 37 | ''); 38 | yield AllSessionalLoadedState(changedHtml); 39 | } on Exception catch (e) { 40 | yield SessionalErrorState( 41 | "Failed to load sessional marks!\nError : ${e.toString()}"); 42 | } 43 | } else 44 | yield SessionalErrorState("Failed to load sessional marks!"); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: ipecstudentsapp 2 | description: IPEC Student's App 3 | 4 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 5 | 6 | version: 5.0.1+36 7 | 8 | environment: 9 | sdk: '>=2.12.0 <3.0.0' 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | flutter_neumorphic: 15 | git: 16 | url: https://github.com/tsvillain/Flutter-Neumorphic.git 17 | adaptive_theme: ^2.2.0 18 | circular_profile_avatar: ^2.0.0 19 | cupertino_icons: ^1.0.3 20 | cached_network_image: ^3.2.0 21 | dio: ^4.0.0 22 | equatable: ^2.0.2 23 | # firebase_analytics: ^8.1.0 24 | polls: ^1.0.1 25 | introduction_screen: ^2.1.0 26 | firebase_auth: ^3.3.5 27 | firebase_core: ^1.11.0 28 | firebase_database: ^8.2.0 29 | firebase_messaging: ^11.2.5 30 | fl_chart: ^0.40.2 31 | flutter_bloc: ^7.1.0 32 | flutter_share: ^2.0.0 33 | flutter_svg: ^0.22.0 34 | flutter_markdown: ^0.6.10 35 | html: ^0.15.0 36 | intl: ^0.17.0 37 | lottie: ^1.0.1 38 | mantras: 39 | git: 40 | url: https://github.com/uttusharma/mantras.git 41 | provider: ^6.0.2 42 | share: ^2.0.1 43 | shared_preferences: ^2.0.5 44 | shimmer: ^2.0.0 45 | syncfusion_flutter_pdfviewer: ^19.3.55-beta 46 | url_launcher: ^6.0.4 47 | string_validator: ^0.3.0 48 | image_picker: ^0.8.0+1 49 | webview_flutter: ^2.0.7 50 | firebase_storage: ^8.1.1 51 | giphy_picker: ^2.0.0 52 | pull_to_refresh: ^2.0.0 53 | upgrader: ^3.10.0 54 | profanity_filter: ^2.0.0 55 | sweetsheet: ^0.3.1 56 | in_app_review: ^2.0.4 57 | is_first_run: ^1.0.0 58 | rainbow_color: ^2.0.1 59 | # to build in android remove this 60 | platform: ^3.1.0 61 | 62 | dev_dependencies: 63 | flutter_test: 64 | sdk: flutter 65 | flutter_launcher_icons: null 66 | flutter_native_splash: ^1.2.3 67 | # flutter_lints: ^1.0.0 68 | 69 | flutter: 70 | uses-material-design: true 71 | 72 | assets: 73 | - assets/images/ 74 | - assets/anim/ 75 | - assets/icons/ 76 | 77 | fonts: 78 | - family: averta 79 | fonts: 80 | - asset: fonts/averta/Averta-Regular.ttf 81 | - asset: fonts/averta/Averta-Bold.ttf 82 | weight: 500 83 | 84 | flutter_native_splash: 85 | image: assets/images/logo.png 86 | color: "#FFFFFF" 87 | -------------------------------------------------------------------------------- /lib/screens/dashboard/attendance/myLocalWebview.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:provider/provider.dart'; 3 | import 'package:webview_flutter/webview_flutter.dart'; 4 | 5 | import '../../../data/repo/session.dart'; 6 | 7 | class MyLocalWebView extends StatefulWidget { 8 | static const String = "/MyLocalWebview"; 9 | 10 | const MyLocalWebView({ 11 | Key? key, 12 | }) : super(key: key); 13 | 14 | @override 15 | _MyLocalWebViewState createState() => _MyLocalWebViewState(); 16 | } 17 | 18 | class _MyLocalWebViewState extends State { 19 | String html = 20 | "

Something went wrong😞!
If issue persists please reach out to @uttufy on instagram

"; 21 | 22 | @override 23 | void initState() { 24 | super.initState(); 25 | // if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView(); 26 | } 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | return Consumer( 31 | builder: (context, session, child) { 32 | return _getBody(session); 33 | }, 34 | ); 35 | } 36 | 37 | Widget _getBody(Session session) { 38 | if (session.attendanceStatus == AttendanceStatus.Loading) { 39 | return Center( 40 | child: CircularProgressIndicator( 41 | strokeWidth: 2, 42 | ), 43 | ); 44 | } else if (session.attendanceStatus == AttendanceStatus.Loaded) { 45 | _loadTable(session); 46 | return SafeArea( 47 | child: WebView( 48 | initialUrl: 49 | Uri.dataFromString(html, mimeType: 'text/html').toString(), 50 | gestureNavigationEnabled: true, 51 | ), 52 | ); 53 | } else if (session.attendanceStatus == AttendanceStatus.Init) 54 | return Center(child: Text('Intializing')); 55 | else 56 | return Center(child: Text('Something went wrong')); 57 | } 58 | 59 | void _loadTable(Session session) { 60 | try { 61 | html = session.getTable(); 62 | } catch (e) { 63 | print(e.toString()); 64 | html = 65 | "

Failed to parse table

${e.toString()}

"; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/screens/hangout/bloc/hangout/hangout_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_database/firebase_database.dart'; 2 | import 'package:html/parser.dart'; 3 | 4 | import '../../../../../data/base_bloc/base_bloc.dart'; 5 | import '../../../../../data/base_bloc/base_event.dart'; 6 | import '../../../../../data/base_bloc/base_state.dart'; 7 | import '../../../../data/model/GeneralResponse.dart'; 8 | import '../../../../data/model/hangout/hangUser.dart'; 9 | import '../../../../util/helper.dart'; 10 | import 'hangout_event.dart'; 11 | import 'hangout_state.dart'; 12 | 13 | class HangoutBloc extends BaseBloc { 14 | HangoutBloc(BaseState initialState) : super(initialState); 15 | 16 | @override 17 | BaseState get initialState => HangoutInitState(); 18 | 19 | @override 20 | Stream mapBaseEventToBaseState(BaseEvent event) async* { 21 | if (event is CheckUserEvent) { 22 | yield HangoutLoading(); 23 | 24 | final res = await checkUserExist(event.auth.user!.id); 25 | 26 | if (res['exists']) { 27 | final huser = Huser.fromMap(res['data']); 28 | print(huser.isBanned); 29 | if (huser.isBanned!) 30 | yield UserBannedState(); 31 | else 32 | yield UserExistState(huser); 33 | 34 | // update user profile 35 | 36 | GeneralResponse response = await event.session.webClientService 37 | .getMyProfile(event.auth.token.cookies); 38 | if (response.status) { 39 | var document = parse(response.data); 40 | String? depart = document 41 | .querySelector("#ContentPlaceHolder1_lblDepartment")! 42 | .attributes["value"]; 43 | 44 | String? yr = document 45 | .querySelector("#ContentPlaceHolder1_lblYear")! 46 | .attributes["value"]; 47 | 48 | String? section = document 49 | .querySelector("#ContentPlaceHolder1_lblBranch")! 50 | .attributes["value"]; 51 | 52 | FirebaseDatabase.instance 53 | .reference() 54 | .child('hangout') 55 | .child('user') 56 | .child(event.auth.user!.id) 57 | .update({"depart": depart, "yr": yr, "section": section}); 58 | } 59 | } else { 60 | yield UserNotExistState(); 61 | } 62 | } 63 | if (event is OnboardFinishEvent) { 64 | yield UserExistState(event.huser); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lib/screens/hangout/widget/linked_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:adaptive_theme/adaptive_theme.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:sweetsheet/sweetsheet.dart'; 4 | import 'package:url_launcher/url_launcher.dart'; 5 | 6 | import '../../../theme/style.dart'; 7 | 8 | class LinkWidget extends StatelessWidget { 9 | final String? url; 10 | 11 | LinkWidget( 12 | this.url, { 13 | Key? key, 14 | }) : super(key: key); 15 | 16 | _launchURL(String url) async { 17 | print(url); 18 | if (await canLaunch(url)) { 19 | await launch(url); 20 | } else { 21 | throw 'Could not launch $url'; 22 | } 23 | } 24 | 25 | final SweetSheet _sweetSheet = SweetSheet(); 26 | 27 | @override 28 | Widget build(BuildContext context) { 29 | final isDark = AdaptiveTheme.of(context).mode == AdaptiveThemeMode.dark; 30 | 31 | return Padding( 32 | padding: const EdgeInsets.symmetric(vertical: 10), 33 | child: InkWell( 34 | onTap: () { 35 | _sweetSheet.show( 36 | context: context, 37 | title: Text("Warning!"), 38 | description: Text( 39 | "Do you really want open link ? If 'yes' then press 'Open in browser' "), 40 | color: SweetSheetColor.NICE, 41 | icon: Icons.link, 42 | positive: SweetSheetAction( 43 | onPressed: () { 44 | _launchURL(url!); 45 | Navigator.of(context).pop(); 46 | }, 47 | title: 'OPEN IN BROWSER', 48 | icon: Icons.open_in_browser, 49 | ), 50 | negative: SweetSheetAction( 51 | onPressed: () { 52 | Navigator.of(context).pop(); 53 | }, 54 | title: 'CANCEL', 55 | ), 56 | ); 57 | }, 58 | child: Ink( 59 | padding: const EdgeInsets.all(10.0), 60 | decoration: BoxDecoration( 61 | color: isDark ? Colors.black45 : Colors.grey.shade200, 62 | borderRadius: BorderRadius.circular(10)), 63 | child: Row( 64 | children: [ 65 | Icon(Icons.link), 66 | kMedWidthPadding, 67 | Expanded( 68 | child: Text( 69 | url!, 70 | overflow: TextOverflow.ellipsis, 71 | )), 72 | ], 73 | ), 74 | ), 75 | ), 76 | ); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /lib/widgets/simple_appbar.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:adaptive_theme/adaptive_theme.dart'; 4 | import 'package:flutter/material.dart'; 5 | 6 | import '../util/SizeConfig.dart'; 7 | 8 | class SimpleAppBar extends StatelessWidget { 9 | final img; 10 | final VoidCallback? onPic; 11 | final VoidCallback onBack; 12 | final Color? bgColor; 13 | final String? title; 14 | const SimpleAppBar( 15 | {Key? key, 16 | this.img, 17 | this.onPic, 18 | required this.onBack, 19 | this.title, 20 | this.bgColor = Colors.transparent}) 21 | : super(key: key); 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | final isDark = AdaptiveTheme.of(context).mode == AdaptiveThemeMode.dark; 26 | return Container( 27 | color: bgColor, 28 | child: Padding( 29 | padding: const EdgeInsets.all(5.0), 30 | child: Row( 31 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 32 | children: [ 33 | InkWell( 34 | onTap: onBack, 35 | borderRadius: BorderRadius.circular(50), 36 | child: Ink( 37 | padding: const EdgeInsets.all(10), 38 | child: Icon( 39 | Icons.chevron_left, 40 | size: 30, 41 | ), 42 | ), 43 | ), 44 | img != null 45 | ? GestureDetector( 46 | onTap: onPic, 47 | child: Padding( 48 | padding: const EdgeInsets.symmetric(horizontal: 20.0), 49 | child: CircleAvatar( 50 | backgroundColor: Colors.white, 51 | radius: SizeConfig.widthMultiplier * 5, 52 | backgroundImage: MemoryImage( 53 | base64Decode(img), 54 | ), 55 | ), 56 | ), 57 | ) 58 | : Padding( 59 | padding: const EdgeInsets.symmetric(horizontal: 20.0), 60 | child: Text( 61 | title!, 62 | style: Theme.of(context).textTheme.headline5!.copyWith( 63 | color: isDark ? Colors.white : Colors.black, 64 | fontWeight: FontWeight.bold), 65 | ), 66 | ), 67 | ], 68 | ), 69 | ), 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /lib/data/bad_hindi_words.dart: -------------------------------------------------------------------------------- 1 | // https://github.com/",LDNOOBW/List-of-Dirty-Naughty-Obscene-and-Otherwise-Bad-Words 2 | List badwordsHindi = const [ 3 | "aandu", 4 | "aand", 5 | "balatkar", 6 | "balatkari", 7 | "behen chod", 8 | "beti chod", 9 | "bhadva", 10 | "bhadve", 11 | "bhandve", 12 | "bhangi", 13 | "bhootni ke", 14 | "bhosad", 15 | "bhosadi ke", 16 | "boobe", 17 | "chakke", 18 | "chinaal", 19 | "chinki", 20 | "chod", 21 | "chodu", 22 | "chodu bhagat", 23 | "chooche", 24 | "choochi", 25 | "choope", 26 | "choot", 27 | "choot ke baal", 28 | "chootia", 29 | "chootiya", 30 | "chuche", 31 | "chuchi", 32 | "chudaap", 33 | "chudai khanaa", 34 | "chudam chudai", 35 | "chude", 36 | "chut", 37 | "chut ka chuha", 38 | "chut ka churan", 39 | "chut ka mail", 40 | "chut ke baal", 41 | "chut ke dhakkan", 42 | "chut maarli", 43 | "chutad", 44 | "chutadd", 45 | "chutan", 46 | "chutia", 47 | "chutiya", 48 | "gaand", 49 | "gaandfat", 50 | "gaandmasti", 51 | "gaandufad", 52 | "gandfattu", 53 | "gandu", 54 | "gashti", 55 | "gasti", 56 | "ghassa", 57 | "ghasti", 58 | "gucchi", 59 | "gucchu", 60 | "harami", 61 | "haramzade", 62 | "hawas", 63 | "hawas ke pujari", 64 | "hijda", 65 | "hijra", 66 | "jhant", 67 | "jhant chaatu", 68 | "jhant ka keeda", 69 | "jhant ke baal", 70 | "jhant ke pissu", 71 | "jhantu", 72 | "kamine", 73 | "kaminey", 74 | "kanjar", 75 | "kutta", 76 | "kutta kamina", 77 | "kutte ki aulad", 78 | "kutte ki jat", 79 | "kuttiya", 80 | "loda", 81 | "lodu", 82 | "lund", 83 | "lund choos", 84 | "lund ka bakkal", 85 | "lund khajoor", 86 | "lundtopi", 87 | "lundure", 88 | "maa ki chut", 89 | "maal", 90 | "madar chod", 91 | "madarchod", 92 | "madhavchod", 93 | "mooh mein le", 94 | "mutth", 95 | "mutthal", 96 | "najayaz", 97 | "najayaz aulaad", 98 | "najayaz paidaish", 99 | "paki", 100 | "pataka", 101 | "patakha", 102 | "raand", 103 | "randaap", 104 | "randi", 105 | "randi rona", 106 | "saala", 107 | "saala kutta", 108 | "saali kutti", 109 | "saali randi", 110 | "suar", 111 | "suar ke lund", 112 | "suar ki aulad", 113 | "tatte", 114 | "tatti", 115 | "teri maa ka bhosada", 116 | "teri maa ka boba chusu", 117 | "teri maa ki behenchod ", 118 | "teri maa ki chut", 119 | "tharak", 120 | "tharki", 121 | "tu chuda" 122 | ]; 123 | -------------------------------------------------------------------------------- /lib/theme/style.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'colors.dart'; 4 | 5 | ThemeData appTheme = new ThemeData( 6 | hintColor: Colors.white, 7 | brightness: Brightness.light, 8 | fontFamily: 'Averta', 9 | primaryColor: kPrimaryColor, 10 | scaffoldBackgroundColor: Colors.white, 11 | textTheme: TextTheme( 12 | headline1: TextStyle(fontWeight: FontWeight.w500, color: Colors.black), 13 | headline4: TextStyle(fontWeight: FontWeight.bold, color: Colors.black), 14 | headline5: TextStyle(fontWeight: FontWeight.bold, color: Colors.black), 15 | headline6: TextStyle(fontWeight: FontWeight.bold, color: Colors.black), 16 | // bodyText2: TextStyle(fontSize: 14.0, fontFamily: 'Hind'), 17 | ), 18 | // inputDecorationTheme: InputDecorationTheme( 19 | // // fillColor: kLighterGrey, 20 | // // filled: true, 21 | // border: OutlineInputBorder( 22 | // borderSide: BorderSide.none, 23 | // borderRadius: BorderRadius.circular(kLowCircleRadius), 24 | // ), 25 | // ), 26 | ); 27 | ThemeData appdarkTheme = new ThemeData( 28 | brightness: Brightness.dark, 29 | fontFamily: 'Averta', 30 | primaryColor: kPrimaryColor, 31 | scaffoldBackgroundColor: kDarkBg, 32 | textTheme: TextTheme( 33 | headline1: TextStyle(fontWeight: FontWeight.w500, color: Colors.white), 34 | headline4: TextStyle(fontWeight: FontWeight.bold, color: Colors.white), 35 | headline5: TextStyle(fontWeight: FontWeight.bold, color: Colors.white), 36 | headline6: TextStyle(fontWeight: FontWeight.bold, color: Colors.white), 37 | // bodyText2: TextStyle(fontSize: 14.0, fontFamily: 'Hind'), 38 | ), 39 | // inputDecorationTheme: InputDecorationTheme( 40 | // // fillColor: kLighterGrey, 41 | // // filled: true, 42 | // border: OutlineInputBorder( 43 | // borderSide: BorderSide.none, 44 | // borderRadius: BorderRadius.circular(kLowCircleRadius), 45 | // ), 46 | // ), 47 | ); 48 | 49 | const kLowCircleRadius = 20.0; 50 | const kMedCircleRadius = 30.0; 51 | 52 | // Text 53 | const kHeadingSize = 4.0; 54 | const kBodySize = 3.0; 55 | const kParagraphSize = 2.0; 56 | 57 | //Padding 58 | const kLowPadding = SizedBox( 59 | height: 10, 60 | ); 61 | const kMedPadding = SizedBox( 62 | height: 20, 63 | ); 64 | const kHighPadding = SizedBox( 65 | height: 30, 66 | ); 67 | 68 | const kLowWidthPadding = SizedBox( 69 | width: 10, 70 | ); 71 | const kMedWidthPadding = SizedBox( 72 | width: 20, 73 | ); 74 | const kHighWidthPadding = SizedBox( 75 | width: 30, 76 | ); 77 | 78 | const kBoldH3 = TextStyle(fontWeight: FontWeight.bold); 79 | -------------------------------------------------------------------------------- /lib/screens/about/about_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:circular_profile_avatar/circular_profile_avatar.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:ipecstudentsapp/theme/colors.dart'; 4 | 5 | import '../../theme/style.dart'; 6 | 7 | Column aboutWidget( 8 | BuildContext context, 9 | String url, 10 | String intial, 11 | String name, 12 | Function ontap, 13 | Function onTap2, 14 | bool isDark, 15 | ) { 16 | return Column( 17 | crossAxisAlignment: CrossAxisAlignment.center, 18 | children: [ 19 | profileImage(url, intial, ontap), 20 | kMedPadding, 21 | GestureDetector( 22 | onTap: () { 23 | onTap2(); 24 | }, 25 | child: Column( 26 | crossAxisAlignment: CrossAxisAlignment.center, 27 | children: [ 28 | Text( 29 | name, 30 | overflow: TextOverflow.ellipsis, 31 | style: Theme.of(context).textTheme.headline6!.copyWith( 32 | color: isDark ? Colors.white : Colors.black, 33 | fontWeight: FontWeight.bold), 34 | ), 35 | Text( 36 | "I.T Batch 2019-2022", 37 | overflow: TextOverflow.ellipsis, 38 | style: Theme.of(context).textTheme.bodyText1!.copyWith( 39 | color: isDark ? Colors.white : Colors.black, 40 | ), 41 | ), 42 | ], 43 | ), 44 | ), 45 | ], 46 | ); 47 | } 48 | 49 | Widget profileImage(String image, String intial, Function onTap) { 50 | return CircularProfileAvatar( 51 | image, //sets image path, it should be a URL string. default value is empty string, if path is empty it will display only initials 52 | radius: 100, // sets radius, default 50.0 53 | backgroundColor: kBlue, // sets background color, default Colors.white 54 | borderWidth: 1, // sets border, default 0.0 55 | initialsText: Text( 56 | intial, 57 | style: TextStyle( 58 | fontSize: 40, color: Colors.white, fontWeight: FontWeight.bold), 59 | ), // sets initials text, set your own style, default Text('') 60 | // borderColor: Colors.blue, // sets border color, default Colors.white 61 | elevation: 62 | 10.0, // sets elevation (shadow of the profile picture), default value is 0.0 63 | 64 | cacheImage: true, // allow widget to cache image against provided url 65 | onTap: () { 66 | onTap(); 67 | }, // sets on tap 68 | 69 | showInitialTextAbovePicture: 70 | false, // setting it true will show initials text above profile picture, default false 71 | ); 72 | } 73 | -------------------------------------------------------------------------------- /lib/data/local/shared_pref.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:shared_preferences/shared_preferences.dart'; 4 | 5 | import 'saver_keys.dart'; 6 | 7 | class LocalData { 8 | static final LocalData _singleton = LocalData._internal(); 9 | 10 | factory LocalData() { 11 | return _singleton; 12 | } 13 | 14 | LocalData._internal(); 15 | 16 | final kUsername = 'username'; 17 | final kPassword = 'password'; 18 | final kName = 'name'; 19 | final kImage = 'userImage'; 20 | final kLoginStatus = 'userImage'; 21 | final kCookie = 'cookie'; 22 | Future saveUserPreference( 23 | String username, String password, String name, String userImage, 24 | {bool loginStatus = true}) async { 25 | SharedPreferences prefs = await SharedPreferences.getInstance(); 26 | // FIXME: REMOVE LINE BELOW INORDER TO BUILD 27 | removeMeInOrderToBuild( 28 | kUsername, kPassword, username, password, kName, name); 29 | prefs.setString(kUsername, username); 30 | prefs.setString(kPassword, password); 31 | prefs.setString(kName, name); 32 | prefs.setString(kImage, userImage); 33 | prefs.setBool(kLoginStatus, loginStatus); 34 | } 35 | 36 | Future getUsername() async { 37 | SharedPreferences prefs = await SharedPreferences.getInstance(); 38 | return prefs.get(kUsername) as FutureOr; 39 | } 40 | 41 | Future getPassword() async { 42 | SharedPreferences prefs = await SharedPreferences.getInstance(); 43 | return prefs.get(kPassword) as FutureOr; 44 | } 45 | 46 | Future getImagePreference() async { 47 | SharedPreferences prefs = await SharedPreferences.getInstance(); 48 | return prefs.get(kImage) as FutureOr; 49 | } 50 | 51 | Future getNamePreference() async { 52 | SharedPreferences prefs = await SharedPreferences.getInstance(); 53 | return prefs.get(kName) as FutureOr; 54 | } 55 | 56 | Future setLogout() async { 57 | SharedPreferences prefs = await SharedPreferences.getInstance(); 58 | prefs.setBool(kLoginStatus, false); 59 | } 60 | 61 | Future saveCookie(String cookie) async { 62 | SharedPreferences prefs = await SharedPreferences.getInstance(); 63 | prefs.setString(kCookie, cookie); 64 | } 65 | 66 | Future getCookie() async { 67 | SharedPreferences prefs = await SharedPreferences.getInstance(); 68 | return prefs.get(kCookie) as FutureOr; 69 | } 70 | 71 | Future getLoginStatus() async { 72 | SharedPreferences prefs = await SharedPreferences.getInstance(); 73 | return prefs.get(kLoginStatus) as FutureOr; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lib/data/base_bloc/base_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc/bloc.dart'; 2 | import 'package:dio/dio.dart'; 3 | import 'package:flutter/services.dart'; 4 | 5 | import 'base_event.dart'; 6 | import 'base_state.dart'; 7 | 8 | abstract class BaseBloc 9 | extends Bloc { 10 | BaseBloc(BaseState initialState) : super(initialState); 11 | 12 | get initialState => initialState; 13 | 14 | Stream mapEventToState(BaseEvent event) async* { 15 | print(">>>>>>>>>>>>> BaseBloc Event ${event.toString()}"); 16 | 17 | if (event is ShowSnackBarErrorEvent) { 18 | yield ShowSnackBarErrorState(event.error); 19 | } 20 | 21 | if (event is PlaceHolderEvent) { 22 | yield PlaceHolderState(); 23 | } 24 | 25 | if (event is ShowDialogInfoEvent) { 26 | yield ShowDialogInfoState(event.title, event.message); 27 | } 28 | 29 | if (event is ShowDialogErrorEvent) { 30 | yield ShowDialogErrorState(event.error); 31 | } 32 | 33 | if (event is InitStateEvent) { 34 | yield InitState(); 35 | } 36 | 37 | if (event is LogoutEvent) { 38 | yield LogoutState(); 39 | } 40 | 41 | yield* mapBaseEventToBaseState(event as E); 42 | } 43 | 44 | Stream mapBaseEventToBaseState(E event); 45 | 46 | bool resetToInitStateOnError() => false; 47 | 48 | @override 49 | void onError(Object error, StackTrace stackTrace) { 50 | print("On Error"); 51 | print(error.toString()); 52 | print(stackTrace.toString()); 53 | 54 | if (resetToInitStateOnError()) { 55 | add(InitStateEvent()); 56 | } 57 | 58 | if (error is DioError) { 59 | errorHandlerEvent(error); 60 | } else { 61 | String? errorMessage; 62 | if (error is PlatformException) { 63 | errorMessage = error.message; 64 | } 65 | 66 | add(ShowDialogErrorEvent(errorMessage ?? error.toString())); 67 | } 68 | super.onError(error, stackTrace); 69 | } 70 | 71 | void errorHandlerEvent(DioError error) { 72 | if (error.type == DioErrorType.response) { 73 | add(ShowDialogErrorEvent( 74 | "Something went wrong : " + error.message.toString())); 75 | } 76 | 77 | if (error.type == DioErrorType.connectTimeout || 78 | error.type == DioErrorType.receiveTimeout || 79 | error.type == DioErrorType.sendTimeout) { 80 | add(ShowDialogErrorEvent( 81 | "Connection Time Out : " + error.message.toString())); 82 | } 83 | if (error.type == DioErrorType.other) { 84 | add(ShowDialogErrorEvent( 85 | "Something went wrong : " + error.message.toString())); 86 | } 87 | } 88 | } 89 | 90 | class DataRepo {} 91 | -------------------------------------------------------------------------------- /lib/data/model/hangout/comment.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'hangUser.dart'; 4 | 5 | class CommentModel { 6 | String? commentId; 7 | final String? id; 8 | final Huser author; 9 | final String? authorImage; 10 | final int? postedOn; 11 | final String? text; 12 | int? reports; 13 | final bool? isGif; 14 | final String? gifUrl; 15 | CommentModel({ 16 | this.commentId = "", 17 | required this.id, 18 | required this.author, 19 | required this.authorImage, 20 | required this.postedOn, 21 | required this.text, 22 | required this.reports, 23 | required this.isGif, 24 | required this.gifUrl, 25 | }); 26 | 27 | Map toMap() { 28 | return { 29 | 'commentId': commentId, 30 | 'id': id, 31 | 'author': author.toMap(), 32 | 'authorImage': authorImage, 33 | 'postedOn': postedOn, 34 | 'text': text, 35 | 'reports': reports, 36 | 'isGif': isGif, 37 | 'gifUrl': gifUrl, 38 | }; 39 | } 40 | 41 | factory CommentModel.fromMap(Map map) { 42 | return CommentModel( 43 | commentId: map['commentId'], 44 | id: map['id'], 45 | author: Huser.fromMap(map['author']), 46 | authorImage: map['authorImage'], 47 | postedOn: map['postedOn'], 48 | text: map['text'], 49 | reports: map['reports'], 50 | isGif: map['isGif'], 51 | gifUrl: map['gifUrl'], 52 | ); 53 | } 54 | 55 | factory CommentModel.fromSnapshot(data, indivisualKey) { 56 | CommentModel commentItem = new CommentModel( 57 | commentId: indivisualKey, 58 | id: data[indivisualKey]['id'], 59 | author: Huser.fromMap(data[indivisualKey]['author']), 60 | authorImage: data[indivisualKey]['authorImage'], 61 | postedOn: data[indivisualKey]['postedOn'], 62 | text: data[indivisualKey]['text'], 63 | reports: data[indivisualKey]['reports'], 64 | gifUrl: data[indivisualKey]['gifUrl'], 65 | isGif: data[indivisualKey]['isGif']); 66 | return commentItem; 67 | } 68 | 69 | String toJson() => json.encode(toMap()); 70 | 71 | factory CommentModel.fromJson(String source) => 72 | CommentModel.fromMap(json.decode(source)); 73 | 74 | @override 75 | bool operator ==(Object other) { 76 | if (identical(this, other)) return true; 77 | 78 | return other is CommentModel && other.id == id; 79 | } 80 | 81 | @override 82 | int get hashCode { 83 | return id.hashCode ^ 84 | author.hashCode ^ 85 | authorImage.hashCode ^ 86 | postedOn.hashCode ^ 87 | text.hashCode ^ 88 | reports.hashCode ^ 89 | isGif.hashCode ^ 90 | gifUrl.hashCode; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /lib/data/model/Attendance.dart: -------------------------------------------------------------------------------- 1 | class Attendance { 2 | double? presentPercent; 3 | String? totalLectures; 4 | String? presentLecture; 5 | String? sipPresentClasses; 6 | String? sipTotalClasses; 7 | String? sessionalPresent; 8 | String? sessionalTotal; 9 | String? extra; 10 | String? cummulativeTotalLectures; 11 | 12 | double? percent; 13 | Attendance( 14 | {this.percent, 15 | this.presentPercent, 16 | this.presentLecture, 17 | this.totalLectures, 18 | this.sipPresentClasses, 19 | this.sipTotalClasses, 20 | this.sessionalPresent, 21 | this.sessionalTotal, 22 | this.cummulativeTotalLectures, 23 | this.extra}); 24 | 25 | double? getPresentPercent() => presentPercent; 26 | double getAbsentPercent() => (100 - percent!); 27 | String? getTotalLectures() { 28 | return totalLectures; 29 | } 30 | 31 | String getPresentLectures() { 32 | if (presentLecture!.toLowerCase().contains('extra')) 33 | return presentLecture!.split('=')[1].split(':')[1].replaceAll(")", ""); 34 | else 35 | return presentLecture!.split(":")[1].replaceAll(")", ""); 36 | } 37 | 38 | void setCummulativeAttendance() { 39 | int ex = (int.tryParse(extra!) ?? 0); 40 | int pl = (int.tryParse(presentLecture!) ?? 0); 41 | cummulativeTotalLectures = (ex + pl).toString(); 42 | } 43 | 44 | String getAttendanceMessage() { 45 | double attendance = percent!; 46 | if (attendance > 100) { 47 | return "This feels like illegal :)"; 48 | } 49 | if (attendance == 100) { 50 | return "God Level! 🙏👑👏"; 51 | } 52 | if (90 <= attendance) { 53 | return "I know you love attending classes 😌"; 54 | } 55 | if (80 <= attendance) { 56 | return "Safezone! Keep on maintaining\nit! 🌠🌈"; 57 | } 58 | if (75 <= attendance) { 59 | return "Pheww...You are Safe ! 👏😁"; 60 | } 61 | if (65 <= attendance) { 62 | return "Oh!no...Short Attendance! 😱"; 63 | } 64 | if (50 <= attendance) { 65 | return "Daredevil Attend more Classes 😈"; 66 | } 67 | if (attendance < 50 && attendance != 0) { 68 | return "Classes are calling attend them 🐱🔥"; 69 | } 70 | if (attendance == 0) { 71 | return "Zero-zero is a big score! 🌸"; 72 | } 73 | return "Attendance Loaded :)"; 74 | } 75 | 76 | @override 77 | String toString() { 78 | return 'Attendance(presentPercent: $presentPercent, totalLectures: $totalLectures, presentLecture: $presentLecture, sipPresentClasses: $sipPresentClasses, sipTotalClasses: $sipTotalClasses, sessionalPresent: $sessionalPresent, sessionalTotal: $sessionalTotal, extra: $extra, cummulativeTotalLectures: $cummulativeTotalLectures, percent: $percent)'; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lib/screens/loading/bloc/loading_bloc.dart: -------------------------------------------------------------------------------- 1 | import '../../../data/base_bloc/base_bloc.dart'; 2 | import '../../../data/base_bloc/base_event.dart'; 3 | import '../../../data/base_bloc/base_state.dart'; 4 | import '../../../data/local/shared_pref.dart'; 5 | import '../../../data/model/GeneralResponse.dart'; 6 | import '../../../util/SugarParse.dart'; 7 | import 'loading_event.dart'; 8 | import 'loading_state.dart'; 9 | 10 | class LoadingBloc extends BaseBloc { 11 | LoadingBloc(BaseState initialState) : super(initialState); 12 | 13 | @override 14 | BaseState get initialState => LoadingInitState(); 15 | 16 | @override 17 | Stream mapBaseEventToBaseState(BaseEvent event) async* { 18 | LocalData _localData = LocalData(); 19 | if (event is ResetState) yield LoadingInitState(); 20 | 21 | if (event is CheckCredentials) { 22 | try { 23 | GeneralResponse response = await event.auth 24 | .login(event.auth.cred!.username!, event.auth.cred!.password); 25 | if (response.status) { 26 | event.auth.user = 27 | SugarParser().user(response.data.data, event.auth.cred!.username); 28 | 29 | await _localData.saveUserPreference( 30 | event.auth.cred!.username!, 31 | event.auth.cred!.password!, 32 | event.auth.user!.name!, 33 | event.auth.user!.img); 34 | await Future.delayed(Duration(milliseconds: 50)); 35 | yield AuthenticatedState(); 36 | } else { 37 | // Invalid Cred probably so trying again 38 | await Future.delayed(Duration(seconds: 1)); 39 | GeneralResponse response = await event.auth 40 | .login(event.auth.cred!.username!, event.auth.cred!.password); 41 | if (response.status) { 42 | event.auth.user = SugarParser() 43 | .user(response.data.data, event.auth.cred!.username); 44 | 45 | await _localData.saveUserPreference( 46 | event.auth.cred!.username!, 47 | event.auth.cred!.password!, 48 | event.auth.user!.name!, 49 | event.auth.user!.img); 50 | await Future.delayed(Duration(milliseconds: 50)); 51 | yield AuthenticatedState(); 52 | } else { 53 | // Invalid Cred confirm 54 | yield LoginFailState(); 55 | await Future.delayed(Duration(seconds: 2)); 56 | yield CloseLoadingState(); 57 | } 58 | // yield LoginFailState(); 59 | // await Future.delayed(Duration(seconds: 2)); 60 | // yield CloseLoadingState(); 61 | } 62 | } on Exception catch (e) { 63 | yield ShowDialogErrorState(e.toString()); 64 | yield CloseLoadingState(); 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/widgets/progress_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../theme/colors.dart'; 4 | import '../theme/style.dart'; 5 | 6 | class ProgressDialog { 7 | static final ProgressDialog _instance = ProgressDialog._internal(); 8 | 9 | static ProgressDialog getInstance() => _instance; 10 | 11 | ProgressDialog._internal(); 12 | 13 | bool isShowing = false; 14 | BuildContext? context; 15 | 16 | void hide({BuildContext? context}) { 17 | if (isShowing) { 18 | isShowing = false; 19 | if (Navigator.of(this.context ?? context!).mounted && 20 | Navigator.of(this.context ?? context!).canPop()) { 21 | Navigator.of(this.context ?? context!).pop(); 22 | print('ProgressDialog dismissed'); 23 | } 24 | } 25 | } 26 | 27 | void show(BuildContext context, String message) { 28 | this.context = context; 29 | print('ProgressDialog shown'); 30 | 31 | if (isShowing) { 32 | hide(context: context); 33 | } 34 | 35 | isShowing = true; 36 | 37 | showDialog( 38 | context: context, 39 | barrierDismissible: false, 40 | builder: (BuildContext context) { 41 | // _context = context; 42 | return Dialog( 43 | elevation: 10.0, 44 | shape: RoundedRectangleBorder( 45 | borderRadius: 46 | BorderRadius.all(Radius.circular(kMedCircleRadius))), 47 | child: Padding( 48 | padding: EdgeInsets.all(20), 49 | child: _MyDialog(message), 50 | ), 51 | ); 52 | }, 53 | ); 54 | } 55 | } 56 | 57 | // ignore: must_be_immutable 58 | class _MyDialog extends StatefulWidget { 59 | String message; 60 | 61 | _MyDialog(this.message); 62 | 63 | @override 64 | State createState() { 65 | return _MyDialogState(this.message); 66 | } 67 | } 68 | 69 | class _MyDialogState extends State<_MyDialog> { 70 | String message; 71 | 72 | _MyDialogState(this.message); 73 | 74 | @override 75 | void initState() { 76 | super.initState(); 77 | } 78 | 79 | @override 80 | Widget build(BuildContext context) { 81 | return Container( 82 | padding: EdgeInsets.all(10), 83 | child: Row( 84 | children: [ 85 | SizedBox( 86 | child: CircularProgressIndicator( 87 | strokeWidth: 2, 88 | backgroundColor: kLighterGrey, 89 | ), 90 | ), 91 | kMedWidthPadding, 92 | Expanded( 93 | child: Text( 94 | message, 95 | textAlign: TextAlign.justify, 96 | ), 97 | ), 98 | ], 99 | ), 100 | ); 101 | } 102 | 103 | @override 104 | void dispose() { 105 | super.dispose(); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /lib/data/model/hangout/hangUser.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | class Huser { 4 | String? id; 5 | String? name; 6 | String? email; 7 | String? gender; 8 | String? phone; 9 | String? depart; 10 | String? yr; 11 | String? section; 12 | String? profile; 13 | bool? isBanned; 14 | AddtionalUserInfo? addtionalUserInfo; 15 | List likes = []; 16 | Huser( 17 | {required this.id, 18 | required this.name, 19 | required this.email, 20 | required this.gender, 21 | required this.phone, 22 | required this.depart, 23 | required this.yr, 24 | required this.section, 25 | required this.likes, 26 | this.addtionalUserInfo, 27 | this.isBanned = false}); 28 | 29 | Map toMap() { 30 | return { 31 | 'id': id, 32 | 'name': name, 33 | 'email': email, 34 | 'gender': gender, 35 | 'phone': phone, 36 | 'depart': depart, 37 | 'yr': yr, 38 | 'section': section, 39 | 'isBanned': isBanned, 40 | 'likes': likes, 41 | 'additionalUserInfo': addtionalUserInfo?.toMap() ?? {}, 42 | }; 43 | } 44 | 45 | factory Huser.fromMap(Map map) { 46 | return Huser( 47 | id: map['id'], 48 | name: map['name'], 49 | email: map['email'], 50 | gender: map['gender'], 51 | phone: map['phone'], 52 | depart: map['depart'], 53 | yr: map['yr'], 54 | section: map['section'], 55 | isBanned: map['isBanned'], 56 | likes: map['likes'] != null ? List.from(map['likes']) : [], 57 | addtionalUserInfo: map['additionalUserInfo'] != null 58 | ? AddtionalUserInfo.fromMap(map['additionalUserInfo']) 59 | : null); 60 | } 61 | 62 | String toJson() => json.encode(toMap()); 63 | 64 | factory Huser.fromJson(String source) => Huser.fromMap(json.decode(source)); 65 | } 66 | 67 | class AddtionalUserInfo { 68 | String? profileImg; 69 | String? bio; 70 | String? insta; 71 | String? snapchat; 72 | AddtionalUserInfo({ 73 | this.profileImg, 74 | this.bio, 75 | this.insta, 76 | this.snapchat, 77 | }); 78 | 79 | Map toMap() { 80 | return { 81 | 'profileImg': profileImg, 82 | 'bio': bio, 83 | 'insta': insta, 84 | 'snapchat': snapchat, 85 | }; 86 | } 87 | 88 | factory AddtionalUserInfo.fromMap(Map map) { 89 | return AddtionalUserInfo( 90 | profileImg: map['profileImg'], 91 | bio: map['bio'], 92 | insta: map['insta'], 93 | snapchat: map['snapchat'], 94 | ); 95 | } 96 | 97 | String toJson() => json.encode(toMap()); 98 | 99 | factory AddtionalUserInfo.fromJson(String source) => 100 | AddtionalUserInfo.fromMap(json.decode(source)); 101 | } 102 | -------------------------------------------------------------------------------- /lib/data/repo/auth.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:html/parser.dart'; 3 | 4 | import '../local/shared_pref.dart'; 5 | import '../model/Cred.dart'; 6 | import '../model/GeneralResponse.dart'; 7 | import '../model/TokensModel.dart'; 8 | import '../model/User.dart'; 9 | import '../service/webClientService.dart'; 10 | 11 | class Auth extends ChangeNotifier { 12 | WebClientService _webClient = WebClientService(); 13 | 14 | Tokens _tokens = Tokens(); 15 | 16 | User? _user; 17 | 18 | Cred? _cred; 19 | // ignore: unnecessary_getters_setters 20 | User? get user => _user; 21 | // ignore: unnecessary_getters_setters 22 | set user(User? u) => _user = u; 23 | // ignore: unnecessary_getters_setters 24 | Cred? get cred => _cred; 25 | // ignore: unnecessary_getters_setters 26 | set cred(Cred? u) => _cred = u; 27 | 28 | Tokens get token => _tokens; 29 | 30 | // Handle Login 31 | // Step 1: Get Cookies 32 | Future login(String username, String? password) async { 33 | GeneralResponse response = await _webClient.getLoginToken(); 34 | 35 | username = username.trim(); 36 | 37 | print(response.status); 38 | if (response.status) { 39 | _tokens.cookies = 40 | response.data?.headers?.map['set-cookie']?.elementAt(0) ?? ""; 41 | 42 | // Step 2: Prepare formData for Login 43 | var document = parse(response.data.data); 44 | 45 | _tokens.viewState = 46 | document.querySelector('#__VIEWSTATE')!.attributes['value']; 47 | _tokens.viewStateGenerator = 48 | document.querySelector('#__VIEWSTATEGENERATOR')!.attributes['value']; 49 | _tokens.eventValidation = 50 | document.querySelector('#__EVENTVALIDATION')!.attributes['value']; 51 | String btnTarget = document.getElementsByTagName('button')[0].id; 52 | // Form Data for POST 53 | Map formData = { 54 | '__LASTFOCUS': '', 55 | '__EVENTTARGET': btnTarget, 56 | '__EVENTARGUMENT': '', 57 | '__VIEWSTATE': _tokens.viewState, 58 | '__VIEWSTATEGENERATOR': _tokens.viewStateGenerator, 59 | '__EVENTVALIDATION': _tokens.eventValidation, 60 | 'txtUser': '$username', 61 | 'txtPassword': '$password' 62 | }; 63 | // Submit login Request 64 | GeneralResponse postResponse = 65 | await _webClient.postLogin(formData, _tokens.cookies); 66 | print(postResponse.data); 67 | if (postResponse.status) { 68 | // Login Success 69 | return postResponse; 70 | } else { 71 | // Invalid Credentials 72 | return GeneralResponse( 73 | status: false, 74 | error: "Invalid Credentials", 75 | data: postResponse.data); 76 | } 77 | } else 78 | return response; 79 | } 80 | 81 | Future logout() async { 82 | LocalData _local = LocalData(); 83 | await _local.setLogout(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IPEC Student's App 2 | 3 | A Flutter project for IPEC mobile app. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply plugin: 'com.google.gms.google-services' 27 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 28 | 29 | def multidex_version = "2.0.1" 30 | 31 | def keystoreProperties = new Properties() 32 | def keystorePropertiesFile = rootProject.file('key.properties') 33 | if (keystorePropertiesFile.exists()) { 34 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) 35 | } 36 | 37 | android { 38 | compileSdkVersion 31 39 | 40 | compileOptions { 41 | sourceCompatibility JavaVersion.VERSION_1_8 42 | targetCompatibility JavaVersion.VERSION_1_8 43 | } 44 | 45 | kotlinOptions { 46 | jvmTarget = '1.8' 47 | } 48 | 49 | sourceSets { 50 | main.java.srcDirs += 'src/main/kotlin' 51 | } 52 | 53 | lintOptions { 54 | disable 'InvalidPackage' 55 | } 56 | 57 | defaultConfig { 58 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 59 | applicationId "com.uttu.ipecstudentsapp" 60 | minSdkVersion 19 61 | targetSdkVersion 30 62 | versionCode flutterVersionCode.toInteger() 63 | versionName flutterVersionName 64 | multiDexEnabled true 65 | 66 | } 67 | 68 | signingConfigs { 69 | release { 70 | keyAlias keystoreProperties['keyAlias'] 71 | keyPassword keystoreProperties['keyPassword'] 72 | storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null 73 | storePassword keystoreProperties['storePassword'] 74 | } 75 | } 76 | buildTypes { 77 | release { 78 | signingConfig signingConfigs.release 79 | } 80 | } 81 | } 82 | 83 | flutter { 84 | source '../..' 85 | } 86 | 87 | dependencies { 88 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 89 | implementation "androidx.multidex:multidex:$multidex_version" 90 | // implementation platform('com.google.firebase:firebase-bom:26.1.1') 91 | // implementation 'com.google.firebase:firebase-analytics-ktx' 92 | 93 | } 94 | 95 | 96 | -------------------------------------------------------------------------------- /lib/data/base_bloc/base_bloc_listener.dart: -------------------------------------------------------------------------------- 1 | // import 'package:bloc/bloc.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/widgets.dart'; 4 | import 'package:flutter_bloc/flutter_bloc.dart'; 5 | 6 | import '../../widgets/general_dialog.dart'; 7 | import '../../widgets/progress_dialog.dart'; 8 | import 'base_bloc.dart'; 9 | import 'base_event.dart'; 10 | import 'base_state.dart'; 11 | 12 | class BaseBlocListener 13 | extends BlocListenerBase { 14 | /// The [Bloc] whose state will be listened to. 15 | /// Whenever the bloc's state changes, `listener` will be invoked. 16 | final B bloc; 17 | 18 | /// The [BlocWidgetListener] which will be called on every state change (including the `initialState`). 19 | /// This listener should be used for any code which needs to execute 20 | /// in response to a state change (`Transition`). 21 | /// The state will be the `nextState` for the most recent `Transition`. 22 | // final BlocWidgetListener listener; 23 | 24 | /// The [Widget] which will be rendered as a descendant of the [BlocListener]. 25 | final Widget? child; 26 | 27 | final ProgressDialog? pd = null; 28 | 29 | BaseBlocListener({ 30 | Key? key, 31 | required this.bloc, 32 | required BlocWidgetListener listener, 33 | this.child, 34 | }) : assert((bloc is BaseBloc), "Bloc should be instance of BaseBlock !!"), 35 | super( 36 | key: key, 37 | bloc: bloc, 38 | child: child, 39 | listener: (context, state) { 40 | ProgressDialog.getInstance().hide(context: context); 41 | 42 | if (state is ShowDialogInfoState) { 43 | GeneralDialog.show(context, 44 | title: state.title, message: state.message); 45 | bloc.add(PlaceHolderEvent()); 46 | } 47 | 48 | if (state is ShowDialogErrorState) { 49 | GeneralDialog.show(context, title: 'Error', message: state.error); 50 | bloc.add(PlaceHolderEvent()); 51 | } 52 | 53 | if (state is ShowSnackBarErrorState) { 54 | // ignore: deprecated_member_use 55 | Scaffold.of(context).showSnackBar( 56 | SnackBar( 57 | content: Text(state.error), 58 | duration: Duration(seconds: 3), 59 | ), 60 | ); 61 | bloc.add(PlaceHolderEvent()); 62 | } 63 | if (state is ShowProgressLoader) { 64 | ProgressDialog.getInstance().show(context, state.message); 65 | } 66 | 67 | if (state is LogoutState) { 68 | GeneralDialog.show(context, 69 | title: 'Logout', 70 | message: 'Do you really want to logout?', 71 | positiveButtonLabel: 'LOGOUT', onPositiveTap: () async { 72 | // await FirebaseAuth.instance.signOut(); 73 | // await GoogleSignIn().signOut(); 74 | // Navigator.of(context).pushNamedAndRemoveUntil( 75 | // SplashScreen.ROUTE_NAME, (route) => false); 76 | }); 77 | } 78 | 79 | listener(context, state); 80 | }, 81 | ); 82 | } 83 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 40 | 44 | 48 | 53 | 57 | 58 | 59 | 60 | 61 | 62 | 64 | 67 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /lib/data/model/User.dart: -------------------------------------------------------------------------------- 1 | class User { 2 | final String? name; 3 | final String id; 4 | String img; 5 | late bool isFirstYear; 6 | User({this.name, required this.id, required this.img}) { 7 | if (double.parse(id.substring(0, 1)) == DateTime.now().year) { 8 | this.isFirstYear = true; 9 | } else { 10 | this.isFirstYear = false; 11 | } 12 | if (!img.contains("base64")) 13 | this.img = 14 | "data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABmJLR0QA/wD/AP+gvaeTAAAIvElEQVRoge2ZWWxc1RnHf+eOZ7zOOONtsD0ZB2yTDddO4iQNzmYnEBRoiwokQBGUiooHHgBVgpaqAqn0ofCSik3NA63U0qoJlQoVS1rAWZzUaRKcOLETx46XjJcZx9t4xrPfe/pgbBxn7iwuUR/q/9O95/vO//v+957lO/fCIhaxiP8LiJsd4ITTmdlvt4f3CKEm20e+guKtK7lTGLRxVRNvCzAj5M9zd7g+0evzjQlpa2szua3mekWKBhC1wHKgZE6MIMhuhGgXyCZVKp82lJZ2xBTSSJpXLblPQz4vYOtXqXoshsECUU/0pghpGhx0qJr2vBQ8BhSk1FlySsLbZpfrvdra2sh88+RnxWclVH+VasSSpeSKO/sDsaiU1FOfRvPoqKWxv39fVGqdUvAcqYoAEKwXgt/5im0djYOD9883SyF/BsIDIoKQL+iJmKZaAL4Ycm5TNPEeULqQ/roQvB8JhJ66q7zcM9MkG0mDZWmivjcYv2uKODIw8IxE/gYwLCDVZNClqto9OxyOK3MbX2g+Z8eomF9bV3UxVqeUhtbhwf6XJPJNbp4IgAqDQTl+ZHBw5dxGYRC/F5o889CBAzFjJy3kSH//00h+lay/qqpc6+2hr6WFsf7+ZLvNwCalduhzp3N26Gqa2IcQLx7csyfmMp7U0DrqdG7QFHEMMCXy9Y5co/Ozj8npbabQ6MckVCajRto9Odi2f5fVO3ciRPywApCAEJzMHnRtibWipSzkhNOZGTaI80jK4/mpkQhn3n0Th/cChaYwsXL1hBSax3Kx3F6Dfc1ayqprYnKtLSgkpGm0jY0iJb+ot9tfTZRnwqEVVvhpIhEAJ9/6NWvDX1KUHlsEQG66xq7icTZ6Ghn+5A+6XO5AgJHA9EorBC81Dg0tSxQ/rpATTmceiOcTkVzr6aYi3Jn0hFMUEBb9bWdgyoc74J+5zRSa9lJCznjGsEE8DZgTkfQ0HSYvQwNgZEolENbi+msSDEtXJaKdA/nEZ263LZ5H/IcoeTyZMP7RawgBEwEV2+rN5CzfQt9UJh7/jQvMiE9FERBx9SRDPQOTQY08Es8hTc/Q6Lp6ByorkoqSmQkhCKUVsHlHAwB127dy7ssWejs6Cfo8RNUoGeYlmCsK8fY2k5E2lYoQhJTfB/bp2XXfiFBFfbJBrLfdTlAVWGyldHVe5aO/H+bQp8epWLGS+3/wMEUVNeSVVeGorOLu3XcxPKkhjVkpCQGx8ZDLlZ2yEBBrkg1hX1PLgFdQsmwZFZUOyspKqNuylpyc6WQbdmzEbrexfkMVQgiCahrqkuIURABgSpdh3YkVb45UJsPuGxnm3P59TGHFXuYA4OKlbi5d7J710TTJ+385xITHC0BGfjGRK+24z59LJsQspBTL9Wy6c4Qky/JwKMz3dm+lreU0VusSAB58aNd1u7eiCF7+5TMYDNNl0sqaaizZ6Rzt7cFWVZ1MmK8gdHOK90ayjYrCmoJCVlnzdEsAa3EJfWN+Vtxxx2zysUqQGREABYVFjExFKVxVlVT6s9DI0TPFExIym0xYTCYKMzMxKrFdhaIwQgaIG4tSt3uUvt5BpJTXtatSo9U5ia08YcEwL5jQPZPEm+wT48EgPd5JLk2ME9b0NznHtrv44vLIbMJe7xQDA8PkWS0sdRQzfG0ct3t01v+DY+2Uf+fB1EQACG1iAUJktwSuer24/X59N0AxGKjcdR9NF3oBMJuzKSrKw9nvoqurj8wMEzZbPgAdPUMUVq/DnJ+fuhCVrtSFSC6kEsOcn093NJv+MR8ARmMaNlsBeXlLsFimh/aEL8gHJzupqNuSCvVsRiajsV3PGPO0JVsftS4JtO01ab41fmMJmoi3uH0Nq6OMs+09eK504LDfQiQSJRpVycrK4NTZyxw83sH6x57AYDQuQIdo31pS8rqeNWaG0Yg8kMPAzpzIAJZIL23Wp5IOV7ZhEyMHT3H+VBPCZAVFcPVyK9eGhlhx95MY09MXIAJA+zieVe9Rb5y5MEf6kgoTmpqi+/A/GGn9N4/Xl1KcZwAm0aSGkpfGrXlFvPvndxhdXcuyht3T9VkKUDT+GM8ec3uInnlkv4QfA7izvi27LA/oniT7zpyi7fDnhIQRy4Yt1DlM1IY7sGjXF4UhYeSc6TaOutIZPt1MlhZm5eZt2GvWJjz6ImjcXmJvSFmIlAi1Ze89AE22138Iyp75PuFAgC/2v0V02Sry121CpH39coWUFGtj2NRxBJIxxYzTUIQqvl5bNFVl/OxptM5WVq1fR3ndNt0kpSbr65cuPZyykLk4MjCwVCLb4fpdteVvB/B9axvGrFSr2Bsx8ekBtj+4l4ycmBv3ge2l9r2JOBKeTreVljqRvDC/3RMMfyMiAExVmxhqbYlhES5pjDybDEdSx+ztdvs7IP40cx8JBgmn65Y9KSMtO4fw5Ph1bQYZiiDlo/VFt7qS4kg2mN/v/1F2VqZNwg7f2BgiN/Vv1nowZGQQ8nln7y2RPq1q7C2DRFsONCbDkfSXxt2VlaEpf+BeIflrNBwCU0bqGevAYErHHwzP3IaNWvA5JI0CRXcnn4+k3whMi2mU8uGxpqb9UmQ8OdMe0TTd6lgPqpQYZpZdRSGAEcCpIR6pum3HceCNVPhS/j9SL0T0o5dfftb54cFjI/86GpVS0uX3Ju44D5enJmevtUiECfdwl0mTNQ2lpcdTJuO//GP1wJZNu3JvX/VGqKa2fPX6OkVJoYa66PPgGB1j/PSJSc+VziZXa+tz/7x4sXOhuaQk5MWTF6qlola+tr76/bnt92zcuLmovPxVi6NsRWbBLVZjcYkpw1aMMmceSS1KaHSEsGtA+rq7fF7PhDs6PLR/ov3Sbz/p6pq8IdhNFXLq/Icg783MMuS+snq1L5bPrpUri3MKrHfmV1RuUIzpdi0czo2Gg0akmFCD/ubx3qvH0itaWg4eJOm/vN84fvJle9mLp89u/p8lsIhFLGIR/wFAwkbNhhVozQAAAABJRU5ErkJggg=="; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /lib/screens/hangout/widget/pollsWidget.dart: -------------------------------------------------------------------------------- 1 | import 'package:adaptive_theme/adaptive_theme.dart'; 2 | import 'package:firebase_database/firebase_database.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:polls/polls.dart'; 5 | 6 | import '../../../data/model/hangout/PollModel.dart'; 7 | import '../../../theme/colors.dart'; 8 | 9 | class PollView extends StatefulWidget { 10 | final PollModel? poll; 11 | final String? user; 12 | final String? postId; 13 | final isCreate; 14 | const PollView( 15 | {Key? key, 16 | required this.poll, 17 | this.postId, 18 | required this.user, 19 | this.isCreate = false}) 20 | : super(key: key); 21 | @override 22 | _PollViewState createState() => _PollViewState(); 23 | } 24 | 25 | class _PollViewState extends State { 26 | PollModel? poll; 27 | 28 | final firebaseRef = 29 | FirebaseDatabase.instance.reference().child('hangout/pings'); 30 | @override 31 | void initState() { 32 | super.initState(); 33 | poll = widget.poll; 34 | if (poll!.userWhoVoted == null) 35 | poll!.userWhoVoted = Map(); 36 | } 37 | 38 | @override 39 | Widget build(BuildContext context) { 40 | final isDark = AdaptiveTheme.of(context).mode == AdaptiveThemeMode.dark; 41 | 42 | if (widget.isCreate) 43 | return Polls.creator( 44 | children: [ 45 | // This cannot be less than 2, else will throw an exception 46 | Polls.options( 47 | title: poll!.optionLabel.first, 48 | value: poll!.numberOfVotes.first!), 49 | Polls.options( 50 | title: poll!.optionLabel[1], value: poll!.numberOfVotes[1]!), 51 | ], 52 | question: Text(''), 53 | onVoteBackgroundColor: Colors.blue, 54 | leadingBackgroundColor: Colors.blue, 55 | backgroundColor: isDark ? Colors.black54 : Colors.white, 56 | ); 57 | else 58 | return Polls( 59 | children: [ 60 | // This cannot be less than 2, else will throw an exception 61 | Polls.options( 62 | title: poll!.optionLabel.first, 63 | value: poll!.numberOfVotes.first!), 64 | Polls.options( 65 | title: poll!.optionLabel[1], value: poll!.numberOfVotes[1]!), 66 | ], 67 | question: Text( 68 | '', 69 | style: TextStyle(fontSize: 1), 70 | ), 71 | currentUser: widget.user, 72 | creatorID: poll!.creator, 73 | voteData: poll!.userWhoVoted, 74 | userChoice: poll!.userWhoVoted![widget.user], 75 | onVoteBackgroundColor: Colors.blue, 76 | leadingBackgroundColor: Colors.blue, 77 | outlineColor: kBlue, 78 | backgroundColor: isDark ? Colors.black54 : Colors.white, 79 | onVote: (choice) { 80 | print(choice); 81 | setState(() { 82 | poll!.userWhoVoted![widget.user] = choice; 83 | }); 84 | if (choice == 1) { 85 | setState(() { 86 | var res = poll!.numberOfVotes.first; 87 | if (res != null) res += 1.0; 88 | }); 89 | } 90 | if (choice == 2) { 91 | setState(() { 92 | var res = poll!.numberOfVotes[1]; 93 | if (res != null) res += 1.0; 94 | }); 95 | } 96 | firebaseRef.child(widget.postId!).update({'pollData': poll!.toMap()}); 97 | }, 98 | ); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /lib/screens/hangout/widget/userStrip.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../../../data/const.dart'; 4 | import '../../../theme/style.dart'; 5 | import '../../../util/SizeConfig.dart'; 6 | 7 | class UserStripWidget extends StatelessWidget { 8 | const UserStripWidget({ 9 | Key? key, 10 | required this.name, 11 | required this.section, 12 | required this.yr, 13 | required this.id, 14 | this.isCompact = false, 15 | }) : super(key: key); 16 | final bool isCompact; 17 | final String? id; 18 | final String? name; 19 | final String? section; 20 | final String? yr; 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | var subTitle = isCompact 25 | ? [ 26 | Row( 27 | children: [ 28 | Expanded( 29 | child: Text( 30 | name!, 31 | style: TextStyle( 32 | fontSize: 12, 33 | ), 34 | overflow: TextOverflow.clip, 35 | ), 36 | ), 37 | kLowWidthPadding, 38 | Text( 39 | yr! + " year, ", 40 | style: TextStyle(fontSize: 12), 41 | overflow: TextOverflow.ellipsis, 42 | ), 43 | Text( 44 | section!, 45 | style: TextStyle(fontSize: 12), 46 | overflow: TextOverflow.ellipsis, 47 | ), 48 | ], 49 | ), 50 | ] 51 | : [ 52 | Row( 53 | children: [ 54 | Flexible( 55 | child: Text( 56 | name!, 57 | style: TextStyle(fontSize: 12, fontWeight: FontWeight.bold), 58 | overflow: TextOverflow.ellipsis, 59 | ), 60 | ), 61 | Visibility( 62 | visible: kAdmins.contains(id), child: kLowWidthPadding), 63 | Visibility( 64 | visible: kAdmins.contains(id), 65 | child: Image.asset( 66 | 'assets/icons/verified.png', 67 | width: 15, 68 | ), 69 | ), 70 | ], 71 | ), 72 | Row( 73 | mainAxisAlignment: MainAxisAlignment.start, 74 | children: [ 75 | Text( 76 | yr! + " year, ", 77 | style: TextStyle(fontSize: 12), 78 | overflow: TextOverflow.ellipsis, 79 | ), 80 | Text( 81 | section!, 82 | style: TextStyle(fontSize: 12), 83 | overflow: TextOverflow.ellipsis, 84 | ), 85 | ], 86 | ), 87 | ]; 88 | 89 | return InkWell( 90 | onTap: () { 91 | //Open Profile 92 | }, 93 | child: Row( 94 | children: [ 95 | CircleAvatar( 96 | radius: isCompact 97 | ? SizeConfig.widthMultiplier * 4 98 | : SizeConfig.widthMultiplier * 5, 99 | backgroundImage: NetworkImage("https://robohash.org/$name"), 100 | ), 101 | kMedWidthPadding, 102 | Flexible( 103 | child: Column( 104 | crossAxisAlignment: CrossAxisAlignment.start, 105 | children: subTitle, 106 | ), 107 | ), 108 | ], 109 | ), 110 | ); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | IPEC Student's App 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ipecstudentsapp 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSExceptionDomains 30 | 31 | ipec.org.in 32 | 33 | NSExceptionAllowsInsecureHTTPLoads 34 | 35 | NSIncludesSubdomains 36 | 37 | 38 | 39 | 40 | NSAppleMusicUsageDescription 41 | $(PRODUCT_NAME) Play music in background 42 | NSBluetoothAlwaysUsageDescription 43 | Our app does not request this permission or utilize this functionality but it is included in our info.plist since our app utilizes the flutter library, which references this permission in its code. 44 | NSBluetoothPeripheralUsageDescription 45 | $(PRODUCT_NAME) Bluetooth Peripheral use 46 | NSCalendarsUsageDescription 47 | $(PRODUCT_NAME) calendar events 48 | NSCameraUsageDescription 49 | $(PRODUCT_NAME) camera use 50 | NSContactsUsageDescription 51 | $(PRODUCT_NAME) contact use 52 | NSLocationAlwaysUsageDescription 53 | $(PRODUCT_NAME) location use 54 | NSLocationWhenInUseUsageDescription 55 | $(PRODUCT_NAME) location use 56 | NSMotionUsageDescription 57 | $(PRODUCT_NAME) motion use 58 | NSPhotoLibraryAddUsageDescription 59 | $(PRODUCT_NAME) photo use 60 | NSPhotoLibraryUsageDescription 61 | $(PRODUCT_NAME) photo use 62 | NSSpeechRecognitionUsageDescription 63 | $(PRODUCT_NAME) speech use 64 | UIBackgroundModes 65 | 66 | fetch 67 | remote-notification 68 | 69 | UILaunchStoryboardName 70 | LaunchScreen 71 | UIMainStoryboardFile 72 | Main 73 | UIStatusBarHidden 74 | 75 | UIStatusBarStyle 76 | UIStatusBarStyleDefault 77 | UISupportedInterfaceOrientations 78 | 79 | UIInterfaceOrientationPortrait 80 | UIInterfaceOrientationLandscapeLeft 81 | UIInterfaceOrientationLandscapeRight 82 | 83 | UISupportedInterfaceOrientations~ipad 84 | 85 | UIInterfaceOrientationPortrait 86 | UIInterfaceOrientationPortraitUpsideDown 87 | UIInterfaceOrientationLandscapeLeft 88 | UIInterfaceOrientationLandscapeRight 89 | 90 | UIViewControllerBasedStatusBarAppearance 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /lib/screens/hangout/bloc/onboarding/onboarding_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_auth/firebase_auth.dart'; 2 | import 'package:firebase_database/firebase_database.dart'; 3 | import 'package:html/parser.dart'; 4 | 5 | import '../../../../../data/base_bloc/base_bloc.dart'; 6 | import '../../../../../data/base_bloc/base_event.dart'; 7 | import '../../../../../data/base_bloc/base_state.dart'; 8 | import '../../../../data/const.dart'; 9 | import '../../../../data/model/GeneralResponse.dart'; 10 | import '../../../../data/model/hangout/hangUser.dart'; 11 | import 'onboarding_event.dart'; 12 | import 'onboarding_state.dart'; 13 | 14 | class OnboardingBloc extends BaseBloc { 15 | OnboardingBloc(BaseState initialState) : super(initialState); 16 | 17 | @override 18 | BaseState get initialState => OnboardingInitState(); 19 | 20 | @override 21 | Stream mapBaseEventToBaseState(BaseEvent event) async* { 22 | if (event is LoadStudentData) { 23 | yield OnboardingLoading(); 24 | GeneralResponse response = await event.session.webClientService 25 | .getMyProfile(event.auth!.token.cookies); 26 | if (response.status) { 27 | var document = parse(response.data); 28 | 29 | String? email = document 30 | .querySelector("#ContentPlaceHolder1_lblStudentEMail")! 31 | .attributes["value"]; 32 | 33 | String? gender = document 34 | .querySelector("#ContentPlaceHolder1_lblGender")! 35 | .attributes["value"]; 36 | 37 | String? phone = document 38 | .querySelector("#ContentPlaceHolder1_lblStudentMoileNo")! 39 | .attributes["value"]; 40 | 41 | String? depart = document 42 | .querySelector("#ContentPlaceHolder1_lblDepartment")! 43 | .attributes["value"]; 44 | 45 | String? yr = document 46 | .querySelector("#ContentPlaceHolder1_lblYear")! 47 | .attributes["value"]; 48 | 49 | String? section = document 50 | .querySelector("#ContentPlaceHolder1_lblBranch")! 51 | .attributes["value"]; 52 | 53 | Huser user = Huser( 54 | depart: depart, 55 | email: email, 56 | gender: gender, 57 | id: event.auth!.user!.id, 58 | name: event.auth!.user!.name, 59 | phone: phone, 60 | section: section, 61 | yr: yr, 62 | likes: [kDefaultPOst]); 63 | print(user.toJson()); 64 | final ref = FirebaseDatabase.instance 65 | .reference() 66 | .child('hangout/pings/$kDefaultPOst'); 67 | final res = await ref.once(); 68 | if (res.value != null && res.value['likes'] != null) 69 | ref.update({'likes': res.value['likes'] + 1}); 70 | if (depart == null || 71 | // email == null || 72 | gender == null || 73 | // phone == null || 74 | section == null || 75 | yr == null) 76 | yield OnboardingFailed(); 77 | else 78 | yield OnboardingLoaded(user); 79 | } else { 80 | yield ShowDialogErrorState(response.error.toString()); 81 | } 82 | } 83 | if (event is SaveStudentDataEvent) { 84 | try { 85 | FirebaseAuth.instance.createUserWithEmailAndPassword( 86 | email: event.user.email ?? "N/A", password: event.user.id!); 87 | 88 | FirebaseDatabase.instance 89 | .reference() 90 | .child('hangout') 91 | .child('user') 92 | .child(event.user.id!) 93 | .set(event.user.toMap()); 94 | 95 | yield SavedUserState(event.user); 96 | } catch (e) { 97 | yield ShowDialogErrorState(e.toString()); 98 | } 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /lib/screens/dashboard/attendance/bloc/attendance_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:dio/dio.dart'; 2 | import 'package:html/parser.dart'; 3 | 4 | import '../../../../data/base_bloc/base_bloc.dart'; 5 | import '../../../../data/base_bloc/base_event.dart'; 6 | import '../../../../data/base_bloc/base_state.dart'; 7 | import '../../../../data/model/GeneralResponse.dart'; 8 | import '../../../../data/model/TokensModel.dart'; 9 | import '../../../../data/repo/session.dart'; 10 | import 'attendance_event.dart'; 11 | import 'attendance_state.dart'; 12 | 13 | class AttendanceBloc extends BaseBloc { 14 | AttendanceBloc(BaseState initialState) : super(initialState); 15 | 16 | @override 17 | BaseState get initialState => AttendanceInitState(); 18 | 19 | @override 20 | Stream mapBaseEventToBaseState(BaseEvent event) async* { 21 | if (event is LoadAttendance) { 22 | yield AttendanceLoading(); 23 | event.session.setStatus(AttendanceStatus.Loading); 24 | try { 25 | GeneralResponse response = 26 | await event.session.webClientService.getAttendanceToken( 27 | event.auth!.cred, 28 | event.auth!.token, 29 | ); 30 | if (response.status) { 31 | Tokens _tokens = Tokens(); 32 | // Step 2: parse Tokens 33 | var document = parse(response.data.data); 34 | 35 | _tokens.viewState = 36 | document.querySelector('#__VIEWSTATE')!.attributes['value']; 37 | _tokens.viewStateGenerator = document 38 | .querySelector('#__VIEWSTATEGENERATOR')! 39 | .attributes['value']; 40 | _tokens.eventValidation = 41 | document.querySelector('#__EVENTVALIDATION')!.attributes['value']; 42 | if (_tokens.viewState != null && 43 | _tokens.viewStateGenerator != null && 44 | _tokens.eventValidation != null) { 45 | Map body = { 46 | '__VIEWSTATE': _tokens.viewState, 47 | '__VIEWSTATEGENERATOR': _tokens.viewStateGenerator, 48 | '__EVENTVALIDATION': _tokens.eventValidation, 49 | "ctl00\$ContentPlaceHolder1\$txtstudent": 50 | event.auth!.cred!.username, 51 | "ctl00\$ContentPlaceHolder1\$btnview": "view" 52 | }; 53 | GeneralResponse postResponse = await event.session.webClientService 54 | .postAttendance(event.auth!.cred, event.auth!.token, body); 55 | if (postResponse.status) { 56 | // parse attendance 57 | 58 | event.session.setAttendance(postResponse.data.data); 59 | event.session.setStatus(AttendanceStatus.Loaded); 60 | yield AttendanceLoaded(); 61 | } else 62 | throw Exception(postResponse.error); 63 | } else 64 | throw Exception( 65 | "Failed to load attendance! Error at parsing tokens"); 66 | } else { 67 | yield ShowDialogErrorState(response.error); 68 | yield AttendanceFailed(); 69 | } 70 | } on Exception catch (e) { 71 | event.session.setStatus(AttendanceStatus.Error); 72 | 73 | if (e is DioError) { 74 | // print("😀 dio error"); 75 | if (e.type == DioErrorType.connectTimeout) { 76 | yield ShowDialogErrorState( 77 | "Connection Timeout! Check your internet connectivity and retry again."); 78 | } else if (e.type == DioErrorType.receiveTimeout) { 79 | yield ShowDialogErrorState( 80 | "Connection Timeout! Maybe IPEC Server is down or check your connectivity."); 81 | } else { 82 | yield ShowDialogErrorState( 83 | "Something went wrong! Maybe IPEC Server is down or your internet connectivity is down. Please try again by restarting app"); 84 | } 85 | } else { 86 | yield ShowDialogErrorState(e.toString()); 87 | } 88 | yield AttendanceFailed(); 89 | } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /lib/screens/loading/loading_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:adaptive_theme/adaptive_theme.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:lottie/lottie.dart'; 4 | import 'package:mantras/mantras.dart'; 5 | import 'package:provider/provider.dart'; 6 | 7 | import '../../data/base_bloc/base_bloc_builder.dart'; 8 | import '../../data/base_bloc/base_bloc_listener.dart'; 9 | import '../../data/base_bloc/base_state.dart'; 10 | import '../../data/repo/auth.dart'; 11 | import '../../theme/colors.dart'; 12 | import '../../widgets/background.dart'; 13 | import '../dashboard/dashboard_page.dart'; 14 | import '../login/login_screen.dart'; 15 | import 'bloc/loading_bloc.dart'; 16 | import 'bloc/loading_event.dart'; 17 | import 'bloc/loading_state.dart'; 18 | 19 | class LoadingScreen extends StatefulWidget { 20 | static const String ROUTE = "/Loading"; 21 | 22 | final bool? isFirstLogin; 23 | 24 | const LoadingScreen({Key? key, this.isFirstLogin}) : super(key: key); 25 | 26 | @override 27 | _LoadingScreenState createState() => _LoadingScreenState(); 28 | } 29 | 30 | class _LoadingScreenState extends State { 31 | final LoadingBloc _bloc = LoadingBloc(LoadingInitState()); 32 | String mantra = Mantras().getMantra(); 33 | 34 | @override 35 | void dispose() { 36 | _bloc.close(); 37 | super.dispose(); 38 | } 39 | 40 | @override 41 | Widget build(BuildContext context) { 42 | final size = MediaQuery.of(context).size; 43 | return Scaffold( 44 | body: BaseBlocListener( 45 | bloc: _bloc, 46 | listener: (BuildContext context, BaseState state) { 47 | print("$runtimeType BlocListener - ${state.toString()}"); 48 | if (state is CloseLoadingState) { 49 | if (widget.isFirstLogin!) 50 | Navigator.pop(context); 51 | else 52 | Navigator.pushReplacementNamed(context, LoginScreen.ROUTE); 53 | } 54 | 55 | if (state is AuthenticatedState) { 56 | Navigator.pushNamedAndRemoveUntil( 57 | context, DashboardScreen.ROUTE, (route) => false); 58 | } 59 | }, 60 | child: BaseBlocBuilder( 61 | bloc: _bloc, 62 | condition: (BaseState previous, BaseState current) { 63 | // return !(BaseBlocBuilder.isBaseState(current)); 64 | return true; 65 | }, 66 | builder: (BuildContext context, BaseState state) { 67 | print("$runtimeType BlocBuilder - ${state.toString()}"); 68 | if (state is LoadingInitState) 69 | _bloc.add( 70 | CheckCredentials(Provider.of(context, listen: false))); 71 | 72 | return _getBody(context, size, state); 73 | }, 74 | ), 75 | ), 76 | ); 77 | } 78 | 79 | Background _getBody(BuildContext context, Size size, BaseState state) { 80 | final isDark = AdaptiveTheme.of(context).mode == AdaptiveThemeMode.dark; 81 | return Background( 82 | child: Stack( 83 | alignment: Alignment.center, 84 | children: [ 85 | Text( 86 | state is LoginFailState ? 'Please Try Again' : 'Loading', 87 | textAlign: TextAlign.center, 88 | style: Theme.of(context).primaryTextTheme.headline5!.copyWith( 89 | color: isDark ? Colors.white : Colors.black, 90 | fontWeight: FontWeight.w700), 91 | ), 92 | Lottie.asset('assets/anim/loading2.json'), 93 | Positioned( 94 | bottom: 0, 95 | child: Container( 96 | width: size.width, 97 | padding: const EdgeInsets.symmetric(horizontal: 20), 98 | child: Text( 99 | "Mantra : " + mantra, 100 | overflow: TextOverflow.clip, 101 | textAlign: TextAlign.center, 102 | style: Theme.of(context).primaryTextTheme.bodyText1!.copyWith( 103 | color: kGrey, 104 | ), 105 | ), 106 | ), 107 | ) 108 | ], 109 | ), 110 | ); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /lib/screens/hangout/chatters.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../data/base_bloc/base_bloc_builder.dart'; 3 | import '../../data/base_bloc/base_bloc_listener.dart'; 4 | import '../../data/base_bloc/base_state.dart'; 5 | import '../../data/model/hangout/comment.dart'; 6 | import '../../data/repo/pings.dart'; 7 | import 'bloc/chatter/chatters_bloc.dart'; 8 | import 'widget/comment_widget.dart'; 9 | import '../../theme/style.dart'; 10 | import 'package:provider/provider.dart'; 11 | import 'bloc/chatter/chatters_event.dart'; 12 | import 'bloc/chatter/chatters_state.dart'; 13 | 14 | class Chatters extends StatefulWidget { 15 | final String? postID; 16 | final String? currentUserID; 17 | const Chatters({Key? key, required this.postID, required this.currentUserID}) 18 | : super(key: key); 19 | 20 | @override 21 | _ChattersState createState() => _ChattersState(); 22 | } 23 | 24 | class _ChattersState extends State { 25 | final _bloc = ChattersBloc(ChattersInitialState()); 26 | 27 | @override 28 | void dispose() { 29 | _bloc.close(); 30 | 31 | super.dispose(); 32 | } 33 | 34 | @override 35 | Widget build(BuildContext context) { 36 | return Consumer( 37 | builder: (context, pings, child) { 38 | return BaseBlocListener( 39 | bloc: _bloc, 40 | listener: (BuildContext context, BaseState state) { 41 | print("$runtimeType BlocListener - ${state.toString()}"); 42 | }, 43 | child: BaseBlocBuilder( 44 | bloc: _bloc, 45 | condition: (BaseState previous, BaseState current) { 46 | return !(BaseBlocBuilder.isBaseState(current)); 47 | }, 48 | builder: (BuildContext context, BaseState state) { 49 | print("$runtimeType BlocBuilder - ${state.toString()}"); 50 | 51 | if (state is ChattersInitialState) 52 | _bloc.add(LoadChattersEvent(widget.postID, pings)); 53 | 54 | if (state is ChattersLoadingState) 55 | return Center( 56 | child: Padding( 57 | padding: const EdgeInsets.all(30.0), 58 | child: CircularProgressIndicator( 59 | strokeWidth: 2, 60 | ), 61 | ), 62 | ); 63 | if (state is ChattersLoadedState) 64 | return _getBody(pings.comments[widget.postID]); 65 | return Container(); 66 | }, 67 | ), 68 | ); 69 | }, 70 | ); 71 | } 72 | 73 | Widget _getBody(List? comments) { 74 | if (comments == null || comments.length == 0) 75 | return Container( 76 | padding: const EdgeInsets.all(20), 77 | child: Text("Be the first one to chatter 😊 "), 78 | ); 79 | else 80 | return Column( 81 | crossAxisAlignment: CrossAxisAlignment.start, 82 | children: [ 83 | kMedPadding, 84 | Text( 85 | "Chatter", 86 | style: Theme.of(context).textTheme.headline6, 87 | ), 88 | kMedPadding, 89 | ListView.builder( 90 | shrinkWrap: true, 91 | physics: NeverScrollableScrollPhysics(), 92 | itemCount: comments.length, 93 | itemBuilder: (context, index) { 94 | if (comments[index].reports! > 0) { 95 | return Padding( 96 | padding: const EdgeInsets.all(8.0), 97 | child: Text( 98 | 'A comment has been removed due to many reports', 99 | textAlign: TextAlign.center, 100 | ), 101 | ); 102 | } else 103 | return Padding( 104 | padding: const EdgeInsets.symmetric(vertical: 10.0), 105 | child: CommentWidget( 106 | commentModel: comments[index], 107 | currentUserID: widget.currentUserID, 108 | postID: widget.postID, 109 | ), 110 | ); 111 | }, 112 | ), 113 | ], 114 | ); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /lib/data/model/hangout/post.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'PollModel.dart'; 4 | import 'hangUser.dart'; 5 | 6 | class Post { 7 | final String? id; 8 | final Huser author; 9 | final String? authorImage; 10 | final int? postedOn; 11 | final String? text; 12 | int? likes; 13 | int? comments; 14 | int? reports; 15 | final bool? isLinkAttached; 16 | final String? link; 17 | final bool? isImage; 18 | final String? imageUrl; 19 | final bool? isPoll; 20 | final PollModel pollData; 21 | final bool? isGif; 22 | final String? gifUrl; 23 | Post({ 24 | required this.id, 25 | required this.author, 26 | required this.authorImage, 27 | required this.postedOn, 28 | required this.text, 29 | this.likes = 0, 30 | this.comments = 0, 31 | this.reports = 0, 32 | this.isLinkAttached = false, 33 | required this.link, 34 | this.isImage = false, 35 | required this.imageUrl, 36 | this.isPoll = false, 37 | required this.pollData, 38 | this.isGif = false, 39 | required this.gifUrl, 40 | }); 41 | 42 | Map toMap() { 43 | return { 44 | 'id': id, 45 | 'author': author.toMap(), 46 | 'authorImage': authorImage, 47 | 'postedOn': postedOn, 48 | 'text': text, 49 | 'likes': likes, 50 | 'comments': comments, 51 | 'reports': reports, 52 | 'isLinkAttached': isLinkAttached, 53 | 'link': link, 54 | 'isImage': isImage, 55 | 'imageUrl': imageUrl, 56 | 'isPoll': isPoll, 57 | 'pollData': pollData.toMap(), 58 | 'isGif': isGif, 59 | 'gifUrl': gifUrl 60 | }; 61 | } 62 | 63 | factory Post.fromMap(Map map) { 64 | return Post( 65 | id: map['id'], 66 | author: Huser.fromMap(map['author']), 67 | authorImage: map['authorImage'], 68 | postedOn: map['postedOn'], 69 | text: map['text'], 70 | likes: map['likes'], 71 | comments: map['comments'], 72 | reports: map['reports'], 73 | isLinkAttached: map['isLinkAttached'], 74 | link: map['link'], 75 | isImage: map['isImage'], 76 | imageUrl: map['imageUrl'], 77 | isPoll: map['isPoll'], 78 | pollData: PollModel.fromMap(map['pollData']), 79 | gifUrl: map['gifUrl'], 80 | isGif: map['isGif']); 81 | } 82 | 83 | factory Post.fromSnapshot(data, indivisualKey) { 84 | Post postItem = new Post( 85 | id: data[indivisualKey]['id'], 86 | author: Huser.fromMap(data[indivisualKey]['author']), 87 | authorImage: data[indivisualKey]['authorImage'], 88 | postedOn: data[indivisualKey]['postedOn'], 89 | text: data[indivisualKey]['text'], 90 | likes: data[indivisualKey]['likes'], 91 | comments: data[indivisualKey]['comments'], 92 | reports: data[indivisualKey]['reports'], 93 | isLinkAttached: data[indivisualKey]['isLinkAttached'], 94 | link: data[indivisualKey]['link'], 95 | isImage: data[indivisualKey]['isImage'], 96 | imageUrl: data[indivisualKey]['imageUrl'], 97 | isPoll: data[indivisualKey]['isPoll'], 98 | pollData: PollModel.fromMap(data[indivisualKey]['pollData']), 99 | gifUrl: data[indivisualKey]['gifUrl'], 100 | isGif: data[indivisualKey]['isGif']); 101 | return postItem; 102 | } 103 | 104 | String toJson() => json.encode(toMap()); 105 | 106 | factory Post.fromJson(String source) => Post.fromMap(json.decode(source)); 107 | 108 | @override 109 | bool operator ==(Object other) { 110 | if (identical(this, other)) return true; 111 | 112 | return other is Post && other.id == id; 113 | } 114 | 115 | @override 116 | int get hashCode { 117 | return id.hashCode ^ 118 | author.hashCode ^ 119 | authorImage.hashCode ^ 120 | postedOn.hashCode ^ 121 | text.hashCode ^ 122 | likes.hashCode ^ 123 | comments.hashCode ^ 124 | reports.hashCode ^ 125 | isLinkAttached.hashCode ^ 126 | link.hashCode ^ 127 | isImage.hashCode ^ 128 | imageUrl.hashCode ^ 129 | isPoll.hashCode ^ 130 | pollData.hashCode ^ 131 | isGif.hashCode ^ 132 | gifUrl.hashCode; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /lib/screens/sessional/sessional_screen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io' show Platform; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:provider/provider.dart'; 5 | import 'package:webview_flutter/webview_flutter.dart'; 6 | 7 | import '../../data/base_bloc/base_bloc_builder.dart'; 8 | import '../../data/base_bloc/base_bloc_listener.dart'; 9 | import '../../data/base_bloc/base_state.dart'; 10 | import '../../data/repo/auth.dart'; 11 | import '../../data/repo/session.dart'; 12 | import '../../theme/style.dart'; 13 | import '../../widgets/loading_widget.dart'; 14 | import '../../widgets/simple_appbar.dart'; 15 | import 'bloc/sessional_bloc.dart'; 16 | import 'bloc/sessional_event.dart'; 17 | import 'bloc/sessional_state.dart'; 18 | 19 | class SessionalMarksScreen extends StatefulWidget { 20 | static const String ROUTE = "/sessional"; 21 | const SessionalMarksScreen({Key? key}) : super(key: key); 22 | 23 | @override 24 | State createState() => _SessionalMarksScreenState(); 25 | } 26 | 27 | class _SessionalMarksScreenState extends State { 28 | final SessionalBloc _bloc = SessionalBloc(SessionalInitial()); 29 | Auth? _auth; 30 | 31 | @override 32 | void initState() { 33 | super.initState(); 34 | _auth = Provider.of(context, listen: false); 35 | } 36 | 37 | @override 38 | void dispose() { 39 | _bloc.close(); 40 | super.dispose(); 41 | } 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | return ScaffoldMessenger( 46 | child: Scaffold( 47 | body: Consumer( 48 | builder: (context, session, child) { 49 | return BaseBlocListener( 50 | bloc: _bloc, 51 | listener: (BuildContext context, BaseState state) { 52 | print("$runtimeType BlocListener - ${state.toString()}"); 53 | }, 54 | child: BaseBlocBuilder( 55 | bloc: _bloc, 56 | condition: (BaseState previous, BaseState current) { 57 | return true; 58 | }, 59 | builder: (BuildContext context, BaseState state) { 60 | print("$runtimeType BlocBuilder - ${state.toString()}"); 61 | if (state is SessionalInitial) 62 | _bloc.add(SessionalLoadEvent(session, _auth)); 63 | 64 | return SafeArea( 65 | child: Column( 66 | children: [ 67 | SimpleAppBar( 68 | onBack: () { 69 | Navigator.popUntil( 70 | context, (route) => route.isFirst); 71 | }, 72 | title: "Marks", 73 | ), 74 | Expanded( 75 | child: _getBody(session, context, state), 76 | ) 77 | ], 78 | ), 79 | ); 80 | }, 81 | ), 82 | ); 83 | }, 84 | ), 85 | ), 86 | ); 87 | } 88 | 89 | Widget _getBody(session, BuildContext context, BaseState state) { 90 | if (state is SessionalErrorState) 91 | return Column( 92 | mainAxisAlignment: MainAxisAlignment.center, 93 | children: [ 94 | Text("😓🥴", style: TextStyle(fontSize: 100)), 95 | kMedPadding, 96 | Text( 97 | state.msg, 98 | style: Theme.of(context).textTheme.headline5, 99 | textAlign: TextAlign.center, 100 | ), 101 | ], 102 | ); 103 | else if (state is SessionalLoadingState) 104 | return LoadingWidget(); 105 | else if (state is AllSessionalLoadedState) 106 | return SafeArea( 107 | child: Platform.isMacOS || Platform.isWindows 108 | ? Center(child: Text("Sorry Not available on desktop")) 109 | : WebView( 110 | initialUrl: 111 | Uri.dataFromString(state.data, mimeType: 'text/html') 112 | .toString(), 113 | gestureNavigationEnabled: true, 114 | ), 115 | ); 116 | else 117 | return Container(); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /lib/screens/splash/splash_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_messaging/firebase_messaging.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:lottie/lottie.dart'; 4 | import 'package:provider/provider.dart'; 5 | 6 | import '../../data/base_bloc/base_bloc_builder.dart'; 7 | import '../../data/base_bloc/base_bloc_listener.dart'; 8 | import '../../data/base_bloc/base_state.dart'; 9 | import '../../data/repo/auth.dart'; 10 | import '../../util/SizeConfig.dart'; 11 | import '../loading/loading_screen.dart'; 12 | import '../login/login_screen.dart'; 13 | import 'bloc/splash_bloc.dart'; 14 | import 'bloc/splash_event.dart'; 15 | import 'bloc/splash_state.dart'; 16 | 17 | class SplashScreen extends StatefulWidget { 18 | static const String ROUTE = "/Splash"; 19 | 20 | @override 21 | _SplashScreenState createState() => _SplashScreenState(); 22 | } 23 | 24 | class _SplashScreenState extends State { 25 | final SplashScreenBloc _bloc = SplashScreenBloc(SplashInitState()); 26 | 27 | @override 28 | void initState() { 29 | super.initState(); 30 | initFirebase(); 31 | } 32 | 33 | Future initFirebase() async { 34 | final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; 35 | // _firebaseMessaging.configure( 36 | // onMessage: (Map message) async { 37 | // print("onMessage: $message"); 38 | // // _showItemDialog(message); 39 | // }, 40 | // onLaunch: (Map message) async { 41 | // print("onLaunch: $message"); 42 | // // _navigateToItemDetail(message); 43 | // }, 44 | // onResume: (Map message) async { 45 | // print("onResume: $message"); 46 | // // _navigateToItemDetail(message); 47 | // }, 48 | // ); 49 | FirebaseMessaging messaging = FirebaseMessaging.instance; 50 | 51 | NotificationSettings settings = await messaging.requestPermission( 52 | alert: true, 53 | badge: true, 54 | sound: true, 55 | ); 56 | 57 | if (settings.authorizationStatus == AuthorizationStatus.authorized) { 58 | print('User granted permission'); 59 | } else if (settings.authorizationStatus == 60 | AuthorizationStatus.provisional) { 61 | print('User granted provisional permission'); 62 | } else { 63 | print('User declined or has not accepted permission'); 64 | } 65 | _firebaseMessaging.subscribeToTopic("GeneralNotices"); 66 | } 67 | 68 | @override 69 | void dispose() { 70 | _bloc.close(); 71 | super.dispose(); 72 | } 73 | 74 | @override 75 | Widget build(BuildContext context) { 76 | return Scaffold( 77 | body: BaseBlocListener( 78 | bloc: _bloc, 79 | listener: (BuildContext context, BaseState state) { 80 | print("$runtimeType BlocListener - ${state.toString()}"); 81 | if (state is OpenAuthenticationScreen) 82 | Navigator.pushReplacementNamed(context, LoginScreen.ROUTE); 83 | 84 | if (state is OpenDashboardScreen) 85 | Navigator.pushReplacementNamed(context, LoadingScreen.ROUTE, 86 | arguments: {'isFirstLogin': false}); 87 | // if (state is OpenHomeScreenState) 88 | // Navigator.pushReplacementNamed(context, HomePage.ROUTE); 89 | }, 90 | child: BaseBlocBuilder( 91 | bloc: _bloc, 92 | condition: (BaseState previous, BaseState current) { 93 | return !(BaseBlocBuilder.isBaseState(current)); 94 | }, 95 | builder: (BuildContext context, BaseState state) { 96 | print("$runtimeType BlocBuilder - ${state.toString()}"); 97 | if (state is SplashInitState) 98 | _bloc.add( 99 | CheckUserAuth(Provider.of(context, listen: false))); 100 | return _getBody(); 101 | }, 102 | ), 103 | ), 104 | ); 105 | } 106 | } 107 | 108 | Widget _getBody() { 109 | return SafeArea( 110 | child: Column( 111 | crossAxisAlignment: CrossAxisAlignment.stretch, 112 | mainAxisAlignment: MainAxisAlignment.center, 113 | children: [ 114 | Spacer(), 115 | Image( 116 | height: SizeConfig.heightMultiplier * 20, 117 | image: AssetImage('assets/images/logo.png'), 118 | ), 119 | Spacer(), 120 | Lottie.asset('assets/anim/loading.json', 121 | height: SizeConfig.heightMultiplier * 20), 122 | Spacer(), 123 | ], 124 | ), 125 | ); 126 | } 127 | -------------------------------------------------------------------------------- /lib/screens/dashboard/attendance/prediction_result_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:adaptive_theme/adaptive_theme.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:lottie/lottie.dart'; 4 | import 'package:provider/provider.dart'; 5 | 6 | import '../../../data/repo/auth.dart'; 7 | import '../../../theme/colors.dart'; 8 | import '../../../theme/style.dart'; 9 | import '../../../widgets/simple_appbar.dart'; 10 | 11 | class PredictionResultScreen extends StatefulWidget { 12 | static const String ROUTE = "/PredictionResultScreen"; 13 | final double attendance; 14 | final String? attend; 15 | final String? total; 16 | 17 | final double result; 18 | const PredictionResultScreen( 19 | {Key? key, 20 | required this.attendance, 21 | required this.result, 22 | this.attend, 23 | this.total}) 24 | : super(key: key); 25 | 26 | @override 27 | _PredictionResultScreenState createState() => _PredictionResultScreenState(); 28 | } 29 | 30 | class _PredictionResultScreenState extends State { 31 | int state = 0; 32 | 33 | @override 34 | void initState() { 35 | super.initState(); 36 | if (widget.attendance < widget.result) 37 | state = 1; 38 | else if (widget.attendance > widget.result) state = -1; 39 | } 40 | 41 | @override 42 | Widget build(BuildContext context) { 43 | final isDark = AdaptiveTheme.of(context).mode == AdaptiveThemeMode.dark; 44 | return Consumer( 45 | builder: (context, _auth, child) { 46 | final img = _auth.user!.img.toString().split(',')[1]; 47 | final textColor = state == 1 48 | ? kGreen 49 | : state == -1 50 | ? kOrange 51 | : isDark 52 | ? Colors.white 53 | : Colors.black; 54 | return Scaffold( 55 | body: SafeArea( 56 | child: Column( 57 | crossAxisAlignment: CrossAxisAlignment.center, 58 | children: [ 59 | SimpleAppBar( 60 | img: img, 61 | onPic: () {}, 62 | onBack: () { 63 | Navigator.pop(context); 64 | }, 65 | ), 66 | kLowPadding, 67 | Text('Your Result', 68 | textAlign: TextAlign.center, 69 | style: Theme.of(context).textTheme.bodyText1!.copyWith( 70 | color: isDark ? Colors.white : Colors.black, 71 | )), 72 | kLowPadding, 73 | Text( 74 | '${widget.result.toStringAsFixed(2)}%', 75 | style: Theme.of(context) 76 | .textTheme 77 | .headline3! 78 | .copyWith(color: textColor, fontWeight: FontWeight.w700), 79 | ), 80 | kLowPadding, 81 | Text( 82 | 'If you attend ${widget.attend} more lecture\n' 83 | 'out of ${widget.total} lectures.', 84 | textAlign: TextAlign.center, 85 | style: Theme.of(context).textTheme.bodyText1!.copyWith( 86 | color: isDark ? Colors.white : Colors.black, 87 | )), 88 | kMedPadding, 89 | Visibility( 90 | visible: state != 0, 91 | child: Row( 92 | mainAxisAlignment: MainAxisAlignment.center, 93 | children: [ 94 | Icon( 95 | state == 1 96 | ? Icons.arrow_drop_up 97 | : Icons.arrow_drop_down, 98 | color: textColor, 99 | size: 30, 100 | ), 101 | Text( 102 | ((state > 0 ? "+" : "-") + 103 | (widget.attendance - widget.result) 104 | .abs() 105 | .toStringAsFixed(2)), 106 | style: TextStyle(color: textColor), 107 | ), 108 | ], 109 | ), 110 | ), 111 | kHighPadding, 112 | Expanded( 113 | child: Padding( 114 | padding: const EdgeInsets.all(30.0), 115 | child: Lottie.asset('assets/anim/loading.json'), 116 | ), 117 | ), 118 | ], 119 | ), 120 | ), 121 | ); 122 | }, 123 | ); 124 | } 125 | } 126 | --------------------------------------------------------------------------------