├── .gitignore
├── .metadata
├── README.md
├── android
├── .project
├── .settings
│ └── org.eclipse.buildship.core.prefs
├── app
│ ├── .classpath
│ ├── .project
│ ├── .settings
│ │ └── org.eclipse.buildship.core.prefs
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── todo
│ │ │ └── MainActivity.java
│ │ └── res
│ │ ├── drawable
│ │ └── launch_background.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── todo_icon.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── todo_icon.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── todo_icon.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── todo_icon.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── todo_icon.png
│ │ └── values
│ │ └── styles.xml
├── build.gradle
├── debug.keystore
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── flutter_export_environment.sh
├── 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
│ │ ├── 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
│ └── main.m
├── lib
├── component
│ ├── colorpicker
│ │ └── color_picker_builder.dart
│ ├── iconpicker
│ │ ├── icon_picker.dart
│ │ └── icon_picker_builder.dart
│ └── todo_badge.dart
├── db
│ └── db_provider.dart
├── diamond_border.dart
├── gradient_background.dart
├── main.dart
├── model
│ ├── data
│ │ └── choice_card.dart
│ ├── hero_id_model.dart
│ ├── task_model.dart
│ ├── task_model.g.dart
│ ├── todo_model.dart
│ └── todo_model.g.dart
├── page
│ ├── add_task_screen.dart
│ ├── add_todo_screen.dart
│ ├── detail_screen.dart
│ ├── edit_task_screen.dart
│ └── privacy_policy.dart
├── route
│ └── scale_route.dart
├── scopedmodel
│ └── todo_list_model.dart
├── shadow_image.dart
├── task_progress_indicator.dart
└── utils
│ ├── color_utils.dart
│ ├── datetime_utils.dart
│ └── uuid.dart
├── pubspec.yaml
├── screenshots
├── screen01.png
├── screen02.png
├── screen03.png
└── screen04.png
└── test
└── widget_test.dart
/.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 |
19 | # Visual Studio Code related
20 | .vscode/
21 |
22 | # Flutter/Dart/Pub related
23 | **/doc/api/
24 | .dart_tool/
25 | .flutter-plugins
26 | .packages
27 | .pub-cache/
28 | .pub/
29 | build/
30 |
31 | # Android related
32 | **/android/**/gradle-wrapper.jar
33 | **/android/.gradle
34 | **/android/captures/
35 | **/android/gradlew
36 | **/android/gradlew.bat
37 | **/android/local.properties
38 | **/android/**/GeneratedPluginRegistrant.java
39 |
40 | # iOS/XCode related
41 | **/ios/**/*.mode1v3
42 | **/ios/**/*.mode2v3
43 | **/ios/**/*.moved-aside
44 | **/ios/**/*.pbxuser
45 | **/ios/**/*.perspectivev3
46 | **/ios/**/*sync/
47 | **/ios/**/.sconsign.dblite
48 | **/ios/**/.tags*
49 | **/ios/**/.vagrant/
50 | **/ios/**/DerivedData/
51 | **/ios/**/Icon?
52 | **/ios/**/Pods/
53 | **/ios/**/.symlinks/
54 | **/ios/**/profile
55 | **/ios/**/xcuserdata
56 | **/ios/.generated/
57 | **/ios/Flutter/App.framework
58 | **/ios/Flutter/Flutter.framework
59 | **/ios/Flutter/Generated.xcconfig
60 | **/ios/Flutter/app.flx
61 | **/ios/Flutter/app.zip
62 | **/ios/Flutter/flutter_assets/
63 | **/ios/ServiceDefinitions.json
64 | **/ios/Runner/GeneratedPluginRegistrant.*
65 |
66 | # Exceptions to above rules.
67 | !**/ios/**/default.mode1v3
68 | !**/ios/**/default.mode2v3
69 | !**/ios/**/default.pbxuser
70 | !**/ios/**/default.perspectivev3
71 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
72 |
--------------------------------------------------------------------------------
/.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.
5 |
6 | version:
7 | revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
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: e3c29ec00c9c825c891d75054c63fcc46454dca1
17 | base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
18 | - platform: android
19 | create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
20 | base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
21 | - platform: ios
22 | create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
23 | base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
24 | - platform: linux
25 | create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
26 | base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
27 | - platform: macos
28 | create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
29 | base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
30 | - platform: web
31 | create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
32 | base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
33 | - platform: windows
34 | create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
35 | base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
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 | [](https://codemagic.io/apps/5d0f190099fdb70008475b03/5d0f190099fdb70008475b02/latest_build)
2 |
3 |
4 |
5 |
6 |
7 | Todo - Simple & Beautiful
8 |
9 |
10 |
11 | A minimal Todo mobile app made using Flutter.
12 |
13 |
14 | Key Features •
15 | How To Use •
16 | Download •
17 | Credits •
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | ## Key Features
28 |
29 | * Easily add and remove tasks
30 | * Organize tasks under categories. editing.
31 | * Personalize task category using color and icon.
32 |
33 | ## How To Use
34 |
35 | To clone and run this application, you'll need [Git](https://git-scm.com) and [Flutter](https://flutter.dev/docs/get-started/install) installed on your computer. From your command line:
36 |
37 | ```bash
38 | # Clone this repository
39 | $ git clone https://github.com/sabinbajracharya/fluttery-todo.git
40 |
41 | # Go into the repository
42 | $ cd fluttery-todo
43 |
44 | # Install dependencies
45 | $ flutter packages get
46 |
47 | # Run the app
48 | $ flutter run
49 | ```
50 |
51 | ## Download
52 |
53 | You can [download](https://play.google.com/store/apps/details?id=com.queenstech.todo) the latest installable version of Todo for Android.
54 |
55 |
56 |
57 |
58 |
59 | ## Credits
60 | - [Design Inspiration](https://goo.gl/Y5rd7L)
61 |
62 | ## License
63 |
64 | MIT
65 |
66 | ---
67 |
68 | > GitHub [@sabinbajracharya](https://github.com/sabinbajracharya) ·
69 | > Instagram [@er_sabin](https://www.instagram.com/er_sabin/)
70 |
71 |
--------------------------------------------------------------------------------
/android/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | android
4 | Project android created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.buildship.core.gradleprojectbuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.buildship.core.gradleprojectnature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/android/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/android/app/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/android/app/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | app
4 | Project app created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.buildship.core.gradleprojectbuilder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.buildship.core.gradleprojectnature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/android/app/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=..
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '3'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0.2'
22 | }
23 |
24 | def keystoreProperties = new Properties()
25 | def keystorePropertiesFile = rootProject.file('key.properties')
26 | if (keystorePropertiesFile.exists()) {
27 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
28 | }
29 |
30 | apply plugin: 'com.android.application'
31 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
32 |
33 | android {
34 | compileSdkVersion 31
35 |
36 | lintOptions {
37 | disable 'InvalidPackage'
38 | }
39 |
40 | defaultConfig {
41 | applicationId "com.queenstech.todo"
42 | minSdkVersion 16
43 | targetSdkVersion 31
44 | versionCode flutterVersionCode.toInteger()
45 | versionName flutterVersionName
46 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
47 | }
48 |
49 | signingConfigs {
50 | release {
51 | if (System.getenv()["CI"]) { // CI=true is exported by Codemagic
52 | keyAlias keystoreProperties['keyAlias']
53 | keyPassword keystoreProperties['keyPassword']
54 | storeFile file(keystoreProperties['storeFile'])
55 | storePassword keystoreProperties['storePassword']
56 | } else {
57 | // TODO: Replace with your own signing config for the release build.
58 | // Signing with the debug keys for now, so `flutter run --release` works.
59 | storeFile file('../debug.keystore')
60 | keyAlias "androiddebugkey"
61 | keyPassword "android"
62 | storePassword "android"
63 | }
64 | }
65 | }
66 |
67 | buildTypes {
68 | release {
69 | signingConfig signingConfigs.release
70 | minifyEnabled true
71 | useProguard true
72 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
73 | }
74 |
75 | debug {
76 | signingConfig signingConfigs.debug
77 | minifyEnabled false
78 | useProguard false
79 | }
80 | }
81 | }
82 |
83 | flutter {
84 | source '../..'
85 | }
86 |
87 | dependencies {
88 | testImplementation 'junit:junit:4.12'
89 | androidTestImplementation 'androidx.test:runner:1.1.0'
90 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
91 | }
92 |
--------------------------------------------------------------------------------
/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | #Flutter Wrapper
2 | -keep class io.flutter.app.** { *; }
3 | -keep class io.flutter.plugin.** { *; }
4 | -keep class io.flutter.util.** { *; }
5 | -keep class io.flutter.view.** { *; }
6 | -keep class io.flutter.** { *; }
7 | -keep class io.flutter.plugins.** { *; }
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
15 |
19 |
27 |
31 |
34 |
35 |
36 |
37 |
38 |
39 |
41 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/example/todo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.todo;
2 |
3 | import io.flutter.embedding.android.FlutterActivity;
4 |
5 | public class MainActivity extends FlutterActivity {
6 | }
7 |
--------------------------------------------------------------------------------
/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/todo_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/android/app/src/main/res/mipmap-hdpi/todo_icon.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/todo_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/android/app/src/main/res/mipmap-mdpi/todo_icon.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/todo_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/android/app/src/main/res/mipmap-xhdpi/todo_icon.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/todo_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/android/app/src/main/res/mipmap-xxhdpi/todo_icon.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/todo_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/android/app/src/main/res/mipmap-xxxhdpi/todo_icon.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:3.4.0'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | google()
15 | jcenter()
16 | }
17 | }
18 |
19 | rootProject.buildDir = '../build'
20 | subprojects {
21 | project.buildDir = "${rootProject.buildDir}/${project.name}"
22 | }
23 | subprojects {
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/android/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/android/debug.keystore
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Jun 23 21:45:27 NPT 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/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 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/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=/home/hellojukay/dev/flutter"
4 | export "FLUTTER_APPLICATION_PATH=/home/hellojukay/github/fluttery-todo"
5 | export "COCOAPODS_PARALLEL_CODE_SIGN=true"
6 | export "FLUTTER_TARGET=lib/main.dart"
7 | export "FLUTTER_BUILD_DIR=build"
8 | export "FLUTTER_BUILD_NAME=1.1.1"
9 | export "FLUTTER_BUILD_NUMBER=20191101"
10 | export "DART_OBFUSCATION=false"
11 | export "TRACK_WIDGET_CREATION=true"
12 | export "TREE_SHAKE_ICONS=false"
13 | export "PACKAGE_CONFIG=.dart_tool/package_config.json"
14 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | platform :ios, '9.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
32 | end
33 |
34 | post_install do |installer|
35 | installer.pods_project.targets.each do |target|
36 | flutter_additional_ios_build_settings(target)
37 | end
38 | end
39 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
12 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
13 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
14 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
15 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
16 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
17 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
18 | D141452D868D527CC693F39D /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 54F3733F6E14C00EFBA422DF /* libPods-Runner.a */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXCopyFilesBuildPhase section */
22 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
23 | isa = PBXCopyFilesBuildPhase;
24 | buildActionMask = 2147483647;
25 | dstPath = "";
26 | dstSubfolderSpec = 10;
27 | files = (
28 | );
29 | name = "Embed Frameworks";
30 | runOnlyForDeploymentPostprocessing = 0;
31 | };
32 | /* End PBXCopyFilesBuildPhase section */
33 |
34 | /* Begin PBXFileReference section */
35 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
36 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
37 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
38 | 54F3733F6E14C00EFBA422DF /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
39 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
40 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
41 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
42 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
43 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
44 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
45 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
46 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
47 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
48 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
49 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
50 | CED73B26C33C593F1C74498D /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
51 | D9DE1C44A481F3BE827A9C1B /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
52 | EC472703C62012B5390546D9 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
53 | /* End PBXFileReference section */
54 |
55 | /* Begin PBXFrameworksBuildPhase section */
56 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
57 | isa = PBXFrameworksBuildPhase;
58 | buildActionMask = 2147483647;
59 | files = (
60 | D141452D868D527CC693F39D /* libPods-Runner.a in Frameworks */,
61 | );
62 | runOnlyForDeploymentPostprocessing = 0;
63 | };
64 | /* End PBXFrameworksBuildPhase section */
65 |
66 | /* Begin PBXGroup section */
67 | 05D85A74FFAF90F9CB2F0C1E /* Pods */ = {
68 | isa = PBXGroup;
69 | children = (
70 | D9DE1C44A481F3BE827A9C1B /* Pods-Runner.debug.xcconfig */,
71 | CED73B26C33C593F1C74498D /* Pods-Runner.release.xcconfig */,
72 | EC472703C62012B5390546D9 /* Pods-Runner.profile.xcconfig */,
73 | );
74 | name = Pods;
75 | sourceTree = "";
76 | };
77 | 0F70B91065607A526AA2FE55 /* Frameworks */ = {
78 | isa = PBXGroup;
79 | children = (
80 | 54F3733F6E14C00EFBA422DF /* libPods-Runner.a */,
81 | );
82 | name = Frameworks;
83 | sourceTree = "";
84 | };
85 | 9740EEB11CF90186004384FC /* Flutter */ = {
86 | isa = PBXGroup;
87 | children = (
88 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
89 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
90 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
91 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
92 | );
93 | name = Flutter;
94 | sourceTree = "";
95 | };
96 | 97C146E51CF9000F007C117D = {
97 | isa = PBXGroup;
98 | children = (
99 | 9740EEB11CF90186004384FC /* Flutter */,
100 | 97C146F01CF9000F007C117D /* Runner */,
101 | 97C146EF1CF9000F007C117D /* Products */,
102 | 05D85A74FFAF90F9CB2F0C1E /* Pods */,
103 | 0F70B91065607A526AA2FE55 /* Frameworks */,
104 | );
105 | sourceTree = "";
106 | };
107 | 97C146EF1CF9000F007C117D /* Products */ = {
108 | isa = PBXGroup;
109 | children = (
110 | 97C146EE1CF9000F007C117D /* Runner.app */,
111 | );
112 | name = Products;
113 | sourceTree = "";
114 | };
115 | 97C146F01CF9000F007C117D /* Runner */ = {
116 | isa = PBXGroup;
117 | children = (
118 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
119 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
120 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
121 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
122 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
123 | 97C147021CF9000F007C117D /* Info.plist */,
124 | 97C146F11CF9000F007C117D /* Supporting Files */,
125 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
126 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
127 | );
128 | path = Runner;
129 | sourceTree = "";
130 | };
131 | 97C146F11CF9000F007C117D /* Supporting Files */ = {
132 | isa = PBXGroup;
133 | children = (
134 | 97C146F21CF9000F007C117D /* main.m */,
135 | );
136 | name = "Supporting Files";
137 | sourceTree = "";
138 | };
139 | /* End PBXGroup section */
140 |
141 | /* Begin PBXNativeTarget section */
142 | 97C146ED1CF9000F007C117D /* Runner */ = {
143 | isa = PBXNativeTarget;
144 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
145 | buildPhases = (
146 | 6E5C8F5757CC7DC321B122A0 /* [CP] Check Pods Manifest.lock */,
147 | 9740EEB61CF901F6004384FC /* Run Script */,
148 | 97C146EA1CF9000F007C117D /* Sources */,
149 | 97C146EB1CF9000F007C117D /* Frameworks */,
150 | 97C146EC1CF9000F007C117D /* Resources */,
151 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
152 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
153 | );
154 | buildRules = (
155 | );
156 | dependencies = (
157 | );
158 | name = Runner;
159 | productName = Runner;
160 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
161 | productType = "com.apple.product-type.application";
162 | };
163 | /* End PBXNativeTarget section */
164 |
165 | /* Begin PBXProject section */
166 | 97C146E61CF9000F007C117D /* Project object */ = {
167 | isa = PBXProject;
168 | attributes = {
169 | LastUpgradeCheck = 0910;
170 | ORGANIZATIONNAME = "The Chromium Authors";
171 | TargetAttributes = {
172 | 97C146ED1CF9000F007C117D = {
173 | CreatedOnToolsVersion = 7.3.1;
174 | DevelopmentTeam = RLK6MZB6PQ;
175 | };
176 | };
177 | };
178 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
179 | compatibilityVersion = "Xcode 3.2";
180 | developmentRegion = English;
181 | hasScannedForEncodings = 0;
182 | knownRegions = (
183 | English,
184 | en,
185 | Base,
186 | );
187 | mainGroup = 97C146E51CF9000F007C117D;
188 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
189 | projectDirPath = "";
190 | projectRoot = "";
191 | targets = (
192 | 97C146ED1CF9000F007C117D /* Runner */,
193 | );
194 | };
195 | /* End PBXProject section */
196 |
197 | /* Begin PBXResourcesBuildPhase section */
198 | 97C146EC1CF9000F007C117D /* Resources */ = {
199 | isa = PBXResourcesBuildPhase;
200 | buildActionMask = 2147483647;
201 | files = (
202 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
203 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
204 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
205 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
206 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
207 | );
208 | runOnlyForDeploymentPostprocessing = 0;
209 | };
210 | /* End PBXResourcesBuildPhase section */
211 |
212 | /* Begin PBXShellScriptBuildPhase section */
213 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
214 | isa = PBXShellScriptBuildPhase;
215 | buildActionMask = 2147483647;
216 | files = (
217 | );
218 | inputPaths = (
219 | );
220 | name = "Thin Binary";
221 | outputPaths = (
222 | );
223 | runOnlyForDeploymentPostprocessing = 0;
224 | shellPath = /bin/sh;
225 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
226 | };
227 | 6E5C8F5757CC7DC321B122A0 /* [CP] Check Pods Manifest.lock */ = {
228 | isa = PBXShellScriptBuildPhase;
229 | buildActionMask = 2147483647;
230 | files = (
231 | );
232 | inputPaths = (
233 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
234 | "${PODS_ROOT}/Manifest.lock",
235 | );
236 | name = "[CP] Check Pods Manifest.lock";
237 | outputPaths = (
238 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
239 | );
240 | runOnlyForDeploymentPostprocessing = 0;
241 | shellPath = /bin/sh;
242 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
243 | showEnvVarsInLog = 0;
244 | };
245 | 9740EEB61CF901F6004384FC /* Run Script */ = {
246 | isa = PBXShellScriptBuildPhase;
247 | buildActionMask = 2147483647;
248 | files = (
249 | );
250 | inputPaths = (
251 | );
252 | name = "Run Script";
253 | outputPaths = (
254 | );
255 | runOnlyForDeploymentPostprocessing = 0;
256 | shellPath = /bin/sh;
257 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
258 | };
259 | /* End PBXShellScriptBuildPhase section */
260 |
261 | /* Begin PBXSourcesBuildPhase section */
262 | 97C146EA1CF9000F007C117D /* Sources */ = {
263 | isa = PBXSourcesBuildPhase;
264 | buildActionMask = 2147483647;
265 | files = (
266 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
267 | 97C146F31CF9000F007C117D /* main.m in Sources */,
268 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
269 | );
270 | runOnlyForDeploymentPostprocessing = 0;
271 | };
272 | /* End PBXSourcesBuildPhase section */
273 |
274 | /* Begin PBXVariantGroup section */
275 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
276 | isa = PBXVariantGroup;
277 | children = (
278 | 97C146FB1CF9000F007C117D /* Base */,
279 | );
280 | name = Main.storyboard;
281 | sourceTree = "";
282 | };
283 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
284 | isa = PBXVariantGroup;
285 | children = (
286 | 97C147001CF9000F007C117D /* Base */,
287 | );
288 | name = LaunchScreen.storyboard;
289 | sourceTree = "";
290 | };
291 | /* End PBXVariantGroup section */
292 |
293 | /* Begin XCBuildConfiguration section */
294 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
295 | isa = XCBuildConfiguration;
296 | buildSettings = {
297 | ALWAYS_SEARCH_USER_PATHS = NO;
298 | CLANG_ANALYZER_NONNULL = YES;
299 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
300 | CLANG_CXX_LIBRARY = "libc++";
301 | CLANG_ENABLE_MODULES = YES;
302 | CLANG_ENABLE_OBJC_ARC = YES;
303 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
304 | CLANG_WARN_BOOL_CONVERSION = YES;
305 | CLANG_WARN_COMMA = YES;
306 | CLANG_WARN_CONSTANT_CONVERSION = YES;
307 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
308 | CLANG_WARN_EMPTY_BODY = YES;
309 | CLANG_WARN_ENUM_CONVERSION = YES;
310 | CLANG_WARN_INFINITE_RECURSION = YES;
311 | CLANG_WARN_INT_CONVERSION = YES;
312 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
313 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
314 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
315 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
316 | CLANG_WARN_STRICT_PROTOTYPES = YES;
317 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
318 | CLANG_WARN_UNREACHABLE_CODE = YES;
319 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
320 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
321 | COPY_PHASE_STRIP = NO;
322 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
323 | ENABLE_NS_ASSERTIONS = NO;
324 | ENABLE_STRICT_OBJC_MSGSEND = YES;
325 | GCC_C_LANGUAGE_STANDARD = gnu99;
326 | GCC_NO_COMMON_BLOCKS = YES;
327 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
328 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
329 | GCC_WARN_UNDECLARED_SELECTOR = YES;
330 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
331 | GCC_WARN_UNUSED_FUNCTION = YES;
332 | GCC_WARN_UNUSED_VARIABLE = YES;
333 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
334 | MTL_ENABLE_DEBUG_INFO = NO;
335 | SDKROOT = iphoneos;
336 | TARGETED_DEVICE_FAMILY = "1,2";
337 | VALIDATE_PRODUCT = YES;
338 | };
339 | name = Profile;
340 | };
341 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
342 | isa = XCBuildConfiguration;
343 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
344 | buildSettings = {
345 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
346 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
347 | DEVELOPMENT_TEAM = S8QB4VV633;
348 | ENABLE_BITCODE = NO;
349 | FRAMEWORK_SEARCH_PATHS = (
350 | "$(inherited)",
351 | "$(PROJECT_DIR)/Flutter",
352 | );
353 | INFOPLIST_FILE = Runner/Info.plist;
354 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
355 | LIBRARY_SEARCH_PATHS = (
356 | "$(inherited)",
357 | "$(PROJECT_DIR)/Flutter",
358 | );
359 | PRODUCT_BUNDLE_IDENTIFIER = com.example.todo;
360 | PRODUCT_NAME = "$(TARGET_NAME)";
361 | VERSIONING_SYSTEM = "apple-generic";
362 | };
363 | name = Profile;
364 | };
365 | 97C147031CF9000F007C117D /* Debug */ = {
366 | isa = XCBuildConfiguration;
367 | buildSettings = {
368 | ALWAYS_SEARCH_USER_PATHS = NO;
369 | CLANG_ANALYZER_NONNULL = YES;
370 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
371 | CLANG_CXX_LIBRARY = "libc++";
372 | CLANG_ENABLE_MODULES = YES;
373 | CLANG_ENABLE_OBJC_ARC = YES;
374 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
375 | CLANG_WARN_BOOL_CONVERSION = YES;
376 | CLANG_WARN_COMMA = YES;
377 | CLANG_WARN_CONSTANT_CONVERSION = YES;
378 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
379 | CLANG_WARN_EMPTY_BODY = YES;
380 | CLANG_WARN_ENUM_CONVERSION = YES;
381 | CLANG_WARN_INFINITE_RECURSION = YES;
382 | CLANG_WARN_INT_CONVERSION = YES;
383 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
384 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
385 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
386 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
387 | CLANG_WARN_STRICT_PROTOTYPES = YES;
388 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
389 | CLANG_WARN_UNREACHABLE_CODE = YES;
390 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
391 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
392 | COPY_PHASE_STRIP = NO;
393 | DEBUG_INFORMATION_FORMAT = dwarf;
394 | ENABLE_STRICT_OBJC_MSGSEND = YES;
395 | ENABLE_TESTABILITY = YES;
396 | GCC_C_LANGUAGE_STANDARD = gnu99;
397 | GCC_DYNAMIC_NO_PIC = NO;
398 | GCC_NO_COMMON_BLOCKS = YES;
399 | GCC_OPTIMIZATION_LEVEL = 0;
400 | GCC_PREPROCESSOR_DEFINITIONS = (
401 | "DEBUG=1",
402 | "$(inherited)",
403 | );
404 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
405 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
406 | GCC_WARN_UNDECLARED_SELECTOR = YES;
407 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
408 | GCC_WARN_UNUSED_FUNCTION = YES;
409 | GCC_WARN_UNUSED_VARIABLE = YES;
410 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
411 | MTL_ENABLE_DEBUG_INFO = YES;
412 | ONLY_ACTIVE_ARCH = YES;
413 | SDKROOT = iphoneos;
414 | TARGETED_DEVICE_FAMILY = "1,2";
415 | };
416 | name = Debug;
417 | };
418 | 97C147041CF9000F007C117D /* Release */ = {
419 | isa = XCBuildConfiguration;
420 | buildSettings = {
421 | ALWAYS_SEARCH_USER_PATHS = NO;
422 | CLANG_ANALYZER_NONNULL = YES;
423 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
424 | CLANG_CXX_LIBRARY = "libc++";
425 | CLANG_ENABLE_MODULES = YES;
426 | CLANG_ENABLE_OBJC_ARC = YES;
427 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
428 | CLANG_WARN_BOOL_CONVERSION = YES;
429 | CLANG_WARN_COMMA = YES;
430 | CLANG_WARN_CONSTANT_CONVERSION = YES;
431 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
432 | CLANG_WARN_EMPTY_BODY = YES;
433 | CLANG_WARN_ENUM_CONVERSION = YES;
434 | CLANG_WARN_INFINITE_RECURSION = YES;
435 | CLANG_WARN_INT_CONVERSION = YES;
436 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
437 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
438 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
439 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
440 | CLANG_WARN_STRICT_PROTOTYPES = YES;
441 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
442 | CLANG_WARN_UNREACHABLE_CODE = YES;
443 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
444 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
445 | COPY_PHASE_STRIP = NO;
446 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
447 | ENABLE_NS_ASSERTIONS = NO;
448 | ENABLE_STRICT_OBJC_MSGSEND = YES;
449 | GCC_C_LANGUAGE_STANDARD = gnu99;
450 | GCC_NO_COMMON_BLOCKS = YES;
451 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
452 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
453 | GCC_WARN_UNDECLARED_SELECTOR = YES;
454 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
455 | GCC_WARN_UNUSED_FUNCTION = YES;
456 | GCC_WARN_UNUSED_VARIABLE = YES;
457 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
458 | MTL_ENABLE_DEBUG_INFO = NO;
459 | SDKROOT = iphoneos;
460 | TARGETED_DEVICE_FAMILY = "1,2";
461 | VALIDATE_PRODUCT = YES;
462 | };
463 | name = Release;
464 | };
465 | 97C147061CF9000F007C117D /* Debug */ = {
466 | isa = XCBuildConfiguration;
467 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
468 | buildSettings = {
469 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
470 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
471 | DEVELOPMENT_TEAM = RLK6MZB6PQ;
472 | ENABLE_BITCODE = NO;
473 | FRAMEWORK_SEARCH_PATHS = (
474 | "$(inherited)",
475 | "$(PROJECT_DIR)/Flutter",
476 | );
477 | INFOPLIST_FILE = Runner/Info.plist;
478 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
479 | LIBRARY_SEARCH_PATHS = (
480 | "$(inherited)",
481 | "$(PROJECT_DIR)/Flutter",
482 | );
483 | PRODUCT_BUNDLE_IDENTIFIER = com.example.todo;
484 | PRODUCT_NAME = "$(TARGET_NAME)";
485 | VERSIONING_SYSTEM = "apple-generic";
486 | };
487 | name = Debug;
488 | };
489 | 97C147071CF9000F007C117D /* Release */ = {
490 | isa = XCBuildConfiguration;
491 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
492 | buildSettings = {
493 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
494 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
495 | DEVELOPMENT_TEAM = 7KZCF372N7;
496 | ENABLE_BITCODE = NO;
497 | FRAMEWORK_SEARCH_PATHS = (
498 | "$(inherited)",
499 | "$(PROJECT_DIR)/Flutter",
500 | );
501 | INFOPLIST_FILE = Runner/Info.plist;
502 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
503 | LIBRARY_SEARCH_PATHS = (
504 | "$(inherited)",
505 | "$(PROJECT_DIR)/Flutter",
506 | );
507 | PRODUCT_BUNDLE_IDENTIFIER = com.example.todo;
508 | PRODUCT_NAME = "$(TARGET_NAME)";
509 | VERSIONING_SYSTEM = "apple-generic";
510 | };
511 | name = Release;
512 | };
513 | /* End XCBuildConfiguration section */
514 |
515 | /* Begin XCConfigurationList section */
516 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
517 | isa = XCConfigurationList;
518 | buildConfigurations = (
519 | 97C147031CF9000F007C117D /* Debug */,
520 | 97C147041CF9000F007C117D /* Release */,
521 | 249021D3217E4FDB00AE95B9 /* Profile */,
522 | );
523 | defaultConfigurationIsVisible = 0;
524 | defaultConfigurationName = Release;
525 | };
526 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
527 | isa = XCConfigurationList;
528 | buildConfigurations = (
529 | 97C147061CF9000F007C117D /* Debug */,
530 | 97C147071CF9000F007C117D /* Release */,
531 | 249021D4217E4FDB00AE95B9 /* Profile */,
532 | );
533 | defaultConfigurationIsVisible = 0;
534 | defaultConfigurationName = Release;
535 | };
536 | /* End XCConfigurationList section */
537 | };
538 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
539 | }
540 |
--------------------------------------------------------------------------------
/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 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
77 |
83 |
84 |
85 |
86 |
88 |
89 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #include "AppDelegate.h"
2 | #include "GeneratedPluginRegistrant.h"
3 |
4 | @implementation AppDelegate
5 |
6 | - (BOOL)application:(UIApplication *)application
7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
8 | [GeneratedPluginRegistrant registerWithRegistry:self];
9 | // Override point for customization after application launch.
10 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
11 | }
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/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 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | todo
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/ios/Runner/main.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char* argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lib/component/colorpicker/color_picker_builder.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_colorpicker/flutter_colorpicker.dart';
3 |
4 | import 'package:todo/utils/color_utils.dart';
5 |
6 | class ColorPickerBuilder extends StatelessWidget {
7 | final Color color;
8 | final ValueChanged onColorChanged;
9 |
10 | ColorPickerBuilder({required this.color, required this.onColorChanged});
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 | //https://stackoverflow.com/questions/45424621/inkwell-not-showing-ripple-effect
15 | return ClipOval(
16 | child: Container(
17 | height: 32.0,
18 | width: 32.0,
19 | child: Material(
20 | color: color,
21 | child: InkWell(
22 | borderRadius: BorderRadius.circular(50.0),
23 | onTap: () {
24 | showDialog(
25 | context: context,
26 | builder: (BuildContext context) {
27 | return AlertDialog(
28 | title: Text('Select a color'),
29 | content: SingleChildScrollView(
30 | child: BlockPicker(
31 | availableColors: ColorUtils.defaultColors,
32 | pickerColor: color,
33 | onColorChanged: onColorChanged,
34 | ),
35 | ),
36 | );
37 | },
38 | );
39 | },
40 | ),
41 | ),
42 | ),
43 | );
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/lib/component/iconpicker/icon_picker.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:todo/component/todo_badge.dart';
3 |
4 | class IconPicker extends StatefulWidget {
5 | final ValueChanged onIconChanged;
6 | final IconData currentIconData;
7 | final Color highlightColor, unHighlightColor;
8 |
9 | final List icons = [
10 | Icons.threesixty,
11 | Icons.threed_rotation,
12 | Icons.four_k,
13 | Icons.ac_unit,
14 | Icons.access_alarm,
15 | Icons.access_alarms,
16 | Icons.access_time,
17 | Icons.accessibility,
18 | Icons.accessibility_new,
19 | Icons.accessible,
20 | Icons.accessible_forward,
21 | Icons.account_balance,
22 | Icons.account_balance_wallet,
23 | Icons.account_box,
24 | Icons.account_circle,
25 | Icons.adb,
26 | Icons.add,
27 | Icons.add_a_photo,
28 | Icons.add_alarm,
29 | Icons.add_alert,
30 | Icons.add_box,
31 | Icons.add_call,
32 | Icons.add_circle,
33 | Icons.add_circle_outline,
34 | Icons.add_comment,
35 | Icons.add_location,
36 | Icons.add_photo_alternate,
37 | Icons.add_shopping_cart,
38 | Icons.add_to_home_screen,
39 | Icons.add_to_photos,
40 | Icons.add_to_queue,
41 | Icons.adjust,
42 | Icons.airline_seat_flat,
43 | Icons.airline_seat_flat_angled,
44 | Icons.airline_seat_individual_suite,
45 | Icons.airline_seat_legroom_extra,
46 | Icons.airline_seat_legroom_normal,
47 | Icons.airline_seat_legroom_reduced,
48 | Icons.airline_seat_recline_extra,
49 | Icons.airline_seat_recline_normal,
50 | Icons.airplanemode_active,
51 | Icons.airplanemode_inactive,
52 | Icons.airplay,
53 | Icons.airport_shuttle,
54 | Icons.alarm,
55 | Icons.alarm_add,
56 | Icons.alarm_off,
57 | Icons.alarm_on,
58 | Icons.album,
59 | Icons.all_inclusive,
60 | Icons.all_out,
61 | Icons.alternate_email,
62 | Icons.android,
63 | Icons.announcement,
64 | Icons.apps,
65 | Icons.archive,
66 | Icons.arrow_back,
67 | Icons.arrow_back_ios,
68 | Icons.arrow_downward,
69 | Icons.arrow_drop_down,
70 | Icons.arrow_drop_down_circle,
71 | Icons.arrow_drop_up,
72 | Icons.arrow_forward,
73 | Icons.arrow_forward_ios,
74 | Icons.arrow_left,
75 | Icons.arrow_right,
76 | Icons.arrow_upward,
77 | Icons.art_track,
78 | Icons.aspect_ratio,
79 | Icons.assessment,
80 | Icons.assignment,
81 | Icons.assignment_ind,
82 | Icons.assignment_late,
83 | Icons.assignment_return,
84 | Icons.assignment_returned,
85 | Icons.assignment_turned_in,
86 | Icons.assistant,
87 | Icons.assistant_photo,
88 | Icons.atm,
89 | Icons.attach_file,
90 | Icons.attach_money,
91 | Icons.attachment,
92 | Icons.audiotrack,
93 | Icons.autorenew,
94 | Icons.av_timer,
95 | Icons.backspace,
96 | Icons.backup,
97 | Icons.battery_alert,
98 | Icons.battery_charging_full,
99 | Icons.battery_full,
100 | Icons.battery_std,
101 | Icons.battery_unknown,
102 | Icons.beach_access,
103 | Icons.beenhere,
104 | Icons.block,
105 | Icons.bluetooth,
106 | Icons.bluetooth_audio,
107 | Icons.bluetooth_connected,
108 | Icons.bluetooth_disabled,
109 | Icons.bluetooth_searching,
110 | Icons.blur_circular,
111 | Icons.blur_linear,
112 | Icons.blur_off,
113 | Icons.blur_on,
114 | Icons.book,
115 | Icons.bookmark,
116 | Icons.bookmark_border,
117 | Icons.border_all,
118 | Icons.border_bottom,
119 | Icons.border_clear,
120 | Icons.border_color,
121 | Icons.border_horizontal,
122 | Icons.border_inner,
123 | Icons.border_left,
124 | Icons.border_outer,
125 | Icons.border_right,
126 | Icons.border_style,
127 | Icons.border_top,
128 | Icons.border_vertical,
129 | Icons.branding_watermark,
130 | Icons.brightness_1,
131 | Icons.brightness_2,
132 | Icons.brightness_3,
133 | Icons.brightness_4,
134 | Icons.brightness_5,
135 | Icons.brightness_6,
136 | Icons.brightness_7,
137 | Icons.brightness_auto,
138 | Icons.brightness_high,
139 | Icons.brightness_low,
140 | Icons.brightness_medium,
141 | Icons.broken_image,
142 | Icons.brush,
143 | Icons.bubble_chart,
144 | Icons.bug_report,
145 | Icons.build,
146 | Icons.burst_mode,
147 | Icons.business,
148 | Icons.business_center,
149 | Icons.cached,
150 | Icons.cake,
151 | Icons.calendar_today,
152 | Icons.calendar_view_day,
153 | Icons.call,
154 | Icons.call_end,
155 | Icons.call_made,
156 | Icons.call_merge,
157 | Icons.call_missed,
158 | Icons.call_missed_outgoing,
159 | Icons.call_received,
160 | Icons.call_split,
161 | Icons.call_to_action,
162 | Icons.camera,
163 | Icons.camera_alt,
164 | Icons.camera_enhance,
165 | Icons.camera_front,
166 | Icons.camera_rear,
167 | Icons.camera_roll,
168 | Icons.cancel,
169 | Icons.card_giftcard,
170 | Icons.card_membership,
171 | Icons.card_travel,
172 | Icons.casino,
173 | Icons.cast,
174 | Icons.cast_connected,
175 | Icons.category,
176 | Icons.center_focus_strong,
177 | Icons.center_focus_weak,
178 | Icons.change_history,
179 | Icons.chat,
180 | Icons.chat_bubble,
181 | Icons.chat_bubble_outline,
182 | Icons.check,
183 | Icons.check_box,
184 | Icons.check_box_outline_blank,
185 | Icons.check_circle,
186 | Icons.check_circle_outline,
187 | Icons.chevron_left,
188 | Icons.chevron_right,
189 | Icons.child_care,
190 | Icons.child_friendly,
191 | Icons.chrome_reader_mode,
192 | Icons.class_,
193 | Icons.clear,
194 | Icons.clear_all,
195 | Icons.close,
196 | Icons.closed_caption,
197 | Icons.cloud,
198 | Icons.cloud_circle,
199 | Icons.cloud_done,
200 | Icons.cloud_download,
201 | Icons.cloud_off,
202 | Icons.cloud_queue,
203 | Icons.cloud_upload,
204 | Icons.code,
205 | Icons.collections,
206 | Icons.collections_bookmark,
207 | Icons.color_lens,
208 | Icons.colorize,
209 | Icons.comment,
210 | Icons.compare,
211 | Icons.compare_arrows,
212 | Icons.computer,
213 | Icons.confirmation_number,
214 | Icons.contact_mail,
215 | Icons.contact_phone,
216 | Icons.contacts,
217 | Icons.content_copy,
218 | Icons.content_cut,
219 | Icons.content_paste,
220 | Icons.control_point,
221 | Icons.control_point_duplicate,
222 | Icons.copyright,
223 | Icons.create,
224 | Icons.create_new_folder,
225 | Icons.credit_card,
226 | Icons.crop,
227 | Icons.crop_16_9,
228 | Icons.crop_3_2,
229 | Icons.crop_5_4,
230 | Icons.crop_7_5,
231 | Icons.crop_din,
232 | Icons.crop_free,
233 | Icons.crop_landscape,
234 | Icons.crop_original,
235 | Icons.crop_portrait,
236 | Icons.crop_rotate,
237 | Icons.crop_square,
238 | Icons.dashboard,
239 | Icons.data_usage,
240 | Icons.date_range,
241 | Icons.dehaze,
242 | Icons.delete,
243 | Icons.delete_forever,
244 | Icons.delete_outline,
245 | Icons.delete_sweep,
246 | Icons.departure_board,
247 | Icons.description,
248 | Icons.desktop_mac,
249 | Icons.desktop_windows,
250 | Icons.details,
251 | Icons.developer_board,
252 | Icons.developer_mode,
253 | Icons.device_hub,
254 | Icons.device_unknown,
255 | Icons.devices,
256 | Icons.devices_other,
257 | Icons.dialer_sip,
258 | Icons.dialpad,
259 | Icons.directions,
260 | Icons.directions_bike,
261 | Icons.directions_boat,
262 | Icons.directions_bus,
263 | Icons.directions_car,
264 | Icons.directions_railway,
265 | Icons.directions_run,
266 | Icons.directions_subway,
267 | Icons.directions_transit,
268 | Icons.directions_walk,
269 | Icons.disc_full,
270 | Icons.dns,
271 | Icons.do_not_disturb,
272 | Icons.do_not_disturb_alt,
273 | Icons.do_not_disturb_off,
274 | Icons.do_not_disturb_on,
275 | Icons.dock,
276 | Icons.domain,
277 | Icons.done,
278 | Icons.done_all,
279 | Icons.done_outline,
280 | Icons.donut_large,
281 | Icons.donut_small,
282 | Icons.drafts,
283 | Icons.drag_handle,
284 | Icons.drive_eta,
285 | Icons.dvr,
286 | Icons.edit,
287 | Icons.edit_attributes,
288 | Icons.edit_location,
289 | Icons.eject,
290 | Icons.email,
291 | Icons.enhanced_encryption,
292 | Icons.equalizer,
293 | Icons.error,
294 | Icons.error_outline,
295 | Icons.euro_symbol,
296 | Icons.ev_station,
297 | Icons.event,
298 | Icons.event_available,
299 | Icons.event_busy,
300 | Icons.event_note,
301 | Icons.event_seat,
302 | Icons.exit_to_app,
303 | Icons.expand_less,
304 | Icons.expand_more,
305 | Icons.explicit,
306 | Icons.explore,
307 | Icons.exposure,
308 | Icons.exposure_neg_1,
309 | Icons.exposure_neg_2,
310 | Icons.exposure_plus_1,
311 | Icons.exposure_plus_2,
312 | Icons.exposure_zero,
313 | Icons.extension,
314 | Icons.face,
315 | Icons.fast_forward,
316 | Icons.fast_rewind,
317 | Icons.fastfood,
318 | Icons.favorite,
319 | Icons.favorite_border,
320 | Icons.featured_play_list,
321 | Icons.featured_video,
322 | Icons.feedback,
323 | Icons.fiber_dvr,
324 | Icons.fiber_manual_record,
325 | Icons.fiber_new,
326 | Icons.fiber_pin,
327 | Icons.fiber_smart_record,
328 | Icons.file_download,
329 | Icons.file_upload,
330 | Icons.filter,
331 | Icons.filter_1,
332 | Icons.filter_2,
333 | Icons.filter_3,
334 | Icons.filter_4,
335 | Icons.filter_5,
336 | Icons.filter_6,
337 | Icons.filter_7,
338 | Icons.filter_8,
339 | Icons.filter_9,
340 | Icons.filter_9_plus,
341 | Icons.filter_b_and_w,
342 | Icons.filter_center_focus,
343 | Icons.filter_drama,
344 | Icons.filter_frames,
345 | Icons.filter_hdr,
346 | Icons.filter_list,
347 | Icons.filter_none,
348 | Icons.filter_tilt_shift,
349 | Icons.filter_vintage,
350 | Icons.find_in_page,
351 | Icons.find_replace,
352 | Icons.fingerprint,
353 | Icons.first_page,
354 | Icons.fitness_center,
355 | Icons.flag,
356 | Icons.flare,
357 | Icons.flash_auto,
358 | Icons.flash_off,
359 | Icons.flash_on,
360 | Icons.flight,
361 | Icons.flight_land,
362 | Icons.flight_takeoff,
363 | Icons.flip,
364 | Icons.flip_to_back,
365 | Icons.flip_to_front,
366 | Icons.folder,
367 | Icons.folder_open,
368 | Icons.folder_shared,
369 | Icons.folder_special,
370 | Icons.font_download,
371 | Icons.format_align_center,
372 | Icons.format_align_justify,
373 | Icons.format_align_left,
374 | Icons.format_align_right,
375 | Icons.format_bold,
376 | Icons.format_clear,
377 | Icons.format_color_fill,
378 | Icons.format_color_reset,
379 | Icons.format_color_text,
380 | Icons.format_indent_decrease,
381 | Icons.format_indent_increase,
382 | Icons.format_italic,
383 | Icons.format_line_spacing,
384 | Icons.format_list_bulleted,
385 | Icons.format_list_numbered,
386 | Icons.format_list_numbered_rtl,
387 | Icons.format_paint,
388 | Icons.format_quote,
389 | Icons.format_shapes,
390 | Icons.format_size,
391 | Icons.format_strikethrough,
392 | Icons.format_textdirection_l_to_r,
393 | Icons.format_textdirection_r_to_l,
394 | Icons.format_underlined,
395 | Icons.forum,
396 | Icons.forward,
397 | Icons.forward_10,
398 | Icons.forward_30,
399 | Icons.forward_5,
400 | Icons.free_breakfast,
401 | Icons.fullscreen,
402 | Icons.fullscreen_exit,
403 | Icons.functions,
404 | Icons.g_translate,
405 | Icons.gamepad,
406 | Icons.games,
407 | Icons.gavel,
408 | Icons.gesture,
409 | Icons.get_app,
410 | Icons.gif,
411 | Icons.golf_course,
412 | Icons.gps_fixed,
413 | Icons.gps_not_fixed,
414 | Icons.gps_off,
415 | Icons.grade,
416 | Icons.gradient,
417 | Icons.grain,
418 | Icons.graphic_eq,
419 | Icons.grid_off,
420 | Icons.grid_on,
421 | Icons.group,
422 | Icons.group_add,
423 | Icons.group_work,
424 | Icons.hd,
425 | Icons.hdr_off,
426 | Icons.hdr_on,
427 | Icons.hdr_strong,
428 | Icons.hdr_weak,
429 | Icons.headset,
430 | Icons.headset_mic,
431 | Icons.headset_off,
432 | Icons.healing,
433 | Icons.hearing,
434 | Icons.help,
435 | Icons.help_outline,
436 | Icons.high_quality,
437 | Icons.highlight,
438 | Icons.highlight_off,
439 | Icons.history,
440 | Icons.home,
441 | Icons.hot_tub,
442 | Icons.hotel,
443 | Icons.hourglass_empty,
444 | Icons.hourglass_full,
445 | Icons.http,
446 | Icons.https,
447 | Icons.image,
448 | Icons.image_aspect_ratio,
449 | Icons.import_contacts,
450 | Icons.import_export,
451 | Icons.important_devices,
452 | Icons.inbox,
453 | Icons.indeterminate_check_box,
454 | Icons.info,
455 | Icons.info_outline,
456 | Icons.input,
457 | Icons.insert_chart,
458 | Icons.insert_comment,
459 | Icons.insert_drive_file,
460 | Icons.insert_emoticon,
461 | Icons.insert_invitation,
462 | Icons.insert_link,
463 | Icons.insert_photo,
464 | Icons.invert_colors,
465 | Icons.invert_colors_off,
466 | Icons.iso,
467 | Icons.keyboard,
468 | Icons.keyboard_arrow_down,
469 | Icons.keyboard_arrow_left,
470 | Icons.keyboard_arrow_right,
471 | Icons.keyboard_arrow_up,
472 | Icons.keyboard_backspace,
473 | Icons.keyboard_capslock,
474 | Icons.keyboard_hide,
475 | Icons.keyboard_return,
476 | Icons.keyboard_tab,
477 | Icons.keyboard_voice,
478 | Icons.kitchen,
479 | Icons.label,
480 | Icons.label_important,
481 | Icons.label_outline,
482 | Icons.landscape,
483 | Icons.language,
484 | Icons.laptop,
485 | Icons.laptop_chromebook,
486 | Icons.laptop_mac,
487 | Icons.laptop_windows,
488 | Icons.last_page,
489 | Icons.launch,
490 | Icons.layers,
491 | Icons.layers_clear,
492 | Icons.leak_add,
493 | Icons.leak_remove,
494 | Icons.lens,
495 | Icons.library_add,
496 | Icons.library_books,
497 | Icons.library_music,
498 | Icons.lightbulb_outline,
499 | Icons.line_style,
500 | Icons.line_weight,
501 | Icons.linear_scale,
502 | Icons.link,
503 | Icons.link_off,
504 | Icons.linked_camera,
505 | Icons.list,
506 | Icons.live_help,
507 | Icons.live_tv,
508 | Icons.local_activity,
509 | Icons.local_airport,
510 | Icons.local_atm,
511 | Icons.local_bar,
512 | Icons.local_cafe,
513 | Icons.local_car_wash,
514 | Icons.local_convenience_store,
515 | Icons.local_dining,
516 | Icons.local_drink,
517 | Icons.local_florist,
518 | Icons.local_gas_station,
519 | Icons.local_grocery_store,
520 | Icons.local_hospital,
521 | Icons.local_hotel,
522 | Icons.local_laundry_service,
523 | Icons.local_library,
524 | Icons.local_mall,
525 | Icons.local_movies,
526 | Icons.local_offer,
527 | Icons.local_parking,
528 | Icons.local_pharmacy,
529 | Icons.local_phone,
530 | Icons.local_pizza,
531 | Icons.local_play,
532 | Icons.local_post_office,
533 | Icons.local_printshop,
534 | Icons.local_see,
535 | Icons.local_shipping,
536 | Icons.local_taxi,
537 | Icons.location_city,
538 | Icons.location_disabled,
539 | Icons.location_off,
540 | Icons.location_on,
541 | Icons.location_searching,
542 | Icons.lock,
543 | Icons.lock_open,
544 | Icons.lock_outline,
545 | Icons.looks,
546 | Icons.looks_3,
547 | Icons.looks_4,
548 | Icons.looks_5,
549 | Icons.looks_6,
550 | Icons.looks_one,
551 | Icons.looks_two,
552 | Icons.loop,
553 | Icons.loupe,
554 | Icons.low_priority,
555 | Icons.loyalty,
556 | Icons.mail,
557 | Icons.mail_outline,
558 | Icons.map,
559 | Icons.markunread,
560 | Icons.markunread_mailbox,
561 | Icons.maximize,
562 | Icons.memory,
563 | Icons.menu,
564 | Icons.merge_type,
565 | Icons.message,
566 | Icons.mic,
567 | Icons.mic_none,
568 | Icons.mic_off,
569 | Icons.minimize,
570 | Icons.missed_video_call,
571 | Icons.mms,
572 | Icons.mobile_screen_share,
573 | Icons.mode_comment,
574 | Icons.mode_edit,
575 | Icons.monetization_on,
576 | Icons.money_off,
577 | Icons.monochrome_photos,
578 | Icons.mood,
579 | Icons.mood_bad,
580 | Icons.more,
581 | Icons.more_horiz,
582 | Icons.more_vert,
583 | Icons.motorcycle,
584 | Icons.mouse,
585 | Icons.move_to_inbox,
586 | Icons.movie,
587 | Icons.movie_creation,
588 | Icons.movie_filter,
589 | Icons.multiline_chart,
590 | Icons.music_note,
591 | Icons.music_video,
592 | Icons.my_location,
593 | Icons.nature,
594 | Icons.nature_people,
595 | Icons.navigate_before,
596 | Icons.navigate_next,
597 | Icons.navigation,
598 | Icons.near_me,
599 | Icons.network_cell,
600 | Icons.network_check,
601 | Icons.network_locked,
602 | Icons.network_wifi,
603 | Icons.new_releases,
604 | Icons.next_week,
605 | Icons.nfc,
606 | Icons.no_encryption,
607 | Icons.no_sim,
608 | Icons.not_interested,
609 | Icons.not_listed_location,
610 | Icons.note,
611 | Icons.note_add,
612 | Icons.notification_important,
613 | Icons.notifications,
614 | Icons.notifications_active,
615 | Icons.notifications_none,
616 | Icons.notifications_off,
617 | Icons.notifications_paused,
618 | Icons.offline_bolt,
619 | Icons.offline_pin,
620 | Icons.ondemand_video,
621 | Icons.opacity,
622 | Icons.open_in_browser,
623 | Icons.open_in_new,
624 | Icons.open_with,
625 | Icons.outlined_flag,
626 | Icons.pages,
627 | Icons.pageview,
628 | Icons.palette,
629 | Icons.pan_tool,
630 | Icons.panorama,
631 | Icons.panorama_fish_eye,
632 | Icons.panorama_horizontal,
633 | Icons.panorama_vertical,
634 | Icons.panorama_wide_angle,
635 | Icons.party_mode,
636 | Icons.pause,
637 | Icons.pause_circle_filled,
638 | Icons.pause_circle_outline,
639 | Icons.payment,
640 | Icons.people,
641 | Icons.people_outline,
642 | Icons.perm_camera_mic,
643 | Icons.perm_contact_calendar,
644 | Icons.perm_data_setting,
645 | Icons.perm_device_information,
646 | Icons.perm_identity,
647 | Icons.perm_media,
648 | Icons.perm_phone_msg,
649 | Icons.perm_scan_wifi,
650 | Icons.person,
651 | Icons.person_add,
652 | Icons.person_outline,
653 | Icons.person_pin,
654 | Icons.person_pin_circle,
655 | Icons.personal_video,
656 | Icons.pets,
657 | Icons.phone,
658 | Icons.phone_android,
659 | Icons.phone_bluetooth_speaker,
660 | Icons.phone_forwarded,
661 | Icons.phone_in_talk,
662 | Icons.phone_iphone,
663 | Icons.phone_locked,
664 | Icons.phone_missed,
665 | Icons.phone_paused,
666 | Icons.phonelink,
667 | Icons.phonelink_erase,
668 | Icons.phonelink_lock,
669 | Icons.phonelink_off,
670 | Icons.phonelink_ring,
671 | Icons.phonelink_setup,
672 | Icons.photo,
673 | Icons.photo_album,
674 | Icons.photo_camera,
675 | Icons.photo_filter,
676 | Icons.photo_library,
677 | Icons.photo_size_select_actual,
678 | Icons.photo_size_select_large,
679 | Icons.photo_size_select_small,
680 | Icons.picture_as_pdf,
681 | Icons.picture_in_picture,
682 | Icons.picture_in_picture_alt,
683 | Icons.pie_chart,
684 | Icons.pie_chart_outline_outlined,
685 | Icons.pin_drop,
686 | Icons.place,
687 | Icons.play_arrow,
688 | Icons.play_circle_filled,
689 | Icons.play_circle_outline,
690 | Icons.play_for_work,
691 | Icons.playlist_add,
692 | Icons.playlist_add_check,
693 | Icons.playlist_play,
694 | Icons.plus_one,
695 | Icons.poll,
696 | Icons.polymer,
697 | Icons.pool,
698 | Icons.portable_wifi_off,
699 | Icons.portrait,
700 | Icons.power,
701 | Icons.power_input,
702 | Icons.power_settings_new,
703 | Icons.pregnant_woman,
704 | Icons.present_to_all,
705 | Icons.print,
706 | Icons.priority_high,
707 | Icons.public,
708 | Icons.publish,
709 | Icons.query_builder,
710 | Icons.question_answer,
711 | Icons.queue,
712 | Icons.queue_music,
713 | Icons.queue_play_next,
714 | Icons.radio,
715 | Icons.radio_button_checked,
716 | Icons.radio_button_unchecked,
717 | Icons.rate_review,
718 | Icons.receipt,
719 | Icons.recent_actors,
720 | Icons.record_voice_over,
721 | Icons.redeem,
722 | Icons.redo,
723 | Icons.refresh,
724 | Icons.remove,
725 | Icons.remove_circle,
726 | Icons.remove_circle_outline,
727 | Icons.remove_from_queue,
728 | Icons.remove_red_eye,
729 | Icons.remove_shopping_cart,
730 | Icons.reorder,
731 | Icons.repeat,
732 | Icons.repeat_one,
733 | Icons.replay,
734 | Icons.replay_10,
735 | Icons.replay_30,
736 | Icons.replay_5,
737 | Icons.reply,
738 | Icons.reply_all,
739 | Icons.report,
740 | Icons.report_off,
741 | Icons.report_problem,
742 | Icons.restaurant,
743 | Icons.restaurant_menu,
744 | Icons.restore,
745 | Icons.restore_from_trash,
746 | Icons.restore_page,
747 | Icons.ring_volume,
748 | Icons.room,
749 | Icons.room_service,
750 | Icons.rotate_90_degrees_ccw,
751 | Icons.rotate_left,
752 | Icons.rotate_right,
753 | Icons.rounded_corner,
754 | Icons.router,
755 | Icons.rowing,
756 | Icons.rss_feed,
757 | Icons.rv_hookup,
758 | Icons.satellite,
759 | Icons.save,
760 | Icons.save_alt,
761 | Icons.scanner,
762 | Icons.scatter_plot,
763 | Icons.schedule,
764 | Icons.school,
765 | Icons.score,
766 | Icons.screen_lock_landscape,
767 | Icons.screen_lock_portrait,
768 | Icons.screen_lock_rotation,
769 | Icons.screen_rotation,
770 | Icons.screen_share,
771 | Icons.sd_card,
772 | Icons.sd_storage,
773 | Icons.search,
774 | Icons.security,
775 | Icons.select_all,
776 | Icons.send,
777 | Icons.sentiment_dissatisfied,
778 | Icons.sentiment_neutral,
779 | Icons.sentiment_satisfied,
780 | Icons.sentiment_very_dissatisfied,
781 | Icons.sentiment_very_satisfied,
782 | Icons.settings,
783 | Icons.settings_applications,
784 | Icons.settings_backup_restore,
785 | Icons.settings_bluetooth,
786 | Icons.settings_brightness,
787 | Icons.settings_cell,
788 | Icons.settings_ethernet,
789 | Icons.settings_input_antenna,
790 | Icons.settings_input_component,
791 | Icons.settings_input_composite,
792 | Icons.settings_input_hdmi,
793 | Icons.settings_input_svideo,
794 | Icons.settings_overscan,
795 | Icons.settings_phone,
796 | Icons.settings_power,
797 | Icons.settings_remote,
798 | Icons.settings_system_daydream,
799 | Icons.settings_voice,
800 | Icons.share,
801 | Icons.shop,
802 | Icons.shop_two,
803 | Icons.shopping_basket,
804 | Icons.shopping_cart,
805 | Icons.short_text,
806 | Icons.show_chart,
807 | Icons.shuffle,
808 | Icons.shutter_speed,
809 | Icons.signal_cellular_4_bar,
810 | Icons.signal_cellular_connected_no_internet_4_bar,
811 | Icons.signal_cellular_no_sim,
812 | Icons.signal_cellular_null,
813 | Icons.signal_cellular_off,
814 | Icons.signal_wifi_4_bar,
815 | Icons.signal_wifi_4_bar_lock,
816 | Icons.signal_wifi_off,
817 | Icons.sim_card,
818 | Icons.sim_card_alert,
819 | Icons.skip_next,
820 | Icons.skip_previous,
821 | Icons.slideshow,
822 | Icons.slow_motion_video,
823 | Icons.smartphone,
824 | Icons.smoke_free,
825 | Icons.smoking_rooms,
826 | Icons.sms,
827 | Icons.sms_failed,
828 | Icons.snooze,
829 | Icons.sort,
830 | Icons.sort_by_alpha,
831 | Icons.spa,
832 | Icons.space_bar,
833 | Icons.speaker,
834 | Icons.speaker_group,
835 | Icons.speaker_notes,
836 | Icons.speaker_notes_off,
837 | Icons.speaker_phone,
838 | Icons.spellcheck,
839 | Icons.star,
840 | Icons.star_border,
841 | Icons.star_half,
842 | Icons.stars,
843 | Icons.stay_current_landscape,
844 | Icons.stay_current_portrait,
845 | Icons.stay_primary_landscape,
846 | Icons.stay_primary_portrait,
847 | Icons.stop,
848 | Icons.stop_screen_share,
849 | Icons.storage,
850 | Icons.store,
851 | Icons.store_mall_directory,
852 | Icons.straighten,
853 | Icons.streetview,
854 | Icons.strikethrough_s,
855 | Icons.style,
856 | Icons.subdirectory_arrow_left,
857 | Icons.subdirectory_arrow_right,
858 | Icons.subject,
859 | Icons.subscriptions,
860 | Icons.subtitles,
861 | Icons.subway,
862 | Icons.supervised_user_circle,
863 | Icons.supervisor_account,
864 | Icons.surround_sound,
865 | Icons.swap_calls,
866 | Icons.swap_horiz,
867 | Icons.swap_horizontal_circle,
868 | Icons.swap_vert,
869 | Icons.swap_vertical_circle,
870 | Icons.switch_camera,
871 | Icons.switch_video,
872 | Icons.sync,
873 | Icons.sync_disabled,
874 | Icons.sync_problem,
875 | Icons.system_update,
876 | Icons.system_update_alt,
877 | Icons.tab,
878 | Icons.tab_unselected,
879 | Icons.table_chart,
880 | Icons.tablet,
881 | Icons.tablet_android,
882 | Icons.tablet_mac,
883 | Icons.tag_faces,
884 | Icons.tap_and_play,
885 | Icons.terrain,
886 | Icons.text_fields,
887 | Icons.text_format,
888 | Icons.text_rotate_up,
889 | Icons.text_rotate_vertical,
890 | Icons.text_rotation_angledown,
891 | Icons.text_rotation_angleup,
892 | Icons.text_rotation_down,
893 | Icons.text_rotation_none,
894 | Icons.textsms,
895 | Icons.texture,
896 | Icons.theaters,
897 | Icons.thumb_down,
898 | Icons.thumb_up,
899 | Icons.thumbs_up_down,
900 | Icons.time_to_leave,
901 | Icons.timelapse,
902 | Icons.timeline,
903 | Icons.timer,
904 | Icons.timer_10,
905 | Icons.timer_3,
906 | Icons.timer_off,
907 | Icons.title,
908 | Icons.toc,
909 | Icons.today,
910 | Icons.toll,
911 | Icons.tonality,
912 | Icons.touch_app,
913 | Icons.toys,
914 | Icons.track_changes,
915 | Icons.traffic,
916 | Icons.train,
917 | Icons.tram,
918 | Icons.transfer_within_a_station,
919 | Icons.transform,
920 | Icons.transit_enterexit,
921 | Icons.translate,
922 | Icons.trending_down,
923 | Icons.trending_flat,
924 | Icons.trending_up,
925 | Icons.trip_origin,
926 | Icons.tune,
927 | Icons.turned_in,
928 | Icons.turned_in_not,
929 | Icons.tv,
930 | Icons.unarchive,
931 | Icons.undo,
932 | Icons.unfold_less,
933 | Icons.unfold_more,
934 | Icons.update,
935 | Icons.usb,
936 | Icons.verified_user,
937 | Icons.vertical_align_bottom,
938 | Icons.vertical_align_center,
939 | Icons.vertical_align_top,
940 | Icons.vibration,
941 | Icons.video_call,
942 | Icons.video_label,
943 | Icons.video_library,
944 | Icons.videocam,
945 | Icons.videocam_off,
946 | Icons.videogame_asset,
947 | Icons.view_agenda,
948 | Icons.view_array,
949 | Icons.view_carousel,
950 | Icons.view_column,
951 | Icons.view_comfy,
952 | Icons.view_compact,
953 | Icons.view_day,
954 | Icons.view_headline,
955 | Icons.view_list,
956 | Icons.view_module,
957 | Icons.view_quilt,
958 | Icons.view_stream,
959 | Icons.view_week,
960 | Icons.vignette,
961 | Icons.visibility,
962 | Icons.visibility_off,
963 | Icons.voice_chat,
964 | Icons.voicemail,
965 | Icons.volume_down,
966 | Icons.volume_mute,
967 | Icons.volume_off,
968 | Icons.volume_up,
969 | Icons.vpn_key,
970 | Icons.vpn_lock,
971 | Icons.wallpaper,
972 | Icons.warning,
973 | Icons.watch,
974 | Icons.watch_later,
975 | Icons.wb_auto,
976 | Icons.wb_cloudy,
977 | Icons.wb_incandescent,
978 | Icons.wb_iridescent,
979 | Icons.wb_sunny,
980 | Icons.wc,
981 | Icons.web,
982 | Icons.web_asset,
983 | Icons.weekend,
984 | Icons.whatshot,
985 | Icons.widgets,
986 | Icons.wifi,
987 | Icons.wifi_lock,
988 | Icons.wifi_tethering,
989 | Icons.work,
990 | Icons.wrap_text,
991 | Icons.youtube_searched_for,
992 | Icons.zoom_in,
993 | Icons.zoom_out,
994 | Icons.zoom_out_map,
995 | ];
996 |
997 | IconPicker({
998 | required this.currentIconData,
999 | required this.onIconChanged,
1000 | Color? highlightColor,
1001 | Color? unHighlightColor,
1002 | }) : this.highlightColor = highlightColor ?? Colors.red,
1003 | this.unHighlightColor = unHighlightColor ?? Colors.blueGrey;
1004 |
1005 | @override
1006 | State createState() {
1007 | return _IconPickerState();
1008 | }
1009 | }
1010 |
1011 | class _IconPickerState extends State {
1012 | late IconData selectedIconData;
1013 |
1014 | @override
1015 | void initState() {
1016 | selectedIconData = widget.currentIconData;
1017 | super.initState();
1018 | }
1019 |
1020 | @override
1021 | Widget build(BuildContext context) {
1022 | Orientation orientation = MediaQuery.of(context).orientation;
1023 | return Container(
1024 | width: orientation == Orientation.portrait ? 300.0 : 300.0,
1025 | height: orientation == Orientation.portrait ? 360.0 : 200.0,
1026 | child: GridView.builder(
1027 | itemBuilder: (BuildContext context, int index) {
1028 | var iconData = widget.icons[index];
1029 | return Material(
1030 | color: Colors.transparent,
1031 | child: InkWell(
1032 | onTap: () {
1033 | setState(() {
1034 | selectedIconData = iconData;
1035 | });
1036 | widget.onIconChanged(iconData);
1037 | },
1038 | borderRadius: BorderRadius.circular(50.0),
1039 | child: TodoBadge(
1040 | id: iconData.hashCode.toString(),
1041 | codePoint: iconData.codePoint,
1042 | outlineColor: iconData == selectedIconData
1043 | ? widget.highlightColor
1044 | : widget.unHighlightColor,
1045 | color: iconData == selectedIconData
1046 | ? widget.highlightColor
1047 | : widget.unHighlightColor,
1048 | size: 32,
1049 | ),
1050 | ),
1051 | );
1052 | },
1053 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
1054 | crossAxisCount: orientation == Orientation.portrait ? 4 : 6,
1055 | mainAxisSpacing: 8.0,
1056 | crossAxisSpacing: 8.0,
1057 | childAspectRatio: 1.0,
1058 | ),
1059 | itemCount: widget.icons.length,
1060 | ),
1061 | );
1062 | }
1063 | }
1064 |
--------------------------------------------------------------------------------
/lib/component/iconpicker/icon_picker_builder.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:todo/component/todo_badge.dart';
3 |
4 | import 'icon_picker.dart';
5 |
6 | class IconPickerBuilder extends StatelessWidget {
7 | final IconData iconData;
8 | final ValueChanged action;
9 | final Color highlightColor;
10 |
11 | IconPickerBuilder({
12 | required this.iconData,
13 | required this.action,
14 | required Color highlightColor,
15 | }) : this.highlightColor = highlightColor;
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | return InkWell(
20 | borderRadius: BorderRadius.circular(50.0),
21 | onTap: () {
22 | showDialog(
23 | context: context,
24 | builder: (BuildContext context) {
25 | return AlertDialog(
26 | title: Text('Select an icon'),
27 | content: SingleChildScrollView(
28 | child: IconPicker(
29 | currentIconData: iconData,
30 | onIconChanged: action,
31 | highlightColor: highlightColor,
32 | ),
33 | ),
34 | );
35 | },
36 | );
37 | },
38 | child: TodoBadge(
39 | id: 'id',
40 | codePoint: iconData.codePoint,
41 | color: highlightColor,
42 | outlineColor: highlightColor,
43 | size: 24,
44 | ),
45 | );
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/lib/component/todo_badge.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class TodoBadge extends StatelessWidget {
4 | final int codePoint;
5 | final Color color;
6 | final String id;
7 | final double? size;
8 | final Color outlineColor;
9 |
10 | TodoBadge({
11 | required this.codePoint,
12 | required this.color,
13 | required this.id,
14 | Color? outlineColor,
15 | this.size,
16 | }) : this.outlineColor = outlineColor ?? Colors.grey.shade200;
17 |
18 | @override
19 | Widget build(BuildContext context) {
20 | return Hero(
21 | tag: id,
22 | child: Container(
23 | padding: EdgeInsets.all(8.0),
24 | decoration: BoxDecoration(
25 | shape: BoxShape.circle,
26 | border: Border.all(
27 | color: outlineColor,
28 | ),
29 | ),
30 | child: Icon(
31 | IconData(
32 | codePoint,
33 | fontFamily: 'MaterialIcons',
34 | ),
35 | color: color,
36 | size: size,
37 | ),
38 | ),
39 | );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/lib/db/db_provider.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:sqflite/sqflite.dart';
3 | import 'package:path/path.dart' as p;
4 | import 'package:path_provider/path_provider.dart';
5 | import 'dart:io';
6 |
7 | import 'package:todo/model/todo_model.dart';
8 | import 'package:todo/model/task_model.dart';
9 | import 'package:sqflite_common/sqlite_api.dart';
10 | import 'package:sqflite_common_ffi/sqflite_ffi.dart';
11 |
12 | class DBProvider {
13 | static Database? _database;
14 |
15 | DBProvider._();
16 | static final DBProvider db = DBProvider._();
17 |
18 | var todos = [
19 | Todo(
20 | "Vegetables",
21 | parent: '1',
22 | ),
23 | Todo(
24 | "Birthday gift",
25 | parent: '1',
26 | ),
27 | Todo("Chocolate cookies", parent: '1', isCompleted: 1),
28 | Todo(
29 | "20 pushups",
30 | parent: '2',
31 | ),
32 | Todo(
33 | "Tricep",
34 | parent: '2',
35 | ),
36 | Todo(
37 | "15 burpees (3 sets)",
38 | parent: '2',
39 | ),
40 | ];
41 |
42 | var tasks = [
43 | Task('Shopping',
44 | id: '1',
45 | color: Colors.purple.value,
46 | codePoint: Icons.shopping_cart.codePoint),
47 | Task('Workout',
48 | id: '2',
49 | color: Colors.pink.value,
50 | codePoint: Icons.fitness_center.codePoint),
51 | ];
52 |
53 | Future get database async {
54 | return _database ?? await initDB();
55 | }
56 |
57 | get _dbPath async {
58 | String documentsDirectory = await _localPath;
59 | return p.join(documentsDirectory, "Todo.db");
60 | }
61 |
62 | Future dbExists() async {
63 | return File(await _dbPath).exists();
64 | }
65 |
66 | initDB() async {
67 | String path = await _dbPath;
68 | if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
69 | sqfliteFfiInit();
70 | var db = await databaseFactoryFfi.openDatabase(path);
71 | await db.execute("CREATE TABLE IF NOT EXISTS Task ("
72 | "id TEXT PRIMARY KEY,"
73 | "name TEXT,"
74 | "color INTEGER,"
75 | "code_point INTEGER"
76 | ")");
77 | await db.execute("CREATE TABLE IF NOT EXISTS Todo ("
78 | "id TEXT PRIMARY KEY,"
79 | "name TEXT,"
80 | "parent TEXT,"
81 | "completed INTEGER NOT NULL DEFAULT 0"
82 | ")");
83 | return db;
84 | }
85 | return await openDatabase(path, version: 1, onOpen: (db) {},
86 | onCreate: (Database db, int version) async {
87 | print("DBProvider:: onCreate()");
88 | await db.execute("CREATE TABLE IF NOT EXISTS Task ("
89 | "id TEXT PRIMARY KEY,"
90 | "name TEXT,"
91 | "color INTEGER,"
92 | "code_point INTEGER"
93 | ")");
94 | await db.execute("CREATE TABLE IF NOT EXISTS Todo ("
95 | "id TEXT PRIMARY KEY,"
96 | "name TEXT,"
97 | "parent TEXT,"
98 | "completed INTEGER NOT NULL DEFAULT 0"
99 | ")");
100 | });
101 | }
102 |
103 | insertBulkTask(List tasks) async {
104 | final db = await database;
105 | tasks.forEach((it) async {
106 | var res = await db.insert("Task", it.toJson());
107 | print("Task ${it.id} = $res");
108 | });
109 | }
110 |
111 | insertBulkTodo(List todos) async {
112 | final db = await database;
113 | todos.forEach((it) async {
114 | var res = await db.insert("Todo", it.toJson());
115 | print("Todo ${it.id} = $res");
116 | });
117 | }
118 |
119 | Future> getAllTask() async {
120 | final db = await database;
121 | var result = await db.query('Task');
122 | return result.map((it) => Task.fromJson(it)).toList();
123 | }
124 |
125 | Future> getAllTodo() async {
126 | final db = await database;
127 | var result = await db.query('Todo');
128 | return result.map((it) => Todo.fromJson(it)).toList();
129 | }
130 |
131 | Future updateTodo(Todo todo) async {
132 | final db = await database;
133 | return db
134 | .update('Todo', todo.toJson(), where: 'id = ?', whereArgs: [todo.id]);
135 | }
136 |
137 | Future removeTodo(Todo todo) async {
138 | final db = await database;
139 | return db.delete('Todo', where: 'id = ?', whereArgs: [todo.id]);
140 | }
141 |
142 | Future insertTodo(Todo todo) async {
143 | final db = await database;
144 | return db.insert('Todo', todo.toJson());
145 | }
146 |
147 | Future insertTask(Task task) async {
148 | final db = await database;
149 | return db.insert('Task', task.toJson());
150 | }
151 |
152 | Future removeTask(Task task) async {
153 | final db = await database;
154 | return db.transaction((txn) async {
155 | await txn.delete('Todo', where: 'parent = ?', whereArgs: [task.id]);
156 | await txn.delete('Task', where: 'id = ?', whereArgs: [task.id]);
157 | });
158 | }
159 |
160 | Future updateTask(Task task) async {
161 | final db = await database;
162 | return db
163 | .update('Task', task.toJson(), where: 'id = ?', whereArgs: [task.id]);
164 | }
165 |
166 | Future get _localPath async {
167 | final directory = await getApplicationDocumentsDirectory();
168 | return directory.path;
169 | }
170 |
171 | closeDB() {
172 | _database?.close();
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/lib/diamond_border.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class DiamondBorder extends ShapeBorder {
4 | const DiamondBorder();
5 |
6 | @override
7 | EdgeInsetsGeometry get dimensions {
8 | return const EdgeInsets.only();
9 | }
10 |
11 | @override
12 | Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
13 | return getOuterPath(rect, textDirection: textDirection);
14 | }
15 |
16 | @override
17 | Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
18 | return Path()
19 | ..moveTo(rect.left + rect.width / 2.0, rect.top)
20 | ..lineTo(rect.right, rect.top + rect.height / 2.0)
21 | ..lineTo(rect.left + rect.width / 2.0, rect.bottom)
22 | ..lineTo(rect.left, rect.top + rect.height / 2.0)
23 | ..close();
24 | }
25 |
26 | @override
27 | void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {}
28 |
29 | @override
30 | ShapeBorder scale(double t) {
31 | return CircleBorder().scale(t);
32 | }
33 | }
34 |
35 | // https://proandroiddev.com/a-deep-dive-into-floatingactionbutton-in-flutter-bf95bee11627
--------------------------------------------------------------------------------
/lib/gradient_background.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class GradientBackground extends StatelessWidget {
4 | final Widget child;
5 | final Color color;
6 |
7 | GradientBackground({required this.child, required this.color});
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | return AnimatedContainer(
12 | decoration: BoxDecoration(
13 | // Box decoration takes a gradient
14 | gradient: LinearGradient(
15 | // Where the linear gradient begins and ends
16 | begin: Alignment.topRight,
17 | end: Alignment.bottomLeft,
18 | // Add one stop for each color. Stops should increase from 0 to 1
19 | stops: [0.3, 0.5, 0.7, 0.9],
20 | colors: getColorList(color)),
21 | ),
22 | curve: Curves.linear,
23 | child: child,
24 | duration: Duration(milliseconds: 500),
25 | );
26 | }
27 |
28 | List getColorList(Color color) {
29 | if (color is MaterialColor) {
30 | return [
31 | color.shade300,
32 | color.shade600,
33 | color.shade700,
34 | color.shade900,
35 | ];
36 | } else {
37 | return List.filled(4, color);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:scoped_model/scoped_model.dart';
3 |
4 | import 'package:todo/scopedmodel/todo_list_model.dart';
5 | import 'package:todo/gradient_background.dart';
6 | import 'package:todo/task_progress_indicator.dart';
7 | import 'package:todo/page/add_task_screen.dart';
8 | import 'package:todo/model/hero_id_model.dart';
9 | import 'package:todo/model/task_model.dart';
10 | import 'package:todo/route/scale_route.dart';
11 | import 'package:todo/utils/color_utils.dart';
12 | import 'package:todo/utils/datetime_utils.dart';
13 | import 'package:todo/page/detail_screen.dart';
14 | import 'package:todo/component/todo_badge.dart';
15 | import 'package:todo/page/privacy_policy.dart';
16 | import 'package:todo/model/data/choice_card.dart';
17 |
18 | void main() => runApp(MyApp());
19 |
20 | class MyApp extends StatelessWidget {
21 | @override
22 | Widget build(BuildContext context) {
23 | var app = MaterialApp(
24 | title: 'Todo',
25 | debugShowCheckedModeBanner: false,
26 | theme: ThemeData(
27 | primarySwatch: Colors.deepPurple,
28 | textTheme: TextTheme(
29 | headline1: TextStyle(fontSize: 32.0, fontWeight: FontWeight.w400),
30 | subtitle1: TextStyle(fontSize: 28.0, fontWeight: FontWeight.w500),
31 | bodyText1: TextStyle(
32 | fontSize: 14.0,
33 | fontFamily: 'Hind',
34 | ),
35 | ),
36 | ),
37 | home: MyHomePage(title: ''),
38 | );
39 |
40 | return ScopedModel(
41 | model: TodoListModel(),
42 | child: app,
43 | );
44 | }
45 | }
46 |
47 | class MyHomePage extends StatefulWidget {
48 | MyHomePage({Key? key, required this.title}) : super(key: key);
49 |
50 | final String title;
51 |
52 | HeroId _generateHeroIds(Task task) {
53 | return HeroId(
54 | codePointId: 'code_point_id_${task.id}',
55 | progressId: 'progress_id_${task.id}',
56 | titleId: 'title_id_${task.id}',
57 | remainingTaskId: 'remaining_task_id_${task.id}',
58 | );
59 | }
60 |
61 | String currentDay(BuildContext context) {
62 | return DateTimeUtils.currentDay;
63 | }
64 |
65 | @override
66 | _MyHomePageState createState() => _MyHomePageState();
67 | }
68 |
69 | class _MyHomePageState extends State
70 | with SingleTickerProviderStateMixin {
71 | late AnimationController _controller;
72 | late Animation _animation;
73 | final GlobalKey _backdropKey = GlobalKey(debugLabel: 'Backdrop');
74 | late PageController _pageController;
75 | int _currentPageIndex = 0;
76 |
77 | @override
78 | void initState() {
79 | super.initState();
80 | _controller = AnimationController(
81 | vsync: this,
82 | duration: Duration(milliseconds: 300),
83 | );
84 | _animation = Tween(begin: 0.0, end: 1.0).animate(_controller);
85 | _pageController = PageController(initialPage: 0, viewportFraction: 0.8);
86 | }
87 |
88 | @override
89 | Widget build(BuildContext context) {
90 | return ScopedModelDescendant(
91 | builder: (BuildContext context, Widget? child, TodoListModel model) {
92 | var _isLoading = model.isLoading;
93 | var _tasks = model.tasks;
94 | var _todos = model.todos;
95 | var backgroundColor = _tasks.isEmpty || _tasks.length == _currentPageIndex
96 | ? Colors.blueGrey
97 | : ColorUtils.getColorFrom(id: _tasks[_currentPageIndex].color);
98 | if (!_isLoading) {
99 | // move the animation value towards upperbound only when loading is complete
100 | _controller.forward();
101 | }
102 | return GradientBackground(
103 | color: backgroundColor,
104 | child: Scaffold(
105 | backgroundColor: Colors.transparent,
106 | appBar: AppBar(
107 | title: Text(widget.title),
108 | centerTitle: true,
109 | elevation: 0.0,
110 | backgroundColor: Colors.transparent,
111 | actions: [
112 | PopupMenuButton(
113 | onSelected: (choice) {
114 | Navigator.of(context).push(MaterialPageRoute(
115 | builder: (BuildContext context) =>
116 | PrivacyPolicyScreen()));
117 | },
118 | itemBuilder: (BuildContext context) {
119 | return choices.map((Choice choice) {
120 | return PopupMenuItem(
121 | value: choice,
122 | child: Text(choice.title),
123 | );
124 | }).toList();
125 | },
126 | ),
127 | ],
128 | ),
129 | body: _isLoading
130 | ? Center(
131 | child: CircularProgressIndicator(
132 | strokeWidth: 1.0,
133 | valueColor: new AlwaysStoppedAnimation(Colors.white),
134 | ),
135 | )
136 | : FadeTransition(
137 | opacity: _animation,
138 | child: Column(
139 | crossAxisAlignment: CrossAxisAlignment.start,
140 | children: [
141 | Container(
142 | margin: EdgeInsets.only(top: 0.0, left: 56.0),
143 | child: Column(
144 | crossAxisAlignment: CrossAxisAlignment.start,
145 | children: [
146 | // ShadowImage(),
147 | Container(
148 | // margin: EdgeInsets.only(top: 22.0),
149 | child: Text(
150 | '${widget.currentDay(context)}',
151 | style: Theme.of(context)
152 | .textTheme
153 | .headline1
154 | ?.copyWith(color: Colors.white),
155 | ),
156 | ),
157 | Text(
158 | '${DateTimeUtils.currentDate} ${DateTimeUtils.currentMonth}',
159 | style: Theme.of(context)
160 | .textTheme
161 | .subtitle1
162 | ?.copyWith(
163 | color: Colors.white.withOpacity(0.7)),
164 | ),
165 | Container(height: 16.0),
166 | Text(
167 | 'You have ${_todos.where((todo) => todo.isCompleted == 0).length} tasks to complete',
168 | style: Theme.of(context)
169 | .textTheme
170 | .bodyText1
171 | ?.copyWith(
172 | color: Colors.white.withOpacity(0.7)),
173 | ),
174 | Container(
175 | height: 16.0,
176 | )
177 | // Container(
178 | // margin: EdgeInsets.only(top: 42.0),
179 | // child: Text(
180 | // 'TODAY : FEBURARY 13, 2019',
181 | // style: Theme.of(context)
182 | // .textTheme
183 | // .subtitle
184 | // .copyWith(color: Colors.white.withOpacity(0.8)),
185 | // ),
186 | // ),
187 | ],
188 | ),
189 | ),
190 | Expanded(
191 | key: _backdropKey,
192 | flex: 1,
193 | child: NotificationListener(
194 | onNotification: (notification) {
195 | if (notification is ScrollEndNotification) {
196 | print(
197 | "ScrollNotification = ${_pageController.page}");
198 | var currentPage =
199 | _pageController.page?.round().toInt() ?? 0;
200 | if (_currentPageIndex != currentPage) {
201 | setState(() => _currentPageIndex = currentPage);
202 | }
203 | }
204 | return true;
205 | },
206 | child: PageView.builder(
207 | controller: _pageController,
208 | itemBuilder: (BuildContext context, int index) {
209 | if (index == _tasks.length) {
210 | return AddPageCard(
211 | color: Colors.blueGrey,
212 | );
213 | } else {
214 | return TaskCard(
215 | backdropKey: _backdropKey,
216 | color: ColorUtils.getColorFrom(
217 | id: _tasks[index].color),
218 | getHeroIds: widget._generateHeroIds,
219 | getTaskCompletionPercent:
220 | model.getTaskCompletionPercent,
221 | getTotalTodos: model.getTotalTodosFrom,
222 | task: _tasks[index],
223 | );
224 | }
225 | },
226 | itemCount: _tasks.length + 1,
227 | ),
228 | ),
229 | ),
230 | Container(
231 | margin: EdgeInsets.only(bottom: 32.0),
232 | ),
233 | ],
234 | ),
235 | ),
236 | ),
237 | );
238 | });
239 | }
240 |
241 | @override
242 | void dispose() {
243 | _controller.dispose();
244 | super.dispose();
245 | }
246 | }
247 |
248 | class AddPageCard extends StatelessWidget {
249 | final Color color;
250 |
251 | const AddPageCard({Key? key, this.color = Colors.black}) : super(key: key);
252 |
253 | @override
254 | Widget build(BuildContext context) {
255 | return Card(
256 | shape: RoundedRectangleBorder(
257 | borderRadius: BorderRadius.circular(16.0),
258 | ),
259 | elevation: 4.0,
260 | margin: EdgeInsets.symmetric(vertical: 16.0, horizontal: 8.0),
261 | child: Material(
262 | borderRadius: BorderRadius.circular(16.0),
263 | color: Colors.white,
264 | child: InkWell(
265 | onTap: () {
266 | Navigator.push(
267 | context,
268 | MaterialPageRoute(
269 | builder: (context) => AddTaskScreen(),
270 | ),
271 | );
272 | },
273 | child: Padding(
274 | padding: EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0),
275 | child: Column(
276 | mainAxisAlignment: MainAxisAlignment.center,
277 | children: [
278 | Icon(
279 | Icons.add,
280 | size: 52.0,
281 | color: color,
282 | ),
283 | Container(
284 | height: 8.0,
285 | ),
286 | Text(
287 | 'Add Category',
288 | style: TextStyle(color: color),
289 | ),
290 | ],
291 | ),
292 | ),
293 | ),
294 | ),
295 | );
296 | }
297 | }
298 |
299 | typedef TaskGetter = V Function(T value);
300 |
301 | class TaskCard extends StatelessWidget {
302 | final GlobalKey backdropKey;
303 | final Task task;
304 | final Color color;
305 |
306 | final TaskGetter getTotalTodos;
307 | final TaskGetter getHeroIds;
308 | final TaskGetter getTaskCompletionPercent;
309 |
310 | TaskCard({
311 | required this.backdropKey,
312 | required this.color,
313 | required this.task,
314 | required this.getTotalTodos,
315 | required this.getHeroIds,
316 | required this.getTaskCompletionPercent,
317 | });
318 |
319 | @override
320 | Widget build(BuildContext context) {
321 | var heroIds = getHeroIds(task);
322 | return GestureDetector(
323 | onTap: () {
324 | final RenderBox? renderBox =
325 | backdropKey.currentContext?.findRenderObject() as RenderBox;
326 | var backDropHeight = renderBox?.size.height ?? 0;
327 | var bottomOffset = 60.0;
328 | var horizontalOffset = 52.0;
329 | var topOffset = MediaQuery.of(context).size.height - backDropHeight;
330 |
331 | var rect = RelativeRect.fromLTRB(
332 | horizontalOffset, topOffset, horizontalOffset, bottomOffset);
333 | Navigator.push(
334 | context,
335 | ScaleRoute(
336 | rect: rect,
337 | widget: DetailScreen(
338 | taskId: task.id,
339 | heroIds: heroIds,
340 | ),
341 | ),
342 | // MaterialPageRoute(
343 | // builder: (context) => DetailScreen(
344 | // taskId: task.id,
345 | // heroIds: heroIds,
346 | // ),
347 | // ),
348 | );
349 | },
350 | child: Card(
351 | shape: RoundedRectangleBorder(
352 | borderRadius: BorderRadius.circular(16.0),
353 | ),
354 | elevation: 4.0,
355 | margin: EdgeInsets.symmetric(vertical: 16.0, horizontal: 8.0),
356 | color: Colors.white,
357 | child: Padding(
358 | padding: EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0),
359 | child: Column(
360 | crossAxisAlignment: CrossAxisAlignment.start,
361 | mainAxisAlignment: MainAxisAlignment.end,
362 | children: [
363 | TodoBadge(
364 | id: heroIds.codePointId,
365 | codePoint: task.codePoint,
366 | color: ColorUtils.getColorFrom(
367 | id: task.color,
368 | ),
369 | ),
370 | Spacer(
371 | flex: 8,
372 | ),
373 | Container(
374 | margin: EdgeInsets.only(bottom: 4.0),
375 | child: Hero(
376 | tag: heroIds.remainingTaskId,
377 | child: Text(
378 | "${getTotalTodos(task)} Task",
379 | style: Theme.of(context)
380 | .textTheme
381 | .bodyText1
382 | ?.copyWith(color: Colors.grey[500]),
383 | ),
384 | ),
385 | ),
386 | Container(
387 | child: Hero(
388 | tag: heroIds.titleId,
389 | child: Text(task.name,
390 | style: Theme.of(context)
391 | .textTheme
392 | .subtitle1
393 | ?.copyWith(color: Colors.black54)),
394 | ),
395 | ),
396 | Spacer(),
397 | Hero(
398 | tag: heroIds.progressId,
399 | child: TaskProgressIndicator(
400 | color: color,
401 | progress: getTaskCompletionPercent(task),
402 | ),
403 | ),
404 | ],
405 | ),
406 | ),
407 | ),
408 | );
409 | }
410 | }
411 |
--------------------------------------------------------------------------------
/lib/model/data/choice_card.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class Choice {
4 | const Choice({required this.title, required this.icon});
5 |
6 | final String title;
7 | final IconData icon;
8 | }
9 |
10 | const List choices = const [
11 | const Choice(title: 'Privacy Policy', icon: Icons.vpn_key),
12 | ];
13 |
--------------------------------------------------------------------------------
/lib/model/hero_id_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:meta/meta.dart';
2 |
3 | class HeroId {
4 | final String progressId;
5 | final String titleId;
6 | final String codePointId;
7 | final String remainingTaskId;
8 |
9 | HeroId({
10 | required this.progressId,
11 | required this.titleId,
12 | required this.codePointId,
13 | required this.remainingTaskId,
14 | });
15 | }
16 |
--------------------------------------------------------------------------------
/lib/model/task_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | import 'package:todo/utils/uuid.dart';
5 |
6 | part 'task_model.g.dart';
7 |
8 | @JsonSerializable()
9 | class Task {
10 | String id;
11 | String name;
12 | int color;
13 | @JsonKey(name: 'code_point')
14 | int codePoint;
15 |
16 | Task(
17 | this.name, {
18 | required this.color,
19 | required this.codePoint,
20 | String? id,
21 | }) : this.id = id ?? Uuid().generateV4();
22 |
23 | /// A necessary factory constructor for creating a new User instance
24 | /// from a map. Pass the map to the generated `_$TaskFromJson()` constructor.
25 | /// The constructor is named after the source class, in this case User.
26 | factory Task.fromJson(Map json) => _$TaskFromJson(json);
27 |
28 | /// `toJson` is the convention for a class to declare support for serialization
29 | /// to JSON. The implementation simply calls the private, generated
30 | /// helper method `_$TaskFromJson`.
31 | Map toJson() => _$TaskToJson(this);
32 | }
33 |
--------------------------------------------------------------------------------
/lib/model/task_model.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'task_model.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | Task _$TaskFromJson(Map json) {
10 | return Task(json['name'] as String,
11 | color: json['color'] as int,
12 | codePoint: json['code_point'] as int,
13 | id: json['id'] as String);
14 | }
15 |
16 | Map _$TaskToJson(Task instance) => {
17 | 'id': instance.id,
18 | 'name': instance.name,
19 | 'color': instance.color,
20 | 'code_point': instance.codePoint
21 | };
22 |
--------------------------------------------------------------------------------
/lib/model/todo_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:meta/meta.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | import 'package:todo/utils/uuid.dart';
5 |
6 | part 'todo_model.g.dart';
7 |
8 | @JsonSerializable()
9 | class Todo {
10 | final String id, parent;
11 | final String name;
12 | @JsonKey(name: 'completed')
13 | final int isCompleted;
14 |
15 | Todo(this.name, {required this.parent, this.isCompleted = 0, String? id})
16 | : this.id = id ?? Uuid().generateV4();
17 |
18 | Todo copy({String? name, int? isCompleted, String? id, String? parent}) {
19 | return Todo(
20 | name ?? this.name,
21 | isCompleted: isCompleted ?? this.isCompleted,
22 | id: id ?? this.id,
23 | parent: parent ?? this.parent,
24 | );
25 | }
26 |
27 | /// A necessary factory constructor for creating a new User instance
28 | /// from a map. Pass the map to the generated `_$TodoFromJson()` constructor.
29 | /// The constructor is named after the source class, in this case User.
30 | factory Todo.fromJson(Map json) => _$TodoFromJson(json);
31 |
32 | /// `toJson` is the convention for a class to declare support for serialization
33 | /// to JSON. The implementation simply calls the private, generated
34 | /// helper method `_$TodoFromJson`.
35 | Map toJson() => _$TodoToJson(this);
36 | }
37 |
--------------------------------------------------------------------------------
/lib/model/todo_model.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'todo_model.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | Todo _$TodoFromJson(Map json) {
10 | return Todo(json['name'] as String,
11 | parent: json['parent'] as String,
12 | isCompleted: json['completed'] as int,
13 | id: json['id'] as String);
14 | }
15 |
16 | Map _$TodoToJson(Todo instance) => {
17 | 'id': instance.id,
18 | 'parent': instance.parent,
19 | 'name': instance.name,
20 | 'completed': instance.isCompleted
21 | };
22 |
--------------------------------------------------------------------------------
/lib/page/add_task_screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:scoped_model/scoped_model.dart';
3 |
4 | import 'package:todo/scopedmodel/todo_list_model.dart';
5 | import 'package:todo/model/task_model.dart';
6 | import 'package:todo/component/iconpicker/icon_picker_builder.dart';
7 | import 'package:todo/component/colorpicker/color_picker_builder.dart';
8 | import 'package:todo/utils/color_utils.dart';
9 |
10 | class AddTaskScreen extends StatefulWidget {
11 | AddTaskScreen();
12 |
13 | @override
14 | State createState() {
15 | return _AddTaskScreenState();
16 | }
17 | }
18 |
19 | class _AddTaskScreenState extends State {
20 | late String newTask;
21 | final GlobalKey _scaffoldKey = new GlobalKey();
22 | late Color taskColor;
23 | late IconData taskIcon;
24 |
25 | @override
26 | void initState() {
27 | super.initState();
28 | newTask = '';
29 | taskColor = ColorUtils.defaultColors[0];
30 | taskIcon = Icons.work;
31 | }
32 |
33 | @override
34 | Widget build(BuildContext context) {
35 | return ScopedModelDescendant(
36 | builder: (BuildContext context, Widget? child, TodoListModel model) {
37 | return Scaffold(
38 | key: _scaffoldKey,
39 | backgroundColor: Colors.white,
40 | appBar: AppBar(
41 | title: Text(
42 | 'New Category',
43 | style: TextStyle(color: Colors.black),
44 | ),
45 | centerTitle: true,
46 | elevation: 0,
47 | iconTheme: IconThemeData(color: Colors.black26),
48 | brightness: Brightness.light,
49 | backgroundColor: Colors.white,
50 | ),
51 | body: Container(
52 | constraints: BoxConstraints.expand(),
53 | padding: EdgeInsets.symmetric(horizontal: 36.0, vertical: 36.0),
54 | child: Column(
55 | crossAxisAlignment: CrossAxisAlignment.start,
56 | children: [
57 | Text(
58 | 'Category will help you group related task!',
59 | style: TextStyle(
60 | color: Colors.black38,
61 | fontWeight: FontWeight.w600,
62 | fontSize: 16.0),
63 | ),
64 | Container(
65 | height: 16.0,
66 | ),
67 | TextField(
68 | onChanged: (text) {
69 | setState(() => newTask = text);
70 | },
71 | cursorColor: taskColor,
72 | autofocus: true,
73 | decoration: InputDecoration(
74 | border: InputBorder.none,
75 | hintText: 'Category Name...',
76 | hintStyle: TextStyle(
77 | color: Colors.black26,
78 | )),
79 | style: TextStyle(
80 | color: Colors.black54,
81 | fontWeight: FontWeight.w500,
82 | fontSize: 36.0),
83 | ),
84 | Container(
85 | height: 26.0,
86 | ),
87 | Row(
88 | children: [
89 | ColorPickerBuilder(
90 | color: taskColor,
91 | onColorChanged: (newColor) =>
92 | setState(() => taskColor = newColor)),
93 | Container(
94 | width: 22.0,
95 | ),
96 | IconPickerBuilder(
97 | iconData: taskIcon,
98 | highlightColor: taskColor,
99 | action: (newIcon) =>
100 | setState(() => taskIcon = newIcon)),
101 | ],
102 | ),
103 | ],
104 | ),
105 | ),
106 | floatingActionButtonLocation:
107 | FloatingActionButtonLocation.centerFloat,
108 | floatingActionButton: Builder(
109 | builder: (BuildContext context) {
110 | return FloatingActionButton.extended(
111 | heroTag: 'fab_new_card',
112 | icon: Icon(Icons.save),
113 | backgroundColor: taskColor,
114 | label: Text('Create New Card'),
115 | onPressed: () {
116 | if (newTask.isEmpty) {
117 | final snackBar = SnackBar(
118 | content: Text(
119 | 'Ummm... It seems that you are trying to add an invisible task which is not allowed in this realm.'),
120 | backgroundColor: taskColor,
121 | );
122 | ScaffoldMessenger.of(context).showSnackBar(snackBar);
123 | // _scaffoldKey.currentState.showSnackBar(snackBar);
124 | } else {
125 | model.addTask(Task(newTask,
126 | codePoint: taskIcon.codePoint, color: taskColor.value));
127 | Navigator.pop(context);
128 | }
129 | },
130 | );
131 | },
132 | ),
133 | );
134 | },
135 | );
136 | }
137 | }
138 | // Reason for wraping fab with builder (to get scafold context)
139 | // https://stackoverflow.com/a/52123080/4934757
140 |
--------------------------------------------------------------------------------
/lib/page/add_todo_screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:scoped_model/scoped_model.dart';
3 |
4 | import 'package:todo/scopedmodel/todo_list_model.dart';
5 | import 'package:todo/model/todo_model.dart';
6 | import 'package:todo/utils/color_utils.dart';
7 | import 'package:todo/component/todo_badge.dart';
8 | import 'package:todo/model/hero_id_model.dart';
9 |
10 | class AddTodoScreen extends StatefulWidget {
11 | final String taskId;
12 | final HeroId heroIds;
13 |
14 | AddTodoScreen({
15 | required this.taskId,
16 | required this.heroIds,
17 | });
18 |
19 | @override
20 | State createState() {
21 | return _AddTodoScreenState();
22 | }
23 | }
24 |
25 | class _AddTodoScreenState extends State {
26 | late String newTask;
27 | final GlobalKey _scaffoldKey = new GlobalKey();
28 |
29 | @override
30 | void initState() {
31 | super.initState();
32 | newTask = '';
33 | }
34 |
35 | @override
36 | Widget build(BuildContext context) {
37 | return ScopedModelDescendant(
38 | builder: (BuildContext context, Widget? child, TodoListModel model) {
39 | if (model.tasks.isEmpty) {
40 | // Loading
41 | return Container(
42 | color: Colors.white,
43 | );
44 | }
45 |
46 | var _task = model.tasks.firstWhere((it) => it.id == widget.taskId);
47 | var _color = ColorUtils.getColorFrom(id: _task.color);
48 | return Scaffold(
49 | key: _scaffoldKey,
50 | backgroundColor: Colors.white,
51 | appBar: AppBar(
52 | title: Text(
53 | 'New Task',
54 | style: TextStyle(color: Colors.black),
55 | ),
56 | centerTitle: true,
57 | elevation: 0,
58 | iconTheme: IconThemeData(color: Colors.black26),
59 | brightness: Brightness.light,
60 | backgroundColor: Colors.white,
61 | ),
62 | body: Container(
63 | constraints: BoxConstraints.expand(),
64 | padding: EdgeInsets.symmetric(horizontal: 36.0, vertical: 36.0),
65 | child: Column(
66 | crossAxisAlignment: CrossAxisAlignment.start,
67 | children: [
68 | Text(
69 | 'What task are you planning to perfrom?',
70 | style: TextStyle(
71 | color: Colors.black38,
72 | fontWeight: FontWeight.w600,
73 | fontSize: 16.0),
74 | ),
75 | Container(
76 | height: 16.0,
77 | ),
78 | TextField(
79 | onChanged: (text) {
80 | setState(() => newTask = text);
81 | },
82 | cursorColor: _color,
83 | autofocus: true,
84 | decoration: InputDecoration(
85 | border: InputBorder.none,
86 | hintText: 'Your Task...',
87 | hintStyle: TextStyle(
88 | color: Colors.black26,
89 | )),
90 | style: TextStyle(
91 | color: Colors.black54,
92 | fontWeight: FontWeight.w500,
93 | fontSize: 36.0),
94 | ),
95 | Container(
96 | height: 26.0,
97 | ),
98 | Row(
99 | children: [
100 | TodoBadge(
101 | codePoint: _task.codePoint,
102 | color: _color,
103 | id: widget.heroIds.codePointId,
104 | size: 20.0,
105 | ),
106 | Container(
107 | width: 16.0,
108 | ),
109 | Hero(
110 | child: Text(
111 | _task.name,
112 | style: TextStyle(
113 | color: Colors.black38,
114 | fontWeight: FontWeight.w600,
115 | ),
116 | ),
117 | tag: "not_using_right_now", //widget.heroIds.titleId,
118 | ),
119 | ],
120 | )
121 | ],
122 | ),
123 | ),
124 | floatingActionButtonLocation:
125 | FloatingActionButtonLocation.centerFloat,
126 | floatingActionButton: Builder(
127 | builder: (BuildContext context) {
128 | return FloatingActionButton.extended(
129 | heroTag: 'fab_new_task',
130 | icon: Icon(Icons.add),
131 | backgroundColor: _color,
132 | label: Text('Create Task'),
133 | onPressed: () {
134 | if (newTask.isEmpty) {
135 | final snackBar = SnackBar(
136 | content: Text(
137 | 'Ummm... It seems that you are trying to add an invisible task which is not allowed in this realm.'),
138 | backgroundColor: _color,
139 | );
140 | ScaffoldMessenger.of(context).showSnackBar(snackBar);
141 | // _scaffoldKey.currentState.showSnackBar(snackBar);
142 | } else {
143 | model.addTodo(Todo(
144 | newTask,
145 | parent: _task.id,
146 | ));
147 | Navigator.pop(context);
148 | }
149 | },
150 | );
151 | },
152 | ),
153 | );
154 | },
155 | );
156 | }
157 | }
158 |
159 | // Reason for wraping fab with builder (to get scafold context)
160 | // https://stackoverflow.com/a/52123080/4934757
161 |
--------------------------------------------------------------------------------
/lib/page/detail_screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:scoped_model/scoped_model.dart';
3 |
4 | import 'package:todo/scopedmodel/todo_list_model.dart';
5 | import 'package:todo/task_progress_indicator.dart';
6 | import 'package:todo/component/todo_badge.dart';
7 | import 'package:todo/model/hero_id_model.dart';
8 | import 'package:todo/model/task_model.dart';
9 | import 'package:todo/utils/color_utils.dart';
10 | import 'package:todo/page/add_todo_screen.dart';
11 | import 'package:todo/page/edit_task_screen.dart';
12 |
13 | class DetailScreen extends StatefulWidget {
14 | final String taskId;
15 | final HeroId heroIds;
16 |
17 | DetailScreen({
18 | required this.taskId,
19 | required this.heroIds,
20 | });
21 |
22 | @override
23 | State createState() {
24 | return _DetailScreenState();
25 | }
26 | }
27 |
28 | class _DetailScreenState extends State
29 | with SingleTickerProviderStateMixin {
30 | late AnimationController _controller;
31 | late Animation _animation;
32 |
33 | @override
34 | void initState() {
35 | super.initState();
36 | _controller = AnimationController(
37 | vsync: this,
38 | duration: Duration(milliseconds: 300),
39 | );
40 | _animation = Tween(begin: Offset(0, 1.0), end: Offset(0.0, 0.0))
41 | .animate(_controller);
42 | }
43 |
44 | // getContainer(bool isCompleted, {Widget child}) {
45 | // if (isCompleted) {
46 | // return Container(
47 | // padding: EdgeInsets.only(left: 22.0, right: 22.0),
48 | // decoration: BoxDecoration(
49 | // gradient: LinearGradient(
50 | // begin: Alignment.centerLeft,
51 | // end: Alignment.centerRight,
52 | // stops: [0.4, 0.6, 1],
53 | // colors: [
54 | // Colors.grey.shade100,
55 | // Colors.grey.shade50,
56 | // Colors.white,
57 | // ],
58 | // ),
59 | // ),
60 | // child: child,
61 | // );
62 | // } else {
63 | // return Container(
64 | // padding: EdgeInsets.only(left: 22.0, right: 22.0),
65 | // child: child,
66 | // );
67 | // }
68 | // }
69 |
70 | @override
71 | Widget build(BuildContext context) {
72 | _controller.forward();
73 | return ScopedModelDescendant(
74 | builder: (BuildContext context, Widget? child, TodoListModel model) {
75 | Task _task;
76 |
77 | try {
78 | _task = model.tasks.firstWhere((it) => it.id == widget.taskId);
79 | } catch (e) {
80 | return Container(
81 | color: Colors.white,
82 | );
83 | }
84 |
85 | var _todos =
86 | model.todos.where((it) => it.parent == widget.taskId).toList();
87 | var _hero = widget.heroIds;
88 | var _color = ColorUtils.getMaterialColorFrom(id: _task.color);
89 | var _icon = IconData(_task.codePoint, fontFamily: 'MaterialIcons');
90 |
91 | return Theme(
92 | data: ThemeData(primarySwatch: _color),
93 | child: Scaffold(
94 | backgroundColor: Colors.white,
95 | appBar: AppBar(
96 | elevation: 0,
97 | iconTheme: IconThemeData(color: Colors.black26),
98 | brightness: Brightness.light,
99 | backgroundColor: Colors.white,
100 | actions: [
101 | IconButton(
102 | icon: Icon(Icons.edit),
103 | color: _color,
104 | onPressed: () {
105 | Navigator.push(
106 | context,
107 | MaterialPageRoute(
108 | builder: (context) => EditTaskScreen(
109 | taskId: _task.id,
110 | taskName: _task.name,
111 | icon: _icon,
112 | color: _color,
113 | ),
114 | ),
115 | );
116 | },
117 | ),
118 | SimpleAlertDialog(
119 | color: _color,
120 | onActionPressed: () => model.removeTask(_task),
121 | ),
122 | ],
123 | ),
124 | body: Padding(
125 | padding: EdgeInsets.symmetric(horizontal: 0.0, vertical: 8.0),
126 | child: Column(children: [
127 | Container(
128 | margin: EdgeInsets.symmetric(horizontal: 36.0, vertical: 0.0),
129 | height: 160,
130 | child: Column(
131 | crossAxisAlignment: CrossAxisAlignment.start,
132 | mainAxisAlignment: MainAxisAlignment.end,
133 | children: [
134 | TodoBadge(
135 | color: _color,
136 | codePoint: _task.codePoint,
137 | id: _hero.codePointId,
138 | ),
139 | Spacer(
140 | flex: 1,
141 | ),
142 | Container(
143 | margin: EdgeInsets.only(bottom: 4.0),
144 | child: Hero(
145 | tag: _hero.remainingTaskId,
146 | child: Text(
147 | "${model.getTotalTodosFrom(_task)} Task",
148 | style: Theme.of(context)
149 | .textTheme
150 | .bodyText1
151 | ?.copyWith(color: Colors.grey[500]),
152 | ),
153 | ),
154 | ),
155 | Container(
156 | child: Hero(
157 | tag: 'title_hero_unused', //_hero.titleId,
158 | child: Text(_task.name,
159 | style: Theme.of(context)
160 | .textTheme
161 | .subtitle1
162 | ?.copyWith(color: Colors.black54)),
163 | ),
164 | ),
165 | Spacer(),
166 | Hero(
167 | tag: _hero.progressId,
168 | child: TaskProgressIndicator(
169 | color: _color,
170 | progress: model.getTaskCompletionPercent(_task),
171 | ),
172 | )
173 | ],
174 | ),
175 | ),
176 | Expanded(
177 | child: Padding(
178 | padding: EdgeInsets.only(top: 16.0),
179 | child: ListView.builder(
180 | itemBuilder: (BuildContext context, int index) {
181 | if (index == _todos.length) {
182 | return SizedBox(
183 | height: 56, // size of FAB
184 | );
185 | }
186 | var todo = _todos[index];
187 | return Container(
188 | padding: EdgeInsets.only(left: 22.0, right: 22.0),
189 | child: ListTile(
190 | onTap: () => model.updateTodo(todo.copy(
191 | isCompleted: todo.isCompleted == 1 ? 0 : 1)),
192 | contentPadding: EdgeInsets.symmetric(
193 | horizontal: 0, vertical: 8.0),
194 | leading: Checkbox(
195 | onChanged: (value) => model.updateTodo(todo
196 | .copy(isCompleted: value == true ? 1 : 0)),
197 | value: todo.isCompleted == 1 ? true : false),
198 | trailing: IconButton(
199 | icon: Icon(Icons.delete_outline),
200 | onPressed: () => model.removeTodo(todo),
201 | ),
202 | title: Text(
203 | todo.name,
204 | style: TextStyle(
205 | fontSize: 18.0,
206 | fontWeight: FontWeight.w600,
207 | color: todo.isCompleted == 1
208 | ? _color
209 | : Colors.black54,
210 | decoration: todo.isCompleted == 1
211 | ? TextDecoration.lineThrough
212 | : TextDecoration.none,
213 | ),
214 | ),
215 | ),
216 | );
217 | },
218 | itemCount: _todos.length + 1,
219 | ),
220 | ),
221 | ),
222 | ]),
223 | ),
224 | floatingActionButton: FloatingActionButton(
225 | heroTag: 'fab_new_task',
226 | onPressed: () {
227 | Navigator.push(
228 | context,
229 | MaterialPageRoute(
230 | builder: (context) =>
231 | AddTodoScreen(taskId: widget.taskId, heroIds: _hero),
232 | ),
233 | );
234 | },
235 | tooltip: 'New Todo',
236 | backgroundColor: _color,
237 | foregroundColor: Colors.white,
238 | child: Icon(Icons.add),
239 | ),
240 | ),
241 | );
242 | },
243 | );
244 | }
245 |
246 | @override
247 | void dispose() {
248 | _controller.dispose();
249 | super.dispose();
250 | }
251 | }
252 |
253 | typedef void Callback();
254 |
255 | class SimpleAlertDialog extends StatelessWidget {
256 | final Color color;
257 | final Callback onActionPressed;
258 |
259 | SimpleAlertDialog({
260 | required this.color,
261 | required this.onActionPressed,
262 | });
263 |
264 | @override
265 | Widget build(BuildContext context) {
266 | return IconButton(
267 | color: color,
268 | icon: Icon(Icons.delete),
269 | onPressed: () {
270 | showDialog(
271 | context: context,
272 | barrierDismissible: false, // user must tap button!
273 | builder: (BuildContext context) {
274 | return AlertDialog(
275 | title: Text('Delete this card?'),
276 | content: SingleChildScrollView(
277 | child: ListBody(
278 | children: [
279 | Text(
280 | 'This is a one way street! Deleting this will remove all the task assigned in this card.'),
281 | ],
282 | ),
283 | ),
284 | actions: [
285 | TextButton(
286 | child: Text('Delete'),
287 | onPressed: () {
288 | Navigator.of(context).pop();
289 | Navigator.of(context).pop();
290 | onActionPressed();
291 | },
292 | ),
293 | TextButton(
294 | child: Text('Cancel'),
295 | style: TextButton.styleFrom(foregroundColor: Colors.grey),
296 | onPressed: () {
297 | Navigator.of(context).pop();
298 | },
299 | ),
300 | ],
301 | );
302 | },
303 | );
304 | },
305 | );
306 | }
307 | }
308 |
--------------------------------------------------------------------------------
/lib/page/edit_task_screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:scoped_model/scoped_model.dart';
3 |
4 | import 'package:todo/scopedmodel/todo_list_model.dart';
5 | import 'package:todo/model/task_model.dart';
6 | import 'package:todo/component/iconpicker/icon_picker_builder.dart';
7 | import 'package:todo/component/colorpicker/color_picker_builder.dart';
8 |
9 | class EditTaskScreen extends StatefulWidget {
10 | final String taskId;
11 | final String taskName;
12 | final Color color;
13 | final IconData icon;
14 |
15 | EditTaskScreen({
16 | required this.taskId,
17 | required this.taskName,
18 | required this.color,
19 | required this.icon,
20 | });
21 |
22 | @override
23 | State createState() {
24 | return _EditCardScreenState();
25 | }
26 | }
27 |
28 | class _EditCardScreenState extends State {
29 | late String taskName;
30 | late Color taskColor;
31 | late IconData taskIcon;
32 |
33 | final btnSaveTitle = "Save Changes";
34 |
35 | final GlobalKey _scaffoldKey = new GlobalKey();
36 |
37 | @override
38 | void initState() {
39 | super.initState();
40 | taskName = widget.taskName;
41 | taskColor = widget.color;
42 | taskIcon = widget.icon;
43 | }
44 |
45 | @override
46 | Widget build(BuildContext context) {
47 | return ScopedModelDescendant(
48 | builder: (BuildContext context, Widget? child, TodoListModel model) {
49 | return Scaffold(
50 | key: _scaffoldKey,
51 | backgroundColor: Colors.white,
52 | appBar: AppBar(
53 | title: Text(
54 | 'Edit Category',
55 | style: TextStyle(
56 | color: Colors.black,
57 | ),
58 | ),
59 | centerTitle: true,
60 | elevation: 0,
61 | iconTheme: IconThemeData(
62 | color: Colors.black26,
63 | ),
64 | brightness: Brightness.light,
65 | backgroundColor: Colors.white,
66 | ),
67 | body: Container(
68 | constraints: BoxConstraints.expand(),
69 | padding: EdgeInsets.symmetric(
70 | horizontal: 36.0,
71 | vertical: 36.0,
72 | ),
73 | child: Column(
74 | crossAxisAlignment: CrossAxisAlignment.start,
75 | children: [
76 | Text(
77 | 'Category will help you group related task!',
78 | style: TextStyle(
79 | color: Colors.black38,
80 | fontWeight: FontWeight.w600,
81 | fontSize: 16.0,
82 | ),
83 | ),
84 | Container(
85 | height: 16.0,
86 | ),
87 | TextFormField(
88 | initialValue: taskName,
89 | onChanged: (text) {
90 | setState(
91 | () => taskName = text,
92 | );
93 | },
94 | cursorColor: taskColor,
95 | autofocus: true,
96 | decoration: InputDecoration(
97 | border: InputBorder.none,
98 | hintText: 'Category Name...',
99 | hintStyle: TextStyle(
100 | color: Colors.black26,
101 | )),
102 | style: TextStyle(
103 | color: Colors.black54,
104 | fontWeight: FontWeight.w500,
105 | fontSize: 36.0),
106 | ),
107 | Container(
108 | height: 26.0,
109 | ),
110 | Row(
111 | children: [
112 | ColorPickerBuilder(
113 | color: taskColor,
114 | onColorChanged: (newColor) => setState(
115 | () => taskColor = newColor,
116 | ),
117 | ),
118 | Container(
119 | width: 22.0,
120 | ),
121 | IconPickerBuilder(
122 | iconData: taskIcon,
123 | highlightColor: taskColor,
124 | action: (newIcon) => setState(
125 | () => taskIcon = newIcon,
126 | ),
127 | ),
128 | ],
129 | ),
130 | ],
131 | ),
132 | ),
133 | floatingActionButtonLocation:
134 | FloatingActionButtonLocation.centerFloat,
135 | floatingActionButton: Builder(
136 | builder: (BuildContext context) {
137 | return FloatingActionButton.extended(
138 | heroTag: 'fab_new_card',
139 | icon: Icon(Icons.save),
140 | backgroundColor: taskColor,
141 | label: Text(btnSaveTitle),
142 | onPressed: () {
143 | if (taskName.isEmpty) {
144 | final snackBar = SnackBar(
145 | content: Text(
146 | 'Ummm... It seems that you are trying to add an invisible task which is not allowed in this realm.'),
147 | backgroundColor: taskColor,
148 | );
149 | ScaffoldMessenger.of(context).showSnackBar(snackBar);
150 | // _scaffoldKey.currentState.showSnackBar(snackBar);
151 | } else {
152 | model.updateTask(
153 | Task(
154 | taskName,
155 | codePoint: taskIcon.codePoint,
156 | color: taskColor.value,
157 | id: widget.taskId,
158 | ),
159 | );
160 | Navigator.pop(context);
161 | }
162 | },
163 | );
164 | },
165 | ),
166 | );
167 | },
168 | );
169 | }
170 | }
171 |
172 | // Reason for wraping fab with builder (to get scafold context)
173 | // https://stackoverflow.com/a/52123080/4934757
174 |
--------------------------------------------------------------------------------
/lib/page/privacy_policy.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_markdown/flutter_markdown.dart';
3 |
4 | class PrivacyPolicyScreen extends StatelessWidget {
5 | @override
6 | Widget build(BuildContext context) {
7 | return Scaffold(
8 | backgroundColor: Colors.white,
9 | appBar: AppBar(
10 | title: Text(
11 | 'Privacy Policy',
12 | style: TextStyle(color: Colors.black),
13 | ),
14 | centerTitle: true,
15 | elevation: 0,
16 | iconTheme: IconThemeData(color: Colors.black26),
17 | brightness: Brightness.light,
18 | backgroundColor: Colors.white,
19 | ),
20 | body: Markdown(data: _PRIVACY_POLICY),
21 | );
22 | }
23 |
24 | static const _PRIVACY_POLICY = """
25 |
26 | Sabin Bajracharya built the Todo app as a Free app. This SERVICE is provided by Sabin Bajracharya at no cost and is intended for use as is.
27 |
28 | This page is used to inform visitors regarding my policies with the collection, use, and disclosure of Personal Information if anyone decided to use my Service.
29 |
30 | If you choose to use my Service, then you agree to the collection and use of information in relation to this policy. The Personal Information that I collect is used for providing and improving the Service. I will not use or share your information with anyone except as described in this Privacy Policy.
31 |
32 | The terms used in this Privacy Policy have the same meanings as in our Terms and Conditions, which is accessible at Todo unless otherwise defined in this Privacy Policy.
33 |
34 | **Information Collection and Use**
35 |
36 | For a better experience, while using our Service, I may require you to provide us with certain personally identifiable information. The information that I request will be retained on your device and is not collected by me in any way.
37 |
38 | The app does use third party services that may collect information used to identify you.
39 |
40 | Link to privacy policy of third party service providers used by the app
41 |
42 | * [Firebase Analytics](https://firebase.google.com/policies/analytics)
43 |
44 | **Log Data**
45 |
46 | I want to inform you that whenever you use my Service, in a case of an error in the app I collect data and information (through third party products) on your phone called Log Data. This Log Data may include information such as your device Internet Protocol (“IP”) address, device name, operating system version, the configuration of the app when utilizing my Service, the time and date of your use of the Service, and other statistics.
47 |
48 | **Cookies**
49 |
50 | Cookies are files with a small amount of data that are commonly used as anonymous unique identifiers. These are sent to your browser from the websites that you visit and are stored on your device's internal memory.
51 |
52 | This Service does not use these “cookies” explicitly. However, the app may use third party code and libraries that use “cookies” to collect information and improve their services. You have the option to either accept or refuse these cookies and know when a cookie is being sent to your device. If you choose to refuse our cookies, you may not be able to use some portions of this Service.
53 |
54 | **Service Providers**
55 |
56 | I may employ third-party companies and individuals due to the following reasons:
57 |
58 | * To facilitate our Service;
59 | * To provide the Service on our behalf;
60 | * To perform Service-related services; or
61 | * To assist us in analyzing how our Service is used.
62 |
63 | I want to inform users of this Service that these third parties have access to your Personal Information. The reason is to perform the tasks assigned to them on our behalf. However, they are obligated not to disclose or use the information for any other purpose.
64 |
65 | **Security**
66 |
67 | I value your trust in providing us your Personal Information, thus we are striving to use commercially acceptable means of protecting it. But remember that no method of transmission over the internet, or method of electronic storage is 100% secure and reliable, and I cannot guarantee its absolute security.
68 |
69 | **Links to Other Sites**
70 |
71 | This Service may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by me. Therefore, I strongly advise you to review the Privacy Policy of these websites. I have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services.
72 |
73 | **Children’s Privacy**
74 |
75 | These Services do not address anyone under the age of 13\. I do not knowingly collect personally identifiable information from children under 13\. In the case I discover that a child under 13 has provided me with personal information, I immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact me so that I will be able to do necessary actions.
76 |
77 | **Changes to This Privacy Policy**
78 |
79 | I may update our Privacy Policy from time to time. Thus, you are advised to review this page periodically for any changes. I will notify you of any changes by posting the new Privacy Policy on this page. These changes are effective immediately after they are posted on this page.
80 |
81 | **Contact Us**
82 |
83 | If you have any questions or suggestions about my Privacy Policy, do not hesitate to contact me at birqueens@gmail.com
84 | """;
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/lib/route/scale_route.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | // class MaterialScaleRoute extends MaterialPageRoute {
4 | // final Widget widget;
5 |
6 | // MaterialScaleRoute({this.widget})
7 | // : super(
8 | // builder: (BuildContext context) {
9 | // return new ScaleTransition(
10 | // scale: new Tween(
11 | // begin: 0.6,
12 | // end: 1.0,
13 | // ).animate(
14 | // CurvedAnimation(
15 | // parent: animation,
16 | // curve: Interval(
17 | // 0.00,
18 | // 1.00,
19 | // curve: Curves.linear,
20 | // ),
21 | // ),
22 | // ),
23 | // child: widget,
24 | // );
25 | // },
26 | // );
27 | // }
28 |
29 | // class ScaleRoute extends PageRouteBuilder {
30 | // final Widget widget;
31 | // ScaleRoute({this.widget})
32 | // : super(pageBuilder: (
33 | // BuildContext context,
34 | // Animation animation,
35 | // Animation secondaryAnimation,
36 | // ) {
37 | // return widget;
38 | // }, transitionsBuilder: (
39 | // BuildContext context,
40 | // Animation animation,
41 | // Animation secondaryAnimation,
42 | // Widget child,
43 | // ) {
44 |
45 | // return new PositionedTransition(
46 | // // scale: new Tween(
47 | // // begin: 0,
48 | // // end: 1,
49 | // // ).animate(
50 | // // CurvedAnimation(
51 | // // parent: animation,
52 | // // curve: Interval(
53 | // // 0.00,
54 | // // 1.00,
55 | // // curve: Curves.linear,
56 | // // ),
57 | // // ),
58 | // // ),
59 | // child: child, rect: RelativeRectTween(
60 | // begin: RelativeRect.fromLTRB(
61 | // 0, 100, 0.0, 100),
62 | // end: RelativeRect.fromLTRB(0.0, 0.0, 0.0, 0.0),
63 | // ).animate(
64 | // animation
65 | // ),
66 | // );
67 | // }, transitionDuration: Duration(milliseconds: 300));
68 | // }
69 |
70 | class ScaleRoute extends PageRouteBuilder {
71 | final Widget widget;
72 | final RelativeRect rect;
73 | ScaleRoute({required this.widget, required this.rect})
74 | : super(
75 | pageBuilder: (BuildContext context, Animation animation,
76 | Animation secondaryAnimation) {
77 | return widget;
78 | },
79 | transitionsBuilder: (BuildContext context,
80 | Animation animation,
81 | Animation secondaryAnimation,
82 | Widget child) {
83 | return Stack(
84 | children: [
85 | Container(),
86 | PositionedTransition(
87 | child: child,
88 | rect: RelativeRectTween(
89 | begin: rect,
90 | end: RelativeRect.fromLTRB(0.0, 0.0, 0.0, 0.0),
91 | ).animate(animation),
92 | ),
93 | ],
94 | );
95 | },
96 | transitionDuration: Duration(milliseconds: 300),
97 | );
98 | }
99 | // Ref: https://medium.com/@agungsurya/create-custom-router-transition-in-flutter-using-pageroutebuilder-73a1a9c4a171
100 | // Ref: Tween: https://flutterbyexample.com/step-one-tweening/
101 |
--------------------------------------------------------------------------------
/lib/scopedmodel/todo_list_model.dart:
--------------------------------------------------------------------------------
1 | // import 'dart:convert';
2 | // import 'dart:io';
3 | import 'package:flutter/material.dart';
4 | import 'package:scoped_model/scoped_model.dart';
5 |
6 | // import 'package:objectdb/objectdb.dart';
7 |
8 | import 'package:todo/model/todo_model.dart';
9 | import 'package:todo/model/task_model.dart';
10 | import 'package:todo/db/db_provider.dart';
11 |
12 | class TodoListModel extends Model {
13 | // ObjectDB db;
14 | var _db = DBProvider.db;
15 | List get todos => _todos.toList();
16 | List get tasks => _tasks.toList();
17 | int getTaskCompletionPercent(Task task) =>
18 | _taskCompletionPercentage[task.id] ?? 0;
19 | int getTotalTodosFrom(Task task) =>
20 | todos.where((it) => it.parent == task.id).length;
21 | bool get isLoading => _isLoading;
22 |
23 | bool _isLoading = false;
24 | List _tasks = [];
25 | List _todos = [];
26 | Map _taskCompletionPercentage = Map();
27 |
28 | static TodoListModel of(BuildContext context) =>
29 | ScopedModel.of(context);
30 |
31 | @override
32 | void addListener(listener) {
33 | super.addListener(listener);
34 | // update data for every subscriber, especially for the first one
35 | _isLoading = true;
36 | loadTodos();
37 | notifyListeners();
38 | }
39 |
40 | void loadTodos() async {
41 | var isNew = !await DBProvider.db.dbExists();
42 | if (isNew) {
43 | await _db.insertBulkTask(_db.tasks);
44 | await _db.insertBulkTodo(_db.todos);
45 | }
46 | _tasks = await _db.getAllTask();
47 | _todos = await _db.getAllTodo();
48 | _tasks.forEach((it) => _calcTaskCompletionPercent(it.id));
49 | _isLoading = false;
50 | await Future.delayed(Duration(milliseconds: 300));
51 | notifyListeners();
52 | }
53 |
54 | @override
55 | void removeListener(listener) {
56 | super.removeListener(listener);
57 | print("remove listner called");
58 | // DBProvider.db.closeDB();
59 | }
60 |
61 | void addTask(Task task) {
62 | _tasks.add(task);
63 | _calcTaskCompletionPercent(task.id);
64 | _db.insertTask(task);
65 | notifyListeners();
66 | }
67 |
68 | void removeTask(Task task) {
69 | _db.removeTask(task).then((_) {
70 | _tasks.removeWhere((it) => it.id == task.id);
71 | _todos.removeWhere((it) => it.parent == task.id);
72 | notifyListeners();
73 | });
74 | }
75 |
76 | void updateTask(Task task) {
77 | var oldTask = _tasks.firstWhere((it) => it.id == task.id);
78 | var replaceIndex = _tasks.indexOf(oldTask);
79 | _tasks.replaceRange(replaceIndex, replaceIndex + 1, [task]);
80 | _db.updateTask(task);
81 | notifyListeners();
82 | }
83 |
84 | void removeTodo(Todo todo) {
85 | _todos.removeWhere((it) => it.id == todo.id);
86 | _syncJob(todo);
87 | _db.removeTodo(todo);
88 | notifyListeners();
89 | }
90 |
91 | void addTodo(Todo todo) {
92 | _todos.add(todo);
93 | _syncJob(todo);
94 | _db.insertTodo(todo);
95 | notifyListeners();
96 | }
97 |
98 | void updateTodo(Todo todo) {
99 | var oldTodo = _todos.firstWhere((it) => it.id == todo.id);
100 | var replaceIndex = _todos.indexOf(oldTodo);
101 | _todos.replaceRange(replaceIndex, replaceIndex + 1, [todo]);
102 |
103 | _syncJob(todo);
104 | _db.updateTodo(todo);
105 |
106 | notifyListeners();
107 | }
108 |
109 | _syncJob(Todo todo) {
110 | _calcTaskCompletionPercent(todo.parent);
111 | // _syncTodoToDB();
112 | }
113 |
114 | void _calcTaskCompletionPercent(String taskId) {
115 | var todos = this.todos.where((it) => it.parent == taskId);
116 | var totalTodos = todos.length;
117 |
118 | if (totalTodos == 0) {
119 | _taskCompletionPercentage[taskId] = 0;
120 | } else {
121 | var totalCompletedTodos = todos.where((it) => it.isCompleted == 1).length;
122 | _taskCompletionPercentage[taskId] =
123 | (totalCompletedTodos / totalTodos * 100).toInt();
124 | }
125 | // return todos.fold(0, (total, todo) => todo.isCompleted ? total + scoreOfTask : total);
126 | }
127 |
128 | // Future _syncTodoToDB() async {
129 | // return await db.update({'user': 'guest'}, {'todos': _todos});
130 | // }
131 | }
132 |
--------------------------------------------------------------------------------
/lib/shadow_image.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class ShadowImage extends StatelessWidget {
4 | @override
5 | Widget build(BuildContext context) {
6 | return Container(
7 | decoration: BoxDecoration(
8 | shape: BoxShape.circle,
9 | color: Colors.white,
10 | boxShadow: [
11 | BoxShadow(
12 | color: Colors.black.withOpacity(0.6),
13 | blurRadius: 25.0, // has the effect of softening the shadow
14 | spreadRadius: 0.0, // has the effect of extending the shadow
15 | offset: Offset(
16 | 0.0, // horizontal, move right 10
17 | 8.0, // vertical, move down 10
18 | ),
19 | ),
20 | ],
21 | ),
22 | child: ClipOval(
23 | child: Image.network(
24 | 'https://content-static.upwork.com/uploads/2014/10/01073427/profilephoto1.jpg',
25 | height: 52,
26 | width: 52,
27 | fit: BoxFit.cover,
28 | ),
29 | ),
30 | );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/lib/task_progress_indicator.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class TaskProgressIndicator extends StatelessWidget {
4 | final Color color;
5 | final progress;
6 |
7 | final _height = 3.0;
8 |
9 | TaskProgressIndicator({required this.color, required this.progress});
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return Row(
14 | children: [
15 | Expanded(
16 | child: LayoutBuilder(
17 | builder: (BuildContext context, BoxConstraints constraints) {
18 | return Stack(
19 | children: [
20 | Container(
21 | height: _height,
22 | color: Colors.grey.withOpacity(0.1),
23 | ),
24 | AnimatedContainer(
25 | height: _height,
26 | width: (progress / 100) * constraints.maxWidth,
27 | color: color,
28 | duration: Duration(milliseconds: 300),
29 | ),
30 | ],
31 | );
32 | },
33 | ),
34 | ),
35 | Container(
36 | margin: EdgeInsets.only(left: 8.0),
37 | child: Text(
38 | "$progress%",
39 | style: Theme.of(context).textTheme.caption,
40 | ),
41 | )
42 | ],
43 | );
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/lib/utils/color_utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class ColorUtils {
4 | static const List defaultColors = [
5 | Colors.blueGrey,
6 | Colors.red,
7 | Colors.pink,
8 | Colors.purple,
9 | Colors.deepPurple,
10 | Colors.indigo,
11 | Colors.blue,
12 | Colors.lightBlue,
13 | Colors.cyan,
14 | Colors.teal,
15 | Colors.green,
16 | Colors.lightGreen,
17 | Colors.lime,
18 | Colors.yellow,
19 | Colors.amber,
20 | Colors.orange,
21 | Colors.deepOrange,
22 | Colors.brown,
23 | Colors.grey,
24 | ];
25 |
26 | static Map _color = {
27 | 50: Color.fromRGBO(136, 14, 79, .1),
28 | 100: Color.fromRGBO(136, 14, 79, .2),
29 | 200: Color.fromRGBO(136, 14, 79, .3),
30 | 300: Color.fromRGBO(136, 14, 79, .4),
31 | 400: Color.fromRGBO(136, 14, 79, .5),
32 | 500: Color.fromRGBO(136, 14, 79, .6),
33 | 600: Color.fromRGBO(136, 14, 79, .7),
34 | 700: Color.fromRGBO(136, 14, 79, .8),
35 | 800: Color.fromRGBO(136, 14, 79, .9),
36 | 900: Color.fromRGBO(136, 14, 79, 1),
37 | };
38 |
39 | static Map _colors = Map();
40 |
41 | static Map get colors {
42 | if (_colors.isNotEmpty) {
43 | return _colors;
44 | }
45 |
46 | defaultColors.forEach((color) {
47 | _colors[color.value] = color;
48 | });
49 | return _colors;
50 | }
51 |
52 | static Color getColorFrom({required int id}) {
53 | return colors[id] ?? Colors.blueGrey;
54 | }
55 |
56 | static MaterialColor getMaterialColorFrom({required int id}) {
57 | return MaterialColor((colors[id] ?? Colors.blueGrey).value, _color);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/lib/utils/datetime_utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:intl/intl.dart';
2 |
3 | class DateTimeUtils {
4 |
5 | static String get currentDay {
6 | DateTime now = DateTime.now();
7 | return DateFormat('EEEE').format(now);
8 | }
9 |
10 | static String get currentMonth {
11 | DateTime now = DateTime.now();
12 | return DateFormat('MMM').format(now);
13 | }
14 |
15 | static String get currentDate {
16 | DateTime now = DateTime.now();
17 | return DateFormat('d').format(now);
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/lib/utils/uuid.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2018 The Flutter Architecture Sample Authors. All rights reserved.
2 | // Use of this source code is governed by the MIT license that can be found
3 | // in the LICENSE file.
4 |
5 | import 'dart:math';
6 |
7 | /// A UUID generator, useful for generating unique IDs for your Todos.
8 | /// Shamelessly extracted from the Flutter source code.
9 | ///
10 | /// This will generate unique IDs in the format:
11 | ///
12 | /// f47ac10b-58cc-4372-a567-0e02b2c3d479
13 | ///
14 | /// ### Example
15 | ///
16 | /// final String id = Uuid().generateV4();
17 | class Uuid {
18 | final Random _random = Random();
19 |
20 | /// Generate a version 4 (random) uuid. This is a uuid scheme that only uses
21 | /// random numbers as the source of the generated uuid.
22 | String generateV4() {
23 | // Generate xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx / 8-4-4-4-12.
24 | final int special = 8 + _random.nextInt(4);
25 |
26 | return '${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}-'
27 | '${_bitsDigits(16, 4)}-'
28 | '4${_bitsDigits(12, 3)}-'
29 | '${_printDigits(special, 1)}${_bitsDigits(12, 3)}-'
30 | '${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}';
31 | }
32 |
33 | String _bitsDigits(int bitCount, int digitCount) =>
34 | _printDigits(_generateBits(bitCount), digitCount);
35 |
36 | int _generateBits(int bitCount) => _random.nextInt(1 << bitCount);
37 |
38 | String _printDigits(int value, int count) =>
39 | value.toRadixString(16).padLeft(count, '0');
40 | }
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: todo
2 | description: A new Flutter project.
3 |
4 | # The following defines the version and build number for your application.
5 | # A version number is three numbers separated by dots, like 1.2.43
6 | # followed by an optional build number separated by a +.
7 | # Both the version and the builder number may be overridden in flutter
8 | # build by specifying --build-name and --build-number, respectively.
9 | # In Android, build-name is used as versionName while build-number used as versionCode.
10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
12 | # Read more about iOS versioning at
13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
14 | version: 1.1.1+20191101
15 |
16 | environment:
17 | sdk: ">=2.12.0 <3.0.0"
18 |
19 | dependencies:
20 | flutter:
21 | sdk: flutter
22 | scoped_model: ^2.0.0-nullsafety.0
23 | # objectdb: ^1.0.5
24 | path_provider: ^2.0.9
25 | json_annotation: ^4.0.1
26 | sqflite: ^2.0.0+3
27 | flutter_colorpicker: ^1.0.3
28 | intl: ^0.17.0
29 | # firebase_analytics: ^2.0.2+1
30 | flutter_markdown: ^0.6.2
31 |
32 | # The following adds the Cupertino Icons font to your application.
33 | # Use with the CupertinoIcons class for iOS style icons.
34 | cupertino_icons: ^1.0.3
35 | sqflite_common_ffi:
36 |
37 | dev_dependencies:
38 | flutter_test:
39 | sdk: flutter
40 | build_runner: ^2.0.5
41 | json_serializable: ^4.1.3
42 |
43 | # For information on the generic Dart part of this file, see the
44 | # following page: https://www.dartlang.org/tools/pub/pubspec
45 |
46 | # The following section is specific to Flutter.
47 | flutter:
48 | # The following line ensures that the Material Icons font is
49 | # included with your application, so that you can use the icons in
50 | # the material Icons class.
51 | uses-material-design: true
52 |
53 | # To add assets to your application, add an assets section, like this:
54 | # assets:
55 | # - images/a_dot_burr.jpeg
56 | # - images/a_dot_ham.jpeg
57 |
58 | # An image asset can refer to one or more resolution-specific "variants", see
59 | # https://flutter.dev/assets-and-images/#resolution-aware.
60 |
61 | # For details regarding adding assets from package dependencies, see
62 | # https://flutter.dev/assets-and-images/#from-packages
63 |
64 | # To add custom fonts to your application, add a fonts section here,
65 | # in this "flutter" section. Each entry in this list should have a
66 | # "family" key with the font family name, and a "fonts" key with a
67 | # list giving the asset and other descriptors for the font. For
68 | # example:
69 | # fonts:
70 | # - family: Schyler
71 | # fonts:
72 | # - asset: fonts/Schyler-Regular.ttf
73 | # - asset: fonts/Schyler-Italic.ttf
74 | # style: italic
75 | # - family: Trajan Pro
76 | # fonts:
77 | # - asset: fonts/TrajanPro.ttf
78 | # - asset: fonts/TrajanPro_Bold.ttf
79 | # weight: 700
80 | #
81 | # For details regarding fonts from package dependencies,
82 | # see https://flutter.dev/custom-fonts/#from-packages
83 |
--------------------------------------------------------------------------------
/screenshots/screen01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/screenshots/screen01.png
--------------------------------------------------------------------------------
/screenshots/screen02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/screenshots/screen02.png
--------------------------------------------------------------------------------
/screenshots/screen03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/screenshots/screen03.png
--------------------------------------------------------------------------------
/screenshots/screen04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sabinbajracharya/fluttery-todo/e71447c0132be9b1f1e361a9039dbd057bb43f6a/screenshots/screen04.png
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 | import 'package:flutter_test/flutter_test.dart' as prefix0;
11 |
12 | import 'package:todo/main.dart';
13 |
14 | void main() {
15 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
16 | // Build our app and trigger a frame.
17 | await tester.pumpWidget(MyApp());
18 | expect(0,0);
19 |
20 | // // Verify that our counter starts at 0.
21 | // expect(find.text('0'), findsOneWidget);
22 | // expect(find.text('1'), findsNothing);
23 |
24 | // // Tap the '+' icon and trigger a frame.
25 | // await tester.tap(find.byIcon(Icons.add));
26 | // await tester.pump();
27 |
28 | // // Verify that our counter has incremented.
29 | // expect(find.text('0'), findsNothing);
30 | // expect(find.text('1'), findsOneWidget);
31 | });
32 | }
33 |
--------------------------------------------------------------------------------