├── .gitignore ├── .metadata ├── LICENSE ├── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── app │ ├── build.gradle │ ├── google-services.json │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── wave │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── assets ├── icons │ ├── add_ico.png │ ├── add_image_ico.png │ ├── add_story_ico.png │ ├── change_image_ico.png │ ├── chat_full_ico.png │ ├── chat_ico.png │ ├── comment_ico.png │ ├── double_check_ico.png │ ├── empty_ico.png │ ├── explore_full_ico.png │ ├── explore_ico.png │ ├── follow_ico.png │ ├── images_ico.png │ ├── like_full_ico.png │ ├── like_ico.png │ ├── more_ico.png │ ├── no_user_found_ico.png │ ├── notification_ico.png │ ├── profile_full_ico.png │ ├── profile_ico.png │ ├── saved_ico.png │ ├── search_full_ico.png │ ├── search_ico.png │ ├── send_message_ico.png │ ├── share_ico.png │ ├── text_post_ico.png │ ├── verified_ico.png │ ├── video_ico.png │ └── viewed_by_ico.png └── logo │ ├── logo.png │ └── primaryLogo.png ├── codemagic.yaml ├── fonts ├── Alex.ttf ├── Inter.ttf └── poppins.ttf ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings ├── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h └── RunnerTests │ └── RunnerTests.swift ├── lib ├── controllers │ ├── Authentication │ │ ├── auth_screen_controller.dart │ │ └── user_controller.dart │ ├── HomeNavController │ │ └── home_nav_controller.dart │ └── PostController │ │ ├── create_post_controller.dart │ │ └── feed_post_controller.dart ├── data │ ├── chat_data.dart │ ├── notification_data.dart │ ├── post_data.dart │ ├── story_data.dart │ └── users_data.dart ├── main.dart ├── models │ ├── chat_model.dart │ ├── comment_post_model.dart │ ├── like_post_model.dart │ ├── message_model.dart │ ├── notification_model.dart │ ├── post_content_model.dart │ ├── post_model.dart │ ├── reply_comment_post.dart │ ├── response_model.dart │ ├── story_content_model.dart │ ├── story_model.dart │ └── user_model.dart ├── services │ ├── auth_services.dart │ ├── custom_notification_service.dart │ ├── notification_service.dart │ ├── notification_token.dart │ └── storage_service.dart ├── utils │ ├── constants │ │ ├── custom_colors.dart │ │ ├── custom_fonts.dart │ │ ├── custom_icons.dart │ │ ├── cutom_logo.dart │ │ ├── database_endpoints.dart │ │ ├── keys.dart │ │ └── preferences.dart │ ├── device_size.dart │ ├── enums.dart │ ├── image_config.dart │ ├── routing.dart │ └── util_functions.dart └── view │ ├── reusable_components │ ├── auth_textfield.dart │ ├── chat_head_container.dart │ ├── custom_textbox_for_comment.dart │ ├── feedbox.dart │ ├── mention_user_tile.dart │ ├── message_container.dart │ ├── more_option_feed.dart │ ├── notification_box.dart │ ├── single_comment_box.dart │ ├── textbox_editprofile.dart │ ├── thumbnail_media.dart │ ├── user_container.dart │ ├── video_play.dart │ └── view_image.dart │ └── screens │ ├── Authentication │ ├── login_screen.dart │ └── register_screen.dart │ ├── ChatScreen │ ├── chat_list_screen.dart │ ├── inbox_screen.dart │ ├── more_options_message.dart │ └── search_to_chat.dart │ ├── CreatePostScreen │ ├── add_image_for_post_box.dart │ ├── create_post_screen.dart │ ├── post_detail_screen.dart │ └── search_to_mention.dart │ ├── FeedScreen │ ├── feed_screen.dart │ └── list_comment_screen.dart │ ├── HomeNavigation │ └── home_navigation_screen.dart │ ├── NotificationScreen │ └── notification_screen.dart │ ├── ProfileScreen │ ├── blocked_contacts_screen.dart │ ├── edit_profile_screen.dart │ ├── list_users.dart │ ├── more_options_other_profile.dart │ ├── more_options_self.dart │ ├── other_profile.dart │ ├── profile_screen.dart │ ├── self_profile.dart │ ├── view_posts.dart │ └── view_saved_posts.dart │ ├── SearchScreen │ └── search_screen.dart │ ├── SplashScreen │ └── splash_screen.dart │ └── StoryScreen │ ├── create_story_screen.dart │ ├── list_stories.dart │ ├── view_story_screen.dart │ └── viewers_dialog.dart ├── linux ├── .gitignore ├── CMakeLists.txt ├── flutter │ ├── CMakeLists.txt │ ├── ephemeral │ │ └── .plugin_symlinks │ │ │ ├── path_provider_linux │ │ │ ├── shared_preferences_linux │ │ │ └── url_launcher_linux │ ├── generated_plugin_registrant.cc │ ├── generated_plugin_registrant.h │ └── generated_plugins.cmake ├── main.cc ├── my_application.cc └── my_application.h ├── macos ├── .gitignore ├── Flutter │ ├── Flutter-Debug.xcconfig │ ├── Flutter-Release.xcconfig │ ├── GeneratedPluginRegistrant.swift │ └── ephemeral │ │ ├── Flutter-Generated.xcconfig │ │ └── flutter_export_environment.sh ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── 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 │ ├── Base.lproj │ │ └── MainMenu.xib │ ├── Configs │ │ ├── AppInfo.xcconfig │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── Warnings.xcconfig │ ├── DebugProfile.entitlements │ ├── Info.plist │ ├── MainFlutterWindow.swift │ └── Release.entitlements └── RunnerTests │ └── RunnerTests.swift ├── pubspec.lock ├── pubspec.yaml ├── test ├── authentication_test.dart └── home_nav_test.dart ├── web ├── favicon.png ├── icons │ ├── Icon-192.png │ ├── Icon-512.png │ ├── Icon-maskable-192.png │ └── Icon-maskable-512.png ├── index.html └── manifest.json └── windows ├── .gitignore ├── CMakeLists.txt ├── flutter ├── CMakeLists.txt ├── ephemeral │ └── .plugin_symlinks │ │ ├── cloud_firestore │ │ ├── file_selector_windows │ │ ├── firebase_auth │ │ ├── firebase_core │ │ ├── firebase_storage │ │ ├── image_picker_windows │ │ ├── path_provider_windows │ │ ├── permission_handler_windows │ │ ├── shared_preferences_windows │ │ └── url_launcher_windows ├── generated_plugin_registrant.cc ├── generated_plugin_registrant.h └── generated_plugins.cmake └── runner ├── CMakeLists.txt ├── Runner.rc ├── flutter_window.cpp ├── flutter_window.h ├── main.cpp ├── resource.h ├── resources └── app_icon.ico ├── runner.exe.manifest ├── utils.cpp ├── utils.h ├── win32_window.cpp └── win32_window.h /.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 | .gradle/ 34 | 35 | # Web related 36 | lib/generated_plugin_registrant.dart 37 | lib/utils/Encrypt_Message.dart 38 | lib/utils/password.txt 39 | #android/app/google-services.json 40 | 41 | # Symbolication related 42 | app.*.symbols 43 | 44 | # Obfuscation related 45 | app.*.map.json 46 | 47 | # Android Studio will place build artifacts here 48 | /android/app/debug 49 | /android/app/profile 50 | /android/app/release 51 | 52 | 53 | -------------------------------------------------------------------------------- /.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: "ba393198430278b6595976de84fe170f553cc728" 8 | channel: "stable" 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: ba393198430278b6595976de84fe170f553cc728 17 | base_revision: ba393198430278b6595976de84fe170f553cc728 18 | - platform: android 19 | create_revision: ba393198430278b6595976de84fe170f553cc728 20 | base_revision: ba393198430278b6595976de84fe170f553cc728 21 | - platform: ios 22 | create_revision: ba393198430278b6595976de84fe170f553cc728 23 | base_revision: ba393198430278b6595976de84fe170f553cc728 24 | - platform: linux 25 | create_revision: ba393198430278b6595976de84fe170f553cc728 26 | base_revision: ba393198430278b6595976de84fe170f553cc728 27 | - platform: macos 28 | create_revision: ba393198430278b6595976de84fe170f553cc728 29 | base_revision: ba393198430278b6595976de84fe170f553cc728 30 | - platform: web 31 | create_revision: ba393198430278b6595976de84fe170f553cc728 32 | base_revision: ba393198430278b6595976de84fe170f553cc728 33 | - platform: windows 34 | create_revision: ba393198430278b6595976de84fe170f553cc728 35 | base_revision: ba393198430278b6595976de84fe170f553cc728 36 | 37 | # User provided section 38 | 39 | # List of Local paths (relative to this file) that should be 40 | # ignored by the migrate tool. 41 | # 42 | # Files that are not part of the templates will be ignored by default. 43 | unmanaged_files: 44 | - 'lib/main.dart' 45 | - 'ios/Runner.xcodeproj/project.pbxproj' 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Wave 2 | 3 | Wave is an open source social media app that allows users to connect with friends, share updates, and discover new content. With features like posting, feed displaying, chat, and profile creation, Wave offers a platform for users to express themselves and stay connected with their social circles. 4 | 5 | ## Features 6 | 7 | - **Posting:** Users can create and share posts with text, images, and videos. 8 | - **Feed Displaying:** The feed displays posts from friends and the community, keeping users updated on the latest content. 9 | - **Chat:** Real-time chat functionality allows users to communicate with each other privately. 10 | - **Profile Creation:** Users can create and customize their profiles with personal information and profile pictures. 11 | 12 | ## Installation 13 | 14 | 1. Clone the repository: `git clone https://github.com/Wave-2024/Wave.git` 15 | 2. Navigate to the project directory: `cd Wave` 16 | 3. Install dependencies: `flutter pub get` 17 | 4. Run the app: `flutter run` 18 | 19 | ## Usage 20 | 21 | 1. Sign up for a new account or log in with existing credentials. 22 | 2. Explore the feed to view posts from friends and the community. 23 | 3. Create new posts to share updates, photos, or videos. 24 | 4. Use the chat feature to communicate with friends privately. 25 | 5. Customize your profile with personal information and profile picture. 26 | 27 | ## Contributing 28 | 29 | We welcome contributions from the community to help improve Wave. If you'd like to contribute, please follow these steps: 30 | 31 | 1. Fork the repository. 32 | 2. Create a new branch: `git checkout -b feature/your-feature-name` 33 | 3. Make your changes and commit them: `git commit -m 'Add new feature'` 34 | 4. Push to the branch: `git push origin feature/your-feature-name` 35 | 5. Submit a pull request. 36 | 37 | Please read [CONTRIBUTING.md](CONTRIBUTING.md) for more details. 38 | 39 | ## License 40 | `Copyright © 2024 Wave` 41 | 42 | Being Open Source doesn't mean you can just make a copy of the app and upload it on playstore or sell 43 | a closed source copy of the same. 44 | Read the following carefully: 45 | 1. Any copy of a software under GPL must be under same license. So you can't upload the app on a closed source 46 | app repository like PlayStore/AppStore without distributing the source code. 47 | 2. You can't sell any copied/modified version of the app under any "non-free" license. 48 | You must provide the copy with the original software or with instructions on how to obtain original software, 49 | should clearly state all changes, should clearly disclose full source code, should include same license 50 | and all copyrights should be retained. 51 | 52 | In simple words, You can ONLY use the source code of this app for `Open Source` Project under `GPL v3.0` or later 53 | with all your source code CLEARLY DISCLOSED on any code hosting platform like GitHub, with clear INSTRUCTIONS on 54 | how to obtain the original software, should clearly STATE ALL CHANGES made and should RETAIN all copyrights. 55 | Use of this software under any "non-free" license is NOT permitted. 56 | 57 | This project is licensed under the GNU Affero General Public License (AGPL). See the [LICENSE](LICENSE) file for details. 58 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | analyzer: 11 | errors: 12 | must_be_immutable: ignore 13 | include: package:flutter_lints/flutter.yaml 14 | 15 | linter: 16 | # The lint rules applied to this project can be customized in the 17 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 18 | # included above or to enable additional rules. A list of all available lints 19 | # and their documentation is published at https://dart.dev/lints. 20 | # 21 | # Instead of disabling a lint rule for the entire project in the 22 | # section below, it can also be suppressed for a single line of code 23 | # or a specific dart file by using the `// ignore: name_of_lint` and 24 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 25 | # producing the lint. 26 | rules: 27 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 28 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 29 | 30 | # Additional information about this file can be found at 31 | # https://dart.dev/guides/language/analysis-options 32 | -------------------------------------------------------------------------------- /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 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "kotlin-android" 4 | id "dev.flutter.flutter-gradle-plugin" 5 | id 'com.google.gms.google-services' 6 | } 7 | 8 | def localProperties = new Properties() 9 | def localPropertiesFile = rootProject.file('local.properties') 10 | if (localPropertiesFile.exists()) { 11 | localPropertiesFile.withReader('UTF-8') { reader -> 12 | localProperties.load(reader) 13 | } 14 | } 15 | 16 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 17 | if (flutterVersionCode == null) { 18 | flutterVersionCode = '1' 19 | } 20 | 21 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 22 | if (flutterVersionName == null) { 23 | flutterVersionName = '1.0' 24 | } 25 | 26 | android { 27 | namespace "com.example.wave" 28 | compileSdk flutter.compileSdkVersion 29 | ndkVersion flutter.ndkVersion 30 | 31 | compileOptions { 32 | sourceCompatibility JavaVersion.VERSION_1_8 33 | targetCompatibility JavaVersion.VERSION_1_8 34 | } 35 | 36 | kotlinOptions { 37 | jvmTarget = '1.8' 38 | } 39 | 40 | sourceSets { 41 | main.java.srcDirs += 'src/main/kotlin' 42 | } 43 | 44 | defaultConfig { 45 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 46 | applicationId "com.starcoding.wave" 47 | // You can update the following values to match your application needs. 48 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. 49 | minSdkVersion 26 50 | targetSdkVersion 31 51 | versionCode flutterVersionCode.toInteger() 52 | versionName flutterVersionName 53 | } 54 | 55 | buildTypes { 56 | release { 57 | // TODO: Add your own signing config for the release build. 58 | // Signing with the debug keys for now, so `flutter run --release` works. 59 | signingConfig signingConfigs.debug 60 | } 61 | } 62 | } 63 | 64 | flutter { 65 | source '../..' 66 | } 67 | 68 | dependencies { 69 | implementation platform('com.google.firebase:firebase-bom:32.7.4') 70 | } 71 | -------------------------------------------------------------------------------- /android/app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "637608151880", 4 | "project_id": "wave-dev-42598", 5 | "storage_bucket": "wave-dev-42598.appspot.com" 6 | }, 7 | "client": [ 8 | { 9 | "client_info": { 10 | "mobilesdk_app_id": "1:637608151880:android:f001b8bcc31ab3c19f417d", 11 | "android_client_info": { 12 | "package_name": "com.starcoding.wave" 13 | } 14 | }, 15 | "oauth_client": [], 16 | "api_key": [ 17 | { 18 | "current_key": "AIzaSyDNJosx7KqYLqDSJH9KVpkM4DRArzOnm94" 19 | } 20 | ], 21 | "services": { 22 | "appinvite_service": { 23 | "other_platform_oauth_client": [] 24 | } 25 | } 26 | } 27 | ], 28 | "configuration_version": "1" 29 | } -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 36 | 37 | 38 | 39 | 43 | 44 | 45 | 48 | 49 | 50 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 74 | 75 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/wave/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.wave 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() 6 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.7.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.google.gms:google-services:4.3.15' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | tasks.register("clean", Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4G 2 | android.useAndroidX=true 3 | android.enableJetifier=true -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip 6 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | } 9 | settings.ext.flutterSdkPath = flutterSdkPath() 10 | 11 | includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") 12 | 13 | repositories { 14 | google() 15 | mavenCentral() 16 | gradlePluginPortal() 17 | } 18 | } 19 | 20 | plugins { 21 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 22 | id "com.android.application" version "7.3.0" apply false 23 | id "org.jetbrains.kotlin.android" version "1.7.10" apply false 24 | } 25 | 26 | include ":app" 27 | -------------------------------------------------------------------------------- /assets/icons/add_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/add_ico.png -------------------------------------------------------------------------------- /assets/icons/add_image_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/add_image_ico.png -------------------------------------------------------------------------------- /assets/icons/add_story_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/add_story_ico.png -------------------------------------------------------------------------------- /assets/icons/change_image_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/change_image_ico.png -------------------------------------------------------------------------------- /assets/icons/chat_full_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/chat_full_ico.png -------------------------------------------------------------------------------- /assets/icons/chat_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/chat_ico.png -------------------------------------------------------------------------------- /assets/icons/comment_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/comment_ico.png -------------------------------------------------------------------------------- /assets/icons/double_check_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/double_check_ico.png -------------------------------------------------------------------------------- /assets/icons/empty_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/empty_ico.png -------------------------------------------------------------------------------- /assets/icons/explore_full_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/explore_full_ico.png -------------------------------------------------------------------------------- /assets/icons/explore_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/explore_ico.png -------------------------------------------------------------------------------- /assets/icons/follow_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/follow_ico.png -------------------------------------------------------------------------------- /assets/icons/images_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/images_ico.png -------------------------------------------------------------------------------- /assets/icons/like_full_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/like_full_ico.png -------------------------------------------------------------------------------- /assets/icons/like_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/like_ico.png -------------------------------------------------------------------------------- /assets/icons/more_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/more_ico.png -------------------------------------------------------------------------------- /assets/icons/no_user_found_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/no_user_found_ico.png -------------------------------------------------------------------------------- /assets/icons/notification_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/notification_ico.png -------------------------------------------------------------------------------- /assets/icons/profile_full_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/profile_full_ico.png -------------------------------------------------------------------------------- /assets/icons/profile_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/profile_ico.png -------------------------------------------------------------------------------- /assets/icons/saved_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/saved_ico.png -------------------------------------------------------------------------------- /assets/icons/search_full_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/search_full_ico.png -------------------------------------------------------------------------------- /assets/icons/search_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/search_ico.png -------------------------------------------------------------------------------- /assets/icons/send_message_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/send_message_ico.png -------------------------------------------------------------------------------- /assets/icons/share_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/share_ico.png -------------------------------------------------------------------------------- /assets/icons/text_post_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/text_post_ico.png -------------------------------------------------------------------------------- /assets/icons/verified_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/verified_ico.png -------------------------------------------------------------------------------- /assets/icons/video_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/video_ico.png -------------------------------------------------------------------------------- /assets/icons/viewed_by_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/icons/viewed_by_ico.png -------------------------------------------------------------------------------- /assets/logo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/logo/logo.png -------------------------------------------------------------------------------- /assets/logo/primaryLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/assets/logo/primaryLogo.png -------------------------------------------------------------------------------- /codemagic.yaml: -------------------------------------------------------------------------------- 1 | workflows: 2 | build_android: 3 | name: Build Android APK 4 | triggering: 5 | events: 6 | - push 7 | branch_patterns: 8 | - pattern: 'prod' 9 | include: true 10 | source: true 11 | environment: 12 | flutter: stable 13 | java: "17" 14 | scripts: 15 | - name: Install dependencies 16 | script: flutter pub get 17 | - name: Build APK 18 | script: flutter build apk --release 19 | artifacts: 20 | - build/app/outputs/flutter-apk/app-release.apk 21 | publishing: 22 | email: 23 | recipients: 24 | - alphaisgod1@gmail.com 25 | - skshrutikumari46@gmail.com 26 | notify: 27 | success: true 28 | -------------------------------------------------------------------------------- /fonts/Alex.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/fonts/Alex.ttf -------------------------------------------------------------------------------- /fonts/Inter.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/fonts/Inter.ttf -------------------------------------------------------------------------------- /fonts/poppins.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/fonts/poppins.ttf -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleURLTypes 6 | 7 | 8 | CFBundleTypeRole 9 | Editor 10 | CFBundleURLSchemes 11 | 12 | com.googleusercontent.apps.637608151880-fikt6h6e9o3b0853fnt32s2gja76gntk 13 | 14 | 15 | 16 | CFBundleDevelopmentRegion 17 | $(DEVELOPMENT_LANGUAGE) 18 | CFBundleDisplayName 19 | Wave 20 | CFBundleExecutable 21 | $(EXECUTABLE_NAME) 22 | CFBundleIdentifier 23 | $(PRODUCT_BUNDLE_IDENTIFIER) 24 | CFBundleInfoDictionaryVersion 25 | 6.0 26 | CFBundleName 27 | wave 28 | CFBundlePackageType 29 | APPL 30 | CFBundleShortVersionString 31 | $(FLUTTER_BUILD_NAME) 32 | CFBundleSignature 33 | ???? 34 | CFBundleVersion 35 | $(FLUTTER_BUILD_NUMBER) 36 | LSRequiresIPhoneOS 37 | 38 | UILaunchStoryboardName 39 | LaunchScreen 40 | UIMainStoryboardFile 41 | Main 42 | UISupportedInterfaceOrientations 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | UISupportedInterfaceOrientations~ipad 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationPortraitUpsideDown 52 | UIInterfaceOrientationLandscapeLeft 53 | UIInterfaceOrientationLandscapeRight 54 | 55 | CADisableMinimumFrameDurationOnPhone 56 | 57 | UIApplicationSupportsIndirectInputEvents 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /ios/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /lib/controllers/Authentication/auth_screen_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_auth/firebase_auth.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:shared_preferences/shared_preferences.dart'; 4 | import 'package:wave/models/response_model.dart'; 5 | import 'package:wave/services/auth_services.dart'; 6 | import 'package:wave/utils/constants/preferences.dart'; 7 | import 'package:wave/utils/enums.dart'; 8 | 9 | class AuthScreenController extends ChangeNotifier { 10 | LOGIN loginState = LOGIN.IDLE; 11 | REGISTER registerState = REGISTER.IDLE; 12 | bool _obscuredTextLogin = false; 13 | bool _obscuredTextReg = false; 14 | bool get obscuredTextLogin => _obscuredTextLogin; 15 | bool get obscuredTextReg => _obscuredTextReg; 16 | 17 | // Method to toggle password visibility for login screen 18 | void togglePasswordVisibilityLogin() { 19 | _obscuredTextLogin = !_obscuredTextLogin; 20 | notifyListeners(); // Notify listeners to update the UI 21 | } 22 | 23 | // Method to toggle password visibility for registration screen 24 | void togglePasswordVisibilityReg() { 25 | _obscuredTextReg = !_obscuredTextReg; 26 | notifyListeners(); // Notify listeners to update the UI 27 | } 28 | 29 | Future startLoginProcess( 30 | {required String email, 31 | required String password, 32 | required FirebaseAuth firebaseAuth}) async { 33 | loginState = LOGIN.LOGGING_IN; 34 | await Future.delayed(Duration.zero); 35 | notifyListeners(); 36 | 37 | var auth = AuthService(firebaseAuth); 38 | var authResponse = await auth.signIn(email: email, password: password); 39 | // Successful sign in 40 | if (authResponse.runtimeType == UserCredential) { 41 | loginState = LOGIN.IDLE; 42 | notifyListeners(); 43 | return CustomResponse(responseStatus: true, response: authResponse); 44 | } 45 | // Sign in failed 46 | else { 47 | loginState = LOGIN.IDLE; 48 | notifyListeners(); 49 | 50 | return CustomResponse(responseStatus: false, response: authResponse); 51 | } 52 | } 53 | 54 | Future startRegistrationProcess( 55 | {required String email, 56 | required String password, 57 | required FirebaseAuth firebaseAuth}) async { 58 | registerState = REGISTER.CREATING; 59 | await Future.delayed(Duration.zero); 60 | notifyListeners(); 61 | var auth = AuthService(firebaseAuth); 62 | var authResponse = await auth.signUp(email: email, password: password); 63 | // Successful sign up 64 | if (authResponse.runtimeType == UserCredential) { 65 | registerState = REGISTER.IDLE; 66 | notifyListeners(); 67 | return CustomResponse(responseStatus: true, response: authResponse); 68 | } 69 | // Sign up failed 70 | else { 71 | registerState = REGISTER.IDLE; 72 | notifyListeners(); 73 | return CustomResponse(responseStatus: false, response: authResponse); 74 | } 75 | } 76 | 77 | Future signOut({required FirebaseAuth firebaseAuth}) async { 78 | var auth = AuthService(firebaseAuth); 79 | await auth.signOut(); 80 | final SharedPreferences prefs = await SharedPreferences.getInstance(); 81 | await prefs.setBool(Pref.login_pref, false); 82 | await prefs.setString(Pref.user_id, ""); 83 | } 84 | 85 | Future loginWithGoogle( 86 | {required FirebaseAuth firebaseAuth}) async { 87 | var auth = AuthService(firebaseAuth); 88 | CustomResponse customResponse = await auth.signInWithGoogle(); 89 | return customResponse; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /lib/controllers/HomeNavController/home_nav_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class HomeNavController extends ChangeNotifier { 4 | int currentScreenIndex = 0; 5 | 6 | void setCurrentScreenIndex(int newIndex) { 7 | currentScreenIndex = newIndex; 8 | notifyListeners(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/controllers/PostController/feed_post_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:wave/models/post_model.dart'; 4 | import 'package:wave/utils/constants/database_endpoints.dart'; 5 | import 'package:wave/utils/enums.dart'; 6 | 7 | class FeedPostController extends ChangeNotifier { 8 | List posts = []; 9 | POSTS_STATE postState = POSTS_STATE.ABSENT; 10 | int currentPostLimit = 15; 11 | DocumentSnapshot? lastDocument; 12 | 13 | Future getPosts(List following) async { 14 | if (following.isEmpty) { 15 | postState = POSTS_STATE.PRESENT; 16 | await Future.delayed(Duration.zero); 17 | notifyListeners(); 18 | return; 19 | } 20 | 21 | postState = POSTS_STATE.LOADING; 22 | await Future.delayed(Duration.zero); 23 | notifyListeners(); 24 | 25 | try { 26 | Query query = Database.postDatabase 27 | .where('userId', whereIn: following) 28 | .orderBy('createdAt', descending: true) 29 | .limit(currentPostLimit); 30 | 31 | if (lastDocument != null) { 32 | query = query.startAfterDocument(lastDocument!); 33 | } 34 | 35 | final postQuerySnapshot = await query.get(); 36 | debugPrint("lenght of posts = ${postQuerySnapshot.docs.length}"); 37 | if (postQuerySnapshot.docs.isNotEmpty) { 38 | lastDocument = postQuerySnapshot.docs.last; 39 | 40 | for (var index = 0; index < postQuerySnapshot.docs.length; ++index) { 41 | try { 42 | Post post = Post.fromMap( 43 | postQuerySnapshot.docs[index].data() as Map); 44 | posts.add(post); 45 | } catch (e) { 46 | debugPrint("Error converting document to Post: $e"); 47 | } 48 | } 49 | } 50 | postState = POSTS_STATE.PRESENT; 51 | } catch (e) { 52 | postState = POSTS_STATE.PRESENT; 53 | } 54 | 55 | notifyListeners(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /lib/data/notification_data.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | import 'package:wave/models/response_model.dart'; 3 | import 'package:wave/utils/constants/database_endpoints.dart'; 4 | import 'package:wave/models/notification_model.dart' as notification; 5 | 6 | class NotificationData { 7 | static Future getNotification( 8 | String userId, String notificationId) async { 9 | var res = await Database.getNotificationDatabase(userId) 10 | .doc(notificationId) 11 | .get(); 12 | return notification.Notification.fromMap( 13 | res.data()! as Map); 14 | } 15 | 16 | static Future createNotification( 17 | {required notification.Notification notification}) async { 18 | try { 19 | var response = 20 | await Database.getNotificationDatabase(notification.forUser) 21 | .add(notification.toMap()); 22 | await Database.getNotificationDatabase(notification.forUser) 23 | .doc(response.id) 24 | .update({'id': response.id}); 25 | return CustomResponse(responseStatus: true); 26 | } on FirebaseException catch (e) { 27 | return CustomResponse(responseStatus: false, response: e.message!); 28 | } 29 | } 30 | 31 | static Future viewNotification( 32 | {required String userId, required String notificationId}) async { 33 | try { 34 | var docRef = Database.getNotificationDatabase(userId).doc(notificationId); 35 | await docRef.update({'seen': true}); 36 | return CustomResponse(responseStatus: true); 37 | } on FirebaseException catch (e) { 38 | return CustomResponse(responseStatus: false, response: e.message!); 39 | } 40 | } 41 | 42 | static Future deleteNotification( 43 | {required String userId, required String notificationId}) async { 44 | try { 45 | var docRef = Database.getNotificationDatabase(userId).doc(notificationId); 46 | await docRef.delete(); 47 | return CustomResponse(responseStatus: true); 48 | } on FirebaseException catch (e) { 49 | return CustomResponse(responseStatus: false, response: e.message!); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/data/users_data.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | import 'package:get/get.dart'; 3 | import 'package:wave/models/response_model.dart'; 4 | import 'package:wave/models/user_model.dart'; 5 | import 'package:wave/utils/constants/database_endpoints.dart'; 6 | 7 | class UserData { 8 | static Future getUser({required String userID}) async { 9 | var userResponse = await Database.userDatabase.doc(userID).get(); 10 | User user = User.fromMap(userResponse.data()!); 11 | return user; 12 | } 13 | 14 | static Future createUser({required User user}) async { 15 | var userResponse = 16 | await Database.userDatabase.doc(user.id).set(user.toMap()); 17 | return user; 18 | } 19 | 20 | static Future savePost({required String userId, required String postId}) async { 21 | try { 22 | await FirebaseFirestore.instance.runTransaction((transaction) async { 23 | DocumentReference userDocRef = Database.userDatabase.doc(userId); 24 | DocumentSnapshot userDoc = await transaction.get(userDocRef); 25 | if (userDoc.exists) { 26 | List savedPosts = (userDoc.data() as Map)['savedPosts'] ?? []; 27 | if (!savedPosts.contains(postId)) { 28 | savedPosts.add(postId); 29 | transaction.update(userDocRef, {'savedPosts': savedPosts}); 30 | } 31 | } 32 | }); 33 | return CustomResponse(responseStatus: true, response: 'Post saved successfully.'); 34 | } catch (e) { 35 | return CustomResponse(responseStatus: false, response: 'Failed to save post: $e'); 36 | } 37 | } 38 | 39 | static Future unsavePost({required String userId, required String postId}) async { 40 | try { 41 | await FirebaseFirestore.instance.runTransaction((transaction) async { 42 | DocumentReference userDocRef = Database.userDatabase.doc(userId); 43 | DocumentSnapshot userDoc = await transaction.get(userDocRef); 44 | if (userDoc.exists) { 45 | List savedPosts = (userDoc.data() as Map)['savedPosts'] ?? []; 46 | if (savedPosts.contains(postId)) { 47 | savedPosts.remove(postId); 48 | transaction.update(userDocRef, {'savedPosts': savedPosts}); 49 | } 50 | } 51 | }); 52 | return CustomResponse(responseStatus: true, response: 'Post removed successfully.'); 53 | } catch (e) { 54 | return CustomResponse(responseStatus: false, response: 'Failed to unsave post: $e'); 55 | } 56 | } 57 | 58 | static Future updateUser({ 59 | required String userId, 60 | String? name, 61 | String? username, 62 | String? bio, 63 | String? fcmToken, 64 | String? coverPicture, 65 | String? displayPicture, 66 | List? following, 67 | List? followers, 68 | }) async { 69 | try { 70 | Map dataToUpdate = {}; 71 | 72 | // Only add fields that are not null to the map 73 | if (name != null) dataToUpdate['name'] = name; 74 | if (username != null) dataToUpdate['username'] = username; 75 | if (bio != null) dataToUpdate['bio'] = bio; 76 | if (coverPicture != null) dataToUpdate['coverPicture'] = coverPicture; 77 | if (displayPicture != null) 78 | dataToUpdate['displayPicture'] = displayPicture; 79 | if (following != null) dataToUpdate['following'] = following; 80 | if (followers != null) dataToUpdate['followers'] = followers; 81 | if (fcmToken != null) dataToUpdate['fcmToken'] = fcmToken; 82 | // Update the document in Firestore only if there's something to update 83 | if (dataToUpdate.isNotEmpty) { 84 | await Database.userDatabase.doc(userId).update(dataToUpdate); 85 | return CustomResponse( 86 | responseStatus: true, response: 'Update successful'); 87 | } else { 88 | return CustomResponse( 89 | responseStatus: false, response: 'No data to update'); 90 | } 91 | } on FirebaseException catch (e) { 92 | return CustomResponse(responseStatus: false, response: e.toString()); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_messaging/firebase_messaging.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:firebase_core/firebase_core.dart'; 4 | import 'package:get/get.dart'; 5 | 6 | import 'package:wave/controllers/Authentication/auth_screen_controller.dart'; 7 | import 'package:wave/controllers/Authentication/user_controller.dart'; 8 | import 'package:wave/controllers/HomeNavController/home_nav_controller.dart'; 9 | import 'package:wave/controllers/PostController/create_post_controller.dart'; 10 | import 'package:wave/controllers/PostController/feed_post_controller.dart'; 11 | import 'package:wave/data/users_data.dart'; 12 | import 'package:wave/utils/routing.dart'; 13 | import 'package:provider/provider.dart'; 14 | 15 | import 'models/user_model.dart'; 16 | 17 | // Background message handler 18 | Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { 19 | "Handling a background message: ${message.messageId}".printInfo(); 20 | if (message.notification != null) { 21 | 'Message also contained a notification: ${message.notification}' 22 | .printError(); 23 | } 24 | } 25 | 26 | Future handleNotificationClick(Map messageData) async { 27 | if (messageData.containsKey('chatId') && 28 | messageData.containsKey('otherUserId')) { 29 | User otherUser = await UserData.getUser(userID: messageData['otherUserId']); 30 | User selfUser = await UserData.getUser(userID: messageData['selfUserId']); 31 | Get.toNamed(AppRoutes.inboxScreen, arguments: { 32 | 'chatId': messageData['chatId'], 33 | 'otherUser': otherUser, 34 | 'selfUser': selfUser, 35 | }); 36 | } 37 | } 38 | 39 | Future main() async { 40 | WidgetsFlutterBinding.ensureInitialized(); 41 | 42 | await Firebase.initializeApp(); 43 | FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); 44 | RemoteMessage? initialMessage = 45 | await FirebaseMessaging.instance.getInitialMessage(); 46 | FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async { 47 | await handleNotificationClick(message.data); 48 | }); 49 | runApp(Wave( 50 | initialMessage: initialMessage, 51 | )); 52 | } 53 | 54 | class Wave extends StatelessWidget { 55 | final RemoteMessage? initialMessage; 56 | const Wave({Key? key, this.initialMessage}) : super(key: key); 57 | 58 | @override 59 | Widget build(BuildContext context) { 60 | return MultiProvider( 61 | providers: [ 62 | ChangeNotifierProvider( 63 | create: (context) => AuthScreenController(), 64 | ), 65 | ChangeNotifierProvider( 66 | create: (context) => UserDataController(), 67 | ), 68 | ChangeNotifierProvider( 69 | create: (context) => HomeNavController(), 70 | ), 71 | ChangeNotifierProvider( 72 | create: (context) => CreatePostController(), 73 | ), 74 | ChangeNotifierProvider( 75 | create: (context) => FeedPostController(), 76 | ), 77 | ], 78 | builder: (context, child) { 79 | if (initialMessage != null) { 80 | WidgetsBinding.instance.addPostFrameCallback((_) async { 81 | await handleNotificationClick(initialMessage!.data); 82 | }); 83 | } else {} 84 | return child!; 85 | }, 86 | child: GetMaterialApp( 87 | debugShowCheckedModeBanner: false, 88 | getPages: AppRoutes.routes, 89 | initialRoute: AppRoutes.splashScreen, 90 | ), 91 | ); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /lib/models/chat_model.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'dart:convert'; 3 | 4 | class Chat { 5 | String id; 6 | String firstUser; 7 | String secondUser; 8 | String lastMessage; 9 | String lastSender; 10 | DateTime timeOfLastMessage; 11 | bool seenLastMessage; 12 | Chat({ 13 | required this.id, 14 | required this.firstUser, 15 | required this.secondUser, 16 | required this.lastSender, 17 | required this.lastMessage, 18 | required this.timeOfLastMessage, 19 | required this.seenLastMessage, 20 | 21 | }); 22 | 23 | 24 | 25 | Chat copyWith({ 26 | String? id, 27 | String? firstUser, 28 | String? lastSender, 29 | String? secondUser, 30 | String? lastMessage, 31 | DateTime? timeOfLastMessage, 32 | bool? seenLastMessage, 33 | 34 | }) { 35 | return Chat( 36 | id: id ?? this.id, 37 | lastSender: lastSender?? this.lastSender, 38 | seenLastMessage: seenLastMessage??this.seenLastMessage, 39 | firstUser: firstUser ?? this.firstUser, 40 | secondUser: secondUser ?? this.secondUser, 41 | lastMessage: lastMessage ?? this.lastMessage, 42 | timeOfLastMessage: timeOfLastMessage ?? this.timeOfLastMessage, 43 | ); 44 | } 45 | 46 | Map toMap() { 47 | return { 48 | 'id': id, 49 | 'lastSender':lastSender, 50 | 'firstUser': firstUser, 51 | 'seenLastMessage':seenLastMessage, 52 | 'secondUser': secondUser, 53 | 'lastMessage': lastMessage, 54 | 'timeOfLastMessage': timeOfLastMessage.millisecondsSinceEpoch, 55 | }; 56 | } 57 | 58 | factory Chat.fromMap(Map map) { 59 | return Chat( 60 | lastSender: map['lastSender']as String, 61 | seenLastMessage: map['seenLastMessage'] as bool, 62 | id: map['id'] as String, 63 | firstUser: map['firstUser'] as String, 64 | secondUser: map['secondUser'] as String, 65 | lastMessage: map['lastMessage'] as String, 66 | timeOfLastMessage: DateTime.fromMillisecondsSinceEpoch(map['timeOfLastMessage'] as int), 67 | ); 68 | } 69 | 70 | String toJson() => json.encode(toMap()); 71 | 72 | factory Chat.fromJson(String source) => Chat.fromMap(json.decode(source) as Map); 73 | 74 | @override 75 | String toString() { 76 | return 'Chat(id: $id, firstUser: $firstUser, secondUser: $secondUser,seenLastMessage :$seenLastMessage , lastMessage: $lastMessage, timeOfLastMessage: $timeOfLastMessage)'; 77 | } 78 | 79 | @override 80 | bool operator ==(covariant Chat other) { 81 | if (identical(this, other)) return true; 82 | 83 | return 84 | other.id == id && 85 | other.firstUser == firstUser && 86 | other.secondUser == secondUser && 87 | other.lastMessage == lastMessage && 88 | other.timeOfLastMessage == timeOfLastMessage; 89 | } 90 | 91 | @override 92 | int get hashCode { 93 | return id.hashCode ^ 94 | firstUser.hashCode ^ 95 | secondUser.hashCode ^ 96 | lastMessage.hashCode ^ 97 | timeOfLastMessage.hashCode; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /lib/models/comment_post_model.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'dart:convert'; 3 | 4 | class Comment { 5 | String id; 6 | String userId; 7 | String comment; 8 | DateTime createdAt; 9 | String postId; 10 | Comment({ 11 | required this.id, 12 | required this.userId, 13 | required this.postId, 14 | required this.comment, 15 | required this.createdAt, 16 | }); 17 | 18 | Comment copyWith({ 19 | String? id, 20 | String? userId, 21 | String? comment, 22 | DateTime? createdAt, 23 | String? postId, 24 | }) { 25 | return Comment( 26 | postId: postId??this.postId, 27 | id: id ?? this.id, 28 | userId: userId ?? this.userId, 29 | comment: comment ?? this.comment, 30 | createdAt: createdAt ?? this.createdAt, 31 | ); 32 | } 33 | 34 | Map toMap() { 35 | return { 36 | 'id': id, 37 | 'userId': userId, 38 | 'postId':postId, 39 | 'comment': comment, 40 | 'createdAt': createdAt.millisecondsSinceEpoch, 41 | }; 42 | } 43 | 44 | factory Comment.fromMap(Map map) { 45 | return Comment( 46 | id: map['id'] as String, 47 | postId: map['postId'] as String, 48 | userId: map['userId'] as String, 49 | comment: map['comment'] as String, 50 | createdAt: DateTime.fromMillisecondsSinceEpoch(map['createdAt'] as int), 51 | ); 52 | } 53 | 54 | String toJson() => json.encode(toMap()); 55 | 56 | factory Comment.fromJson(String source) => Comment.fromMap(json.decode(source) as Map); 57 | 58 | @override 59 | String toString() { 60 | return 'Comment(id: $id, userId: $userId, comment: $comment, createdAt: $createdAt, postId: $postId)'; 61 | } 62 | 63 | @override 64 | bool operator ==(covariant Comment other) { 65 | if (identical(this, other)) return true; 66 | 67 | return 68 | other.id == id && 69 | other.postId==postId && 70 | other.userId == userId && 71 | other.comment == comment && 72 | other.createdAt == createdAt; 73 | } 74 | 75 | @override 76 | int get hashCode { 77 | return id.hashCode ^ 78 | userId.hashCode ^ 79 | comment.hashCode ^ 80 | createdAt.hashCode; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lib/models/like_post_model.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'dart:convert'; 3 | 4 | class Like { 5 | String id; 6 | String userId; 7 | DateTime createdAt; 8 | Like({ 9 | required this.id, 10 | required this.userId, 11 | required this.createdAt, 12 | }); 13 | 14 | 15 | Like copyWith({ 16 | String? id, 17 | String? userId, 18 | DateTime? createdAt, 19 | }) { 20 | return Like( 21 | id: id ?? this.id, 22 | userId: userId ?? this.userId, 23 | createdAt: createdAt ?? this.createdAt, 24 | ); 25 | } 26 | 27 | Map toMap() { 28 | return { 29 | 'id': id, 30 | 'userId': userId, 31 | 'createdAt': createdAt.millisecondsSinceEpoch, 32 | }; 33 | } 34 | 35 | factory Like.fromMap(Map map) { 36 | return Like( 37 | id: map['id'] as String, 38 | userId: map['userId'] as String, 39 | createdAt: DateTime.fromMillisecondsSinceEpoch(map['createdAt'] as int), 40 | ); 41 | } 42 | 43 | String toJson() => json.encode(toMap()); 44 | 45 | factory Like.fromJson(String source) => Like.fromMap(json.decode(source) as Map); 46 | 47 | @override 48 | String toString() => 'Like(id: $id, userId: $userId, createdAt: $createdAt)'; 49 | 50 | @override 51 | bool operator ==(covariant Like other) { 52 | if (identical(this, other)) return true; 53 | 54 | return 55 | other.id == id && 56 | other.userId == userId && 57 | other.createdAt == createdAt; 58 | } 59 | 60 | @override 61 | int get hashCode => id.hashCode ^ userId.hashCode ^ createdAt.hashCode; 62 | } 63 | -------------------------------------------------------------------------------- /lib/models/message_model.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:wave/utils/enums.dart'; 3 | 4 | class Message { 5 | String message; 6 | String sender; 7 | DateTime createdAt; 8 | MESSAGE_TYPE message_type; 9 | String id; 10 | String chatId; 11 | bool seen; 12 | 13 | Message({ 14 | required this.message, 15 | required this.sender, 16 | required this.createdAt, 17 | required this.message_type, 18 | required this.id, 19 | required this.chatId, 20 | this.seen = false, 21 | }); 22 | 23 | Message copyWith({ 24 | String? message, 25 | String? sender, 26 | DateTime? createdAt, 27 | MESSAGE_TYPE? message_type, 28 | String? id, 29 | String? chatId, 30 | bool? seen, 31 | }) { 32 | return Message( 33 | message: message ?? this.message, 34 | sender: sender ?? this.sender, 35 | createdAt: createdAt ?? this.createdAt, 36 | message_type: message_type ?? this.message_type, 37 | id: id ?? this.id, 38 | chatId: chatId ?? this.chatId, 39 | seen: seen ?? this.seen, 40 | ); 41 | } 42 | 43 | Map toMap() { 44 | return { 45 | 'message': message, 46 | 'sender': sender, 47 | 'createdAt': createdAt.millisecondsSinceEpoch, 48 | 'message_type': message_type.toString().split('.').last, 49 | 'id': id, 50 | 'chatId': chatId, 51 | 'seen': seen, 52 | }; 53 | } 54 | 55 | factory Message.fromMap(Map map) { 56 | return Message( 57 | message: map['message'] as String, 58 | sender: map['sender'] as String, 59 | createdAt: DateTime.fromMillisecondsSinceEpoch(map['createdAt'] as int), 60 | id: map['id'] as String, 61 | chatId: map['chatId'] as String, 62 | message_type: map['message_type'] != null 63 | ? (map['message_type'] == 'TEXT') 64 | ? MESSAGE_TYPE.TEXT 65 | : MESSAGE_TYPE.IMAGE 66 | : MESSAGE_TYPE.TEXT, 67 | seen: map['seen'] as bool? ?? false, 68 | ); 69 | } 70 | 71 | String toJson() => json.encode(toMap()); 72 | 73 | factory Message.fromJson(String source) => 74 | Message.fromMap(json.decode(source) as Map); 75 | 76 | @override 77 | String toString() { 78 | return 'Message(message: $message, sender: $sender, createdAt: $createdAt, message_type: $message_type, id: $id, chatId: $chatId, seen: $seen)'; 79 | } 80 | 81 | @override 82 | bool operator ==(covariant Message other) { 83 | if (identical(this, other)) return true; 84 | 85 | return other.message == message && 86 | other.sender == sender && 87 | other.createdAt == createdAt && 88 | other.message_type == message_type && 89 | other.id == id && 90 | other.chatId == chatId && 91 | other.seen == seen; 92 | } 93 | 94 | @override 95 | int get hashCode { 96 | return message.hashCode ^ 97 | sender.hashCode ^ 98 | createdAt.hashCode ^ 99 | message_type.hashCode ^ 100 | id.hashCode ^ 101 | chatId.hashCode ^ 102 | seen.hashCode; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /lib/models/post_content_model.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'dart:convert'; 3 | 4 | class PostContent { 5 | String type; 6 | /* type cane be of image,video */ 7 | String url; 8 | 9 | bool isMediaLandscape; 10 | PostContent({ 11 | required this.type, 12 | required this.url, 13 | required this.isMediaLandscape, 14 | }); 15 | 16 | PostContent copyWith({ 17 | String? type, 18 | String? url, 19 | bool? isMediaLandscape, 20 | }) { 21 | return PostContent( 22 | type: type ?? this.type, 23 | url: url ?? this.url, 24 | isMediaLandscape: isMediaLandscape ?? this.isMediaLandscape, 25 | ); 26 | } 27 | 28 | Map toMap() { 29 | return { 30 | 'type': type, 31 | 'url': url, 32 | 'isMediaLandscape': isMediaLandscape, 33 | }; 34 | } 35 | 36 | factory PostContent.fromMap(Map map) { 37 | return PostContent( 38 | type: map['type'] as String, 39 | url: map['url'] as String, 40 | isMediaLandscape: map['isMediaLandscape'] as bool, 41 | ); 42 | } 43 | 44 | String toJson() => json.encode(toMap()); 45 | 46 | factory PostContent.fromJson(String source) => 47 | PostContent.fromMap(json.decode(source) as Map); 48 | 49 | @override 50 | String toString() => 'PostContent(type: $type, url: $url, isMediaLandscape: $isMediaLandscape)'; 51 | 52 | @override 53 | bool operator ==(covariant PostContent other) { 54 | if (identical(this, other)) return true; 55 | 56 | return 57 | other.type == type && 58 | other.url == url && 59 | other.isMediaLandscape == isMediaLandscape; 60 | } 61 | 62 | @override 63 | int get hashCode => type.hashCode ^ url.hashCode ^ isMediaLandscape.hashCode; 64 | } 65 | -------------------------------------------------------------------------------- /lib/models/post_model.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'dart:convert'; 3 | 4 | import 'package:flutter/foundation.dart'; 5 | import 'package:get/get.dart'; 6 | 7 | import 'package:wave/models/post_content_model.dart'; 8 | 9 | class Post { 10 | // Doc based variables 11 | String id; 12 | List postList; 13 | DateTime createdAt; 14 | String userId; 15 | String caption; 16 | List mentions; 17 | Post({ 18 | required this.id, 19 | required this.postList, 20 | required this.createdAt, 21 | required this.userId, 22 | required this.caption, 23 | required this.mentions, 24 | }); 25 | // Collection based variables 26 | /* 27 | likes 28 | comments 29 | reports 30 | */ 31 | 32 | Post copyWith({ 33 | String? id, 34 | List? postList, 35 | DateTime? createdAt, 36 | String? userId, 37 | String? caption, 38 | List? mentions, 39 | }) { 40 | 41 | return Post( 42 | id: id ?? this.id, 43 | postList: postList ?? this.postList, 44 | createdAt: createdAt ?? this.createdAt, 45 | userId: userId ?? this.userId, 46 | caption: caption ?? this.caption, 47 | mentions: mentions ?? this.mentions, 48 | ); 49 | } 50 | 51 | Map toMap() { 52 | return { 53 | 'id': id, 54 | 'postList': postList.map((x) => x.toMap()).toList(), 55 | 'createdAt': createdAt.millisecondsSinceEpoch, 56 | 'userId': userId, 57 | 'caption': caption, 58 | 'mentions': mentions, 59 | }; 60 | } 61 | 62 | factory Post.fromMap(Map map) { 63 | return Post( 64 | id: map['id'] as String, 65 | postList: List.from( 66 | (map['postList'] as List).map( 67 | (x) => PostContent.fromMap(x as Map), 68 | ), 69 | ), 70 | createdAt: DateTime.fromMillisecondsSinceEpoch(map['createdAt'] as int), 71 | userId: map['userId'] as String, 72 | caption: map['caption'] as String, 73 | mentions: List.from((map['mentions'] as List)), 74 | ); 75 | } 76 | 77 | String toJson() => json.encode(toMap()); 78 | 79 | factory Post.fromJson(String source) => 80 | Post.fromMap(json.decode(source) as Map); 81 | 82 | @override 83 | String toString() { 84 | return 'Post(id: $id, postList: $postList, createdAt: $createdAt, userId: $userId, caption: $caption, mentions: $mentions)'; 85 | } 86 | 87 | @override 88 | bool operator ==(Object other) { 89 | if (identical(this, other)) return true; 90 | return other is Post && other.id == id; 91 | } 92 | 93 | @override 94 | int get hashCode => id.hashCode; 95 | } 96 | -------------------------------------------------------------------------------- /lib/models/reply_comment_post.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'dart:convert'; 3 | 4 | class ReplyComment { 5 | String reply; 6 | String id; 7 | String userId; 8 | String parentCommentId; 9 | DateTime createdAt; 10 | 11 | ReplyComment({ 12 | required this.reply, 13 | required this.id, 14 | required this.userId, 15 | required this.parentCommentId, 16 | required this.createdAt, 17 | }); 18 | 19 | 20 | ReplyComment copyWith({ 21 | String? reply, 22 | String? id, 23 | String? userId, 24 | String? parentCommentId, 25 | DateTime? createdAt, 26 | }) { 27 | return ReplyComment( 28 | reply: reply ?? this.reply, 29 | id: id ?? this.id, 30 | userId: userId ?? this.userId, 31 | parentCommentId: parentCommentId ?? this.parentCommentId, 32 | createdAt: createdAt ?? this.createdAt, 33 | ); 34 | } 35 | 36 | Map toMap() { 37 | return { 38 | 'reply': reply, 39 | 'id': id, 40 | 'userId': userId, 41 | 'parentCommentId': parentCommentId, 42 | 'createdAt': createdAt.millisecondsSinceEpoch, 43 | }; 44 | } 45 | 46 | factory ReplyComment.fromMap(Map map) { 47 | return ReplyComment( 48 | reply: map['reply'] as String, 49 | id: map['id'] as String, 50 | userId: map['userId'] as String, 51 | parentCommentId: map['parentCommentId'] as String, 52 | createdAt: DateTime.fromMillisecondsSinceEpoch(map['createdAt'] as int), 53 | ); 54 | } 55 | 56 | String toJson() => json.encode(toMap()); 57 | 58 | factory ReplyComment.fromJson(String source) => ReplyComment.fromMap(json.decode(source) as Map); 59 | 60 | @override 61 | String toString() { 62 | return 'ReplyComment(reply: $reply, id: $id, userId: $userId, parentCommentId: $parentCommentId, createdAt: $createdAt)'; 63 | } 64 | 65 | @override 66 | bool operator ==(covariant ReplyComment other) { 67 | if (identical(this, other)) return true; 68 | 69 | return 70 | other.reply == reply && 71 | other.id == id && 72 | other.userId == userId && 73 | other.parentCommentId == parentCommentId && 74 | other.createdAt == createdAt; 75 | } 76 | 77 | @override 78 | int get hashCode { 79 | return reply.hashCode ^ 80 | id.hashCode ^ 81 | userId.hashCode ^ 82 | parentCommentId.hashCode ^ 83 | createdAt.hashCode; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /lib/models/response_model.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'dart:convert'; 3 | 4 | class CustomResponse { 5 | 6 | final bool responseStatus; // Returns true if the operation was successful, otherwise false. 7 | dynamic response; // Returns a dynamic value if required by the situation 8 | 9 | CustomResponse({ 10 | required this.responseStatus, 11 | this.response, 12 | }); 13 | 14 | CustomResponse copyWith({ 15 | bool? responseStatus, 16 | dynamic response, 17 | }) { 18 | return CustomResponse( 19 | responseStatus: responseStatus ?? this.responseStatus, 20 | response: response ?? this.response, 21 | ); 22 | } 23 | 24 | Map toMap() { 25 | return { 26 | 'responseStatus': responseStatus, 27 | 'response': response, 28 | }; 29 | } 30 | 31 | factory CustomResponse.fromMap(Map map) { 32 | return CustomResponse( 33 | responseStatus: map['responseStatus'] as bool, 34 | response: map['response'] as dynamic, 35 | ); 36 | } 37 | 38 | String toJson() => json.encode(toMap()); 39 | 40 | factory CustomResponse.fromJson(String source) => 41 | CustomResponse.fromMap(json.decode(source) as Map); 42 | 43 | @override 44 | String toString() => 45 | 'CustomResponse(responseStatus: $responseStatus, response: $response)'; 46 | 47 | @override 48 | bool operator ==(covariant CustomResponse other) { 49 | if (identical(this, other)) return true; 50 | 51 | return other.responseStatus == responseStatus && other.response == response; 52 | } 53 | 54 | @override 55 | int get hashCode => responseStatus.hashCode ^ response.hashCode; 56 | } 57 | -------------------------------------------------------------------------------- /lib/models/story_content_model.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'dart:convert'; 3 | 4 | import 'package:flutter/foundation.dart'; 5 | 6 | import 'package:wave/utils/enums.dart'; 7 | 8 | class StoryContent { 9 | String id; 10 | DateTime createdAt; 11 | STORY_TYPE story_type; 12 | List seenBy; 13 | String url; 14 | StoryContent({ 15 | required this.id, 16 | required this.createdAt, 17 | required this.story_type, 18 | required this.seenBy, 19 | required this.url, 20 | }); 21 | 22 | StoryContent copyWith({ 23 | String? id, 24 | String?url, 25 | DateTime? createdAt, 26 | STORY_TYPE? story_type, 27 | List? seenBy, 28 | }) { 29 | return StoryContent( 30 | id: id ?? this.id, 31 | url: url ??this.url, 32 | createdAt: createdAt ?? this.createdAt, 33 | story_type: story_type ?? this.story_type, 34 | seenBy: seenBy ?? this.seenBy, 35 | ); 36 | } 37 | 38 | Map toMap() { 39 | return { 40 | 'id': id, 41 | 'createdAt': createdAt.millisecondsSinceEpoch, 42 | 'story_type': story_type.toString().split('.').last, 43 | 'seenBy': seenBy, 44 | 'url':url, 45 | }; 46 | } 47 | 48 | static STORY_TYPE decideStoryType(String type) { 49 | if (type == 'POST') { 50 | return STORY_TYPE.POST; 51 | } else if (type == 'IMAGE') { 52 | return STORY_TYPE.IMAGE; 53 | } else if (type == 'VIDEO') { 54 | return STORY_TYPE.VIDEO; 55 | } else { 56 | return STORY_TYPE.TEXT; 57 | } 58 | } 59 | 60 | factory StoryContent.fromMap(Map map) { 61 | return StoryContent(url: map['url'] as String, 62 | id: map['id'] as String, 63 | createdAt: DateTime.fromMillisecondsSinceEpoch(map['createdAt'] as int), 64 | story_type: decideStoryType(map['story_type']), 65 | seenBy: List.from((map['seenBy'] as List)), 66 | ); 67 | } 68 | 69 | String toJson() => json.encode(toMap()); 70 | 71 | factory StoryContent.fromJson(String source) => 72 | StoryContent.fromMap(json.decode(source) as Map); 73 | 74 | @override 75 | String toString() { 76 | return 'StoryContent(id: $id, createdAt: $createdAt, story_type: $story_type, seenBy: $seenBy)'; 77 | } 78 | 79 | @override 80 | bool operator ==(covariant StoryContent other) { 81 | if (identical(this, other)) return true; 82 | 83 | return other.id == id && 84 | other.createdAt == createdAt && 85 | other.story_type == story_type && 86 | listEquals(other.seenBy, seenBy); 87 | } 88 | 89 | @override 90 | int get hashCode { 91 | return id.hashCode ^ 92 | createdAt.hashCode ^ 93 | story_type.hashCode ^ 94 | seenBy.hashCode; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /lib/models/story_model.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'dart:convert'; 3 | 4 | import 'package:flutter/foundation.dart'; 5 | 6 | import 'package:wave/models/story_content_model.dart'; 7 | 8 | class Story { 9 | String userId; 10 | String id; 11 | List contents; 12 | Story({ 13 | required this.userId, 14 | required this.id, 15 | required this.contents, 16 | }); 17 | 18 | Story copyWith({ 19 | String? userId, 20 | String? id, 21 | List? contents, 22 | }) { 23 | return Story( 24 | userId: userId ?? this.userId, 25 | id: id ?? this.id, 26 | contents: contents ?? this.contents, 27 | ); 28 | } 29 | 30 | Map toMap() { 31 | return { 32 | 'userId': userId, 33 | 'id': id, 34 | 'contents': contents.map((x) => x.toMap()).toList(), 35 | }; 36 | } 37 | 38 | factory Story.fromMap(Map map) { 39 | return Story( 40 | userId: map['userId'] as String, 41 | id: map['id'] as String, 42 | contents: List.from( 43 | (map['contents'] as List).map( 44 | (x) => StoryContent.fromMap(x as Map), 45 | ), 46 | ), 47 | ); 48 | } 49 | 50 | String toJson() => json.encode(toMap()); 51 | 52 | factory Story.fromJson(String source) => 53 | Story.fromMap(json.decode(source) as Map); 54 | 55 | @override 56 | String toString() => 'Story(userId: $userId, id: $id, contents: $contents)'; 57 | 58 | @override 59 | bool operator ==(covariant Story other) { 60 | if (identical(this, other)) return true; 61 | 62 | return other.userId == userId && 63 | other.id == id && 64 | listEquals(other.contents, contents); 65 | } 66 | 67 | @override 68 | int get hashCode => userId.hashCode ^ id.hashCode ^ contents.hashCode; 69 | } 70 | -------------------------------------------------------------------------------- /lib/services/auth_services.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_auth/firebase_auth.dart'; 2 | import 'package:google_sign_in/google_sign_in.dart'; 3 | import 'package:wave/models/response_model.dart'; 4 | 5 | class AuthService { 6 | final FirebaseAuth _auth; 7 | 8 | AuthService(this._auth); 9 | 10 | Future signOut() async { 11 | await _auth.signOut(); 12 | } 13 | 14 | final FirebaseAuth auth = FirebaseAuth.instance; 15 | 16 | Future signIn( 17 | {required String email, required String password}) async { 18 | try { 19 | UserCredential? userCredential = await _auth.signInWithEmailAndPassword( 20 | email: email, password: password); 21 | return userCredential; 22 | } on FirebaseAuthException catch (e) { 23 | return e; 24 | } 25 | } 26 | 27 | Future signUp({ 28 | required String email, 29 | required String password, 30 | }) async { 31 | try { 32 | UserCredential? userCredential = await _auth 33 | .createUserWithEmailAndPassword(email: email, password: password); 34 | await userCredential.user!.sendEmailVerification(); 35 | return userCredential; 36 | } on FirebaseAuthException catch (e) { 37 | return e; 38 | } 39 | } 40 | 41 | Future signInWithGoogle() async { 42 | try { 43 | final gUser = await GoogleSignIn().signIn(); 44 | if (gUser != null) { 45 | final gauth = await gUser.authentication; 46 | final gCred = GoogleAuthProvider.credential( 47 | accessToken: gauth.accessToken, idToken: gauth.idToken); 48 | 49 | final UserCredential userCredential = 50 | await auth.signInWithCredential(gCred); 51 | return CustomResponse(responseStatus: true, response: userCredential); 52 | } else { 53 | return CustomResponse(responseStatus: false); 54 | } 55 | } catch (e) { 56 | return CustomResponse(responseStatus: false); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lib/services/custom_notification_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:wave/data/post_data.dart'; 2 | import 'package:wave/data/users_data.dart'; 3 | import 'package:wave/models/post_model.dart'; 4 | import 'package:wave/models/user_model.dart'; 5 | import 'package:wave/services/notification_service.dart'; 6 | 7 | class CustomNotificationService { 8 | static Future sendNotificationForComment( 9 | {required String postId, 10 | required String comment, 11 | required String myUserId}) async { 12 | Post post = await PostData.getPost(postId); 13 | User otherUser = await UserData.getUser(userID: post.userId); 14 | User me = await UserData.getUser(userID: myUserId); 15 | await NotificationService.sendPushNotification( 16 | fcmToken: otherUser.fcmToken, 17 | message: "${me.name} commented on your post : $comment", 18 | title: "You received a new comment", 19 | ); 20 | } 21 | 22 | static Future sendNotificationForMessage({ 23 | required String message, 24 | required User otherUser, 25 | required User me, 26 | required String chatId, 27 | }) async { 28 | await NotificationService.sendPushNotification( 29 | fcmToken: otherUser.fcmToken, 30 | message: "${me.name}: $message", 31 | title: "You received a new message", 32 | data: { 33 | 'chatId': chatId, 34 | 'otherUserId': otherUser.id, 35 | 'selfUserId' : me.id 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/services/notification_service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | import 'dart:io'; 3 | import 'package:http/http.dart'; 4 | import 'dart:convert'; 5 | 6 | import 'package:wave/services/notification_token.dart'; 7 | 8 | class NotificationService { 9 | // for sending push notification (Updated Codes) 10 | static Future sendPushNotification({ 11 | required String fcmToken, 12 | required String title, 13 | required String message, 14 | Map? data, // Added data parameter 15 | }) async { 16 | try { 17 | final body = { 18 | "message": { 19 | "token": fcmToken, 20 | "apns": { 21 | "payload": { 22 | "aps": {"content-available": 1} 23 | } 24 | }, 25 | "notification": { 26 | "title": title, 27 | "body": message, 28 | }, 29 | "data": data // Adding data to the payload 30 | } 31 | }; 32 | 33 | const projectID = 'wave-dev-42598'; 34 | final bearerToken = await NotificationAccessToken.getToken; 35 | 36 | log('bearerToken: $bearerToken'); 37 | 38 | if (bearerToken == null) return; 39 | 40 | var res = await post( 41 | Uri.parse( 42 | 'https://fcm.googleapis.com/v1/projects/$projectID/messages:send'), 43 | headers: { 44 | HttpHeaders.contentTypeHeader: 'application/json', 45 | HttpHeaders.authorizationHeader: 'Bearer $bearerToken' 46 | }, 47 | body: jsonEncode(body), 48 | ); 49 | 50 | log('Response status: ${res.statusCode}'); 51 | log('Response body: ${res.body}'); 52 | } catch (e) { 53 | log('\nsendPushNotificationE: $e'); 54 | } 55 | } 56 | 57 | } -------------------------------------------------------------------------------- /lib/services/notification_token.dart: -------------------------------------------------------------------------------- 1 | import 'package:googleapis_auth/auth_io.dart'; 2 | 3 | class NotificationAccessToken { 4 | static String? _token; 5 | 6 | //to generate token only once for an app run 7 | static Future get getToken async => 8 | _token ?? await _getAccessToken(); 9 | 10 | // to get admin bearer token 11 | static Future _getAccessToken() async { 12 | try { 13 | const fMessagingScope = 14 | 'https://www.googleapis.com/auth/firebase.messaging'; 15 | 16 | final client = await clientViaServiceAccount( 17 | // To get Admin Json File: Go to Firebase > Project Settings > Service Accounts 18 | // > Click on 'Generate new private key' Btn & Json file will be downloaded 19 | 20 | // Paste Your Generated Json File Content 21 | ServiceAccountCredentials.fromJson({ 22 | "type": "service_account", 23 | "project_id": "wave-dev-42598", 24 | "private_key_id": "04a9c0140acc5b2b5dfe6919fd8fbad64f10d273", 25 | "private_key": 26 | "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCs6+2ppUi7iikj\niyW/L6CHujHuATOLl3jPuXQ7JmvKGanh7e+BG3u8hxxnLWt3N19B772A+A0zGDRp\nPsGzmlUDvn0rfS2j2R+TgdWQX/noP2rGXg9DvmkGLVSV5Dliq0qP6LxnhPL3tgqS\ns/KJHXddbGz8AR7ijPvbXBT6c5plLDDJS8NsA2zmvMUGcQSKcyD6xdfVKvFuyUhw\nETzx6va62ZCV9tQ/aQgbxiJCSmOuOgmShq0fvG20rK0fvpe52KmP7glgj7DQhLDT\n6+3+BbUkYvJ/Oj27FwONdRDPW4QgLbvg7c4M7rrR2CguBLODK1EFkEG/HMKKkseb\ntm3twUYLAgMBAAECggEAQ6SM1RprX7VVj2pcqzOxy7ZJ1s0QgVAQ+c0Vixfl/WpZ\nmqANWwdJuX9u3GuXiMyXzj6+didSXoTe57adZij+jZbj9vGiO2Bxai3VQYNRyoiY\nN53OwdTH15s+5d2flxnjcnT70lDfDIhhDW8n9nwY1+pUnaXAk6XL1czpBenX4TAo\nmQTAlRBbOb6vrOTNQ7+iq1DYen4r5nyEwbnR8dsXuRtqFK065BQns1ZLlkhiYGLq\nnJBUbTM/koNHOMGTHBF44p1GgNEe8oDf2HbiM2W6OKuipSnQrpVm12UvEJCZNODi\n3rPA7RKzbqK/123VrszqfdWJyNmSEE4md6kKNDZD/QKBgQDwYgbNuhnSgmvm4dVi\nGLPmzxkYc4ExtjcDMgP8mO441xux/VhlwsSb94FO1Ubn9ba+4wH4+l8jQV7PBC3G\nlS1eBnoX0m5QmfImdA+CjcwwcYL6/mP0P1/bSU10/q1/fMZsn14iCxgCOruYHkUv\nVoKBQX2+vBnkT/gmxP9UgSXXTwKBgQC4J+f9xTIU9MLFaZb+nMbRNfMy/kc9jMyx\n2ucBEjFdrgbiL2VShMe7+llB7CmglymYOvH2h+/ncF/1n7HAWIOumEZxOOVJ8txa\nD1k4V+pBU2hMnSrEpMf0P1dhhVIRBp8Ehtnnn7jtsPKq7nGfCjAFWNW8uwfAge4g\nYj8IKAZ2hQKBgQCls2ztM3PJYI3wwYvN6ylX2Tp7WGOeWPTjBv8oiGLuW5mDwBfH\nTdMpkBtatDoEe6RVQTaC4lPigZVRLpg/Y2W6gsx2z1+rv/Lj/u0SGZy/Z//Z9LIC\nFA2Ho6f5FfWTA/fjuJey7+LE5qeZ3IPkdcXQQ8ziRdezQkzUrMc1ATGMkQKBgCZ3\nJ20JWImqCljj0kdChgDDDRZ0qHrBwyvPNnsxyp/vrr5l+fr/gxzPkP9FDfjeOjDy\n9wFwqXqlLVYH0kAD/RVl9yjFIpeMo9wn4pHzQxn8CwgduAY1CRMKe/0BtP+ba3Gt\nnSxVX3I+iKGNhqwam6cyRArU4iyitxOKkfHpMlhlAoGBAICCiE9BD1VIhEwyrl4f\nv9W0DIYeBpCk84qin/NW7fC2Bqkc+knzHAytYu3QVgG1ekYjV9YOLeCL+Q5PdfeN\nHXfKZL8Yu9uN1MI1u9kETzThlII6buQneZtnxnsr5vSo+s7H6pp10yiqA11l1SkT\nBUYQmhrQuRHDivGy0E+QO0WJ\n-----END PRIVATE KEY-----\n", 27 | "client_email": 28 | "firebase-adminsdk-a77ia@wave-dev-42598.iam.gserviceaccount.com", 29 | "client_id": "117189559479665717716", 30 | "auth_uri": "https://accounts.google.com/o/oauth2/auth", 31 | "token_uri": "https://oauth2.googleapis.com/token", 32 | "auth_provider_x509_cert_url": 33 | "https://www.googleapis.com/oauth2/v1/certs", 34 | "client_x509_cert_url": 35 | "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-a77ia%40wave-dev-42598.iam.gserviceaccount.com", 36 | "universe_domain": "googleapis.com" 37 | }), 38 | [fMessagingScope], 39 | ); 40 | 41 | _token = client.credentials.accessToken.data; 42 | 43 | return _token; 44 | } catch (e) { 45 | return null; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/services/storage_service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:firebase_storage/firebase_storage.dart'; 3 | 4 | Future getImageUrl(File image, String location) async { 5 | try { 6 | final Reference storageReference = 7 | FirebaseStorage.instance.ref().child(location); 8 | final UploadTask uploadTask = storageReference.putFile(image); 9 | final TaskSnapshot taskSnapshot = await uploadTask; 10 | final url = await taskSnapshot.ref.getDownloadURL(); 11 | return url; 12 | } on FirebaseException catch (e) { 13 | return null; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/utils/constants/custom_colors.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class CustomColor { 4 | static Color primaryColor = Color(0xfbA40606).withOpacity(0.7); 5 | static Color primaryGradient1 = Color(0xfbFF4433); 6 | static Color primaryGradient2 = Color(0xfbE30B5C); 7 | static Color authTextBoxColor = Color(0xfbFAFAFBFF); 8 | static Color authTextBoxBorderColor = Colors.blueGrey; 9 | static Color primaryButtonColor = Color(0xfbFFBF00); 10 | static Color errorColor = Colors.red.shade500; 11 | static Color primaryBackGround = Color(0xfbF8F9FA); 12 | } 13 | -------------------------------------------------------------------------------- /lib/utils/constants/custom_fonts.dart: -------------------------------------------------------------------------------- 1 | class CustomFont { 2 | static String poppins = "Poppins"; 3 | static String alex = "Alex"; 4 | static String inter = "Inter"; 5 | } 6 | -------------------------------------------------------------------------------- /lib/utils/constants/custom_icons.dart: -------------------------------------------------------------------------------- 1 | class CustomIcon { 2 | static String exploreIcon = "assets/icons/explore_ico.png"; 3 | static String exploreFullIcon = "assets/icons/explore_full_ico.png"; 4 | static String searchIcon = "assets/icons/search_ico.png"; 5 | static String searchFullIcon = "assets/icons/search_full_ico.png"; 6 | static String chatIcon = "assets/icons/chat_ico.png"; 7 | static String chatFullIcon = "assets/icons/chat_full_ico.png"; 8 | static String profileIcon = "assets/icons/profile_ico.png"; 9 | static String profileFullIcon = "assets/icons/profile_full_ico.png"; 10 | static String addPostIcon = "assets/icons/add_ico.png"; 11 | static String doubleCheckIcon = "assets/icons/double_check_ico.png"; 12 | static String sendMessageIcon = "assets/icons/send_message_ico.png"; 13 | static String moreIcon = "assets/icons/more_ico.png"; 14 | static String photosIcon = "assets/icons/images_ico.png"; 15 | static String savedIcon = "assets/icons/saved_ico.png"; 16 | static String videoIcon = "assets/icons/video_ico.png"; 17 | static String changeImageIcon = "assets/icons/change_image_ico.png"; 18 | static String verifiedIcon = "assets/icons/verified_ico.png"; 19 | static String addImageIcon = "assets/icons/add_image_ico.png"; 20 | static String followIcon = "assets/icons/follow_ico.png"; 21 | static String addStoryIcon = "assets/icons/add_story_ico.png"; 22 | static String likeIcon = "assets/icons/like_ico.png"; 23 | static String likeFullIcon = "assets/icons/like_full_ico.png"; 24 | static String noUserFoundIcon = "assets/icons/no_user_found_ico.png"; 25 | static String commentIcon = "assets/icons/comment_ico.png"; 26 | static String shareIcon = "assets/icons/share_ico.png"; 27 | static String textPostIcon = "assets/icons/text_post_ico.png"; 28 | static String emptyIcon = "assets/icons/empty_ico.png"; 29 | static String viewedByIcon = "assets/icons/viewed_by_ico.png"; 30 | 31 | static String notificationIcon = "assets/icons/notification_ico.png"; 32 | } 33 | -------------------------------------------------------------------------------- /lib/utils/constants/cutom_logo.dart: -------------------------------------------------------------------------------- 1 | class CustomLogo{ 2 | static String primaryLogo = "assets/logo/primaryLogo.png"; 3 | static String logo = "assets/logo/logo.png"; 4 | } -------------------------------------------------------------------------------- /lib/utils/constants/database_endpoints.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | 3 | class Database { 4 | static var postDatabase = FirebaseFirestore.instance.collection("posts"); 5 | 6 | static var userDatabase = FirebaseFirestore.instance.collection("users"); 7 | 8 | static var chatDatabase = FirebaseFirestore.instance.collection("chats"); 9 | 10 | static CollectionReference getPostLikesDatabase(String postId) { 11 | return postDatabase.doc(postId).collection('likes'); 12 | } 13 | 14 | static CollectionReference getPostCommentsDatabase(String postId) { 15 | return postDatabase.doc(postId).collection('comments'); 16 | } 17 | 18 | static CollectionReference getPostCommentsLikesDatabase( 19 | String postId, String commentId) { 20 | return getPostCommentsDatabase(postId).doc(commentId).collection("likes"); 21 | } 22 | 23 | static CollectionReference getNotificationDatabase(String userId) { 24 | return userDatabase.doc(userId).collection('notifications'); 25 | } 26 | 27 | static CollectionReference getUserChats(String userId) { 28 | return userDatabase.doc(userId).collection('chats'); 29 | } 30 | 31 | static CollectionReference getStories(String userId) { 32 | return userDatabase.doc(userId).collection('stories'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/utils/constants/keys.dart: -------------------------------------------------------------------------------- 1 | class Keys { 2 | static const String keyForExploreIcon = 'keyForExploreIcon'; 3 | static const String keyForSearchIcon = 'keyForSearchIcon'; 4 | static const String keyForAddPostIcon = 'keyForAddPostIcon'; 5 | static const String keyForChatIcon = 'keyForChatIcon'; 6 | static const String keyForProfileIcon = 'keyForProfileIcon'; 7 | static const String keyForPasswordTextFieldLogin = 'keyForPasswordTextFieldLogin'; 8 | static const String keyForEmailTextFieldLogin = 'keyForEmailTextFieldLogin'; 9 | static const String keyForLoginButton = 'keyForLoginButton'; 10 | static const String keyForNameBoxRegister = 'keyForNameBoxRegister'; 11 | static const String keyForEmailTextFieldRegister = 'keyForEmailTextFieldRegister'; 12 | static const String keyForPasswordTextFieldRegister = 'keyForPasswordTextFieldRegister'; 13 | static const String keyForRegisterButton = 'keyForRegisterButton'; 14 | static const String keyForBottomNavButton = 'keyForBottomNavButton'; 15 | } 16 | -------------------------------------------------------------------------------- /lib/utils/constants/preferences.dart: -------------------------------------------------------------------------------- 1 | class Pref { 2 | static String login_pref = "login_pref"; 3 | static String user_id = "user_id"; 4 | static String notification_access = "notification_access"; 5 | static String alreadyAskedForNotification = 'alreadyAskedForNotification'; 6 | } 7 | -------------------------------------------------------------------------------- /lib/utils/device_size.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | double displayHeight(BuildContext context) { 4 | return MediaQuery.of(context).size.height; 5 | } 6 | 7 | double displayWidth(BuildContext context) { 8 | return MediaQuery.of(context).size.width; 9 | } -------------------------------------------------------------------------------- /lib/utils/enums.dart: -------------------------------------------------------------------------------- 1 | enum USER {ABSENT,PRESENT,LOADING} 2 | enum LOGIN {LOGGING_IN , IDLE} 3 | enum REGISTER {CREATING , IDLE} 4 | enum ACCOUNT_TYPE {PRIVATE,PUBLIC} 5 | enum CREATE_POST {CREATING,IDLE} 6 | enum FOLLOWING_USER {FOLLOWING,IDLE} 7 | enum POSTS_STATE {PRESENT,ABSENT,LOADING} 8 | enum POST_TYPE {VIDEO,IMAGE,TEXT} 9 | enum FETCH_SELF_POST {FETCHING,FETCHED,NOT_FETCHED} 10 | enum MESSAGE_TYPE {TEXT,IMAGE} 11 | enum STORY_TYPE{TEXT,POST,VIDEO,IMAGE} 12 | enum FETCH_FEED_STORY{FETCHING,FETCHED,NOT_FETCHED} 13 | enum FETCH_SAVED_POSTS{FETCHING,FETCHED,NOT_FETCHED} -------------------------------------------------------------------------------- /lib/utils/util_functions.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:get/get.dart'; 4 | import 'package:wave/utils/constants/database_endpoints.dart'; 5 | 6 | String capitalizeWords(String input) { 7 | // Split the string into words 8 | List words = input.split(' '); 9 | 10 | // Capitalize the first letter of each word 11 | List capitalizedWords = words.map((word) { 12 | if (word.isEmpty) return word; 13 | // Ensure the first letter is capitalized and the rest are lower case 14 | return word[0].toUpperCase() + word.substring(1).toLowerCase(); 15 | }).toList(); 16 | 17 | // Join all the words back into a single string 18 | return capitalizedWords.join(' '); 19 | } 20 | 21 | String timeAgo(DateTime dateTime) { 22 | final now = DateTime.now(); 23 | final difference = now.difference(dateTime); 24 | 25 | if (difference.inSeconds < 60) { 26 | return 'just now'; 27 | } else if (difference.inMinutes < 60) { 28 | return '${difference.inMinutes}m ago'; 29 | } else if (difference.inHours < 24) { 30 | return '${difference.inHours}h ago'; 31 | } else { 32 | return '${difference.inDays}d ago'; 33 | } 34 | } 35 | 36 | String getInitials(String fullName) { 37 | if (fullName.length >= 3) { 38 | "returning substring from full name : ${fullName.replaceAll(' ', '').substring(0, 3).toLowerCase()}" 39 | .printInfo(); 40 | return fullName.replaceAll(' ', '').substring(0, 3).toLowerCase(); 41 | } else { 42 | return "wave"; 43 | } 44 | } 45 | 46 | String generateUsername(String initials) { 47 | final random = Random(); 48 | final randomDigits = 49 | random.nextInt(90000) + 1000; // Generate a random 5-digit number 50 | return '$initials$randomDigits'; 51 | } 52 | 53 | Future checkUsernameUniqueness(String username) async { 54 | final querySnapshot = 55 | await Database.userDatabase.where('username', isEqualTo: username).get(); 56 | return querySnapshot.docs.isEmpty; 57 | } 58 | 59 | Future getUniqueUsername(String initials) async { 60 | initials = getInitials(initials); 61 | String username = 'wave'; 62 | bool isUnique = false; 63 | while (!isUnique) { 64 | username = generateUsername(initials); 65 | isUnique = await checkUsernameUniqueness(username); 66 | } 67 | return username; 68 | } 69 | 70 | String getMonthName(int month) { 71 | Map months = { 72 | 1: "Jan", 73 | 2: "Feb", 74 | 3: "Mar", 75 | 4: "Apr", 76 | 5: "May", 77 | 6: "June", 78 | 7: "July", 79 | 8: "Aug", 80 | 9: "Sep", 81 | 10: "Oct", 82 | 11: "Nov", 83 | 12: "Dec", 84 | }; 85 | return months[month]!; 86 | } 87 | -------------------------------------------------------------------------------- /lib/view/reusable_components/auth_textfield.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:wave/utils/constants/custom_colors.dart'; 3 | import 'package:wave/utils/constants/custom_fonts.dart'; 4 | 5 | class AuthTextField extends StatelessWidget { 6 | final String label; 7 | final TextEditingController controller; 8 | final bool visible; 9 | final Icon prefixIcon; 10 | final suffixIcon; 11 | int? maxLength; 12 | String? uniqueKey; 13 | bool? readOnly; 14 | 15 | String? Function(String?)? validator; 16 | 17 | AuthTextField( 18 | {required this.controller, 19 | required this.label, 20 | required this.visible, 21 | this.readOnly, 22 | required this.prefixIcon, 23 | this.suffixIcon, 24 | this.maxLength, 25 | this.uniqueKey, 26 | required this.validator}); 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | return TextFormField( 31 | key: Key(uniqueKey!), 32 | readOnly: readOnly ?? false, 33 | controller: controller, 34 | validator: validator, 35 | maxLength: maxLength, 36 | obscureText: !visible, 37 | cursorColor: Colors.black87, 38 | style: TextStyle(color: Colors.black, fontFamily: CustomFont.poppins), 39 | decoration: InputDecoration( 40 | counterStyle: const TextStyle(color: Colors.black), 41 | filled: true, 42 | fillColor: CustomColor.authTextBoxColor, 43 | prefixIcon: prefixIcon, 44 | suffixIcon: suffixIcon, 45 | labelText: label, 46 | labelStyle: 47 | TextStyle(color: Colors.black, fontFamily: CustomFont.poppins), 48 | focusedBorder: OutlineInputBorder( 49 | borderSide: BorderSide(color: CustomColor.authTextBoxBorderColor), 50 | borderRadius: BorderRadius.circular(15), 51 | ), 52 | enabledBorder: OutlineInputBorder( 53 | borderSide: BorderSide(color: CustomColor.authTextBoxBorderColor), 54 | borderRadius: BorderRadius.circular(15), 55 | ), 56 | border: OutlineInputBorder( 57 | borderSide: BorderSide(color: CustomColor.authTextBoxBorderColor), 58 | borderRadius: BorderRadius.circular(15), 59 | ), 60 | errorBorder: OutlineInputBorder( 61 | borderSide: const BorderSide(color: Colors.red), 62 | borderRadius: BorderRadius.circular(15), 63 | ), 64 | ), 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lib/view/reusable_components/chat_head_container.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:get/get.dart'; 4 | import 'package:wave/data/chat_data.dart'; 5 | import 'package:wave/models/chat_model.dart'; 6 | import 'package:wave/models/user_model.dart'; 7 | import 'package:wave/utils/constants/custom_fonts.dart'; 8 | import 'package:wave/utils/constants/custom_icons.dart'; 9 | import 'package:wave/utils/routing.dart'; 10 | import 'package:wave/utils/util_functions.dart'; 11 | 12 | class ChatHeadContainer extends StatelessWidget { 13 | const ChatHeadContainer( 14 | {super.key, 15 | required this.chat, 16 | required this.otherUser, 17 | required this.seenLastMessage, 18 | required this.selfUser}); 19 | final Chat chat; 20 | final User otherUser; 21 | final User selfUser; 22 | final bool seenLastMessage; 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | return ListTile( 27 | visualDensity: const VisualDensity(vertical: -0.5), 28 | onTap: () async { 29 | Get.toNamed(AppRoutes.inboxScreen, arguments: { 30 | 'chatId': chat.id, 31 | 'otherUser': otherUser, 32 | 'selfUser': selfUser 33 | }); 34 | }, 35 | subtitle: Text( 36 | ChatData.getDecryptedMessage(chat.lastMessage), 37 | maxLines: 2, 38 | overflow: TextOverflow.ellipsis, 39 | style: TextStyle( 40 | fontFamily: CustomFont.poppins, 41 | fontSize: 12, 42 | // color: seenLastMessage ? Colors.black : Colors.black87, 43 | fontWeight: seenLastMessage ? FontWeight.normal : FontWeight.bold), 44 | ), 45 | trailing: seenLastMessage 46 | ? Text( 47 | timeAgo(chat.timeOfLastMessage), 48 | style: const TextStyle( 49 | color: Colors.green, 50 | ), 51 | ) 52 | : Column( 53 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 54 | children: [ 55 | Text( 56 | timeAgo(chat.timeOfLastMessage), 57 | style: const TextStyle( 58 | color: Colors.green, fontWeight: FontWeight.bold), 59 | ), 60 | const CircleAvatar( 61 | backgroundColor: Colors.green, 62 | radius: 10, 63 | child: Text( 64 | '1', 65 | style: TextStyle(color: Colors.white, fontSize: 10), 66 | ), 67 | ) 68 | ], 69 | ), 70 | leading: CircleAvatar( 71 | backgroundImage: (otherUser.displayPicture != null && 72 | otherUser.displayPicture!.isNotEmpty) 73 | ? CachedNetworkImageProvider(otherUser.displayPicture!) 74 | : null, 75 | radius: 25, 76 | child: otherUser.displayPicture == null || 77 | otherUser.displayPicture!.isEmpty 78 | ? const Icon(Icons.person) 79 | : null, 80 | ), 81 | title: Row( 82 | mainAxisAlignment: MainAxisAlignment.start, 83 | crossAxisAlignment: CrossAxisAlignment.center, 84 | children: [ 85 | Text( 86 | otherUser.name, 87 | style: TextStyle( 88 | fontFamily: CustomFont.poppins, 89 | fontSize: 14.5, 90 | fontWeight: FontWeight.w600, 91 | letterSpacing: 0.1), 92 | ), 93 | const SizedBox( 94 | width: 2, 95 | ), 96 | Visibility( 97 | visible: otherUser.verified, 98 | child: Padding( 99 | padding: const EdgeInsets.only(top: 2.0), 100 | child: Image.asset( 101 | CustomIcon.verifiedIcon, 102 | height: 12.2, 103 | ), 104 | )) 105 | ], 106 | ), 107 | ); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /lib/view/reusable_components/custom_textbox_for_comment.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:wave/utils/constants/custom_colors.dart'; 4 | import '../../utils/constants/custom_fonts.dart'; 5 | 6 | // ignore: must_be_immutable 7 | class CustomTextBoxForComments extends StatelessWidget { 8 | Widget? child; 9 | dynamic formKey; 10 | dynamic sendButtonMethod; 11 | dynamic commentController; 12 | String? imageUrl; 13 | String? fontFamily; 14 | String? labelText; 15 | String? errorText; 16 | Widget? sendWidget; 17 | Color? backgroundColor; 18 | Color? textColor; 19 | bool withBorder; 20 | Widget? header; 21 | FocusNode? focusNode; 22 | CustomTextBoxForComments( 23 | {this.child, 24 | this.header, 25 | this.sendButtonMethod, 26 | this.formKey, 27 | this.commentController, 28 | this.sendWidget, 29 | this.imageUrl, 30 | this.labelText, 31 | this.fontFamily, 32 | this.focusNode, 33 | this.errorText, 34 | this.withBorder = true, 35 | this.backgroundColor, 36 | this.textColor}); 37 | 38 | @override 39 | Widget build(BuildContext context) { 40 | return Column( 41 | children: [ 42 | Expanded(child: child!), 43 | const Divider( 44 | height: 1, 45 | ), 46 | header ?? const SizedBox.shrink(), 47 | ListTile( 48 | visualDensity: VisualDensity(horizontal: -2), 49 | tileColor: backgroundColor, 50 | leading: CircleAvatar( 51 | radius: 20, 52 | backgroundImage: (imageUrl != null && imageUrl!.isNotEmpty) 53 | ? CachedNetworkImageProvider(imageUrl!) 54 | : null, 55 | child: imageUrl == null || imageUrl!.isEmpty 56 | ? const Icon(Icons.person) 57 | : null, 58 | ), 59 | title: Form( 60 | key: formKey, 61 | child: SizedBox( 62 | child: TextFormField( 63 | textCapitalization: TextCapitalization.sentences, 64 | controller: commentController, 65 | maxLines: 5, 66 | minLines: 1, 67 | style: TextStyle( 68 | color: Colors.black, 69 | fontFamily: fontFamily ?? CustomFont.poppins, 70 | fontSize: fontFamily != null ? 14 : 12), 71 | decoration: InputDecoration( 72 | labelText: labelText ?? "Comment", 73 | labelStyle: TextStyle( 74 | color: Colors.black, 75 | fontFamily: CustomFont.poppins, 76 | fontSize: 14), 77 | focusedBorder: OutlineInputBorder( 78 | borderSide: 79 | BorderSide(color: CustomColor.authTextBoxBorderColor), 80 | borderRadius: BorderRadius.circular(16), 81 | ), 82 | enabledBorder: OutlineInputBorder( 83 | borderSide: 84 | BorderSide(color: CustomColor.authTextBoxBorderColor), 85 | borderRadius: BorderRadius.circular(16), 86 | ), 87 | border: OutlineInputBorder( 88 | borderSide: 89 | BorderSide(color: CustomColor.authTextBoxBorderColor), 90 | borderRadius: BorderRadius.circular(16), 91 | ), 92 | errorBorder: OutlineInputBorder( 93 | borderSide: const BorderSide(color: Colors.red), 94 | borderRadius: BorderRadius.circular(16), 95 | ), 96 | ), 97 | ), 98 | ), 99 | ), 100 | trailing: InkWell( 101 | onTap: sendButtonMethod, 102 | child: sendWidget, 103 | ), 104 | ), 105 | ], 106 | ); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /lib/view/reusable_components/mention_user_tile.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:wave/models/user_model.dart'; 3 | import 'package:wave/utils/constants/custom_fonts.dart'; 4 | import 'package:wave/utils/constants/custom_icons.dart'; 5 | 6 | class MentionUserTile extends StatelessWidget { 7 | User user; 8 | bool isMentioned; 9 | final VoidCallback onPressed; 10 | MentionUserTile( 11 | {super.key, 12 | required this.user, 13 | required this.isMentioned, 14 | required this.onPressed}); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return ListTile( 19 | onTap: () { 20 | onPressed(); 21 | }, 22 | subtitle: Text( 23 | user.username, 24 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 13), 25 | ), 26 | leading: CircleAvatar( 27 | backgroundImage: 28 | (user.displayPicture != null && user.displayPicture!.isNotEmpty) 29 | ? NetworkImage(user.displayPicture!) 30 | : null, 31 | radius: 25, 32 | child: user.displayPicture == null || user.displayPicture!.isEmpty 33 | ? const Icon(Icons.person) 34 | : null, 35 | ), 36 | title: Row( 37 | mainAxisAlignment: MainAxisAlignment.start, 38 | crossAxisAlignment: CrossAxisAlignment.center, 39 | children: [ 40 | Text( 41 | user.name, 42 | style: 43 | TextStyle(fontFamily: CustomFont.poppins, letterSpacing: 0.1), 44 | ), 45 | const SizedBox( 46 | width: 2, 47 | ), 48 | Visibility( 49 | visible: user.verified, 50 | child: Image.asset( 51 | CustomIcon.verifiedIcon, 52 | height: 15, 53 | )) 54 | ], 55 | ), 56 | trailing: Visibility( 57 | visible: isMentioned, 58 | child: Image.asset( 59 | CustomIcon.doubleCheckIcon, 60 | height: 20, 61 | )), 62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /lib/view/reusable_components/more_option_feed.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:wave/models/post_model.dart'; 3 | import 'package:wave/utils/constants/custom_fonts.dart'; 4 | 5 | 6 | class MoreOptionsForFeedPost extends StatelessWidget { 7 | final Post post; 8 | const MoreOptionsForFeedPost({super.key, required this.post}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | child: Wrap( 14 | children: [ 15 | ListTile( 16 | leading: Icon(Icons.settings_outlined), 17 | title: Text('Settings', 18 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14)), 19 | onTap: () { 20 | //Settings 21 | }, 22 | ), 23 | ListTile( 24 | leading: Icon(Icons.block_outlined), 25 | title: Text('Blocked Contacts', 26 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14)), 27 | onTap: () { 28 | //Help 29 | }, 30 | ), 31 | ListTile( 32 | leading: Icon(Icons.info_outline), 33 | title: Text('About', 34 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14)), 35 | onTap: () { 36 | //About 37 | }, 38 | ), 39 | ListTile( 40 | leading: Icon(Icons.help_outline_outlined), 41 | title: Text('Help', 42 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14)), 43 | onTap: () { 44 | //Help 45 | }, 46 | ), 47 | ], 48 | )); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/view/reusable_components/textbox_editprofile.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:wave/utils/constants/custom_colors.dart'; 3 | import 'package:wave/utils/constants/custom_fonts.dart'; 4 | import 'package:wave/utils/device_size.dart'; 5 | 6 | class TextBoxForEditProfile extends StatelessWidget { 7 | TextBoxForEditProfile( 8 | {super.key, 9 | required this.label, 10 | required this.controller, 11 | required this.visible, 12 | this.prefixIcon, 13 | this.maxLines, 14 | this.suffixIcon, 15 | this.maxLength, 16 | this.uniqueKey, 17 | this.readOnly, 18 | this.onChanged, 19 | this.validator}); 20 | 21 | final String label; 22 | final TextEditingController controller; 23 | final bool visible; 24 | final Icon? prefixIcon; 25 | final Widget? suffixIcon; 26 | int? maxLength; 27 | int? maxLines; 28 | String? uniqueKey; 29 | bool? readOnly; 30 | Function(String)? onChanged; 31 | String? Function(String?)? validator; 32 | 33 | @override 34 | Widget build(BuildContext context) { 35 | return SizedBox( 36 | height: maxLines == null ? displayHeight(context) * 0.11 : null, 37 | child: TextFormField( 38 | onChanged: onChanged, 39 | maxLines: maxLines, 40 | minLines: 1, 41 | key: uniqueKey != null ? Key(uniqueKey!) : null, 42 | readOnly: readOnly ?? false, 43 | controller: controller, 44 | validator: validator, 45 | maxLength: maxLength, 46 | obscureText: !visible, 47 | cursorColor: Colors.black87, 48 | style: TextStyle( 49 | color: Colors.black, fontFamily: CustomFont.poppins, fontSize: 13), 50 | decoration: InputDecoration( 51 | counterStyle: const TextStyle(color: Colors.black), 52 | filled: true, 53 | fillColor: Colors.white, 54 | prefixIcon: prefixIcon, 55 | suffixIcon: suffixIcon, 56 | labelText: label, 57 | labelStyle: TextStyle( 58 | color: Colors.black, 59 | fontFamily: CustomFont.poppins, 60 | fontSize: 13.5), 61 | focusedBorder: OutlineInputBorder( 62 | borderSide: BorderSide(color: CustomColor.authTextBoxBorderColor), 63 | borderRadius: BorderRadius.circular(15), 64 | ), 65 | enabledBorder: OutlineInputBorder( 66 | borderSide: BorderSide(color: CustomColor.authTextBoxBorderColor), 67 | borderRadius: BorderRadius.circular(15), 68 | ), 69 | border: OutlineInputBorder( 70 | borderSide: BorderSide(color: CustomColor.authTextBoxBorderColor), 71 | borderRadius: BorderRadius.circular(15), 72 | ), 73 | errorBorder: OutlineInputBorder( 74 | borderSide: const BorderSide(color: Colors.red), 75 | borderRadius: BorderRadius.circular(15), 76 | ), 77 | ), 78 | ), 79 | ); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/view/reusable_components/thumbnail_media.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:video_player/video_player.dart'; 4 | import 'package:wave/utils/device_size.dart'; 5 | 6 | class ImageThumbnail extends StatelessWidget { 7 | final File file; 8 | 9 | ImageThumbnail({required this.file}); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return ClipRRect( 14 | borderRadius: BorderRadius.circular(6), 15 | child: Image.file(file, 16 | height: displayHeight(context) * 0.11, 17 | width: displayWidth(context) * 0.23, 18 | fit: BoxFit.cover), 19 | ); 20 | } 21 | } 22 | 23 | class VideoThumbnail extends StatefulWidget { 24 | final File file; 25 | 26 | VideoThumbnail({required this.file}); 27 | 28 | @override 29 | _VideoThumbnailState createState() => _VideoThumbnailState(); 30 | } 31 | 32 | class _VideoThumbnailState extends State { 33 | late VideoPlayerController _controller; 34 | late Future _initializeVideoPlayerFuture; 35 | 36 | @override 37 | void initState() { 38 | super.initState(); 39 | _controller = VideoPlayerController.file(widget.file); 40 | _initializeVideoPlayerFuture = _controller.initialize(); 41 | } 42 | 43 | @override 44 | void dispose() { 45 | _controller.dispose(); 46 | super.dispose(); 47 | } 48 | 49 | @override 50 | Widget build(BuildContext context) { 51 | return FutureBuilder( 52 | future: _initializeVideoPlayerFuture, 53 | builder: (context, snapshot) { 54 | if (snapshot.connectionState == ConnectionState.done) { 55 | return Container( 56 | height: displayHeight(context) * 0.11, 57 | width: displayWidth(context) * 0.23, 58 | //aspectRatio: _controller.value.aspectRatio, 59 | child: ClipRRect( 60 | borderRadius: BorderRadius.circular(6), 61 | child: VideoPlayer(_controller)), 62 | ); 63 | } else { 64 | return CircularProgressIndicator(); 65 | } 66 | }, 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/view/reusable_components/user_container.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:get/get.dart'; 4 | import 'package:wave/models/user_model.dart'; 5 | import 'package:wave/utils/constants/custom_fonts.dart'; 6 | import 'package:wave/utils/constants/custom_icons.dart'; 7 | import 'package:wave/utils/routing.dart'; 8 | 9 | class UserContainerTile extends StatelessWidget { 10 | User user; 11 | final VoidCallback? onTap; 12 | UserContainerTile({super.key, required this.user, this.onTap}); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return ListTile( 17 | visualDensity: const VisualDensity(vertical: -0.5), 18 | onTap: () async { 19 | if (onTap != null) { 20 | onTap!(); 21 | } else { 22 | Get.toNamed(AppRoutes.profileScreen, arguments: user.id); 23 | } 24 | }, 25 | subtitle: Text( 26 | user.username, 27 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 11), 28 | ), 29 | leading: CircleAvatar( 30 | backgroundImage: 31 | (user.displayPicture != null && user.displayPicture!.isNotEmpty) 32 | ? CachedNetworkImageProvider(user.displayPicture!) 33 | : null, 34 | radius: 20, 35 | child: user.displayPicture == null || user.displayPicture!.isEmpty 36 | ? const Icon(Icons.person) 37 | : null, 38 | ), 39 | title: Row( 40 | mainAxisAlignment: MainAxisAlignment.start, 41 | crossAxisAlignment: CrossAxisAlignment.center, 42 | children: [ 43 | Text( 44 | user.name, 45 | style: TextStyle( 46 | fontFamily: CustomFont.poppins, 47 | fontSize: 12.5, 48 | letterSpacing: 0.1), 49 | ), 50 | const SizedBox( 51 | width: 2, 52 | ), 53 | Visibility( 54 | visible: user.verified, 55 | child: Padding( 56 | padding: const EdgeInsets.only(top: 2.0), 57 | child: Image.asset( 58 | CustomIcon.verifiedIcon, 59 | height: 12.2, 60 | ), 61 | )) 62 | ], 63 | ), 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/view/reusable_components/view_image.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:get/get.dart'; 4 | import 'package:photo_view/photo_view.dart'; 5 | 6 | class ViewImage extends StatelessWidget { 7 | ViewImage({super.key}); 8 | 9 | final String url = Get.arguments; 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Scaffold( 14 | appBar: AppBar( 15 | iconTheme: IconThemeData(color: Colors.white), 16 | backgroundColor: Colors.black87, 17 | ), 18 | backgroundColor: Colors.black87, 19 | body: SafeArea( 20 | child: SizedBox( 21 | height: double.infinity, 22 | width: double.infinity, 23 | child: PhotoView( 24 | enableRotation: true, 25 | imageProvider: CachedNetworkImageProvider(url), 26 | ), 27 | )), 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/view/screens/CreatePostScreen/add_image_for_post_box.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:get/get.dart'; 5 | import 'package:image_picker/image_picker.dart'; 6 | import 'package:wave/controllers/PostController/create_post_controller.dart'; 7 | import 'package:wave/utils/constants/custom_icons.dart'; 8 | import 'package:wave/utils/device_size.dart'; 9 | import 'package:wave/utils/image_config.dart'; 10 | import 'package:wave/view/reusable_components/thumbnail_media.dart'; 11 | 12 | class AddImageForPostBox extends StatelessWidget { 13 | CreatePostController postController; 14 | AddImageForPostBox({super.key, required this.postController}); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Container( 19 | height: displayHeight(context) * 0.13, 20 | width: double.infinity, 21 | // color: Colors.red.shade100, 22 | child: Row( 23 | mainAxisAlignment: MainAxisAlignment.start, 24 | crossAxisAlignment: CrossAxisAlignment.center, 25 | children: [ 26 | InkWell( 27 | onTap: () async { 28 | List? selectedMediaFile = 29 | await pickMultipleMediaFiles(context); 30 | if (selectedMediaFile != null) { 31 | "adding image".printInfo(); 32 | postController.addMediaFiles(selectedMediaFile); 33 | } 34 | }, 35 | child: Image.asset( 36 | CustomIcon.addImageIcon, 37 | height: displayHeight(context) * 0.11, 38 | ), 39 | ), 40 | const SizedBox( 41 | width: 5, 42 | ), 43 | Expanded( 44 | child: ListView.builder( 45 | scrollDirection: Axis.horizontal, 46 | itemCount: postController.selectedMediaFiles.length, 47 | itemBuilder: (context, index) { 48 | File file = postController.selectedMediaFiles[index]; 49 | return Padding( 50 | padding: 51 | const EdgeInsets.symmetric(horizontal: 4.0, vertical: 8), 52 | child: Stack( 53 | children: [ 54 | file.path.endsWith('.mp4') 55 | ? VideoThumbnail(file: file) 56 | : ImageThumbnail(file: file), 57 | Positioned( 58 | top: 0, 59 | right: 0, 60 | child: InkWell( 61 | onTap: () { 62 | postController.removeMediaFileAtIndex(index); 63 | }, 64 | child: const CircleAvatar( 65 | backgroundColor: Colors.white70, 66 | radius: 11, 67 | child: Icon( 68 | Icons.close, 69 | size: 15.4, 70 | color: Colors.black, 71 | ), 72 | ), 73 | ), 74 | ) 75 | ], 76 | ), 77 | ); 78 | }, 79 | )), 80 | ], 81 | ), 82 | ); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/view/screens/ProfileScreen/blocked_contacts_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/widgets.dart'; 4 | 5 | class BlockedContacts extends StatelessWidget { 6 | const BlockedContacts({super.key}); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Scaffold( 11 | appBar: AppBar( 12 | title: Text("Blocked Contacts"), 13 | ), 14 | ); 15 | } 16 | } -------------------------------------------------------------------------------- /lib/view/screens/ProfileScreen/list_users.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | import 'package:wave/data/users_data.dart'; 4 | import 'package:wave/models/user_model.dart'; 5 | import 'package:wave/utils/constants/custom_colors.dart'; 6 | import 'package:wave/utils/constants/custom_fonts.dart'; 7 | import 'package:wave/view/reusable_components/user_container.dart'; 8 | 9 | class ListUsers extends StatefulWidget { 10 | @override 11 | State createState() => _ListUsersState(); 12 | } 13 | 14 | class _ListUsersState extends State { 15 | List users = []; 16 | String title = ""; 17 | 18 | @override 19 | void initState() { 20 | super.initState(); 21 | users = Get.arguments[0]; 22 | title = Get.arguments[1]; 23 | } 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return Scaffold( 28 | appBar: AppBar( 29 | title: Text( 30 | title, 31 | style: TextStyle( 32 | fontFamily: CustomFont.poppins, 33 | fontSize: 16.5, 34 | letterSpacing: -0.1, 35 | ), 36 | ), 37 | centerTitle: true, 38 | elevation: 0, 39 | backgroundColor: CustomColor.primaryBackGround, 40 | ), 41 | backgroundColor: CustomColor.primaryBackGround, 42 | body: ListView.builder( 43 | itemCount: users.length, 44 | itemBuilder: (BuildContext context, int index) { 45 | return FutureBuilder( 46 | future: UserData.getUser(userID: users[index].toString()), 47 | initialData: null, 48 | builder: (BuildContext context, AsyncSnapshot user) { 49 | if (user.connectionState == ConnectionState.done && 50 | user.hasData) { 51 | return UserContainerTile(user: user.data!); 52 | } 53 | return SizedBox(); 54 | }, 55 | ); 56 | }, 57 | ), 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lib/view/screens/ProfileScreen/more_options_other_profile.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:wave/utils/constants/custom_fonts.dart'; 3 | 4 | class MoreOptionForOtherProfile extends StatelessWidget { 5 | const MoreOptionForOtherProfile({super.key}); 6 | 7 | @override 8 | Widget build(BuildContext context) { 9 | return Container( 10 | child: Wrap( 11 | children: [ 12 | ListTile( 13 | leading: Icon(Icons.report), 14 | title: Text('Report', 15 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14)), 16 | onTap: () async { 17 | // report functionalities 18 | }, 19 | ), 20 | ListTile( 21 | leading: Icon(Icons.block_flipped), 22 | title: Text('Block', 23 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14)), 24 | onTap: () async { 25 | //block functionalities 26 | }, 27 | ), 28 | ListTile( 29 | leading: Icon(Icons.share), 30 | title: Text('Share To', 31 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14)), 32 | onTap: () { 33 | //Share Profile Functionalities 34 | }, 35 | ), 36 | ListTile( 37 | leading: Icon(Icons.link), 38 | title: Text('Website Url', 39 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14)), 40 | onTap: () { 41 | //Website Url functionalities 42 | }, 43 | ), 44 | ListTile( 45 | leading: Icon(Icons.cancel), 46 | title: Text('Cancel', 47 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14)), 48 | onTap: () { 49 | //Cancel Functionalities 50 | }, 51 | ), 52 | ], 53 | )); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lib/view/screens/ProfileScreen/more_options_self.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:cloud_firestore/cloud_firestore.dart'; 3 | import 'package:firebase_auth/firebase_auth.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:get/get.dart'; 6 | import 'package:provider/provider.dart'; 7 | import 'package:wave/controllers/Authentication/auth_screen_controller.dart'; 8 | import 'package:wave/controllers/Authentication/user_controller.dart'; 9 | import 'package:wave/utils/constants/custom_fonts.dart'; 10 | import 'package:wave/utils/constants/custom_icons.dart'; 11 | import 'package:wave/utils/routing.dart'; 12 | 13 | class MoreOptionsForSelfProfile extends StatelessWidget { 14 | const MoreOptionsForSelfProfile({super.key}); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Container( 19 | child: Wrap( 20 | children: [ 21 | Consumer( 22 | builder: (context, userDataController, child) { 23 | return ListTile( 24 | leading: CircleAvatar( 25 | radius: 14, 26 | backgroundImage: 27 | userDataController.user!.displayPicture != null && 28 | userDataController.user!.displayPicture!.isNotEmpty 29 | ? CachedNetworkImageProvider( 30 | userDataController.user!.displayPicture!) 31 | : null, 32 | child: userDataController.user!.displayPicture == null || 33 | userDataController.user!.displayPicture!.isEmpty 34 | ? Image.asset( 35 | CustomIcon.profileFullIcon, 36 | height: 15, 37 | fit: BoxFit.contain, 38 | ) 39 | : null, 40 | ), 41 | title: Text( 42 | 'Edit Profile', 43 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14), 44 | ), 45 | onTap: () async { 46 | Navigator.pop(context); 47 | Get.toNamed(AppRoutes.editProfileScreen, 48 | arguments: userDataController.user!); 49 | }, 50 | ); 51 | }, 52 | ), 53 | ListTile( 54 | leading: Icon(Icons.settings_outlined), 55 | title: Text('Settings', 56 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14)), 57 | onTap: () { 58 | //Settings 59 | }, 60 | ), 61 | ListTile( 62 | leading: Icon(Icons.block_outlined), 63 | title: Text('Blocked Contacts', 64 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14)), 65 | onTap: () { 66 | Navigator.pop(context); // Close the bottom sheet 67 | Get.toNamed(AppRoutes.blockedContactsScreen); 68 | }, 69 | ), 70 | ListTile( 71 | leading: Icon(Icons.info_outline), 72 | title: Text('About', 73 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14)), 74 | onTap: () { 75 | //About 76 | }, 77 | ), 78 | ListTile( 79 | leading: Icon(Icons.help_outline_outlined), 80 | title: Text('Help', 81 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14)), 82 | onTap: () { 83 | //Help 84 | }, 85 | ), 86 | ListTile( 87 | leading: Icon(Icons.logout), 88 | title: Text('Logout', 89 | style: TextStyle(fontFamily: CustomFont.poppins, fontSize: 14)), 90 | onTap: () async { 91 | // Close the bottom sheet 92 | await Provider.of(context, listen: false) 93 | .signOut(firebaseAuth: FirebaseAuth.instance); 94 | Get.offAllNamed(AppRoutes.loginScreen); 95 | }, 96 | ), 97 | ], 98 | )); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /lib/view/screens/ProfileScreen/profile_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | import 'package:wave/utils/constants/custom_colors.dart'; 4 | import 'other_profile.dart'; 5 | import 'self_profile.dart'; 6 | 7 | class ProfileScreen extends StatelessWidget { 8 | ProfileScreen({super.key}); 9 | String? otherUserId = Get.arguments; 10 | @override 11 | Widget build(BuildContext context) { 12 | return Scaffold( 13 | backgroundColor: CustomColor.primaryBackGround, 14 | // Display my profile if other param is null 15 | body: otherUserId == null 16 | ? SelfProfile() 17 | : OtherProfile( 18 | otherUserId: otherUserId!, 19 | )); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/view/screens/SplashScreen/splash_screen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:get/get.dart'; 4 | import 'package:provider/provider.dart'; 5 | import 'package:shared_preferences/shared_preferences.dart'; 6 | import 'package:wave/controllers/Authentication/user_controller.dart'; 7 | import 'package:wave/utils/constants/custom_fonts.dart'; 8 | import 'package:wave/utils/constants/cutom_logo.dart'; 9 | import 'package:wave/utils/constants/preferences.dart'; 10 | import 'package:wave/utils/routing.dart'; 11 | 12 | class SplashScreen extends StatefulWidget { 13 | const SplashScreen({super.key}); 14 | 15 | @override 16 | State createState() => _SplashScreenState(); 17 | } 18 | 19 | class _SplashScreenState extends State { 20 | @override 21 | void initState() { 22 | super.initState(); 23 | decideNavigation(); 24 | // _navigateToLogin(); 25 | } 26 | 27 | decideNavigation() async { 28 | final SharedPreferences prefs = await SharedPreferences.getInstance(); 29 | if (prefs.containsKey(Pref.login_pref)) { 30 | if (prefs.getBool(Pref.login_pref) ?? false) { 31 | _navigatetohome(prefs.getString(Pref.user_id)!); 32 | } else { 33 | _navigateToLogin(); 34 | } 35 | } else { 36 | _navigateToLogin(); 37 | } 38 | } 39 | 40 | _navigateToLogin() async { 41 | await Future.delayed(const Duration(milliseconds: 3000), () {}); 42 | Get.offNamed(AppRoutes.loginScreen); 43 | } 44 | 45 | _navigatetohome(String userId) async { 46 | var userProvider = Provider.of(context, listen: false); 47 | await userProvider.setUser(userID: userId); 48 | "User set to ${userProvider.user!.name}".printInfo(); 49 | "My fcm token = ${userProvider.user!.fcmToken}".printInfo(); 50 | "My followings = ${userProvider.user!.following}".printInfo(); 51 | Get.offNamed(AppRoutes.homeNavigationScreen); 52 | } 53 | 54 | @override 55 | Widget build(BuildContext context) { 56 | return Scaffold( 57 | backgroundColor: const Color(0xfbE30B5C), 58 | body: Center( 59 | child: Column( 60 | mainAxisAlignment: MainAxisAlignment.center, 61 | crossAxisAlignment: CrossAxisAlignment.center, 62 | children: [ 63 | Image.asset( 64 | CustomLogo.primaryLogo, 65 | width: 200, 66 | height: 200, 67 | ), 68 | const SizedBox(height: 30), 69 | Text( 70 | 'Wave', 71 | style: TextStyle( 72 | color: Colors.white, 73 | fontSize: 40, 74 | fontFamily: CustomFont.alex, 75 | fontWeight: FontWeight.bold, 76 | ), 77 | ), 78 | ], 79 | ), 80 | ), 81 | ); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /lib/view/screens/StoryScreen/viewers_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | import 'package:wave/data/users_data.dart'; 4 | import 'package:wave/models/user_model.dart'; 5 | import 'package:wave/view/reusable_components/user_container.dart'; 6 | 7 | class ViewersDialog extends StatelessWidget { 8 | List viewers; 9 | ViewersDialog({super.key, required this.viewers}); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Container( 14 | height: Get.height * 0.6, 15 | width: Get.width, 16 | decoration: const BoxDecoration( 17 | color: Colors.white, 18 | borderRadius: BorderRadius.all(Radius.circular(10))), 19 | child: Column( 20 | children: [ 21 | Icon( 22 | Icons.remove, 23 | color: Colors.grey[600], 24 | ), 25 | Expanded( 26 | child: ListView.builder( 27 | itemCount: viewers.length, 28 | itemBuilder: (BuildContext context, int index) { 29 | return FutureBuilder( 30 | future: UserData.getUser(userID: viewers[index]), 31 | builder: (BuildContext context, AsyncSnapshot userSnap) { 32 | if (userSnap.connectionState == ConnectionState.done) { 33 | return UserContainerTile(user: userSnap.data!); 34 | } else { 35 | return const SizedBox.shrink(); 36 | } 37 | }, 38 | ); 39 | }, 40 | )) 41 | ], 42 | ), 43 | ); 44 | 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | -------------------------------------------------------------------------------- /linux/flutter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file controls Flutter-level build steps. It should not be edited. 2 | cmake_minimum_required(VERSION 3.10) 3 | 4 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") 5 | 6 | # Configuration provided via flutter tool. 7 | include(${EPHEMERAL_DIR}/generated_config.cmake) 8 | 9 | # TODO: Move the rest of this into files in ephemeral. See 10 | # https://github.com/flutter/flutter/issues/57146. 11 | 12 | # Serves the same purpose as list(TRANSFORM ... PREPEND ...), 13 | # which isn't available in 3.10. 14 | function(list_prepend LIST_NAME PREFIX) 15 | set(NEW_LIST "") 16 | foreach(element ${${LIST_NAME}}) 17 | list(APPEND NEW_LIST "${PREFIX}${element}") 18 | endforeach(element) 19 | set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) 20 | endfunction() 21 | 22 | # === Flutter Library === 23 | # System-level dependencies. 24 | find_package(PkgConfig REQUIRED) 25 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) 26 | pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) 27 | pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) 28 | 29 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") 30 | 31 | # Published to parent scope for install step. 32 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 33 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 34 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 35 | set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) 36 | 37 | list(APPEND FLUTTER_LIBRARY_HEADERS 38 | "fl_basic_message_channel.h" 39 | "fl_binary_codec.h" 40 | "fl_binary_messenger.h" 41 | "fl_dart_project.h" 42 | "fl_engine.h" 43 | "fl_json_message_codec.h" 44 | "fl_json_method_codec.h" 45 | "fl_message_codec.h" 46 | "fl_method_call.h" 47 | "fl_method_channel.h" 48 | "fl_method_codec.h" 49 | "fl_method_response.h" 50 | "fl_plugin_registrar.h" 51 | "fl_plugin_registry.h" 52 | "fl_standard_message_codec.h" 53 | "fl_standard_method_codec.h" 54 | "fl_string_codec.h" 55 | "fl_value.h" 56 | "fl_view.h" 57 | "flutter_linux.h" 58 | ) 59 | list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") 60 | add_library(flutter INTERFACE) 61 | target_include_directories(flutter INTERFACE 62 | "${EPHEMERAL_DIR}" 63 | ) 64 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") 65 | target_link_libraries(flutter INTERFACE 66 | PkgConfig::GTK 67 | PkgConfig::GLIB 68 | PkgConfig::GIO 69 | ) 70 | add_dependencies(flutter flutter_assemble) 71 | 72 | # === Flutter tool backend === 73 | # _phony_ is a non-existent file to force this command to run every time, 74 | # since currently there's no way to get a full input/output list from the 75 | # flutter tool. 76 | add_custom_command( 77 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 78 | ${CMAKE_CURRENT_BINARY_DIR}/_phony_ 79 | COMMAND ${CMAKE_COMMAND} -E env 80 | ${FLUTTER_TOOL_ENVIRONMENT} 81 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" 82 | ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} 83 | VERBATIM 84 | ) 85 | add_custom_target(flutter_assemble DEPENDS 86 | "${FLUTTER_LIBRARY}" 87 | ${FLUTTER_LIBRARY_HEADERS} 88 | ) 89 | -------------------------------------------------------------------------------- /linux/flutter/ephemeral/.plugin_symlinks/path_provider_linux: -------------------------------------------------------------------------------- 1 | /Users/user/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/ -------------------------------------------------------------------------------- /linux/flutter/ephemeral/.plugin_symlinks/shared_preferences_linux: -------------------------------------------------------------------------------- 1 | /Users/user/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.3.2/ -------------------------------------------------------------------------------- /linux/flutter/ephemeral/.plugin_symlinks/url_launcher_linux: -------------------------------------------------------------------------------- 1 | /Users/user/.pub-cache/hosted/pub.dev/url_launcher_linux-3.1.1/ -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | #include 11 | 12 | void fl_register_plugins(FlPluginRegistry* registry) { 13 | g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = 14 | fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); 15 | file_selector_plugin_register_with_registrar(file_selector_linux_registrar); 16 | g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = 17 | fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); 18 | url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); 19 | } 20 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void fl_register_plugins(FlPluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | file_selector_linux 7 | url_launcher_linux 8 | ) 9 | 10 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 11 | ) 12 | 13 | set(PLUGIN_BUNDLED_LIBRARIES) 14 | 15 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 16 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) 17 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 18 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 19 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 20 | endforeach(plugin) 21 | 22 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 23 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) 24 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 25 | endforeach(ffi_plugin) 26 | -------------------------------------------------------------------------------- /linux/main.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | int main(int argc, char** argv) { 4 | g_autoptr(MyApplication) app = my_application_new(); 5 | return g_application_run(G_APPLICATION(app), argc, argv); 6 | } 7 | -------------------------------------------------------------------------------- /linux/my_application.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_MY_APPLICATION_H_ 2 | #define FLUTTER_MY_APPLICATION_H_ 3 | 4 | #include 5 | 6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, 7 | GtkApplication) 8 | 9 | /** 10 | * my_application_new: 11 | * 12 | * Creates a new Flutter-based application. 13 | * 14 | * Returns: a new #MyApplication. 15 | */ 16 | MyApplication* my_application_new(); 17 | 18 | #endif // FLUTTER_MY_APPLICATION_H_ 19 | -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ephemeral/Flutter-Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ephemeral/Flutter-Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import cloud_firestore 9 | import device_info_plus 10 | import file_selector_macos 11 | import firebase_auth 12 | import firebase_core 13 | import firebase_messaging 14 | import firebase_storage 15 | import flutter_image_compress_macos 16 | import flutter_local_notifications 17 | import google_sign_in_ios 18 | import path_provider_foundation 19 | import shared_preferences_foundation 20 | import sqflite 21 | import url_launcher_macos 22 | import video_player_avfoundation 23 | 24 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 25 | FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin")) 26 | DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) 27 | FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) 28 | FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) 29 | FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) 30 | FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) 31 | FLTFirebaseStoragePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseStoragePlugin")) 32 | FlutterImageCompressMacosPlugin.register(with: registry.registrar(forPlugin: "FlutterImageCompressMacosPlugin")) 33 | FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) 34 | FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin")) 35 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) 36 | SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) 37 | SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) 38 | UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) 39 | FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) 40 | } 41 | -------------------------------------------------------------------------------- /macos/Flutter/ephemeral/Flutter-Generated.xcconfig: -------------------------------------------------------------------------------- 1 | // This is a generated file; do not edit or check into version control. 2 | FLUTTER_ROOT=/Users/user/FlutterDev/flutter 3 | FLUTTER_APPLICATION_PATH=/Users/user/Dev/FlutterApps/wave 4 | COCOAPODS_PARALLEL_CODE_SIGN=true 5 | FLUTTER_BUILD_DIR=build 6 | FLUTTER_BUILD_NAME=1.0.0 7 | FLUTTER_BUILD_NUMBER=1 8 | DART_OBFUSCATION=false 9 | TRACK_WIDGET_CREATION=true 10 | TREE_SHAKE_ICONS=false 11 | PACKAGE_CONFIG=.dart_tool/package_config.json 12 | -------------------------------------------------------------------------------- /macos/Flutter/ephemeral/flutter_export_environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is a generated file; do not edit or check into version control. 3 | export "FLUTTER_ROOT=/Users/user/FlutterDev/flutter" 4 | export "FLUTTER_APPLICATION_PATH=/Users/user/Dev/FlutterApps/wave" 5 | export "COCOAPODS_PARALLEL_CODE_SIGN=true" 6 | export "FLUTTER_BUILD_DIR=build" 7 | export "FLUTTER_BUILD_NAME=1.0.0" 8 | export "FLUTTER_BUILD_NUMBER=1" 9 | export "DART_OBFUSCATION=false" 10 | export "TRACK_WIDGET_CREATION=true" 11 | export "TREE_SHAKE_ICONS=false" 12 | export "PACKAGE_CONFIG=.dart_tool/package_config.json" 13 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /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 = wave 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.wave 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2024 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /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 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController() 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/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import FlutterMacOS 2 | import Cocoa 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: wave 2 | description: "A new Flutter project." 3 | # The following line prevents the package from being accidentally published to 4 | # pub.dev using `flutter pub publish`. This is preferred for private packages. 5 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 6 | 7 | # The following defines the version and build number for your application. 8 | # A version number is three numbers separated by dots, like 1.2.43 9 | # followed by an optional build number separated by a +. 10 | # Both the version and the builder number may be overridden in flutter 11 | # build by specifying --build-name and --build-number, respectively. 12 | # In Android, build-name is used as versionName while build-number used as versionCode. 13 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 14 | # In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. 15 | # Read more about iOS versioning at 16 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 17 | # In Windows, build-name is used as the major, minor, and patch parts 18 | # of the product and file versions while build-number is used as the build suffix. 19 | version: 1.0.0+1 20 | 21 | environment: 22 | sdk: '>=3.3.1 <4.0.0' 23 | 24 | # Dependencies specify other packages that your package needs in order to work. 25 | # To automatically upgrade your package dependencies to the latest versions 26 | # consider running `flutter pub upgrade --major-versions`. Alternatively, 27 | # dependencies can be manually updated by changing the version numbers below to 28 | # the latest version available on pub.dev. To see which dependencies have newer 29 | # versions available, run `flutter pub outdated`. 30 | dependencies: 31 | animated_bottom_navigation_bar: ^1.3.3 32 | badges: ^3.1.2 33 | cached_network_image: ^3.3.1 34 | carousel_slider: ^4.2.1 35 | cloud_firestore: ^5.0.2 36 | comment_box: ^0.0.18 37 | cupertino_icons: ^1.0.6 38 | custom_refresh_indicator: ^3.1.1 39 | device_info_plus: ^10.1.0 40 | encrypt: ^5.0.3 41 | firebase_auth: ^5.1.1 42 | firebase_core: ^3.0.0 43 | firebase_messaging: ^15.0.0 44 | firebase_storage: ^12.1.0 45 | flutter: 46 | sdk: flutter 47 | flutter_image_compress: ^2.3.0 48 | flutter_local_notifications: ^17.1.2 49 | flutter_slidable: ^3.1.0 50 | flutter_staggered_grid_view: ^0.7.0 51 | get: ^4.6.6 52 | google_sign_in: ^6.2.1 53 | googleapis_auth: ^1.6.0 54 | http: ^1.2.1 55 | icons_plus: ^5.0.0 56 | image_cropper: ^7.0.4 57 | image_picker: ^1.1.2 58 | intl: ^0.19.0 59 | liquid_pull_to_refresh: ^3.0.1 60 | path_provider: ^2.1.3 61 | permission_handler: ^11.3.1 62 | photo_view: ^0.15.0 63 | provider: ^6.1.2 64 | scrollable_positioned_list: ^0.3.8 65 | shared_preferences: ^2.2.3 66 | smooth_page_indicator: ^1.1.0 67 | url_launcher: ^6.3.0 68 | video_player: ^2.9.1 69 | 70 | dev_dependencies: 71 | flutter_lints: ^4.0.0 72 | flutter_test: 73 | sdk: flutter 74 | 75 | # For information on the generic Dart part of this file, see the 76 | # following page: https://dart.dev/tools/pub/pubspec 77 | # The following section is specific to Flutter packages. 78 | flutter: 79 | 80 | # The following line ensures that the Material Icons font is 81 | # included with your application, so that you can use the icons in 82 | # the material Icons class. 83 | uses-material-design: true 84 | 85 | # To add assets to your application, add an assets section, like this: 86 | assets: 87 | - assets/logo/ 88 | - assets/icons/ 89 | 90 | fonts: 91 | - family: Poppins 92 | fonts: 93 | - asset: fonts/poppins.ttf 94 | - family: Alex 95 | fonts: 96 | - asset: fonts/Alex.ttf 97 | - family: Inter 98 | fonts: 99 | - asset: fonts/Inter.ttf 100 | -------------------------------------------------------------------------------- /test/home_nav_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:provider/provider.dart'; 4 | import 'package:wave/controllers/HomeNavController/home_nav_controller.dart'; 5 | import 'package:wave/utils/constants/keys.dart'; 6 | import 'package:wave/view/screens/HomeNavigation/home_navigation_screen.dart'; 7 | 8 | void main() { 9 | group('HomeNavigationScreen Logic Test', () { 10 | testWidgets('Bottom navigation screen index update test', 11 | (WidgetTester tester) async { 12 | // Create a HomeNavController instance 13 | final homeNavController = HomeNavController(); 14 | 15 | // Build our widget and trigger a frame. 16 | await tester.pumpWidget( 17 | ChangeNotifierProvider.value( 18 | value: homeNavController, 19 | child: MaterialApp( 20 | home: HomeNavigationScreen(), 21 | ), 22 | ), 23 | ); 24 | 25 | // Verify that the initial screen index is 0 26 | expect(homeNavController.currentScreenIndex, equals(0)); 27 | 28 | // Tap on the second bottom navigation bar item (index 1) 29 | await tester.tap( 30 | warnIfMissed: false, find.byKey(const Key(Keys.keyForSearchIcon))); 31 | await tester.pump(); 32 | 33 | // Verify that the screen index is updated to 1 34 | expect(homeNavController.currentScreenIndex, equals(1)); 35 | 36 | // Tap on the third bottom navigation bar item (index 2) 37 | await tester.tap( 38 | warnIfMissed: false, find.byKey(const Key(Keys.keyForAddPostIcon))); 39 | await tester.pump(); 40 | 41 | // Verify that the screen index is updated to 2 42 | expect(homeNavController.currentScreenIndex, equals(2)); 43 | }); 44 | }); 45 | } 46 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | wave 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wave", 3 | "short_name": "wave", 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 | -------------------------------------------------------------------------------- /windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /windows/flutter/ephemeral/.plugin_symlinks/cloud_firestore: -------------------------------------------------------------------------------- 1 | /Users/user/.pub-cache/hosted/pub.dev/cloud_firestore-5.0.2/ -------------------------------------------------------------------------------- /windows/flutter/ephemeral/.plugin_symlinks/file_selector_windows: -------------------------------------------------------------------------------- 1 | /Users/user/.pub-cache/hosted/pub.dev/file_selector_windows-0.9.3+1/ -------------------------------------------------------------------------------- /windows/flutter/ephemeral/.plugin_symlinks/firebase_auth: -------------------------------------------------------------------------------- 1 | /Users/user/.pub-cache/hosted/pub.dev/firebase_auth-5.1.1/ -------------------------------------------------------------------------------- /windows/flutter/ephemeral/.plugin_symlinks/firebase_core: -------------------------------------------------------------------------------- 1 | /Users/user/.pub-cache/hosted/pub.dev/firebase_core-3.1.1/ -------------------------------------------------------------------------------- /windows/flutter/ephemeral/.plugin_symlinks/firebase_storage: -------------------------------------------------------------------------------- 1 | /Users/user/.pub-cache/hosted/pub.dev/firebase_storage-12.1.0/ -------------------------------------------------------------------------------- /windows/flutter/ephemeral/.plugin_symlinks/image_picker_windows: -------------------------------------------------------------------------------- 1 | /Users/user/.pub-cache/hosted/pub.dev/image_picker_windows-0.2.1+1/ -------------------------------------------------------------------------------- /windows/flutter/ephemeral/.plugin_symlinks/path_provider_windows: -------------------------------------------------------------------------------- 1 | /Users/user/.pub-cache/hosted/pub.dev/path_provider_windows-2.2.1/ -------------------------------------------------------------------------------- /windows/flutter/ephemeral/.plugin_symlinks/permission_handler_windows: -------------------------------------------------------------------------------- 1 | /Users/user/.pub-cache/hosted/pub.dev/permission_handler_windows-0.2.1/ -------------------------------------------------------------------------------- /windows/flutter/ephemeral/.plugin_symlinks/shared_preferences_windows: -------------------------------------------------------------------------------- 1 | /Users/user/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.3.2/ -------------------------------------------------------------------------------- /windows/flutter/ephemeral/.plugin_symlinks/url_launcher_windows: -------------------------------------------------------------------------------- 1 | /Users/user/.pub-cache/hosted/pub.dev/url_launcher_windows-3.1.1/ -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | void RegisterPlugins(flutter::PluginRegistry* registry) { 18 | CloudFirestorePluginCApiRegisterWithRegistrar( 19 | registry->GetRegistrarForPlugin("CloudFirestorePluginCApi")); 20 | FileSelectorWindowsRegisterWithRegistrar( 21 | registry->GetRegistrarForPlugin("FileSelectorWindows")); 22 | FirebaseAuthPluginCApiRegisterWithRegistrar( 23 | registry->GetRegistrarForPlugin("FirebaseAuthPluginCApi")); 24 | FirebaseCorePluginCApiRegisterWithRegistrar( 25 | registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); 26 | FirebaseStoragePluginCApiRegisterWithRegistrar( 27 | registry->GetRegistrarForPlugin("FirebaseStoragePluginCApi")); 28 | PermissionHandlerWindowsPluginRegisterWithRegistrar( 29 | registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); 30 | UrlLauncherWindowsRegisterWithRegistrar( 31 | registry->GetRegistrarForPlugin("UrlLauncherWindows")); 32 | } 33 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | cloud_firestore 7 | file_selector_windows 8 | firebase_auth 9 | firebase_core 10 | firebase_storage 11 | permission_handler_windows 12 | url_launcher_windows 13 | ) 14 | 15 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 16 | ) 17 | 18 | set(PLUGIN_BUNDLED_LIBRARIES) 19 | 20 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 21 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 22 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 23 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 24 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 25 | endforeach(plugin) 26 | 27 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 28 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) 29 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 30 | endforeach(ffi_plugin) 31 | -------------------------------------------------------------------------------- /windows/runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(runner LANGUAGES CXX) 3 | 4 | # Define the application target. To change its name, change BINARY_NAME in the 5 | # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer 6 | # work. 7 | # 8 | # Any new source files that you add to the application should be added here. 9 | add_executable(${BINARY_NAME} WIN32 10 | "flutter_window.cpp" 11 | "main.cpp" 12 | "utils.cpp" 13 | "win32_window.cpp" 14 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 15 | "Runner.rc" 16 | "runner.exe.manifest" 17 | ) 18 | 19 | # Apply the standard set of build settings. This can be removed for applications 20 | # that need different build settings. 21 | apply_standard_settings(${BINARY_NAME}) 22 | 23 | # Add preprocessor definitions for the build version. 24 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") 25 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") 26 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") 27 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") 28 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") 29 | 30 | # Disable Windows macros that collide with C++ standard library functions. 31 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") 32 | 33 | # Add dependency libraries and include directories. Add any application-specific 34 | # dependencies here. 35 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) 36 | target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") 37 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") 38 | 39 | # Run the Flutter tool portions of the build. This must not be removed. 40 | add_dependencies(${BINARY_NAME} flutter_assemble) 41 | -------------------------------------------------------------------------------- /windows/runner/Runner.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #pragma code_page(65001) 4 | #include "resource.h" 5 | 6 | #define APSTUDIO_READONLY_SYMBOLS 7 | ///////////////////////////////////////////////////////////////////////////// 8 | // 9 | // Generated from the TEXTINCLUDE 2 resource. 10 | // 11 | #include "winres.h" 12 | 13 | ///////////////////////////////////////////////////////////////////////////// 14 | #undef APSTUDIO_READONLY_SYMBOLS 15 | 16 | ///////////////////////////////////////////////////////////////////////////// 17 | // English (United States) resources 18 | 19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Icon 51 | // 52 | 53 | // Icon with lowest ID value placed first to ensure application icon 54 | // remains consistent on all systems. 55 | IDI_APP_ICON ICON "resources\\app_icon.ico" 56 | 57 | 58 | ///////////////////////////////////////////////////////////////////////////// 59 | // 60 | // Version 61 | // 62 | 63 | #if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) 64 | #define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD 65 | #else 66 | #define VERSION_AS_NUMBER 1,0,0,0 67 | #endif 68 | 69 | #if defined(FLUTTER_VERSION) 70 | #define VERSION_AS_STRING FLUTTER_VERSION 71 | #else 72 | #define VERSION_AS_STRING "1.0.0" 73 | #endif 74 | 75 | VS_VERSION_INFO VERSIONINFO 76 | FILEVERSION VERSION_AS_NUMBER 77 | PRODUCTVERSION VERSION_AS_NUMBER 78 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 79 | #ifdef _DEBUG 80 | FILEFLAGS VS_FF_DEBUG 81 | #else 82 | FILEFLAGS 0x0L 83 | #endif 84 | FILEOS VOS__WINDOWS32 85 | FILETYPE VFT_APP 86 | FILESUBTYPE 0x0L 87 | BEGIN 88 | BLOCK "StringFileInfo" 89 | BEGIN 90 | BLOCK "040904e4" 91 | BEGIN 92 | VALUE "CompanyName", "com.example" "\0" 93 | VALUE "FileDescription", "wave" "\0" 94 | VALUE "FileVersion", VERSION_AS_STRING "\0" 95 | VALUE "InternalName", "wave" "\0" 96 | VALUE "LegalCopyright", "Copyright (C) 2024 com.example. All rights reserved." "\0" 97 | VALUE "OriginalFilename", "wave.exe" "\0" 98 | VALUE "ProductName", "wave" "\0" 99 | VALUE "ProductVersion", VERSION_AS_STRING "\0" 100 | END 101 | END 102 | BLOCK "VarFileInfo" 103 | BEGIN 104 | VALUE "Translation", 0x409, 1252 105 | END 106 | END 107 | 108 | #endif // English (United States) resources 109 | ///////////////////////////////////////////////////////////////////////////// 110 | 111 | 112 | 113 | #ifndef APSTUDIO_INVOKED 114 | ///////////////////////////////////////////////////////////////////////////// 115 | // 116 | // Generated from the TEXTINCLUDE 3 resource. 117 | // 118 | 119 | 120 | ///////////////////////////////////////////////////////////////////////////// 121 | #endif // not APSTUDIO_INVOKED 122 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.cpp: -------------------------------------------------------------------------------- 1 | #include "flutter_window.h" 2 | 3 | #include 4 | 5 | #include "flutter/generated_plugin_registrant.h" 6 | 7 | FlutterWindow::FlutterWindow(const flutter::DartProject& project) 8 | : project_(project) {} 9 | 10 | FlutterWindow::~FlutterWindow() {} 11 | 12 | bool FlutterWindow::OnCreate() { 13 | if (!Win32Window::OnCreate()) { 14 | return false; 15 | } 16 | 17 | RECT frame = GetClientArea(); 18 | 19 | // The size here must match the window dimensions to avoid unnecessary surface 20 | // creation / destruction in the startup path. 21 | flutter_controller_ = std::make_unique( 22 | frame.right - frame.left, frame.bottom - frame.top, project_); 23 | // Ensure that basic setup of the controller was successful. 24 | if (!flutter_controller_->engine() || !flutter_controller_->view()) { 25 | return false; 26 | } 27 | RegisterPlugins(flutter_controller_->engine()); 28 | SetChildContent(flutter_controller_->view()->GetNativeWindow()); 29 | 30 | flutter_controller_->engine()->SetNextFrameCallback([&]() { 31 | this->Show(); 32 | }); 33 | 34 | // Flutter can complete the first frame before the "show window" callback is 35 | // registered. The following call ensures a frame is pending to ensure the 36 | // window is shown. It is a no-op if the first frame hasn't completed yet. 37 | flutter_controller_->ForceRedraw(); 38 | 39 | return true; 40 | } 41 | 42 | void FlutterWindow::OnDestroy() { 43 | if (flutter_controller_) { 44 | flutter_controller_ = nullptr; 45 | } 46 | 47 | Win32Window::OnDestroy(); 48 | } 49 | 50 | LRESULT 51 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message, 52 | WPARAM const wparam, 53 | LPARAM const lparam) noexcept { 54 | // Give Flutter, including plugins, an opportunity to handle window messages. 55 | if (flutter_controller_) { 56 | std::optional result = 57 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, 58 | lparam); 59 | if (result) { 60 | return *result; 61 | } 62 | } 63 | 64 | switch (message) { 65 | case WM_FONTCHANGE: 66 | flutter_controller_->engine()->ReloadSystemFonts(); 67 | break; 68 | } 69 | 70 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam); 71 | } 72 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_FLUTTER_WINDOW_H_ 2 | #define RUNNER_FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "win32_window.h" 10 | 11 | // A window that does nothing but host a Flutter view. 12 | class FlutterWindow : public Win32Window { 13 | public: 14 | // Creates a new FlutterWindow hosting a Flutter view running |project|. 15 | explicit FlutterWindow(const flutter::DartProject& project); 16 | virtual ~FlutterWindow(); 17 | 18 | protected: 19 | // Win32Window: 20 | bool OnCreate() override; 21 | void OnDestroy() override; 22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 23 | LPARAM const lparam) noexcept override; 24 | 25 | private: 26 | // The project to run. 27 | flutter::DartProject project_; 28 | 29 | // The Flutter instance hosted by this window. 30 | std::unique_ptr flutter_controller_; 31 | }; 32 | 33 | #endif // RUNNER_FLUTTER_WINDOW_H_ 34 | -------------------------------------------------------------------------------- /windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "utils.h" 7 | 8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 9 | _In_ wchar_t *command_line, _In_ int show_command) { 10 | // Attach to console when present (e.g., 'flutter run') or create a 11 | // new console when running with a debugger. 12 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 13 | CreateAndAttachConsole(); 14 | } 15 | 16 | // Initialize COM, so that it is available for use in the library and/or 17 | // plugins. 18 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 19 | 20 | flutter::DartProject project(L"data"); 21 | 22 | std::vector command_line_arguments = 23 | GetCommandLineArguments(); 24 | 25 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); 26 | 27 | FlutterWindow window(project); 28 | Win32Window::Point origin(10, 10); 29 | Win32Window::Size size(1280, 720); 30 | if (!window.Create(L"wave", origin, size)) { 31 | return EXIT_FAILURE; 32 | } 33 | window.SetQuitOnClose(true); 34 | 35 | ::MSG msg; 36 | while (::GetMessage(&msg, nullptr, 0, 0)) { 37 | ::TranslateMessage(&msg); 38 | ::DispatchMessage(&msg); 39 | } 40 | 41 | ::CoUninitialize(); 42 | return EXIT_SUCCESS; 43 | } 44 | -------------------------------------------------------------------------------- /windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wave-2024/Wave/f1f39486774192080c22a0b6c7ed0170389bf3b1/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /windows/runner/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | void CreateAndAttachConsole() { 11 | if (::AllocConsole()) { 12 | FILE *unused; 13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) { 14 | _dup2(_fileno(stdout), 1); 15 | } 16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) { 17 | _dup2(_fileno(stdout), 2); 18 | } 19 | std::ios::sync_with_stdio(); 20 | FlutterDesktopResyncOutputStreams(); 21 | } 22 | } 23 | 24 | std::vector GetCommandLineArguments() { 25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. 26 | int argc; 27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); 28 | if (argv == nullptr) { 29 | return std::vector(); 30 | } 31 | 32 | std::vector command_line_arguments; 33 | 34 | // Skip the first argument as it's the binary name. 35 | for (int i = 1; i < argc; i++) { 36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i])); 37 | } 38 | 39 | ::LocalFree(argv); 40 | 41 | return command_line_arguments; 42 | } 43 | 44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) { 45 | if (utf16_string == nullptr) { 46 | return std::string(); 47 | } 48 | int target_length = ::WideCharToMultiByte( 49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 50 | -1, nullptr, 0, nullptr, nullptr) 51 | -1; // remove the trailing null character 52 | int input_length = (int)wcslen(utf16_string); 53 | std::string utf8_string; 54 | if (target_length <= 0 || target_length > utf8_string.max_size()) { 55 | return utf8_string; 56 | } 57 | utf8_string.resize(target_length); 58 | int converted_length = ::WideCharToMultiByte( 59 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 60 | input_length, utf8_string.data(), target_length, nullptr, nullptr); 61 | if (converted_length == 0) { 62 | return std::string(); 63 | } 64 | return utf8_string; 65 | } 66 | -------------------------------------------------------------------------------- /windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | -------------------------------------------------------------------------------- /windows/runner/win32_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_WIN32_WINDOW_H_ 2 | #define RUNNER_WIN32_WINDOW_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | // A class abstraction for a high DPI-aware Win32 Window. Intended to be 11 | // inherited from by classes that wish to specialize with custom 12 | // rendering and input handling 13 | class Win32Window { 14 | public: 15 | struct Point { 16 | unsigned int x; 17 | unsigned int y; 18 | Point(unsigned int x, unsigned int y) : x(x), y(y) {} 19 | }; 20 | 21 | struct Size { 22 | unsigned int width; 23 | unsigned int height; 24 | Size(unsigned int width, unsigned int height) 25 | : width(width), height(height) {} 26 | }; 27 | 28 | Win32Window(); 29 | virtual ~Win32Window(); 30 | 31 | // Creates a win32 window with |title| that is positioned and sized using 32 | // |origin| and |size|. New windows are created on the default monitor. Window 33 | // sizes are specified to the OS in physical pixels, hence to ensure a 34 | // consistent size this function will scale the inputted width and height as 35 | // as appropriate for the default monitor. The window is invisible until 36 | // |Show| is called. Returns true if the window was created successfully. 37 | bool Create(const std::wstring& title, const Point& origin, const Size& size); 38 | 39 | // Show the current window. Returns true if the window was successfully shown. 40 | bool Show(); 41 | 42 | // Release OS resources associated with window. 43 | void Destroy(); 44 | 45 | // Inserts |content| into the window tree. 46 | void SetChildContent(HWND content); 47 | 48 | // Returns the backing Window handle to enable clients to set icon and other 49 | // window properties. Returns nullptr if the window has been destroyed. 50 | HWND GetHandle(); 51 | 52 | // If true, closing this window will quit the application. 53 | void SetQuitOnClose(bool quit_on_close); 54 | 55 | // Return a RECT representing the bounds of the current client area. 56 | RECT GetClientArea(); 57 | 58 | protected: 59 | // Processes and route salient window messages for mouse handling, 60 | // size change and DPI. Delegates handling of these to member overloads that 61 | // inheriting classes can handle. 62 | virtual LRESULT MessageHandler(HWND window, 63 | UINT const message, 64 | WPARAM const wparam, 65 | LPARAM const lparam) noexcept; 66 | 67 | // Called when CreateAndShow is called, allowing subclass window-related 68 | // setup. Subclasses should return false if setup fails. 69 | virtual bool OnCreate(); 70 | 71 | // Called when Destroy is called. 72 | virtual void OnDestroy(); 73 | 74 | private: 75 | friend class WindowClassRegistrar; 76 | 77 | // OS callback called by message pump. Handles the WM_NCCREATE message which 78 | // is passed when the non-client area is being created and enables automatic 79 | // non-client DPI scaling so that the non-client area automatically 80 | // responds to changes in DPI. All other messages are handled by 81 | // MessageHandler. 82 | static LRESULT CALLBACK WndProc(HWND const window, 83 | UINT const message, 84 | WPARAM const wparam, 85 | LPARAM const lparam) noexcept; 86 | 87 | // Retrieves a class instance pointer for |window| 88 | static Win32Window* GetThisFromHandle(HWND const window) noexcept; 89 | 90 | // Update the window frame's theme to match the system theme. 91 | static void UpdateTheme(HWND const window); 92 | 93 | bool quit_on_close_ = false; 94 | 95 | // window handle for top level window. 96 | HWND window_handle_ = nullptr; 97 | 98 | // window handle for hosted content. 99 | HWND child_content_ = nullptr; 100 | }; 101 | 102 | #endif // RUNNER_WIN32_WINDOW_H_ 103 | --------------------------------------------------------------------------------