diff --git a/.gitignore b/.gitignore index ec275280..441f8df8 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release +/example/linux/flutter/emphemeral/.plugin_symlinks diff --git a/.metadata b/.metadata new file mode 100644 index 00000000..019302aa --- /dev/null +++ b/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 135454af32477f815a7525073027a3ff9eff1bfd + channel: stable + +project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + - platform: android + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/CHANGELOG.md b/CHANGELOG.md index 9082b9a9..4a118b15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,101 @@ +# 1.0.4 + +- FIX: Removed leftover plugin declaration and unused native iOS/Android stubs - survey_kit is now a pure Dart package, fixing the "does not support Swift Package Manager" warning + +# 1.0.3 + +- CHORE: Removed depracted lint `package_api_docs` +- FIX: Refactored SurveyStateProvider to follow proper InheritedWidget pattern - separated mutable state into StatefulWidget wrapper to prevent reinstantiation on rebuilds +- FIX: Fixed SurveyStateProvider state persistence by using SurveyStateProviderWidget (StatefulWidget) with immutable SurveyStateProvider (InheritedWidget) + +# 1.0.2 + +- INFO: Update use `dart:ui_web`instead if `dart:ui` + +# 1.0.1 + +- CHORE: Upgrade dependencies to latest Flutter Version 3.35.2 + +# 1.0.0-dev.10 + +- BREAKING: Removed image_picker for to avoid permission issues (Will be readded with 1.0.0 as separate package) + +# 1.0.0-dev.9 + +- CHORE: Expose backgroundColor param for SurveyPage + +# 1.0.0-dev.8 + +- INFO: Support AGP 8.x, bump compileSdk to 34 + +# 1.0.0-dev.7 + +- INFO: Updated dependencies to latest Flutter Version 3.24.5 + +# 1.0.0-dev.6 + +- INFO: Revert intl dependency to 0.18.1 because of Flutter incompatibility issues + +# 1.0.0-dev.5 + +- INFO: Updated dependencies to latest Flutter Version 3.19.5 + +# 1.0.0-dev.4 + +- INFO: Revert intl dependency to 0.18.0 + +# 1.0.0-dev.3 + +- INFO: Update dependencies + +# 1.0.0-dev.2 + +- BREAKING: `resultToStepIdentifierMapper` now also returns the previous results + - (StepResult? result) -> (List results, StepResult? result) +- BUGFIX: Fixed a bug where `resultToStepIdentifierMapper` was not called when the result was null + +# 1.0.0-dev.1 + +- INFO: We we completly reworked how survey_kit works and want to get it to a stable release version 1.0 +- BREAKING: Enum BooleanResult is now lowercase +- BREAKING: Enum FinishReason is now lowercase +- BREAKING: Id's are now simple Strings +- BREAKING: TextChoice is not const anymore +- BREAKING: SurveyResult: Every Step has now one Result with a generic parameter instead of different objects +- BREAKING: Return typoe of the boolean step is now a TimeResult objects which wraps TimeOfDay +- FEATURE: survey_kit is now more dynamic and every content can be used before the question + - VideoContent + - AudioContent + - MarkdownContent + - TextContent + - LottieContent +- FEATURE: MeasureDateStateMixin to measure when the user entered and left a step +- FEATURE: PreviousStepResultMixin: If one of your steps depends on a previous step just implement this mixin and you can access the previous result +- CHORE: Updated dependecies + +HOW TO MIGRATE: + +- JSON +- Code-Definition + +# 0.1.2 + +- INFO: Update dependencies (Flutter 3.7.0) + # 0.1.1 + - INFO: Update dependencies (Flutter 3.0.2) + # 0.1.0 + - INFO: Updated dependencies + # 0.0.21 + - BREAKING: Adapated text styles to to TextThemes - You can find a complete list in the README.md # 0.0.20 + - BREAKING: Value identifier for Single-/Multiplechoice answers is now the value - BREAKING: You now have to close the survey yourself when finished in onResult - BREAKING: Remove video player step for now because of dependency issues (If you rely on it use https://github.com/quickbirdstudios/survey_kit.git) @@ -21,6 +111,7 @@ - INFO: Updated dependencies # 0.0.12 + - FEATURE: Video-Step - BUGFIX: isOptional Parameter works now as expected @@ -56,4 +147,4 @@ Initial Version of the library. -- Includes the ability to create a surveys with prebuild and customs step. \ No newline at end of file +- Includes the ability to create a surveys with prebuild and customs step. diff --git a/README.md b/README.md index 7824bf26..19beb037 100644 --- a/README.md +++ b/README.md @@ -25,20 +25,36 @@ This is an early version and work in progress. Do not hesitate to give feedback, | | | | | | ## 📚 Overview: Creating Research Surveys -- [What SurveyKit does for you](#what-surveykit-does-for-you) -- [What SurveyKit does not (yet) do for you](#what-surveykit-does-not-yet-do-for-you) -- [🏃 Setup](#-🏃-setup) +- [SurveyKit: Create beautiful surveys with Flutter (inspired by iOS ResearchKit Surveys)](#surveykit-create-beautiful-surveys-with-flutter-inspired-by-ios-researchkit-surveys) +- [Examples](#examples) + - [Flow](#flow) + - [Screenshots](#screenshots) + - [📚 Overview: Creating Research Surveys](#-overview-creating-research-surveys) + - [What SurveyKit does for you](#what-surveykit-does-for-you) + - [What SurveyKit does not (yet) do for you](#what-surveykit-does-not-yet-do-for-you) +- [🏃 Setup](#-setup) - [1. Add the dependecy](#1-add-the-dependecy) - [2. Install it](#2-install-it) - [3. Import it](#3-import-it) - [💻 Usage](#-usage) - - [Create survey steps](#create-survey-steps) - - [Create a Task](#create-a-task) - - [Evaluate the results](#evaluate-the-results) - - [Style](#style) - - [Start the survey](#start-the-survey) -- [📇 Custom steps](#-custom-steps) -- [🍏vs🤖 : Comparison of Flutter SurveyKit, SurveyKit on Android to ResearchKit on iOS](#-🍏vs🤖-:-comparison-of-flutter-surveykit,-surveykit-on-android-to-researchkit-on-iOS) + - [Example](#example) + - [Create survey steps](#create-survey-steps) + - [`Step`](#step) + - [`InstructionStep`](#instructionstep) + - [`CompletionStep`](#completionstep) + - [`QuestionStep`](#questionstep) + - [Create a Task](#create-a-task) + - [OrderedTask](#orderedtask) + - [NavigableOrderedTask](#navigableorderedtask) + - [Evaluate the results](#evaluate-the-results) + - [Export the results to JSON](#export-the-results-to-json) + - [Style](#style) + - [Localization](#localization) + - [Start the survey](#start-the-survey) +- [📇 Custom content widgets](#-custom-content-widgets) +- [📇 Custom answer formats](#-custom-answer-formats) +- [🍏vs🤖 : Comparison of Flutter SurveyKit, SurveyKit on Android to ResearchKit on iOS](#vs--comparison-of-flutter-surveykit-surveykit-on-android-to-researchkit-on-ios) +- [🤖 : Create your Survey via JSON](#--create-your-survey-via-json) - [👤 Author](#-author) - [❤️ Contributing](#️-contributing) - [📃 License](#-license) @@ -57,7 +73,7 @@ This is an early version and work in progress. Do not hesitate to give feedback, As stated before, this is an early version and a work in progress. We aim to extend this library until it matches the functionality of the [iOS ResearchKit Surveys](https://researchkit.org/docs/docs/Survey/CreatingSurveys.html). # 🏃 Setup -To use this plugin, add flutter_surveykit as a dependency in your pubspec.yaml file. +To use this plugin, add survey_kit as a dependency in your pubspec.yaml file. ## 1. Add the dependecy `pubspec.yaml` @@ -81,7 +97,42 @@ import 'package:survey_kit/survey_kit.dart'; A working example project can be found [HERE](example/) ### Create survey steps -To create a step, create an instance of one of these 3 classes: +To create a step, just use the Step class of survey_kit + +#### `Step` +```dart +Step( + content: [ + TextContent('Your journey starts here',), + TextContent('Have fun with a quick survey',), + ], + buttonText: 'Start survey', + answerFormat: TextAnswerFormat( + maxLines: 5, + ), +); +``` + +The `content` is the general content that you want to display before your question. You can use these content in any particular order. Currently supported are: +- `TextContent` +- `MarkdownContent` +- `VideoContent` +- `AudioContent` +- `LottieContent` +- `TextAnswerFormat` +- `IntegerAnswerFormat` +- `ScaleAnswerFormat` +- `SingleChoiceAnswerFormat` +- `MultipleChoiceAnswerFormat` +- `BooleanAnswerFormat` +- `DateAnswerFormat` +- `TimeAnswerFormat` +- `DoubleAnswerFormat` +- `ImageAnswerFormat` +- `MultiChoiceAutoCompleteAnswerFormat` + +Or you can also use one of our predefined steps. + #### `InstructionStep` ```dart InstructionStep( @@ -93,7 +144,6 @@ InstructionStep( The `title` is the general title of the Survey you want to conduct. The `text` is, in this case, the introduction text which should give an introduction, about what the survey is about. The `buttonText` specifies the text of the button, which will start the survey. -All of these properties have to be resource Ids. #### `CompletionStep` ```dart @@ -106,7 +156,6 @@ CompletionStep( The `title` is the general title of the Survey you want to conduct, same as for the `InstructionStep`. The `text` is here should be something motivational: that the survey has been completed successfully. The `buttonText` specifies the text of the button, which will end the survey. -All of these properties have to be resource Ids. #### `QuestionStep` ```dart @@ -120,13 +169,7 @@ QuestionStep( ``` The `title` same as for the `InstructionStep` and `CompletionStep`. The `text` the actual question you want to ask. Depending on the answer type of this, you should set the next property. -The `answerFormat` specifies the type of question (the type of answer to the question) you want to ask. Currently there these types supported: -- `TextAnswerFormat` -- `IntegerAnswerFormat` -- `ScaleAnswerFormat` -- `SingleChoiceAnswerFormat` -- `MultipleChoiceAnswerFormat` -- `BooleanAnswerFormat` + All that's left is to collect your steps in a list or add them inline in the widget. ```dart @@ -181,7 +224,7 @@ task.addNavigationRule( ### Evaluate the results When the survey is finished, you get a callback. No matter of the `FinishReason`, you always get all results gathered until now. -The `SurveyResult` contains a list of `StepResult`s and the `FinishReason`. The `StepResult` contains a list of `QuestionResult`s. +The `SurveyResult` contains a list of `StepResult`s and the `FinishReason`. ```dart SurveyKit( onResult: (SurveyResult result) { @@ -210,8 +253,6 @@ The styling can be adjusted by the build in Flutter theme. | textTheme | Used in | |-------------|-----------------------------| -| headline2 | Title of question | -| headline5 | Text of question | | bodyText2 | Text of ListTiles | | subtitle1 | Textstyle used in TextFields| @@ -248,57 +289,17 @@ Scaffold( ); ``` - -# 📇 Custom steps +# 📇 Custom content widgets +##TODO +# 📇 Custom answer formats At some point, you might wanna define your own custom question steps. That could, for example, be a question which prompts the user to pick color values or even sound samples. These are not implemented yet but you can easily create them yourself: -You'll need a `CustomResult` and a `CustomStep`. The Result class tells SurveyKit which data you want to save. -```dart -class CustomResult extends QuestionResult { - final String customData; - final String valueIdentifier; - final Identifier identifier; - final DateTime startDate; - final DateTime endDate; - final String value; //Custom value -} -``` -Next you'll need a CustomStep class. It is recommended to use the `StepView` widget as your foundation. It gives you the AppBar and the next button. -```dart -class CustomStep extends Step { - final String title; - final String text; - - CustomStep({ - @required StepIdentifier id, - bool isOptional = false, - String buttonText = 'Next', - this.title, - this.text, - }) : super(isOptional, id, buttonText); - - @override - Widget createView({@required QuestionResult questionResult}) { - return StepView( - step: widget.questionStep, - result: () => CustomResult( - id: id, - startDate: DateTime.now(), - endDate: DateTime.now(), - valueIdentifier: 'custom'//Identification for NavigableTask, - result: 'custom_result', - ), - title: Text('Title'), - child: Container(), //Add your view here - ); - } -} -``` +##TODO -If you want to create a complete custom view or just override the navigation behavior you should use the SurveyController with its three methods: +If you want to create a complete custom view or just override the navigation behavior you should use the SurveyController with has these three methods: * onNextStep() * onStepBack() * onCloseSurvey() @@ -318,89 +319,9 @@ To create your survey in JSON is almost as easy as in Dart. Just call ```dart Task.fromJson() ``` with your JSON-File or Response. The JSON should look like this: ```json -{ - "id": "123", - "type": "navigable", - "rules": [ - { - "type": "conditional", - "triggerStepIdentifier": { - "id": "3" - }, - "values": { - "Yes": "2", - "No": "10" - } - }, - { - "type": "direct", - "triggerStepIdentifier": { - "id": "1" - }, - "destinationStepIdentifier": { - "id": "3" - } - }, - { - "type": "direct", - "triggerStepIdentifier": { - "id": "2" - }, - "destinationStepIdentifier": { - "id": "10" - } - } - ], - "steps": [ - { - "stepIdentifier": { - "id": "1" - }, - "type": "intro", - "title": "Welcome to the\nQuickBird Studios\nHealth Survey", - "text": "Get ready for a bunch of super random questions!", - "buttonText": "Let's go!" - }, - { - "stepIdentifier": { - "id": "2" - }, - "type": "question", - "title": "How old are you?", - "answerFormat": { - "type": "integer", - "defaultValue": 25, - "hint": "Please enter your age" - } - }, - { - "stepIdentifier": { - "id": "3" - }, - "type": "question", - "title": "Medication?", - "text": "Are you using any medication", - "answerFormat": { - "type": "bool", - "positiveAnswer": "Yes", - "negativeAnswer": "No", - "result": "POSITIVE" - } - }, - { - "stepIdentifier": { - "id": "10" - }, - "type": "completion", - "text": "Thanks for taking the survey, we will contact you soon!", - "title": "Done!", - "buttonText": "Submit survey" - } - ] -} +##TODO ``` - You can find the complete example [HERE](https://github.com/quickbirdstudios/survey_kit/blob/main/example/assets/example_json.json) diff --git a/analysis_option.yaml b/analysis_option.yaml deleted file mode 100644 index 7febab12..00000000 --- a/analysis_option.yaml +++ /dev/null @@ -1,233 +0,0 @@ -# Specify analysis options. -# -# Until there are meta linter rules, each desired lint must be explicitly enabled. -# See: https://github.com/dart-lang/linter/issues/288 -# -# For a list of lints, see: http://dart-lang.github.io/linter/lints/ -# See the configuration guide for more -# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer -# -# There are other similar analysis options files in the flutter repos, -# which should be kept in sync with this file: -# -# - analysis_options.yaml (this file) -# - packages/flutter/lib/analysis_options_user.yaml -# - https://github.com/flutter/plugins/blob/master/analysis_options.yaml -# - https://github.com/flutter/engine/blob/master/analysis_options.yaml -# -# This file contains the analysis options used by Flutter tools, such as IntelliJ, -# Android Studio, and the `flutter analyze` command. -include: package:extra_pedantic/analysis_options.yaml - -exclude: - - "**/*.g.dart" - -analyzer: - strong-mode: - implicit-casts: false - implicit-dynamic: false - errors: - # treat missing required parameters as a warning (not a hint) - missing_required_param: warning - # treat missing returns as a warning (not a hint) - missing_return: warning - # allow having TODOs in the code - todo: ignore - # allow self-reference to deprecated members (we do this because otherwise we have - # to annotate every member in every test, assert, etc, when we deprecate something) - deprecated_member_use_from_same_package: ignore - # Ignore analyzer hints for updating pubspecs when using Future or - # Stream and not importing dart:async - # Please see https://github.com/flutter/flutter/pull/24528 for details. - sdk_version_async_exported_from_core: ignore - exclude: - - "bin/cache/**" - # the following two are relative to the stocks example and the flutter package respectively - # see https://github.com/dart-lang/sdk/issues/28463 - - "lib/i18n/messages_*.dart" - - "lib/src/http/**" - - "test_fixes/**" - -linter: - rules: - # these rules are documented on and in the same order as - # the Dart Lint rules page to make maintenance easier - # https://github.com/dart-lang/linter/blob/master/example/all.yaml - - always_declare_return_types - - always_put_control_body_on_new_line - # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 - - always_require_non_null_named_parameters - - always_specify_types - # - always_use_package_imports # we do this commonly - - annotate_overrides - # - avoid_annotating_with_dynamic # conflicts with always_specify_types - # - avoid_as # required for implicit-casts: true - - avoid_bool_literals_in_conditional_expressions - # - avoid_catches_without_on_clauses # we do this commonly - # - avoid_catching_errors # we do this commonly - - avoid_classes_with_only_static_members - # - avoid_double_and_int_checks # only useful when targeting JS runtime - - avoid_empty_else - - avoid_equals_and_hash_code_on_mutable_classes - # - avoid_escaping_inner_quotes # not yet tested - - avoid_field_initializers_in_const_classes - - avoid_function_literals_in_foreach_calls - # - avoid_implementing_value_types # not yet tested - - avoid_init_to_null - # - avoid_js_rounded_ints # only useful when targeting JS runtime - - avoid_null_checks_in_equality_operators - # - avoid_positional_boolean_parameters # not yet tested - # - avoid_print # not yet tested - # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) - # - avoid_redundant_argument_values # not yet tested - - avoid_relative_lib_imports - - avoid_renaming_method_parameters - - avoid_return_types_on_setters - # - avoid_returning_null # there are plenty of valid reasons to return null - # - avoid_returning_null_for_future # not yet tested - - avoid_returning_null_for_void - # - avoid_returning_this # there are plenty of valid reasons to return this - # - avoid_setters_without_getters # not yet tested - - avoid_shadowing_type_parameters - - avoid_single_cascade_in_expression_statements - - avoid_slow_async_io - # - avoid_type_to_string # we do this commonly - - avoid_types_as_parameter_names - # - avoid_types_on_closure_parameters # conflicts with always_specify_types - # - avoid_unnecessary_containers # not yet tested - - avoid_unused_constructor_parameters - - avoid_void_async - # - avoid_web_libraries_in_flutter # not yet tested - - await_only_futures - - camel_case_extensions - - camel_case_types - - cancel_subscriptions - # - cascade_invocations # not yet tested - - cast_nullable_to_non_nullable - # - close_sinks # not reliable enough - # - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 - # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 - - control_flow_in_finally - # - curly_braces_in_flow_control_structures # not required by flutter style - # - diagnostic_describe_all_properties # not yet tested - - directives_ordering - # - do_not_use_environment # we do this commonly - - empty_catches - - empty_constructor_bodies - - empty_statements - - exhaustive_cases - # - file_names # not yet tested - - flutter_style_todos - - hash_and_equals - - implementation_imports - # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 - - iterable_contains_unrelated_type - # - join_return_with_assignment # not required by flutter style - - leading_newlines_in_multiline_strings - - library_names - - library_prefixes - # - lines_longer_than_80_chars # not required by flutter style - - list_remove_unrelated_type - # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 - # - missing_whitespace_between_adjacent_strings # not yet tested - - no_adjacent_strings_in_list - # - no_default_cases # too many false positives - - no_duplicate_case_values - - no_logic_in_create_state - # - no_runtimeType_toString # ok in tests; we enable this only in packages/ - - non_constant_identifier_names - - null_check_on_nullable_type_parameter - # - null_closures # not required by flutter style - # - omit_local_variable_types # opposite of always_specify_types - # - one_member_abstracts # too many false positives - # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 - - overridden_fields - - package_api_docs - # - package_names # non conforming packages in sdk - - package_prefixed_library_names - # - parameter_assignments # we do this commonly - - prefer_adjacent_string_concatenation - - prefer_asserts_in_initializer_lists - # - prefer_asserts_with_message # not required by flutter style - - prefer_collection_literals - - prefer_conditional_assignment - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_const_literals_to_create_immutables - # - prefer_constructors_over_static_methods # far too many false positives - - prefer_contains - # - prefer_double_quotes # opposite of prefer_single_quotes - - prefer_equal_for_default_values - # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - - prefer_for_elements_to_map_fromIterable - - prefer_foreach - # - prefer_function_declarations_over_variables # not yet tested - - prefer_generic_function_type_aliases - - prefer_if_elements_to_conditional_expressions - - prefer_if_null_operators - - prefer_initializing_formals - - prefer_inlined_adds - # - prefer_int_literals # not yet tested - # - prefer_interpolation_to_compose_strings # not yet tested - - prefer_is_empty - - prefer_is_not_empty - - prefer_is_not_operator - - prefer_iterable_whereType - # - prefer_mixin # https://github.com/dart-lang/language/issues/32 - # - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 - # - prefer_relative_imports # not yet tested - - prefer_single_quotes - - prefer_spread_collections - - prefer_typing_uninitialized_variables - - prefer_void_to_null - # - provide_deprecation_message # not yet tested - # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml - - recursive_getters - # - sized_box_for_whitespace # not yet tested - - slash_for_doc_comments - # - sort_child_properties_last # not yet tested - - sort_constructors_first - # - sort_pub_dependencies # prevents separating pinned transitive dependencies - - sort_unnamed_constructors_first - - test_types_in_equals - - throw_in_finally - - tighten_type_of_initializing_formals - # - type_annotate_public_apis # subset of always_specify_types - - type_init_formals - # - unawaited_futures # too many false positives - # - unnecessary_await_in_return # not yet tested - - unnecessary_brace_in_string_interps - - unnecessary_const - # - unnecessary_final # conflicts with prefer_final_locals - - unnecessary_getters_setters - # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 - - unnecessary_new - - unnecessary_null_aware_assignments - # - unnecessary_null_checks # not yet tested - - unnecessary_null_in_if_null_operators - - unnecessary_nullable_for_final_variable_declarations - - unnecessary_overrides - - unnecessary_parenthesis - # - unnecessary_raw_strings # not yet tested - - unnecessary_statements - - unnecessary_string_escapes - - unnecessary_string_interpolations - - unnecessary_this - - unrelated_type_equality_checks - # - unsafe_html # not yet tested - - use_full_hex_values_for_flutter_colors - # - use_function_type_syntax_for_parameters # not yet tested - - use_is_even_rather_than_modulo - # - use_key_in_widget_constructors # not yet tested - - use_late_for_private_fields_and_variables - - use_raw_strings - - use_rethrow_when_possible - # - use_setters_to_change_properties # not yet tested - # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 - # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review - - valid_regexps - - void_checks \ No newline at end of file diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 00000000..9c41dda4 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,181 @@ +analyzer: + strong-mode: + implicit-casts: false + implicit-dynamic: false + + errors: + close_sinks: ignore + missing_required_param: error + missing_return: error + # Ignored because of freezed and JsonKey (https://github.com/rrousselGit/freezed/issues/488) + invalid_annotation_target: ignore + body_might_complete_normally_nullable: ignore + + exclude: + - test/.test_coverage.dart + - lib/generated_plugin_registrant.dart + - packages/** + - "**/*.g.dart" + - "**/*.freezed.dart" + +linter: + rules: + - always_declare_return_types + - always_use_package_imports + - annotate_overrides + - avoid_bool_literals_in_conditional_expressions + - avoid_catching_errors + - avoid_double_and_int_checks + - avoid_dynamic_calls + - avoid_empty_else + - avoid_equals_and_hash_code_on_mutable_classes + - avoid_escaping_inner_quotes + - avoid_field_initializers_in_const_classes + - avoid_function_literals_in_foreach_calls + - avoid_init_to_null + - avoid_js_rounded_ints + - avoid_null_checks_in_equality_operators + - avoid_positional_boolean_parameters + - avoid_print + # - avoid_private_typedef_functions + # - avoid_redundant_argument_values + - avoid_relative_lib_imports + - avoid_renaming_method_parameters + - avoid_return_types_on_setters + - avoid_returning_null_for_void + - avoid_returning_this + - avoid_setters_without_getters + - avoid_shadowing_type_parameters + - avoid_single_cascade_in_expression_statements + - avoid_slow_async_io + - avoid_type_to_string + - avoid_types_as_parameter_names + - avoid_unnecessary_containers + - avoid_unused_constructor_parameters + - avoid_void_async + - avoid_web_libraries_in_flutter + - await_only_futures + - camel_case_extensions + - camel_case_types + - cancel_subscriptions + - cascade_invocations + - cast_nullable_to_non_nullable + # - comment_references + - constant_identifier_names + - control_flow_in_finally + - curly_braces_in_flow_control_structures + - deprecated_consistency + - directives_ordering + - empty_catches + - empty_constructor_bodies + - empty_statements + # - eol_at_end_of_file + - exhaustive_cases + - file_names + - flutter_style_todos + - hash_and_equals + - implementation_imports + - join_return_with_assignment + - leading_newlines_in_multiline_strings + - library_names + - library_prefixes + # - library_private_types_in_public_api + # - lines_longer_than_80_chars + - literal_only_boolean_expressions + - missing_whitespace_between_adjacent_strings + - no_adjacent_strings_in_list + - no_default_cases + - no_duplicate_case_values + - no_logic_in_create_state + - no_runtimeType_toString + - non_constant_identifier_names + # - noop_primitive_operations + - null_check_on_nullable_type_parameter + - null_closures + - omit_local_variable_types + - only_throw_errors + - overridden_fields + - package_names + - package_prefixed_library_names + - parameter_assignments + - prefer_adjacent_string_concatenation + - prefer_asserts_in_initializer_lists + - prefer_asserts_with_message + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_const_constructors_in_immutables + - prefer_const_declarations + - prefer_const_literals_to_create_immutables + - prefer_constructors_over_static_methods + - prefer_contains + - prefer_final_fields + - prefer_final_in_for_each + - prefer_final_locals + - prefer_for_elements_to_map_fromIterable + - prefer_function_declarations_over_variables + - prefer_generic_function_type_aliases + - prefer_if_elements_to_conditional_expressions + - prefer_if_null_operators + - prefer_initializing_formals + - prefer_inlined_adds + # - prefer_int_literals + - prefer_interpolation_to_compose_strings + - prefer_is_empty + - prefer_is_not_empty + - prefer_is_not_operator + - prefer_iterable_whereType + - prefer_null_aware_operators + # - prefer_null_aware_method_calls + - prefer_single_quotes + - prefer_spread_collections + - prefer_typing_uninitialized_variables + - prefer_void_to_null + - provide_deprecation_message + # - public_member_api_docs + - recursive_getters + - require_trailing_commas + # - sized_box_for_whitespace //To error prone + - slash_for_doc_comments + - sort_child_properties_last + # - sort_constructors_first + - sort_pub_dependencies + - sort_unnamed_constructors_first + - test_types_in_equals + - throw_in_finally + - tighten_type_of_initializing_formals + - type_annotate_public_apis + - type_init_formals + - unawaited_futures + - unnecessary_await_in_return + - unnecessary_brace_in_string_interps + - unnecessary_const + - unnecessary_getters_setters + - unnecessary_lambdas + - unnecessary_new + - unnecessary_null_aware_assignments + - unnecessary_null_checks + - unnecessary_null_in_if_null_operators + - unnecessary_nullable_for_final_variable_declarations + - unnecessary_overrides + - unnecessary_parenthesis + - unnecessary_raw_strings + - unnecessary_statements + - unnecessary_string_escapes + - unnecessary_string_interpolations + - unnecessary_this + - unrelated_type_equality_checks + # - use_build_context_synchronously + - use_full_hex_values_for_flutter_colors + - use_function_type_syntax_for_parameters + - use_is_even_rather_than_modulo + - use_key_in_widget_constructors + - use_late_for_private_fields_and_variables + - use_named_constants + - use_raw_strings + - use_rethrow_when_possible + - use_setters_to_change_properties + - use_string_buffers + - use_to_and_as_if_applicable + - valid_regexps + - void_checks diff --git a/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java deleted file mode 100644 index 6aa3b529..00000000 --- a/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.flutter.plugins; - -import io.flutter.plugin.common.PluginRegistry; -import io.flutter.plugins.camera.CameraPlugin; -import io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin; -import io.flutter.plugins.imagepicker.ImagePickerPlugin; -import io.flutter.plugins.videoplayer.VideoPlayerPlugin; - -/** - * Generated file. Do not edit. - */ -public final class GeneratedPluginRegistrant { - public static void registerWith(PluginRegistry registry) { - if (alreadyRegisteredWith(registry)) { - return; - } - CameraPlugin.registerWith(registry.registrarFor("io.flutter.plugins.camera.CameraPlugin")); - FlutterAndroidLifecyclePlugin.registerWith(registry.registrarFor("io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin")); - ImagePickerPlugin.registerWith(registry.registrarFor("io.flutter.plugins.imagepicker.ImagePickerPlugin")); - VideoPlayerPlugin.registerWith(registry.registrarFor("io.flutter.plugins.videoplayer.VideoPlayerPlugin")); - } - - private static boolean alreadyRegisteredWith(PluginRegistry registry) { - final String key = GeneratedPluginRegistrant.class.getCanonicalName(); - if (registry.hasPlugin(key)) { - return true; - } - registry.registrarFor(key); - return false; - } -} diff --git a/devtools_options.yaml b/devtools_options.yaml new file mode 100644 index 00000000..fa0b357c --- /dev/null +++ b/devtools_options.yaml @@ -0,0 +1,3 @@ +description: This file stores settings for Dart & Flutter DevTools. +documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states +extensions: diff --git a/example/.gitignore b/example/.gitignore index 0fa6b675..8e289d78 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -44,3 +44,5 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + +/linux/flutter/ephemeral/ diff --git a/example/.metadata b/example/.metadata index 36a46146..24a13c13 100644 --- a/example/.metadata +++ b/example/.metadata @@ -4,7 +4,42 @@ # This file should be version controlled and should not be manually edited. version: - revision: 63062a64432cce03315d6b5196fda7912866eb37 - channel: dev + revision: "bae5e49bc2a867403c43b2aae2de8f8c33b037e4" + channel: "stable" project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 + base_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 + - platform: android + create_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 + base_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 + - platform: ios + create_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 + base_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 + - platform: linux + create_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 + base_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 + - platform: macos + create_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 + base_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 + - platform: web + create_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 + base_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 + - platform: windows + create_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 + base_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml new file mode 100644 index 00000000..50d51fa6 --- /dev/null +++ b/example/analysis_options.yaml @@ -0,0 +1,180 @@ +analyzer: + strong-mode: + implicit-casts: false + implicit-dynamic: false + + errors: + close_sinks: ignore + missing_required_param: error + missing_return: error + # Ignored because of freezed and JsonKey (https://github.com/rrousselGit/freezed/issues/488) + invalid_annotation_target: ignore + body_might_complete_normally_nullable: ignore + + exclude: + - test/.test_coverage.dart + - lib/generated_plugin_registrant.dart + - packages/** + - "**/*.g.dart" + - "**/*.freezed.dart" + +linter: + rules: + - always_declare_return_types + - always_use_package_imports + - annotate_overrides + - avoid_bool_literals_in_conditional_expressions + - avoid_catching_errors + - avoid_double_and_int_checks + - avoid_dynamic_calls + - avoid_empty_else + - avoid_equals_and_hash_code_on_mutable_classes + - avoid_escaping_inner_quotes + - avoid_field_initializers_in_const_classes + - avoid_function_literals_in_foreach_calls + - avoid_init_to_null + - avoid_js_rounded_ints + - avoid_null_checks_in_equality_operators + - avoid_positional_boolean_parameters + - avoid_print + # - avoid_private_typedef_functions + # - avoid_redundant_argument_values + - avoid_relative_lib_imports + - avoid_renaming_method_parameters + - avoid_return_types_on_setters + - avoid_returning_null_for_void + - avoid_returning_this + - avoid_setters_without_getters + - avoid_shadowing_type_parameters + - avoid_single_cascade_in_expression_statements + - avoid_slow_async_io + - avoid_type_to_string + - avoid_types_as_parameter_names + - avoid_unnecessary_containers + - avoid_unused_constructor_parameters + - avoid_void_async + - avoid_web_libraries_in_flutter + - await_only_futures + - camel_case_extensions + - camel_case_types + - cancel_subscriptions + - cascade_invocations + - cast_nullable_to_non_nullable + # - comment_references + - constant_identifier_names + - control_flow_in_finally + - curly_braces_in_flow_control_structures + - deprecated_consistency + - directives_ordering + - empty_catches + - empty_constructor_bodies + - empty_statements + # - eol_at_end_of_file + - exhaustive_cases + - file_names + - flutter_style_todos + - hash_and_equals + - implementation_imports + - leading_newlines_in_multiline_strings + - library_names + - library_prefixes + # - library_private_types_in_public_api + # - lines_longer_than_80_chars + - literal_only_boolean_expressions + - missing_whitespace_between_adjacent_strings + - no_adjacent_strings_in_list + - no_default_cases + - no_duplicate_case_values + - no_logic_in_create_state + - no_runtimeType_toString + - non_constant_identifier_names + # - noop_primitive_operations + - null_check_on_nullable_type_parameter + - null_closures + - omit_local_variable_types + - only_throw_errors + - overridden_fields + - package_names + - package_prefixed_library_names + - parameter_assignments + - prefer_adjacent_string_concatenation + - prefer_asserts_in_initializer_lists + - prefer_asserts_with_message + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_const_constructors_in_immutables + - prefer_const_declarations + - prefer_const_literals_to_create_immutables + - prefer_constructors_over_static_methods + - prefer_contains + - prefer_final_fields + - prefer_final_in_for_each + - prefer_final_locals + - prefer_for_elements_to_map_fromIterable + - prefer_function_declarations_over_variables + - prefer_generic_function_type_aliases + - prefer_if_elements_to_conditional_expressions + - prefer_if_null_operators + - prefer_initializing_formals + - prefer_inlined_adds + # - prefer_int_literals + - prefer_interpolation_to_compose_strings + - prefer_is_empty + - prefer_is_not_empty + - prefer_is_not_operator + - prefer_iterable_whereType + - prefer_null_aware_operators + # - prefer_null_aware_method_calls + - prefer_single_quotes + - prefer_spread_collections + - prefer_typing_uninitialized_variables + - prefer_void_to_null + - provide_deprecation_message + # - public_member_api_docs + - recursive_getters + - require_trailing_commas + # - sized_box_for_whitespace //To error prone + - slash_for_doc_comments + - sort_child_properties_last + # - sort_constructors_first + - sort_pub_dependencies + - sort_unnamed_constructors_first + - test_types_in_equals + - throw_in_finally + - tighten_type_of_initializing_formals + - type_annotate_public_apis + - type_init_formals + - unawaited_futures + - unnecessary_await_in_return + - unnecessary_brace_in_string_interps + - unnecessary_const + - unnecessary_getters_setters + - unnecessary_lambdas + - unnecessary_new + - unnecessary_null_aware_assignments + - unnecessary_null_checks + - unnecessary_null_in_if_null_operators + - unnecessary_nullable_for_final_variable_declarations + - unnecessary_overrides + - unnecessary_parenthesis + - unnecessary_raw_strings + - unnecessary_statements + - unnecessary_string_escapes + - unnecessary_string_interpolations + - unnecessary_this + - unrelated_type_equality_checks + # - use_build_context_synchronously + - use_full_hex_values_for_flutter_colors + - use_function_type_syntax_for_parameters + - use_is_even_rather_than_modulo + - use_key_in_widget_constructors + - use_late_for_private_fields_and_variables + - use_named_constants + - use_raw_strings + - use_rethrow_when_possible + - use_setters_to_change_properties + - use_string_buffers + - use_to_and_as_if_applicable + - valid_regexps + - void_checks diff --git a/example/android/.gitignore b/example/android/.gitignore index 0a741cb4..6f568019 100644 --- a/example/android/.gitignore +++ b/example/android/.gitignore @@ -9,3 +9,5 @@ GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app key.properties +**/*.keystore +**/*.jks diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index f3450c79..5eb12c4f 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -1,3 +1,9 @@ +plugins { + id "com.android.application" + id "kotlin-android" + id "dev.flutter.flutter-gradle-plugin" +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) { } } -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' @@ -21,12 +22,19 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { - compileSdkVersion 31 + namespace "com.quickbirdstudios.example" + compileSdk flutter.compileSdkVersion + ndkVersion flutter.ndkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } sourceSets { main.java.srcDirs += 'src/main/kotlin' @@ -34,11 +42,14 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.quickbirdstudios.surveykit_example" - minSdkVersion 21 - targetSdkVersion 31 + applicationId "com.quickbirdstudios.example" + // You can update the following values to match your application needs. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. + minSdkVersion flutter.minSdkVersion + targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName + multiDexEnabled true } buildTypes { @@ -54,6 +65,4 @@ flutter { source '../..' } -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} +dependencies {} diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml index 80b55cbb..399f6981 100644 --- a/example/android/app/src/debug/AndroidManifest.xml +++ b/example/android/app/src/debug/AndroidManifest.xml @@ -1,6 +1,6 @@ - - diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index b39465c6..aff7dec7 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,12 +1,11 @@ - - - - + - - @@ -40,4 +30,15 @@ android:name="flutterEmbedding" android:value="2" /> + + + + + + + diff --git a/example/android/app/src/main/kotlin/com/quickbirdstudios/example/MainActivity.kt b/example/android/app/src/main/kotlin/com/quickbirdstudios/example/MainActivity.kt index 76f16e4f..d49bac85 100644 --- a/example/android/app/src/main/kotlin/com/quickbirdstudios/example/MainActivity.kt +++ b/example/android/app/src/main/kotlin/com/quickbirdstudios/example/MainActivity.kt @@ -2,5 +2,4 @@ package com.quickbirdstudios.example import io.flutter.embedding.android.FlutterActivity -class MainActivity: FlutterActivity() { -} +class MainActivity: FlutterActivity() diff --git a/example/android/app/src/main/kotlin/com/quickbirdstudios/surveykit_flutter_example/MainActivity.kt b/example/android/app/src/main/kotlin/com/quickbirdstudios/surveykit_flutter_example/MainActivity.kt deleted file mode 100644 index 96de7d50..00000000 --- a/example/android/app/src/main/kotlin/com/quickbirdstudios/surveykit_flutter_example/MainActivity.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.quickbirdstudios.surveykit_example - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() { -} diff --git a/example/android/app/src/main/res/values-night/styles.xml b/example/android/app/src/main/res/values-night/styles.xml index 449a9f93..06952be7 100644 --- a/example/android/app/src/main/res/values-night/styles.xml +++ b/example/android/app/src/main/res/values-night/styles.xml @@ -3,14 +3,14 @@