├── .fvm
└── fvm_config.json
├── .github
└── workflows
│ ├── android-deploy.yaml
│ ├── ios-deploy.yaml
│ └── main.yml
├── .gitignore
├── .metadata
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── android
├── .gitignore
├── Gemfile
├── app
│ ├── build.gradle
│ └── src
│ │ ├── androidTest
│ │ └── java
│ │ │ └── ja
│ │ │ └── burhanrashid52
│ │ │ └── whattodo
│ │ │ └── MainActivityTest.java
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── ja
│ │ │ └── burhanrashid52
│ │ │ └── whattodo
│ │ │ └── MainActivity.kt
│ │ └── res
│ │ ├── 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
│ │ └── styles.xml
├── build.gradle
├── fastlane
│ ├── Appfile
│ ├── Fastfile
│ ├── README.md
│ ├── metadata
│ │ └── android
│ │ │ └── en-US
│ │ │ ├── full_description.txt
│ │ │ ├── images
│ │ │ ├── featureGraphic.png
│ │ │ ├── icon.png
│ │ │ └── phoneScreenshots
│ │ │ │ ├── 1_en-US.png
│ │ │ │ ├── 2_en-US.png
│ │ │ │ ├── 3_en-US.png
│ │ │ │ └── 4_en-US.png
│ │ │ ├── short_description.txt
│ │ │ ├── title.txt
│ │ │ └── video.txt
│ └── report.xml
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
├── Logo
│ ├── horizontal.png
│ ├── logomark.png
│ └── vertical.png
├── facebook_logo.png
├── profile_pic.jpg
└── twitter_logo.png
├── integration_test
├── about_us_page_test.dart
├── add_label_page_test.dart
├── add_project_page_test.dart
├── add_task_page_test.dart
├── completed_tasks_page_test.dart
├── home_page_test.dart
├── main.dart
├── test_data.dart
└── test_helper.dart
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Gemfile
├── Gemfile.lock
├── Podfile
├── 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.h
│ ├── AppDelegate.m
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── 100.png
│ │ │ ├── 1024.png
│ │ │ ├── 114.png
│ │ │ ├── 120.png
│ │ │ ├── 144.png
│ │ │ ├── 152.png
│ │ │ ├── 167.png
│ │ │ ├── 180.png
│ │ │ ├── 20.png
│ │ │ ├── 29.png
│ │ │ ├── 40.png
│ │ │ ├── 50.png
│ │ │ ├── 57.png
│ │ │ ├── 58.png
│ │ │ ├── 60.png
│ │ │ ├── 72.png
│ │ │ ├── 76.png
│ │ │ ├── 80.png
│ │ │ ├── 87.png
│ │ │ └── Contents.json
│ │ └── 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
│ └── main.m
├── exportOptions.plist
└── fastlane
│ ├── Appfile
│ ├── Fastfile
│ ├── Matchfile
│ ├── README.md
│ └── report.xml
├── lib
├── bloc
│ └── bloc_provider.dart
├── db
│ └── app_db.dart
├── main.dart
├── models
│ └── priority.dart
├── pages
│ ├── about
│ │ └── about_us.dart
│ ├── home
│ │ ├── home.dart
│ │ ├── home_bloc.dart
│ │ └── side_drawer.dart
│ ├── labels
│ │ ├── add_label.dart
│ │ ├── label.dart
│ │ ├── label_bloc.dart
│ │ ├── label_db.dart
│ │ └── label_widget.dart
│ ├── projects
│ │ ├── add_project.dart
│ │ ├── project.dart
│ │ ├── project_bloc.dart
│ │ ├── project_db.dart
│ │ └── project_widget.dart
│ └── tasks
│ │ ├── add_task.dart
│ │ ├── bloc
│ │ ├── add_task_bloc.dart
│ │ └── task_bloc.dart
│ │ ├── models
│ │ ├── task_labels.dart
│ │ └── tasks.dart
│ │ ├── row_task.dart
│ │ ├── task_completed
│ │ ├── row_task_completed.dart
│ │ └── task_complted.dart
│ │ ├── task_db.dart
│ │ └── task_widgets.dart
└── utils
│ ├── app_constant.dart
│ ├── app_util.dart
│ ├── collapsable_expand_tile.dart
│ ├── color_utils.dart
│ ├── date_util.dart
│ ├── extension.dart
│ └── keys.dart
├── macos
├── .gitignore
├── Flutter
│ ├── Flutter-Debug.xcconfig
│ ├── Flutter-Release.xcconfig
│ └── GeneratedPluginRegistrant.swift
├── Podfile
├── 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
├── pubspec.yaml
├── shorebird.yaml
├── test
├── add_task.png
├── add_task_widget_test.dart
├── add_task_widget_test.mocks.dart
├── home_bloc_test.dart
├── label_bloc_test.dart
├── label_project_row_widget_test.dart
├── project_bloc_test.dart
├── task_list_dissmissble_widget_test.dart
├── task_list_dissmissble_widget_test.mocks.dart
├── task_row_widget_test.dart
├── test_data.dart
└── test_helpers.dart
└── test_driver
└── integration_test.dart
/.fvm/fvm_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "flutterSdkVersion": "3.24.0",
3 | "flavors": {}
4 | }
--------------------------------------------------------------------------------
/.github/workflows/android-deploy.yaml:
--------------------------------------------------------------------------------
1 | name: 🍏🤖 Deploy to play store
2 |
3 | on:
4 | push:
5 | tags:
6 | - '[0-9]+.[0-9]+.[0-9]+'
7 |
8 | jobs:
9 | deployAndroid:
10 | runs-on: ubuntu-latest
11 | env:
12 | GPS_JSON_KEY: ${{ secrets.GPS_JSON_KEY }}
13 | RELEASE_KEYSTORE_FILE: ${{ secrets.RELEASE_KEYSTORE_FILE }}
14 | KEYSTORE_PROPERTIES: ${{ secrets.KEYSTORE_PROPERTIES }}
15 | steps:
16 | - name: ⬇️ Checkout repository
17 | uses: actions/checkout@v3
18 | - name: Configure Java for the runner
19 | uses: actions/setup-java@v1
20 | with:
21 | java-version: "17"
22 | - name: ⚙️ Setup Flutter
23 | uses: subosito/flutter-action@v2
24 | with:
25 | flutter-version: "3.24.0"
26 | channel: 'stable'
27 | cache: true
28 | id: flutter
29 | - name: Update version number from tag
30 | run: |
31 | # Extract the version components from refs tag (e.g., 1.2.3)
32 | TAG_NAME=${{ github.ref_name }}
33 | VERSION=${TAG_NAME#v} # Remove the 'v' prefix if it exists
34 | echo "FLUTTER_BUILD_NAME=$VERSION" >> $GITHUB_ENV
35 | MAJOR=$(echo $VERSION | cut -d. -f1)
36 | MINOR=$(echo $VERSION | cut -d. -f2)
37 | PATCH=$(echo $VERSION | cut -d. -f3)
38 | NUMBER=$MAJOR$MINOR$PATCH
39 | echo "FLUTTER_BUILD_NUMBER=$NUMBER" >> $GITHUB_ENV
40 | - name: 📦 Get Packages
41 | run: flutter pub get
42 | - name: Setup Fastlane
43 | uses: ruby/setup-ruby@v1
44 | with:
45 | ruby-version: "3.3"
46 | bundler-cache: true
47 | - name: Setup play store service
48 | run: echo "$GPS_JSON_KEY" >> ./android/play-store.json
49 | - name: Setup store key properties
50 | run: echo "$KEYSTORE_PROPERTIES" >> ./android/key.properties
51 | - name: Get the release keystore
52 | run: |
53 | echo $RELEASE_KEYSTORE_FILE | base64 --decode > android/app/whattodo_keystore.jks
54 | - name: Build and Deploy to Play store
55 | run: |
56 | cd ./android
57 | fastlane android beta
--------------------------------------------------------------------------------
/.github/workflows/ios-deploy.yaml:
--------------------------------------------------------------------------------
1 | name: 🍏🚀 Deploy to appstore
2 |
3 | on:
4 | push:
5 | tags:
6 | - '[0-9]+.[0-9]+.[0-9]+'
7 |
8 | jobs:
9 | deployIos:
10 | runs-on: macos-latest
11 | env:
12 | ASC_JSON_KEY: ${{ secrets.ASC_JSON_KEY }}
13 | FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
14 | FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }}
15 | steps:
16 | - name: ⬇️ Checkout repository
17 | uses: actions/checkout@v3
18 | - name: ⚙️ Setup Flutter
19 | uses: subosito/flutter-action@v2
20 | with:
21 | flutter-version: "3.24.0"
22 | channel: 'stable'
23 | cache: true
24 | id: flutter
25 | - name: Update version number from tag
26 | run: |
27 | # Extract the version components from refs tag (e.g., 1.2.3)
28 | TAG_NAME=${{ github.ref_name }}
29 | VERSION=${TAG_NAME#v} # Remove the 'v' prefix if it exists
30 | echo "FLUTTER_BUILD_NAME=$VERSION" >> $GITHUB_ENV
31 | MAJOR=$(echo $VERSION | cut -d. -f1)
32 | MINOR=$(echo $VERSION | cut -d. -f2)
33 | PATCH=$(echo $VERSION | cut -d. -f3)
34 | NUMBER=$MAJOR$MINOR$PATCH
35 | echo "FLUTTER_BUILD_NUMBER=$NUMBER" >> $GITHUB_ENV
36 | - name: 📦 Get Packages
37 | run: flutter pub get
38 | - name: Setup Fastlane
39 | uses: ruby/setup-ruby@v1
40 | with:
41 | ruby-version: "3.3"
42 | bundler-cache: true
43 | working-directory: ios
44 | - name: Setup app store connect
45 | run: echo "$ASC_JSON_KEY" >> ./ios/fastlane/store.json
46 | - name: Install pod
47 | run: cd ios && pod install
48 | - name: Build and Deploy to TestFlight
49 | env:
50 | MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
51 | MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }}
52 | run: |
53 | cd ./ios
54 | bundle exec fastlane ios beta
55 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: WhatTodo Flutter Tests
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 |
11 | jobs:
12 | test:
13 | name: Run Flutter Tests
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/checkout@v3
18 | - uses: subosito/flutter-action@v2
19 | with:
20 | flutter-version: '3.24.0'
21 | channel: 'stable'
22 | - run: flutter --version
23 |
24 | - name: Get Packages
25 | run: flutter pub get
26 |
27 | - name: Run Tests
28 | run: flutter test
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.lock
4 | *.log
5 | *.pyc
6 | *.swp
7 | .DS_Store
8 | .atom/
9 | .buildlog/
10 | .history
11 | .svn/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 | coverage
19 |
20 | # Visual Studio Code related
21 | .vscode/
22 |
23 | # Flutter repo-specific
24 | /bin/cache/
25 | /bin/mingit/
26 | /dev/benchmarks/mega_gallery/
27 | /dev/bots/.recipe_deps
28 | /dev/bots/android_tools/
29 | /dev/docs/doc/
30 | /dev/docs/lib/
31 | /dev/docs/pubspec.yaml
32 | /packages/flutter/coverage/
33 | version
34 |
35 | # Flutter/Dart/Pub related
36 | **/doc/api/
37 | .dart_tool/
38 | .flutter-plugins
39 | .packages
40 | .pub-cache/
41 | .pub/
42 | build/
43 | flutter_*.png
44 | linked_*.ds
45 | unlinked.ds
46 | unlinked_spec.ds
47 |
48 | # Android related
49 | **/android/**/gradle-wrapper.jar
50 | **/android/.gradle
51 | **/android/captures/
52 | **/android/gradlew
53 | **/android/gradlew.bat
54 | **/android/local.properties
55 | **/android/**/GeneratedPluginRegistrant.java
56 |
57 | # iOS/XCode related
58 | **/ios/**/*.mode1v3
59 | **/ios/**/*.mode2v3
60 | **/ios/**/*.moved-aside
61 | **/ios/**/*.pbxuser
62 | **/ios/**/*.perspectivev3
63 | **/ios/**/*sync/
64 | **/ios/**/.sconsign.dblite
65 | **/ios/**/.tags*
66 | **/ios/**/.vagrant/
67 | **/ios/**/DerivedData/
68 | **/ios/**/Icon?
69 | **/ios/**/Pods/
70 | **/ios/**/.symlinks/
71 | **/ios/**/profile
72 | **/ios/**/xcuserdata
73 | **/ios/.generated/
74 | **/ios/Flutter/App.framework
75 | **/ios/Flutter/Flutter.framework
76 | **/ios/Flutter/Generated.xcconfig
77 | **/ios/Flutter/app.flx
78 | **/ios/Flutter/app.zip
79 | **/ios/Flutter/flutter_assets/
80 | **/ios/Flutter/flutter_export_environment.sh
81 | **/ios/ServiceDefinitions.json
82 | **/ios/Runner/GeneratedPluginRegistrant.*
83 | .flutter-plugins-dependencies
84 |
85 | # Exceptions to above rules.
86 | !**/ios/**/default.mode1v3
87 | !**/ios/**/default.mode2v3
88 | !**/ios/**/default.pbxuser
89 | !**/ios/**/default.perspectivev3
90 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
91 | .fvm/flutter_sdk
92 | /ios/Flutter/Flutter.podspec
93 |
--------------------------------------------------------------------------------
/.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: 3ea4d06340a97a1e9d7cae97567c64e0569dcaa2
8 | channel: beta
9 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at burhanrashid5253@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## How to contribute?
2 |
3 | 1. Fork the project.
4 | 2. Make required changes and commit.
5 | 3. Generate pull request. Mention all the required description regarding changes you made.
6 |
7 | Happy coding.:-)
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WhatTodo
2 |
3 | [](https://actions-badge.atrox.dev/burhanrashid52/whattodo/goto)   [](https://www.uplabs.com/posts/whattodo) [](https://mailchi.mp/193f2a7fe907/flutter-weekly-257173) [](https://android.libhunt.com/newsletter/101)
4 |
5 |
6 | 
7 |
8 | Life can feel overwhelming. But it doesn’t have to.
9 |
10 | A Simple To-do app design in flutter to keep track of your task on daily basis. You can add project, labels and due-date to your tasks
11 |
12 | [
](https://play.google.com/store/apps/details?id=ja.burhanrashid52.whattodo)
13 |
14 | ## Features
15 |
16 | - Build on [**BLoC**](#bloc-diagram) Architecture Pattern
17 | - Add [**Projects**](#project) by specifying a unique color to it
18 | - Add [**Labels**](#labels) by specifying a unique color to it
19 | - Add [**Task**](#task) by defining its priority
20 | - [**Swipe**](#swipe-the-task) to delete or complete the task
21 | - [**Sorting**](#sorting) Task
22 | - Works offline using [**Sqflite**](https://github.com/tekartik/sqflite "Flutter Database") database
23 |
24 | ## BLoC Diagram
25 | This diagram show case the dependencies to create a feature specific BLoCs.The HomeBloc is independent and used as communication channel between its child widgets.
26 |
27 | 
28 |
29 | ## Widget-BLoC Relationship
30 | This diagram shows that how each widget uses BLoCs.
31 |
32 | 
33 |
34 | ## Project
35 | The app already has a preloaded **_Inbox_** project. You can add more projects by clicking add project button on SideDrawer. From material color list you can specify any single color to the project
36 |
37 | 
38 |
39 | > You can assign only one project to a single task
40 |
41 | ## Labels
42 | You can add multiple labels by clicking add Labels button on SideDrawer. From material color list you can specify any single color to the label
43 |
44 | 
45 |
46 | > You can assign multiple labels to a single task
47 |
48 | ## Task
49 | You can add task with multiple attributes. You must assign a project to task if not than by default it will be added in _Inbox_ project.
50 | Task can have zero or more to label assing to it
51 |
52 | 
53 |
54 | ## Swipe the Task
55 | You can delete a task by swiping left-to-right or your can mark task as completed by swiping right-to-left. You can also undo a completed task by clicking on options menu where it shows the list of all completed tasks there you can swipe right-to-left to undo the completed task
56 |
57 | 
58 |
59 | ## Sorting
60 | You can sort your task with date i.e today and next 7 days and also acoording to project and labels
61 |
62 | 
63 |
64 |
65 | ## How to contribute?
66 | * Check out contribution guidelines 👉[CONTRIBUTING.md](https://github.com/burhanrashid52/WhatTodo/blob/master/CONTRIBUTING.md)
67 |
68 |
69 | ## What's next?
70 |
71 | - Editable Project,label and Task
72 | - Deletable Project and Label
73 | - Comment/Description in Task
74 | - Reminder with notification
75 |
76 |
77 | ## Questions?🤔
78 | Hit me on twitter [](https://twitter.com/burhanrashid52)
79 | [](https://medium.com/@burhanrashid52)
80 | [](https://www.facebook.com/Bursid)
81 |
82 |
83 | ## Credits
84 | - UI/UX inspired from [**Todoist**](https://play.google.com/store/apps/details?id=com.todoist&hl=en) app
85 | - Flutter [**Documentation**](https://flutter.io/docs/)
86 | - [**Collin Jackson**](https://stackoverflow.com/users/1463116/collin-jackson) answer's on stackoverflow :laughing:
87 |
88 | ## License
89 | Copyright 2020 Burhanuddin Rashid
90 |
91 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
92 |
93 | http://www.apache.org/licenses/LICENSE-2.0
94 |
95 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
96 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | *.class
3 | .gradle
4 | /local.properties
5 | /.idea/workspace.xml
6 | /.idea/libraries
7 | .DS_Store
8 | /build
9 | /captures
10 | GeneratedPluginRegistrant.java
11 | key.properties
12 | app/whattodo_keystore.jks
13 | play-store.json
14 | *.jks
15 |
--------------------------------------------------------------------------------
/android/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gem "fastlane"
4 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "com.android.application"
3 | id "kotlin-android"
4 | id "dev.flutter.flutter-gradle-plugin"
5 | }
6 |
7 | def localProperties = new Properties()
8 | def localPropertiesFile = rootProject.file('local.properties')
9 | if (localPropertiesFile.exists()) {
10 | localPropertiesFile.withReader('UTF-8') { reader ->
11 | localProperties.load(reader)
12 | }
13 | }
14 |
15 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
16 | if (flutterVersionCode == null) {
17 | flutterVersionCode = '1'
18 | }
19 |
20 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
21 | if (flutterVersionName == null) {
22 | flutterVersionName = '1.0'
23 | }
24 |
25 | def keystoreProperties = new Properties()
26 | def keystorePropertiesFile = rootProject.file('key.properties')
27 | if (keystorePropertiesFile.exists()) {
28 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
29 | }
30 |
31 | android {
32 | compileSdkVersion 34
33 |
34 | lintOptions {
35 | disable 'InvalidPackage'
36 | }
37 |
38 | defaultConfig {
39 | applicationId "ja.burhanrashid52.whattodo"
40 | minSdkVersion 24 //flutter.minSdkVersion
41 | targetSdkVersion 34
42 | versionCode flutterVersionCode.toInteger()
43 | versionName flutterVersionName
44 | }
45 |
46 | compileOptions {
47 | sourceCompatibility JavaVersion.VERSION_1_8
48 | targetCompatibility JavaVersion.VERSION_1_8
49 | }
50 |
51 | kotlinOptions {
52 | jvmTarget = '1.8'
53 | }
54 |
55 | sourceSets {
56 | main.java.srcDirs += 'src/main/kotlin'
57 | }
58 |
59 | signingConfigs {
60 | file(rootProject.file('key.properties')).with { propFile ->
61 | if (propFile.canRead()) {
62 | release {
63 | keyAlias keystoreProperties['keyAlias']
64 | keyPassword keystoreProperties['keyPassword']
65 | storeFile file(keystoreProperties['storeFile'])
66 | storePassword keystoreProperties['storePassword']
67 | }
68 | } else {
69 | print('not signed')
70 | }
71 | }
72 | }
73 |
74 | buildTypes {
75 | release {
76 | file(rootProject.file('key.properties')).with { propFile ->
77 | if (propFile.canRead()) {
78 | signingConfig signingConfigs.release
79 | }
80 | }
81 |
82 | applicationVariants.all { variant ->
83 | variant.outputs.all { output ->
84 | output.outputFileName = "app-release.apk"
85 | }
86 | }
87 | }
88 | }
89 |
90 | buildFeatures {
91 | viewBinding true
92 | }
93 | }
94 |
95 | flutter {
96 | source '../..'
97 | }
98 |
99 | dependencies {
100 | implementation 'com.android.support:support-annotations:28.0.0'
101 | }
102 |
--------------------------------------------------------------------------------
/android/app/src/androidTest/java/ja/burhanrashid52/whattodo/MainActivityTest.java:
--------------------------------------------------------------------------------
1 | package ja.burhanrashid52.whattodo;
2 |
3 | import androidx.test.rule.ActivityTestRule;
4 | import ja.burhanrashid52.whattodo.MainActivity;
5 | import dev.flutter.plugins.integration_test.FlutterTestRunner;
6 | import org.junit.Rule;
7 | import org.junit.runner.RunWith;
8 |
9 | @RunWith(FlutterTestRunner.class)
10 | public class MainActivityTest {
11 | @Rule
12 | public ActivityTestRule rule = new ActivityTestRule<>(MainActivity.class, true, false);
13 | }
14 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
27 |
30 |
38 |
42 |
43 |
44 |
45 |
46 |
47 |
50 |
51 |
--------------------------------------------------------------------------------
/android/app/src/main/java/ja/burhanrashid52/whattodo/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package ja.burhanrashid52.whattodo
2 |
3 | import io.flutter.embedding.android.FlutterFragmentActivity
4 |
5 | class MainActivity: FlutterFragmentActivity() {
6 | }
--------------------------------------------------------------------------------
/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/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | allprojects {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | }
6 | }
7 |
8 | rootProject.buildDir = '../build'
9 | subprojects {
10 | project.buildDir = "${rootProject.buildDir}/${project.name}"
11 | }
12 | subprojects {
13 | project.evaluationDependsOn(':app')
14 | }
15 |
16 | tasks.register("clean", Delete) {
17 | delete rootProject.buildDir
18 | }
--------------------------------------------------------------------------------
/android/fastlane/Appfile:
--------------------------------------------------------------------------------
1 | json_key_file("play-store.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
2 | package_name("ja.burhanrashid52.whattodo") # e.g. com.krausefx.app
3 |
--------------------------------------------------------------------------------
/android/fastlane/Fastfile:
--------------------------------------------------------------------------------
1 | # This file contains the fastlane.tools configuration
2 | # You can find the documentation at https://docs.fastlane.tools
3 | #
4 | # For a list of all available actions, check out
5 | #
6 | # https://docs.fastlane.tools/actions
7 | #
8 | # For a list of all available plugins, check out
9 | #
10 | # https://docs.fastlane.tools/plugins/available-plugins
11 | #
12 |
13 | # Uncomment the line if you want fastlane to automatically update itself
14 | # update_fastlane
15 |
16 | default_platform(:android)
17 |
18 | platform :android do
19 | desc "Deploy a new version to the Google Play"
20 | lane :beta do
21 | updated_version_name = ENV["FLUTTER_BUILD_NAME"]
22 | updated_version_number = ENV["FLUTTER_BUILD_NUMBER"]
23 | sh "flutter build apk --release --build-name=#{updated_version_name} --build-number=#{updated_version_number}"
24 | upload_to_play_store(
25 | track: "internal",
26 | apk: "../build/app/outputs/flutter-apk/app-release.apk",
27 | )
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/android/fastlane/README.md:
--------------------------------------------------------------------------------
1 | fastlane documentation
2 | ----
3 |
4 | # Installation
5 |
6 | Make sure you have the latest version of the Xcode command line tools installed:
7 |
8 | ```sh
9 | xcode-select --install
10 | ```
11 |
12 | For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
13 |
14 | # Available Actions
15 |
16 | ## Android
17 |
18 | ### android beta
19 |
20 | ```sh
21 | [bundle exec] fastlane android beta
22 | ```
23 |
24 | Deploy a new version to the Google Play
25 |
26 | ----
27 |
28 | This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
29 |
30 | More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
31 |
32 | The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
33 |
--------------------------------------------------------------------------------
/android/fastlane/metadata/android/en-US/full_description.txt:
--------------------------------------------------------------------------------
1 | A Simple To-do app design in flutter to keep track of your task on daily basis. You can add project, labels and due-date to your tasks.
2 |
3 | - Build on BLoC Architecture Pattern
4 | - Add Projects by specifying a unique color to it
5 | - Add Labels by specifying a unique color to it
6 | - Add Task by defining its priority
7 | - Swipe to delete or complete the task
8 | - Sorting Task
9 | - Works offline using Sqflite database
--------------------------------------------------------------------------------
/android/fastlane/metadata/android/en-US/images/featureGraphic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/android/fastlane/metadata/android/en-US/images/featureGraphic.png
--------------------------------------------------------------------------------
/android/fastlane/metadata/android/en-US/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/android/fastlane/metadata/android/en-US/images/icon.png
--------------------------------------------------------------------------------
/android/fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/android/fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png
--------------------------------------------------------------------------------
/android/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/android/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png
--------------------------------------------------------------------------------
/android/fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/android/fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png
--------------------------------------------------------------------------------
/android/fastlane/metadata/android/en-US/images/phoneScreenshots/4_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/android/fastlane/metadata/android/en-US/images/phoneScreenshots/4_en-US.png
--------------------------------------------------------------------------------
/android/fastlane/metadata/android/en-US/short_description.txt:
--------------------------------------------------------------------------------
1 | A Simple To-do app design in flutter to keep track of your task on daily basis.
--------------------------------------------------------------------------------
/android/fastlane/metadata/android/en-US/title.txt:
--------------------------------------------------------------------------------
1 | WhatTodo
--------------------------------------------------------------------------------
/android/fastlane/metadata/android/en-US/video.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/android/fastlane/metadata/android/en-US/video.txt
--------------------------------------------------------------------------------
/android/fastlane/report.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xms1024m -Xmx4096m
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-7.5-all.zip
--------------------------------------------------------------------------------
/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 |
10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
11 |
12 | repositories {
13 | google()
14 | mavenCentral()
15 | gradlePluginPortal()
16 | }
17 | }
18 |
19 | plugins {
20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0"
21 | id "com.android.application" version "7.4.2" apply false
22 | id "org.jetbrains.kotlin.android" version "1.9.0" apply false
23 | }
24 |
25 | include ":app"
--------------------------------------------------------------------------------
/assets/Logo/horizontal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/assets/Logo/horizontal.png
--------------------------------------------------------------------------------
/assets/Logo/logomark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/assets/Logo/logomark.png
--------------------------------------------------------------------------------
/assets/Logo/vertical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/assets/Logo/vertical.png
--------------------------------------------------------------------------------
/assets/facebook_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/assets/facebook_logo.png
--------------------------------------------------------------------------------
/assets/profile_pic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/assets/profile_pic.jpg
--------------------------------------------------------------------------------
/assets/twitter_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burhanrashid52/WhatTodo/db6ba701a4b71cf15ee6c53646c05cbff247863f/assets/twitter_logo.png
--------------------------------------------------------------------------------
/integration_test/about_us_page_test.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_app/pages/about/about_us.dart';
4 | import 'package:flutter_test/flutter_test.dart';
5 | import 'package:integration_test/integration_test.dart';
6 |
7 | void main() {
8 | IntegrationTestWidgetsFlutterBinding.ensureInitialized();
9 |
10 | group("About Screen", () {
11 | testWidgets('Profile Details', (WidgetTester tester) async {
12 | await tester.pumpWidget(
13 | MaterialApp(
14 | home: AboutUsScreen(),
15 | ),
16 | );
17 | expect(find.text("About"), findsOneWidget);
18 | expect(find.text("Report an Issue"), findsOneWidget);
19 | expect(find.text("Having an issue ? Report it here"), findsOneWidget);
20 | expect(find.text("Burhanuddin Rashid"), findsOneWidget);
21 | expect(find.text("burhanrashid52"), findsOneWidget);
22 | expect(find.text("burhanrashid5253@gmail.com"), findsOneWidget);
23 | expect(find.text("1.0.0"), findsOneWidget);
24 | });
25 | });
26 | }
27 |
--------------------------------------------------------------------------------
/integration_test/add_label_page_test.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:flutter_app/main.dart' as app;
3 | import 'package:flutter_app/utils/keys.dart';
4 | import 'package:flutter_test/flutter_test.dart';
5 | import 'package:integration_test/integration_test.dart';
6 |
7 | import 'test_helper.dart';
8 |
9 | void main() {
10 | IntegrationTestWidgetsFlutterBinding.ensureInitialized();
11 |
12 | group("Add Labels", () {
13 | setUp(() async {
14 | await cleanDb();
15 | });
16 |
17 | testWidgets('Enter Label Details and verify on Side drawer screen',
18 | (WidgetTester tester) async {
19 | app.main();
20 | await tester.pumpAndSettle();
21 |
22 | await tester.tapAndSettle(SideDrawerKeys.DRAWER);
23 |
24 | await tester.tapAndSettle(SideDrawerKeys.DRAWER_LABELS);
25 |
26 | await tester.tapAndSettle(SideDrawerKeys.ADD_LABEL);
27 |
28 | var addLabelNameField =
29 | find.byValueKey(AddLabelKeys.TEXT_FORM_LABEL_NAME);
30 |
31 | await tester.enterText(addLabelNameField, "Android");
32 | await tester.pumpAndSettle();
33 |
34 | await tester.tapAndSettle(AddLabelKeys.ADD_LABEL_BUTTON);
35 |
36 | await tester.tapAndSettle(SideDrawerKeys.DRAWER);
37 |
38 | await tester.tapAndSettle(SideDrawerKeys.DRAWER_LABELS);
39 |
40 | expect(find.text("@ Android"), findsOneWidget);
41 | //TODO Match the Label color as well
42 | },skip: true);//Flaky on CI
43 | });
44 | }
45 |
--------------------------------------------------------------------------------
/integration_test/add_project_page_test.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:flutter_app/main.dart' as app;
3 | import 'package:flutter_app/utils/keys.dart';
4 | import 'package:flutter_test/flutter_test.dart';
5 | import 'package:integration_test/integration_test.dart';
6 |
7 | import 'test_helper.dart';
8 |
9 | void main() {
10 | IntegrationTestWidgetsFlutterBinding.ensureInitialized();
11 |
12 | group("Add Projects", () {
13 |
14 | setUp(() async {
15 | await cleanDb();
16 | });
17 |
18 | testWidgets('Enter Project Details and verify on Side drawer screen',
19 | (WidgetTester tester) async {
20 | app.main();
21 | await tester.pumpAndSettle();
22 |
23 | await tester.tapAndSettle(SideDrawerKeys.DRAWER);
24 |
25 | await tester.tapAndSettle(SideDrawerKeys.DRAWER_PROJECTS);
26 |
27 | await tester.tapAndSettle(SideDrawerKeys.ADD_PROJECT);
28 |
29 | final addProjectName =
30 | find.byValueKey(AddProjectKeys.TEXT_FORM_PROJECT_NAME);
31 | await tester.enterText(addProjectName, "Personal");
32 |
33 | await tester.tapAndSettle(AddProjectKeys.ADD_PROJECT_BUTTON);
34 |
35 | await tester.tapAndSettle(SideDrawerKeys.DRAWER);
36 |
37 | await tester.tapAndSettle(SideDrawerKeys.DRAWER_PROJECTS);
38 |
39 | expect(find.text("Personal"), findsOneWidget);
40 | //TODO Match the project color as well
41 | });
42 | });
43 | }
44 |
--------------------------------------------------------------------------------
/integration_test/add_task_page_test.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:flutter_app/main.dart' as app;
3 | import 'package:flutter_app/utils/keys.dart';
4 | import 'package:flutter_test/flutter_test.dart';
5 | import 'package:integration_test/integration_test.dart';
6 | import 'test_helper.dart';
7 |
8 | void main() {
9 | IntegrationTestWidgetsFlutterBinding.ensureInitialized();
10 |
11 |
12 | group("Add Tasks", () {
13 |
14 | setUp(() async {
15 | await cleanDb();
16 | });
17 |
18 | testWidgets('Enter Task Details and verify on Task page screen',
19 | (WidgetTester tester) async {
20 | app.main();
21 | await tester.pumpAndSettle();
22 |
23 | await tester.tapAndSettle(HomePageKeys.ADD_NEW_TASK_BUTTON);
24 |
25 | expect(find.text("Add Task"), findsOneWidget);
26 |
27 | await tester.enterText(
28 | find.byValueKey(AddTaskKeys.ADD_TITLE), "First Task");
29 | await tester.pumpAndSettle();
30 | //TODO: 1. Add Project in selection 2. Add Label from dialog 3. Change due date
31 |
32 | await tester.tapAndSettle(AddTaskKeys.ADD_TASK);
33 |
34 | expect(find.text("First Task"), findsOneWidget);
35 | expect(find.text("Inbox"), findsOneWidget);
36 | });
37 | });
38 | }
39 |
--------------------------------------------------------------------------------
/integration_test/completed_tasks_page_test.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:flutter_app/main.dart' as app;
3 | import 'package:flutter_app/utils/keys.dart';
4 | import 'package:flutter_test/flutter_test.dart';
5 | import 'package:integration_test/integration_test.dart';
6 |
7 | import 'test_helper.dart';
8 |
9 | void main() {
10 | IntegrationTestWidgetsFlutterBinding.ensureInitialized();
11 |
12 | group('Completed Tasks Page', () {
13 | testWidgets('Show Today Tasks', (WidgetTester tester) async {
14 | app.main();
15 | await tester.pumpAndSettle();
16 | await seedDataInDb();
17 |
18 | await tester.tapAndSettle(SideDrawerKeys.DRAWER);
19 |
20 | await tester.tapAndSettle(SideDrawerKeys.TODAY);
21 |
22 | //swipe left to mark as complete
23 | var firstTaskListItem = find.byValueKey('swipe_1_0');
24 | await tester.drag(firstTaskListItem, const Offset(-300.0, 0.0));
25 | await tester.pumpAndSettle();
26 |
27 | await tester.tapAndSettle(CompletedTaskPageKeys.POPUP_ACTION);
28 |
29 | await tester.tapAndSettle(CompletedTaskPageKeys.COMPLETED_TASKS);
30 |
31 | expect(find.text("Task One"), findsOneWidget);
32 |
33 | //swipe left to mark to undo
34 | var firstCompletedTaskListItem = find.byValueKey('task_completed_1');
35 | await tester.drag(firstCompletedTaskListItem, const Offset(-300.0, 0.0));
36 | await tester.pumpAndSettle();
37 |
38 | await tester.pageBack();
39 | await tester.pumpAndSettle();
40 |
41 | expect(find.text("Task One"), findsOneWidget);
42 | });
43 |
44 | tearDown(() async {
45 | await cleanDb();
46 | });
47 | });
48 | }
49 |
--------------------------------------------------------------------------------
/integration_test/home_page_test.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:flutter_app/main.dart' as app;
3 | import 'package:flutter_app/utils/keys.dart';
4 | import 'package:flutter_test/flutter_test.dart';
5 | import 'package:integration_test/integration_test.dart';
6 |
7 | import 'test_helper.dart';
8 |
9 | void main() {
10 | IntegrationTestWidgetsFlutterBinding.ensureInitialized();
11 |
12 | group('Home Page', () {
13 | testWidgets('Today in Title', (WidgetTester tester) async {
14 | app.main();
15 | await tester.pumpAndSettle();
16 | expect(find.text("Today"), findsOneWidget);
17 | expect(find.text("No Task Added"), findsOneWidget);
18 | });
19 |
20 | testWidgets('Show Today Tasks', (WidgetTester tester) async {
21 | await seedAndStartApp(tester);
22 |
23 | await tester.tapAndSettle(SideDrawerKeys.DRAWER);
24 |
25 | await tester.tapAndSettle(SideDrawerKeys.TODAY);
26 |
27 | expect(find.text("Today"), findsOneWidget);
28 |
29 | expect(find.text("Task One"), findsOneWidget);
30 | expect(find.text("Inbox"), findsOneWidget);
31 |
32 | expect(find.text("Task Two"), findsOneWidget);
33 | expect(find.text("Personal"), findsOneWidget);
34 | });
35 |
36 | testWidgets('Show Inbox Tasks', (WidgetTester tester) async {
37 | await seedAndStartApp(tester);
38 |
39 | await tester.tapAndSettle(SideDrawerKeys.DRAWER);
40 |
41 | await tester.tapAndSettle(SideDrawerKeys.INBOX);
42 |
43 | expect(find.text("Task One"), findsOneWidget);
44 | expect(find.text("Inbox"), findsNWidgets(2));
45 | });
46 |
47 | testWidgets('Show Next 7 days Tasks', (WidgetTester tester) async {
48 | await seedAndStartApp(tester);
49 |
50 | await tester.tapAndSettle(SideDrawerKeys.DRAWER);
51 |
52 | await tester.tapAndSettle(SideDrawerKeys.NEXT_7_DAYS);
53 |
54 | expect(find.text("Next 7 Days"), findsOneWidget);
55 |
56 | expect(find.text("Task One"), findsOneWidget);
57 | expect(find.text("Inbox"), findsOneWidget);
58 |
59 | expect(find.text("Task Two"), findsOneWidget);
60 | expect(find.text("Personal"), findsOneWidget);
61 |
62 | expect(find.text("Task Three"), findsOneWidget);
63 | expect(find.text("Work"), findsOneWidget);
64 | });
65 |
66 | testWidgets('Show Personal project Tasks', (WidgetTester tester) async {
67 | await seedAndStartApp(tester);
68 |
69 | await tester.tapAndSettle(SideDrawerKeys.DRAWER);
70 |
71 | await tester.tapAndSettle(SideDrawerKeys.DRAWER_PROJECTS);
72 |
73 | await tester.tapAndSettle('Personal_2');
74 |
75 | expect(find.text("Task Two"), findsOneWidget);
76 | expect(find.text("Personal"), findsNWidgets(2));
77 | });
78 |
79 | testWidgets('Show No Travel project Tasks Found',
80 | (WidgetTester tester) async {
81 | await seedAndStartApp(tester);
82 |
83 | await tester.tapAndSettle(SideDrawerKeys.DRAWER);
84 |
85 | await tester.tapAndSettle(SideDrawerKeys.DRAWER_PROJECTS);
86 |
87 | await tester.tapAndSettle('Travel_4');
88 |
89 | expect(find.text("No Task Added"), findsOneWidget);
90 | });
91 |
92 | //TODO: Add test for tasks Label Filter
93 | });
94 |
95 | tearDown(() async {
96 | await cleanDb();
97 | });
98 | }
99 |
100 | Future seedAndStartApp(WidgetTester tester) async {
101 | app.main();
102 | await seedDataInDb();
103 | await tester.pumpAndSettle();
104 | }
105 |
--------------------------------------------------------------------------------
/integration_test/main.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'about_us_page_test.dart' as about;
3 | import 'add_label_page_test.dart' as label;
4 | import 'add_project_page_test.dart' as project;
5 | import 'add_task_page_test.dart' as tasks;
6 | import 'completed_tasks_page_test.dart' as tasks_completed;
7 | import 'home_page_test.dart' as home;
8 |
9 | void main() {
10 | //Run test
11 | home.main();
12 | tasks.main();
13 | tasks_completed.main();
14 | project.main();
15 | label.main();
16 | about.main();
17 | }
18 |
--------------------------------------------------------------------------------
/integration_test/test_data.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_app/models/priority.dart';
4 | import 'package:flutter_app/pages/labels/label.dart';
5 | import 'package:flutter_app/pages/projects/project.dart';
6 | import 'package:flutter_app/pages/tasks/models/tasks.dart';
7 |
8 | //Project Test data
9 | var testProject1 = Project.getInbox();
10 | var testProject2 = Project.update(
11 | id: 2,
12 | name: "Personal",
13 | colorCode: Colors.red.value,
14 | colorName: "Red",
15 | );
16 | var testProject3 = Project.update(
17 | id: 3,
18 | name: "Work",
19 | colorCode: Colors.black.value,
20 | colorName: "Black",
21 | );
22 | var testProject4 = Project.update(
23 | id: 4,
24 | name: "Travel",
25 | colorCode: Colors.orange.value,
26 | colorName: "Orange",
27 | );
28 |
29 | //Label Test data
30 | var testLabel1 = Label.update(
31 | id: 1,
32 | name: "Android",
33 | colorCode: Colors.green.value,
34 | colorName: "Green",
35 | );
36 |
37 | var testLabel2 = Label.update(
38 | id: 2,
39 | name: "Flutter",
40 | colorCode: Colors.lightBlue.value,
41 | colorName: "Blue Light",
42 | );
43 |
44 | var testLabel3 = Label.update(
45 | id: 3,
46 | name: "React",
47 | colorCode: Colors.purple.value,
48 | colorName: "Purple",
49 | );
50 |
51 |
52 | //Task Test data
53 | var testTask1 = Tasks.update(
54 | id: 1,
55 | title: "Task One",
56 | projectId: 1,
57 | priority: Status.PRIORITY_3,
58 | dueDate: DateTime.now().millisecondsSinceEpoch,
59 | );
60 |
61 | var testTask2 = Tasks.update(
62 | id: 2,
63 | title: "Task Two",
64 | projectId: 2,
65 | priority: Status.PRIORITY_2,
66 | dueDate: DateTime.now().millisecondsSinceEpoch,
67 | );
68 |
69 | var testTask3 = Tasks.update(
70 | id: 3,
71 | title: "Task Three",
72 | projectId: 3,
73 | priority: Status.PRIORITY_1,
74 | dueDate: DateTime.now().add(new Duration(days: 7)).millisecondsSinceEpoch,
75 | );
76 |
--------------------------------------------------------------------------------
/integration_test/test_helper.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:flutter/widgets.dart';
3 | import 'package:flutter_app/pages/labels/label.dart';
4 | import 'package:flutter_app/pages/labels/label_db.dart';
5 | import 'package:flutter_app/pages/projects/project.dart';
6 | import 'package:flutter_app/pages/projects/project_db.dart';
7 | import 'package:flutter_app/pages/tasks/models/tasks.dart';
8 | import 'package:flutter_app/pages/tasks/task_db.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'test_data.dart';
12 |
13 | extension TestFinder on CommonFinders {
14 | Finder byValueKey(String key) {
15 | return find.byKey(ValueKey(key));
16 | }
17 | }
18 |
19 | extension TestWidgetTester on WidgetTester {
20 | Future tapAndSettle(String key) async {
21 | await this.tap(find.byKey(ValueKey(key)));
22 | await pumpAndSettle();
23 | }
24 | }
25 |
26 | seedDataInDb() async {
27 | var projectDB = ProjectDB.get();
28 | await projectDB.insertOrReplace(testProject1);
29 | await projectDB.insertOrReplace(testProject2);
30 | await projectDB.insertOrReplace(testProject3);
31 | await projectDB.insertOrReplace(testProject4);
32 |
33 | var labelDB = LabelDB.get();
34 | await labelDB.updateLabels(testLabel1);
35 | await labelDB.updateLabels(testLabel2);
36 | await labelDB.updateLabels(testLabel3);
37 |
38 | var taskDB = TaskDB.get();
39 | await taskDB.updateTask(testTask1);
40 | await taskDB.updateTask(testTask2);
41 | await taskDB.updateTask(testTask3);
42 | }
43 |
44 | cleanDb() async {
45 | var projectDB = ProjectDB.get();
46 | List projects = await projectDB.getProjects(isInboxVisible: false);
47 | projects.forEach((project) {
48 | projectDB.deleteProject(project.id!);
49 | });
50 |
51 | var labelDB = LabelDB.get();
52 | List