├── .github └── workflows │ └── main.yml ├── .gitignore ├── .metadata ├── LICENSE ├── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── .project ├── .settings │ └── org.eclipse.buildship.core.prefs ├── app │ ├── .classpath │ ├── .project │ ├── .settings │ │ └── org.eclipse.buildship.core.prefs │ ├── build.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ └── com │ │ │ └── mono0926 │ │ │ └── taskshare │ │ │ └── MainActivity.kt │ │ └── res │ │ ├── drawable │ │ └── launch_background.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ └── values │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── draw └── design.xml ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ └── Icon-App-83.5x83.5@2x.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── Runner-Bridging-Header.h │ └── ja.lproj │ ├── LaunchScreen.strings │ └── Main.strings ├── lib ├── app.dart ├── bloc │ ├── account_bloc.dart │ └── account_bloc_provider.dart ├── l10n │ ├── intl_ja.arb │ ├── intl_messages.arb │ ├── l10n.dart │ ├── messages_all.dart │ ├── messages_ja.dart │ └── messages_messages.dart ├── lib.dart ├── main.dart ├── model │ ├── authenticator.dart │ ├── database.dart │ ├── group.dart │ ├── model.dart │ ├── service_provider.dart │ ├── task.dart │ └── tasks_store.dart ├── pages │ ├── home.dart │ ├── input_task.dart │ ├── setting.dart │ ├── task │ │ ├── add_task_button.dart │ │ ├── addition │ │ │ ├── task_addition_bloc.dart │ │ │ ├── task_addition_bloc_provider.dart │ │ │ └── task_input.dart │ │ ├── bottom_menu.dart │ │ ├── list │ │ │ ├── task_animated_list.dart │ │ │ ├── task_list.dart │ │ │ └── task_list_tile.dart │ │ ├── menu_button.dart │ │ ├── task_page.dart │ │ ├── task_page_state.dart │ │ ├── tasks_bloc.dart │ │ └── tasks_bloc_provider.dart │ └── welcome.dart ├── util │ ├── logger.dart │ └── util.dart └── widgets │ ├── app_progress_indicator.dart │ └── widgets.dart ├── pubspec.lock ├── pubspec.yaml ├── res └── values │ └── strings_en.arb └── test ├── model └── task_test.dart └── test.dart /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Add issue to projects 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | pull_request: 8 | types: 9 | - opened 10 | 11 | jobs: 12 | add-to-project: 13 | name: Add issue to projects 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Generate github token 17 | id: generate_token 18 | uses: tibdex/github-app-token@v1 19 | with: 20 | app_id: ${{ secrets.APP_ID }} 21 | private_key: ${{ secrets.PRIVATE_KEY }} 22 | - uses: actions/add-to-project@v0.2.0 23 | with: 24 | project-url: https://github.com/orgs/TaskShare/projects/2 25 | github-token: ${{ steps.generate_token.outputs.token }} 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .dart_tool/ 2 | .packages 3 | .pub/ 4 | build/ 5 | 6 | .flutter-plugins 7 | 8 | # Android Studio 9 | *.iml 10 | *.ipr 11 | *.iws 12 | .idea/ 13 | *.log 14 | 15 | ## Mac 16 | .DS_Store 17 | 18 | doc/api/ 19 | 20 | #Firebase 21 | GoogleService-Info.plist 22 | google-services.json 23 | /.history 24 | /.vscode 25 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: b931640c1d582fe51525b8c1b32641fb13b25d5c 8 | channel: master 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # taskshare 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | For help getting started with Flutter, view our online 8 | [documentation](https://flutter.io/). 9 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | analyzer: 2 | strong-mode: 3 | implicit-casts: false 4 | implicit-dynamic: false 5 | errors: 6 | # treat missing required parameters as a warning (not a hint) 7 | missing_required_param: warning 8 | # treat missing returns as a warning (not a hint) 9 | missing_return: warning 10 | todo: warning 11 | # Ignore analyzer hints for updating pubspecs when using Future or 12 | # Stream and not importing dart:async 13 | # Please see https://github.com/flutter/flutter/pull/24528 for details. 14 | sdk_version_async_exported_from_core: ignore 15 | exclude: 16 | - lib/l10n/messages_*.dart 17 | - ios/** 18 | linter: 19 | rules: 20 | - always_declare_return_types 21 | - always_put_control_body_on_new_line 22 | # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 23 | - always_require_non_null_named_parameters 24 | # - always_specify_types 25 | - annotate_overrides 26 | # - avoid_annotating_with_dynamic # conflicts with always_specify_types 27 | # - avoid_as 28 | - avoid_bool_literals_in_conditional_expressions # not yet tested 29 | - avoid_catches_without_on_clauses # we do this commonly 30 | - avoid_catching_errors # we do this commonly 31 | - avoid_classes_with_only_static_members 32 | - avoid_double_and_int_checks # only useful when targeting JS runtime 33 | - avoid_empty_else 34 | - avoid_field_initializers_in_const_classes 35 | - avoid_function_literals_in_foreach_calls 36 | - avoid_implementing_value_types # not yet tested 37 | - avoid_init_to_null 38 | - avoid_js_rounded_ints # only useful when targeting JS runtime 39 | - avoid_null_checks_in_equality_operators 40 | - avoid_positional_boolean_parameters # not yet tested 41 | - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) 42 | - avoid_relative_lib_imports 43 | - avoid_renaming_method_parameters 44 | - avoid_return_types_on_setters 45 | - avoid_returning_null # there are plenty of valid reasons to return null 46 | - avoid_returning_null_for_future # not yet tested 47 | - avoid_returning_null_for_void 48 | - avoid_returning_this # there are plenty of valid reasons to return this 49 | - avoid_setters_without_getters # not yet tested 50 | - avoid_shadowing_type_parameters # not yet tested 51 | - avoid_single_cascade_in_expression_statements # not yet tested 52 | - avoid_slow_async_io 53 | - avoid_types_as_parameter_names 54 | # - avoid_types_on_closure_parameters # conflicts with always_specify_types 55 | - avoid_unused_constructor_parameters 56 | # - avoid_void_async 57 | - await_only_futures 58 | - camel_case_types 59 | - cancel_subscriptions 60 | - cascade_invocations # not yet tested 61 | - close_sinks # not reliable enough 62 | - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 63 | - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 64 | - control_flow_in_finally 65 | - curly_braces_in_flow_control_structures # not yet tested 66 | - directives_ordering 67 | - empty_catches 68 | - empty_constructor_bodies 69 | - empty_statements 70 | - file_names # not yet tested 71 | - flutter_style_todos 72 | - hash_and_equals 73 | - implementation_imports 74 | - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 75 | - iterable_contains_unrelated_type 76 | - join_return_with_assignment # not yet tested 77 | - library_names 78 | - library_prefixes 79 | - lines_longer_than_80_chars # not yet tested 80 | - list_remove_unrelated_type 81 | - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 82 | - no_adjacent_strings_in_list 83 | - no_duplicate_case_values 84 | - non_constant_identifier_names 85 | - null_closures # not yet tested 86 | - omit_local_variable_types # opposite of always_specify_types 87 | - one_member_abstracts # too many false positives 88 | - only_throw_errors # https://github.com/flutter/flutter/issues/5792 89 | - overridden_fields 90 | - package_api_docs 91 | - package_names 92 | - package_prefixed_library_names 93 | - parameter_assignments # we do this commonly 94 | - prefer_adjacent_string_concatenation 95 | - prefer_asserts_in_initializer_lists 96 | - prefer_collection_literals 97 | - prefer_conditional_assignment 98 | - prefer_const_constructors 99 | - prefer_const_constructors_in_immutables 100 | - prefer_const_declarations 101 | - prefer_const_literals_to_create_immutables 102 | - prefer_constructors_over_static_methods # not yet tested 103 | - prefer_contains 104 | - prefer_equal_for_default_values 105 | # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods 106 | - prefer_final_fields 107 | - prefer_final_locals 108 | - prefer_foreach 109 | - prefer_function_declarations_over_variables # not yet tested 110 | - prefer_generic_function_type_aliases 111 | - prefer_initializing_formals 112 | - prefer_int_literals # not yet tested 113 | - prefer_interpolation_to_compose_strings # not yet tested 114 | - prefer_is_empty 115 | - prefer_is_not_empty 116 | - prefer_iterable_whereType 117 | # - prefer_mixin # https://github.com/dart-lang/language/issues/32 118 | - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 119 | - prefer_single_quotes 120 | - prefer_typing_uninitialized_variables 121 | - prefer_void_to_null 122 | # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml 123 | - recursive_getters 124 | - slash_for_doc_comments 125 | - sort_constructors_first 126 | - sort_pub_dependencies 127 | - sort_unnamed_constructors_first 128 | - test_types_in_equals 129 | - throw_in_finally 130 | - type_annotate_public_apis # subset of always_specify_types 131 | - type_init_formals 132 | - unawaited_futures # too many false positives 133 | - unnecessary_await_in_return # not yet tested 134 | - unnecessary_brace_in_string_interps 135 | - unnecessary_const 136 | - unnecessary_getters_setters 137 | - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 138 | - unnecessary_new 139 | - unnecessary_null_aware_assignments 140 | - unnecessary_null_in_if_null_operators 141 | - unnecessary_overrides 142 | - unnecessary_parenthesis 143 | - unnecessary_statements 144 | - unnecessary_this 145 | - unrelated_type_equality_checks 146 | - use_function_type_syntax_for_parameters # not yet tested 147 | - use_rethrow_when_possible 148 | - use_setters_to_change_properties # not yet tested 149 | - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 150 | - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review 151 | - valid_regexps 152 | - void_checks # not yet tested -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | *.class 3 | .gradle 4 | /local.properties 5 | /.idea/workspace.xml 6 | /.idea/libraries 7 | .DS_Store 8 | /build 9 | /captures 10 | GeneratedPluginRegistrant.java 11 | -------------------------------------------------------------------------------- /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 = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 27 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.mono0926.taskshare" 42 | minSdkVersion 16 43 | targetSdkVersion 27 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 47 | multiDexEnabled true 48 | } 49 | 50 | buildTypes { 51 | release { 52 | // TODO: Add your own signing config for the release build. 53 | // Signing with the debug keys for now, so `flutter run --release` works. 54 | signingConfig signingConfigs.debug 55 | } 56 | } 57 | } 58 | 59 | flutter { 60 | source '../..' 61 | } 62 | 63 | dependencies { 64 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" 65 | testImplementation 'junit:junit:4.12' 66 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 67 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 68 | compile 'com.google.firebase:firebase-core:16.0.0' 69 | implementation 'com.android.support:multidex:1.0.3' 70 | } 71 | 72 | apply plugin: 'com.google.gms.google-services' 73 | com.google.gms.googleservices.GoogleServicesPlugin.config.disableVersionCheck = true -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 9 | 10 | 15 | 19 | 26 | 30 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/mono0926/taskshare/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.mono0926.taskshare 2 | 3 | import android.os.Bundle 4 | 5 | import io.flutter.app.FlutterActivity 6 | import io.flutter.plugins.GeneratedPluginRegistrant 7 | 8 | class MainActivity(): FlutterActivity() { 9 | override fun onCreate(savedInstanceState: Bundle?) { 10 | super.onCreate(savedInstanceState) 11 | GeneratedPluginRegistrant.registerWith(this) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.2.30' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.1.3' 10 | classpath 'com.google.gms:google-services:4.0.0' 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | rootProject.buildDir = '../build' 23 | subprojects { 24 | project.buildDir = "${rootProject.buildDir}/${project.name}" 25 | } 26 | subprojects { 27 | project.evaluationDependsOn(':app') 28 | } 29 | 30 | task clean(type: Delete) { 31 | delete rootProject.buildDir 32 | } 33 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 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-4.4-all.zip 7 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /draw/design.xml: -------------------------------------------------------------------------------- 1 | dZFNE4IgEIZ/DXc+xpnuZnXp1KEzCQITug7iaP36NDBjLC7sPvvuvsyCWF6PR8dbfQYhLaJYjIjtEaWEEDxdM3lEgkkWiHJGRLaCi3nKRRhpb4TsEqEHsN60KSyhaWTpE8adgyGVVWBT15YruQGXktstvRrhdaC7DK/8JI3SizPBsXLj5V056Jvohyir3ieUa77MivpOcwHDF2IFYrkD8CGqx1zaebnL2kLf4U/1824nG/+jYQrW2VOS/CArXg== -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/app.flx 37 | /Flutter/app.zip 38 | /Flutter/flutter_assets/ 39 | /Flutter/App.framework 40 | /Flutter/Flutter.framework 41 | /Flutter/Generated.xcconfig 42 | /ServiceDefinitions.json 43 | 44 | Pods/ 45 | .symlinks/ 46 | -------------------------------------------------------------------------------- /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/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 | def parse_KV_file(file, separator='=') 8 | file_abs_path = File.expand_path(file) 9 | if !File.exists? file_abs_path 10 | return []; 11 | end 12 | pods_ary = [] 13 | skip_line_start_symbols = ["#", "/"] 14 | File.foreach(file_abs_path) { |line| 15 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 16 | plugin = line.split(pattern=separator) 17 | if plugin.length == 2 18 | podname = plugin[0].strip() 19 | path = plugin[1].strip() 20 | podpath = File.expand_path("#{path}", file_abs_path) 21 | pods_ary.push({:name => podname, :path => podpath}); 22 | else 23 | puts "Invalid plugin specification: #{line}" 24 | end 25 | } 26 | return pods_ary 27 | end 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | 32 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 33 | # referring to absolute paths on developers' machines. 34 | system('rm -rf .symlinks') 35 | system('mkdir -p .symlinks/plugins') 36 | 37 | # Flutter Pods 38 | generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') 39 | if generated_xcode_build_settings.empty? 40 | puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." 41 | end 42 | generated_xcode_build_settings.map { |p| 43 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR' 44 | symlink = File.join('.symlinks', 'flutter') 45 | File.symlink(File.dirname(p[:path]), symlink) 46 | pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) 47 | end 48 | } 49 | 50 | # Plugin Pods 51 | plugin_pods = parse_KV_file('../.flutter-plugins') 52 | plugin_pods.map { |p| 53 | symlink = File.join('.symlinks', 'plugins', p[:name]) 54 | File.symlink(p[:path], symlink) 55 | pod p[:name], :path => File.join(symlink, 'ios') 56 | } 57 | end 58 | 59 | post_install do |installer| 60 | installer.pods_project.targets.each do |target| 61 | target.build_configurations.each do |config| 62 | config.build_settings['ENABLE_BITCODE'] = 'NO' 63 | end 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - BoringSSL-GRPC (0.0.3): 3 | - BoringSSL-GRPC/Implementation (= 0.0.3) 4 | - BoringSSL-GRPC/Interface (= 0.0.3) 5 | - BoringSSL-GRPC/Implementation (0.0.3): 6 | - BoringSSL-GRPC/Interface (= 0.0.3) 7 | - BoringSSL-GRPC/Interface (0.0.3) 8 | - cloud_firestore (0.0.1): 9 | - Firebase/Auth 10 | - Firebase/Core 11 | - Firebase/Database 12 | - Firebase/Firestore 13 | - Flutter 14 | - Firebase/Auth (6.4.0): 15 | - Firebase/CoreOnly 16 | - FirebaseAuth (~> 6.2.0) 17 | - Firebase/Core (6.4.0): 18 | - Firebase/CoreOnly 19 | - FirebaseAnalytics (= 6.0.3) 20 | - Firebase/CoreOnly (6.4.0): 21 | - FirebaseCore (= 6.0.4) 22 | - Firebase/Database (6.4.0): 23 | - Firebase/CoreOnly 24 | - FirebaseDatabase (~> 6.0.0) 25 | - Firebase/Firestore (6.4.0): 26 | - Firebase/CoreOnly 27 | - FirebaseFirestore (~> 1.4.1) 28 | - firebase_auth (0.0.1): 29 | - Firebase/Auth 30 | - Firebase/Core 31 | - Flutter 32 | - firebase_core (0.0.1): 33 | - Firebase/Core 34 | - Flutter 35 | - FirebaseAnalytics (6.0.3): 36 | - FirebaseCore (~> 6.0) 37 | - FirebaseInstanceID (~> 4.2) 38 | - GoogleAppMeasurement (= 6.0.3) 39 | - GoogleUtilities/AppDelegateSwizzler (~> 6.0) 40 | - GoogleUtilities/MethodSwizzler (~> 6.0) 41 | - GoogleUtilities/Network (~> 6.0) 42 | - "GoogleUtilities/NSData+zlib (~> 6.0)" 43 | - nanopb (~> 0.3) 44 | - FirebaseAuth (6.2.0): 45 | - FirebaseAuthInterop (~> 1.0) 46 | - FirebaseCore (~> 6.0) 47 | - GoogleUtilities/AppDelegateSwizzler (~> 6.2) 48 | - GoogleUtilities/Environment (~> 6.2) 49 | - GTMSessionFetcher/Core (~> 1.1) 50 | - FirebaseAuthInterop (1.0.0) 51 | - FirebaseCore (6.0.4): 52 | - GoogleUtilities/Environment (~> 6.0) 53 | - GoogleUtilities/Logger (~> 6.0) 54 | - FirebaseDatabase (6.0.0): 55 | - FirebaseAuthInterop (~> 1.0) 56 | - FirebaseCore (~> 6.0) 57 | - leveldb-library (~> 1.18) 58 | - FirebaseFirestore (1.4.1): 59 | - FirebaseAuthInterop (~> 1.0) 60 | - FirebaseCore (~> 6.0) 61 | - FirebaseFirestore/abseil-cpp (= 1.4.1) 62 | - "gRPC-C++ (= 0.0.9)" 63 | - leveldb-library (~> 1.20) 64 | - nanopb (~> 0.3.901) 65 | - Protobuf (~> 3.1) 66 | - FirebaseFirestore/abseil-cpp (1.4.1): 67 | - FirebaseAuthInterop (~> 1.0) 68 | - FirebaseCore (~> 6.0) 69 | - "gRPC-C++ (= 0.0.9)" 70 | - leveldb-library (~> 1.20) 71 | - nanopb (~> 0.3.901) 72 | - Protobuf (~> 3.1) 73 | - FirebaseInstanceID (4.2.1): 74 | - FirebaseCore (~> 6.0) 75 | - GoogleUtilities/Environment (~> 6.0) 76 | - GoogleUtilities/UserDefaults (~> 6.0) 77 | - Flutter (1.0.0) 78 | - google_sign_in (0.0.1): 79 | - Flutter 80 | - GoogleSignIn (~> 4.0) 81 | - GoogleAppMeasurement (6.0.3): 82 | - GoogleUtilities/AppDelegateSwizzler (~> 6.0) 83 | - GoogleUtilities/MethodSwizzler (~> 6.0) 84 | - GoogleUtilities/Network (~> 6.0) 85 | - "GoogleUtilities/NSData+zlib (~> 6.0)" 86 | - nanopb (~> 0.3) 87 | - GoogleSignIn (4.4.0): 88 | - "GoogleToolboxForMac/NSDictionary+URLArguments (~> 2.1)" 89 | - "GoogleToolboxForMac/NSString+URLArguments (~> 2.1)" 90 | - GTMSessionFetcher/Core (~> 1.1) 91 | - GoogleToolboxForMac/DebugUtils (2.2.1): 92 | - GoogleToolboxForMac/Defines (= 2.2.1) 93 | - GoogleToolboxForMac/Defines (2.2.1) 94 | - "GoogleToolboxForMac/NSDictionary+URLArguments (2.2.1)": 95 | - GoogleToolboxForMac/DebugUtils (= 2.2.1) 96 | - GoogleToolboxForMac/Defines (= 2.2.1) 97 | - "GoogleToolboxForMac/NSString+URLArguments (= 2.2.1)" 98 | - "GoogleToolboxForMac/NSString+URLArguments (2.2.1)" 99 | - GoogleUtilities/AppDelegateSwizzler (6.2.3): 100 | - GoogleUtilities/Environment 101 | - GoogleUtilities/Logger 102 | - GoogleUtilities/Network 103 | - GoogleUtilities/Environment (6.2.3) 104 | - GoogleUtilities/Logger (6.2.3): 105 | - GoogleUtilities/Environment 106 | - GoogleUtilities/MethodSwizzler (6.2.3): 107 | - GoogleUtilities/Logger 108 | - GoogleUtilities/Network (6.2.3): 109 | - GoogleUtilities/Logger 110 | - "GoogleUtilities/NSData+zlib" 111 | - GoogleUtilities/Reachability 112 | - "GoogleUtilities/NSData+zlib (6.2.3)" 113 | - GoogleUtilities/Reachability (6.2.3): 114 | - GoogleUtilities/Logger 115 | - GoogleUtilities/UserDefaults (6.2.3): 116 | - GoogleUtilities/Logger 117 | - "gRPC-C++ (0.0.9)": 118 | - "gRPC-C++/Implementation (= 0.0.9)" 119 | - "gRPC-C++/Interface (= 0.0.9)" 120 | - "gRPC-C++/Implementation (0.0.9)": 121 | - "gRPC-C++/Interface (= 0.0.9)" 122 | - gRPC-Core (= 1.21.0) 123 | - nanopb (~> 0.3) 124 | - "gRPC-C++/Interface (0.0.9)" 125 | - gRPC-Core (1.21.0): 126 | - gRPC-Core/Implementation (= 1.21.0) 127 | - gRPC-Core/Interface (= 1.21.0) 128 | - gRPC-Core/Implementation (1.21.0): 129 | - BoringSSL-GRPC (= 0.0.3) 130 | - gRPC-Core/Interface (= 1.21.0) 131 | - nanopb (~> 0.3) 132 | - gRPC-Core/Interface (1.21.0) 133 | - GTMSessionFetcher/Core (1.2.2) 134 | - leveldb-library (1.20) 135 | - nanopb (0.3.901): 136 | - nanopb/decode (= 0.3.901) 137 | - nanopb/encode (= 0.3.901) 138 | - nanopb/decode (0.3.901) 139 | - nanopb/encode (0.3.901) 140 | - path_provider (0.0.1): 141 | - Flutter 142 | - Protobuf (3.9.0) 143 | - shared_preferences (0.0.1): 144 | - Flutter 145 | 146 | DEPENDENCIES: 147 | - cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`) 148 | - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`) 149 | - firebase_core (from `.symlinks/plugins/firebase_core/ios`) 150 | - Flutter (from `.symlinks/flutter/ios`) 151 | - google_sign_in (from `.symlinks/plugins/google_sign_in/ios`) 152 | - path_provider (from `.symlinks/plugins/path_provider/ios`) 153 | - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) 154 | 155 | SPEC REPOS: 156 | https://github.com/cocoapods/specs.git: 157 | - BoringSSL-GRPC 158 | - Firebase 159 | - FirebaseAnalytics 160 | - FirebaseAuth 161 | - FirebaseAuthInterop 162 | - FirebaseCore 163 | - FirebaseDatabase 164 | - FirebaseFirestore 165 | - FirebaseInstanceID 166 | - GoogleAppMeasurement 167 | - GoogleSignIn 168 | - GoogleToolboxForMac 169 | - GoogleUtilities 170 | - "gRPC-C++" 171 | - gRPC-Core 172 | - GTMSessionFetcher 173 | - leveldb-library 174 | - nanopb 175 | - Protobuf 176 | 177 | EXTERNAL SOURCES: 178 | cloud_firestore: 179 | :path: ".symlinks/plugins/cloud_firestore/ios" 180 | firebase_auth: 181 | :path: ".symlinks/plugins/firebase_auth/ios" 182 | firebase_core: 183 | :path: ".symlinks/plugins/firebase_core/ios" 184 | Flutter: 185 | :path: ".symlinks/flutter/ios" 186 | google_sign_in: 187 | :path: ".symlinks/plugins/google_sign_in/ios" 188 | path_provider: 189 | :path: ".symlinks/plugins/path_provider/ios" 190 | shared_preferences: 191 | :path: ".symlinks/plugins/shared_preferences/ios" 192 | 193 | SPEC CHECKSUMS: 194 | BoringSSL-GRPC: db8764df3204ccea016e1c8dd15d9a9ad63ff318 195 | cloud_firestore: cd6e849ecb8ab43e5a7a5f1f169304ca65436c03 196 | Firebase: 9445469655a98e9010737f4bc4720e5bda465873 197 | firebase_auth: 02ced56521bc9f220d40edda27b1ec5a2fcdf01e 198 | firebase_core: ce5006bb48508ee4e71e0f429a3f519bb8ee2961 199 | FirebaseAnalytics: 69fe25866d2ec87c6f02d72c3c9a82bce9c065a0 200 | FirebaseAuth: 68cfa47997f53d29ce978e7a615fb78d7925fcbe 201 | FirebaseAuthInterop: 0ffa57668be100582bb7643d4fcb7615496c41fc 202 | FirebaseCore: 7ea99e200f0024262650be56623fbe6a7bef1707 203 | FirebaseDatabase: f48e067716864be2b855cf716b927ef375d6cfa0 204 | FirebaseFirestore: f9d8dbe06cb1e50b5025d0d9ece41e173d0c7e00 205 | FirebaseInstanceID: 9782fcfb89e4d7da76cc28eac4b8543dc7be4a4b 206 | Flutter: 58dd7d1b27887414a370fcccb9e645c08ffd7a6a 207 | google_sign_in: 27e70a98b529f0b076d4b19f231b81da28b1750b 208 | GoogleAppMeasurement: 1e45fa601e6280c180880d57010390f6679cd971 209 | GoogleSignIn: 7ff245e1a7b26d379099d3243a562f5747e23d39 210 | GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55 211 | GoogleUtilities: d2b0e277a95962e09bb27f5cd42f5f0b6a506c7d 212 | "gRPC-C++": 9dfe7b44821e7b3e44aacad2af29d2c21f7cde83 213 | gRPC-Core: c9aef9a261a1247e881b18059b84d597293c9947 214 | GTMSessionFetcher: 61bb0f61a4cb560030f1222021178008a5727a23 215 | leveldb-library: 08cba283675b7ed2d99629a4bc5fd052cd2bb6a5 216 | nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 217 | path_provider: f96fff6166a8867510d2c25fdcc346327cc4b259 218 | Protobuf: 1097ca58584c8d9be81bfbf2c5ff5975648dd87a 219 | shared_preferences: 1feebfa37bb57264736e16865e7ffae7fc99b523 220 | 221 | PODFILE CHECKSUM: 7765ea4305eaab0b3dfd384c7de11902aa3195fd 222 | 223 | COCOAPODS: 1.7.3 224 | -------------------------------------------------------------------------------- /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 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 13 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 14 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 15 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 16 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 17 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 18 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 19 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 20 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 21 | D1B7301356EF5358BF6806D7 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEE4865E8C35E4F702B20AB3 /* Pods_Runner.framework */; }; 22 | FE6C8DF1213BE57900254CF1 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = FE6C8DF0213BE57900254CF1 /* GoogleService-Info.plist */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXCopyFilesBuildPhase section */ 26 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 27 | isa = PBXCopyFilesBuildPhase; 28 | buildActionMask = 2147483647; 29 | dstPath = ""; 30 | dstSubfolderSpec = 10; 31 | files = ( 32 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 33 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, 34 | ); 35 | name = "Embed Frameworks"; 36 | runOnlyForDeploymentPostprocessing = 0; 37 | }; 38 | /* End PBXCopyFilesBuildPhase section */ 39 | 40 | /* Begin PBXFileReference section */ 41 | 014BBB6662A65FEBC5B194D2 /* 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 = ""; }; 42 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 43 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 44 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 45 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 46 | 6BBBD955B4672455A5A5C7AE /* 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 = ""; }; 47 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 48 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 49 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 50 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 51 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 52 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 53 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 55 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 56 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 57 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | AB31D756A428D77D19260ED7 /* 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 = ""; }; 59 | AEE4865E8C35E4F702B20AB3 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 60 | FE6C8DEC213BE1E200254CF1 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Main.strings; sourceTree = ""; }; 61 | FE6C8DED213BE1E200254CF1 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/LaunchScreen.strings; sourceTree = ""; }; 62 | FE6C8DF0213BE57900254CF1 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 63 | /* End PBXFileReference section */ 64 | 65 | /* Begin PBXFrameworksBuildPhase section */ 66 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 67 | isa = PBXFrameworksBuildPhase; 68 | buildActionMask = 2147483647; 69 | files = ( 70 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 71 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 72 | D1B7301356EF5358BF6806D7 /* Pods_Runner.framework in Frameworks */, 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | /* End PBXFrameworksBuildPhase section */ 77 | 78 | /* Begin PBXGroup section */ 79 | 749DF0EE65D028FDE826F2BA /* Pods */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | AB31D756A428D77D19260ED7 /* Pods-Runner.debug.xcconfig */, 83 | 014BBB6662A65FEBC5B194D2 /* Pods-Runner.release.xcconfig */, 84 | 6BBBD955B4672455A5A5C7AE /* Pods-Runner.profile.xcconfig */, 85 | ); 86 | name = Pods; 87 | sourceTree = ""; 88 | }; 89 | 9740EEB11CF90186004384FC /* Flutter */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | 3B80C3931E831B6300D905FE /* App.framework */, 93 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 94 | 9740EEBA1CF902C7004384FC /* Flutter.framework */, 95 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 96 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 97 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 98 | ); 99 | name = Flutter; 100 | sourceTree = ""; 101 | }; 102 | 97C146E51CF9000F007C117D = { 103 | isa = PBXGroup; 104 | children = ( 105 | 9740EEB11CF90186004384FC /* Flutter */, 106 | 97C146F01CF9000F007C117D /* Runner */, 107 | 97C146EF1CF9000F007C117D /* Products */, 108 | 749DF0EE65D028FDE826F2BA /* Pods */, 109 | AB39B84943764B36D7B9074B /* Frameworks */, 110 | ); 111 | sourceTree = ""; 112 | }; 113 | 97C146EF1CF9000F007C117D /* Products */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 97C146EE1CF9000F007C117D /* Runner.app */, 117 | ); 118 | name = Products; 119 | sourceTree = ""; 120 | }; 121 | 97C146F01CF9000F007C117D /* Runner */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | FE6C8DF0213BE57900254CF1 /* GoogleService-Info.plist */, 125 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 126 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 127 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 128 | 97C147021CF9000F007C117D /* Info.plist */, 129 | 97C146F11CF9000F007C117D /* Supporting Files */, 130 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 131 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 132 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 133 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 134 | ); 135 | path = Runner; 136 | sourceTree = ""; 137 | }; 138 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | ); 142 | name = "Supporting Files"; 143 | sourceTree = ""; 144 | }; 145 | AB39B84943764B36D7B9074B /* Frameworks */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | AEE4865E8C35E4F702B20AB3 /* Pods_Runner.framework */, 149 | ); 150 | name = Frameworks; 151 | sourceTree = ""; 152 | }; 153 | /* End PBXGroup section */ 154 | 155 | /* Begin PBXNativeTarget section */ 156 | 97C146ED1CF9000F007C117D /* Runner */ = { 157 | isa = PBXNativeTarget; 158 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 159 | buildPhases = ( 160 | EA9990A76B210230E26F42C0 /* [CP] Check Pods Manifest.lock */, 161 | 9740EEB61CF901F6004384FC /* Run Script */, 162 | 97C146EA1CF9000F007C117D /* Sources */, 163 | 97C146EB1CF9000F007C117D /* Frameworks */, 164 | 97C146EC1CF9000F007C117D /* Resources */, 165 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 166 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 167 | DFD8A05A729D0A9793983C65 /* [CP] Embed Pods Frameworks */, 168 | 7FE1A93726962E5BFF750580 /* [CP] Copy Pods Resources */, 169 | ); 170 | buildRules = ( 171 | ); 172 | dependencies = ( 173 | ); 174 | name = Runner; 175 | productName = Runner; 176 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 177 | productType = "com.apple.product-type.application"; 178 | }; 179 | /* End PBXNativeTarget section */ 180 | 181 | /* Begin PBXProject section */ 182 | 97C146E61CF9000F007C117D /* Project object */ = { 183 | isa = PBXProject; 184 | attributes = { 185 | LastUpgradeCheck = 0910; 186 | ORGANIZATIONNAME = "The Chromium Authors"; 187 | TargetAttributes = { 188 | 97C146ED1CF9000F007C117D = { 189 | CreatedOnToolsVersion = 7.3.1; 190 | LastSwiftMigration = 0910; 191 | }; 192 | }; 193 | }; 194 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 195 | compatibilityVersion = "Xcode 3.2"; 196 | developmentRegion = English; 197 | hasScannedForEncodings = 0; 198 | knownRegions = ( 199 | English, 200 | en, 201 | Base, 202 | ja, 203 | ); 204 | mainGroup = 97C146E51CF9000F007C117D; 205 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 206 | projectDirPath = ""; 207 | projectRoot = ""; 208 | targets = ( 209 | 97C146ED1CF9000F007C117D /* Runner */, 210 | ); 211 | }; 212 | /* End PBXProject section */ 213 | 214 | /* Begin PBXResourcesBuildPhase section */ 215 | 97C146EC1CF9000F007C117D /* Resources */ = { 216 | isa = PBXResourcesBuildPhase; 217 | buildActionMask = 2147483647; 218 | files = ( 219 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 220 | FE6C8DF1213BE57900254CF1 /* GoogleService-Info.plist in Resources */, 221 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 222 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 223 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 224 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 225 | ); 226 | runOnlyForDeploymentPostprocessing = 0; 227 | }; 228 | /* End PBXResourcesBuildPhase section */ 229 | 230 | /* Begin PBXShellScriptBuildPhase section */ 231 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 232 | isa = PBXShellScriptBuildPhase; 233 | buildActionMask = 2147483647; 234 | files = ( 235 | ); 236 | inputPaths = ( 237 | ); 238 | name = "Thin Binary"; 239 | outputPaths = ( 240 | ); 241 | runOnlyForDeploymentPostprocessing = 0; 242 | shellPath = /bin/sh; 243 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; 244 | }; 245 | 7FE1A93726962E5BFF750580 /* [CP] Copy Pods Resources */ = { 246 | isa = PBXShellScriptBuildPhase; 247 | buildActionMask = 2147483647; 248 | files = ( 249 | ); 250 | inputPaths = ( 251 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh", 252 | "${PODS_ROOT}/GoogleSignIn/Resources/GoogleSignIn.bundle", 253 | ); 254 | name = "[CP] Copy Pods Resources"; 255 | outputPaths = ( 256 | "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleSignIn.bundle", 257 | ); 258 | runOnlyForDeploymentPostprocessing = 0; 259 | shellPath = /bin/sh; 260 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; 261 | showEnvVarsInLog = 0; 262 | }; 263 | 9740EEB61CF901F6004384FC /* Run Script */ = { 264 | isa = PBXShellScriptBuildPhase; 265 | buildActionMask = 2147483647; 266 | files = ( 267 | ); 268 | inputPaths = ( 269 | ); 270 | name = "Run Script"; 271 | outputPaths = ( 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | shellPath = /bin/sh; 275 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 276 | }; 277 | DFD8A05A729D0A9793983C65 /* [CP] Embed Pods Frameworks */ = { 278 | isa = PBXShellScriptBuildPhase; 279 | buildActionMask = 2147483647; 280 | files = ( 281 | ); 282 | inputPaths = ( 283 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", 284 | "${BUILT_PRODUCTS_DIR}/BoringSSL-GRPC/openssl_grpc.framework", 285 | "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework", 286 | "${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework", 287 | "${BUILT_PRODUCTS_DIR}/GoogleToolboxForMac/GoogleToolboxForMac.framework", 288 | "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework", 289 | "${BUILT_PRODUCTS_DIR}/Protobuf/Protobuf.framework", 290 | "${BUILT_PRODUCTS_DIR}/gRPC-C++/grpcpp.framework", 291 | "${BUILT_PRODUCTS_DIR}/gRPC-Core/grpc.framework", 292 | "${BUILT_PRODUCTS_DIR}/leveldb-library/leveldb.framework", 293 | "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework", 294 | "${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework", 295 | "${BUILT_PRODUCTS_DIR}/shared_preferences/shared_preferences.framework", 296 | ); 297 | name = "[CP] Embed Pods Frameworks"; 298 | outputPaths = ( 299 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl_grpc.framework", 300 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", 301 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework", 302 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleToolboxForMac.framework", 303 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework", 304 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Protobuf.framework", 305 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/grpcpp.framework", 306 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/grpc.framework", 307 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/leveldb.framework", 308 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework", 309 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework", 310 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences.framework", 311 | ); 312 | runOnlyForDeploymentPostprocessing = 0; 313 | shellPath = /bin/sh; 314 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 315 | showEnvVarsInLog = 0; 316 | }; 317 | EA9990A76B210230E26F42C0 /* [CP] Check Pods Manifest.lock */ = { 318 | isa = PBXShellScriptBuildPhase; 319 | buildActionMask = 2147483647; 320 | files = ( 321 | ); 322 | inputPaths = ( 323 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 324 | "${PODS_ROOT}/Manifest.lock", 325 | ); 326 | name = "[CP] Check Pods Manifest.lock"; 327 | outputPaths = ( 328 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 329 | ); 330 | runOnlyForDeploymentPostprocessing = 0; 331 | shellPath = /bin/sh; 332 | 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"; 333 | showEnvVarsInLog = 0; 334 | }; 335 | /* End PBXShellScriptBuildPhase section */ 336 | 337 | /* Begin PBXSourcesBuildPhase section */ 338 | 97C146EA1CF9000F007C117D /* Sources */ = { 339 | isa = PBXSourcesBuildPhase; 340 | buildActionMask = 2147483647; 341 | files = ( 342 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 343 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | }; 347 | /* End PBXSourcesBuildPhase section */ 348 | 349 | /* Begin PBXVariantGroup section */ 350 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 351 | isa = PBXVariantGroup; 352 | children = ( 353 | 97C146FB1CF9000F007C117D /* Base */, 354 | FE6C8DEC213BE1E200254CF1 /* ja */, 355 | ); 356 | name = Main.storyboard; 357 | sourceTree = ""; 358 | }; 359 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 360 | isa = PBXVariantGroup; 361 | children = ( 362 | 97C147001CF9000F007C117D /* Base */, 363 | FE6C8DED213BE1E200254CF1 /* ja */, 364 | ); 365 | name = LaunchScreen.storyboard; 366 | sourceTree = ""; 367 | }; 368 | /* End PBXVariantGroup section */ 369 | 370 | /* Begin XCBuildConfiguration section */ 371 | 97C147031CF9000F007C117D /* Debug */ = { 372 | isa = XCBuildConfiguration; 373 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 374 | buildSettings = { 375 | ALWAYS_SEARCH_USER_PATHS = NO; 376 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 377 | CLANG_ANALYZER_NONNULL = YES; 378 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 379 | CLANG_CXX_LIBRARY = "libc++"; 380 | CLANG_ENABLE_MODULES = YES; 381 | CLANG_ENABLE_OBJC_ARC = YES; 382 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 383 | CLANG_WARN_BOOL_CONVERSION = YES; 384 | CLANG_WARN_COMMA = YES; 385 | CLANG_WARN_CONSTANT_CONVERSION = YES; 386 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 387 | CLANG_WARN_EMPTY_BODY = YES; 388 | CLANG_WARN_ENUM_CONVERSION = YES; 389 | CLANG_WARN_INFINITE_RECURSION = YES; 390 | CLANG_WARN_INT_CONVERSION = YES; 391 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 392 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 393 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 394 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 395 | CLANG_WARN_STRICT_PROTOTYPES = YES; 396 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 397 | CLANG_WARN_UNREACHABLE_CODE = YES; 398 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 399 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 400 | COPY_PHASE_STRIP = NO; 401 | DEBUG_INFORMATION_FORMAT = dwarf; 402 | ENABLE_STRICT_OBJC_MSGSEND = YES; 403 | ENABLE_TESTABILITY = YES; 404 | GCC_C_LANGUAGE_STANDARD = gnu99; 405 | GCC_DYNAMIC_NO_PIC = NO; 406 | GCC_NO_COMMON_BLOCKS = YES; 407 | GCC_OPTIMIZATION_LEVEL = 0; 408 | GCC_PREPROCESSOR_DEFINITIONS = ( 409 | "DEBUG=1", 410 | "$(inherited)", 411 | ); 412 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 413 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 414 | GCC_WARN_UNDECLARED_SELECTOR = YES; 415 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 416 | GCC_WARN_UNUSED_FUNCTION = YES; 417 | GCC_WARN_UNUSED_VARIABLE = YES; 418 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 419 | MTL_ENABLE_DEBUG_INFO = YES; 420 | ONLY_ACTIVE_ARCH = YES; 421 | SDKROOT = iphoneos; 422 | TARGETED_DEVICE_FAMILY = "1,2"; 423 | }; 424 | name = Debug; 425 | }; 426 | 97C147041CF9000F007C117D /* Release */ = { 427 | isa = XCBuildConfiguration; 428 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 429 | buildSettings = { 430 | ALWAYS_SEARCH_USER_PATHS = NO; 431 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 432 | CLANG_ANALYZER_NONNULL = YES; 433 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 434 | CLANG_CXX_LIBRARY = "libc++"; 435 | CLANG_ENABLE_MODULES = YES; 436 | CLANG_ENABLE_OBJC_ARC = YES; 437 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 438 | CLANG_WARN_BOOL_CONVERSION = YES; 439 | CLANG_WARN_COMMA = YES; 440 | CLANG_WARN_CONSTANT_CONVERSION = YES; 441 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 442 | CLANG_WARN_EMPTY_BODY = YES; 443 | CLANG_WARN_ENUM_CONVERSION = YES; 444 | CLANG_WARN_INFINITE_RECURSION = YES; 445 | CLANG_WARN_INT_CONVERSION = YES; 446 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 447 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 448 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 449 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 450 | CLANG_WARN_STRICT_PROTOTYPES = YES; 451 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 452 | CLANG_WARN_UNREACHABLE_CODE = YES; 453 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 454 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 455 | COPY_PHASE_STRIP = NO; 456 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 457 | ENABLE_NS_ASSERTIONS = NO; 458 | ENABLE_STRICT_OBJC_MSGSEND = YES; 459 | GCC_C_LANGUAGE_STANDARD = gnu99; 460 | GCC_NO_COMMON_BLOCKS = YES; 461 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 462 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 463 | GCC_WARN_UNDECLARED_SELECTOR = YES; 464 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 465 | GCC_WARN_UNUSED_FUNCTION = YES; 466 | GCC_WARN_UNUSED_VARIABLE = YES; 467 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 468 | MTL_ENABLE_DEBUG_INFO = NO; 469 | SDKROOT = iphoneos; 470 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 471 | TARGETED_DEVICE_FAMILY = "1,2"; 472 | VALIDATE_PRODUCT = YES; 473 | }; 474 | name = Release; 475 | }; 476 | 97C147061CF9000F007C117D /* Debug */ = { 477 | isa = XCBuildConfiguration; 478 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 479 | buildSettings = { 480 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 481 | CLANG_ENABLE_MODULES = YES; 482 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 483 | ENABLE_BITCODE = NO; 484 | FRAMEWORK_SEARCH_PATHS = ( 485 | "$(inherited)", 486 | "$(PROJECT_DIR)/Flutter", 487 | ); 488 | INFOPLIST_FILE = Runner/Info.plist; 489 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 490 | LIBRARY_SEARCH_PATHS = ( 491 | "$(inherited)", 492 | "$(PROJECT_DIR)/Flutter", 493 | ); 494 | PRODUCT_BUNDLE_IDENTIFIER = com.mono0926.taskshare; 495 | PRODUCT_NAME = "$(TARGET_NAME)"; 496 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 497 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 498 | SWIFT_SWIFT3_OBJC_INFERENCE = On; 499 | SWIFT_VERSION = 4.0; 500 | VERSIONING_SYSTEM = "apple-generic"; 501 | }; 502 | name = Debug; 503 | }; 504 | 97C147071CF9000F007C117D /* Release */ = { 505 | isa = XCBuildConfiguration; 506 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 507 | buildSettings = { 508 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 509 | CLANG_ENABLE_MODULES = YES; 510 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 511 | ENABLE_BITCODE = NO; 512 | FRAMEWORK_SEARCH_PATHS = ( 513 | "$(inherited)", 514 | "$(PROJECT_DIR)/Flutter", 515 | ); 516 | INFOPLIST_FILE = Runner/Info.plist; 517 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 518 | LIBRARY_SEARCH_PATHS = ( 519 | "$(inherited)", 520 | "$(PROJECT_DIR)/Flutter", 521 | ); 522 | PRODUCT_BUNDLE_IDENTIFIER = com.mono0926.taskshare; 523 | PRODUCT_NAME = "$(TARGET_NAME)"; 524 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 525 | SWIFT_SWIFT3_OBJC_INFERENCE = On; 526 | SWIFT_VERSION = 4.0; 527 | VERSIONING_SYSTEM = "apple-generic"; 528 | }; 529 | name = Release; 530 | }; 531 | FE65FFE621B10FBA001D658A /* Profile */ = { 532 | isa = XCBuildConfiguration; 533 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 534 | buildSettings = { 535 | ALWAYS_SEARCH_USER_PATHS = NO; 536 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 537 | CLANG_ANALYZER_NONNULL = YES; 538 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 539 | CLANG_CXX_LIBRARY = "libc++"; 540 | CLANG_ENABLE_MODULES = YES; 541 | CLANG_ENABLE_OBJC_ARC = YES; 542 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 543 | CLANG_WARN_BOOL_CONVERSION = YES; 544 | CLANG_WARN_COMMA = YES; 545 | CLANG_WARN_CONSTANT_CONVERSION = YES; 546 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 547 | CLANG_WARN_EMPTY_BODY = YES; 548 | CLANG_WARN_ENUM_CONVERSION = YES; 549 | CLANG_WARN_INFINITE_RECURSION = YES; 550 | CLANG_WARN_INT_CONVERSION = YES; 551 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 552 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 553 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 554 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 555 | CLANG_WARN_STRICT_PROTOTYPES = YES; 556 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 557 | CLANG_WARN_UNREACHABLE_CODE = YES; 558 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 559 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 560 | COPY_PHASE_STRIP = NO; 561 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 562 | ENABLE_NS_ASSERTIONS = NO; 563 | ENABLE_STRICT_OBJC_MSGSEND = YES; 564 | GCC_C_LANGUAGE_STANDARD = gnu99; 565 | GCC_NO_COMMON_BLOCKS = YES; 566 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 567 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 568 | GCC_WARN_UNDECLARED_SELECTOR = YES; 569 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 570 | GCC_WARN_UNUSED_FUNCTION = YES; 571 | GCC_WARN_UNUSED_VARIABLE = YES; 572 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 573 | MTL_ENABLE_DEBUG_INFO = NO; 574 | SDKROOT = iphoneos; 575 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 576 | TARGETED_DEVICE_FAMILY = "1,2"; 577 | VALIDATE_PRODUCT = YES; 578 | }; 579 | name = Profile; 580 | }; 581 | FE65FFE721B10FBA001D658A /* Profile */ = { 582 | isa = XCBuildConfiguration; 583 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 584 | buildSettings = { 585 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 586 | CLANG_ENABLE_MODULES = YES; 587 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 588 | ENABLE_BITCODE = NO; 589 | FRAMEWORK_SEARCH_PATHS = ( 590 | "$(inherited)", 591 | "$(PROJECT_DIR)/Flutter", 592 | ); 593 | INFOPLIST_FILE = Runner/Info.plist; 594 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 595 | LIBRARY_SEARCH_PATHS = ( 596 | "$(inherited)", 597 | "$(PROJECT_DIR)/Flutter", 598 | ); 599 | PRODUCT_BUNDLE_IDENTIFIER = com.mono0926.taskshare; 600 | PRODUCT_NAME = "$(TARGET_NAME)"; 601 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 602 | SWIFT_SWIFT3_OBJC_INFERENCE = On; 603 | SWIFT_VERSION = 4.0; 604 | VERSIONING_SYSTEM = "apple-generic"; 605 | }; 606 | name = Profile; 607 | }; 608 | /* End XCBuildConfiguration section */ 609 | 610 | /* Begin XCConfigurationList section */ 611 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 612 | isa = XCConfigurationList; 613 | buildConfigurations = ( 614 | 97C147031CF9000F007C117D /* Debug */, 615 | 97C147041CF9000F007C117D /* Release */, 616 | FE65FFE621B10FBA001D658A /* Profile */, 617 | ); 618 | defaultConfigurationIsVisible = 0; 619 | defaultConfigurationName = Release; 620 | }; 621 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 622 | isa = XCConfigurationList; 623 | buildConfigurations = ( 624 | 97C147061CF9000F007C117D /* Debug */, 625 | 97C147071CF9000F007C117D /* Release */, 626 | FE65FFE721B10FBA001D658A /* Profile */, 627 | ); 628 | defaultConfigurationIsVisible = 0; 629 | defaultConfigurationName = Release; 630 | }; 631 | /* End XCConfigurationList section */ 632 | }; 633 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 634 | } 635 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /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 | BuildSystemType 6 | Original 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | import Firebase 4 | 5 | @UIApplicationMain 6 | @objc class AppDelegate: FlutterAppDelegate { 7 | override func application( 8 | _ application: UIApplication, 9 | didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? 10 | ) -> Bool { 11 | 12 | // TODO: Configurationによって参照するファイル名を切り替え 13 | // let path = Bundle.main.path(forResource: "GoogleService-Info2", ofType: "plist")! 14 | // FirebaseApp.configure(options: FirebaseOptions(contentsOfFile: path)!) 15 | // print("projectID: \(FirebaseApp.app()?.options.projectID ?? "")"); 16 | 17 | GeneratedPluginRegistrant.register(with: self) 18 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/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 | taskshare 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleURLTypes 22 | 23 | 24 | CFBundleTypeRole 25 | Editor 26 | CFBundleURLSchemes 27 | 28 | com.googleusercontent.apps.998581175991-iecdcg8lbte7jsji5engkeiqpneu2n46 29 | 30 | 31 | 32 | CFBundleVersion 33 | $(FLUTTER_BUILD_NUMBER) 34 | LSRequiresIPhoneOS 35 | 36 | UILaunchStoryboardName 37 | LaunchScreen 38 | UIMainStoryboardFile 39 | Main 40 | UISupportedInterfaceOrientations 41 | 42 | UIInterfaceOrientationPortrait 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | UISupportedInterfaceOrientations~ipad 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationPortraitUpsideDown 50 | UIInterfaceOrientationLandscapeLeft 51 | UIInterfaceOrientationLandscapeRight 52 | 53 | UIViewControllerBasedStatusBarAppearance 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /ios/Runner/ja.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ios/Runner/ja.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lib/app.dart: -------------------------------------------------------------------------------- 1 | import 'package:taskshare/bloc/account_bloc_provider.dart'; 2 | import 'package:taskshare/util/util.dart'; 3 | import 'package:taskshare/widgets/widgets.dart'; 4 | 5 | import 'pages/home.dart'; 6 | import 'pages/input_task.dart'; 7 | import 'pages/setting.dart'; 8 | 9 | class App extends StatelessWidget { 10 | const App(); 11 | 12 | factory App.forDesignTime() => const App(); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | logger.finest('App build called'); 17 | return AccountBlocProvider( 18 | child: MaterialApp( 19 | localizationsDelegates: const [ 20 | AppLocalizationsDelegate(), 21 | GlobalMaterialLocalizations.delegate, 22 | GlobalWidgetsLocalizations.delegate 23 | ], 24 | supportedLocales: const [ 25 | Locale('en', 'US'), 26 | Locale('ja', 'JP'), 27 | ], 28 | title: 'TaskShare', 29 | theme: ThemeData( 30 | primarySwatch: Colors.deepPurple, 31 | accentColor: Colors.deepPurpleAccent, 32 | errorColor: Colors.red), 33 | initialRoute: Home.routeName, 34 | routes: _routes, 35 | onGenerateRoute: _handleRoutes, 36 | ), 37 | ); 38 | } 39 | 40 | Map get _routes => { 41 | Home.routeName: (context) => const Home(), 42 | Setting.routeName: (context) => const Setting(), 43 | }; 44 | 45 | Route _handleRoutes(RouteSettings settings) { 46 | switch (settings.name) { 47 | case InputTask.routeName: 48 | return MaterialPageRoute( 49 | settings: settings, 50 | fullscreenDialog: true, 51 | builder: (_context) => 52 | InputTask.withDependencies(settings.arguments as BuildContext), 53 | ); 54 | break; 55 | } 56 | assert(false); 57 | return null; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lib/bloc/account_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc_provider/bloc_provider.dart'; 2 | import 'package:taskshare/model/authenticator.dart'; 3 | import 'package:taskshare/model/model.dart'; 4 | 5 | export 'package:taskshare/model/authenticator.dart'; 6 | 7 | class AccountBloc implements Bloc { 8 | AccountBloc({@required this.authenticator}) { 9 | _signInController.stream.listen((_) { 10 | authenticator.signIn(); 11 | }); 12 | 13 | _signOutController.stream.listen((_) { 14 | authenticator.signOut(); 15 | }); 16 | } 17 | 18 | ValueObservable get user => authenticator.user; 19 | 20 | ValueObservable get state => authenticator.state; 21 | 22 | Sink get signIn => _signInController.sink; 23 | 24 | Sink get signOut => _signOutController.sink; 25 | 26 | final Authenticator authenticator; 27 | 28 | final _signInController = StreamController(); 29 | 30 | final _signOutController = StreamController(); 31 | 32 | @override 33 | void dispose() { 34 | _signInController.close(); 35 | _signOutController.close(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/bloc/account_bloc_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc_provider/bloc_provider.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:taskshare/bloc/account_bloc.dart'; 4 | import 'package:taskshare/model/service_provider.dart'; 5 | 6 | export 'package:taskshare/bloc/account_bloc.dart'; 7 | 8 | class AccountBlocProvider extends BlocProvider { 9 | AccountBlocProvider({ 10 | @required Widget child, 11 | }) : super( 12 | child: child, 13 | creator: (context, _bag) { 14 | final provider = ServiceProvider.of(context); 15 | return AccountBloc(authenticator: provider.authenticator); 16 | }, 17 | ); 18 | 19 | static AccountBloc of(BuildContext context) => BlocProvider.of(context); 20 | } 21 | -------------------------------------------------------------------------------- /lib/l10n/intl_ja.arb: -------------------------------------------------------------------------------- 1 | { 2 | "@@last_modified": "2018-07-30T15:20:37.916931", 3 | "addTask": "タスクを追加", 4 | "@addTask": { 5 | "description": "Add a new task", 6 | "type": "text", 7 | "placeholders": {} 8 | }, 9 | "snackTaskDone": "完了: タスク「{title}」", 10 | "@snackTaskDone": { 11 | "type": "text", 12 | "placeholders": { 13 | "title": {} 14 | } 15 | }, 16 | "snackTaskDeleted": "削除: タスク「{title}」", 17 | "@snackTaskDeleted": { 18 | "type": "text", 19 | "placeholders": { 20 | "title": {} 21 | } 22 | }, 23 | "SAVE": "保存", 24 | "@SAVE": { 25 | "type": "text", 26 | "placeholders": {} 27 | }, 28 | "UNDO": "元に戻す", 29 | "@UNDO": { 30 | "type": "text", 31 | "placeholders": {} 32 | } 33 | } -------------------------------------------------------------------------------- /lib/l10n/intl_messages.arb: -------------------------------------------------------------------------------- 1 | { 2 | "@@last_modified": "2018-07-31T17:08:38.864519", 3 | "addTask": "Add a new task", 4 | "@addTask": { 5 | "description": "Add a new task", 6 | "type": "text", 7 | "placeholders": {} 8 | }, 9 | "snackTaskDone": "Task \"{title}\" done", 10 | "@snackTaskDone": { 11 | "type": "text", 12 | "placeholders": { 13 | "title": {} 14 | } 15 | }, 16 | "snackTaskDeleted": "Task \"{title}\" deleted", 17 | "@snackTaskDeleted": { 18 | "type": "text", 19 | "placeholders": { 20 | "title": {} 21 | } 22 | }, 23 | "SAVE": "SAVE", 24 | "@SAVE": { 25 | "type": "text", 26 | "placeholders": {} 27 | }, 28 | "UNDO": "UNDO", 29 | "@UNDO": { 30 | "type": "text", 31 | "placeholders": {} 32 | } 33 | } -------------------------------------------------------------------------------- /lib/l10n/l10n.dart: -------------------------------------------------------------------------------- 1 | import 'package:taskshare/widgets/widgets.dart'; 2 | import 'package:intl/intl.dart'; 3 | import 'package:taskshare/l10n/messages_all.dart'; 4 | 5 | class L10N { 6 | static Future load(Locale locale) { 7 | final name = 8 | locale.countryCode.isEmpty ? locale.languageCode : locale.toString(); 9 | final localeName = Intl.canonicalizedLocale(name); 10 | return initializeMessages(localeName).then((_) { 11 | Intl.defaultLocale = localeName; 12 | return L10N(); 13 | }); 14 | } 15 | 16 | static L10N of(BuildContext context) => Localizations.of(context, L10N); 17 | 18 | String get addTask => Intl.message( 19 | 'Add a new task', 20 | name: 'addTask', 21 | desc: 'Add a new task', 22 | ); 23 | 24 | String snackTaskDone(String title) => Intl.message( 25 | 'Task "$title" done', 26 | name: 'snackTaskDone', 27 | args: [title], 28 | ); 29 | 30 | String snackTaskDeleted(String title) => Intl.message( 31 | 'Task "$title" deleted', 32 | name: 'snackTaskDeleted', 33 | args: [title], 34 | ); 35 | 36 | String get buttonSave => Intl.message('SAVE'); 37 | 38 | String get buttonUndo => Intl.message('UNDO'); 39 | } 40 | 41 | class AppLocalizationsDelegate extends LocalizationsDelegate { 42 | const AppLocalizationsDelegate(); 43 | 44 | @override 45 | bool isSupported(Locale locale) => ['en', 'ja'].contains(locale.languageCode); 46 | 47 | @override 48 | Future load(Locale locale) => L10N.load(locale); 49 | 50 | @override 51 | bool shouldReload(LocalizationsDelegate old) => false; 52 | } 53 | -------------------------------------------------------------------------------- /lib/l10n/messages_all.dart: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart 2 | // This is a library that looks up messages for specific locales by 3 | // delegating to the appropriate library. 4 | 5 | import 'dart:async'; 6 | 7 | import 'package:intl/intl.dart'; 8 | import 'package:intl/message_lookup_by_library.dart'; 9 | // ignore: implementation_imports 10 | import 'package:intl/src/intl_helpers.dart'; 11 | 12 | import 'messages_ja.dart' as messages_ja; 13 | import 'messages_messages.dart' as messages_messages; 14 | 15 | typedef Future LibraryLoader(); 16 | Map _deferredLibraries = { 17 | 'ja': () => new Future.value(null), 18 | 'messages': () => new Future.value(null), 19 | }; 20 | 21 | MessageLookupByLibrary _findExact(localeName) { 22 | switch (localeName) { 23 | case 'ja': 24 | return messages_ja.messages; 25 | case 'messages': 26 | return messages_messages.messages; 27 | default: 28 | return null; 29 | } 30 | } 31 | 32 | /// User programs should call this before using [localeName] for messages. 33 | Future initializeMessages(String localeName) async { 34 | var availableLocale = Intl.verifiedLocale( 35 | localeName, 36 | (locale) => _deferredLibraries[locale] != null, 37 | onFailure: (_) => null); 38 | if (availableLocale == null) { 39 | return new Future.value(false); 40 | } 41 | var lib = _deferredLibraries[availableLocale]; 42 | await (lib == null ? new Future.value(false) : lib()); 43 | initializeInternalMessageLookup(() => new CompositeMessageLookup()); 44 | messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor); 45 | return new Future.value(true); 46 | } 47 | 48 | bool _messagesExistFor(String locale) { 49 | try { 50 | return _findExact(locale) != null; 51 | } catch (e) { 52 | return false; 53 | } 54 | } 55 | 56 | MessageLookupByLibrary _findGeneratedMessagesFor(locale) { 57 | var actualLocale = Intl.verifiedLocale(locale, _messagesExistFor, 58 | onFailure: (_) => null); 59 | if (actualLocale == null) return null; 60 | return _findExact(actualLocale); 61 | } 62 | -------------------------------------------------------------------------------- /lib/l10n/messages_ja.dart: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart 2 | // This is a library that provides messages for a ja locale. All the 3 | // messages from the main program should be duplicated here with the same 4 | // function name. 5 | 6 | import 'package:intl/intl.dart'; 7 | import 'package:intl/message_lookup_by_library.dart'; 8 | 9 | final messages = new MessageLookup(); 10 | 11 | // ignore: unused_element 12 | final _keepAnalysisHappy = Intl.defaultLocale; 13 | 14 | // ignore: non_constant_identifier_names 15 | typedef MessageIfAbsent(String message_str, List args); 16 | 17 | class MessageLookup extends MessageLookupByLibrary { 18 | get localeName => 'ja'; 19 | 20 | static m0(title) => "削除: タスク「${title}」"; 21 | 22 | static m1(title) => "完了: タスク「${title}」"; 23 | 24 | final messages = _notInlinedMessages(_notInlinedMessages); 25 | static _notInlinedMessages(_) => { 26 | "SAVE" : MessageLookupByLibrary.simpleMessage("保存"), 27 | "UNDO" : MessageLookupByLibrary.simpleMessage("元に戻す"), 28 | "addTask" : MessageLookupByLibrary.simpleMessage("タスクを追加"), 29 | "snackTaskDeleted" : m0, 30 | "snackTaskDone" : m1 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /lib/l10n/messages_messages.dart: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart 2 | // This is a library that provides messages for a messages locale. All the 3 | // messages from the main program should be duplicated here with the same 4 | // function name. 5 | 6 | import 'package:intl/intl.dart'; 7 | import 'package:intl/message_lookup_by_library.dart'; 8 | 9 | final messages = new MessageLookup(); 10 | 11 | // ignore: unused_element 12 | final _keepAnalysisHappy = Intl.defaultLocale; 13 | 14 | // ignore: non_constant_identifier_names 15 | typedef MessageIfAbsent(String message_str, List args); 16 | 17 | class MessageLookup extends MessageLookupByLibrary { 18 | get localeName => 'messages'; 19 | 20 | static m0(title) => "Task \"${title}\" deleted"; 21 | 22 | static m1(title) => "Task \"${title}\" done"; 23 | 24 | final messages = _notInlinedMessages(_notInlinedMessages); 25 | static _notInlinedMessages(_) => { 26 | "SAVE" : MessageLookupByLibrary.simpleMessage("SAVE"), 27 | "UNDO" : MessageLookupByLibrary.simpleMessage("UNDO"), 28 | 'addTask' : MessageLookupByLibrary.simpleMessage("Add a new task"), 29 | 'snackTaskDeleted' : m0, 30 | 'snackTaskDone' : m1 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /lib/lib.dart: -------------------------------------------------------------------------------- 1 | export 'dart:async'; 2 | 3 | export 'package:meta/meta.dart'; 4 | export 'package:scoped_model/scoped_model.dart'; 5 | export 'package:taskshare/util/util.dart'; 6 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:taskshare/app.dart'; 2 | import 'package:taskshare/bloc/account_bloc.dart'; 3 | import 'package:taskshare/model/authenticator.dart'; 4 | import 'package:taskshare/model/service_provider.dart'; 5 | import 'package:taskshare/model/tasks_store.dart'; 6 | import 'package:taskshare/widgets/widgets.dart'; 7 | 8 | void main() { 9 | runApp( 10 | ServiceProvider( 11 | authenticator: GoogleAuthenticator(), 12 | tasksStore: TasksStoreFlutter(), 13 | child: const App(), 14 | ), 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /lib/model/authenticator.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_auth/firebase_auth.dart'; 2 | import 'package:google_sign_in/google_sign_in.dart'; 3 | import 'package:taskshare/model/model.dart'; 4 | 5 | enum AccountState { loading, signedOut, signedIn, signingIn, singingOut } 6 | 7 | class User { 8 | User({ 9 | @required this.id, 10 | @required this.imageUrl, 11 | }); 12 | 13 | User.fromFirUser( 14 | FirebaseUser user, 15 | ) : this(id: user.uid, imageUrl: Uri.parse(user.photoUrl)); 16 | 17 | final String id; 18 | final Uri imageUrl; 19 | } 20 | 21 | abstract class Authenticator { 22 | ValueObservable get user; 23 | ValueObservable get state; 24 | Future signIn(); 25 | Future signOut(); 26 | } 27 | 28 | class GoogleAuthenticator implements Authenticator { 29 | GoogleAuthenticator() { 30 | _auth.onAuthStateChanged.map((user) { 31 | logger.info('onAuthStateChanged: $user'); 32 | _state.add(user == null ? AccountState.signedOut : AccountState.signedIn); 33 | return user == null ? null : User.fromFirUser(user); 34 | }).pipe(_user); 35 | } 36 | 37 | @override 38 | ValueObservable get user => _user.stream; 39 | 40 | @override 41 | ValueObservable get state => _state.stream; 42 | final _user = BehaviorSubject(); 43 | 44 | final _state = BehaviorSubject.seeded(AccountState.loading); 45 | 46 | final _auth = FirebaseAuth.instance; 47 | final _googleSignIn = GoogleSignIn(scopes: [ 48 | 'email', 49 | 'https://www.googleapis.com/auth/contacts.readonly', 50 | ]); 51 | 52 | @override 53 | Future signIn() async { 54 | assert(_state.value == AccountState.signedOut); 55 | _state.add(AccountState.signingIn); 56 | final gAccount = await _googleSignIn.signIn(); 57 | final gAuth = await gAccount.authentication; 58 | final firUser = await _auth.signInWithCredential( 59 | GoogleAuthProvider.getCredential( 60 | idToken: gAuth.idToken, 61 | accessToken: gAuth.accessToken, 62 | ), 63 | ); 64 | logger.info(firUser); 65 | return User.fromFirUser(firUser); 66 | } 67 | 68 | @override 69 | Future signOut() async { 70 | assert(_state.value == AccountState.signedIn); 71 | _state.add(AccountState.singingOut); 72 | // TEMP: 本当は呼ぶけど開発中はコメントアウト 73 | // await _googleSignIn.signOut(); 74 | await _auth.signOut(); 75 | } 76 | 77 | void dispose() { 78 | _user.close(); 79 | _state.close(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/model/database.dart: -------------------------------------------------------------------------------- 1 | import 'package:taskshare/model/model.dart'; 2 | 3 | typedef MakeQuery = Query Function(CollectionReference collectionRef); 4 | 5 | abstract class Database { 6 | Stream> entities(MakeQuery makeQuery); 7 | Stream entity(String id); 8 | Future get(String id); 9 | Future set(T entity); 10 | Future delete(T entity); 11 | } 12 | 13 | abstract class Entity { 14 | Entity({@required this.id}); 15 | static const idKey = 'id'; 16 | final String id; 17 | } 18 | 19 | class AppDatabase implements Database { 20 | AppDatabase({ 21 | @required this.collectionRef, 22 | @required this.encoder, 23 | @required this.decoder, 24 | }); 25 | final CollectionReference collectionRef; 26 | final SnapshotEncoder encoder; 27 | final SnapshotDecoder decoder; 28 | 29 | @override 30 | Stream> entities(MakeQuery makeQuery) => 31 | makeQuery(collectionRef).snapshots().map((snap) => snap.documents 32 | .map((snap) => 33 | decoder.decode(snap.data..[Entity.idKey] = snap.documentID)) 34 | .toList()); 35 | 36 | @override 37 | Stream entity(String id) { 38 | final ref = collectionRef.document(id); 39 | return ref.snapshots().map( 40 | (snap) => decoder.decode(snap.data..[Entity.idKey] = snap.documentID)); 41 | } 42 | 43 | @override 44 | Future get(String id) async { 45 | final ref = collectionRef.document(id); 46 | return decoder 47 | .decode((await ref.get()).data..[Entity.idKey] = ref.documentID); 48 | } 49 | 50 | @override 51 | Future set(T entity) async { 52 | final ref = collectionRef.document(entity.id); 53 | return ref.setData(encoder.encode(entity)..remove(Entity.idKey), 54 | merge: true); 55 | } 56 | 57 | @override 58 | Future delete(T entity) async { 59 | final ref = collectionRef.document(entity.id); 60 | await ref.delete(); 61 | } 62 | } 63 | 64 | // ignore: one_member_abstracts 65 | abstract class SnapshotDecoder { 66 | T decode(Map data); 67 | } 68 | 69 | // ignore: one_member_abstracts 70 | abstract class SnapshotEncoder { 71 | Map encode(T entity); 72 | } 73 | -------------------------------------------------------------------------------- /lib/model/group.dart: -------------------------------------------------------------------------------- 1 | class Group { 2 | static const name = 'groups'; 3 | } 4 | -------------------------------------------------------------------------------- /lib/model/model.dart: -------------------------------------------------------------------------------- 1 | export 'package:rxdart/rxdart.dart'; 2 | export 'package:cloud_firestore/cloud_firestore.dart'; 3 | export 'package:taskshare/model/database.dart'; 4 | export 'package:taskshare/lib.dart'; 5 | -------------------------------------------------------------------------------- /lib/model/service_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:taskshare/model/authenticator.dart'; 3 | import 'package:taskshare/model/tasks_store.dart'; 4 | 5 | class ServiceProvider extends InheritedWidget { 6 | const ServiceProvider({ 7 | @required this.authenticator, 8 | @required this.tasksStore, 9 | @required Widget child, 10 | }) : super(child: child); 11 | final Authenticator authenticator; 12 | final TasksStore tasksStore; 13 | 14 | @override 15 | bool updateShouldNotify(InheritedWidget oldWidget) => false; 16 | 17 | static ServiceProvider of(BuildContext context) => context 18 | .ancestorInheritedElementForWidgetOfExactType(ServiceProvider) 19 | .widget as ServiceProvider; 20 | } 21 | -------------------------------------------------------------------------------- /lib/model/task.dart: -------------------------------------------------------------------------------- 1 | import 'package:taskshare/model/model.dart'; 2 | 3 | class Task implements Entity { 4 | Task( 5 | {@required this.id, 6 | @required this.title, 7 | this.doneTime, 8 | this.dueTime, 9 | this.createTime, 10 | this.updateTime}); 11 | static const name = 'tasks'; 12 | @override 13 | // MEMO: @required にしてidはdocumentRef()経由で持ってくるとかもありかも?? 14 | final String id; 15 | final String title; 16 | Timestamp doneTime; 17 | Timestamp dueTime; 18 | Timestamp createTime; 19 | Timestamp updateTime; 20 | 21 | @override 22 | bool operator ==(Object other) { 23 | return identical(this, other) || 24 | other is Task && runtimeType == other.runtimeType && id == other.id; 25 | } 26 | 27 | @override 28 | int get hashCode => id.hashCode ^ title.hashCode; 29 | 30 | @override 31 | String toString() => ''' 32 | 33 | Task{ 34 | id: $id, 35 | title: $title, 36 | doneTime: $doneTime, 37 | dueTime: $dueTime, 38 | createTime: $createTime, 39 | updateTime: $updateTime 40 | }'''; 41 | } 42 | 43 | class TaskEncoder extends SnapshotEncoder { 44 | @override 45 | Map encode(Task entity) => { 46 | Entity.idKey: entity.id, 47 | TaskProperties.title: entity.title, 48 | TaskProperties.doneTime: entity.doneTime, 49 | TaskProperties.dueTime: entity.dueTime, 50 | TaskProperties.createTime: entity.createTime, 51 | TaskProperties.updateTime: entity.updateTime 52 | }; 53 | } 54 | 55 | class TaskDecoder extends SnapshotDecoder { 56 | @override 57 | Task decode(Map data) => Task( 58 | id: data[Entity.idKey] as String, 59 | title: data[TaskProperties.title] as String, 60 | doneTime: data[TaskProperties.doneTime] as Timestamp, 61 | dueTime: data[TaskProperties.dueTime] as Timestamp, 62 | createTime: data[TaskProperties.createTime] as Timestamp, 63 | updateTime: data[TaskProperties.updateTime] as Timestamp, 64 | ); 65 | } 66 | 67 | // 'dart:mirrors'がDart 2では未実装なので 68 | class TaskProperties { 69 | static const title = 'title'; 70 | static const doneTime = 'doneTime'; 71 | static const dueTime = 'dueTime'; 72 | static const createTime = 'createTime'; 73 | static const updateTime = 'updateTime'; 74 | } 75 | -------------------------------------------------------------------------------- /lib/model/tasks_store.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | import 'package:taskshare/model/group.dart'; 3 | import 'package:taskshare/model/model.dart'; 4 | import 'package:taskshare/model/task.dart'; 5 | 6 | abstract class TasksStore { 7 | void updateGroup(String groupName); 8 | String get groupName; 9 | Stream> get tasks; 10 | 11 | void set(Task task); 12 | void delete(Task task); 13 | } 14 | 15 | class TasksStoreFlutter implements TasksStore { 16 | final _firestore = Firestore.instance; 17 | Database _database; 18 | String _groupName; 19 | Stream> _tasks; 20 | 21 | @override 22 | void updateGroup(String groupName) { 23 | if (_groupName == groupName) { 24 | return; 25 | } 26 | _groupName = groupName; 27 | if (groupName == null) { 28 | return; 29 | } 30 | logger.info('groupName updated: $groupName'); 31 | _database = AppDatabase( 32 | collectionRef: _firestore 33 | .collection(Group.name) 34 | .document(groupName) 35 | .collection(Task.name), 36 | encoder: TaskEncoder(), 37 | decoder: TaskDecoder()); 38 | 39 | _tasks = _database.entities((ref) => ref 40 | .where('${TaskProperties.doneTime}', isNull: true) 41 | .orderBy('${TaskProperties.dueTime}', descending: false) 42 | .orderBy('${TaskProperties.createTime}', descending: true)); 43 | } 44 | 45 | @override 46 | void set(Task task) { 47 | _database.set(task); 48 | } 49 | 50 | @override 51 | void delete(Task task) { 52 | _database.delete(task); 53 | } 54 | 55 | @override 56 | String get groupName => _groupName; 57 | 58 | @override 59 | Stream> get tasks => _tasks; 60 | } 61 | -------------------------------------------------------------------------------- /lib/pages/home.dart: -------------------------------------------------------------------------------- 1 | import 'package:taskshare/bloc/account_bloc.dart'; 2 | import 'package:taskshare/bloc/account_bloc_provider.dart'; 3 | import 'package:taskshare/widgets/widgets.dart'; 4 | 5 | import 'task/task_page.dart'; 6 | import 'welcome.dart'; 7 | 8 | class Home extends StatelessWidget { 9 | const Home(); 10 | 11 | factory Home.forDesignTime() => const Home(); 12 | static const routeName = '/'; 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | final accountBloc = AccountBlocProvider.of(context); 17 | return StreamBuilder( 18 | initialData: accountBloc.state.value, 19 | stream: accountBloc.state, 20 | builder: (context, snapshot) { 21 | switch (snapshot.data) { 22 | case AccountState.loading: 23 | return const AppProgressIndicator(); 24 | case AccountState.signedOut: 25 | case AccountState.signingIn: 26 | return const Welcome(); 27 | case AccountState.signedIn: 28 | case AccountState.singingOut: 29 | return TaskScreen.withDependencies(); 30 | } 31 | assert(false); 32 | return Container(); 33 | }, 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/pages/input_task.dart: -------------------------------------------------------------------------------- 1 | import 'package:taskshare/widgets/widgets.dart'; 2 | 3 | import 'task/tasks_bloc_provider.dart'; 4 | 5 | // TOOD: 途中 6 | class InputTask extends StatelessWidget { 7 | const InputTask(); 8 | 9 | static const routeName = '/input_task'; 10 | 11 | static Widget withDependencies(BuildContext context) { 12 | return TasksBlocProvider.fromBlocContext( 13 | context: context, 14 | child: const InputTask(), 15 | ); 16 | } 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return Scaffold( 21 | appBar: AppBar( 22 | title: const Text('Input New Task'), 23 | actions: [ 24 | Builder( 25 | builder: (context) => FlatButton( 26 | child: Text( 27 | 'ADD', 28 | style: TextStyle( 29 | color: Theme.of(context).canvasColor, 30 | ), 31 | ), 32 | onPressed: () { 33 | Scaffold.of(context).showSnackBar(SnackBar( 34 | content: const Text('Not implemented'), 35 | )); 36 | }, 37 | ), 38 | ), 39 | ], 40 | ), 41 | body: ListView( 42 | children: const [ 43 | TextField( 44 | autofocus: true, 45 | ) 46 | ], 47 | )); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/pages/setting.dart: -------------------------------------------------------------------------------- 1 | import 'package:taskshare/bloc/account_bloc_provider.dart'; 2 | import 'package:taskshare/widgets/widgets.dart'; 3 | 4 | class Setting extends StatelessWidget { 5 | const Setting(); 6 | 7 | factory Setting.forDesignTime() => const Setting(); 8 | static const routeName = '/settings'; 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | final accountBloc = AccountBlocProvider.of(context); 13 | return StreamBuilder( 14 | initialData: accountBloc.user.value, 15 | stream: accountBloc.user, 16 | builder: (context, snapshot) { 17 | final user = snapshot.data; 18 | return Scaffold( 19 | appBar: AppBar( 20 | title: const Text('Settings'), 21 | ), 22 | body: ListView( 23 | children: [ 24 | ListTile( 25 | title: Text(user?.toString() ?? ''), 26 | ), 27 | const Divider( 28 | height: 1, 29 | ), 30 | ListTile( 31 | title: Text( 32 | 'Sign out', 33 | style: TextStyle(color: Theme.of(context).errorColor), 34 | ), 35 | onTap: () async { 36 | accountBloc.signOut.add(null); 37 | Navigator.of(context).pop(); 38 | }, 39 | ) 40 | ], 41 | )); 42 | }, 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/pages/task/add_task_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:taskshare/l10n/l10n.dart'; 3 | 4 | import 'task_page_state.dart'; 5 | 6 | class AddTaskButton extends StatelessWidget { 7 | const AddTaskButton(); 8 | 9 | factory AddTaskButton.forDesignTime() => const AddTaskButton(); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | final l10n = L10N.of(context); 14 | return FloatingActionButton.extended( 15 | icon: const Icon(Icons.add), 16 | label: Text(l10n.addTask), 17 | onPressed: () => 18 | TaskPageModel.of(context).update(mode: TaskScreenMode.input), 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/pages/task/addition/task_addition_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc_provider/bloc_provider.dart'; 2 | import 'package:rxdart/rxdart.dart'; 3 | import 'package:taskshare/model/task.dart'; 4 | 5 | class TaskAdditionBloc implements Bloc { 6 | TaskAdditionBloc() { 7 | _saveController.listen((title) { 8 | if (title == null || title.isEmpty) { 9 | _failedController.add('Input task title.'); 10 | } else { 11 | final task = Task(id: null, title: title); 12 | _addedController.add(task); 13 | _failedController.add(null); 14 | } 15 | }); 16 | _textController.listen((text) { 17 | if (text != null && text.isNotEmpty) { 18 | _failedController.add(null); 19 | } 20 | }); 21 | } 22 | final _saveController = PublishSubject(); 23 | final _addedController = PublishSubject(); 24 | final _failedController = BehaviorSubject.seeded(null); 25 | final _textController = BehaviorSubject(); 26 | 27 | Stream get added => _addedController.stream; 28 | ValueObservable get failed => _failedController.stream; 29 | Sink get save => _saveController.sink; 30 | Sink get updateText => _textController.sink; 31 | ValueObservable get text => _textController.stream; 32 | 33 | @override 34 | void dispose() { 35 | _saveController.close(); 36 | _addedController.close(); 37 | _failedController.close(); 38 | _textController.close(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/pages/task/addition/task_addition_bloc_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc_provider/bloc_provider.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | import '../tasks_bloc.dart'; 5 | import '../tasks_bloc_provider.dart'; 6 | import 'task_addition_bloc.dart'; 7 | 8 | class TaskAdditionBlocProvider extends BlocProvider { 9 | TaskAdditionBlocProvider({ 10 | @required Widget child, 11 | }) : super( 12 | child: child, 13 | creator: (context, bag) { 14 | final bloc = TaskAdditionBloc(); 15 | final tasksBloc = TasksBlocProvider.of(context); 16 | final subscription = bloc.added.listen((task) { 17 | tasksBloc.taskOperation.add( 18 | TaskOperation( 19 | task: task, 20 | type: TaskOperationType.add, 21 | ), 22 | ); 23 | }); 24 | bag.register(onDisposed: subscription.cancel); 25 | return bloc; 26 | }, 27 | ); 28 | 29 | static TaskAdditionBloc of(BuildContext context) => BlocProvider.of(context); 30 | } 31 | -------------------------------------------------------------------------------- /lib/pages/task/addition/task_input.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:taskshare/l10n/l10n.dart'; 3 | 4 | import '../../input_task.dart'; 5 | import 'task_addition_bloc_provider.dart'; 6 | 7 | class TaskInput extends StatefulWidget { 8 | const TaskInput({ 9 | Key key, 10 | @required this.textController, 11 | }) : super(key: key); 12 | final TextEditingController textController; 13 | 14 | @override 15 | TaskInputState createState() => TaskInputState(); 16 | } 17 | 18 | class TaskInputState extends State { 19 | final _focusNode = FocusNode(); 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | final bloc = TaskAdditionBlocProvider.of(context); 24 | final l10n = L10N.of(context); 25 | return Padding( 26 | padding: const EdgeInsets.only( 27 | left: 20, 28 | right: 20, 29 | top: 20, 30 | bottom: 8, 31 | ), 32 | child: Column( 33 | children: [ 34 | StreamBuilder( 35 | initialData: bloc.failed.value, 36 | stream: bloc.failed, 37 | builder: (context, snap) { 38 | return TextField( 39 | controller: widget.textController, 40 | focusNode: _focusNode, 41 | decoration: InputDecoration( 42 | border: InputBorder.none, 43 | hintText: 'New Task', 44 | errorText: snap.data, 45 | ), 46 | onSubmitted: (text) { 47 | bloc.save.add(text); 48 | }, 49 | ); 50 | }, 51 | ), 52 | Row( 53 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 54 | children: [ 55 | IconButton( 56 | padding: const EdgeInsets.all(0), 57 | icon: const Icon( 58 | Icons.open_in_new, 59 | ), 60 | onPressed: () { 61 | Navigator.of(context).pushNamed( 62 | InputTask.routeName, 63 | arguments: context, 64 | ); 65 | }, 66 | color: Theme.of(context).accentColor, 67 | ), 68 | FlatButton( 69 | onPressed: () async { 70 | bloc.save.add(bloc.text.value); 71 | }, 72 | child: Text( 73 | l10n.buttonSave, 74 | ), 75 | textTheme: ButtonTextTheme.accent, 76 | ), 77 | ], 78 | ), 79 | ], 80 | ), 81 | ); 82 | } 83 | 84 | void focus() { 85 | FocusScope.of(context).requestFocus(_focusNode); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /lib/pages/task/bottom_menu.dart: -------------------------------------------------------------------------------- 1 | import 'package:taskshare/widgets/widgets.dart'; 2 | 3 | class BottomMenu extends StatelessWidget { 4 | const BottomMenu(); 5 | 6 | factory BottomMenu.forDesignTime() => const BottomMenu(); 7 | 8 | @override 9 | Widget build(BuildContext context) => BottomAppBar( 10 | child: Row( 11 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 12 | children: [ 13 | IconButton( 14 | icon: const Icon(Icons.menu), 15 | onPressed: () {}, 16 | ), 17 | IconButton( 18 | icon: const Icon(Icons.more_horiz), 19 | onPressed: () {}, 20 | ), 21 | ], 22 | ), 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /lib/pages/task/list/task_animated_list.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:meta/meta.dart'; 3 | import 'package:observable/observable.dart'; 4 | import 'package:quiver/iterables.dart'; 5 | import 'package:rxdart/rxdart.dart'; 6 | import 'package:taskshare/model/task.dart'; 7 | 8 | import '../../../util/util.dart'; 9 | 10 | typedef TaskRemovedItemBuilder = Widget Function( 11 | Task task, 12 | BuildContext context, 13 | Animation animation, 14 | ); 15 | 16 | @immutable 17 | class TaskAnimatedList { 18 | TaskAnimatedList({ 19 | @required this.listKey, 20 | @required this.stream, 21 | @required this.removedItemBuilder, 22 | }) : _tasks = stream.value ?? [] { 23 | stream.listen((tasks) { 24 | final diffs = _differ.diff(_tasks, tasks); 25 | for (final diff in diffs) { 26 | diff.removed.forEach(remove); 27 | final added = diff.added.toList(); 28 | for (final i in range(0, added.length).cast()) { 29 | final task = added[i]; 30 | final index = diff.index + i; 31 | _tasks.insert(index, task); 32 | _animatedList.insertItem(index); 33 | } 34 | } 35 | }); 36 | } 37 | 38 | final GlobalKey listKey; 39 | final ValueObservable> stream; 40 | final TaskRemovedItemBuilder removedItemBuilder; 41 | final List _tasks; 42 | final _differ = const ListDiffer(); 43 | int get length => _tasks.length; 44 | Task operator [](int index) => _tasks[index]; 45 | 46 | AnimatedListState get _animatedList => listKey.currentState; 47 | 48 | void remove(Task task, {bool skipAnimation = false}) { 49 | final index = _tasks.indexOf(task); 50 | logger.info('index: $index'); 51 | _tasks.removeAt(index); 52 | _animatedList.removeItem(index, (context, animation) { 53 | return removedItemBuilder(task, context, animation); 54 | }, duration: Duration(milliseconds: skipAnimation ? 0 : 500)); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/pages/task/list/task_list.dart: -------------------------------------------------------------------------------- 1 | import 'package:taskshare/widgets/widgets.dart'; 2 | 3 | import '../tasks_bloc.dart'; 4 | import '../tasks_bloc_provider.dart'; 5 | import 'task_animated_list.dart'; 6 | import 'task_list_tile.dart'; 7 | 8 | class TaskList extends StatefulWidget { 9 | const TaskList(); 10 | 11 | factory TaskList.forDesignTime() => const TaskList(); 12 | 13 | @override 14 | TaskListState createState() => TaskListState(); 15 | } 16 | 17 | class TaskListState extends State { 18 | final _listKey = GlobalKey(); 19 | TaskAnimatedList _list; 20 | StreamSubscription _subscription; 21 | @override 22 | void initState() { 23 | super.initState(); 24 | final bloc = TasksBlocProvider.of(context); 25 | _list = TaskAnimatedList( 26 | listKey: _listKey, 27 | stream: bloc.tasks, 28 | removedItemBuilder: (task, context, animation) { 29 | return TaskListTile( 30 | key: ValueKey(task.id), 31 | task: task, 32 | animation: animation, 33 | onDismissed: null, 34 | ); 35 | }, 36 | ); 37 | _subscription = bloc.taskOperations.listen((operation) { 38 | final l10n = L10N.of(context); 39 | final task = operation.task; 40 | final type = operation.type; 41 | String title; 42 | switch (type) { 43 | case TaskOperationType.checked: 44 | title = l10n.snackTaskDone(task.title); 45 | break; 46 | case TaskOperationType.deleted: 47 | title = l10n.snackTaskDeleted(task.title); 48 | break; 49 | case TaskOperationType.add: 50 | case TaskOperationType.updated: 51 | return; 52 | } 53 | Scaffold.of(context).showSnackBar( 54 | SnackBar( 55 | content: Text( 56 | title, 57 | ), 58 | action: SnackBarAction( 59 | label: l10n.buttonUndo, 60 | textColor: 61 | (Theme.of(context).accentColor as MaterialAccentColor)[100], 62 | onPressed: () { 63 | switch (type) { 64 | case TaskOperationType.checked: 65 | task.doneTime = null; 66 | bloc.taskOperation.add(TaskOperation( 67 | task: task, type: TaskOperationType.updated)); 68 | break; 69 | case TaskOperationType.deleted: 70 | bloc.taskOperation.add( 71 | TaskOperation(task: task, type: TaskOperationType.add)); 72 | break; 73 | case TaskOperationType.add: 74 | case TaskOperationType.updated: 75 | break; 76 | } 77 | }, 78 | ), 79 | ), 80 | ); 81 | }); 82 | } 83 | 84 | @override 85 | Widget build(BuildContext context) { 86 | return AnimatedList( 87 | key: _listKey, 88 | initialItemCount: _list.length, 89 | itemBuilder: (context, index, animation) { 90 | final task = _list[index]; 91 | return TaskListTile( 92 | key: ValueKey(task.id), 93 | task: task, 94 | animation: animation, 95 | onDismissed: (_) { 96 | final bloc = TasksBlocProvider.of(context); 97 | _list.remove(task, skipAnimation: true); 98 | bloc.taskOperation.add( 99 | TaskOperation( 100 | task: task, 101 | type: TaskOperationType.deleted, 102 | ), 103 | ); 104 | }, 105 | ); 106 | }, 107 | ); 108 | } 109 | 110 | @override 111 | void dispose() { 112 | _subscription.cancel(); 113 | super.dispose(); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /lib/pages/task/list/task_list_tile.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:taskshare/model/task.dart'; 4 | 5 | import '../tasks_bloc.dart'; 6 | import '../tasks_bloc_provider.dart'; 7 | 8 | class TaskListTile extends StatelessWidget { 9 | const TaskListTile({ 10 | @required Key key, 11 | @required this.task, 12 | @required this.animation, 13 | @required this.onDismissed, 14 | }) : super(key: key); 15 | final Task task; 16 | final Animation animation; 17 | final DismissDirectionCallback onDismissed; 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | final bloc = TasksBlocProvider.of(context); 22 | return Dismissible( 23 | key: ValueKey(task.id), 24 | onDismissed: onDismissed, 25 | background: Container( 26 | color: Theme.of(context).errorColor, 27 | ), 28 | child: SizeTransition( 29 | sizeFactor: animation, 30 | child: Column( 31 | children: [ 32 | ListTile( 33 | title: Text(task.title), 34 | leading: Checkbox( 35 | onChanged: (value) { 36 | // server valueの方が良さそう 37 | task.doneTime = value ? Timestamp.now() : null; 38 | bloc.taskOperation.add( 39 | TaskOperation( 40 | task: task, 41 | type: value 42 | ? TaskOperationType.checked 43 | : TaskOperationType.updated, 44 | ), 45 | ); 46 | }, 47 | value: task.doneTime != null, 48 | ), 49 | ), 50 | const Divider( 51 | height: 0, 52 | ) 53 | ], 54 | ), 55 | ), 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/pages/task/menu_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:taskshare/bloc/account_bloc_provider.dart'; 2 | import 'package:taskshare/widgets/widgets.dart'; 3 | 4 | import '../setting.dart'; 5 | 6 | class MenuButton extends StatelessWidget { 7 | const MenuButton(); 8 | 9 | factory MenuButton.forDesignTime() => const MenuButton(); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | final accountBloc = AccountBlocProvider.of(context); 14 | return StreamBuilder( 15 | initialData: accountBloc.user.value, 16 | stream: accountBloc.user, 17 | builder: (context, snap) { 18 | final user = snap.data; 19 | if (user == null) { 20 | return const AppProgressIndicator(); 21 | } 22 | return IconButton( 23 | icon: ClipOval( 24 | child: Image.network( 25 | user.imageUrl.toString(), 26 | fit: BoxFit.cover, 27 | ), 28 | ), 29 | onPressed: () { 30 | Navigator.of(context).pushNamed(Setting.routeName); 31 | }, 32 | ); 33 | }, 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/pages/task/task_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:scoped_model/scoped_model.dart'; 3 | 4 | import 'add_task_button.dart'; 5 | import 'addition/task_addition_bloc.dart'; 6 | import 'addition/task_addition_bloc_provider.dart'; 7 | import 'addition/task_input.dart'; 8 | import 'bottom_menu.dart'; 9 | import 'list/task_list.dart'; 10 | import 'menu_button.dart'; 11 | import 'task_page_state.dart'; 12 | import 'tasks_bloc_provider.dart'; 13 | 14 | class TaskScreen extends StatefulWidget { 15 | const TaskScreen(); 16 | 17 | static Widget withDependencies() { 18 | return TasksBlocProvider( 19 | child: ScopedModel( 20 | model: TaskPageModel(), 21 | child: TaskAdditionBlocProvider( 22 | child: const TaskScreen(), 23 | ), 24 | ), 25 | ); 26 | } 27 | 28 | @override 29 | TaskScreenState createState() => TaskScreenState(); 30 | } 31 | 32 | class TaskScreenState extends State 33 | with SingleTickerProviderStateMixin { 34 | TaskAdditionBloc _bloc; 35 | var _mode = TaskScreenMode.list; 36 | Animation _backgroundFadeAnimation; 37 | Animation _reverseInputViewFadeAnimation; 38 | AnimationController _animationController; 39 | final _textController = TextEditingController(); 40 | final _taskInputKey = GlobalKey(); 41 | 42 | @override 43 | void initState() { 44 | super.initState(); 45 | _animationController = AnimationController( 46 | vsync: this, 47 | duration: Duration(milliseconds: 200), 48 | ); 49 | _backgroundFadeAnimation = 50 | Tween(begin: 0, end: 0.4).animate(_animationController); 51 | _reverseInputViewFadeAnimation = 52 | Tween(begin: 0, end: 1).animate(CurvedAnimation( 53 | parent: _animationController, 54 | curve: const Interval(0.4, 1), 55 | )); 56 | _bloc = TaskAdditionBlocProvider.of(context); 57 | 58 | _bloc.added.listen((task) { 59 | TaskPageModel.of(context).update(mode: TaskScreenMode.list); 60 | _textController.clear(); 61 | }); 62 | 63 | _textController.addListener(() { 64 | _bloc.updateText.add(_textController.text); 65 | }); 66 | } 67 | 68 | @override 69 | void didChangeDependencies() { 70 | final model = TaskPageModel.of(context, rebuildOnChange: true); 71 | _updateMode(model.mode); 72 | super.didChangeDependencies(); 73 | } 74 | 75 | void _updateMode(TaskScreenMode mode) async { 76 | if (mode == _mode) { 77 | return; 78 | } 79 | switch (mode) { 80 | case TaskScreenMode.input: 81 | setState(() => _mode = mode); 82 | _animationController.forward(); 83 | _taskInputKey.currentState.focus(); 84 | break; 85 | case TaskScreenMode.fullscreen: 86 | // フルスクリーン画面が無いのでとりあえずlistに合わせる 87 | case TaskScreenMode.list: 88 | FocusScope.of(context).requestFocus(FocusNode()); 89 | await _animationController.reverse(); 90 | setState(() => _mode = mode); 91 | break; 92 | } 93 | } 94 | 95 | @override 96 | void dispose() { 97 | _animationController.dispose(); 98 | _textController.dispose(); 99 | super.dispose(); 100 | } 101 | 102 | @override 103 | Widget build(BuildContext context) { 104 | final list = Scaffold( 105 | resizeToAvoidBottomInset: false, 106 | bottomNavigationBar: const BottomMenu(), 107 | appBar: _buildAppBar(), 108 | body: const TaskList(), 109 | floatingActionButton: const AddTaskButton(), 110 | floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, 111 | ); 112 | final mediaQuery = MediaQuery.of(context); 113 | final minInsets = 114 | mediaQuery.padding.copyWith(bottom: mediaQuery.viewInsets.bottom); 115 | final input = Stack( 116 | children: [ 117 | GestureDetector( 118 | onTap: () => 119 | TaskPageModel.of(context).update(mode: TaskScreenMode.list), 120 | child: FadeTransition( 121 | opacity: _backgroundFadeAnimation, 122 | child: Container(color: Colors.black), 123 | ), 124 | ), 125 | Positioned.fill( 126 | top: null, 127 | child: Padding( 128 | padding: minInsets, 129 | child: Material( 130 | color: Colors.transparent, 131 | child: FadeTransition( 132 | opacity: _reverseInputViewFadeAnimation, 133 | child: Container( 134 | decoration: BoxDecoration( 135 | color: Theme.of(context).scaffoldBackgroundColor, 136 | borderRadius: const BorderRadius.only( 137 | topLeft: Radius.circular(10), 138 | topRight: Radius.circular(10), 139 | ), 140 | ), 141 | child: TaskInput( 142 | key: _taskInputKey, 143 | textController: _textController, 144 | ), 145 | ), 146 | ), 147 | ), 148 | ), 149 | ), 150 | ], 151 | ); 152 | 153 | final showInput = _mode == TaskScreenMode.input; 154 | return Stack( 155 | children: [ 156 | list, 157 | Offstage( 158 | offstage: !showInput, 159 | child: input, 160 | ) 161 | ], 162 | ); 163 | } 164 | 165 | AppBar _buildAppBar() => AppBar( 166 | title: const Text('TaskShare'), 167 | actions: const [MenuButton()], 168 | ); 169 | } 170 | -------------------------------------------------------------------------------- /lib/pages/task/task_page_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | import 'package:scoped_model/scoped_model.dart'; 3 | 4 | export 'package:scoped_model/scoped_model.dart'; 5 | 6 | enum TaskScreenMode { list, input, fullscreen } 7 | 8 | class TaskPageModel extends Model { 9 | var _mode = TaskScreenMode.list; 10 | TaskScreenMode get mode => _mode; 11 | 12 | void update({TaskScreenMode mode}) { 13 | _mode = mode; 14 | notifyListeners(); 15 | } 16 | 17 | static TaskPageModel of( 18 | BuildContext context, { 19 | bool rebuildOnChange = false, 20 | }) => 21 | ScopedModel.of( 22 | context, 23 | rebuildOnChange: rebuildOnChange, 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /lib/pages/task/tasks_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc_provider/bloc_provider.dart'; 2 | import 'package:taskshare/model/authenticator.dart'; 3 | import 'package:taskshare/model/model.dart'; 4 | import 'package:taskshare/model/task.dart'; 5 | import 'package:taskshare/model/tasks_store.dart'; 6 | import 'package:taskshare/util/logger.dart'; 7 | 8 | export 'package:taskshare/model/task.dart'; 9 | 10 | enum TaskOperationType { deleted, checked, add, updated } 11 | 12 | class TaskOperation { 13 | TaskOperation({ 14 | @required this.task, 15 | @required this.type, 16 | }); 17 | final Task task; 18 | final TaskOperationType type; 19 | } 20 | 21 | class TasksBloc implements Bloc { 22 | TasksBloc({@required this.authenticator, @required this.store}) { 23 | logger.info('TasksBloc constructor called'); 24 | 25 | _subscription = authenticator.user.flatMap>((user) { 26 | final groupName = user?.id; 27 | if (user == null) { 28 | logger.info('same group name is null'); 29 | store.updateGroup(groupName); 30 | return Observable.just([]); 31 | } 32 | if (store.groupName == groupName) { 33 | logger.info('same group name: $groupName'); 34 | return Observable.empty(); 35 | } 36 | 37 | store.updateGroup(groupName); 38 | 39 | return store.tasks; 40 | }).listen(_tasks.add); 41 | 42 | _taskOperationController.stream 43 | .doOnData(_taskOperations.add) 44 | .listen((operation) async { 45 | final task = operation.task; 46 | switch (operation.type) { 47 | case TaskOperationType.checked: 48 | case TaskOperationType.updated: 49 | case TaskOperationType.add: 50 | _setTask(task); 51 | break; 52 | case TaskOperationType.deleted: 53 | store.delete(task); 54 | break; 55 | } 56 | }); 57 | } 58 | 59 | ValueObservable> get tasks => _tasks.stream; 60 | Stream get taskOperations => _taskOperations.stream; 61 | 62 | Sink get taskOperation => _taskOperationController.sink; 63 | 64 | StreamSubscription _subscription; 65 | final Authenticator authenticator; 66 | final TasksStore store; 67 | final _tasks = BehaviorSubject>(); 68 | final _taskOperations = PublishSubject(); 69 | final _taskOperationController = PublishSubject(); 70 | 71 | void _setTask(Task task) { 72 | final now = Timestamp.now(); 73 | task.createTime ??= now; 74 | task.updateTime = now; 75 | store.set(task); 76 | } 77 | 78 | @override 79 | void dispose() { 80 | _subscription.cancel(); 81 | _taskOperations.close(); 82 | _taskOperationController.close(); 83 | _tasks.close(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /lib/pages/task/tasks_bloc_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:bloc_provider/bloc_provider.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:taskshare/model/service_provider.dart'; 4 | 5 | import 'tasks_bloc.dart'; 6 | 7 | class TasksBlocProvider extends BlocProvider { 8 | TasksBlocProvider({@required Widget child}) 9 | : super( 10 | child: child, 11 | creator: (context, _bag) { 12 | final provider = ServiceProvider.of(context); 13 | return TasksBloc( 14 | authenticator: provider.authenticator, 15 | store: provider.tasksStore, 16 | ); 17 | }, 18 | ); 19 | 20 | TasksBlocProvider.fromBlocContext({ 21 | @required BuildContext context, 22 | @required Widget child, 23 | }) : super.fromBlocContext( 24 | context: context, 25 | child: child, 26 | ); 27 | 28 | static TasksBloc of(BuildContext context) => BlocProvider.of(context); 29 | } 30 | -------------------------------------------------------------------------------- /lib/pages/welcome.dart: -------------------------------------------------------------------------------- 1 | import 'package:taskshare/bloc/account_bloc.dart'; 2 | import 'package:taskshare/bloc/account_bloc_provider.dart'; 3 | import 'package:taskshare/widgets/widgets.dart'; 4 | 5 | class Welcome extends StatelessWidget { 6 | const Welcome(); 7 | 8 | factory Welcome.forDesignTime() => const Welcome(); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | final accountBloc = AccountBlocProvider.of(context); 13 | final body = StreamBuilder( 14 | initialData: accountBloc.state.value, 15 | stream: accountBloc.state, 16 | builder: (context, snap) { 17 | final children = [ 18 | Center( 19 | child: Column( 20 | mainAxisAlignment: MainAxisAlignment.center, 21 | children: [ 22 | const Text('グループ共有に特化したタスク管理アプリです( ´・‿・`)'), 23 | const SizedBox( 24 | height: 16, 25 | ), 26 | RaisedButton( 27 | child: const Text('Googleログイン'), 28 | onPressed: () { 29 | accountBloc.signIn.add(null); 30 | }, 31 | ) 32 | ], 33 | ), 34 | ) 35 | ]; 36 | if (snap.data == AccountState.signingIn) { 37 | children.add(AppProgressIndicator( 38 | color: Theme.of(context).backgroundColor.withAlpha(50), 39 | )); 40 | } 41 | return Stack( 42 | children: children, 43 | ); 44 | }, 45 | ); 46 | 47 | return Scaffold( 48 | body: body, 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/util/logger.dart: -------------------------------------------------------------------------------- 1 | import 'package:simple_logger/simple_logger.dart'; 2 | 3 | // TODO(mono): stacktraceEnabledはリリースビルドではfalseにする 4 | final SimpleLogger logger = SimpleLogger() 5 | ..setLevel( 6 | Level.FINEST, 7 | includeCallerInfo: true, 8 | ); 9 | -------------------------------------------------------------------------------- /lib/util/util.dart: -------------------------------------------------------------------------------- 1 | export 'logger.dart'; 2 | -------------------------------------------------------------------------------- /lib/widgets/app_progress_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'package:taskshare/widgets/widgets.dart'; 2 | 3 | class AppProgressIndicator extends StatelessWidget { 4 | const AppProgressIndicator({this.color}); 5 | 6 | factory AppProgressIndicator.forDesignTime() => const AppProgressIndicator(); 7 | final Color color; 8 | 9 | @override 10 | Widget build(BuildContext context) => Container( 11 | color: color ?? Theme.of(context).canvasColor, 12 | child: const Center( 13 | child: CircularProgressIndicator(), 14 | ), 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /lib/widgets/widgets.dart: -------------------------------------------------------------------------------- 1 | export 'package:flutter/material.dart'; 2 | export 'package:flutter_localizations/flutter_localizations.dart'; 3 | export 'package:taskshare/l10n/l10n.dart'; 4 | export 'package:taskshare/lib.dart'; 5 | 6 | export 'app_progress_indicator.dart'; 7 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | analyzer: 5 | dependency: transitive 6 | description: 7 | name: analyzer 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "0.35.4" 11 | args: 12 | dependency: transitive 13 | description: 14 | name: args 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "1.5.1" 18 | async: 19 | dependency: transitive 20 | description: 21 | name: async 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.2.0" 25 | bloc_provider: 26 | dependency: "direct main" 27 | description: 28 | name: bloc_provider 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "0.5.0+3" 32 | boolean_selector: 33 | dependency: transitive 34 | description: 35 | name: boolean_selector 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.0.4" 39 | build: 40 | dependency: "direct dev" 41 | description: 42 | name: build 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.1.3" 46 | build_config: 47 | dependency: transitive 48 | description: 49 | name: build_config 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "0.3.1+4" 53 | build_daemon: 54 | dependency: transitive 55 | description: 56 | name: build_daemon 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "0.5.0" 60 | build_resolvers: 61 | dependency: transitive 62 | description: 63 | name: build_resolvers 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "1.0.4" 67 | build_runner: 68 | dependency: "direct dev" 69 | description: 70 | name: build_runner 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "1.3.1" 74 | build_runner_core: 75 | dependency: transitive 76 | description: 77 | name: build_runner_core 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "3.0.2" 81 | built_collection: 82 | dependency: transitive 83 | description: 84 | name: built_collection 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "4.2.0" 88 | built_value: 89 | dependency: "direct main" 90 | description: 91 | name: built_value 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "6.3.2" 95 | charcode: 96 | dependency: transitive 97 | description: 98 | name: charcode 99 | url: "https://pub.dartlang.org" 100 | source: hosted 101 | version: "1.1.2" 102 | cloud_firestore: 103 | dependency: "direct main" 104 | description: 105 | name: cloud_firestore 106 | url: "https://pub.dartlang.org" 107 | source: hosted 108 | version: "0.9.11" 109 | code_builder: 110 | dependency: transitive 111 | description: 112 | name: code_builder 113 | url: "https://pub.dartlang.org" 114 | source: hosted 115 | version: "3.2.0" 116 | collection: 117 | dependency: transitive 118 | description: 119 | name: collection 120 | url: "https://pub.dartlang.org" 121 | source: hosted 122 | version: "1.14.11" 123 | convert: 124 | dependency: transitive 125 | description: 126 | name: convert 127 | url: "https://pub.dartlang.org" 128 | source: hosted 129 | version: "2.1.1" 130 | crypto: 131 | dependency: transitive 132 | description: 133 | name: crypto 134 | url: "https://pub.dartlang.org" 135 | source: hosted 136 | version: "2.0.6" 137 | cupertino_icons: 138 | dependency: "direct main" 139 | description: 140 | name: cupertino_icons 141 | url: "https://pub.dartlang.org" 142 | source: hosted 143 | version: "0.1.2" 144 | dart_internal: 145 | dependency: transitive 146 | description: 147 | name: dart_internal 148 | url: "https://pub.dartlang.org" 149 | source: hosted 150 | version: "0.1.5" 151 | dart_style: 152 | dependency: transitive 153 | description: 154 | name: dart_style 155 | url: "https://pub.dartlang.org" 156 | source: hosted 157 | version: "1.2.4" 158 | firebase_auth: 159 | dependency: "direct main" 160 | description: 161 | name: firebase_auth 162 | url: "https://pub.dartlang.org" 163 | source: hosted 164 | version: "0.8.4" 165 | firebase_core: 166 | dependency: transitive 167 | description: 168 | name: firebase_core 169 | url: "https://pub.dartlang.org" 170 | source: hosted 171 | version: "0.3.2" 172 | fixnum: 173 | dependency: transitive 174 | description: 175 | name: fixnum 176 | url: "https://pub.dartlang.org" 177 | source: hosted 178 | version: "0.10.9" 179 | flutter: 180 | dependency: "direct main" 181 | description: flutter 182 | source: sdk 183 | version: "0.0.0" 184 | flutter_localizations: 185 | dependency: "direct main" 186 | description: flutter 187 | source: sdk 188 | version: "0.0.0" 189 | flutter_test: 190 | dependency: "direct dev" 191 | description: flutter 192 | source: sdk 193 | version: "0.0.0" 194 | front_end: 195 | dependency: transitive 196 | description: 197 | name: front_end 198 | url: "https://pub.dartlang.org" 199 | source: hosted 200 | version: "0.1.14" 201 | glob: 202 | dependency: transitive 203 | description: 204 | name: glob 205 | url: "https://pub.dartlang.org" 206 | source: hosted 207 | version: "1.1.7" 208 | google_sign_in: 209 | dependency: "direct main" 210 | description: 211 | name: google_sign_in 212 | url: "https://pub.dartlang.org" 213 | source: hosted 214 | version: "4.0.1+3" 215 | graphs: 216 | dependency: transitive 217 | description: 218 | name: graphs 219 | url: "https://pub.dartlang.org" 220 | source: hosted 221 | version: "0.2.0" 222 | http: 223 | dependency: transitive 224 | description: 225 | name: http 226 | url: "https://pub.dartlang.org" 227 | source: hosted 228 | version: "0.12.0+2" 229 | http_multi_server: 230 | dependency: transitive 231 | description: 232 | name: http_multi_server 233 | url: "https://pub.dartlang.org" 234 | source: hosted 235 | version: "2.0.5" 236 | http_parser: 237 | dependency: transitive 238 | description: 239 | name: http_parser 240 | url: "https://pub.dartlang.org" 241 | source: hosted 242 | version: "3.1.3" 243 | intl: 244 | dependency: "direct main" 245 | description: 246 | name: intl 247 | url: "https://pub.dartlang.org" 248 | source: hosted 249 | version: "0.15.8" 250 | intl_translation: 251 | dependency: "direct dev" 252 | description: 253 | name: intl_translation 254 | url: "https://pub.dartlang.org" 255 | source: hosted 256 | version: "0.17.3" 257 | io: 258 | dependency: transitive 259 | description: 260 | name: io 261 | url: "https://pub.dartlang.org" 262 | source: hosted 263 | version: "0.3.3" 264 | js: 265 | dependency: transitive 266 | description: 267 | name: js 268 | url: "https://pub.dartlang.org" 269 | source: hosted 270 | version: "0.6.1+1" 271 | json_annotation: 272 | dependency: transitive 273 | description: 274 | name: json_annotation 275 | url: "https://pub.dartlang.org" 276 | source: hosted 277 | version: "2.1.0" 278 | kernel: 279 | dependency: transitive 280 | description: 281 | name: kernel 282 | url: "https://pub.dartlang.org" 283 | source: hosted 284 | version: "0.3.14" 285 | logging: 286 | dependency: "direct main" 287 | description: 288 | name: logging 289 | url: "https://pub.dartlang.org" 290 | source: hosted 291 | version: "0.11.3+2" 292 | matcher: 293 | dependency: transitive 294 | description: 295 | name: matcher 296 | url: "https://pub.dartlang.org" 297 | source: hosted 298 | version: "0.12.5" 299 | meta: 300 | dependency: transitive 301 | description: 302 | name: meta 303 | url: "https://pub.dartlang.org" 304 | source: hosted 305 | version: "1.1.6" 306 | mime: 307 | dependency: transitive 308 | description: 309 | name: mime 310 | url: "https://pub.dartlang.org" 311 | source: hosted 312 | version: "0.9.6+2" 313 | observable: 314 | dependency: "direct main" 315 | description: 316 | name: observable 317 | url: "https://pub.dartlang.org" 318 | source: hosted 319 | version: "0.22.2" 320 | package_config: 321 | dependency: transitive 322 | description: 323 | name: package_config 324 | url: "https://pub.dartlang.org" 325 | source: hosted 326 | version: "1.0.5" 327 | package_resolver: 328 | dependency: transitive 329 | description: 330 | name: package_resolver 331 | url: "https://pub.dartlang.org" 332 | source: hosted 333 | version: "1.0.10" 334 | path: 335 | dependency: transitive 336 | description: 337 | name: path 338 | url: "https://pub.dartlang.org" 339 | source: hosted 340 | version: "1.6.2" 341 | path_provider: 342 | dependency: "direct main" 343 | description: 344 | name: path_provider 345 | url: "https://pub.dartlang.org" 346 | source: hosted 347 | version: "0.5.0+1" 348 | pedantic: 349 | dependency: transitive 350 | description: 351 | name: pedantic 352 | url: "https://pub.dartlang.org" 353 | source: hosted 354 | version: "1.7.0" 355 | petitparser: 356 | dependency: transitive 357 | description: 358 | name: petitparser 359 | url: "https://pub.dartlang.org" 360 | source: hosted 361 | version: "2.2.1" 362 | pool: 363 | dependency: transitive 364 | description: 365 | name: pool 366 | url: "https://pub.dartlang.org" 367 | source: hosted 368 | version: "1.4.0" 369 | pub_semver: 370 | dependency: transitive 371 | description: 372 | name: pub_semver 373 | url: "https://pub.dartlang.org" 374 | source: hosted 375 | version: "1.4.2" 376 | pubspec_parse: 377 | dependency: transitive 378 | description: 379 | name: pubspec_parse 380 | url: "https://pub.dartlang.org" 381 | source: hosted 382 | version: "0.1.4" 383 | quiver: 384 | dependency: "direct main" 385 | description: 386 | name: quiver 387 | url: "https://pub.dartlang.org" 388 | source: hosted 389 | version: "2.0.3" 390 | rxdart: 391 | dependency: "direct main" 392 | description: 393 | name: rxdart 394 | url: "https://pub.dartlang.org" 395 | source: hosted 396 | version: "0.21.0" 397 | scoped_model: 398 | dependency: "direct main" 399 | description: 400 | name: scoped_model 401 | url: "https://pub.dartlang.org" 402 | source: hosted 403 | version: "1.0.1" 404 | shared_preferences: 405 | dependency: "direct main" 406 | description: 407 | name: shared_preferences 408 | url: "https://pub.dartlang.org" 409 | source: hosted 410 | version: "0.5.1+2" 411 | shelf: 412 | dependency: transitive 413 | description: 414 | name: shelf 415 | url: "https://pub.dartlang.org" 416 | source: hosted 417 | version: "0.7.5" 418 | shelf_web_socket: 419 | dependency: transitive 420 | description: 421 | name: shelf_web_socket 422 | url: "https://pub.dartlang.org" 423 | source: hosted 424 | version: "0.2.2+5" 425 | simple_logger: 426 | dependency: "direct main" 427 | description: 428 | name: simple_logger 429 | url: "https://pub.dartlang.org" 430 | source: hosted 431 | version: "1.4.1" 432 | sky_engine: 433 | dependency: transitive 434 | description: flutter 435 | source: sdk 436 | version: "0.0.99" 437 | source_gen: 438 | dependency: "direct dev" 439 | description: 440 | name: source_gen 441 | url: "https://pub.dartlang.org" 442 | source: hosted 443 | version: "0.9.4+2" 444 | source_span: 445 | dependency: transitive 446 | description: 447 | name: source_span 448 | url: "https://pub.dartlang.org" 449 | source: hosted 450 | version: "1.5.5" 451 | stack_trace: 452 | dependency: transitive 453 | description: 454 | name: stack_trace 455 | url: "https://pub.dartlang.org" 456 | source: hosted 457 | version: "1.9.3" 458 | stream_channel: 459 | dependency: transitive 460 | description: 461 | name: stream_channel 462 | url: "https://pub.dartlang.org" 463 | source: hosted 464 | version: "2.0.0" 465 | stream_transform: 466 | dependency: transitive 467 | description: 468 | name: stream_transform 469 | url: "https://pub.dartlang.org" 470 | source: hosted 471 | version: "0.0.17" 472 | string_scanner: 473 | dependency: transitive 474 | description: 475 | name: string_scanner 476 | url: "https://pub.dartlang.org" 477 | source: hosted 478 | version: "1.0.4" 479 | term_glyph: 480 | dependency: transitive 481 | description: 482 | name: term_glyph 483 | url: "https://pub.dartlang.org" 484 | source: hosted 485 | version: "1.1.0" 486 | test_api: 487 | dependency: transitive 488 | description: 489 | name: test_api 490 | url: "https://pub.dartlang.org" 491 | source: hosted 492 | version: "0.2.5" 493 | timing: 494 | dependency: transitive 495 | description: 496 | name: timing 497 | url: "https://pub.dartlang.org" 498 | source: hosted 499 | version: "0.1.1+1" 500 | tuple: 501 | dependency: "direct main" 502 | description: 503 | name: tuple 504 | url: "https://pub.dartlang.org" 505 | source: hosted 506 | version: "1.0.2" 507 | typed_data: 508 | dependency: transitive 509 | description: 510 | name: typed_data 511 | url: "https://pub.dartlang.org" 512 | source: hosted 513 | version: "1.1.6" 514 | vector_math: 515 | dependency: transitive 516 | description: 517 | name: vector_math 518 | url: "https://pub.dartlang.org" 519 | source: hosted 520 | version: "2.0.8" 521 | watcher: 522 | dependency: transitive 523 | description: 524 | name: watcher 525 | url: "https://pub.dartlang.org" 526 | source: hosted 527 | version: "0.9.7+10" 528 | web_socket_channel: 529 | dependency: transitive 530 | description: 531 | name: web_socket_channel 532 | url: "https://pub.dartlang.org" 533 | source: hosted 534 | version: "1.0.12" 535 | yaml: 536 | dependency: transitive 537 | description: 538 | name: yaml 539 | url: "https://pub.dartlang.org" 540 | source: hosted 541 | version: "2.1.15" 542 | sdks: 543 | dart: ">=2.2.2 <2.5.0" 544 | flutter: ">=1.2.0 <2.0.0" 545 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: taskshare 2 | description: A new Flutter project. 3 | version: 1.0.0+1 4 | dependencies: 5 | flutter: 6 | sdk: flutter 7 | flutter_localizations: 8 | sdk: flutter 9 | cupertino_icons: 10 | firebase_auth: 11 | google_sign_in: 12 | scoped_model: 13 | logging: 14 | path_provider: 15 | rxdart: 16 | cloud_firestore: 17 | # cached_network_image: 18 | shared_preferences: 19 | intl: 20 | built_value: 21 | quiver: 22 | tuple: 23 | bloc_provider: 24 | simple_logger: 25 | observable: 26 | dev_dependencies: 27 | flutter_test: 28 | sdk: flutter 29 | intl_translation: 30 | build: 31 | build_runner: 32 | source_gen: 33 | flutter: 34 | uses-material-design: true 35 | -------------------------------------------------------------------------------- /res/values/strings_en.arb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TaskShare/taskshare-flutter/3aa23300094f4b0af63595c2697191a5053db0e0/res/values/strings_en.arb -------------------------------------------------------------------------------- /test/model/task_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | import 'package:taskshare/model/task.dart'; 3 | 4 | import '../test.dart'; 5 | 6 | bool isSame(Task a, Task b) { 7 | return a == b && 8 | a.title == b.title && 9 | a.doneTime == b.doneTime && 10 | a.dueTime == b.dueTime && 11 | a.createTime == b.createTime && 12 | a.updateTime == b.updateTime; 13 | } 14 | 15 | void main() { 16 | test('TaskDecoder test', () { 17 | final data = { 18 | 'id': 'id_test', 19 | 'title': 'title_test', 20 | 'doneTime': Timestamp.fromDate(DateTime(2000)), 21 | 'dueTime': Timestamp.fromDate(DateTime(2001)), 22 | 'createTime': Timestamp.fromDate(DateTime(2002)), 23 | 'updateTime': Timestamp.fromDate(DateTime(2003)) 24 | }; 25 | final decoder = TaskDecoder(); 26 | final task = decoder.decode(data); 27 | expect( 28 | isSame( 29 | task, 30 | Task( 31 | id: 'id_test', 32 | title: 'title_test', 33 | doneTime: Timestamp.fromDate(DateTime(2000)), 34 | dueTime: Timestamp.fromDate(DateTime(2001)), 35 | createTime: Timestamp.fromDate(DateTime(2002)), 36 | updateTime: Timestamp.fromDate(DateTime(2003)), 37 | ), 38 | ), 39 | true, 40 | ); 41 | }); 42 | 43 | test('TaskEncoder test', () { 44 | final encoder = TaskEncoder(); 45 | final data = encoder.encode(Task( 46 | id: 'id_test', 47 | title: 'title_test', 48 | doneTime: Timestamp.fromDate(DateTime(2000)), 49 | dueTime: Timestamp.fromDate(DateTime(2001)), 50 | createTime: Timestamp.fromDate(DateTime(2002)), 51 | updateTime: Timestamp.fromDate(DateTime(2003)))); 52 | expect( 53 | { 54 | 'id': 'id_test', 55 | 'title': 'title_test', 56 | 'doneTime': Timestamp.fromDate(DateTime(2000)), 57 | 'dueTime': Timestamp.fromDate(DateTime(2001)), 58 | 'createTime': Timestamp.fromDate(DateTime(2002)), 59 | 'updateTime': Timestamp.fromDate(DateTime(2003)) 60 | }, 61 | data, 62 | ); 63 | }); 64 | } 65 | -------------------------------------------------------------------------------- /test/test.dart: -------------------------------------------------------------------------------- 1 | export 'package:taskshare/lib.dart'; 2 | export 'package:flutter_test/flutter_test.dart'; --------------------------------------------------------------------------------